@elevasis/ui 2.32.0 → 2.33.1
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/app/index.d.ts +3 -0
- package/dist/app/index.js +3 -3
- package/dist/{chunk-LLRXA7D7.js → chunk-2VYMDNJ3.js} +1 -1
- package/dist/{chunk-7KZINJLP.js → chunk-3YZRKADM.js} +4 -4
- package/dist/{chunk-MOY4VOHF.js → chunk-4AAZXKLL.js} +1 -1
- package/dist/{chunk-RQTWIXJ5.js → chunk-53436UTQ.js} +1 -1
- package/dist/{chunk-WQPX44YM.js → chunk-AV2TKVVV.js} +673 -168
- package/dist/chunk-CLDCYJQT.js +1 -0
- package/dist/chunk-DWXDNT7P.js +145 -0
- package/dist/{chunk-T35FWDAB.js → chunk-DYIDXUJS.js} +1089 -158
- package/dist/{chunk-IQHU7O5Y.js → chunk-F3MXFE72.js} +1 -1
- package/dist/{chunk-5FJJ72HU.js → chunk-FOUYP4JX.js} +1 -1
- package/dist/{chunk-QQHOKTJA.js → chunk-H6EFQP2P.js} +39 -2
- package/dist/{chunk-5J4PDX26.js → chunk-KW7ZNQD7.js} +16 -2
- package/dist/{chunk-ZQOKIGZP.js → chunk-NCEQGEW5.js} +4 -4
- package/dist/{chunk-6DWD423K.js → chunk-PIS24NIV.js} +1 -1
- package/dist/{chunk-4MFNGNHF.js → chunk-QVTIOT73.js} +2 -2
- package/dist/{chunk-GCOQ3TBG.js → chunk-SWMQTF2H.js} +2 -2
- package/dist/{chunk-4QK76KIF.js → chunk-UNVRVCXZ.js} +1 -1
- package/dist/{chunk-VRNMNB3O.js → chunk-UYRT7SPM.js} +1 -1
- package/dist/{chunk-IZWTVFJ2.js → chunk-V6SZ4ECN.js} +6 -3
- package/dist/{chunk-YLQEVSOR.js → chunk-WGUEIGPC.js} +202 -54
- package/dist/{chunk-QXCDKE2O.js → chunk-WJOE76FI.js} +9 -28
- package/dist/{chunk-QTI3KC7D.js → chunk-YENKDBUU.js} +106 -43
- package/dist/components/index.d.ts +117 -4
- package/dist/components/index.js +24 -23
- package/dist/components/navigation/index.js +4 -3
- package/dist/execution/index.d.ts +8 -3
- package/dist/features/auth/index.d.ts +3 -0
- package/dist/features/clients/index.js +8 -7
- package/dist/features/crm/index.d.ts +3 -0
- package/dist/features/crm/index.js +10 -9
- package/dist/features/dashboard/index.d.ts +113 -3
- package/dist/features/dashboard/index.js +9 -8
- package/dist/features/delivery/index.d.ts +3 -0
- package/dist/features/delivery/index.js +9 -8
- package/dist/features/knowledge/index.js +8 -18
- package/dist/features/lead-gen/index.js +10 -9
- package/dist/features/monitoring/index.js +10 -9
- package/dist/features/monitoring/requests/index.d.ts +2 -2
- package/dist/features/monitoring/requests/index.js +8 -7
- package/dist/features/operations/index.d.ts +560 -93
- package/dist/features/operations/index.js +13 -12
- package/dist/features/settings/index.d.ts +3 -0
- package/dist/features/settings/index.js +9 -8
- package/dist/hooks/delivery/index.d.ts +3 -0
- package/dist/hooks/index.d.ts +210 -6
- package/dist/hooks/index.js +8 -7
- package/dist/hooks/operations/command-view/utils/transformCommandViewData.d.ts +205 -4
- package/dist/hooks/published.d.ts +210 -6
- package/dist/hooks/published.js +8 -7
- package/dist/index.d.ts +565 -95
- package/dist/index.js +8 -7
- package/dist/initialization/index.d.ts +3 -0
- package/dist/knowledge/index.d.ts +577 -215
- package/dist/knowledge/index.js +1180 -689
- package/dist/knowledge-search-index-P7PR626V.js +1514 -0
- package/dist/layout/index.js +1 -1
- package/dist/profile/index.d.ts +3 -0
- package/dist/provider/index.d.ts +447 -73
- package/dist/provider/index.js +7 -6
- package/dist/provider/published.d.ts +447 -73
- package/dist/provider/published.js +5 -4
- package/dist/supabase/index.d.ts +6 -0
- package/dist/types/index.d.ts +208 -4
- package/dist/utils/index.d.ts +113 -3
- package/package.json +39 -39
- package/src/README.md +29 -29
- package/src/api/README.md +18 -18
- package/src/app/README.md +24 -24
- package/src/auth/README.md +18 -18
- package/src/components/README.md +24 -24
- package/src/execution/README.md +16 -16
- package/src/features/README.md +28 -28
- package/src/graph/README.md +16 -16
- package/src/hooks/README.md +23 -23
- package/src/initialization/README.md +19 -19
- package/src/knowledge/README.md +31 -31
- package/src/organization/README.md +18 -18
- package/src/profile/README.md +19 -19
- package/src/provider/README.md +32 -32
- package/src/router/README.md +18 -18
- package/src/sse/README.md +13 -13
- package/src/test-utils/README.md +7 -7
- package/src/theme/README.md +23 -23
- package/src/theme/presets/README.md +19 -19
- package/src/types/README.md +16 -16
- package/src/utils/README.md +18 -18
- package/src/zustand/README.md +18 -18
- package/dist/chunk-UROTM5OR.js +0 -172
- package/dist/knowledge-search-index-5KYPO746.js +0 -1479
|
@@ -1,74 +1,469 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
|
|
3
|
-
// ../core/src/organization-model/
|
|
3
|
+
// ../core/src/organization-model/ontology.ts
|
|
4
|
+
var OntologyKindSchema = z.enum([
|
|
5
|
+
"object",
|
|
6
|
+
"link",
|
|
7
|
+
"action",
|
|
8
|
+
"catalog",
|
|
9
|
+
"event",
|
|
10
|
+
"interface",
|
|
11
|
+
"value-type",
|
|
12
|
+
"property",
|
|
13
|
+
"group",
|
|
14
|
+
"surface"
|
|
15
|
+
]);
|
|
16
|
+
var SYSTEM_PATH_PATTERN = "[a-z0-9][a-z0-9-]*(?:\\.[a-z0-9][a-z0-9-]*)*";
|
|
17
|
+
var LOCAL_ID_PATTERN = "[a-z0-9][a-z0-9._-]*";
|
|
18
|
+
var ONTOLOGY_ID_PATTERN = `^(global|${SYSTEM_PATH_PATTERN}):(${OntologyKindSchema.options.join("|")})\\/(${LOCAL_ID_PATTERN})$`;
|
|
19
|
+
var ONTOLOGY_ID_REGEX = new RegExp(ONTOLOGY_ID_PATTERN);
|
|
20
|
+
var OntologyIdSchema = z.string().trim().min(1).max(300).regex(
|
|
21
|
+
ONTOLOGY_ID_REGEX,
|
|
22
|
+
"Ontology IDs must use <system-path>:<kind>/<local-id> or global:<kind>/<local-id>"
|
|
23
|
+
);
|
|
24
|
+
function parseOntologyId(id) {
|
|
25
|
+
const normalized = OntologyIdSchema.parse(id);
|
|
26
|
+
const match = ONTOLOGY_ID_REGEX.exec(normalized);
|
|
27
|
+
if (match === null) {
|
|
28
|
+
throw new Error(`Invalid ontology ID "${id}"`);
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
id: normalized,
|
|
32
|
+
scope: match[1],
|
|
33
|
+
kind: match[2],
|
|
34
|
+
localId: match[3],
|
|
35
|
+
isGlobal: match[1] === "global"
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function formatOntologyId(input) {
|
|
39
|
+
return OntologyIdSchema.parse(`${input.scope}:${input.kind}/${input.localId}`);
|
|
40
|
+
}
|
|
41
|
+
var OntologyReferenceListSchema = z.array(OntologyIdSchema).default([]).optional();
|
|
42
|
+
var OntologyRecordBaseSchema = z.object({
|
|
43
|
+
id: OntologyIdSchema,
|
|
44
|
+
label: z.string().trim().min(1).max(160).optional(),
|
|
45
|
+
description: z.string().trim().min(1).max(2e3).optional(),
|
|
46
|
+
ownerSystemId: z.string().trim().min(1).max(200).optional(),
|
|
47
|
+
aliases: z.array(OntologyIdSchema).optional()
|
|
48
|
+
}).passthrough();
|
|
49
|
+
var OntologyObjectTypeSchema = OntologyRecordBaseSchema.extend({
|
|
50
|
+
properties: z.record(z.string().trim().min(1).max(200), z.unknown()).optional(),
|
|
51
|
+
storage: z.record(z.string(), z.unknown()).optional()
|
|
52
|
+
});
|
|
53
|
+
var OntologyLinkTypeSchema = OntologyRecordBaseSchema.extend({
|
|
54
|
+
from: OntologyIdSchema,
|
|
55
|
+
to: OntologyIdSchema,
|
|
56
|
+
cardinality: z.string().trim().min(1).max(80).optional(),
|
|
57
|
+
via: z.string().trim().min(1).max(255).optional()
|
|
58
|
+
});
|
|
59
|
+
var OntologyActionTypeSchema = OntologyRecordBaseSchema.extend({
|
|
60
|
+
actsOn: OntologyReferenceListSchema,
|
|
61
|
+
input: z.record(z.string().trim().min(1).max(200), z.unknown()).optional(),
|
|
62
|
+
effects: z.array(z.record(z.string(), z.unknown())).optional()
|
|
63
|
+
});
|
|
64
|
+
var OntologyCatalogTypeSchema = OntologyRecordBaseSchema.extend({
|
|
65
|
+
kind: z.string().trim().min(1).max(120).optional(),
|
|
66
|
+
appliesTo: OntologyIdSchema.optional(),
|
|
67
|
+
entries: z.record(z.string().trim().min(1).max(200), z.unknown()).optional()
|
|
68
|
+
});
|
|
69
|
+
var OntologyEventTypeSchema = OntologyRecordBaseSchema.extend({
|
|
70
|
+
payload: z.record(z.string().trim().min(1).max(200), z.unknown()).optional()
|
|
71
|
+
});
|
|
72
|
+
var OntologyInterfaceTypeSchema = OntologyRecordBaseSchema.extend({
|
|
73
|
+
properties: z.record(z.string().trim().min(1).max(200), z.unknown()).optional()
|
|
74
|
+
});
|
|
75
|
+
var OntologyValueTypeSchema = OntologyRecordBaseSchema.extend({
|
|
76
|
+
primitive: z.string().trim().min(1).max(120).optional()
|
|
77
|
+
});
|
|
78
|
+
var OntologySharedPropertySchema = OntologyRecordBaseSchema.extend({
|
|
79
|
+
valueType: OntologyIdSchema.optional(),
|
|
80
|
+
searchable: z.boolean().optional(),
|
|
81
|
+
pii: z.boolean().optional()
|
|
82
|
+
});
|
|
83
|
+
var OntologyGroupSchema = OntologyRecordBaseSchema.extend({
|
|
84
|
+
members: OntologyReferenceListSchema
|
|
85
|
+
});
|
|
86
|
+
var OntologySurfaceTypeSchema = OntologyRecordBaseSchema.extend({
|
|
87
|
+
route: z.string().trim().min(1).max(500).optional()
|
|
88
|
+
});
|
|
89
|
+
var OntologyScopeSchema = z.object({
|
|
90
|
+
objectTypes: z.record(OntologyIdSchema, OntologyObjectTypeSchema).default({}).optional(),
|
|
91
|
+
linkTypes: z.record(OntologyIdSchema, OntologyLinkTypeSchema).default({}).optional(),
|
|
92
|
+
actionTypes: z.record(OntologyIdSchema, OntologyActionTypeSchema).default({}).optional(),
|
|
93
|
+
catalogTypes: z.record(OntologyIdSchema, OntologyCatalogTypeSchema).default({}).optional(),
|
|
94
|
+
eventTypes: z.record(OntologyIdSchema, OntologyEventTypeSchema).default({}).optional(),
|
|
95
|
+
interfaceTypes: z.record(OntologyIdSchema, OntologyInterfaceTypeSchema).default({}).optional(),
|
|
96
|
+
valueTypes: z.record(OntologyIdSchema, OntologyValueTypeSchema).default({}).optional(),
|
|
97
|
+
sharedProperties: z.record(OntologyIdSchema, OntologySharedPropertySchema).default({}).optional(),
|
|
98
|
+
groups: z.record(OntologyIdSchema, OntologyGroupSchema).default({}).optional(),
|
|
99
|
+
surfaces: z.record(OntologyIdSchema, OntologySurfaceTypeSchema).default({}).optional()
|
|
100
|
+
}).default({});
|
|
101
|
+
var DEFAULT_ONTOLOGY_SCOPE = {
|
|
102
|
+
valueTypes: {
|
|
103
|
+
"global:value-type/uuid": {
|
|
104
|
+
id: "global:value-type/uuid",
|
|
105
|
+
label: "UUID",
|
|
106
|
+
primitive: "string"
|
|
107
|
+
},
|
|
108
|
+
"global:value-type/text": {
|
|
109
|
+
id: "global:value-type/text",
|
|
110
|
+
label: "Text",
|
|
111
|
+
primitive: "string"
|
|
112
|
+
},
|
|
113
|
+
"global:value-type/url": {
|
|
114
|
+
id: "global:value-type/url",
|
|
115
|
+
label: "URL",
|
|
116
|
+
primitive: "string"
|
|
117
|
+
},
|
|
118
|
+
"global:value-type/email": {
|
|
119
|
+
id: "global:value-type/email",
|
|
120
|
+
label: "Email",
|
|
121
|
+
primitive: "string"
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
var SCOPE_KIND = {
|
|
126
|
+
objectTypes: "object",
|
|
127
|
+
linkTypes: "link",
|
|
128
|
+
actionTypes: "action",
|
|
129
|
+
catalogTypes: "catalog",
|
|
130
|
+
eventTypes: "event",
|
|
131
|
+
interfaceTypes: "interface",
|
|
132
|
+
valueTypes: "value-type",
|
|
133
|
+
sharedProperties: "property",
|
|
134
|
+
groups: "group",
|
|
135
|
+
surfaces: "surface"
|
|
136
|
+
};
|
|
137
|
+
var SCOPE_KEYS = Object.keys(SCOPE_KIND);
|
|
138
|
+
function ontologyGraphNodeId(id) {
|
|
139
|
+
return `ontology:${OntologyIdSchema.parse(id)}`;
|
|
140
|
+
}
|
|
141
|
+
function listResolvedOntologyRecords(index) {
|
|
142
|
+
return SCOPE_KEYS.flatMap((scopeKey) => {
|
|
143
|
+
const kind = SCOPE_KIND[scopeKey];
|
|
144
|
+
return Object.entries(index[scopeKey]).sort(([leftId], [rightId]) => leftId.localeCompare(rightId)).map(([id, record]) => ({
|
|
145
|
+
id,
|
|
146
|
+
kind,
|
|
147
|
+
record
|
|
148
|
+
}));
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
function originFromContext(context) {
|
|
152
|
+
return {
|
|
153
|
+
kind: context.kind,
|
|
154
|
+
source: context.source,
|
|
155
|
+
path: context.path,
|
|
156
|
+
...context.systemPath !== void 0 ? { systemPath: context.systemPath } : {},
|
|
157
|
+
...context.legacyId !== void 0 ? { legacyId: context.legacyId } : {}
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
function createEmptyIndex() {
|
|
161
|
+
return {
|
|
162
|
+
objectTypes: {},
|
|
163
|
+
linkTypes: {},
|
|
164
|
+
actionTypes: {},
|
|
165
|
+
catalogTypes: {},
|
|
166
|
+
eventTypes: {},
|
|
167
|
+
interfaceTypes: {},
|
|
168
|
+
valueTypes: {},
|
|
169
|
+
sharedProperties: {},
|
|
170
|
+
groups: {},
|
|
171
|
+
surfaces: {}
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
function sortResolvedOntologyIndex(index) {
|
|
175
|
+
const sorted = createEmptyIndex();
|
|
176
|
+
for (const scopeKey of SCOPE_KEYS) {
|
|
177
|
+
const target = sorted[scopeKey];
|
|
178
|
+
for (const [id, record] of Object.entries(index[scopeKey]).sort(
|
|
179
|
+
([leftId], [rightId]) => leftId.localeCompare(rightId)
|
|
180
|
+
)) {
|
|
181
|
+
target[id] = record;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return sorted;
|
|
185
|
+
}
|
|
186
|
+
function childSystemsOf(system) {
|
|
187
|
+
return system.systems ?? system.subsystems ?? {};
|
|
188
|
+
}
|
|
189
|
+
function addRecord(index, diagnostics, sourcesById, scopeKey, record, context) {
|
|
190
|
+
let parsed;
|
|
191
|
+
try {
|
|
192
|
+
parsed = parseOntologyId(record.id);
|
|
193
|
+
} catch {
|
|
194
|
+
diagnostics.push({
|
|
195
|
+
code: "invalid_ontology_id",
|
|
196
|
+
message: `Invalid ontology ID "${record.id}" from ${context.source} at ${context.path.join(".")}`,
|
|
197
|
+
id: record.id,
|
|
198
|
+
path: context.path,
|
|
199
|
+
source: context.source,
|
|
200
|
+
origin: originFromContext(context)
|
|
201
|
+
});
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
const expectedKind = SCOPE_KIND[scopeKey];
|
|
205
|
+
if (parsed.kind !== expectedKind) {
|
|
206
|
+
diagnostics.push({
|
|
207
|
+
code: "ontology_kind_mismatch",
|
|
208
|
+
message: `Ontology ID "${record.id}" has kind "${parsed.kind}" but was authored in ${scopeKey} (${expectedKind}) at ${context.path.join(".")}`,
|
|
209
|
+
id: record.id,
|
|
210
|
+
path: context.path,
|
|
211
|
+
source: context.source,
|
|
212
|
+
origin: originFromContext(context)
|
|
213
|
+
});
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
const existing = sourcesById.get(parsed.id);
|
|
217
|
+
if (existing !== void 0) {
|
|
218
|
+
diagnostics.push({
|
|
219
|
+
code: "duplicate_ontology_id",
|
|
220
|
+
message: `Duplicate ontology ID "${parsed.id}" from ${context.source} at ${context.path.join(".")} conflicts with ${existing.source} at ${existing.path.join(".")}`,
|
|
221
|
+
id: parsed.id,
|
|
222
|
+
path: context.path,
|
|
223
|
+
source: context.source,
|
|
224
|
+
origin: originFromContext(context),
|
|
225
|
+
existingSource: existing.source,
|
|
226
|
+
existingOrigin: originFromContext(existing)
|
|
227
|
+
});
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
sourcesById.set(parsed.id, context);
|
|
231
|
+
index[scopeKey][parsed.id] = {
|
|
232
|
+
...record,
|
|
233
|
+
origin: originFromContext(context)
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
function addScope(index, diagnostics, sourcesById, scope, source, path) {
|
|
237
|
+
if (scope === void 0) return;
|
|
238
|
+
for (const scopeKey of SCOPE_KEYS) {
|
|
239
|
+
const records = scope[scopeKey] ?? {};
|
|
240
|
+
for (const [key, record] of Object.entries(records)) {
|
|
241
|
+
addRecord(index, diagnostics, sourcesById, scopeKey, record, {
|
|
242
|
+
source,
|
|
243
|
+
path: [...path, scopeKey, key],
|
|
244
|
+
kind: "authored",
|
|
245
|
+
systemPath: source.startsWith("system:") ? source.slice("system:".length, -".ontology".length) : void 0
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
function legacyObjectId(entity) {
|
|
251
|
+
return formatOntologyId({ scope: entity.ownedBySystemId, kind: "object", localId: entity.id });
|
|
252
|
+
}
|
|
253
|
+
function legacyActionOwner(action, entities) {
|
|
254
|
+
const firstAffectedEntityId = action.affects?.find((entityId) => entities[entityId] !== void 0);
|
|
255
|
+
if (firstAffectedEntityId !== void 0) {
|
|
256
|
+
return entities[firstAffectedEntityId].ownedBySystemId;
|
|
257
|
+
}
|
|
258
|
+
if (typeof action.scope === "object") {
|
|
259
|
+
return action.scope.domain;
|
|
260
|
+
}
|
|
261
|
+
return "global";
|
|
262
|
+
}
|
|
263
|
+
function addLegacyEntityProjections(index, diagnostics, sourcesById, entities) {
|
|
264
|
+
for (const entity of Object.values(entities)) {
|
|
265
|
+
const objectType = {
|
|
266
|
+
id: legacyObjectId(entity),
|
|
267
|
+
label: entity.label,
|
|
268
|
+
description: entity.description,
|
|
269
|
+
ownerSystemId: entity.ownedBySystemId,
|
|
270
|
+
...entity.table !== void 0 ? {
|
|
271
|
+
storage: {
|
|
272
|
+
kind: "table",
|
|
273
|
+
table: entity.table
|
|
274
|
+
}
|
|
275
|
+
} : {},
|
|
276
|
+
...entity.rowSchema !== void 0 ? { rowSchema: entity.rowSchema } : {},
|
|
277
|
+
...entity.stateCatalogId !== void 0 ? { stateCatalogId: entity.stateCatalogId } : {}
|
|
278
|
+
};
|
|
279
|
+
addRecord(index, diagnostics, sourcesById, "objectTypes", objectType, {
|
|
280
|
+
source: "legacy.entities",
|
|
281
|
+
path: ["entities", entity.id],
|
|
282
|
+
kind: "projected",
|
|
283
|
+
systemPath: entity.ownedBySystemId,
|
|
284
|
+
legacyId: entity.id
|
|
285
|
+
});
|
|
286
|
+
entity.links?.forEach((link, linkIndex) => {
|
|
287
|
+
const targetEntity = entities[link.toEntity];
|
|
288
|
+
if (targetEntity === void 0) return;
|
|
289
|
+
const linkType = {
|
|
290
|
+
id: formatOntologyId({
|
|
291
|
+
scope: entity.ownedBySystemId,
|
|
292
|
+
kind: "link",
|
|
293
|
+
localId: `${entity.id}-${link.toEntity}-${linkIndex}`
|
|
294
|
+
}),
|
|
295
|
+
label: link.label ?? link.kind,
|
|
296
|
+
ownerSystemId: entity.ownedBySystemId,
|
|
297
|
+
from: legacyObjectId(entity),
|
|
298
|
+
to: legacyObjectId(targetEntity),
|
|
299
|
+
cardinality: link.kind,
|
|
300
|
+
...link.via !== void 0 ? { via: link.via } : {}
|
|
301
|
+
};
|
|
302
|
+
addRecord(index, diagnostics, sourcesById, "linkTypes", linkType, {
|
|
303
|
+
source: "legacy.entities.links",
|
|
304
|
+
path: ["entities", entity.id, "links", linkIndex],
|
|
305
|
+
kind: "projected",
|
|
306
|
+
systemPath: entity.ownedBySystemId,
|
|
307
|
+
legacyId: `${entity.id}.links.${linkIndex}`
|
|
308
|
+
});
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
function addLegacyActionProjections(index, diagnostics, sourcesById, actions, entities) {
|
|
313
|
+
for (const action of Object.values(actions)) {
|
|
314
|
+
const ownerSystemId = legacyActionOwner(action, entities);
|
|
315
|
+
const actionType = {
|
|
316
|
+
id: formatOntologyId({ scope: ownerSystemId, kind: "action", localId: action.id }),
|
|
317
|
+
label: action.label,
|
|
318
|
+
description: action.description,
|
|
319
|
+
ownerSystemId,
|
|
320
|
+
actsOn: action.affects?.map((entityId) => entities[entityId] ? legacyObjectId(entities[entityId]) : void 0).filter((id) => id !== void 0),
|
|
321
|
+
...action.resourceId !== void 0 ? { resourceId: action.resourceId } : {},
|
|
322
|
+
...action.invocations !== void 0 ? { invocations: action.invocations } : {},
|
|
323
|
+
...action.lifecycle !== void 0 ? { lifecycle: action.lifecycle } : {},
|
|
324
|
+
legacyActionId: action.id
|
|
325
|
+
};
|
|
326
|
+
addRecord(index, diagnostics, sourcesById, "actionTypes", actionType, {
|
|
327
|
+
source: "legacy.actions",
|
|
328
|
+
path: ["actions", action.id],
|
|
329
|
+
kind: "projected",
|
|
330
|
+
systemPath: ownerSystemId,
|
|
331
|
+
legacyId: action.id
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
function addSystemContentProjections(index, diagnostics, sourcesById, systemPath, system, schemaPath) {
|
|
336
|
+
const content = system.content ?? {};
|
|
337
|
+
for (const [localId, node] of Object.entries(content)) {
|
|
338
|
+
if (node.kind !== "schema") continue;
|
|
339
|
+
const entries = Object.fromEntries(
|
|
340
|
+
Object.entries(content).filter(([, candidate]) => candidate.parentContentId === localId).map(([entryId, candidate]) => [
|
|
341
|
+
entryId,
|
|
342
|
+
{
|
|
343
|
+
label: candidate.label ?? entryId,
|
|
344
|
+
type: candidate.type,
|
|
345
|
+
...candidate.description !== void 0 ? { description: candidate.description } : {},
|
|
346
|
+
...candidate.data !== void 0 ? candidate.data : {}
|
|
347
|
+
}
|
|
348
|
+
])
|
|
349
|
+
);
|
|
350
|
+
const catalogType = {
|
|
351
|
+
id: formatOntologyId({ scope: systemPath, kind: "catalog", localId }),
|
|
352
|
+
label: node.label ?? localId,
|
|
353
|
+
description: node.description,
|
|
354
|
+
ownerSystemId: systemPath,
|
|
355
|
+
kind: node.type,
|
|
356
|
+
...typeof node.data?.["entityId"] === "string" ? { appliesTo: formatOntologyId({ scope: systemPath, kind: "object", localId: node.data["entityId"] }) } : {},
|
|
357
|
+
...Object.keys(entries).length > 0 ? { entries } : {},
|
|
358
|
+
...node.data !== void 0 ? { data: node.data } : {}
|
|
359
|
+
};
|
|
360
|
+
addRecord(index, diagnostics, sourcesById, "catalogTypes", catalogType, {
|
|
361
|
+
source: "legacy.system.content",
|
|
362
|
+
path: [...schemaPath, "content", localId],
|
|
363
|
+
kind: "projected",
|
|
364
|
+
systemPath,
|
|
365
|
+
legacyId: `${systemPath}:${localId}`
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
function addSystemScopes(index, diagnostics, sourcesById, systems, prefix, schemaPath) {
|
|
370
|
+
for (const [key, system] of Object.entries(systems)) {
|
|
371
|
+
const systemPath = prefix ? `${prefix}.${key}` : key;
|
|
372
|
+
const currentPath = [...schemaPath, key];
|
|
373
|
+
addScope(index, diagnostics, sourcesById, system.ontology, `system:${systemPath}.ontology`, [
|
|
374
|
+
...currentPath,
|
|
375
|
+
"ontology"
|
|
376
|
+
]);
|
|
377
|
+
addSystemContentProjections(index, diagnostics, sourcesById, systemPath, system, currentPath);
|
|
378
|
+
addSystemScopes(index, diagnostics, sourcesById, childSystemsOf(system), systemPath, [
|
|
379
|
+
...currentPath,
|
|
380
|
+
system.systems !== void 0 ? "systems" : "subsystems"
|
|
381
|
+
]);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
function compileOrganizationOntology(model) {
|
|
385
|
+
const ontology = createEmptyIndex();
|
|
386
|
+
const diagnostics = [];
|
|
387
|
+
const sourcesById = /* @__PURE__ */ new Map();
|
|
388
|
+
addScope(ontology, diagnostics, sourcesById, model.ontology, "organization.ontology", ["ontology"]);
|
|
389
|
+
addSystemScopes(ontology, diagnostics, sourcesById, model.systems ?? {}, "", ["systems"]);
|
|
390
|
+
addLegacyEntityProjections(ontology, diagnostics, sourcesById, model.entities ?? {});
|
|
391
|
+
addLegacyActionProjections(ontology, diagnostics, sourcesById, model.actions ?? {}, model.entities ?? {});
|
|
392
|
+
return { ontology: sortResolvedOntologyIndex(ontology), diagnostics };
|
|
393
|
+
}
|
|
4
394
|
var ORGANIZATION_MODEL_ICON_TOKENS = [
|
|
5
|
-
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
395
|
+
// Navigation / app areas
|
|
396
|
+
"dashboard",
|
|
397
|
+
"calendar",
|
|
398
|
+
"sales",
|
|
399
|
+
"crm",
|
|
400
|
+
"lead-gen",
|
|
401
|
+
"projects",
|
|
402
|
+
"operations",
|
|
403
|
+
"monitoring",
|
|
404
|
+
"knowledge",
|
|
405
|
+
"settings",
|
|
406
|
+
"admin",
|
|
407
|
+
"archive",
|
|
408
|
+
"business",
|
|
409
|
+
"finance",
|
|
410
|
+
"platform",
|
|
411
|
+
"seo",
|
|
412
|
+
// Knowledge kinds
|
|
413
|
+
"playbook",
|
|
414
|
+
"strategy",
|
|
415
|
+
"reference",
|
|
416
|
+
// Resource kinds
|
|
417
|
+
"agent",
|
|
418
|
+
"workflow",
|
|
419
|
+
"integration",
|
|
420
|
+
"database",
|
|
421
|
+
"user",
|
|
422
|
+
"team",
|
|
423
|
+
// Integration specifics
|
|
424
|
+
"gmail",
|
|
425
|
+
"google-sheets",
|
|
426
|
+
"attio",
|
|
427
|
+
// Surface / UI views
|
|
428
|
+
"overview",
|
|
429
|
+
"command-view",
|
|
430
|
+
"command-queue",
|
|
431
|
+
"pipeline",
|
|
432
|
+
"lists",
|
|
433
|
+
"resources",
|
|
434
|
+
// Actions
|
|
435
|
+
"approve",
|
|
436
|
+
"reject",
|
|
437
|
+
"retry",
|
|
438
|
+
"edit",
|
|
439
|
+
"view",
|
|
440
|
+
"launch",
|
|
441
|
+
"message",
|
|
442
|
+
"escalate",
|
|
443
|
+
"promote",
|
|
444
|
+
"submit",
|
|
445
|
+
"email",
|
|
446
|
+
// Status
|
|
447
|
+
"success",
|
|
448
|
+
"error",
|
|
449
|
+
"warning",
|
|
450
|
+
"info",
|
|
451
|
+
"pending",
|
|
452
|
+
// OM / UI group icons
|
|
453
|
+
"bolt",
|
|
454
|
+
"building",
|
|
455
|
+
"briefcase",
|
|
456
|
+
"apps",
|
|
457
|
+
"graph",
|
|
458
|
+
"shield",
|
|
459
|
+
"users",
|
|
460
|
+
"chart-bar",
|
|
461
|
+
"search"
|
|
70
462
|
];
|
|
71
|
-
var CustomIconTokenSchema = z.string().trim().max(80).regex(
|
|
463
|
+
var CustomIconTokenSchema = z.string().trim().max(80).regex(
|
|
464
|
+
/^custom\.[a-z0-9]+(?:[-._][a-z0-9]+)*$/,
|
|
465
|
+
'Custom icon tokens must start with "custom." followed by lowercase alphanumeric segments'
|
|
466
|
+
);
|
|
72
467
|
var OrganizationModelBuiltinIconTokenSchema = z.enum(ORGANIZATION_MODEL_ICON_TOKENS);
|
|
73
468
|
var OrganizationModelIconTokenSchema = z.union([
|
|
74
469
|
OrganizationModelBuiltinIconTokenSchema,
|
|
@@ -430,7 +825,99 @@ var LEAD_GEN_ACTION_ENTRIES = Object.fromEntries(
|
|
|
430
825
|
return [parsed.id, parsed];
|
|
431
826
|
})
|
|
432
827
|
);
|
|
433
|
-
var
|
|
828
|
+
var CRM_ACTION_ENTRY_INPUTS = [
|
|
829
|
+
{
|
|
830
|
+
id: "send_reply",
|
|
831
|
+
order: 210,
|
|
832
|
+
label: "Send Reply",
|
|
833
|
+
description: "Send a contextual reply for an active CRM deal.",
|
|
834
|
+
scope: { domain: "sales" },
|
|
835
|
+
resourceId: "crm-send-reply-workflow",
|
|
836
|
+
affects: ["crm.deal"]
|
|
837
|
+
},
|
|
838
|
+
{
|
|
839
|
+
id: "send_link",
|
|
840
|
+
order: 220,
|
|
841
|
+
label: "Send Booking Link",
|
|
842
|
+
description: "Send a booking link to move a deal toward a scheduled call.",
|
|
843
|
+
scope: { domain: "sales" },
|
|
844
|
+
resourceId: "crm-send-booking-link-workflow",
|
|
845
|
+
affects: ["crm.deal"]
|
|
846
|
+
},
|
|
847
|
+
{
|
|
848
|
+
id: "send_nudge",
|
|
849
|
+
order: 230,
|
|
850
|
+
label: "Send Nudge",
|
|
851
|
+
description: "Send a follow-up nudge for a stalled CRM deal.",
|
|
852
|
+
scope: { domain: "sales" },
|
|
853
|
+
resourceId: "crm-send-nudge-workflow",
|
|
854
|
+
affects: ["crm.deal"]
|
|
855
|
+
},
|
|
856
|
+
{
|
|
857
|
+
id: "rebook",
|
|
858
|
+
order: 240,
|
|
859
|
+
label: "Rebook",
|
|
860
|
+
description: "Rebook a missed or rescheduled CRM appointment.",
|
|
861
|
+
scope: { domain: "sales" },
|
|
862
|
+
resourceId: "crm-rebook-workflow",
|
|
863
|
+
affects: ["crm.deal"]
|
|
864
|
+
},
|
|
865
|
+
{
|
|
866
|
+
id: "move_to_proposal",
|
|
867
|
+
order: 250,
|
|
868
|
+
label: "Move to Proposal",
|
|
869
|
+
description: "Advance a qualified CRM deal into the proposal stage.",
|
|
870
|
+
scope: { domain: "sales" },
|
|
871
|
+
resourceId: "move_to_proposal-workflow",
|
|
872
|
+
affects: ["crm.deal"]
|
|
873
|
+
},
|
|
874
|
+
{
|
|
875
|
+
id: "move_to_closing",
|
|
876
|
+
order: 260,
|
|
877
|
+
label: "Move to Closing",
|
|
878
|
+
description: "Advance a proposal-stage CRM deal into closing.",
|
|
879
|
+
scope: { domain: "sales" },
|
|
880
|
+
resourceId: "move_to_closing-workflow",
|
|
881
|
+
affects: ["crm.deal"]
|
|
882
|
+
},
|
|
883
|
+
{
|
|
884
|
+
id: "move_to_closed_won",
|
|
885
|
+
order: 270,
|
|
886
|
+
label: "Close Won",
|
|
887
|
+
description: "Mark a CRM deal as closed won.",
|
|
888
|
+
scope: { domain: "sales" },
|
|
889
|
+
resourceId: "move_to_closed_won-workflow",
|
|
890
|
+
affects: ["crm.deal"]
|
|
891
|
+
},
|
|
892
|
+
{
|
|
893
|
+
id: "move_to_closed_lost",
|
|
894
|
+
order: 280,
|
|
895
|
+
label: "Close Lost",
|
|
896
|
+
description: "Mark a CRM deal as closed lost.",
|
|
897
|
+
scope: { domain: "sales" },
|
|
898
|
+
resourceId: "move_to_closed_lost-workflow",
|
|
899
|
+
affects: ["crm.deal"]
|
|
900
|
+
},
|
|
901
|
+
{
|
|
902
|
+
id: "move_to_nurturing",
|
|
903
|
+
order: 290,
|
|
904
|
+
label: "Move to Nurturing",
|
|
905
|
+
description: "Move a CRM deal into nurturing for future follow-up.",
|
|
906
|
+
scope: { domain: "sales" },
|
|
907
|
+
resourceId: "move_to_nurturing-workflow",
|
|
908
|
+
affects: ["crm.deal"]
|
|
909
|
+
}
|
|
910
|
+
];
|
|
911
|
+
var CRM_ACTION_ENTRIES = Object.fromEntries(
|
|
912
|
+
CRM_ACTION_ENTRY_INPUTS.map((action) => {
|
|
913
|
+
const parsed = ActionSchema.parse(action);
|
|
914
|
+
return [parsed.id, parsed];
|
|
915
|
+
})
|
|
916
|
+
);
|
|
917
|
+
var DEFAULT_ORGANIZATION_MODEL_ACTIONS = {
|
|
918
|
+
...LEAD_GEN_ACTION_ENTRIES,
|
|
919
|
+
...CRM_ACTION_ENTRIES
|
|
920
|
+
};
|
|
434
921
|
var ContentNodeBaseSchema = z.object({
|
|
435
922
|
/** Human-readable label for the content node. */
|
|
436
923
|
label: z.string().trim().min(1).max(120).meta({ label: "Label" }),
|
|
@@ -491,6 +978,17 @@ var SystemUiSchema = z.object({
|
|
|
491
978
|
icon: IconNameSchema.optional(),
|
|
492
979
|
order: z.number().int().optional()
|
|
493
980
|
});
|
|
981
|
+
var JsonValueSchema = z.lazy(
|
|
982
|
+
() => z.union([
|
|
983
|
+
z.string(),
|
|
984
|
+
z.number(),
|
|
985
|
+
z.boolean(),
|
|
986
|
+
z.null(),
|
|
987
|
+
z.array(JsonValueSchema),
|
|
988
|
+
z.record(z.string(), JsonValueSchema)
|
|
989
|
+
])
|
|
990
|
+
);
|
|
991
|
+
var SystemConfigSchema = z.record(z.string().trim().min(1).max(200), JsonValueSchema).default({}).optional();
|
|
494
992
|
var SystemEntrySchema = z.object({
|
|
495
993
|
/** Stable tenant-defined system id (e.g. "sys.lead-gen" or "sales.crm"). */
|
|
496
994
|
id: SystemIdSchema,
|
|
@@ -536,11 +1034,21 @@ var SystemEntrySchema = z.object({
|
|
|
536
1034
|
/** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
|
|
537
1035
|
order: z.number(),
|
|
538
1036
|
/**
|
|
539
|
-
* System-
|
|
540
|
-
*
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
1037
|
+
* System-local JSON settings and defaults. Strongly typed OM fields,
|
|
1038
|
+
* secrets, credentials, and runtime state stay outside this bucket.
|
|
1039
|
+
*/
|
|
1040
|
+
config: SystemConfigSchema,
|
|
1041
|
+
/**
|
|
1042
|
+
* System-owned ontology declarations. `systems` is now the canonical child
|
|
1043
|
+
* key; this scope holds the object, action, catalog, link, event, and
|
|
1044
|
+
* shared contract records owned by this system.
|
|
1045
|
+
*/
|
|
1046
|
+
ontology: OntologyScopeSchema.optional(),
|
|
1047
|
+
/**
|
|
1048
|
+
* @deprecated Compatibility-only bridge for old tenant content nodes and
|
|
1049
|
+
* migration readers. New schema/catalog authoring belongs in ontology;
|
|
1050
|
+
* new system-local settings belong in config. Bridge nodes are keyed by
|
|
1051
|
+
* local NodeId and may still project to content-node:* graph IDs.
|
|
544
1052
|
*/
|
|
545
1053
|
content: z.record(z.string().trim().min(1).max(200), ContentNodeSchema).optional(),
|
|
546
1054
|
/**
|
|
@@ -550,14 +1058,17 @@ var SystemEntrySchema = z.object({
|
|
|
550
1058
|
* Per Phase 4: `id` and `parentSystemId` fields will be removed in favour of
|
|
551
1059
|
* position-derived paths. Both still exist on this schema for backward compat.
|
|
552
1060
|
*/
|
|
1061
|
+
systems: z.lazy(() => z.record(z.string().trim().min(1).max(100), SystemEntrySchema)).optional(),
|
|
1062
|
+
/** @deprecated Use systems. Accepted as a compatibility alias during the ontology bridge. */
|
|
553
1063
|
subsystems: z.lazy(() => z.record(z.string().trim().min(1).max(100), SystemEntrySchema)).optional()
|
|
554
1064
|
}).refine((system) => system.label !== void 0 || system.title !== void 0, {
|
|
555
1065
|
path: ["label"],
|
|
556
1066
|
message: "System must provide label or title"
|
|
557
1067
|
}).transform((system) => {
|
|
558
|
-
|
|
1068
|
+
const normalizedSystem = system.systems !== void 0 && system.subsystems === void 0 ? { ...system, subsystems: system.systems } : system;
|
|
1069
|
+
if (normalizedSystem.status === void 0) return normalizedSystem;
|
|
559
1070
|
console.warn("[organization-model] System.status is deprecated; use System.lifecycle instead.");
|
|
560
|
-
return
|
|
1071
|
+
return normalizedSystem.lifecycle === void 0 ? { ...normalizedSystem, lifecycle: normalizedSystem.status } : normalizedSystem;
|
|
561
1072
|
});
|
|
562
1073
|
var SystemsDomainSchema = z.record(z.string(), SystemEntrySchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
|
|
563
1074
|
message: "Each system entry id must match its map key"
|
|
@@ -633,6 +1144,7 @@ z.enum(["workflow", "agent", "integration", "script"]).meta({ label: "Resource k
|
|
|
633
1144
|
var ResourceGovernanceStatusSchema = z.enum(["active", "deprecated", "archived"]).meta({ label: "Governance status", color: "teal" });
|
|
634
1145
|
var AgentKindSchema = z.enum(["orchestrator", "specialist", "utility", "platform"]).meta({ label: "Agent kind", color: "violet" });
|
|
635
1146
|
var ScriptResourceLanguageSchema = z.enum(["shell", "sql", "typescript", "python"]).meta({ label: "Language" });
|
|
1147
|
+
var CodeReferenceRoleSchema = z.enum(["entrypoint", "handler", "schema", "test", "docs", "config"]).meta({ label: "Code reference role", color: "blue" });
|
|
636
1148
|
var ResourceIdSchema = z.string().trim().min(1).max(255).regex(/^[A-Za-z0-9]+(?:[-._][A-Za-z0-9]+)*$/, "Resource IDs must use letters, numbers, -, _, or . separators");
|
|
637
1149
|
var EventIdSchema = z.string().trim().min(1).max(300).regex(
|
|
638
1150
|
/^[A-Za-z0-9]+(?:[-._][A-Za-z0-9]+)*:[a-z0-9]+(?:[-._][a-z0-9]+)*$/,
|
|
@@ -650,6 +1162,28 @@ EventEmissionDescriptorSchema.extend({
|
|
|
650
1162
|
ownerId: z.union([ResourceIdSchema, ModelIdSchema]),
|
|
651
1163
|
ownerKind: z.enum(["resource", "entity"]).meta({ label: "Owner kind" })
|
|
652
1164
|
});
|
|
1165
|
+
var ResourceOntologyBindingSchema = z.object({
|
|
1166
|
+
actions: z.array(OntologyIdSchema).optional(),
|
|
1167
|
+
primaryAction: OntologyIdSchema.optional(),
|
|
1168
|
+
reads: z.array(OntologyIdSchema).optional(),
|
|
1169
|
+
writes: z.array(OntologyIdSchema).optional(),
|
|
1170
|
+
usesCatalogs: z.array(OntologyIdSchema).optional(),
|
|
1171
|
+
emits: z.array(OntologyIdSchema).optional()
|
|
1172
|
+
}).superRefine((binding, ctx) => {
|
|
1173
|
+
if (binding.primaryAction === void 0) return;
|
|
1174
|
+
if (binding.actions?.includes(binding.primaryAction)) return;
|
|
1175
|
+
ctx.addIssue({
|
|
1176
|
+
code: z.ZodIssueCode.custom,
|
|
1177
|
+
path: ["primaryAction"],
|
|
1178
|
+
message: "Resource ontology primaryAction must be included in actions"
|
|
1179
|
+
});
|
|
1180
|
+
});
|
|
1181
|
+
var CodeReferenceSchema = z.object({
|
|
1182
|
+
path: z.string().trim().min(1).max(500).regex(/^[A-Za-z0-9_./$@()[\] -]+$/, "Code reference paths must be repo-relative paths"),
|
|
1183
|
+
role: CodeReferenceRoleSchema,
|
|
1184
|
+
symbol: z.string().trim().min(1).max(200).optional(),
|
|
1185
|
+
description: z.string().trim().min(1).max(300).optional()
|
|
1186
|
+
});
|
|
653
1187
|
var ResourceEntryBaseSchema = z.object({
|
|
654
1188
|
/** Canonical resource id; runtime resourceId derives from this value. */
|
|
655
1189
|
id: ResourceIdSchema,
|
|
@@ -657,14 +1191,24 @@ var ResourceEntryBaseSchema = z.object({
|
|
|
657
1191
|
order: z.number().default(0),
|
|
658
1192
|
/** Required single System membership — value is a dot-separated system path (e.g. "sales.lead-gen"). */
|
|
659
1193
|
systemPath: SystemPathSchema.meta({ ref: "system" }),
|
|
1194
|
+
/** Executable display title owned by the OM Resource descriptor. */
|
|
1195
|
+
title: LabelSchema.optional(),
|
|
1196
|
+
/** Executable display description owned by the OM Resource descriptor. */
|
|
1197
|
+
description: DescriptionSchema.optional(),
|
|
660
1198
|
/** Optional role responsible for maintaining this resource. */
|
|
661
1199
|
ownerRoleId: ModelIdSchema.meta({ ref: "role" }).optional(),
|
|
662
|
-
status: ResourceGovernanceStatusSchema
|
|
1200
|
+
status: ResourceGovernanceStatusSchema,
|
|
1201
|
+
/**
|
|
1202
|
+
* Ontology contract bindings for the semantic work this resource performs.
|
|
1203
|
+
* `emits` stays nested here so top-level resource emits descriptors remain
|
|
1204
|
+
* compatible with graph event projection during the bridge.
|
|
1205
|
+
*/
|
|
1206
|
+
ontology: ResourceOntologyBindingSchema.optional(),
|
|
1207
|
+
/** Repo-relative implementation breadcrumbs for agents and operators. */
|
|
1208
|
+
codeRefs: z.array(CodeReferenceSchema).default([])
|
|
663
1209
|
});
|
|
664
1210
|
var WorkflowResourceEntrySchema = ResourceEntryBaseSchema.extend({
|
|
665
1211
|
kind: z.literal("workflow"),
|
|
666
|
-
/** Mirrors WorkflowConfig.actionKey when the runtime workflow has one. */
|
|
667
|
-
actionKey: z.string().trim().min(1).max(255).optional(),
|
|
668
1212
|
emits: z.array(EventEmissionDescriptorSchema).optional()
|
|
669
1213
|
});
|
|
670
1214
|
var AgentResourceEntrySchema = ResourceEntryBaseSchema.extend({
|
|
@@ -706,6 +1250,9 @@ var ResourcesDomainSchema = z.record(z.string(), ResourceEntrySchema).refine((re
|
|
|
706
1250
|
var DEFAULT_ORGANIZATION_MODEL_RESOURCES = {};
|
|
707
1251
|
|
|
708
1252
|
// ../core/src/organization-model/helpers.ts
|
|
1253
|
+
function childSystemsOf2(system) {
|
|
1254
|
+
return system.systems ?? system.subsystems ?? {};
|
|
1255
|
+
}
|
|
709
1256
|
function defaultPathFor(id) {
|
|
710
1257
|
return `/${id.replaceAll(".", "/")}`;
|
|
711
1258
|
}
|
|
@@ -753,7 +1300,7 @@ function getSystem(model, path) {
|
|
|
753
1300
|
for (const seg of segments) {
|
|
754
1301
|
node = current[seg];
|
|
755
1302
|
if (node === void 0) return void 0;
|
|
756
|
-
current = node
|
|
1303
|
+
current = childSystemsOf2(node);
|
|
757
1304
|
}
|
|
758
1305
|
return node;
|
|
759
1306
|
}
|
|
@@ -765,7 +1312,7 @@ function getSystemAncestors(model, path) {
|
|
|
765
1312
|
const node = current[seg];
|
|
766
1313
|
if (node === void 0) return [];
|
|
767
1314
|
result.push(node);
|
|
768
|
-
current = node
|
|
1315
|
+
current = childSystemsOf2(node);
|
|
769
1316
|
}
|
|
770
1317
|
return result;
|
|
771
1318
|
}
|
|
@@ -775,8 +1322,9 @@ function listAllSystems(model) {
|
|
|
775
1322
|
for (const [localId, system] of Object.entries(map)) {
|
|
776
1323
|
const fullPath = prefix ? `${prefix}.${localId}` : localId;
|
|
777
1324
|
results.push({ path: fullPath, system });
|
|
778
|
-
|
|
779
|
-
|
|
1325
|
+
const childSystems = childSystemsOf2(system);
|
|
1326
|
+
if (Object.keys(childSystems).length > 0) {
|
|
1327
|
+
walk(childSystems, fullPath);
|
|
780
1328
|
}
|
|
781
1329
|
}
|
|
782
1330
|
}
|
|
@@ -792,6 +1340,30 @@ function getContent(model, qualifiedId) {
|
|
|
792
1340
|
const system = getSystem(model, systemPath);
|
|
793
1341
|
return system?.content?.[localId];
|
|
794
1342
|
}
|
|
1343
|
+
function isPlainJsonObject(value) {
|
|
1344
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1345
|
+
}
|
|
1346
|
+
function mergeJsonConfig(base, override) {
|
|
1347
|
+
const result = { ...base };
|
|
1348
|
+
for (const [key, value] of Object.entries(override)) {
|
|
1349
|
+
const existing = result[key];
|
|
1350
|
+
result[key] = isPlainJsonObject(existing) && isPlainJsonObject(value) ? mergeJsonConfig(existing, value) : value;
|
|
1351
|
+
}
|
|
1352
|
+
return result;
|
|
1353
|
+
}
|
|
1354
|
+
function resolveSystemConfig(model, path) {
|
|
1355
|
+
const system = getSystem(model, path);
|
|
1356
|
+
if (system === void 0) return {};
|
|
1357
|
+
let resolved = {};
|
|
1358
|
+
for (const node of Object.values(system.content ?? {})) {
|
|
1359
|
+
if (node.kind !== "config" || node.type !== "kv") continue;
|
|
1360
|
+
const entries = node.data?.entries;
|
|
1361
|
+
if (isPlainJsonObject(entries)) {
|
|
1362
|
+
resolved = mergeJsonConfig(resolved, entries);
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
return mergeJsonConfig(resolved, system.config ?? {});
|
|
1366
|
+
}
|
|
795
1367
|
function getResourcesForSystem(model, systemPath, options = {}) {
|
|
796
1368
|
const { includeDescendants = false } = options;
|
|
797
1369
|
const prefix = systemPath + ".";
|
|
@@ -1843,19 +2415,29 @@ var KnowledgeTargetKindSchema = z.enum([
|
|
|
1843
2415
|
"goal",
|
|
1844
2416
|
"customer-segment",
|
|
1845
2417
|
"offering",
|
|
2418
|
+
"ontology",
|
|
1846
2419
|
// D4: content nodes are a valid knowledge target after compound-domain data moved into system.content
|
|
1847
2420
|
"content-node"
|
|
1848
2421
|
]).meta({ label: "Target kind" });
|
|
1849
2422
|
var KnowledgeTargetRefSchema = z.object({
|
|
1850
2423
|
kind: KnowledgeTargetKindSchema,
|
|
1851
|
-
// D4: content-node targets use a qualified id format '<system-path>:<local-content-id>'
|
|
1852
|
-
//
|
|
1853
|
-
//
|
|
1854
|
-
// OrganizationModelSchema.superRefine (knowledgeTargetExists).
|
|
2424
|
+
// D4: content-node targets use a qualified id format '<system-path>:<local-content-id>'.
|
|
2425
|
+
// Ontology targets use the canonical '<scope>:<kind>/<local-id>' ontology id format.
|
|
2426
|
+
// Business-logic validation of target existence is done in OrganizationModelSchema.superRefine.
|
|
1855
2427
|
id: z.string().trim().min(1).max(300)
|
|
2428
|
+
}).superRefine((target, ctx) => {
|
|
2429
|
+
if (target.kind !== "ontology") return;
|
|
2430
|
+
const result = OntologyIdSchema.safeParse(target.id);
|
|
2431
|
+
if (!result.success) {
|
|
2432
|
+
ctx.addIssue({
|
|
2433
|
+
code: z.ZodIssueCode.custom,
|
|
2434
|
+
path: ["id"],
|
|
2435
|
+
message: "Ontology knowledge targets must use <system-path>:<kind>/<local-id> or global:<kind>/<local-id>"
|
|
2436
|
+
});
|
|
2437
|
+
}
|
|
1856
2438
|
});
|
|
1857
2439
|
var LegacyKnowledgeLinkSchema = z.object({
|
|
1858
|
-
nodeId: NodeIdStringSchema
|
|
2440
|
+
nodeId: z.union([NodeIdStringSchema, z.templateLiteral(["ontology:", OntologyIdSchema])])
|
|
1859
2441
|
});
|
|
1860
2442
|
var CanonicalKnowledgeLinkSchema = z.object({
|
|
1861
2443
|
target: KnowledgeTargetRefSchema
|
|
@@ -1886,6 +2468,8 @@ var OrgKnowledgeNodeSchema = z.object({
|
|
|
1886
2468
|
icon: IconNameSchema.optional(),
|
|
1887
2469
|
/** Canonical documentation URL when body content is a local summary. */
|
|
1888
2470
|
externalUrl: z.string().trim().url().max(500).optional(),
|
|
2471
|
+
/** Optional generated source file path for local MDX-backed knowledge nodes. */
|
|
2472
|
+
sourceFilePath: z.string().trim().min(1).max(500).optional(),
|
|
1889
2473
|
/** Raw MDX string. Phase 2 will introduce a structured block format. */
|
|
1890
2474
|
body: z.string().trim().min(1),
|
|
1891
2475
|
/**
|
|
@@ -1899,6 +2483,73 @@ var OrgKnowledgeNodeSchema = z.object({
|
|
|
1899
2483
|
updatedAt: z.string().trim().min(1).max(50)
|
|
1900
2484
|
});
|
|
1901
2485
|
var KnowledgeDomainSchema = z.record(ModelIdSchema, OrgKnowledgeNodeSchema).default({});
|
|
2486
|
+
var SecretLikeMetadataKeySchema = /(?:secret|password|passwd|token|api[-_]?key|credential|private[-_]?key)/i;
|
|
2487
|
+
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-----)/;
|
|
2488
|
+
z.enum([
|
|
2489
|
+
"system",
|
|
2490
|
+
"resource",
|
|
2491
|
+
"ontology",
|
|
2492
|
+
"policy",
|
|
2493
|
+
"role",
|
|
2494
|
+
"trigger",
|
|
2495
|
+
"humanCheckpoint",
|
|
2496
|
+
"externalResource"
|
|
2497
|
+
]);
|
|
2498
|
+
var OmTopologyRelationshipKindSchema = z.enum(["triggers", "uses", "approval"]);
|
|
2499
|
+
var OmTopologyNodeRefSchema = z.discriminatedUnion("kind", [
|
|
2500
|
+
z.object({ kind: z.literal("system"), id: ModelIdSchema }),
|
|
2501
|
+
z.object({ kind: z.literal("resource"), id: ResourceIdSchema }),
|
|
2502
|
+
z.object({ kind: z.literal("ontology"), id: OntologyIdSchema }),
|
|
2503
|
+
z.object({ kind: z.literal("policy"), id: ModelIdSchema }),
|
|
2504
|
+
z.object({ kind: z.literal("role"), id: ModelIdSchema }),
|
|
2505
|
+
z.object({ kind: z.literal("trigger"), id: ResourceIdSchema }),
|
|
2506
|
+
z.object({ kind: z.literal("humanCheckpoint"), id: ResourceIdSchema }),
|
|
2507
|
+
z.object({ kind: z.literal("externalResource"), id: ResourceIdSchema })
|
|
2508
|
+
]);
|
|
2509
|
+
var OmTopologyMetadataSchema = z.record(z.string().trim().min(1).max(120), JsonValueSchema).superRefine((metadata, ctx) => {
|
|
2510
|
+
function visit(value, path) {
|
|
2511
|
+
if (typeof value === "string" && SecretLikeMetadataValueSchema.test(value)) {
|
|
2512
|
+
ctx.addIssue({
|
|
2513
|
+
code: z.ZodIssueCode.custom,
|
|
2514
|
+
path,
|
|
2515
|
+
message: "Topology metadata must not contain secret-like values"
|
|
2516
|
+
});
|
|
2517
|
+
return;
|
|
2518
|
+
}
|
|
2519
|
+
if (Array.isArray(value)) {
|
|
2520
|
+
value.forEach((entry, index) => visit(entry, [...path, index]));
|
|
2521
|
+
return;
|
|
2522
|
+
}
|
|
2523
|
+
if (typeof value !== "object" || value === null) return;
|
|
2524
|
+
Object.entries(value).forEach(([key, entry]) => {
|
|
2525
|
+
if (SecretLikeMetadataKeySchema.test(key)) {
|
|
2526
|
+
ctx.addIssue({
|
|
2527
|
+
code: z.ZodIssueCode.custom,
|
|
2528
|
+
path: [...path, key],
|
|
2529
|
+
message: `Topology metadata key "${key}" looks secret-like`
|
|
2530
|
+
});
|
|
2531
|
+
}
|
|
2532
|
+
visit(entry, [...path, key]);
|
|
2533
|
+
});
|
|
2534
|
+
}
|
|
2535
|
+
visit(metadata, []);
|
|
2536
|
+
});
|
|
2537
|
+
var OmTopologyRelationshipSchema = z.object({
|
|
2538
|
+
from: OmTopologyNodeRefSchema,
|
|
2539
|
+
kind: OmTopologyRelationshipKindSchema,
|
|
2540
|
+
to: OmTopologyNodeRefSchema,
|
|
2541
|
+
systemPath: SystemPathSchema.optional(),
|
|
2542
|
+
required: z.boolean().optional(),
|
|
2543
|
+
metadata: OmTopologyMetadataSchema.optional()
|
|
2544
|
+
});
|
|
2545
|
+
var OmTopologyDomainSchema = z.object({
|
|
2546
|
+
version: z.literal(1).default(1),
|
|
2547
|
+
relationships: z.record(z.string().trim().min(1).max(255), OmTopologyRelationshipSchema).default({})
|
|
2548
|
+
}).default({ version: 1, relationships: {} });
|
|
2549
|
+
var DEFAULT_ORGANIZATION_MODEL_TOPOLOGY = {
|
|
2550
|
+
version: 1,
|
|
2551
|
+
relationships: {}
|
|
2552
|
+
};
|
|
1902
2553
|
var PolicyIdSchema = ModelIdSchema;
|
|
1903
2554
|
var PolicyApplicabilitySchema = z.object({
|
|
1904
2555
|
systemIds: z.array(ModelIdSchema.meta({ ref: "system" })).default([]),
|
|
@@ -1986,7 +2637,9 @@ z.enum([
|
|
|
1986
2637
|
"roles",
|
|
1987
2638
|
"goals",
|
|
1988
2639
|
"systems",
|
|
2640
|
+
"ontology",
|
|
1989
2641
|
"resources",
|
|
2642
|
+
"topology",
|
|
1990
2643
|
"actions",
|
|
1991
2644
|
"entities",
|
|
1992
2645
|
"policies",
|
|
@@ -2004,7 +2657,9 @@ var DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA = {
|
|
|
2004
2657
|
roles: { version: 1, lastModified: "2026-05-10" },
|
|
2005
2658
|
goals: { version: 1, lastModified: "2026-05-10" },
|
|
2006
2659
|
systems: { version: 1, lastModified: "2026-05-10" },
|
|
2660
|
+
ontology: { version: 1, lastModified: "2026-05-14" },
|
|
2007
2661
|
resources: { version: 1, lastModified: "2026-05-10" },
|
|
2662
|
+
topology: { version: 1, lastModified: "2026-05-14" },
|
|
2008
2663
|
actions: { version: 1, lastModified: "2026-05-10" },
|
|
2009
2664
|
entities: { version: 1, lastModified: "2026-05-10" },
|
|
2010
2665
|
policies: { version: 1, lastModified: "2026-05-10" },
|
|
@@ -2018,7 +2673,9 @@ var OrganizationModelDomainMetadataByDomainSchema = z.object({
|
|
|
2018
2673
|
roles: OrganizationModelDomainMetadataSchema,
|
|
2019
2674
|
goals: OrganizationModelDomainMetadataSchema,
|
|
2020
2675
|
systems: OrganizationModelDomainMetadataSchema,
|
|
2676
|
+
ontology: OrganizationModelDomainMetadataSchema,
|
|
2021
2677
|
resources: OrganizationModelDomainMetadataSchema,
|
|
2678
|
+
topology: OrganizationModelDomainMetadataSchema,
|
|
2022
2679
|
actions: OrganizationModelDomainMetadataSchema,
|
|
2023
2680
|
entities: OrganizationModelDomainMetadataSchema,
|
|
2024
2681
|
policies: OrganizationModelDomainMetadataSchema,
|
|
@@ -2035,7 +2692,9 @@ var OrganizationModelSchemaBase = z.object({
|
|
|
2035
2692
|
roles: RolesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ROLES),
|
|
2036
2693
|
goals: GoalsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_GOALS),
|
|
2037
2694
|
systems: SystemsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_SYSTEMS),
|
|
2695
|
+
ontology: OntologyScopeSchema.default(DEFAULT_ONTOLOGY_SCOPE),
|
|
2038
2696
|
resources: ResourcesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_RESOURCES),
|
|
2697
|
+
topology: OmTopologyDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_TOPOLOGY),
|
|
2039
2698
|
actions: ActionsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ACTIONS),
|
|
2040
2699
|
entities: EntitiesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ENTITIES),
|
|
2041
2700
|
policies: PoliciesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_POLICIES),
|
|
@@ -2062,13 +2721,16 @@ function asRoleHolderArray(heldBy) {
|
|
|
2062
2721
|
function isKnowledgeKindCompatibleWithTarget(knowledgeKind, targetKind) {
|
|
2063
2722
|
if (knowledgeKind === "reference") return true;
|
|
2064
2723
|
if (knowledgeKind === "playbook") {
|
|
2065
|
-
return ["system", "resource", "stage", "action"].includes(targetKind);
|
|
2724
|
+
return ["system", "resource", "stage", "action", "ontology"].includes(targetKind);
|
|
2066
2725
|
}
|
|
2067
2726
|
if (knowledgeKind === "strategy") {
|
|
2068
|
-
return ["system", "goal", "offering", "customer-segment"].includes(targetKind);
|
|
2727
|
+
return ["system", "goal", "offering", "customer-segment", "ontology"].includes(targetKind);
|
|
2069
2728
|
}
|
|
2070
2729
|
return false;
|
|
2071
2730
|
}
|
|
2731
|
+
function isRecord(value) {
|
|
2732
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2733
|
+
}
|
|
2072
2734
|
var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ctx) => {
|
|
2073
2735
|
function collectAllSystems(systems, prefix = "", schemaPath = ["systems"]) {
|
|
2074
2736
|
const result = [];
|
|
@@ -2076,8 +2738,11 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
|
|
|
2076
2738
|
const path = prefix ? `${prefix}.${key}` : key;
|
|
2077
2739
|
const currentSchemaPath = [...schemaPath, key];
|
|
2078
2740
|
result.push({ path, schemaPath: currentSchemaPath, system });
|
|
2079
|
-
|
|
2080
|
-
|
|
2741
|
+
const childSystems = system.systems ?? system.subsystems;
|
|
2742
|
+
if (childSystems !== void 0) {
|
|
2743
|
+
result.push(
|
|
2744
|
+
...collectAllSystems(childSystems, path, [...currentSchemaPath, system.systems !== void 0 ? "systems" : "subsystems"])
|
|
2745
|
+
);
|
|
2081
2746
|
}
|
|
2082
2747
|
}
|
|
2083
2748
|
return result;
|
|
@@ -2097,7 +2762,7 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
|
|
|
2097
2762
|
`System "${system.id}" references unknown parent "${system.parentSystemId}"`
|
|
2098
2763
|
);
|
|
2099
2764
|
}
|
|
2100
|
-
const hasChildren = Object.keys(system.subsystems ?? {}).length > 0 || allSystems.some((candidate) => candidate.path.startsWith(`${path}.`) && !candidate.path.slice(path.length + 1).includes("."));
|
|
2765
|
+
const hasChildren = Object.keys(system.systems ?? system.subsystems ?? {}).length > 0 || allSystems.some((candidate) => candidate.path.startsWith(`${path}.`) && !candidate.path.slice(path.length + 1).includes("."));
|
|
2101
2766
|
const contributesRoutePath = system.ui?.path !== void 0 || system.path !== void 0 || !hasChildren;
|
|
2102
2767
|
if (contributesRoutePath) {
|
|
2103
2768
|
const effectivePath = system.ui?.path ?? system.path ?? defaultSystemPathFor(path);
|
|
@@ -2113,7 +2778,7 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
|
|
|
2113
2778
|
}
|
|
2114
2779
|
}
|
|
2115
2780
|
if (hasChildren && isLifecycleEnabled(system.lifecycle, system.enabled)) {
|
|
2116
|
-
const hasEnabledDescendant = Object.values(system.subsystems ?? {}).some(
|
|
2781
|
+
const hasEnabledDescendant = Object.values(system.systems ?? system.subsystems ?? {}).some(
|
|
2117
2782
|
(candidate) => isLifecycleEnabled(candidate.lifecycle, candidate.enabled)
|
|
2118
2783
|
) || allSystems.some(
|
|
2119
2784
|
(candidate) => candidate.path.startsWith(`${path}.`) && !candidate.path.slice(path.length + 1).includes(".") && isLifecycleEnabled(candidate.system.lifecycle, candidate.system.enabled)
|
|
@@ -2358,6 +3023,79 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
|
|
|
2358
3023
|
const stageIds = /* @__PURE__ */ new Set();
|
|
2359
3024
|
const actionIds = new Set(Object.keys(model.actions));
|
|
2360
3025
|
const offeringsById = new Map(Object.entries(model.offerings));
|
|
3026
|
+
const ontologyCompilation = compileOrganizationOntology(model);
|
|
3027
|
+
const ontologyIndexByKind = {
|
|
3028
|
+
object: ontologyCompilation.ontology.objectTypes,
|
|
3029
|
+
link: ontologyCompilation.ontology.linkTypes,
|
|
3030
|
+
action: ontologyCompilation.ontology.actionTypes,
|
|
3031
|
+
catalog: ontologyCompilation.ontology.catalogTypes,
|
|
3032
|
+
event: ontologyCompilation.ontology.eventTypes,
|
|
3033
|
+
interface: ontologyCompilation.ontology.interfaceTypes,
|
|
3034
|
+
"value-type": ontologyCompilation.ontology.valueTypes,
|
|
3035
|
+
property: ontologyCompilation.ontology.sharedProperties,
|
|
3036
|
+
group: ontologyCompilation.ontology.groups,
|
|
3037
|
+
surface: ontologyCompilation.ontology.surfaces
|
|
3038
|
+
};
|
|
3039
|
+
const ontologyIds = new Set(Object.values(ontologyIndexByKind).flatMap((index) => Object.keys(index)));
|
|
3040
|
+
function topologyTargetExists(ref) {
|
|
3041
|
+
if (ref.kind === "system") return systemsById.has(ref.id);
|
|
3042
|
+
if (ref.kind === "resource") return resourcesById.has(ref.id);
|
|
3043
|
+
if (ref.kind === "ontology") return ontologyIds.has(ref.id);
|
|
3044
|
+
if (ref.kind === "policy") return policiesById.has(ref.id);
|
|
3045
|
+
if (ref.kind === "role") return rolesById.has(ref.id);
|
|
3046
|
+
return true;
|
|
3047
|
+
}
|
|
3048
|
+
Object.entries(model.topology.relationships).forEach(([relationshipId, relationship]) => {
|
|
3049
|
+
["from", "to"].forEach((side) => {
|
|
3050
|
+
const ref = relationship[side];
|
|
3051
|
+
if (topologyTargetExists(ref)) return;
|
|
3052
|
+
addIssue(
|
|
3053
|
+
ctx,
|
|
3054
|
+
["topology", "relationships", relationshipId, side],
|
|
3055
|
+
`Topology relationship "${relationshipId}" ${side} references unknown ${ref.kind} "${ref.id}"`
|
|
3056
|
+
);
|
|
3057
|
+
});
|
|
3058
|
+
});
|
|
3059
|
+
const ontologyReferenceKeyKinds = {
|
|
3060
|
+
valueType: "value-type",
|
|
3061
|
+
catalogType: "catalog",
|
|
3062
|
+
objectType: "object",
|
|
3063
|
+
eventType: "event",
|
|
3064
|
+
actionType: "action",
|
|
3065
|
+
linkType: "link",
|
|
3066
|
+
interfaceType: "interface",
|
|
3067
|
+
propertyType: "property",
|
|
3068
|
+
groupType: "group",
|
|
3069
|
+
surfaceType: "surface",
|
|
3070
|
+
stepCatalog: "catalog"
|
|
3071
|
+
};
|
|
3072
|
+
function validateKnownOntologyReferences(ownerId, value, path, seen = /* @__PURE__ */ new WeakSet()) {
|
|
3073
|
+
if (Array.isArray(value)) {
|
|
3074
|
+
value.forEach((entry, index) => validateKnownOntologyReferences(ownerId, entry, [...path, index], seen));
|
|
3075
|
+
return;
|
|
3076
|
+
}
|
|
3077
|
+
if (!isRecord(value)) return;
|
|
3078
|
+
if (seen.has(value)) return;
|
|
3079
|
+
seen.add(value);
|
|
3080
|
+
Object.entries(value).forEach(([key, entry]) => {
|
|
3081
|
+
const expectedKind = ontologyReferenceKeyKinds[key];
|
|
3082
|
+
if (expectedKind !== void 0) {
|
|
3083
|
+
if (typeof entry !== "string") {
|
|
3084
|
+
addIssue(ctx, [...path, key], `Ontology record "${ownerId}" ${key} must be an ontology ID string`);
|
|
3085
|
+
} else if (ontologyIndexByKind[expectedKind][entry] === void 0) {
|
|
3086
|
+
addIssue(
|
|
3087
|
+
ctx,
|
|
3088
|
+
[...path, key],
|
|
3089
|
+
`Ontology record "${ownerId}" ${key} references unknown ${expectedKind} ontology ID "${entry}"`
|
|
3090
|
+
);
|
|
3091
|
+
}
|
|
3092
|
+
}
|
|
3093
|
+
validateKnownOntologyReferences(ownerId, entry, [...path, key], seen);
|
|
3094
|
+
});
|
|
3095
|
+
}
|
|
3096
|
+
for (const { id, record } of listResolvedOntologyRecords(ontologyCompilation.ontology)) {
|
|
3097
|
+
validateKnownOntologyReferences(id, record, record.origin.path);
|
|
3098
|
+
}
|
|
2361
3099
|
Object.values(model.policies).forEach((policy) => {
|
|
2362
3100
|
policy.appliesTo.systemIds.forEach((systemId, systemIndex) => {
|
|
2363
3101
|
if (!systemsById.has(systemId)) {
|
|
@@ -2411,6 +3149,7 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
|
|
|
2411
3149
|
if (kind === "goal") return goalsById.has(id);
|
|
2412
3150
|
if (kind === "customer-segment") return segmentsById.has(id);
|
|
2413
3151
|
if (kind === "offering") return offeringsById.has(id);
|
|
3152
|
+
if (kind === "ontology") return ontologyIds.has(id);
|
|
2414
3153
|
return false;
|
|
2415
3154
|
}
|
|
2416
3155
|
Object.entries(model.knowledge).forEach(([nodeId2, node]) => {
|
|
@@ -2454,6 +3193,34 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
|
|
|
2454
3193
|
);
|
|
2455
3194
|
}
|
|
2456
3195
|
});
|
|
3196
|
+
function validateResourceOntologyBinding(resourceId, bindingKey, expectedKind, ids) {
|
|
3197
|
+
const ontologyIds2 = ids === void 0 ? [] : Array.isArray(ids) ? ids : [ids];
|
|
3198
|
+
ontologyIds2.forEach((ontologyId, ontologyIndex) => {
|
|
3199
|
+
if (ontologyIndexByKind[expectedKind][ontologyId] === void 0) {
|
|
3200
|
+
addIssue(
|
|
3201
|
+
ctx,
|
|
3202
|
+
[
|
|
3203
|
+
"resources",
|
|
3204
|
+
resourceId,
|
|
3205
|
+
"ontology",
|
|
3206
|
+
bindingKey,
|
|
3207
|
+
...Array.isArray(ids) ? [ontologyIndex] : []
|
|
3208
|
+
],
|
|
3209
|
+
`Resource "${resourceId}" ontology binding "${bindingKey}" references unknown ${expectedKind} ontology ID "${ontologyId}"`
|
|
3210
|
+
);
|
|
3211
|
+
}
|
|
3212
|
+
});
|
|
3213
|
+
}
|
|
3214
|
+
Object.values(model.resources).forEach((resource) => {
|
|
3215
|
+
const binding = resource.ontology;
|
|
3216
|
+
if (binding === void 0) return;
|
|
3217
|
+
validateResourceOntologyBinding(resource.id, "actions", "action", binding.actions);
|
|
3218
|
+
validateResourceOntologyBinding(resource.id, "primaryAction", "action", binding.primaryAction);
|
|
3219
|
+
validateResourceOntologyBinding(resource.id, "reads", "object", binding.reads);
|
|
3220
|
+
validateResourceOntologyBinding(resource.id, "writes", "object", binding.writes);
|
|
3221
|
+
validateResourceOntologyBinding(resource.id, "usesCatalogs", "catalog", binding.usesCatalogs);
|
|
3222
|
+
validateResourceOntologyBinding(resource.id, "emits", "event", binding.emits);
|
|
3223
|
+
});
|
|
2457
3224
|
Object.values(model.roles).forEach((role) => {
|
|
2458
3225
|
if (role.heldBy === void 0) return;
|
|
2459
3226
|
asRoleHolderArray(role.heldBy).forEach((holder, holderIndex) => {
|
|
@@ -2488,11 +3255,13 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
|
|
|
2488
3255
|
});
|
|
2489
3256
|
});
|
|
2490
3257
|
function validateSystemContent(system, systemPath) {
|
|
3258
|
+
const childSystems = system.systems ?? system.subsystems;
|
|
3259
|
+
const childKey = system.systems !== void 0 ? "systems" : "subsystems";
|
|
2491
3260
|
const content = system.content;
|
|
2492
3261
|
if (content === void 0 || Object.keys(content).length === 0) {
|
|
2493
|
-
if (
|
|
2494
|
-
Object.entries(
|
|
2495
|
-
validateSystemContent(child, [...systemPath,
|
|
3262
|
+
if (childSystems !== void 0) {
|
|
3263
|
+
Object.entries(childSystems).forEach(([childLocalId, child]) => {
|
|
3264
|
+
validateSystemContent(child, [...systemPath, childKey, childLocalId]);
|
|
2496
3265
|
});
|
|
2497
3266
|
}
|
|
2498
3267
|
return;
|
|
@@ -2548,15 +3317,18 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
|
|
|
2548
3317
|
}
|
|
2549
3318
|
}
|
|
2550
3319
|
});
|
|
2551
|
-
if (
|
|
2552
|
-
Object.entries(
|
|
2553
|
-
validateSystemContent(child, [...systemPath,
|
|
3320
|
+
if (childSystems !== void 0) {
|
|
3321
|
+
Object.entries(childSystems).forEach(([childLocalId, child]) => {
|
|
3322
|
+
validateSystemContent(child, [...systemPath, childKey, childLocalId]);
|
|
2554
3323
|
});
|
|
2555
3324
|
}
|
|
2556
3325
|
}
|
|
2557
3326
|
Object.entries(model.systems).forEach(([systemKey, system]) => {
|
|
2558
3327
|
validateSystemContent(system, ["systems", systemKey]);
|
|
2559
3328
|
});
|
|
3329
|
+
for (const diagnostic of ontologyCompilation.diagnostics) {
|
|
3330
|
+
addIssue(ctx, diagnostic.path, diagnostic.message);
|
|
3331
|
+
}
|
|
2560
3332
|
});
|
|
2561
3333
|
|
|
2562
3334
|
// ../core/src/organization-model/graph/schema.ts
|
|
@@ -2577,6 +3349,7 @@ var OrganizationGraphNodeKindSchema = z.enum([
|
|
|
2577
3349
|
"surface",
|
|
2578
3350
|
"navigation-group",
|
|
2579
3351
|
// Phase 3 preview — Phase 4 populates via graph projection of system.content entries.
|
|
3352
|
+
"ontology",
|
|
2580
3353
|
"content-node"
|
|
2581
3354
|
]);
|
|
2582
3355
|
var OrganizationGraphEdgeKindSchema = z.enum([
|
|
@@ -2590,24 +3363,30 @@ var OrganizationGraphEdgeKindSchema = z.enum([
|
|
|
2590
3363
|
"emits",
|
|
2591
3364
|
"originates_from",
|
|
2592
3365
|
"triggers",
|
|
3366
|
+
"approval",
|
|
2593
3367
|
"applies_to",
|
|
2594
|
-
"effects"
|
|
3368
|
+
"effects",
|
|
3369
|
+
"actions",
|
|
3370
|
+
"reads",
|
|
3371
|
+
"writes",
|
|
3372
|
+
"uses_catalog"
|
|
2595
3373
|
]);
|
|
2596
3374
|
var OrganizationGraphNodeSchema = z.object({
|
|
2597
|
-
id: z.string().trim().min(1).max(
|
|
3375
|
+
id: z.string().trim().min(1).max(400),
|
|
2598
3376
|
kind: OrganizationGraphNodeKindSchema,
|
|
2599
3377
|
label: LabelSchema,
|
|
2600
|
-
sourceId: z.string().trim().min(1).max(
|
|
3378
|
+
sourceId: z.string().trim().min(1).max(400).optional(),
|
|
2601
3379
|
description: DescriptionSchema.optional(),
|
|
2602
3380
|
icon: IconNameSchema.optional(),
|
|
2603
3381
|
enabled: z.boolean().optional(),
|
|
3382
|
+
ontologyKind: z.string().trim().min(1).max(80).optional(),
|
|
2604
3383
|
resourceType: z.enum(["workflow", "agent", "trigger", "integration", "external", "human_checkpoint", "script"]).optional()
|
|
2605
3384
|
});
|
|
2606
3385
|
var OrganizationGraphEdgeSchema = z.object({
|
|
2607
|
-
id: z.string().trim().min(1).max(
|
|
3386
|
+
id: z.string().trim().min(1).max(900),
|
|
2608
3387
|
kind: OrganizationGraphEdgeKindSchema,
|
|
2609
|
-
sourceId: z.string().trim().min(1).max(
|
|
2610
|
-
targetId: z.string().trim().min(1).max(
|
|
3388
|
+
sourceId: z.string().trim().min(1).max(400),
|
|
3389
|
+
targetId: z.string().trim().min(1).max(400),
|
|
2611
3390
|
label: z.string().trim().min(1).max(120).optional(),
|
|
2612
3391
|
relationshipType: z.enum(["triggers", "uses", "approval"]).optional()
|
|
2613
3392
|
});
|
|
@@ -2668,7 +3447,7 @@ function getAllBuildTemplates(model) {
|
|
|
2668
3447
|
label: s.label ?? stepLocalId,
|
|
2669
3448
|
...s.description ? { description: s.description } : {},
|
|
2670
3449
|
// Pass through all data fields — template-step payload is richer than Pipeline;
|
|
2671
|
-
//
|
|
3450
|
+
// Bridge readers preserve the historical shape for round-trip fidelity.
|
|
2672
3451
|
...sd
|
|
2673
3452
|
};
|
|
2674
3453
|
});
|
|
@@ -2832,6 +3611,20 @@ function invocationLabel(invocation) {
|
|
|
2832
3611
|
function eventNodeId(eventId) {
|
|
2833
3612
|
return nodeId("event", eventId);
|
|
2834
3613
|
}
|
|
3614
|
+
function ontologyLabel(id, label) {
|
|
3615
|
+
return label ?? parseOntologyId(id).localId;
|
|
3616
|
+
}
|
|
3617
|
+
function pushOntologyBindingEdges(edges, edgeIds, resourceNodeId, kind, ids) {
|
|
3618
|
+
ids?.forEach((ontologyId) => {
|
|
3619
|
+
const targetId = ontologyGraphNodeId(ontologyId);
|
|
3620
|
+
pushUniqueEdge(edges, edgeIds, {
|
|
3621
|
+
id: edgeId(kind, resourceNodeId, targetId),
|
|
3622
|
+
kind,
|
|
3623
|
+
sourceId: resourceNodeId,
|
|
3624
|
+
targetId
|
|
3625
|
+
});
|
|
3626
|
+
});
|
|
3627
|
+
}
|
|
2835
3628
|
function buildResourceEventDescriptor(resourceId, emission) {
|
|
2836
3629
|
return {
|
|
2837
3630
|
...emission,
|
|
@@ -2879,6 +3672,7 @@ function buildOrganizationGraph(input) {
|
|
|
2879
3672
|
const organizationModelResourceIds = new Set(Object.keys(organizationModel.resources));
|
|
2880
3673
|
const actionIdsByInvocation = /* @__PURE__ */ new Map();
|
|
2881
3674
|
const projectedEventNodeIdsByEventId = /* @__PURE__ */ new Map();
|
|
3675
|
+
const ontologyCompilation = compileOrganizationOntology(organizationModel);
|
|
2882
3676
|
const organizationNode = {
|
|
2883
3677
|
id: nodeId("organization"),
|
|
2884
3678
|
kind: "organization",
|
|
@@ -2893,6 +3687,32 @@ function buildOrganizationGraph(input) {
|
|
|
2893
3687
|
}
|
|
2894
3688
|
const validSystemRefs = new Set(systemPathByRef.keys());
|
|
2895
3689
|
const systemNodeId = (systemRef) => nodeId("system", systemPathByRef.get(systemRef) ?? systemRef);
|
|
3690
|
+
function topologyNodeId(ref) {
|
|
3691
|
+
if (ref.kind === "system") return systemNodeId(ref.id);
|
|
3692
|
+
if (ref.kind === "resource") return nodeId("resource", ref.id);
|
|
3693
|
+
if (ref.kind === "ontology") return ontologyGraphNodeId(ref.id);
|
|
3694
|
+
if (ref.kind === "policy") return nodeId("policy", ref.id);
|
|
3695
|
+
if (ref.kind === "role") return nodeId("role", ref.id);
|
|
3696
|
+
return nodeId("resource", ref.id);
|
|
3697
|
+
}
|
|
3698
|
+
function ensureTopologyNode(ref) {
|
|
3699
|
+
const id = topologyNodeId(ref);
|
|
3700
|
+
if (nodeIds.has(id)) return id;
|
|
3701
|
+
if (ref.kind === "resource") {
|
|
3702
|
+
ensureResourceNode(nodes, nodeIds, resourceNodesById, ref.id);
|
|
3703
|
+
return id;
|
|
3704
|
+
}
|
|
3705
|
+
if (ref.kind === "trigger" || ref.kind === "humanCheckpoint" || ref.kind === "externalResource") {
|
|
3706
|
+
pushUniqueNode(nodes, nodeIds, {
|
|
3707
|
+
id,
|
|
3708
|
+
kind: "resource",
|
|
3709
|
+
label: ref.id,
|
|
3710
|
+
sourceId: ref.id,
|
|
3711
|
+
resourceType: ref.kind === "trigger" ? "trigger" : ref.kind === "humanCheckpoint" ? "human_checkpoint" : "external"
|
|
3712
|
+
});
|
|
3713
|
+
}
|
|
3714
|
+
return id;
|
|
3715
|
+
}
|
|
2896
3716
|
for (const { path, system } of systemsWithPaths.sort((a, b) => a.path.localeCompare(b.path))) {
|
|
2897
3717
|
const id = nodeId("system", path);
|
|
2898
3718
|
pushUniqueNode(nodes, nodeIds, {
|
|
@@ -2920,6 +3740,78 @@ function buildOrganizationGraph(input) {
|
|
|
2920
3740
|
});
|
|
2921
3741
|
}
|
|
2922
3742
|
}
|
|
3743
|
+
for (const { id: ontologyId, kind, record } of listResolvedOntologyRecords(ontologyCompilation.ontology).sort(
|
|
3744
|
+
(a, b) => a.id.localeCompare(b.id)
|
|
3745
|
+
)) {
|
|
3746
|
+
const id = ontologyGraphNodeId(ontologyId);
|
|
3747
|
+
const parsedId = parseOntologyId(ontologyId);
|
|
3748
|
+
pushUniqueNode(nodes, nodeIds, {
|
|
3749
|
+
id,
|
|
3750
|
+
kind: "ontology",
|
|
3751
|
+
label: ontologyLabel(ontologyId, record.label),
|
|
3752
|
+
sourceId: ontologyId,
|
|
3753
|
+
description: record.description,
|
|
3754
|
+
ontologyKind: kind
|
|
3755
|
+
});
|
|
3756
|
+
const ownerSystemId = record.ownerSystemId ?? (parsedId.isGlobal ? void 0 : parsedId.scope);
|
|
3757
|
+
if (ownerSystemId !== void 0 && validSystemRefs.has(ownerSystemId)) {
|
|
3758
|
+
pushUniqueEdge(edges, edgeIds, {
|
|
3759
|
+
id: edgeId("contains", systemNodeId(ownerSystemId), id, `ontology-${kind}`),
|
|
3760
|
+
kind: "contains",
|
|
3761
|
+
sourceId: systemNodeId(ownerSystemId),
|
|
3762
|
+
targetId: id
|
|
3763
|
+
});
|
|
3764
|
+
} else {
|
|
3765
|
+
pushUniqueEdge(edges, edgeIds, {
|
|
3766
|
+
id: edgeId("contains", organizationNode.id, id, `ontology-${kind}`),
|
|
3767
|
+
kind: "contains",
|
|
3768
|
+
sourceId: organizationNode.id,
|
|
3769
|
+
targetId: id
|
|
3770
|
+
});
|
|
3771
|
+
}
|
|
3772
|
+
if (kind === "link") {
|
|
3773
|
+
const link = record;
|
|
3774
|
+
pushUniqueEdge(edges, edgeIds, {
|
|
3775
|
+
id: edgeId("links", ontologyGraphNodeId(link.from), ontologyGraphNodeId(link.to), ontologyId),
|
|
3776
|
+
kind: "links",
|
|
3777
|
+
sourceId: ontologyGraphNodeId(link.from),
|
|
3778
|
+
targetId: ontologyGraphNodeId(link.to),
|
|
3779
|
+
label: link.label ?? parsedId.localId
|
|
3780
|
+
});
|
|
3781
|
+
}
|
|
3782
|
+
if (kind === "action") {
|
|
3783
|
+
const action = record;
|
|
3784
|
+
for (const targetOntologyId of action.actsOn ?? []) {
|
|
3785
|
+
pushUniqueEdge(edges, edgeIds, {
|
|
3786
|
+
id: edgeId("affects", id, ontologyGraphNodeId(targetOntologyId), ontologyId),
|
|
3787
|
+
kind: "affects",
|
|
3788
|
+
sourceId: id,
|
|
3789
|
+
targetId: ontologyGraphNodeId(targetOntologyId)
|
|
3790
|
+
});
|
|
3791
|
+
}
|
|
3792
|
+
}
|
|
3793
|
+
if (kind === "catalog") {
|
|
3794
|
+
const catalog = record;
|
|
3795
|
+
if (catalog.appliesTo === void 0) continue;
|
|
3796
|
+
pushUniqueEdge(edges, edgeIds, {
|
|
3797
|
+
id: edgeId("applies_to", id, ontologyGraphNodeId(catalog.appliesTo), ontologyId),
|
|
3798
|
+
kind: "applies_to",
|
|
3799
|
+
sourceId: id,
|
|
3800
|
+
targetId: ontologyGraphNodeId(catalog.appliesTo)
|
|
3801
|
+
});
|
|
3802
|
+
}
|
|
3803
|
+
if (kind === "group") {
|
|
3804
|
+
const group = record;
|
|
3805
|
+
for (const memberOntologyId of group.members ?? []) {
|
|
3806
|
+
pushUniqueEdge(edges, edgeIds, {
|
|
3807
|
+
id: edgeId("contains", id, ontologyGraphNodeId(memberOntologyId), ontologyId),
|
|
3808
|
+
kind: "contains",
|
|
3809
|
+
sourceId: id,
|
|
3810
|
+
targetId: ontologyGraphNodeId(memberOntologyId)
|
|
3811
|
+
});
|
|
3812
|
+
}
|
|
3813
|
+
}
|
|
3814
|
+
}
|
|
2923
3815
|
for (const role of Object.values(organizationModel.roles).sort((a, b) => a.id.localeCompare(b.id))) {
|
|
2924
3816
|
const id = nodeId("role", role.id);
|
|
2925
3817
|
pushUniqueNode(nodes, nodeIds, {
|
|
@@ -2971,7 +3863,7 @@ function buildOrganizationGraph(input) {
|
|
|
2971
3863
|
targetId: id
|
|
2972
3864
|
});
|
|
2973
3865
|
for (const link of node.links) {
|
|
2974
|
-
const targetId = link.target.kind === "system" ? systemNodeId(link.target.id) : link.nodeId;
|
|
3866
|
+
const targetId = link.target.kind === "system" ? systemNodeId(link.target.id) : link.target.kind === "ontology" ? ontologyGraphNodeId(link.target.id) : link.nodeId;
|
|
2975
3867
|
pushUniqueEdge(edges, edgeIds, {
|
|
2976
3868
|
id: edgeId("governs", id, targetId),
|
|
2977
3869
|
kind: "governs",
|
|
@@ -3136,6 +4028,11 @@ function buildOrganizationGraph(input) {
|
|
|
3136
4028
|
targetId: resourceNode.id
|
|
3137
4029
|
});
|
|
3138
4030
|
}
|
|
4031
|
+
pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, "actions", resource.ontology?.actions);
|
|
4032
|
+
pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, "reads", resource.ontology?.reads);
|
|
4033
|
+
pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, "writes", resource.ontology?.writes);
|
|
4034
|
+
pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, "uses_catalog", resource.ontology?.usesCatalogs);
|
|
4035
|
+
pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, "emits", resource.ontology?.emits);
|
|
3139
4036
|
if (resource.kind === "workflow" || resource.kind === "agent") {
|
|
3140
4037
|
for (const emission of resource.emits ?? []) {
|
|
3141
4038
|
pushEventProjection(
|
|
@@ -3265,6 +4162,19 @@ function buildOrganizationGraph(input) {
|
|
|
3265
4162
|
}
|
|
3266
4163
|
}
|
|
3267
4164
|
}
|
|
4165
|
+
for (const [relationshipId, relationship] of Object.entries(organizationModel.topology.relationships).sort(
|
|
4166
|
+
([a], [b]) => a.localeCompare(b)
|
|
4167
|
+
)) {
|
|
4168
|
+
const sourceId = ensureTopologyNode(relationship.from);
|
|
4169
|
+
const targetId = ensureTopologyNode(relationship.to);
|
|
4170
|
+
pushUniqueEdge(edges, edgeIds, {
|
|
4171
|
+
id: edgeId(relationship.kind, sourceId, targetId, `topology-${relationshipId}`),
|
|
4172
|
+
kind: relationship.kind,
|
|
4173
|
+
sourceId,
|
|
4174
|
+
targetId,
|
|
4175
|
+
relationshipType: relationship.kind
|
|
4176
|
+
});
|
|
4177
|
+
}
|
|
3268
4178
|
for (const segment of Object.values(organizationModel.customers).sort(
|
|
3269
4179
|
(a, b) => a.order - b.order || a.id.localeCompare(b.id)
|
|
3270
4180
|
)) {
|
|
@@ -3510,14 +4420,14 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
|
|
|
3510
4420
|
label: "Dashboard",
|
|
3511
4421
|
path: "/",
|
|
3512
4422
|
surfaceType: "dashboard",
|
|
3513
|
-
icon: "
|
|
4423
|
+
icon: "dashboard",
|
|
3514
4424
|
order: 10,
|
|
3515
4425
|
targets: { systems: ["dashboard"] }
|
|
3516
4426
|
},
|
|
3517
4427
|
business: {
|
|
3518
4428
|
type: "group",
|
|
3519
4429
|
label: "Business",
|
|
3520
|
-
icon: "
|
|
4430
|
+
icon: "business",
|
|
3521
4431
|
order: 20,
|
|
3522
4432
|
children: {
|
|
3523
4433
|
sales: {
|
|
@@ -3525,7 +4435,7 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
|
|
|
3525
4435
|
label: "Sales",
|
|
3526
4436
|
path: "/sales",
|
|
3527
4437
|
surfaceType: "page",
|
|
3528
|
-
icon: "
|
|
4438
|
+
icon: "sales",
|
|
3529
4439
|
order: 10,
|
|
3530
4440
|
targets: { systems: ["sales"] }
|
|
3531
4441
|
},
|
|
@@ -3534,7 +4444,7 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
|
|
|
3534
4444
|
label: "Clients",
|
|
3535
4445
|
path: "/clients",
|
|
3536
4446
|
surfaceType: "list",
|
|
3537
|
-
icon: "
|
|
4447
|
+
icon: "projects",
|
|
3538
4448
|
order: 20,
|
|
3539
4449
|
targets: { systems: ["clients"] }
|
|
3540
4450
|
},
|
|
@@ -3543,7 +4453,7 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
|
|
|
3543
4453
|
label: "Projects",
|
|
3544
4454
|
path: "/projects",
|
|
3545
4455
|
surfaceType: "page",
|
|
3546
|
-
icon: "
|
|
4456
|
+
icon: "projects",
|
|
3547
4457
|
order: 30,
|
|
3548
4458
|
targets: { systems: ["projects"] }
|
|
3549
4459
|
}
|
|
@@ -3552,7 +4462,7 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
|
|
|
3552
4462
|
operations: {
|
|
3553
4463
|
type: "group",
|
|
3554
4464
|
label: "Operations",
|
|
3555
|
-
icon: "
|
|
4465
|
+
icon: "operations",
|
|
3556
4466
|
order: 30,
|
|
3557
4467
|
children: {
|
|
3558
4468
|
"operations-overview": {
|
|
@@ -3600,7 +4510,7 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
|
|
|
3600
4510
|
monitoring: {
|
|
3601
4511
|
type: "group",
|
|
3602
4512
|
label: "Monitoring",
|
|
3603
|
-
icon: "
|
|
4513
|
+
icon: "monitoring",
|
|
3604
4514
|
order: 40,
|
|
3605
4515
|
children: {
|
|
3606
4516
|
"monitoring-overview": {
|
|
@@ -3662,36 +4572,19 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
|
|
|
3662
4572
|
}
|
|
3663
4573
|
},
|
|
3664
4574
|
knowledge: {
|
|
3665
|
-
type: "
|
|
3666
|
-
label: "Knowledge",
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
type: "surface",
|
|
3672
|
-
label: "Knowledge Base",
|
|
3673
|
-
path: "/knowledge",
|
|
3674
|
-
surfaceType: "page",
|
|
3675
|
-
order: 10,
|
|
3676
|
-
targets: { systems: ["knowledge.base"] }
|
|
3677
|
-
},
|
|
3678
|
-
"knowledge-command-view": {
|
|
3679
|
-
type: "surface",
|
|
3680
|
-
label: "Command View",
|
|
3681
|
-
path: "/knowledge/command-view",
|
|
3682
|
-
surfaceType: "graph",
|
|
3683
|
-
order: 20,
|
|
3684
|
-
targets: { systems: ["knowledge.command-view"] },
|
|
3685
|
-
devOnly: true
|
|
3686
|
-
}
|
|
3687
|
-
}
|
|
4575
|
+
type: "surface",
|
|
4576
|
+
label: "Knowledge Base",
|
|
4577
|
+
path: "/knowledge",
|
|
4578
|
+
surfaceType: "page",
|
|
4579
|
+
icon: "knowledge",
|
|
4580
|
+
order: 50
|
|
3688
4581
|
}
|
|
3689
4582
|
},
|
|
3690
4583
|
bottom: {
|
|
3691
4584
|
settings: {
|
|
3692
4585
|
type: "group",
|
|
3693
4586
|
label: "Settings",
|
|
3694
|
-
icon: "
|
|
4587
|
+
icon: "settings",
|
|
3695
4588
|
order: 10,
|
|
3696
4589
|
children: {
|
|
3697
4590
|
"settings-account": {
|
|
@@ -3763,7 +4656,7 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
|
|
|
3763
4656
|
admin: {
|
|
3764
4657
|
type: "group",
|
|
3765
4658
|
label: "Admin",
|
|
3766
|
-
icon: "
|
|
4659
|
+
icon: "admin",
|
|
3767
4660
|
order: 20,
|
|
3768
4661
|
children: {
|
|
3769
4662
|
"admin-dashboard": {
|
|
@@ -3843,7 +4736,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
3843
4736
|
enabled: true,
|
|
3844
4737
|
lifecycle: "active",
|
|
3845
4738
|
path: "/",
|
|
3846
|
-
icon: "
|
|
4739
|
+
icon: "dashboard"
|
|
3847
4740
|
},
|
|
3848
4741
|
platform: {
|
|
3849
4742
|
id: "platform",
|
|
@@ -3853,7 +4746,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
3853
4746
|
enabled: true,
|
|
3854
4747
|
lifecycle: "active",
|
|
3855
4748
|
color: "cyan",
|
|
3856
|
-
icon: "
|
|
4749
|
+
icon: "platform"
|
|
3857
4750
|
},
|
|
3858
4751
|
finance: {
|
|
3859
4752
|
id: "finance",
|
|
@@ -3863,7 +4756,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
3863
4756
|
enabled: true,
|
|
3864
4757
|
lifecycle: "active",
|
|
3865
4758
|
color: "green",
|
|
3866
|
-
icon: "
|
|
4759
|
+
icon: "finance"
|
|
3867
4760
|
},
|
|
3868
4761
|
sales: {
|
|
3869
4762
|
id: "sales",
|
|
@@ -3873,7 +4766,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
3873
4766
|
enabled: true,
|
|
3874
4767
|
lifecycle: "active",
|
|
3875
4768
|
color: "blue",
|
|
3876
|
-
icon: "
|
|
4769
|
+
icon: "sales",
|
|
3877
4770
|
path: "/sales"
|
|
3878
4771
|
},
|
|
3879
4772
|
"sales.crm": {
|
|
@@ -3883,8 +4776,12 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
3883
4776
|
description: "Relationship pipeline and deal management",
|
|
3884
4777
|
enabled: true,
|
|
3885
4778
|
lifecycle: "active",
|
|
4779
|
+
actions: Object.values(CRM_ACTION_ENTRIES).map((action) => ({
|
|
4780
|
+
actionId: action.id,
|
|
4781
|
+
intent: "exposes"
|
|
4782
|
+
})),
|
|
3886
4783
|
color: "blue",
|
|
3887
|
-
icon: "
|
|
4784
|
+
icon: "crm",
|
|
3888
4785
|
path: "/crm"
|
|
3889
4786
|
},
|
|
3890
4787
|
"sales.lead-gen": {
|
|
@@ -3894,12 +4791,12 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
3894
4791
|
description: "Prospecting, qualification, and outreach preparation",
|
|
3895
4792
|
enabled: true,
|
|
3896
4793
|
lifecycle: "active",
|
|
3897
|
-
actions: Object.values(
|
|
4794
|
+
actions: Object.values(LEAD_GEN_ACTION_ENTRIES).map((action) => ({
|
|
3898
4795
|
actionId: action.id,
|
|
3899
4796
|
intent: "exposes"
|
|
3900
4797
|
})),
|
|
3901
4798
|
color: "cyan",
|
|
3902
|
-
icon: "
|
|
4799
|
+
icon: "lead-gen",
|
|
3903
4800
|
path: "/lead-gen"
|
|
3904
4801
|
},
|
|
3905
4802
|
projects: {
|
|
@@ -3910,7 +4807,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
3910
4807
|
enabled: true,
|
|
3911
4808
|
lifecycle: "active",
|
|
3912
4809
|
color: "orange",
|
|
3913
|
-
icon: "
|
|
4810
|
+
icon: "projects",
|
|
3914
4811
|
path: "/projects"
|
|
3915
4812
|
},
|
|
3916
4813
|
clients: {
|
|
@@ -3921,7 +4818,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
3921
4818
|
enabled: true,
|
|
3922
4819
|
lifecycle: "active",
|
|
3923
4820
|
color: "orange",
|
|
3924
|
-
icon: "
|
|
4821
|
+
icon: "projects",
|
|
3925
4822
|
path: "/clients"
|
|
3926
4823
|
},
|
|
3927
4824
|
operations: {
|
|
@@ -3932,7 +4829,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
3932
4829
|
enabled: true,
|
|
3933
4830
|
lifecycle: "active",
|
|
3934
4831
|
color: "violet",
|
|
3935
|
-
icon: "
|
|
4832
|
+
icon: "operations"
|
|
3936
4833
|
},
|
|
3937
4834
|
"knowledge.command-view": {
|
|
3938
4835
|
id: "knowledge.command-view",
|
|
@@ -3998,7 +4895,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
3998
4895
|
enabled: true,
|
|
3999
4896
|
lifecycle: "active",
|
|
4000
4897
|
path: "/monitoring/calendar",
|
|
4001
|
-
icon: "
|
|
4898
|
+
icon: "calendar"
|
|
4002
4899
|
},
|
|
4003
4900
|
"monitoring.activity-log": {
|
|
4004
4901
|
id: "monitoring.activity-log",
|
|
@@ -4054,7 +4951,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
4054
4951
|
label: "Settings",
|
|
4055
4952
|
enabled: true,
|
|
4056
4953
|
lifecycle: "active",
|
|
4057
|
-
icon: "
|
|
4954
|
+
icon: "settings"
|
|
4058
4955
|
},
|
|
4059
4956
|
"settings.account": {
|
|
4060
4957
|
id: "settings.account",
|
|
@@ -4127,7 +5024,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
4127
5024
|
enabled: true,
|
|
4128
5025
|
lifecycle: "active",
|
|
4129
5026
|
path: "/admin",
|
|
4130
|
-
icon: "
|
|
5027
|
+
icon: "admin",
|
|
4131
5028
|
requiresAdmin: true
|
|
4132
5029
|
},
|
|
4133
5030
|
"admin.system-health": {
|
|
@@ -4177,7 +5074,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
4177
5074
|
enabled: true,
|
|
4178
5075
|
lifecycle: "active",
|
|
4179
5076
|
path: "/archive",
|
|
4180
|
-
icon: "
|
|
5077
|
+
icon: "archive",
|
|
4181
5078
|
devOnly: true
|
|
4182
5079
|
},
|
|
4183
5080
|
"archive.agent-chat": {
|
|
@@ -4212,7 +5109,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
4212
5109
|
enabled: true,
|
|
4213
5110
|
lifecycle: "active",
|
|
4214
5111
|
color: "teal",
|
|
4215
|
-
icon: "
|
|
5112
|
+
icon: "knowledge"
|
|
4216
5113
|
},
|
|
4217
5114
|
"knowledge.base": {
|
|
4218
5115
|
id: "knowledge.base",
|
|
@@ -4223,11 +5120,14 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
4223
5120
|
path: "/knowledge"
|
|
4224
5121
|
}
|
|
4225
5122
|
},
|
|
5123
|
+
ontology: DEFAULT_ONTOLOGY_SCOPE,
|
|
4226
5124
|
resources: DEFAULT_ORGANIZATION_MODEL_RESOURCES,
|
|
5125
|
+
topology: DEFAULT_ORGANIZATION_MODEL_TOPOLOGY,
|
|
4227
5126
|
actions: DEFAULT_ORGANIZATION_MODEL_ACTIONS,
|
|
4228
5127
|
entities: DEFAULT_ORGANIZATION_MODEL_ENTITIES2,
|
|
4229
5128
|
policies: DEFAULT_ORGANIZATION_MODEL_POLICIES,
|
|
4230
|
-
// Phase 4 (D1): statuses top-level field removed; status
|
|
5129
|
+
// Phase 4 (D1): statuses top-level field removed; bridge status mirrors may
|
|
5130
|
+
// still project from System.content, but primary authoring belongs in ontology.
|
|
4231
5131
|
knowledge: DEFAULT_ORGANIZATION_MODEL_KNOWLEDGE
|
|
4232
5132
|
};
|
|
4233
5133
|
|
|
@@ -4235,6 +5135,31 @@ var DEFAULT_ORGANIZATION_MODEL = {
|
|
|
4235
5135
|
function isPlainObject(value) {
|
|
4236
5136
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4237
5137
|
}
|
|
5138
|
+
function collectNestedSystemPaths(systems, prefix = "") {
|
|
5139
|
+
const paths = /* @__PURE__ */ new Set();
|
|
5140
|
+
for (const [key, value] of Object.entries(systems)) {
|
|
5141
|
+
if (!isPlainObject(value)) continue;
|
|
5142
|
+
const path = prefix ? `${prefix}.${key}` : key;
|
|
5143
|
+
for (const childKey of ["systems", "subsystems"]) {
|
|
5144
|
+
const childSystems = value[childKey];
|
|
5145
|
+
if (!isPlainObject(childSystems)) continue;
|
|
5146
|
+
for (const childPath of collectNestedSystemPaths(childSystems, path)) {
|
|
5147
|
+
paths.add(childPath);
|
|
5148
|
+
}
|
|
5149
|
+
}
|
|
5150
|
+
if (prefix !== "") {
|
|
5151
|
+
paths.add(path);
|
|
5152
|
+
}
|
|
5153
|
+
}
|
|
5154
|
+
return paths;
|
|
5155
|
+
}
|
|
5156
|
+
function pruneFlatSystemDescendantCollisions(base, override) {
|
|
5157
|
+
const result = { ...base };
|
|
5158
|
+
for (const nestedPath of collectNestedSystemPaths(override)) {
|
|
5159
|
+
delete result[nestedPath];
|
|
5160
|
+
}
|
|
5161
|
+
return result;
|
|
5162
|
+
}
|
|
4238
5163
|
function deepMerge(base, override) {
|
|
4239
5164
|
if (override === void 0) {
|
|
4240
5165
|
return base;
|
|
@@ -4249,12 +5174,18 @@ function deepMerge(base, override) {
|
|
|
4249
5174
|
for (const [key, value] of Object.entries(override)) {
|
|
4250
5175
|
if (value === void 0) continue;
|
|
4251
5176
|
const existing = result[key];
|
|
5177
|
+
if (key === "systems" && isPlainObject(existing) && isPlainObject(value)) {
|
|
5178
|
+
result[key] = deepMerge(pruneFlatSystemDescendantCollisions(existing, value), value);
|
|
5179
|
+
continue;
|
|
5180
|
+
}
|
|
4252
5181
|
result[key] = isPlainObject(existing) && isPlainObject(value) ? deepMerge(existing, value) : value;
|
|
4253
5182
|
}
|
|
4254
5183
|
return result;
|
|
4255
5184
|
}
|
|
4256
|
-
function resolveOrganizationModel(override,
|
|
4257
|
-
const
|
|
5185
|
+
function resolveOrganizationModel(override, organizationIdOrOptions, options) {
|
|
5186
|
+
const resolvedOptions = typeof organizationIdOrOptions === "object" ? organizationIdOrOptions : options;
|
|
5187
|
+
const mergeDefaults = resolvedOptions?.mergeDefaults ?? true;
|
|
5188
|
+
const merged = mergeDefaults ? deepMerge(DEFAULT_ORGANIZATION_MODEL, override) : override ?? {};
|
|
4258
5189
|
return OrganizationModelSchema.parse(merged);
|
|
4259
5190
|
}
|
|
4260
5191
|
|
|
@@ -4339,4 +5270,4 @@ function projectOrganizationSurfaces(model) {
|
|
|
4339
5270
|
});
|
|
4340
5271
|
}
|
|
4341
5272
|
|
|
4342
|
-
export { ActionSchema, AgentResourceEntrySchema, CRM_DISCOVERY_BOOKING_CANCELLED_STATE, CRM_DISCOVERY_LINK_SENT_STATE, CRM_DISCOVERY_NUDGING_STATE, CRM_DISCOVERY_REPLIED_STATE, CRM_PIPELINE_DEFINITION, CRM_PRIORITY_BUCKETS, DEFAULT_CRM_PRIORITY_RULE_CONFIG, EntitySchema, IdentityDomainSchema, IntegrationResourceEntrySchema, LEAD_GEN_PIPELINE_DEFINITIONS, LEAD_GEN_STAGE_CATALOG, PROJECTS_VIEW_ACTION_ID, PROSPECTING_STEPS, PolicySchema, RoleSchema, SalesStageSchema, ScriptResourceEntrySchema, SurfaceDefinitionSchema, SystemEntrySchema, WorkflowResourceEntrySchema, ancestorsOf, buildOrganizationGraph, childrenOf, defaultPathFor, devOnlyFor, findById, findByPath, findPipeline, getContent, getResourcesForSystem, getSortedSidebarEntries, getSystem, getSystemAncestors, listAllSystems, lookupContentType, parentOf, projectOrganizationSurfaces, requiresAdminFor, resolveOrganizationModel, topLevel };
|
|
5273
|
+
export { ActionSchema, AgentResourceEntrySchema, CRM_DISCOVERY_BOOKING_CANCELLED_STATE, CRM_DISCOVERY_LINK_SENT_STATE, CRM_DISCOVERY_NUDGING_STATE, CRM_DISCOVERY_REPLIED_STATE, CRM_PIPELINE_DEFINITION, CRM_PRIORITY_BUCKETS, DEFAULT_CRM_PRIORITY_RULE_CONFIG, DEFAULT_ORGANIZATION_MODEL, EntitySchema, IdentityDomainSchema, IntegrationResourceEntrySchema, LEAD_GEN_PIPELINE_DEFINITIONS, LEAD_GEN_STAGE_CATALOG, OntologyIdSchema, PROJECTS_VIEW_ACTION_ID, PROSPECTING_STEPS, PolicySchema, RoleSchema, SalesStageSchema, ScriptResourceEntrySchema, SurfaceDefinitionSchema, SystemEntrySchema, WorkflowResourceEntrySchema, ancestorsOf, buildOrganizationGraph, childrenOf, compileOrganizationOntology, defaultPathFor, devOnlyFor, findById, findByPath, findPipeline, formatOntologyId, getContent, getResourcesForSystem, getSortedSidebarEntries, getSystem, getSystemAncestors, listAllSystems, lookupContentType, ontologyGraphNodeId, parentOf, parseOntologyId, projectOrganizationSurfaces, requiresAdminFor, resolveOrganizationModel, resolveSystemConfig, topLevel };
|