@elevasis/sdk 1.22.0 → 1.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/cli.cjs +980 -42
  2. package/dist/index.d.ts +1221 -220
  3. package/dist/index.js +390 -15
  4. package/dist/test-utils/index.d.ts +964 -211
  5. package/dist/test-utils/index.js +257 -14
  6. package/dist/worker/index.js +122 -14
  7. package/package.json +3 -3
  8. package/reference/claude-config/rules/operations.md +3 -3
  9. package/reference/claude-config/rules/organization-model.md +88 -85
  10. package/reference/claude-config/rules/organization-os.md +104 -104
  11. package/reference/claude-config/rules/vibe.md +235 -235
  12. package/reference/claude-config/skills/om/SKILL.md +324 -0
  13. package/reference/claude-config/skills/{knowledge → om}/operations/customers.md +110 -109
  14. package/reference/claude-config/skills/{knowledge → om}/operations/features.md +77 -76
  15. package/reference/claude-config/skills/{knowledge → om}/operations/goals.md +119 -118
  16. package/reference/claude-config/skills/{knowledge → om}/operations/identity.md +94 -93
  17. package/reference/claude-config/skills/{knowledge → om}/operations/labels.md +94 -94
  18. package/reference/claude-config/skills/{knowledge → om}/operations/offerings.md +110 -109
  19. package/reference/claude-config/skills/{knowledge → om}/operations/roles.md +100 -99
  20. package/reference/claude-config/skills/{knowledge → om}/operations/techStack.md +30 -30
  21. package/reference/claude-config/skills/project/SKILL.md +1088 -1088
  22. package/reference/claude-config/skills/setup/SKILL.md +275 -275
  23. package/reference/claude-config/skills/tutorial/SKILL.md +259 -259
  24. package/reference/claude-config/skills/tutorial/progress-template.md +74 -74
  25. package/reference/claude-config/skills/tutorial/technical.md +1303 -1303
  26. package/reference/claude-config/skills/tutorial/vibe-coder.md +890 -890
  27. package/reference/claude-config/sync-notes/2026-05-14-organization-model-ontology-refactor.md +7 -4
  28. package/reference/claude-config/sync-notes/2026-05-15-om-skill-rename-and-write-family.md +52 -0
  29. package/reference/examples/organization-model.ts +26 -2
  30. package/reference/scaffold/core/organization-model.mdx +16 -11
  31. package/reference/scaffold/recipes/add-a-feature.md +28 -26
  32. package/reference/scaffold/recipes/add-a-resource.md +26 -16
  33. package/reference/scaffold/recipes/customize-organization-model.md +5 -3
  34. package/reference/scaffold/recipes/extend-lead-gen.md +9 -9
  35. package/reference/scaffold/recipes/index.md +1 -1
  36. package/reference/scaffold/recipes/query-the-knowledge-graph.md +189 -185
  37. package/reference/scaffold/reference/contracts.md +139 -101
  38. package/reference/scaffold/reference/glossary.md +74 -72
  39. package/reference/claude-config/skills/knowledge/SKILL.md +0 -345
  40. /package/reference/claude-config/skills/{knowledge → om}/operations/codify-level-a.md +0 -0
  41. /package/reference/claude-config/skills/{knowledge → om}/operations/codify-level-b.md +0 -0
package/dist/cli.cjs CHANGED
@@ -5246,7 +5246,7 @@ var require_buffer_list = __commonJS({
5246
5246
  }
5247
5247
  }, {
5248
5248
  key: "join",
5249
- value: function join6(s) {
5249
+ value: function join7(s) {
5250
5250
  if (this.length === 0) return "";
5251
5251
  var p = this.head;
5252
5252
  var ret = "" + p.data;
@@ -10756,10 +10756,10 @@ var require_schemas = __commonJS({
10756
10756
  const shape = def.shape;
10757
10757
  const propValues = {};
10758
10758
  for (const key in shape) {
10759
- const field = shape[key]._zod;
10760
- if (field.values) {
10759
+ const field2 = shape[key]._zod;
10760
+ if (field2.values) {
10761
10761
  propValues[key] ?? (propValues[key] = /* @__PURE__ */ new Set());
10762
- for (const v of field.values)
10762
+ for (const v of field2.values)
10763
10763
  propValues[key].add(v);
10764
10764
  }
10765
10765
  }
@@ -26924,10 +26924,10 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
26924
26924
  const shape = def.shape;
26925
26925
  const propValues = {};
26926
26926
  for (const key in shape) {
26927
- const field = shape[key]._zod;
26928
- if (field.values) {
26927
+ const field2 = shape[key]._zod;
26928
+ if (field2.values) {
26929
26929
  propValues[key] ?? (propValues[key] = /* @__PURE__ */ new Set());
26930
- for (const v of field.values)
26930
+ for (const v of field2.values)
26931
26931
  propValues[key].add(v);
26932
26932
  }
26933
26933
  }
@@ -36620,6 +36620,7 @@ var ORGANIZATION_MODEL_ICON_TOKENS = [
36620
36620
  "crm",
36621
36621
  "lead-gen",
36622
36622
  "projects",
36623
+ "clients",
36623
36624
  "operations",
36624
36625
  "monitoring",
36625
36626
  "knowledge",
@@ -37454,7 +37455,6 @@ function addLegacyEntityProjections(index, diagnostics, sourcesById, entities) {
37454
37455
  table: entity.table
37455
37456
  }
37456
37457
  } : {},
37457
- legacyEntityId: entity.id,
37458
37458
  ...entity.rowSchema !== void 0 ? { rowSchema: entity.rowSchema } : {},
37459
37459
  ...entity.stateCatalogId !== void 0 ? { stateCatalogId: entity.stateCatalogId } : {}
37460
37460
  };
@@ -37479,8 +37479,7 @@ function addLegacyEntityProjections(index, diagnostics, sourcesById, entities) {
37479
37479
  from: legacyObjectId(entity),
37480
37480
  to: legacyObjectId(targetEntity),
37481
37481
  cardinality: link.kind,
37482
- ...link.via !== void 0 ? { via: link.via } : {},
37483
- legacyEntityId: entity.id
37482
+ ...link.via !== void 0 ? { via: link.via } : {}
37484
37483
  };
37485
37484
  addRecord(index, diagnostics, sourcesById, "linkTypes", linkType, {
37486
37485
  source: "legacy.entities.links",
@@ -37538,8 +37537,7 @@ function addSystemContentProjections(index, diagnostics, sourcesById, systemPath
37538
37537
  kind: node.type,
37539
37538
  ...typeof node.data?.["entityId"] === "string" ? { appliesTo: formatOntologyId({ scope: systemPath, kind: "object", localId: node.data["entityId"] }) } : {},
37540
37539
  ...Object.keys(entries).length > 0 ? { entries } : {},
37541
- ...node.data !== void 0 ? { data: node.data } : {},
37542
- legacyContentId: `${systemPath}:${localId}`
37540
+ ...node.data !== void 0 ? { data: node.data } : {}
37543
37541
  };
37544
37542
  addRecord(index, diagnostics, sourcesById, "catalogTypes", catalogType, {
37545
37543
  source: "legacy.system.content",
@@ -38114,11 +38112,20 @@ var EventDescriptorSchema = EventEmissionDescriptorSchema.extend({
38114
38112
  ownerKind: external_exports.enum(["resource", "entity"]).meta({ label: "Owner kind" })
38115
38113
  });
38116
38114
  var ResourceOntologyBindingSchema = external_exports.object({
38117
- implements: external_exports.array(OntologyIdSchema).optional(),
38115
+ actions: external_exports.array(OntologyIdSchema).optional(),
38116
+ primaryAction: OntologyIdSchema.optional(),
38118
38117
  reads: external_exports.array(OntologyIdSchema).optional(),
38119
38118
  writes: external_exports.array(OntologyIdSchema).optional(),
38120
38119
  usesCatalogs: external_exports.array(OntologyIdSchema).optional(),
38121
38120
  emits: external_exports.array(OntologyIdSchema).optional()
38121
+ }).superRefine((binding, ctx) => {
38122
+ if (binding.primaryAction === void 0) return;
38123
+ if (binding.actions?.includes(binding.primaryAction)) return;
38124
+ ctx.addIssue({
38125
+ code: external_exports.ZodIssueCode.custom,
38126
+ path: ["primaryAction"],
38127
+ message: "Resource ontology primaryAction must be included in actions"
38128
+ });
38122
38129
  });
38123
38130
  var CodeReferenceSchema = external_exports.object({
38124
38131
  path: external_exports.string().trim().min(1).max(500).regex(/^[A-Za-z0-9_./$@()[\] -]+$/, "Code reference paths must be repo-relative paths"),
@@ -38133,6 +38140,10 @@ var ResourceEntryBaseSchema = external_exports.object({
38133
38140
  order: external_exports.number().default(0),
38134
38141
  /** Required single System membership — value is a dot-separated system path (e.g. "sales.lead-gen"). */
38135
38142
  systemPath: SystemPathSchema.meta({ ref: "system" }),
38143
+ /** Executable display title owned by the OM Resource descriptor. */
38144
+ title: LabelSchema.optional(),
38145
+ /** Executable display description owned by the OM Resource descriptor. */
38146
+ description: DescriptionSchema.optional(),
38136
38147
  /** Optional role responsible for maintaining this resource. */
38137
38148
  ownerRoleId: ModelIdSchema.meta({ ref: "role" }).optional(),
38138
38149
  status: ResourceGovernanceStatusSchema,
@@ -38147,8 +38158,6 @@ var ResourceEntryBaseSchema = external_exports.object({
38147
38158
  });
38148
38159
  var WorkflowResourceEntrySchema = ResourceEntryBaseSchema.extend({
38149
38160
  kind: external_exports.literal("workflow"),
38150
- /** Mirrors WorkflowConfig.actionKey when the runtime workflow has one. */
38151
- actionKey: external_exports.string().trim().min(1).max(255).optional(),
38152
38161
  emits: external_exports.array(EventEmissionDescriptorSchema).optional()
38153
38162
  });
38154
38163
  var AgentResourceEntrySchema = ResourceEntryBaseSchema.extend({
@@ -38373,6 +38382,75 @@ var OrgKnowledgeNodeSchema = external_exports.object({
38373
38382
  });
38374
38383
  var KnowledgeDomainSchema = external_exports.record(ModelIdSchema, OrgKnowledgeNodeSchema).default({});
38375
38384
 
38385
+ // ../core/src/organization-model/domains/topology.ts
38386
+ var SecretLikeMetadataKeySchema = /(?:secret|password|passwd|token|api[-_]?key|credential|private[-_]?key)/i;
38387
+ 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-----)/;
38388
+ var OmTopologyNodeKindSchema = external_exports.enum([
38389
+ "system",
38390
+ "resource",
38391
+ "ontology",
38392
+ "policy",
38393
+ "role",
38394
+ "trigger",
38395
+ "humanCheckpoint",
38396
+ "externalResource"
38397
+ ]);
38398
+ var OmTopologyRelationshipKindSchema = external_exports.enum(["triggers", "uses", "approval"]);
38399
+ var OmTopologyNodeRefSchema = external_exports.discriminatedUnion("kind", [
38400
+ external_exports.object({ kind: external_exports.literal("system"), id: ModelIdSchema }),
38401
+ external_exports.object({ kind: external_exports.literal("resource"), id: ResourceIdSchema }),
38402
+ external_exports.object({ kind: external_exports.literal("ontology"), id: OntologyIdSchema }),
38403
+ external_exports.object({ kind: external_exports.literal("policy"), id: ModelIdSchema }),
38404
+ external_exports.object({ kind: external_exports.literal("role"), id: ModelIdSchema }),
38405
+ external_exports.object({ kind: external_exports.literal("trigger"), id: ResourceIdSchema }),
38406
+ external_exports.object({ kind: external_exports.literal("humanCheckpoint"), id: ResourceIdSchema }),
38407
+ external_exports.object({ kind: external_exports.literal("externalResource"), id: ResourceIdSchema })
38408
+ ]);
38409
+ var OmTopologyMetadataSchema = external_exports.record(external_exports.string().trim().min(1).max(120), JsonValueSchema).superRefine((metadata, ctx) => {
38410
+ function visit(value, path3) {
38411
+ if (typeof value === "string" && SecretLikeMetadataValueSchema.test(value)) {
38412
+ ctx.addIssue({
38413
+ code: external_exports.ZodIssueCode.custom,
38414
+ path: path3,
38415
+ message: "Topology metadata must not contain secret-like values"
38416
+ });
38417
+ return;
38418
+ }
38419
+ if (Array.isArray(value)) {
38420
+ value.forEach((entry, index) => visit(entry, [...path3, index]));
38421
+ return;
38422
+ }
38423
+ if (typeof value !== "object" || value === null) return;
38424
+ Object.entries(value).forEach(([key, entry]) => {
38425
+ if (SecretLikeMetadataKeySchema.test(key)) {
38426
+ ctx.addIssue({
38427
+ code: external_exports.ZodIssueCode.custom,
38428
+ path: [...path3, key],
38429
+ message: `Topology metadata key "${key}" looks secret-like`
38430
+ });
38431
+ }
38432
+ visit(entry, [...path3, key]);
38433
+ });
38434
+ }
38435
+ visit(metadata, []);
38436
+ });
38437
+ var OmTopologyRelationshipSchema = external_exports.object({
38438
+ from: OmTopologyNodeRefSchema,
38439
+ kind: OmTopologyRelationshipKindSchema,
38440
+ to: OmTopologyNodeRefSchema,
38441
+ systemPath: SystemPathSchema.optional(),
38442
+ required: external_exports.boolean().optional(),
38443
+ metadata: OmTopologyMetadataSchema.optional()
38444
+ });
38445
+ var OmTopologyDomainSchema = external_exports.object({
38446
+ version: external_exports.literal(1).default(1),
38447
+ relationships: external_exports.record(external_exports.string().trim().min(1).max(255), OmTopologyRelationshipSchema).default({})
38448
+ }).default({ version: 1, relationships: {} });
38449
+ var DEFAULT_ORGANIZATION_MODEL_TOPOLOGY = {
38450
+ version: 1,
38451
+ relationships: {}
38452
+ };
38453
+
38376
38454
  // ../core/src/organization-model/domains/policies.ts
38377
38455
  var PolicyIdSchema = ModelIdSchema;
38378
38456
  var PolicyApplicabilitySchema = external_exports.object({
@@ -38463,6 +38541,7 @@ var OrganizationModelDomainKeySchema = external_exports.enum([
38463
38541
  "systems",
38464
38542
  "ontology",
38465
38543
  "resources",
38544
+ "topology",
38466
38545
  "actions",
38467
38546
  "entities",
38468
38547
  "policies",
@@ -38482,6 +38561,7 @@ var DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA = {
38482
38561
  systems: { version: 1, lastModified: "2026-05-10" },
38483
38562
  ontology: { version: 1, lastModified: "2026-05-14" },
38484
38563
  resources: { version: 1, lastModified: "2026-05-10" },
38564
+ topology: { version: 1, lastModified: "2026-05-14" },
38485
38565
  actions: { version: 1, lastModified: "2026-05-10" },
38486
38566
  entities: { version: 1, lastModified: "2026-05-10" },
38487
38567
  policies: { version: 1, lastModified: "2026-05-10" },
@@ -38497,6 +38577,7 @@ var OrganizationModelDomainMetadataByDomainSchema = external_exports.object({
38497
38577
  systems: OrganizationModelDomainMetadataSchema,
38498
38578
  ontology: OrganizationModelDomainMetadataSchema,
38499
38579
  resources: OrganizationModelDomainMetadataSchema,
38580
+ topology: OrganizationModelDomainMetadataSchema,
38500
38581
  actions: OrganizationModelDomainMetadataSchema,
38501
38582
  entities: OrganizationModelDomainMetadataSchema,
38502
38583
  policies: OrganizationModelDomainMetadataSchema,
@@ -38515,6 +38596,7 @@ var OrganizationModelSchemaBase = external_exports.object({
38515
38596
  systems: SystemsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_SYSTEMS),
38516
38597
  ontology: OntologyScopeSchema.default(DEFAULT_ONTOLOGY_SCOPE),
38517
38598
  resources: ResourcesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_RESOURCES),
38599
+ topology: OmTopologyDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_TOPOLOGY),
38518
38600
  actions: ActionsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ACTIONS),
38519
38601
  entities: EntitiesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ENTITIES),
38520
38602
  policies: PoliciesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_POLICIES),
@@ -38857,6 +38939,26 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
38857
38939
  surface: ontologyCompilation.ontology.surfaces
38858
38940
  };
38859
38941
  const ontologyIds = new Set(Object.values(ontologyIndexByKind).flatMap((index) => Object.keys(index)));
38942
+ function topologyTargetExists(ref) {
38943
+ if (ref.kind === "system") return systemsById.has(ref.id);
38944
+ if (ref.kind === "resource") return resourcesById.has(ref.id);
38945
+ if (ref.kind === "ontology") return ontologyIds.has(ref.id);
38946
+ if (ref.kind === "policy") return policiesById.has(ref.id);
38947
+ if (ref.kind === "role") return rolesById.has(ref.id);
38948
+ return true;
38949
+ }
38950
+ Object.entries(model.topology.relationships).forEach(([relationshipId, relationship]) => {
38951
+ ;
38952
+ ["from", "to"].forEach((side) => {
38953
+ const ref = relationship[side];
38954
+ if (topologyTargetExists(ref)) return;
38955
+ addIssue(
38956
+ ctx,
38957
+ ["topology", "relationships", relationshipId, side],
38958
+ `Topology relationship "${relationshipId}" ${side} references unknown ${ref.kind} "${ref.id}"`
38959
+ );
38960
+ });
38961
+ });
38860
38962
  const ontologyReferenceKeyKinds = {
38861
38963
  valueType: "value-type",
38862
38964
  catalogType: "catalog",
@@ -38995,11 +39097,18 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
38995
39097
  }
38996
39098
  });
38997
39099
  function validateResourceOntologyBinding(resourceId, bindingKey, expectedKind, ids) {
38998
- ids?.forEach((ontologyId, ontologyIndex) => {
39100
+ const ontologyIds2 = ids === void 0 ? [] : Array.isArray(ids) ? ids : [ids];
39101
+ ontologyIds2.forEach((ontologyId, ontologyIndex) => {
38999
39102
  if (ontologyIndexByKind[expectedKind][ontologyId] === void 0) {
39000
39103
  addIssue(
39001
39104
  ctx,
39002
- ["resources", resourceId, "ontology", bindingKey, ontologyIndex],
39105
+ [
39106
+ "resources",
39107
+ resourceId,
39108
+ "ontology",
39109
+ bindingKey,
39110
+ ...Array.isArray(ids) ? [ontologyIndex] : []
39111
+ ],
39003
39112
  `Resource "${resourceId}" ontology binding "${bindingKey}" references unknown ${expectedKind} ontology ID "${ontologyId}"`
39004
39113
  );
39005
39114
  }
@@ -39008,7 +39117,8 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
39008
39117
  Object.values(model.resources).forEach((resource) => {
39009
39118
  const binding = resource.ontology;
39010
39119
  if (binding === void 0) return;
39011
- validateResourceOntologyBinding(resource.id, "implements", "action", binding.implements);
39120
+ validateResourceOntologyBinding(resource.id, "actions", "action", binding.actions);
39121
+ validateResourceOntologyBinding(resource.id, "primaryAction", "action", binding.primaryAction);
39012
39122
  validateResourceOntologyBinding(resource.id, "reads", "object", binding.reads);
39013
39123
  validateResourceOntologyBinding(resource.id, "writes", "object", binding.writes);
39014
39124
  validateResourceOntologyBinding(resource.id, "usesCatalogs", "catalog", binding.usesCatalogs);
@@ -39156,9 +39266,10 @@ var OrganizationGraphEdgeKindSchema = external_exports.enum([
39156
39266
  "emits",
39157
39267
  "originates_from",
39158
39268
  "triggers",
39269
+ "approval",
39159
39270
  "applies_to",
39160
39271
  "effects",
39161
- "implements",
39272
+ "actions",
39162
39273
  "reads",
39163
39274
  "writes",
39164
39275
  "uses_catalog"
@@ -39443,9 +39554,9 @@ function getModelInfo(model) {
39443
39554
 
39444
39555
  // ../core/src/execution/engine/llm/errors.ts
39445
39556
  var ModelConfigError = class extends ExecutionError {
39446
- constructor(message, field, model, context) {
39447
- super(message, { ...context, field, model });
39448
- this.field = field;
39557
+ constructor(message, field2, model, context) {
39558
+ super(message, { ...context, field: field2, model });
39559
+ this.field = field2;
39449
39560
  this.model = model;
39450
39561
  }
39451
39562
  type = "model_config_error";
@@ -39475,11 +39586,11 @@ function validateModelConfig(config3) {
39475
39586
 
39476
39587
  // ../core/src/platform/registry/validation.ts
39477
39588
  var RegistryValidationError = class extends Error {
39478
- constructor(orgName, resourceId, field, message) {
39589
+ constructor(orgName, resourceId, field2, message) {
39479
39590
  super(message);
39480
39591
  this.orgName = orgName;
39481
39592
  this.resourceId = resourceId;
39482
- this.field = field;
39593
+ this.field = field2;
39483
39594
  this.name = "RegistryValidationError";
39484
39595
  }
39485
39596
  };
@@ -39526,6 +39637,120 @@ function getRuntimeResources(resources) {
39526
39637
  }))
39527
39638
  ];
39528
39639
  }
39640
+ function hasOntologySources(organizationModel) {
39641
+ return organizationModel.ontology !== void 0 || organizationModel.entities !== void 0 || organizationModel.actions !== void 0 || Object.values(organizationModel.systems ?? {}).some(systemHasOntologySource);
39642
+ }
39643
+ function systemHasOntologySource(system) {
39644
+ if (system.ontology !== void 0 || system.content !== void 0 && Object.keys(system.content).length > 0) return true;
39645
+ return Object.values(system.systems ?? system.subsystems ?? {}).some(systemHasOntologySource);
39646
+ }
39647
+ function ontologyIndexForKind(index, kind) {
39648
+ switch (kind) {
39649
+ case "object":
39650
+ return index.objectTypes;
39651
+ case "link":
39652
+ return index.linkTypes;
39653
+ case "action":
39654
+ return index.actionTypes;
39655
+ case "catalog":
39656
+ return index.catalogTypes;
39657
+ case "event":
39658
+ return index.eventTypes;
39659
+ case "interface":
39660
+ return index.interfaceTypes;
39661
+ case "value-type":
39662
+ return index.valueTypes;
39663
+ case "property":
39664
+ return index.sharedProperties;
39665
+ case "group":
39666
+ return index.groups;
39667
+ case "surface":
39668
+ return index.surfaces;
39669
+ }
39670
+ }
39671
+ function sameJson(left, right) {
39672
+ return JSON.stringify(left ?? null) === JSON.stringify(right ?? null);
39673
+ }
39674
+ function addOntologyBindingIssues(issues, orgName, resource, ontologyIndex) {
39675
+ const binding = resource.ontology;
39676
+ if (binding === void 0) return;
39677
+ if ((resource.kind === "workflow" || resource.kind === "agent") && (binding.actions?.length ?? 0) === 0) {
39678
+ addGovernanceIssue(
39679
+ issues,
39680
+ "missing-ontology-actions",
39681
+ orgName,
39682
+ resource.id,
39683
+ `[${orgName}] Resource '${resource.id}' declares ontology bindings but no ontology actions.`
39684
+ );
39685
+ }
39686
+ if (binding.primaryAction !== void 0 && !binding.actions?.includes(binding.primaryAction)) {
39687
+ addGovernanceIssue(
39688
+ issues,
39689
+ "primary-action-mismatch",
39690
+ orgName,
39691
+ resource.id,
39692
+ `[${orgName}] Resource '${resource.id}' primaryAction '${binding.primaryAction}' must be included in ontology.actions.`
39693
+ );
39694
+ }
39695
+ if (ontologyIndex === void 0) return;
39696
+ const validateRefs = (bindingKey, expectedKind, refs) => {
39697
+ const values = refs === void 0 ? [] : Array.isArray(refs) ? refs : [refs];
39698
+ const index = ontologyIndexForKind(ontologyIndex, expectedKind);
39699
+ for (const ref of values) {
39700
+ if (index[ref] !== void 0) continue;
39701
+ addGovernanceIssue(
39702
+ issues,
39703
+ "ontology-reference-missing",
39704
+ orgName,
39705
+ resource.id,
39706
+ `[${orgName}] Resource '${resource.id}' ontology.${bindingKey} references missing ${expectedKind} ontology record '${ref}'.`
39707
+ );
39708
+ }
39709
+ };
39710
+ validateRefs("actions", "action", binding.actions);
39711
+ validateRefs("primaryAction", "action", binding.primaryAction);
39712
+ validateRefs("reads", "object", binding.reads);
39713
+ validateRefs("writes", "object", binding.writes);
39714
+ validateRefs("usesCatalogs", "catalog", binding.usesCatalogs);
39715
+ validateRefs("emits", "event", binding.emits);
39716
+ }
39717
+ function addTopologyIssues(issues, orgName, deployment, organizationModel, systemsById, omResourcesById, ontologyIndex) {
39718
+ const relationships = organizationModel.topology?.relationships;
39719
+ if (relationships === void 0) return;
39720
+ const rolesById = new Set(Object.keys(organizationModel.roles ?? {}));
39721
+ const policiesById = new Set(Object.keys(organizationModel.policies ?? {}));
39722
+ const triggerIds = new Set(deployment.triggers?.map((trigger) => trigger.resourceId) ?? []);
39723
+ const humanCheckpointIds = new Set(deployment.humanCheckpoints?.map((checkpoint) => checkpoint.resourceId) ?? []);
39724
+ const externalResourceIds = new Set(deployment.externalResources?.map((external) => external.resourceId) ?? []);
39725
+ const topologyRefExists = (ref) => {
39726
+ if (ref.kind === "system") return systemsById.has(ref.id);
39727
+ if (ref.kind === "resource") return omResourcesById.has(ref.id);
39728
+ if (ref.kind === "policy") return policiesById.has(ref.id);
39729
+ if (ref.kind === "role") return rolesById.has(ref.id);
39730
+ if (ref.kind === "trigger") return triggerIds.has(ref.id);
39731
+ if (ref.kind === "humanCheckpoint") return humanCheckpointIds.has(ref.id);
39732
+ if (ref.kind === "externalResource") return externalResourceIds.has(ref.id);
39733
+ if (ref.kind === "ontology") {
39734
+ if (ontologyIndex === void 0) return true;
39735
+ return Object.values(ontologyIndex).some((records) => records[ref.id] !== void 0);
39736
+ }
39737
+ return false;
39738
+ };
39739
+ for (const [relationshipId, relationship] of Object.entries(relationships)) {
39740
+ ;
39741
+ ["from", "to"].forEach((side) => {
39742
+ const ref = relationship[side];
39743
+ if (topologyRefExists(ref)) return;
39744
+ addGovernanceIssue(
39745
+ issues,
39746
+ "topology-reference-missing",
39747
+ orgName,
39748
+ ref.id,
39749
+ `[${orgName}] Topology relationship '${relationshipId}' ${side} references missing ${ref.kind} '${ref.id}'.`
39750
+ );
39751
+ });
39752
+ }
39753
+ }
39529
39754
  function validateResourceGovernance(orgName, deployment, organizationModel = deployment.organizationModel, options = {}) {
39530
39755
  const mode = getResourceValidatorMode(options.mode);
39531
39756
  const omResourcesMap = organizationModel?.resources;
@@ -39541,6 +39766,17 @@ function validateResourceGovernance(orgName, deployment, organizationModel = dep
39541
39766
  const omResourcesById = new Map(activeOmResources.map((resource) => [resource.id, resource]));
39542
39767
  const runtimeResources = getRuntimeResources(deployment);
39543
39768
  const runtimeResourcesById = new Map(runtimeResources.map((resource) => [resource.resourceId, resource]));
39769
+ const ontologyCompilation = hasOntologySources(organizationModel) ? compileOrganizationOntology(organizationModel) : void 0;
39770
+ const ontologyIndex = ontologyCompilation?.ontology;
39771
+ for (const diagnostic of ontologyCompilation?.diagnostics ?? []) {
39772
+ addGovernanceIssue(
39773
+ issues,
39774
+ "ontology-reference-missing",
39775
+ orgName,
39776
+ diagnostic.id,
39777
+ `[${orgName}] ${diagnostic.message}`
39778
+ );
39779
+ }
39544
39780
  for (const resource of activeOmResources) {
39545
39781
  if (!systemsById.has(resource.systemPath)) {
39546
39782
  addGovernanceIssue(
@@ -39580,6 +39816,16 @@ function validateResourceGovernance(orgName, deployment, organizationModel = dep
39580
39816
  `[${orgName}] Resource '${resource.id}' system mismatch: code descriptor has '${runtimeResource.descriptor.systemPath}', OM has '${resource.systemPath}'.`
39581
39817
  );
39582
39818
  }
39819
+ if (runtimeResource.descriptor && !sameJson(runtimeResource.descriptor.ontology, resource.ontology)) {
39820
+ addGovernanceIssue(
39821
+ issues,
39822
+ "descriptor-mismatch",
39823
+ orgName,
39824
+ resource.id,
39825
+ `[${orgName}] Resource '${resource.id}' ontology descriptor mismatch between code and OM.`
39826
+ );
39827
+ }
39828
+ addOntologyBindingIssues(issues, orgName, resource, ontologyIndex);
39583
39829
  }
39584
39830
  for (const runtimeResource of runtimeResources) {
39585
39831
  const omResource = omResourcesById.get(runtimeResource.resourceId);
@@ -39621,6 +39867,7 @@ function validateResourceGovernance(orgName, deployment, organizationModel = dep
39621
39867
  );
39622
39868
  }
39623
39869
  }
39870
+ addTopologyIssues(issues, orgName, deployment, organizationModel, systemsById, omResourcesById, ontologyIndex);
39624
39871
  emitGovernanceIssues(issues, mode, options.onWarning);
39625
39872
  return {
39626
39873
  valid: issues.length === 0,
@@ -39690,9 +39937,9 @@ function validateExecutionInterface(orgName, resourceId, executionInterface, inp
39690
39937
  }
39691
39938
  const schemaFieldNames = Object.keys(schemaShape);
39692
39939
  const formToSchemaMap = /* @__PURE__ */ new Map();
39693
- for (const field of form.fields) {
39694
- const schemaKey = fieldMappings[field.name] ?? field.name;
39695
- formToSchemaMap.set(field.name, schemaKey);
39940
+ for (const field2 of form.fields) {
39941
+ const schemaKey = fieldMappings[field2.name] ?? field2.name;
39942
+ formToSchemaMap.set(field2.name, schemaKey);
39696
39943
  }
39697
39944
  for (const schemaFieldName of schemaFieldNames) {
39698
39945
  const schemaField = schemaShape[schemaFieldName];
@@ -43176,7 +43423,7 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
43176
43423
  business: {
43177
43424
  type: "group",
43178
43425
  label: "Business",
43179
- icon: "business",
43426
+ icon: "briefcase",
43180
43427
  order: 20,
43181
43428
  children: {
43182
43429
  sales: {
@@ -43193,7 +43440,7 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
43193
43440
  label: "Clients",
43194
43441
  path: "/clients",
43195
43442
  surfaceType: "list",
43196
- icon: "projects",
43443
+ icon: "clients",
43197
43444
  order: 20,
43198
43445
  targets: { systems: ["clients"] }
43199
43446
  },
@@ -43567,7 +43814,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
43567
43814
  enabled: true,
43568
43815
  lifecycle: "active",
43569
43816
  color: "orange",
43570
- icon: "projects",
43817
+ icon: "clients",
43571
43818
  path: "/clients"
43572
43819
  },
43573
43820
  operations: {
@@ -43871,6 +44118,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
43871
44118
  },
43872
44119
  ontology: DEFAULT_ONTOLOGY_SCOPE,
43873
44120
  resources: DEFAULT_ORGANIZATION_MODEL_RESOURCES,
44121
+ topology: DEFAULT_ORGANIZATION_MODEL_TOPOLOGY,
43874
44122
  actions: DEFAULT_ORGANIZATION_MODEL_ACTIONS,
43875
44123
  entities: DEFAULT_ORGANIZATION_MODEL_ENTITIES2,
43876
44124
  policies: DEFAULT_ORGANIZATION_MODEL_POLICIES,
@@ -44165,6 +44413,32 @@ function buildOrganizationGraph(input) {
44165
44413
  }
44166
44414
  const validSystemRefs = new Set(systemPathByRef.keys());
44167
44415
  const systemNodeId = (systemRef) => nodeId("system", systemPathByRef.get(systemRef) ?? systemRef);
44416
+ function topologyNodeId(ref) {
44417
+ if (ref.kind === "system") return systemNodeId(ref.id);
44418
+ if (ref.kind === "resource") return nodeId("resource", ref.id);
44419
+ if (ref.kind === "ontology") return ontologyGraphNodeId(ref.id);
44420
+ if (ref.kind === "policy") return nodeId("policy", ref.id);
44421
+ if (ref.kind === "role") return nodeId("role", ref.id);
44422
+ return nodeId("resource", ref.id);
44423
+ }
44424
+ function ensureTopologyNode(ref) {
44425
+ const id = topologyNodeId(ref);
44426
+ if (nodeIds.has(id)) return id;
44427
+ if (ref.kind === "resource") {
44428
+ ensureResourceNode(nodes, nodeIds, resourceNodesById, ref.id);
44429
+ return id;
44430
+ }
44431
+ if (ref.kind === "trigger" || ref.kind === "humanCheckpoint" || ref.kind === "externalResource") {
44432
+ pushUniqueNode(nodes, nodeIds, {
44433
+ id,
44434
+ kind: "resource",
44435
+ label: ref.id,
44436
+ sourceId: ref.id,
44437
+ resourceType: ref.kind === "trigger" ? "trigger" : ref.kind === "humanCheckpoint" ? "human_checkpoint" : "external"
44438
+ });
44439
+ }
44440
+ return id;
44441
+ }
44168
44442
  for (const { path: path3, system } of systemsWithPaths.sort((a, b) => a.path.localeCompare(b.path))) {
44169
44443
  const id = nodeId("system", path3);
44170
44444
  pushUniqueNode(nodes, nodeIds, {
@@ -44480,7 +44754,7 @@ function buildOrganizationGraph(input) {
44480
44754
  targetId: resourceNode.id
44481
44755
  });
44482
44756
  }
44483
- pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, "implements", resource.ontology?.implements);
44757
+ pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, "actions", resource.ontology?.actions);
44484
44758
  pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, "reads", resource.ontology?.reads);
44485
44759
  pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, "writes", resource.ontology?.writes);
44486
44760
  pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, "uses_catalog", resource.ontology?.usesCatalogs);
@@ -44614,6 +44888,19 @@ function buildOrganizationGraph(input) {
44614
44888
  }
44615
44889
  }
44616
44890
  }
44891
+ for (const [relationshipId, relationship] of Object.entries(organizationModel.topology.relationships).sort(
44892
+ ([a], [b]) => a.localeCompare(b)
44893
+ )) {
44894
+ const sourceId = ensureTopologyNode(relationship.from);
44895
+ const targetId = ensureTopologyNode(relationship.to);
44896
+ pushUniqueEdge(edges, edgeIds, {
44897
+ id: edgeId(relationship.kind, sourceId, targetId, `topology-${relationshipId}`),
44898
+ kind: relationship.kind,
44899
+ sourceId,
44900
+ targetId,
44901
+ relationshipType: relationship.kind
44902
+ });
44903
+ }
44617
44904
  for (const segment of Object.values(organizationModel.customers).sort(
44618
44905
  (a, b) => a.order - b.order || a.id.localeCompare(b.id)
44619
44906
  )) {
@@ -45048,7 +45335,7 @@ function wrapAction(commandName, fn) {
45048
45335
  // package.json
45049
45336
  var package_default = {
45050
45337
  name: "@elevasis/sdk",
45051
- version: "1.22.0",
45338
+ version: "1.23.0",
45052
45339
  description: "SDK for building Elevasis organization resources",
45053
45340
  type: "module",
45054
45341
  bin: {
@@ -47753,6 +48040,425 @@ function parsePath(pathString) {
47753
48040
  `parsePath: unrecognized path pattern "${pathString}". Supported: /by-system/<id>, /by-kind/<kind>, /by-owner/<id>, /graph/<nodeId>/governs, /graph/<nodeId>/governed-by, /<nodeId>`
47754
48041
  );
47755
48042
  }
48043
+ function omSearch(model, query, options = {}) {
48044
+ const limit = options.limit ?? 10;
48045
+ const kinds = options.kinds ? new Set(options.kinds) : null;
48046
+ const terms = tokenize(query);
48047
+ if (terms.length === 0) return [];
48048
+ const entries = collectSearchable(model, kinds);
48049
+ const scored = [];
48050
+ for (const entry of entries) {
48051
+ const score = scoreEntry(entry, terms);
48052
+ if (score > 0) {
48053
+ scored.push({
48054
+ kind: entry.kind,
48055
+ id: entry.id,
48056
+ title: entry.title,
48057
+ summary: entry.summary,
48058
+ score,
48059
+ subKind: entry.subKind
48060
+ });
48061
+ }
48062
+ }
48063
+ scored.sort((a, b) => b.score - a.score || a.id.localeCompare(b.id));
48064
+ return limit > 0 ? scored.slice(0, limit) : scored;
48065
+ }
48066
+ function tokenize(query) {
48067
+ return query.toLowerCase().split(/[\s,/]+/).map((t) => t.replace(/^[^a-z0-9]+|[^a-z0-9]+$/g, "")).filter((t) => t.length >= 2);
48068
+ }
48069
+ function structuralTokens(text) {
48070
+ return new Set(
48071
+ text.toLowerCase().split(/[\s.\-_:/,;]+/).map((t) => t.replace(/^[^a-z0-9]+|[^a-z0-9]+$/g, "")).filter((t) => t.length >= 2)
48072
+ );
48073
+ }
48074
+ function setsEqual(a, b) {
48075
+ if (a.size !== b.size) return false;
48076
+ for (const item of a) if (!b.has(item)) return false;
48077
+ return true;
48078
+ }
48079
+ function countOccurrences(haystack, needle) {
48080
+ if (!haystack || !needle) return 0;
48081
+ const lower = haystack.toLowerCase();
48082
+ let count = 0;
48083
+ let idx = 0;
48084
+ while ((idx = lower.indexOf(needle, idx)) !== -1) {
48085
+ count++;
48086
+ idx += needle.length;
48087
+ }
48088
+ return count;
48089
+ }
48090
+ var KIND_BOOST = {
48091
+ system: 5,
48092
+ resource: 3,
48093
+ role: 3,
48094
+ policy: 3,
48095
+ ontology: 1,
48096
+ knowledge: 0
48097
+ };
48098
+ function scoreEntry(entry, terms) {
48099
+ let total = 0;
48100
+ const idLower = entry.id.toLowerCase();
48101
+ for (const term of terms) {
48102
+ for (const text of entry.high) total += 8 * countOccurrences(text, term);
48103
+ for (const text of entry.mid) total += 4 * countOccurrences(text, term);
48104
+ for (const text of entry.meta) total += 3 * countOccurrences(text, term);
48105
+ for (const text of entry.low) total += 1 * countOccurrences(text, term);
48106
+ }
48107
+ if (total === 0) return 0;
48108
+ const queryTokenSet = new Set(terms);
48109
+ if (terms.length === 1 && idLower === terms[0]) total += 50;
48110
+ const titleTokens = structuralTokens(entry.title);
48111
+ if (setsEqual(queryTokenSet, titleTokens)) total += 25;
48112
+ const lastSegment = idLower.split(".").pop() ?? idLower;
48113
+ if (setsEqual(queryTokenSet, structuralTokens(lastSegment))) total += 20;
48114
+ if (terms.every((t) => idLower.includes(t))) total += 5;
48115
+ total += KIND_BOOST[entry.kind];
48116
+ return total;
48117
+ }
48118
+ function collectSearchable(model, kinds) {
48119
+ const entries = [];
48120
+ const include = (kind) => kinds === null || kinds.has(kind);
48121
+ if (include("knowledge")) {
48122
+ for (const node of Object.values(model.knowledge ?? {})) {
48123
+ entries.push({
48124
+ kind: "knowledge",
48125
+ id: node.id,
48126
+ title: node.title,
48127
+ summary: node.summary,
48128
+ subKind: node.kind,
48129
+ high: [node.id, node.title],
48130
+ mid: [node.summary],
48131
+ meta: [node.kind, ...node.ownerIds ?? []],
48132
+ low: [node.body]
48133
+ });
48134
+ }
48135
+ }
48136
+ if (include("system")) {
48137
+ for (const { path: path3, system } of listAllSystems(model)) {
48138
+ const title = system.label ?? system.title ?? path3;
48139
+ const description = system.description ?? "";
48140
+ entries.push({
48141
+ kind: "system",
48142
+ id: path3,
48143
+ title,
48144
+ summary: description,
48145
+ subKind: system.kind,
48146
+ high: [path3, title],
48147
+ mid: [description],
48148
+ meta: [system.kind ?? "", system.lifecycle ?? "", system.responsibleRoleId ?? ""],
48149
+ low: []
48150
+ });
48151
+ if (include("ontology") && system.ontology) {
48152
+ entries.push(...collectOntologyEntries(system.ontology));
48153
+ }
48154
+ }
48155
+ } else if (include("ontology")) {
48156
+ for (const { system } of listAllSystems(model)) {
48157
+ if (system.ontology) entries.push(...collectOntologyEntries(system.ontology));
48158
+ }
48159
+ }
48160
+ if (include("ontology") && model.ontology) {
48161
+ entries.push(...collectOntologyEntries(model.ontology));
48162
+ }
48163
+ if (include("resource")) {
48164
+ for (const resource of Object.values(model.resources ?? {})) {
48165
+ const title = resource.title ?? resource.id;
48166
+ const description = resource.description ?? "";
48167
+ entries.push({
48168
+ kind: "resource",
48169
+ id: resource.id,
48170
+ title,
48171
+ summary: description,
48172
+ subKind: resource.kind,
48173
+ high: [resource.id, title],
48174
+ mid: [description],
48175
+ meta: [resource.kind, resource.systemPath, resource.status, resource.ownerRoleId ?? ""],
48176
+ low: []
48177
+ });
48178
+ }
48179
+ }
48180
+ if (include("role")) {
48181
+ for (const role of Object.values(model.roles ?? {})) {
48182
+ const responsibilities = role.responsibilities ?? [];
48183
+ entries.push({
48184
+ kind: "role",
48185
+ id: role.id,
48186
+ title: role.title,
48187
+ summary: responsibilities[0] ?? "",
48188
+ high: [role.id, role.title],
48189
+ mid: [],
48190
+ meta: responsibilities,
48191
+ low: []
48192
+ });
48193
+ }
48194
+ }
48195
+ if (include("policy")) {
48196
+ for (const policy of Object.values(model.policies ?? {})) {
48197
+ const description = policy.description ?? "";
48198
+ entries.push({
48199
+ kind: "policy",
48200
+ id: policy.id,
48201
+ title: policy.label,
48202
+ summary: description,
48203
+ subKind: policy.trigger?.kind,
48204
+ high: [policy.id, policy.label],
48205
+ mid: [description],
48206
+ meta: [policy.trigger?.kind ?? ""],
48207
+ low: []
48208
+ });
48209
+ }
48210
+ }
48211
+ return entries;
48212
+ }
48213
+ function collectOntologyEntries(scope) {
48214
+ const entries = [];
48215
+ const buckets = [
48216
+ ["object", scope.objectTypes],
48217
+ ["link", scope.linkTypes],
48218
+ ["action", scope.actionTypes],
48219
+ ["catalog", scope.catalogTypes],
48220
+ ["event", scope.eventTypes],
48221
+ ["interface", scope.interfaceTypes],
48222
+ ["value-type", scope.valueTypes],
48223
+ ["property", scope.sharedProperties],
48224
+ ["group", scope.groups],
48225
+ ["surface", scope.surfaces]
48226
+ ];
48227
+ for (const [subKind, records] of buckets) {
48228
+ if (!records) continue;
48229
+ for (const [recordId, record2] of Object.entries(records)) {
48230
+ const id = record2.id ?? recordId;
48231
+ const title = record2.label ?? id;
48232
+ const description = record2.description ?? "";
48233
+ entries.push({
48234
+ kind: "ontology",
48235
+ id,
48236
+ title,
48237
+ summary: description,
48238
+ subKind,
48239
+ high: [id, title],
48240
+ mid: [description],
48241
+ meta: [subKind],
48242
+ low: []
48243
+ });
48244
+ }
48245
+ }
48246
+ return entries;
48247
+ }
48248
+ function detectKind(model, id) {
48249
+ if (/:(object|action|event|catalog|link|interface|value-type|property|group|surface)\//.test(id)) {
48250
+ return "ontology";
48251
+ }
48252
+ if (id.startsWith("knowledge.")) return "knowledge";
48253
+ if (id.startsWith("role.")) return "role";
48254
+ if (id.startsWith("policy.")) return "policy";
48255
+ if (model.systems && getSystemByPath(model.systems, id)) return "system";
48256
+ if (model.resources?.[id]) return "resource";
48257
+ return void 0;
48258
+ }
48259
+ function getSystemByPath(systems, path3) {
48260
+ const segments = path3.split(".");
48261
+ let current = systems;
48262
+ for (const seg of segments) {
48263
+ const node = current[seg];
48264
+ if (node === void 0 || typeof node !== "object" || node === null) return void 0;
48265
+ const next = node;
48266
+ if (seg === segments[segments.length - 1]) return next;
48267
+ current = next.systems ?? next.subsystems ?? {};
48268
+ }
48269
+ return void 0;
48270
+ }
48271
+ function omDescribe(model, id) {
48272
+ const kind = detectKind(model, id);
48273
+ if (kind === void 0) return void 0;
48274
+ switch (kind) {
48275
+ case "system":
48276
+ return describeSystem(model, id);
48277
+ case "resource":
48278
+ return describeResource(model, id);
48279
+ case "knowledge":
48280
+ return describeKnowledge(model, id);
48281
+ case "ontology":
48282
+ return describeOntology(model, id);
48283
+ case "role":
48284
+ return describeRole(model, id);
48285
+ case "policy":
48286
+ return describePolicy(model, id);
48287
+ }
48288
+ }
48289
+ function describeSystem(model, path3) {
48290
+ const allSystems = listAllSystems(model);
48291
+ const match = allSystems.find((s) => s.path === path3);
48292
+ if (!match) return void 0;
48293
+ const { system } = match;
48294
+ const prefix = path3 + ".";
48295
+ const childSystemPaths = allSystems.filter((s) => s.path.startsWith(prefix) && !s.path.slice(prefix.length).includes(".")).map((s) => s.path);
48296
+ const resources = Object.values(model.resources ?? {}).filter((r) => r.systemPath === path3);
48297
+ const resourceCountsByKind = {};
48298
+ const resourceIdsByKind = {};
48299
+ for (const r of resources) {
48300
+ resourceCountsByKind[r.kind] = (resourceCountsByKind[r.kind] ?? 0) + 1;
48301
+ if (!resourceIdsByKind[r.kind]) resourceIdsByKind[r.kind] = [];
48302
+ resourceIdsByKind[r.kind].push(r.id);
48303
+ }
48304
+ const governingKnowledgeIds = [];
48305
+ for (const node of Object.values(model.knowledge ?? {})) {
48306
+ if ((node.links ?? []).some((link) => link.nodeId === `system:${path3}`)) {
48307
+ governingKnowledgeIds.push(node.id);
48308
+ }
48309
+ }
48310
+ const ontologyCountsByKind = {};
48311
+ const ontology = system.ontology;
48312
+ if (ontology) {
48313
+ const buckets = [
48314
+ ["object", ontology.objectTypes],
48315
+ ["action", ontology.actionTypes],
48316
+ ["event", ontology.eventTypes],
48317
+ ["catalog", ontology.catalogTypes],
48318
+ ["link", ontology.linkTypes],
48319
+ ["interface", ontology.interfaceTypes],
48320
+ ["value-type", ontology.valueTypes],
48321
+ ["property", ontology.sharedProperties],
48322
+ ["group", ontology.groups],
48323
+ ["surface", ontology.surfaces]
48324
+ ];
48325
+ for (const [k, records] of buckets) {
48326
+ const count = records ? Object.keys(records).length : 0;
48327
+ if (count > 0) ontologyCountsByKind[k] = count;
48328
+ }
48329
+ }
48330
+ return {
48331
+ kind: "system",
48332
+ id: path3,
48333
+ label: system.label ?? system.title ?? path3,
48334
+ description: system.description ?? "",
48335
+ systemKind: system.kind,
48336
+ lifecycle: system.lifecycle,
48337
+ parentSystemId: system.parentSystemId,
48338
+ responsibleRoleId: system.responsibleRoleId,
48339
+ childSystemPaths,
48340
+ governingKnowledgeIds,
48341
+ resourceCountsByKind,
48342
+ resourceIdsByKind,
48343
+ ontologyCountsByKind
48344
+ };
48345
+ }
48346
+ function describeResource(model, id) {
48347
+ const r = model.resources?.[id];
48348
+ if (!r) return void 0;
48349
+ return {
48350
+ kind: "resource",
48351
+ id: r.id,
48352
+ resourceKind: r.kind,
48353
+ systemPath: r.systemPath,
48354
+ title: r.title ?? r.id,
48355
+ description: r.description ?? "",
48356
+ status: r.status,
48357
+ ownerRoleId: r.ownerRoleId,
48358
+ ontology: r.ontology ? {
48359
+ primaryAction: r.ontology.primaryAction,
48360
+ actions: r.ontology.actions,
48361
+ reads: r.ontology.reads,
48362
+ writes: r.ontology.writes,
48363
+ emits: r.ontology.emits,
48364
+ usesCatalogs: r.ontology.usesCatalogs
48365
+ } : void 0,
48366
+ codeRefPaths: (r.codeRefs ?? []).map((c) => c.path)
48367
+ };
48368
+ }
48369
+ function describeKnowledge(model, id) {
48370
+ const node = model.knowledge?.[id];
48371
+ if (!node) return void 0;
48372
+ const bodyLines = node.body.split("\n");
48373
+ const bodyExcerpt = bodyLines.slice(0, 6).join("\n") + (bodyLines.length > 6 ? "\n..." : "");
48374
+ return {
48375
+ kind: "knowledge",
48376
+ id: node.id,
48377
+ knowledgeKind: node.kind,
48378
+ title: node.title,
48379
+ summary: node.summary,
48380
+ bodyExcerpt,
48381
+ bodyLineCount: bodyLines.length,
48382
+ ownerIds: node.ownerIds ?? [],
48383
+ governs: (node.links ?? []).map((link) => link.nodeId),
48384
+ updatedAt: node.updatedAt
48385
+ };
48386
+ }
48387
+ function describeOntology(model, id) {
48388
+ const parsed = id.match(/^([^:]+):([a-z-]+)\/(.+)$/);
48389
+ if (!parsed) return void 0;
48390
+ const [, scope, ontologyKind, localId] = parsed;
48391
+ const buckets = [
48392
+ ["object", "objectTypes"],
48393
+ ["action", "actionTypes"],
48394
+ ["event", "eventTypes"],
48395
+ ["catalog", "catalogTypes"],
48396
+ ["link", "linkTypes"],
48397
+ ["interface", "interfaceTypes"],
48398
+ ["value-type", "valueTypes"],
48399
+ ["property", "sharedProperties"],
48400
+ ["group", "groups"],
48401
+ ["surface", "surfaces"]
48402
+ ];
48403
+ const bucketKey = buckets.find((b) => b[0] === ontologyKind)?.[1];
48404
+ if (!bucketKey) return void 0;
48405
+ function findIn(scopeObj) {
48406
+ if (!scopeObj) return void 0;
48407
+ const records = scopeObj[bucketKey];
48408
+ return records?.[id];
48409
+ }
48410
+ let record2;
48411
+ for (const { system } of listAllSystems(model)) {
48412
+ record2 = findIn(system.ontology);
48413
+ if (record2) break;
48414
+ }
48415
+ if (!record2) record2 = findIn(model.ontology);
48416
+ if (!record2) return void 0;
48417
+ const governingKnowledgeIds = [];
48418
+ for (const node of Object.values(model.knowledge ?? {})) {
48419
+ if ((node.links ?? []).some((link) => link.nodeId === `ontology:${id}`)) {
48420
+ governingKnowledgeIds.push(node.id);
48421
+ }
48422
+ }
48423
+ return {
48424
+ kind: "ontology",
48425
+ id,
48426
+ ontologyKind,
48427
+ scope,
48428
+ localId,
48429
+ label: record2.label ?? id,
48430
+ description: record2.description ?? "",
48431
+ governingKnowledgeIds
48432
+ };
48433
+ }
48434
+ function describeRole(model, id) {
48435
+ const role = model.roles?.[id];
48436
+ if (!role) return void 0;
48437
+ return {
48438
+ kind: "role",
48439
+ id: role.id,
48440
+ title: role.title,
48441
+ responsibilities: role.responsibilities ?? [],
48442
+ responsibleFor: role.responsibleFor ?? [],
48443
+ reportsToId: role.reportsToId
48444
+ };
48445
+ }
48446
+ function describePolicy(model, id) {
48447
+ const policy = model.policies?.[id];
48448
+ if (!policy) return void 0;
48449
+ return {
48450
+ kind: "policy",
48451
+ id: policy.id,
48452
+ label: policy.label,
48453
+ description: policy.description ?? "",
48454
+ triggerKind: policy.trigger?.kind ?? "unknown",
48455
+ appliesToSystemIds: policy.appliesTo?.systemIds ?? [],
48456
+ appliesToActionIds: policy.appliesTo?.actionIds ?? [],
48457
+ appliesToResourceIds: policy.appliesTo?.resourceIds ?? [],
48458
+ appliesToRoleIds: policy.appliesTo?.roleIds ?? [],
48459
+ effectKinds: (policy.actions ?? []).map((a) => a.kind)
48460
+ };
48461
+ }
47756
48462
 
47757
48463
  // ../core/src/knowledge/format.ts
47758
48464
  function formatText(results) {
@@ -47783,6 +48489,159 @@ function formatIdsOnly(results) {
47783
48489
  const ids = results.map((r) => typeof r === "string" ? r : r.id);
47784
48490
  return ids.join("\n");
47785
48491
  }
48492
+ function formatOmSearchHits(hits) {
48493
+ if (hits.length === 0) return "(no results)";
48494
+ const kindWidth = Math.max(...hits.map((h) => labelForKind(h).length), 6);
48495
+ const idWidth = Math.max(...hits.map((h) => h.id.length), 4);
48496
+ const rows = hits.map((hit) => {
48497
+ const summary = hit.summary.length > 80 ? hit.summary.slice(0, 77) + "..." : hit.summary;
48498
+ const kindLabel = labelForKind(hit).padEnd(kindWidth);
48499
+ const idLabel = hit.id.padEnd(idWidth);
48500
+ const tail = summary ? ` \u2014 ${hit.title} \u2014 ${summary}` : ` \u2014 ${hit.title}`;
48501
+ return `${kindLabel} ${idLabel}${tail}`;
48502
+ });
48503
+ return rows.join("\n");
48504
+ }
48505
+ function labelForKind(hit) {
48506
+ return hit.subKind ? `[${hit.kind}/${hit.subKind}]` : `[${hit.kind}]`;
48507
+ }
48508
+ function formatOmDescribe(result) {
48509
+ if (!result) return "(node not found)";
48510
+ switch (result.kind) {
48511
+ case "system":
48512
+ return formatSystemDescribe(result);
48513
+ case "resource":
48514
+ return formatResourceDescribe(result);
48515
+ case "knowledge":
48516
+ return formatKnowledgeDescribe(result);
48517
+ case "ontology":
48518
+ return formatOntologyDescribe(result);
48519
+ case "role":
48520
+ return formatRoleDescribe(result);
48521
+ case "policy":
48522
+ return formatPolicyDescribe(result);
48523
+ }
48524
+ }
48525
+ function section(title, body) {
48526
+ return body ? `${title}:
48527
+ ${body}` : "";
48528
+ }
48529
+ function bullet(items) {
48530
+ if (items.length === 0) return " (none)";
48531
+ return items.map((i) => ` - ${i}`).join("\n");
48532
+ }
48533
+ function field(label, value) {
48534
+ return value === void 0 || value === null || value === "" ? "" : `${label}: ${value}`;
48535
+ }
48536
+ function join3(parts) {
48537
+ return parts.filter((p) => p.length > 0).join("\n\n");
48538
+ }
48539
+ function formatSystemDescribe(r) {
48540
+ const header = join3([
48541
+ `System: ${r.id}`,
48542
+ [
48543
+ field("Label", r.label),
48544
+ field("Kind", r.systemKind),
48545
+ field("Lifecycle", r.lifecycle),
48546
+ field("Parent", r.parentSystemId),
48547
+ field("Responsible role", r.responsibleRoleId)
48548
+ ].filter((s) => s.length > 0).join("\n"),
48549
+ r.description ? `Description: ${r.description}` : ""
48550
+ ]);
48551
+ const govSection = section("Governed by knowledge", bullet(r.governingKnowledgeIds));
48552
+ const resourceLines = [];
48553
+ const totalResources = Object.values(r.resourceCountsByKind).reduce((a, b) => a + b, 0);
48554
+ if (totalResources > 0) {
48555
+ for (const [kind, count] of Object.entries(r.resourceCountsByKind)) {
48556
+ const ids = r.resourceIdsByKind[kind] ?? [];
48557
+ const preview = ids.slice(0, 5).join(", ");
48558
+ const tail = ids.length > 5 ? `, ... (+${ids.length - 5})` : "";
48559
+ resourceLines.push(` ${kind}s (${count}): ${preview}${tail}`);
48560
+ }
48561
+ } else {
48562
+ resourceLines.push(" (none)");
48563
+ }
48564
+ const resourceSection = `Resources (${totalResources}):
48565
+ ${resourceLines.join("\n")}`;
48566
+ const ontologyEntries = Object.entries(r.ontologyCountsByKind);
48567
+ const ontologySection = ontologyEntries.length ? `Ontology: ${ontologyEntries.map(([k, n]) => `${k}s: ${n}`).join(", ")}` : "";
48568
+ const childSection = section("Subsystems", bullet(r.childSystemPaths));
48569
+ return join3([header, govSection, resourceSection, ontologySection, childSection]);
48570
+ }
48571
+ function formatResourceDescribe(r) {
48572
+ const header = join3([
48573
+ `Resource: ${r.id}`,
48574
+ [
48575
+ field("Kind", r.resourceKind),
48576
+ field("System", r.systemPath),
48577
+ field("Title", r.title),
48578
+ field("Status", r.status),
48579
+ field("Owner role", r.ownerRoleId)
48580
+ ].filter((s) => s.length > 0).join("\n"),
48581
+ r.description ? `Description: ${r.description}` : ""
48582
+ ]);
48583
+ const ontologyLines = [];
48584
+ if (r.ontology) {
48585
+ if (r.ontology.primaryAction) ontologyLines.push(` primary action: ${r.ontology.primaryAction}`);
48586
+ if (r.ontology.actions?.length) ontologyLines.push(` actions: ${r.ontology.actions.join(", ")}`);
48587
+ if (r.ontology.reads?.length) ontologyLines.push(` reads: ${r.ontology.reads.join(", ")}`);
48588
+ if (r.ontology.writes?.length) ontologyLines.push(` writes: ${r.ontology.writes.join(", ")}`);
48589
+ if (r.ontology.emits?.length) ontologyLines.push(` emits: ${r.ontology.emits.join(", ")}`);
48590
+ if (r.ontology.usesCatalogs?.length) ontologyLines.push(` uses catalogs: ${r.ontology.usesCatalogs.join(", ")}`);
48591
+ }
48592
+ const ontologySection = ontologyLines.length ? `Ontology bindings:
48593
+ ${ontologyLines.join("\n")}` : "";
48594
+ const codeRefsSection = r.codeRefPaths.length ? `Code refs:
48595
+ ${bullet(r.codeRefPaths)}` : "";
48596
+ return join3([header, ontologySection, codeRefsSection]);
48597
+ }
48598
+ function formatKnowledgeDescribe(r) {
48599
+ const header = join3([
48600
+ `Knowledge: ${r.id}`,
48601
+ [field("Kind", r.knowledgeKind), field("Title", r.title), field("Updated", r.updatedAt)].filter((s) => s.length > 0).join("\n"),
48602
+ r.summary ? `Summary: ${r.summary}` : ""
48603
+ ]);
48604
+ const ownerSection = r.ownerIds.length ? `Owned by:
48605
+ ${bullet(r.ownerIds)}` : "";
48606
+ const govSection = section("Governs", bullet(r.governs));
48607
+ const bodySection = `Body excerpt (${r.bodyLineCount} lines total \u2014 use knowledge:cat for full):
48608
+ ${r.bodyExcerpt}`;
48609
+ return join3([header, ownerSection, govSection, bodySection]);
48610
+ }
48611
+ function formatOntologyDescribe(r) {
48612
+ const header = join3([
48613
+ `Ontology: ${r.id}`,
48614
+ [field("Kind", r.ontologyKind), field("Scope", r.scope), field("Local id", r.localId), field("Label", r.label)].filter((s) => s.length > 0).join("\n"),
48615
+ r.description ? `Description: ${r.description}` : ""
48616
+ ]);
48617
+ const govSection = section("Governed by knowledge", bullet(r.governingKnowledgeIds));
48618
+ return join3([header, govSection]);
48619
+ }
48620
+ function formatRoleDescribe(r) {
48621
+ const header = join3([
48622
+ `Role: ${r.id}`,
48623
+ [field("Title", r.title), field("Reports to", r.reportsToId)].filter((s) => s.length > 0).join("\n")
48624
+ ]);
48625
+ const respSection = section("Responsibilities", bullet(r.responsibilities));
48626
+ const responsibleForSection = section("Responsible for systems", bullet(r.responsibleFor));
48627
+ return join3([header, respSection, responsibleForSection]);
48628
+ }
48629
+ function formatPolicyDescribe(r) {
48630
+ const header = join3([
48631
+ `Policy: ${r.id}`,
48632
+ [field("Label", r.label), field("Trigger", r.triggerKind)].filter((s) => s.length > 0).join("\n"),
48633
+ r.description ? `Description: ${r.description}` : ""
48634
+ ]);
48635
+ const effectSection = section("Effect kinds", bullet(r.effectKinds));
48636
+ const appliesLines = [];
48637
+ if (r.appliesToSystemIds.length) appliesLines.push(` systems: ${r.appliesToSystemIds.join(", ")}`);
48638
+ if (r.appliesToActionIds.length) appliesLines.push(` actions: ${r.appliesToActionIds.join(", ")}`);
48639
+ if (r.appliesToResourceIds.length) appliesLines.push(` resources: ${r.appliesToResourceIds.join(", ")}`);
48640
+ if (r.appliesToRoleIds.length) appliesLines.push(` roles: ${r.appliesToRoleIds.join(", ")}`);
48641
+ const appliesSection = appliesLines.length ? `Applies to:
48642
+ ${appliesLines.join("\n")}` : "";
48643
+ return join3([header, effectSection, appliesSection]);
48644
+ }
47786
48645
 
47787
48646
  // src/cli/commands/knowledge/load-org-model.ts
47788
48647
  var import_path3 = require("path");
@@ -47840,8 +48699,8 @@ async function loadOrgModel(projectRoot) {
47840
48699
 
47841
48700
  // src/cli/commands/knowledge/ls.ts
47842
48701
  function registerKnowledgeLs(program3) {
47843
- program3.command("knowledge:ls <path>").description(
47844
- "List knowledge nodes for a Knowledge Map path\n Examples:\n elevasis-sdk knowledge:ls /by-kind/playbook\n elevasis-sdk knowledge:ls /by-system/sales.crm\n elevasis-sdk knowledge:ls /by-ontology/sales.crm:object/deal\n elevasis-sdk knowledge:ls /by-owner/role.ops-lead\n elevasis-sdk knowledge:ls /graph/knowledge.outreach-playbook/governs\n elevasis-sdk knowledge:ls /graph/system:sales.crm/governed-by"
48702
+ program3.command("knowledge:ls <path>").alias("om:ls").description(
48703
+ "List knowledge nodes for a Knowledge Map path\n Examples:\n elevasis-sdk om:ls /by-kind/playbook\n elevasis-sdk om:ls /by-system/sales.crm\n elevasis-sdk om:ls /by-ontology/sales.crm:object/deal\n elevasis-sdk om:ls /by-owner/role.ops-lead\n elevasis-sdk om:ls /graph/knowledge.outreach-playbook/governs\n elevasis-sdk om:ls /graph/system:sales.crm/governed-by"
47845
48704
  ).option("--json", "Print wrapped JSON envelope { path, mount, args, results }").option("--ids-only", "Print one ID per line (for piping)").action(
47846
48705
  wrapAction("knowledge:ls", async (pathArg, options) => {
47847
48706
  let parsed;
@@ -47920,8 +48779,8 @@ function registerKnowledgeLs(program3) {
47920
48779
 
47921
48780
  // src/cli/commands/knowledge/cat.ts
47922
48781
  function registerKnowledgeCat(program3) {
47923
- program3.command("knowledge:cat <id>").description(
47924
- "Print the raw MDX body of a knowledge node\n Example: elevasis-sdk knowledge:cat knowledge.outreach-playbook\n Use --json for structured output"
48782
+ program3.command("knowledge:cat <id>").alias("om:cat").description(
48783
+ "Print the raw MDX body of a knowledge node\n Example: elevasis-sdk om:cat knowledge.outreach-playbook\n Use --json for structured output"
47925
48784
  ).option("--json", "Return structured JSON with node fields").action(
47926
48785
  wrapAction("knowledge:cat", async (id, options) => {
47927
48786
  const projectRoot = getProjectRoot();
@@ -47943,8 +48802,8 @@ function registerKnowledgeCat(program3) {
47943
48802
 
47944
48803
  // src/cli/commands/knowledge/graph.ts
47945
48804
  function registerKnowledgeGraph(program3) {
47946
- program3.command("knowledge:graph <id>").description(
47947
- "Show outgoing and incoming edges for a knowledge node\n Example: elevasis-sdk knowledge:graph knowledge.outreach-playbook\n Accepts bare OM node id or graph node id (knowledge:<id>)"
48805
+ program3.command("knowledge:graph <id>").alias("om:graph").description(
48806
+ "Show outgoing and incoming edges for a knowledge node\n Example: elevasis-sdk om:graph knowledge.outreach-playbook\n Accepts bare OM node id or graph node id (knowledge:<id>)"
47948
48807
  ).option("--json", "Print JSON: { nodeId, outgoing: string[], incoming: string[] }").option("--ids-only", "Print one edge ID per line (outgoing first, then incoming)").action(
47949
48808
  wrapAction("knowledge:graph", async (id, options) => {
47950
48809
  const projectRoot = getProjectRoot();
@@ -48078,8 +48937,8 @@ function resolveKnowledgeInvocationNeighbors(model, id) {
48078
48937
  };
48079
48938
  }
48080
48939
  function registerKnowledgeSkills(program3) {
48081
- program3.command("knowledge:skills <id>").description(
48082
- "Show callable invocations on graph neighbors for a knowledge node\n Example: elevasis-sdk knowledge:skills knowledge.new-vertical-launch-playbook"
48940
+ program3.command("knowledge:skills <id>").alias("om:skills").description(
48941
+ "Show callable invocations on graph neighbors for a knowledge node\n Example: elevasis-sdk om:skills knowledge.new-vertical-launch-playbook"
48083
48942
  ).option("--json", "Print JSON: { id, title, invocationSources }").action(
48084
48943
  wrapAction("knowledge:skills", async (id, options) => {
48085
48944
  const projectRoot = getProjectRoot();
@@ -48478,8 +49337,8 @@ function generateKnowledgeNodes(options) {
48478
49337
 
48479
49338
  // src/cli/commands/knowledge/generate.ts
48480
49339
  function registerKnowledgeGenerate(program3) {
48481
- program3.command("knowledge:generate").description(
48482
- "Generate OrganizationModel knowledge nodes from MDX source files\n Example: elevasis-sdk knowledge:generate"
49340
+ program3.command("knowledge:generate").alias("om:generate").description(
49341
+ "Generate OrganizationModel knowledge nodes from MDX source files\n Example: elevasis-sdk om:generate"
48483
49342
  ).option("--source <path>", "MDX source directory relative to project root", "core/config/knowledge/nodes").option(
48484
49343
  "--output <path>",
48485
49344
  "Generated TS file relative to project root",
@@ -48518,6 +49377,83 @@ function registerKnowledgeGenerate(program3) {
48518
49377
  );
48519
49378
  }
48520
49379
 
49380
+ // src/cli/commands/knowledge/search.ts
49381
+ var ALL_KINDS = ["system", "resource", "knowledge", "ontology", "role", "policy"];
49382
+ function parseLimit(raw) {
49383
+ if (raw === void 0) return 10;
49384
+ const n = Number.parseInt(raw, 10);
49385
+ if (Number.isNaN(n) || n < 0) {
49386
+ throw new Error(`knowledge:search: --limit must be a non-negative integer (got "${raw}")`);
49387
+ }
49388
+ return n;
49389
+ }
49390
+ function parseKinds(raw) {
49391
+ if (raw === void 0) return void 0;
49392
+ const requested = raw.split(",").map((s) => s.trim().toLowerCase()).filter((s) => s.length > 0);
49393
+ const valid = [];
49394
+ const invalid = [];
49395
+ for (const kind of requested) {
49396
+ if (ALL_KINDS.includes(kind)) {
49397
+ valid.push(kind);
49398
+ } else {
49399
+ invalid.push(kind);
49400
+ }
49401
+ }
49402
+ if (invalid.length > 0) {
49403
+ throw new Error(`knowledge:search: unknown kind(s) "${invalid.join(", ")}". Valid: ${ALL_KINDS.join(", ")}`);
49404
+ }
49405
+ return valid.length > 0 ? valid : void 0;
49406
+ }
49407
+ function registerKnowledgeSearch(program3) {
49408
+ program3.command("knowledge:search <query>").alias("om:search").description(
49409
+ 'Universal keyword search across the entire Organization Model\n (systems, resources, knowledge, ontology, roles, policies)\n Example: elevasis-sdk om:search "lead gen"\n Example: elevasis-sdk om:search outreach --kinds knowledge\n Example: elevasis-sdk om:search apollo --ids-only'
49410
+ ).option("--limit <n>", "max number of hits to return (0 = unlimited)", "10").option("--kinds <list>", "comma-separated kinds filter (system,resource,knowledge,ontology,role,policy)").option("--json", "Print wrapped JSON envelope").option("--ids-only", "Print one ID per line (for piping)").action(
49411
+ wrapAction("knowledge:search", async (query, options) => {
49412
+ const limit = parseLimit(options.limit);
49413
+ const kinds = parseKinds(options.kinds);
49414
+ const projectRoot = getProjectRoot();
49415
+ const model = await loadOrgModel(projectRoot);
49416
+ const hits = omSearch(model, query, { limit, kinds });
49417
+ if (options.json) {
49418
+ const envelope = { query, limit, kinds: kinds ?? null, count: hits.length, results: hits };
49419
+ process.stdout.write(JSON.stringify(envelope, null, 2) + "\n");
49420
+ return;
49421
+ }
49422
+ if (options.idsOnly) {
49423
+ const output = formatIdsOnly(hits);
49424
+ if (output) process.stdout.write(output + "\n");
49425
+ return;
49426
+ }
49427
+ process.stdout.write(formatOmSearchHits(hits) + "\n");
49428
+ })
49429
+ );
49430
+ }
49431
+
49432
+ // src/cli/commands/knowledge/describe.ts
49433
+ function registerKnowledgeDescribe(program3) {
49434
+ program3.command("knowledge:describe <nodeId>").alias("om:describe").description(
49435
+ "Show a structured neighborhood view for any OM node id\n (system, resource, knowledge, ontology, role, policy \u2014 auto-detected from id shape)\n Example: elevasis-sdk om:describe sales.lead-gen\n Example: elevasis-sdk om:describe knowledge.outreach-playbook"
49436
+ ).option("--json", "Print as JSON").action(
49437
+ wrapAction("knowledge:describe", async (nodeId2, options) => {
49438
+ const projectRoot = getProjectRoot();
49439
+ const model = await loadOrgModel(projectRoot);
49440
+ const result = omDescribe(model, nodeId2);
49441
+ if (!result) {
49442
+ process.stderr.write(
49443
+ `knowledge:describe: no OM node found for id "${nodeId2}". Use knowledge:search (alias: om:search) to discover nodes by keyword.
49444
+ `
49445
+ );
49446
+ process.exit(1);
49447
+ }
49448
+ if (options.json) {
49449
+ process.stdout.write(JSON.stringify(result, null, 2) + "\n");
49450
+ return;
49451
+ }
49452
+ process.stdout.write(formatOmDescribe(result) + "\n");
49453
+ })
49454
+ );
49455
+ }
49456
+
48521
49457
  // src/cli/commands/knowledge/index.ts
48522
49458
  function registerKnowledgeCommands(program3) {
48523
49459
  registerKnowledgeGenerate(program3);
@@ -48525,6 +49461,8 @@ function registerKnowledgeCommands(program3) {
48525
49461
  registerKnowledgeCat(program3);
48526
49462
  registerKnowledgeGraph(program3);
48527
49463
  registerKnowledgeSkills(program3);
49464
+ registerKnowledgeSearch(program3);
49465
+ registerKnowledgeDescribe(program3);
48528
49466
  }
48529
49467
 
48530
49468
  // src/cli/commands/request/request.ts