@elevasis/sdk 1.33.0 → 1.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/cli.cjs CHANGED
@@ -23715,7 +23715,6 @@ function emitSystemEntry(opts) {
23715
23715
  const apiInterfaceBlock = opts.apiBacked ? `
23716
23716
  apiInterface: {
23717
23717
  lifecycle: 'active',
23718
- readinessProfile: 'standard',
23719
23718
  resourceIds: []
23720
23719
  },` : "";
23721
23720
  const code = ` {
@@ -24210,7 +24209,6 @@ function emitApiInterfaceBlock(gap) {
24210
24209
 
24211
24210
  export const ${constName} = {
24212
24211
  lifecycle: 'active' as const,
24213
- readinessProfile: 'standard' as const,
24214
24212
  resourceIds: ${resourceIdsLiteral}
24215
24213
  }
24216
24214
  `;
@@ -37928,7 +37926,8 @@ var ONTOLOGY_REFERENCE_KEY_KINDS = {
37928
37926
  surfaceType: "surface",
37929
37927
  stepCatalog: "catalog"
37930
37928
  };
37931
- function buildOmCrossRefIndex(model) {
37929
+ var omCompilationContextCache = /* @__PURE__ */ new WeakMap();
37930
+ function buildOmCrossRefIndexFromOntology(model, ontologyCompilation) {
37932
37931
  const systemsById = /* @__PURE__ */ new Map();
37933
37932
  for (const { path: path3, system } of listAllSystems(model)) {
37934
37933
  systemsById.set(path3, system);
@@ -37942,7 +37941,6 @@ function buildOmCrossRefIndex(model) {
37942
37941
  const actionIds = new Set(Object.keys(model.actions ?? {}));
37943
37942
  const customerSegmentIds = new Set(Object.keys(model.customers ?? {}));
37944
37943
  const offeringIds = new Set(Object.keys(model.offerings ?? {}));
37945
- const ontologyCompilation = compileOrganizationOntology(model);
37946
37944
  const ontologyIndexByKind = {
37947
37945
  object: ontologyCompilation.ontology.objectTypes,
37948
37946
  link: ontologyCompilation.ontology.linkTypes,
@@ -37981,6 +37979,15 @@ function buildOmCrossRefIndex(model) {
37981
37979
  stageIds
37982
37980
  };
37983
37981
  }
37982
+ function buildOmCompilationContext(model) {
37983
+ const cached2 = omCompilationContextCache.get(model);
37984
+ if (cached2 !== void 0) return cached2;
37985
+ const ontologyCompilation = compileOrganizationOntology(model);
37986
+ const crossRefIndex = buildOmCrossRefIndexFromOntology(model, ontologyCompilation);
37987
+ const context = { crossRefIndex, ontologyCompilation };
37988
+ omCompilationContextCache.set(model, context);
37989
+ return context;
37990
+ }
37984
37991
  function knowledgeTargetExists(index, kind, id) {
37985
37992
  if (kind === "system") return index.systemsById.has(id);
37986
37993
  if (kind === "client") return index.clientIds.has(id);
@@ -38632,8 +38639,6 @@ var SystemEntrySchema = external_exports.object({
38632
38639
  path: PathSchema.optional(),
38633
38640
  /** @deprecated Use ui.icon. Kept for one-cycle Feature compatibility. */
38634
38641
  icon: IconNameSchema.optional(),
38635
- /** @deprecated Feature color token, retained for one-cycle compatibility. */
38636
- color: ColorTokenSchema.optional(),
38637
38642
  /** @deprecated UI placement hint, retained for one-cycle compatibility. */
38638
38643
  uiPosition: UiPositionSchema.optional(),
38639
38644
  /** @deprecated Use lifecycle. */
@@ -38730,7 +38735,7 @@ var ResourceOntologyBindingSchema = external_exports.object({
38730
38735
  /**
38731
38736
  * Optional typed contract binding for this resource's workflow I/O.
38732
38737
  * Each ref is a `package/subpath#ExportName` string that resolves to a
38733
- * Zod schema in `@repo/elevasis-core` (or the consumer's equivalent package).
38738
+ * Zod schema in the tenant-owned organization model package.
38734
38739
  *
38735
38740
  * Absence of this field preserves all existing behavior — it is additive + optional.
38736
38741
  * Tier-1 validation (schema.ts): ref-string shape only (browser-safe, no imports).
@@ -39489,9 +39494,8 @@ function refineOrganizationModel(model, ctx) {
39489
39494
  }
39490
39495
  });
39491
39496
  });
39492
- const idx = buildOmCrossRefIndex(model);
39497
+ const { crossRefIndex: idx, ontologyCompilation } = buildOmCompilationContext(model);
39493
39498
  const { ontologyIndexByKind, ontologyIds } = idx;
39494
- const ontologyCompilation = compileOrganizationOntology(model);
39495
39499
  function topologyTargetExists(ref) {
39496
39500
  if (ref.kind === "system") return systemsById.has(ref.id);
39497
39501
  if (ref.kind === "resource") return resourcesById.has(ref.id);
@@ -42173,6 +42177,20 @@ function validateDeclaredSystemInterfaceReadiness(orgName, organizationModel) {
42173
42177
  for (const { path: path3, system } of listAllSystems(model)) {
42174
42178
  if (system.apiInterface === void 0) continue;
42175
42179
  const interfaceKey = "api";
42180
+ const resourceIds = system.apiInterface.resourceIds ?? [];
42181
+ if (resourceIds.length === 0) {
42182
+ const readinessProfile = system.apiInterface.readinessProfile;
42183
+ if (readinessProfile !== void 0 && !SYSTEM_INTERFACE_PROFILES.some((profile) => profile.readinessProfile === readinessProfile)) {
42184
+ addSystemInterfaceIssue(issues, orgName, path3, interfaceKey, {
42185
+ family: "SYSTEM_INTERFACE_INVALID",
42186
+ code: "unknown-readiness-profile",
42187
+ path: `systems.${path3}.apiInterface.readinessProfile`,
42188
+ ref: readinessProfile,
42189
+ message: `System Interface "${path3}/${interfaceKey}" references unknown readiness profile "${readinessProfile}".`
42190
+ });
42191
+ }
42192
+ continue;
42193
+ }
42176
42194
  const result = computeInterfaceReadiness(model, { systemPath: path3, interfaceKey });
42177
42195
  for (const issue2 of result.issues) {
42178
42196
  addSystemInterfaceIssue(issues, orgName, path3, interfaceKey, issue2);
@@ -45716,7 +45734,7 @@ function wrapAction(commandName, fn) {
45716
45734
  // package.json
45717
45735
  var package_default = {
45718
45736
  name: "@elevasis/sdk",
45719
- version: "1.33.0",
45737
+ version: "1.33.1",
45720
45738
  description: "SDK for building Elevasis organization resources",
45721
45739
  type: "module",
45722
45740
  bin: {
@@ -49392,6 +49410,155 @@ ${appliesLines.join("\n")}` : "";
49392
49410
  return join5([header, effectSection, appliesSection]);
49393
49411
  }
49394
49412
 
49413
+ // ../core/src/knowledge/cli-helpers.ts
49414
+ var OM_SEARCH_HIT_KINDS = ["system", "resource", "knowledge", "ontology", "role", "policy"];
49415
+ function parseKnowledgeSearchLimit(raw, commandName = "knowledge:search") {
49416
+ if (raw === void 0) return 10;
49417
+ const n = Number.parseInt(raw, 10);
49418
+ if (Number.isNaN(n) || n < 0) {
49419
+ throw new Error(`${commandName}: --limit must be a non-negative integer (got "${raw}")`);
49420
+ }
49421
+ return n;
49422
+ }
49423
+ function parseKnowledgeSearchKinds(raw, commandName = "knowledge:search") {
49424
+ if (raw === void 0) return void 0;
49425
+ const requested = raw.split(",").map((s) => s.trim().toLowerCase()).filter((s) => s.length > 0);
49426
+ const valid = [];
49427
+ const invalid = [];
49428
+ for (const kind of requested) {
49429
+ if (OM_SEARCH_HIT_KINDS.includes(kind)) {
49430
+ valid.push(kind);
49431
+ } else {
49432
+ invalid.push(kind);
49433
+ }
49434
+ }
49435
+ if (invalid.length > 0) {
49436
+ throw new Error(`${commandName}: unknown kind(s) "${invalid.join(", ")}". Valid: ${OM_SEARCH_HIT_KINDS.join(", ")}`);
49437
+ }
49438
+ return valid.length > 0 ? valid : void 0;
49439
+ }
49440
+ function formatKnowledgeSystemsList(entries) {
49441
+ if (entries.length === 0) return "(no results)";
49442
+ const pathWidth = Math.max(...entries.map((e) => e.path.length), 4);
49443
+ const header = `${"PATH".padEnd(pathWidth)} LABEL`;
49444
+ const divider = "-".repeat(header.length + 20);
49445
+ const rows = entries.map((e) => {
49446
+ const label = e.system.label ?? e.system.title ?? e.path;
49447
+ return `${e.path.padEnd(pathWidth)} ${label}`;
49448
+ });
49449
+ return [header, divider, ...rows].join("\n");
49450
+ }
49451
+ function formatKnowledgeResourcesList(resources) {
49452
+ if (resources.length === 0) return "(no results)";
49453
+ const idWidth = Math.max(...resources.map((r) => r.id.length), 4);
49454
+ const kindWidth = Math.max(...resources.map((r) => r.kind.length), 4);
49455
+ const header = `${"ID".padEnd(idWidth)} ${"KIND".padEnd(kindWidth)} TITLE`;
49456
+ const divider = "-".repeat(header.length + 20);
49457
+ const rows = resources.map((r) => {
49458
+ const title = r.title ?? r.id;
49459
+ return `${r.id.padEnd(idWidth)} ${r.kind.padEnd(kindWidth)} ${title}`;
49460
+ });
49461
+ return [header, divider, ...rows].join("\n");
49462
+ }
49463
+ function formatKnowledgeRolesList(roles) {
49464
+ if (roles.length === 0) return "(no results)";
49465
+ const idWidth = Math.max(...roles.map((r) => r.id.length), 4);
49466
+ const header = `${"ID".padEnd(idWidth)} TITLE`;
49467
+ const divider = "-".repeat(header.length + 20);
49468
+ const rows = roles.map((r) => `${r.id.padEnd(idWidth)} ${r.title}`);
49469
+ return [header, divider, ...rows].join("\n");
49470
+ }
49471
+ function normalizeKnowledgeNodeId(id) {
49472
+ return id.startsWith("knowledge:") ? id.slice("knowledge:".length) : id;
49473
+ }
49474
+ function formatKnowledgeInvocationLabel(invocation) {
49475
+ switch (invocation.kind) {
49476
+ case "slash-command":
49477
+ return invocation.command;
49478
+ case "mcp-tool":
49479
+ return `${invocation.server}/${invocation.name}`;
49480
+ case "api-endpoint":
49481
+ return `${invocation.method} ${invocation.path}`;
49482
+ case "script-execution":
49483
+ return invocation.resourceId;
49484
+ }
49485
+ }
49486
+ function pushActionSource(sources, seen, action) {
49487
+ if (!action || action.invocations.length === 0) return;
49488
+ const key = `action:${action.id}`;
49489
+ if (seen.has(key)) return;
49490
+ seen.add(key);
49491
+ sources.push({
49492
+ kind: "action",
49493
+ id: action.id,
49494
+ label: action.label,
49495
+ targetNodeId: `action:${action.id}`,
49496
+ invocations: action.invocations
49497
+ });
49498
+ }
49499
+ function pushAgentResourceSource(sources, seen, resource) {
49500
+ if (!resource || resource.kind !== "agent" || resource.invocations.length === 0) return;
49501
+ const agentResource = resource;
49502
+ const key = `agent-resource:${agentResource.id}`;
49503
+ if (seen.has(key)) return;
49504
+ seen.add(key);
49505
+ sources.push({
49506
+ kind: "agent-resource",
49507
+ id: agentResource.id,
49508
+ label: agentResource.id,
49509
+ targetNodeId: `resource:${agentResource.id}`,
49510
+ invocations: agentResource.invocations
49511
+ });
49512
+ }
49513
+ function resolveKnowledgeInvocationNeighbors(model, id) {
49514
+ const normalizedNodeId = normalizeKnowledgeNodeId(id);
49515
+ const node = model.knowledge[normalizedNodeId];
49516
+ if (!node) return void 0;
49517
+ const sources = [];
49518
+ const seen = /* @__PURE__ */ new Set();
49519
+ for (const link of node.links) {
49520
+ const target = link.target;
49521
+ if (target.kind === "action") {
49522
+ pushActionSource(sources, seen, model.actions[target.id]);
49523
+ continue;
49524
+ }
49525
+ if (target.kind === "resource") {
49526
+ pushAgentResourceSource(sources, seen, model.resources[target.id]);
49527
+ continue;
49528
+ }
49529
+ if (target.kind === "system") {
49530
+ const system = getSystem(model, target.id);
49531
+ for (const actionRef of system?.actions ?? []) {
49532
+ pushActionSource(sources, seen, model.actions[actionRef.actionId]);
49533
+ }
49534
+ for (const resource of Object.values(model.resources)) {
49535
+ if (resource.systemPath === target.id) {
49536
+ pushAgentResourceSource(sources, seen, resource);
49537
+ }
49538
+ }
49539
+ }
49540
+ }
49541
+ return {
49542
+ id: node.id,
49543
+ title: node.title,
49544
+ invocationSources: sources.sort((a, b) => a.targetNodeId.localeCompare(b.targetNodeId))
49545
+ };
49546
+ }
49547
+ function formatKnowledgeInvocationNeighbors(result) {
49548
+ const lines = [`Invocation-bearing graph neighbors for ${result.id}`, ""];
49549
+ if (result.invocationSources.length === 0) {
49550
+ lines.push(" (none)");
49551
+ } else {
49552
+ for (const source of result.invocationSources) {
49553
+ lines.push(`${source.kind}: ${source.id}`);
49554
+ for (const invocation of source.invocations) {
49555
+ lines.push(` ${invocation.kind}: ${formatKnowledgeInvocationLabel(invocation)}`);
49556
+ }
49557
+ }
49558
+ }
49559
+ return lines.join("\n");
49560
+ }
49561
+
49395
49562
  // src/cli/commands/knowledge/ls.ts
49396
49563
  init_config();
49397
49564
 
@@ -49450,34 +49617,6 @@ async function loadOrgModel(projectRoot) {
49450
49617
  }
49451
49618
 
49452
49619
  // src/cli/commands/knowledge/ls.ts
49453
- function formatAllSystems(entries) {
49454
- if (entries.length === 0) return "(no results)";
49455
- const pathWidth = Math.max(...entries.map((e) => e.path.length), 4);
49456
- const header = `${"PATH".padEnd(pathWidth)} LABEL`;
49457
- const divider = "-".repeat(header.length + 20);
49458
- const rows = entries.map((e) => {
49459
- const label = e.system.label ?? e.system.title ?? e.path;
49460
- return `${e.path.padEnd(pathWidth)} ${label}`;
49461
- });
49462
- return [header, divider, ...rows].join("\n");
49463
- }
49464
- function formatAllResources(resources) {
49465
- if (resources.length === 0) return "(no results)";
49466
- const idWidth = Math.max(...resources.map((r) => r.id.length), 4);
49467
- const kindWidth = Math.max(...resources.map((r) => r.kind.length), 4);
49468
- const header = `${"ID".padEnd(idWidth)} ${"KIND".padEnd(kindWidth)} TITLE`;
49469
- const divider = "-".repeat(header.length + 20);
49470
- const rows = resources.map((r) => `${r.id.padEnd(idWidth)} ${r.kind.padEnd(kindWidth)} ${r.title}`);
49471
- return [header, divider, ...rows].join("\n");
49472
- }
49473
- function formatAllRoles(roles) {
49474
- if (roles.length === 0) return "(no results)";
49475
- const idWidth = Math.max(...roles.map((r) => r.id.length), 4);
49476
- const header = `${"ID".padEnd(idWidth)} TITLE`;
49477
- const divider = "-".repeat(header.length + 20);
49478
- const rows = roles.map((r) => `${r.id.padEnd(idWidth)} ${r.title}`);
49479
- return [header, divider, ...rows].join("\n");
49480
- }
49481
49620
  function registerKnowledgeLs(program3) {
49482
49621
  program3.command("knowledge:ls <path>").alias("om:ls").description(
49483
49622
  "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\n elevasis-sdk om:ls /all-systems\n elevasis-sdk om:ls /all-resources\n elevasis-sdk om:ls /all-roles"
@@ -49501,7 +49640,7 @@ function registerKnowledgeLs(program3) {
49501
49640
  const out = entries.map((e) => e.path).join("\n");
49502
49641
  if (out) process.stdout.write(out + "\n");
49503
49642
  } else {
49504
- process.stdout.write(formatAllSystems(entries) + "\n");
49643
+ process.stdout.write(formatKnowledgeSystemsList(entries) + "\n");
49505
49644
  }
49506
49645
  return;
49507
49646
  }
@@ -49513,7 +49652,7 @@ function registerKnowledgeLs(program3) {
49513
49652
  const out = resources.map((r) => r.id).join("\n");
49514
49653
  if (out) process.stdout.write(out + "\n");
49515
49654
  } else {
49516
- process.stdout.write(formatAllResources(resources) + "\n");
49655
+ process.stdout.write(formatKnowledgeResourcesList(resources) + "\n");
49517
49656
  }
49518
49657
  return;
49519
49658
  }
@@ -49525,7 +49664,7 @@ function registerKnowledgeLs(program3) {
49525
49664
  const out = roles.map((r) => r.id).join("\n");
49526
49665
  if (out) process.stdout.write(out + "\n");
49527
49666
  } else {
49528
- process.stdout.write(formatAllRoles(roles) + "\n");
49667
+ process.stdout.write(formatKnowledgeRolesList(roles) + "\n");
49529
49668
  }
49530
49669
  return;
49531
49670
  }
@@ -49679,82 +49818,6 @@ function registerKnowledgeGraph(program3) {
49679
49818
 
49680
49819
  // src/cli/commands/knowledge/skills.ts
49681
49820
  init_config();
49682
- function normalizeKnowledgeId(id) {
49683
- return id.startsWith("knowledge:") ? id.slice("knowledge:".length) : id;
49684
- }
49685
- function invocationLabel2(invocation) {
49686
- switch (invocation.kind) {
49687
- case "slash-command":
49688
- return invocation.command;
49689
- case "mcp-tool":
49690
- return `${invocation.server}/${invocation.name}`;
49691
- case "api-endpoint":
49692
- return `${invocation.method} ${invocation.path}`;
49693
- case "script-execution":
49694
- return invocation.resourceId;
49695
- }
49696
- }
49697
- function pushActionSource(sources, seen, action) {
49698
- if (!action || action.invocations.length === 0) return;
49699
- const key = `action:${action.id}`;
49700
- if (seen.has(key)) return;
49701
- seen.add(key);
49702
- sources.push({
49703
- kind: "action",
49704
- id: action.id,
49705
- label: action.label,
49706
- targetNodeId: `action:${action.id}`,
49707
- invocations: action.invocations
49708
- });
49709
- }
49710
- function pushAgentResourceSource(sources, seen, resource) {
49711
- if (!resource || resource.kind !== "agent" || resource.invocations.length === 0) return;
49712
- const agentResource = resource;
49713
- const key = `agent-resource:${agentResource.id}`;
49714
- if (seen.has(key)) return;
49715
- seen.add(key);
49716
- sources.push({
49717
- kind: "agent-resource",
49718
- id: agentResource.id,
49719
- label: agentResource.id,
49720
- targetNodeId: `resource:${agentResource.id}`,
49721
- invocations: agentResource.invocations
49722
- });
49723
- }
49724
- function resolveKnowledgeInvocationNeighbors(model, id) {
49725
- const normalizedNodeId = normalizeKnowledgeId(id);
49726
- const node = model.knowledge[normalizedNodeId];
49727
- if (!node) return void 0;
49728
- const sources = [];
49729
- const seen = /* @__PURE__ */ new Set();
49730
- for (const link of node.links) {
49731
- const target = link.target;
49732
- if (target.kind === "action") {
49733
- pushActionSource(sources, seen, model.actions[target.id]);
49734
- continue;
49735
- }
49736
- if (target.kind === "resource") {
49737
- pushAgentResourceSource(sources, seen, model.resources[target.id]);
49738
- continue;
49739
- }
49740
- if (target.kind === "system") {
49741
- const system = getSystem(model, target.id);
49742
- for (const actionRef of system?.actions ?? []) {
49743
- pushActionSource(sources, seen, model.actions[actionRef.actionId]);
49744
- }
49745
- for (const resource of Object.values(model.resources)) {
49746
- if (resource.systemPath === target.id) {
49747
- pushAgentResourceSource(sources, seen, resource);
49748
- }
49749
- }
49750
- }
49751
- }
49752
- return {
49753
- id: node.id,
49754
- title: node.title,
49755
- invocationSources: sources.sort((a, b) => a.targetNodeId.localeCompare(b.targetNodeId))
49756
- };
49757
- }
49758
49821
  function registerKnowledgeSkills(program3) {
49759
49822
  program3.command("knowledge:skills <id>").alias("om:skills").description(
49760
49823
  "Show callable invocations on graph neighbors for a knowledge node\n Example: elevasis-sdk om:skills knowledge.new-vertical-launch-playbook"
@@ -49772,18 +49835,7 @@ function registerKnowledgeSkills(program3) {
49772
49835
  process.stdout.write(JSON.stringify(result, null, 2) + "\n");
49773
49836
  return;
49774
49837
  }
49775
- const lines = [`Invocation-bearing graph neighbors for ${result.id}`, ""];
49776
- if (result.invocationSources.length === 0) {
49777
- lines.push(" (none)");
49778
- } else {
49779
- for (const source of result.invocationSources) {
49780
- lines.push(`${source.kind}: ${source.id}`);
49781
- for (const invocation of source.invocations) {
49782
- lines.push(` ${invocation.kind}: ${invocationLabel2(invocation)}`);
49783
- }
49784
- }
49785
- }
49786
- process.stdout.write(lines.join("\n") + "\n");
49838
+ process.stdout.write(formatKnowledgeInvocationNeighbors(result) + "\n");
49787
49839
  })
49788
49840
  );
49789
49841
  }
@@ -50199,39 +50251,13 @@ function registerKnowledgeGenerate(program3) {
50199
50251
 
50200
50252
  // src/cli/commands/knowledge/search.ts
50201
50253
  init_config();
50202
- var ALL_KINDS = ["system", "resource", "knowledge", "ontology", "role", "policy"];
50203
- function parseLimit(raw) {
50204
- if (raw === void 0) return 10;
50205
- const n = Number.parseInt(raw, 10);
50206
- if (Number.isNaN(n) || n < 0) {
50207
- throw new Error(`knowledge:search: --limit must be a non-negative integer (got "${raw}")`);
50208
- }
50209
- return n;
50210
- }
50211
- function parseKinds(raw) {
50212
- if (raw === void 0) return void 0;
50213
- const requested = raw.split(",").map((s) => s.trim().toLowerCase()).filter((s) => s.length > 0);
50214
- const valid = [];
50215
- const invalid = [];
50216
- for (const kind of requested) {
50217
- if (ALL_KINDS.includes(kind)) {
50218
- valid.push(kind);
50219
- } else {
50220
- invalid.push(kind);
50221
- }
50222
- }
50223
- if (invalid.length > 0) {
50224
- throw new Error(`knowledge:search: unknown kind(s) "${invalid.join(", ")}". Valid: ${ALL_KINDS.join(", ")}`);
50225
- }
50226
- return valid.length > 0 ? valid : void 0;
50227
- }
50228
50254
  function registerKnowledgeSearch(program3) {
50229
50255
  program3.command("knowledge:search <query>").alias("om:search").description(
50230
50256
  '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'
50231
50257
  ).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(
50232
50258
  wrapAction("knowledge:search", async (query, options) => {
50233
- const limit = parseLimit(options.limit);
50234
- const kinds = parseKinds(options.kinds);
50259
+ const limit = parseKnowledgeSearchLimit(options.limit);
50260
+ const kinds = parseKnowledgeSearchKinds(options.kinds);
50235
50261
  const projectRoot = getProjectRoot();
50236
50262
  const model = await loadOrgModel(projectRoot);
50237
50263
  const hits = omSearch(model, query, { limit, kinds });
package/dist/index.d.ts CHANGED
@@ -6728,7 +6728,6 @@ interface SystemEntry {
6728
6728
  status?: 'active' | 'deprecated' | 'archived';
6729
6729
  path?: string;
6730
6730
  icon?: string;
6731
- color?: string;
6732
6731
  uiPosition?: 'sidebar-primary' | 'sidebar-bottom';
6733
6732
  enabled?: boolean;
6734
6733
  devOnly?: boolean;
@@ -12224,7 +12223,7 @@ declare const ResourceOntologyBindingSchema = z
12224
12223
  /**
12225
12224
  * Optional typed contract binding for this resource's workflow I/O.
12226
12225
  * Each ref is a `package/subpath#ExportName` string that resolves to a
12227
- * Zod schema in `@repo/elevasis-core` (or the consumer's equivalent package).
12226
+ * Zod schema in the tenant-owned organization model package.
12228
12227
  *
12229
12228
  * Absence of this field preserves all existing behavior — it is additive + optional.
12230
12229
  * Tier-1 validation (schema.ts): ref-string shape only (browser-safe, no imports).
@@ -12476,7 +12475,7 @@ declare const ActionSchema = z.object({
12476
12475
  })
12477
12476
  type Action = z.infer<typeof ActionSchema>
12478
12477
 
12479
- // CRM stage/state catalogs are model-owned (authored in @repo/elevasis-core
12478
+ // CRM stage/state catalogs are model-owned (authored in the tenant-owned organization model package
12480
12479
  // canonicalOrganizationModel). The published core schema validates only the
12481
12480
  // transport shape; closed-catalog membership is enforced by the caller/API
12482
12481
  // layer via model-injected validators (mirrors LeadGenStageKeySchema).
@@ -12517,7 +12516,7 @@ declare function projectDeploymentSpec(options: ProjectDeploymentSpecOptions): D
12517
12516
  /**
12518
12517
  * Browser-safe generic workflow config helper.
12519
12518
  *
12520
- * Promoted from @repo/elevasis-core so any workflow family (lead-gen, CRM, etc.)
12519
+ * Promoted from the tenant-owned organization model layer so any workflow family (lead-gen, CRM, etc.)
12521
12520
  * can derive resourceId, actions, primaryAction, name, and description from
12522
12521
  * the canonical OM Resource descriptor without duplicating validation logic.
12523
12522
  *
package/dist/index.js CHANGED
@@ -682,8 +682,6 @@ var SystemEntrySchema = z.object({
682
682
  path: PathSchema.optional(),
683
683
  /** @deprecated Use ui.icon. Kept for one-cycle Feature compatibility. */
684
684
  icon: IconNameSchema.optional(),
685
- /** @deprecated Feature color token, retained for one-cycle compatibility. */
686
- color: ColorTokenSchema.optional(),
687
685
  /** @deprecated UI placement hint, retained for one-cycle compatibility. */
688
686
  uiPosition: UiPositionSchema.optional(),
689
687
  /** @deprecated Use lifecycle. */
@@ -779,7 +777,7 @@ var ResourceOntologyBindingSchema = z.object({
779
777
  /**
780
778
  * Optional typed contract binding for this resource's workflow I/O.
781
779
  * Each ref is a `package/subpath#ExportName` string that resolves to a
782
- * Zod schema in `@repo/elevasis-core` (or the consumer's equivalent package).
780
+ * Zod schema in the tenant-owned organization model package.
783
781
  *
784
782
  * Absence of this field preserves all existing behavior — it is additive + optional.
785
783
  * Tier-1 validation (schema.ts): ref-string shape only (browser-safe, no imports).
@@ -2526,6 +2524,20 @@ function validateDeclaredSystemInterfaceReadiness(orgName, organizationModel) {
2526
2524
  for (const { path, system } of listAllSystems(model)) {
2527
2525
  if (system.apiInterface === void 0) continue;
2528
2526
  const interfaceKey = "api";
2527
+ const resourceIds = system.apiInterface.resourceIds ?? [];
2528
+ if (resourceIds.length === 0) {
2529
+ const readinessProfile = system.apiInterface.readinessProfile;
2530
+ if (readinessProfile !== void 0 && !SYSTEM_INTERFACE_PROFILES.some((profile) => profile.readinessProfile === readinessProfile)) {
2531
+ addSystemInterfaceIssue(issues, orgName, path, interfaceKey, {
2532
+ family: "SYSTEM_INTERFACE_INVALID",
2533
+ code: "unknown-readiness-profile",
2534
+ path: `systems.${path}.apiInterface.readinessProfile`,
2535
+ ref: readinessProfile,
2536
+ message: `System Interface "${path}/${interfaceKey}" references unknown readiness profile "${readinessProfile}".`
2537
+ });
2538
+ }
2539
+ continue;
2540
+ }
2529
2541
  const result = computeInterfaceReadiness(model, { systemPath: path, interfaceKey });
2530
2542
  for (const issue of result.issues) {
2531
2543
  addSystemInterfaceIssue(issues, orgName, path, interfaceKey, issue);
@@ -1436,7 +1436,6 @@ interface SystemEntry {
1436
1436
  status?: 'active' | 'deprecated' | 'archived';
1437
1437
  path?: string;
1438
1438
  icon?: string;
1439
- color?: string;
1440
1439
  uiPosition?: 'sidebar-primary' | 'sidebar-bottom';
1441
1440
  enabled?: boolean;
1442
1441
  devOnly?: boolean;
@@ -3222,7 +3221,7 @@ declare const ResourceOntologyBindingSchema = z
3222
3221
  /**
3223
3222
  * Optional typed contract binding for this resource's workflow I/O.
3224
3223
  * Each ref is a `package/subpath#ExportName` string that resolves to a
3225
- * Zod schema in `@repo/elevasis-core` (or the consumer's equivalent package).
3224
+ * Zod schema in the tenant-owned organization model package.
3226
3225
  *
3227
3226
  * Absence of this field preserves all existing behavior — it is additive + optional.
3228
3227
  * Tier-1 validation (schema.ts): ref-string shape only (browser-safe, no imports).
@@ -5923,7 +5923,6 @@ interface SystemEntry {
5923
5923
  status?: 'active' | 'deprecated' | 'archived';
5924
5924
  path?: string;
5925
5925
  icon?: string;
5926
- color?: string;
5927
5926
  uiPosition?: 'sidebar-primary' | 'sidebar-bottom';
5928
5927
  enabled?: boolean;
5929
5928
  devOnly?: boolean;
@@ -8735,8 +8735,6 @@ var SystemEntrySchema = z.object({
8735
8735
  path: PathSchema.optional(),
8736
8736
  /** @deprecated Use ui.icon. Kept for one-cycle Feature compatibility. */
8737
8737
  icon: IconNameSchema.optional(),
8738
- /** @deprecated Feature color token, retained for one-cycle compatibility. */
8739
- color: ColorTokenSchema.optional(),
8740
8738
  /** @deprecated UI placement hint, retained for one-cycle compatibility. */
8741
8739
  uiPosition: UiPositionSchema.optional(),
8742
8740
  /** @deprecated Use lifecycle. */
@@ -9660,6 +9658,20 @@ function validateDeclaredSystemInterfaceReadiness(orgName, organizationModel) {
9660
9658
  for (const { path, system } of listAllSystems(model)) {
9661
9659
  if (system.apiInterface === void 0) continue;
9662
9660
  const interfaceKey = "api";
9661
+ const resourceIds = system.apiInterface.resourceIds ?? [];
9662
+ if (resourceIds.length === 0) {
9663
+ const readinessProfile = system.apiInterface.readinessProfile;
9664
+ if (readinessProfile !== void 0 && !SYSTEM_INTERFACE_PROFILES.some((profile) => profile.readinessProfile === readinessProfile)) {
9665
+ addSystemInterfaceIssue(issues, orgName, path, interfaceKey, {
9666
+ family: "SYSTEM_INTERFACE_INVALID",
9667
+ code: "unknown-readiness-profile",
9668
+ path: `systems.${path}.apiInterface.readinessProfile`,
9669
+ ref: readinessProfile,
9670
+ message: `System Interface "${path}/${interfaceKey}" references unknown readiness profile "${readinessProfile}".`
9671
+ });
9672
+ }
9673
+ continue;
9674
+ }
9663
9675
  const result = computeInterfaceReadiness(model, { systemPath: path, interfaceKey });
9664
9676
  for (const issue of result.issues) {
9665
9677
  addSystemInterfaceIssue(issues, orgName, path, interfaceKey, issue);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elevasis/sdk",
3
- "version": "1.33.0",
3
+ "version": "1.33.1",
4
4
  "description": "SDK for building Elevasis organization resources",
5
5
  "type": "module",
6
6
  "bin": {
@@ -58,7 +58,7 @@
58
58
  "tsup": "^8.0.0",
59
59
  "typescript": "5.9.2",
60
60
  "zod": "^4.1.0",
61
- "@repo/core": "0.42.0",
61
+ "@repo/core": "0.43.0",
62
62
  "@repo/eslint-config": "0.0.0",
63
63
  "@repo/typescript-config": "0.0.0"
64
64
  },
@@ -0,0 +1,34 @@
1
+ # Scaffold registry lane severity annotations
2
+
3
+ ## Why this note exists
4
+
5
+ This train adds `sync_lane_severity` annotations to the scaffold registry schema and moves external sync lane-severity ownership from hardcoded script sets into registry metadata.
6
+
7
+ The change is intended to keep project sync behavior the same while making the registry the single edit point for paths that need critical manual-merge handling or optional-feature-selection treatment.
8
+
9
+ ## Applies to
10
+
11
+ - Template-derived projects that use `/external sync` or `pnpm sync:apply` from the Elevasis monorepo.
12
+ - Projects that receive `@elevasis/core` package-baseline updates through `core/package.json` or `operations/package.json`.
13
+ - Operators reviewing external-sync plans that mention critical manual-merge or optional-feature-selection paths.
14
+
15
+ ## Required actions
16
+
17
+ 1. Run the prepared external sync from the release train so this note reaches derived projects.
18
+ 2. After the `@elevasis/core` publish stage, install the prepared core package baseline in template-derived project package files.
19
+ 3. Review any sync plan lane labels against the registry entry metadata before widening a manifest or applying catch-up work.
20
+
21
+ No project-authored Organization Model content should be overwritten for this train.
22
+
23
+ ## Verification
24
+
25
+ ```bash
26
+ pnpm sync:verify
27
+ pnpm exec tsx scripts/external/sync-apply.ts --all --dry-run --manifest apps/docs/content/docs/in-progress/active-development/sdk-changes/ship/_external-sync-prep.json --strict-manifest
28
+ ```
29
+
30
+ The strict manifest dry-run should authorize only the prepared sync note and the core package-baseline cascades.
31
+
32
+ ## Not handled by /git-sync
33
+
34
+ `/git-sync` can deliver committed file changes, but it does not publish `@elevasis/core`, install package baselines, validate scaffold registry metadata, or enforce manifest-scoped external-sync write authorization.
@@ -46,17 +46,18 @@ Edge kinds:
46
46
 
47
47
  - `contains`
48
48
  - `references`
49
- - `maps_to`
50
- - `uses`
51
- - `governs`
52
- - `governed-by`
53
- - `links`
54
- - `affects`
55
- - `emits`
49
+ - `maps_to`
50
+ - `uses`
51
+ - `governs`
52
+ - `links`
53
+ - `affects`
54
+ - `emits`
56
55
  - `originates_from`
57
56
  - `triggers`
58
57
  - `applies_to`
59
- - `effects`
58
+ - `effects`
59
+
60
+ `governed-by` is a Knowledge Graph route verb for traversing incoming `governs` edges; it is not an Organization Graph edge kind.
60
61
 
61
62
  System nodes come from the id-keyed `OrganizationModel.systems` map. Their graph IDs use `system:<id>`, such as `system:sales.crm`.
62
63
 
@@ -31,15 +31,19 @@ Layer 3: Sync Verification (pnpm sync:verify)
31
31
 
32
32
  ## Layer 1: Source Generation
33
33
 
34
- `pnpm scaffold:sync` is the meta-script that regenerates all derived documentation and validates the output. It chains three sub-scripts:
35
-
36
- | Script | Input | Output |
37
- | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
38
- | `generate-scaffold-contracts.js` | `packages/core/src/organization-model/types.ts`, `packages/ui/src/features/registry/types.ts`, `packages/core/src/platform/registry/types.ts` | `packages/core/src/reference/_generated/contracts.md` |
39
- | `generate-scaffold-feature-registry.js` | `packages/ui/src/features/registry/manifests.ts`, `packages/ui/src/features/*/manifest.ts` | `packages/ui/src/scaffold/_generated/feature-registry.md` |
40
- | `generate-reference-artifacts.js` | SDK manifest, navigation sources | `packages/sdk/reference/_reference-manifest.json`, `_navigation.md` |
41
-
42
- After generation, `validate-reference-artifacts.js` checks that the outputs are consistent. Exit 1 if drifted.
34
+ `pnpm scaffold:sync` is the meta-script that regenerates all derived documentation and validates the output. It chains seven sub-scripts:
35
+
36
+ | Script | Input | Output |
37
+ | ---------------------- | --------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
38
+ | `scaffold:generate` | Scaffold contract and feature-registry sources | `packages/core/src/reference/_generated/**`, `packages/ui/src/scaffold/_generated/feature-registry.md` |
39
+ | `knowledge:generate` | Elevasis core knowledge nodes and UI knowledge body sources | Generated knowledge nodes and UI knowledge bodies |
40
+ | `gen:sdk-catalog` | SDK catalog source definitions | SDK catalog artifacts |
41
+ | `gen:sdk-adapters` | SDK adapter definitions | SDK adapter artifacts |
42
+ | `copy-docs` | SDK docs, package-owned reference docs, scaffold docs, and `_template/.claude` config | `packages/sdk/reference/**` copied docs and scaffold reference bundle |
43
+ | `sdk-ref:generate` | SDK manifest and navigation sources | `packages/sdk/reference/_reference-manifest.json`, `packages/sdk/reference/_navigation.md` |
44
+ | `sdk-ref:check` | Generated SDK reference artifacts | Freshness validation for `packages/sdk/reference/_reference-manifest.json` and `_navigation.md` |
45
+
46
+ The final `sdk-ref:check` step validates that the reference artifacts are consistent. Exit 1 if drifted.
43
47
 
44
48
  ### Trigger Points
45
49
 
@@ -99,13 +99,14 @@ Generated files should never be edited manually. If the output is wrong, fix the
99
99
 
100
100
  ## SDK Build Pipeline (Reference Copy)
101
101
 
102
- `packages/sdk/scripts/copy-reference-docs.mjs` runs during `pnpm --filter @elevasis/sdk build` and has three phases:
103
-
104
- 1. **Phase 1:** Copies SDK public docs from `apps/docs/content/docs/sdk/` with link rewriting and MDX escape stripping
105
- 2. **Phase 2:** Copies package-owned reference docs declared in reference manifests
106
- 3. **Phase 3:** Copies scaffold docs from co-located package sources using the `SCAFFOLD_COPIES` map
107
-
108
- The output lands in `packages/sdk/reference/` which is included in the npm package's `files` array. External projects access it via `node_modules/@elevasis/sdk/reference/`.
102
+ `packages/sdk/scripts/copy-reference-docs.mjs` runs during `pnpm --filter @elevasis/sdk build` and has four phases:
103
+
104
+ 1. **Phase 1:** Copies SDK public docs from `apps/docs/content/docs/sdk/` with link rewriting and MDX escape stripping
105
+ 2. **Phase 2:** Copies package-owned reference docs declared in reference manifests
106
+ 3. **Phase 3:** Copies scaffold docs from co-located package sources using the `SCAFFOLD_COPIES` map
107
+ 4. **Phase 4:** Copies `external/_template/.claude` into `packages/sdk/reference/claude-config` for tenant-facing agent configuration
108
+
109
+ The output lands in `packages/sdk/reference/` which is included in the npm package's `files` array. External projects access it via `node_modules/@elevasis/sdk/reference/`.
109
110
 
110
111
  ---
111
112