@elevasis/sdk 1.28.1 → 1.30.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 (87) hide show
  1. package/dist/cli.cjs +1611 -595
  2. package/dist/index.d.ts +105 -1
  3. package/dist/index.js +30 -25
  4. package/dist/node/index.d.ts +84 -1
  5. package/dist/test-utils/index.d.ts +102 -1
  6. package/dist/test-utils/index.js +242 -23
  7. package/dist/worker/index.js +1 -0
  8. package/package.json +4 -4
  9. package/reference/_navigation.md +4 -4
  10. package/reference/_reference-manifest.json +8 -8
  11. package/reference/claude-config/hooks/scaffold-registry-reminder.mjs +3 -3
  12. package/reference/claude-config/rules/topbar-actions.md +70 -0
  13. package/reference/claude-config/skills/om/SKILL.md +18 -1
  14. package/reference/claude-config/skills/tutorial/technical.md +5 -5
  15. package/reference/claude-config/sync-notes/2026-05-04-knowledge-bundle.md +83 -83
  16. package/reference/claude-config/sync-notes/2026-05-14-organization-model-ontology-refactor.md +45 -45
  17. package/reference/claude-config/sync-notes/2026-05-15-om-skill-rename-and-write-family.md +52 -52
  18. package/reference/claude-config/sync-notes/2026-05-17-sdk-boundary-consolidation.md +33 -33
  19. package/reference/claude-config/sync-notes/2026-05-20-om-define-helpers.md +32 -32
  20. package/reference/claude-config/sync-notes/2026-05-22-access-model-and-right-panel.md +43 -43
  21. package/reference/claude-config/sync-notes/2026-05-22-lead-gen-tenant-config.md +40 -40
  22. package/reference/claude-config/sync-notes/2026-05-22-org-model-multi-file-split.md +61 -61
  23. package/reference/claude-config/sync-notes/2026-05-23-branding-names-to-identity.md +49 -49
  24. package/reference/claude-config/sync-notes/2026-05-23-lead-gen-manage-access.md +31 -31
  25. package/reference/claude-config/sync-notes/2026-05-23-om-deployment-drift-detection.md +42 -42
  26. package/reference/claude-config/sync-notes/2026-05-23-om-full-model-deploy-contract.md +33 -33
  27. package/reference/claude-config/sync-notes/2026-05-23-ui-sdk-package-fixes.md +37 -37
  28. package/reference/claude-config/sync-notes/2026-05-24-platform-invite-router-core-baseline.md +28 -0
  29. package/reference/claude-config/sync-notes/2026-05-24-system-interface-readiness.md +43 -43
  30. package/reference/claude-config/sync-notes/2026-05-25-invitation-login-loader.md +26 -0
  31. package/reference/claude-config/sync-notes/2026-05-25-om-topbar-requests.md +33 -0
  32. package/reference/claude-config/sync-notes/2026-05-25-system-interface-profile-registry-and-substrate.md +35 -0
  33. package/reference/claude-config/sync-notes/2026-05-25-tenant-om-scaffold-cli.md +49 -0
  34. package/reference/claude-config/sync-notes/2026-05-25-vibe-operate-intent.md +47 -0
  35. package/reference/core/exports.mdx +16 -0
  36. package/reference/core/index.mdx +58 -0
  37. package/reference/examples/organization-model.ts +18 -0
  38. package/reference/index.mdx +36 -67
  39. package/reference/rules/organization-model.md +4 -1
  40. package/reference/rules/organization-os.md +7 -1
  41. package/reference/rules/ui.md +207 -207
  42. package/reference/rules/vibe.md +52 -18
  43. package/reference/scaffold/index.mdx +9 -7
  44. package/reference/scaffold/operations/propagation-pipeline.md +152 -152
  45. package/reference/scaffold/operations/scaffold-maintenance.md +14 -4
  46. package/reference/scaffold/reference/contracts.md +423 -338
  47. package/reference/scaffold/reference/glossary.md +14 -2
  48. package/reference/scaffold/reference/system-interface-capabilities.md +50 -0
  49. package/reference/{cli-management.mdx → sdk/cli-management.mdx} +159 -13
  50. package/reference/{cli.mdx → sdk/cli.mdx} +68 -12
  51. package/reference/sdk/exports.mdx +14 -0
  52. package/reference/sdk/index.mdx +93 -0
  53. package/reference/sdk/platform-tools/adapters-integration.mdx +25 -0
  54. package/reference/sdk/platform-tools/adapters-platform.mdx +24 -0
  55. package/reference/{platform-tools → sdk/platform-tools}/index.mdx +9 -30
  56. package/reference/{resources → sdk/resources}/patterns.mdx +29 -11
  57. package/reference/ui/exports.mdx +60 -0
  58. package/reference/ui/index.mdx +75 -0
  59. package/reference/platform-tools/adapters-integration.mdx +0 -300
  60. package/reference/platform-tools/adapters-platform.mdx +0 -552
  61. /package/reference/claude-config/skills/deploy/{skill.md → SKILL.md} +0 -0
  62. /package/reference/{concepts.mdx → sdk/concepts.mdx} +0 -0
  63. /package/reference/{deployment → sdk/deployment}/command-center.mdx +0 -0
  64. /package/reference/{deployment → sdk/deployment}/execution-reference.mdx +0 -0
  65. /package/reference/{deployment → sdk/deployment}/index.mdx +0 -0
  66. /package/reference/{framework → sdk/framework}/agent.mdx +0 -0
  67. /package/reference/{framework → sdk/framework}/index.mdx +0 -0
  68. /package/reference/{framework → sdk/framework}/interaction-guidance.mdx +0 -0
  69. /package/reference/{framework → sdk/framework}/memory.mdx +0 -0
  70. /package/reference/{framework → sdk/framework}/project-structure.mdx +0 -0
  71. /package/reference/{framework → sdk/framework}/resource-documentation.mdx +0 -0
  72. /package/reference/{framework → sdk/framework}/tutorial-system.mdx +0 -0
  73. /package/reference/{getting-started.mdx → sdk/getting-started.mdx} +0 -0
  74. /package/reference/{platform-tools → sdk/platform-tools}/type-safety.mdx +0 -0
  75. /package/reference/{resources → sdk/resources}/index.mdx +0 -0
  76. /package/reference/{resources → sdk/resources}/types.mdx +0 -0
  77. /package/reference/{roadmap.mdx → sdk/roadmap.mdx} +0 -0
  78. /package/reference/{runtime.mdx → sdk/runtime.mdx} +0 -0
  79. /package/reference/{templates → sdk/templates}/data-enrichment.mdx +0 -0
  80. /package/reference/{templates → sdk/templates}/email-sender.mdx +0 -0
  81. /package/reference/{templates → sdk/templates}/index.mdx +0 -0
  82. /package/reference/{templates → sdk/templates}/lead-scorer.mdx +0 -0
  83. /package/reference/{templates → sdk/templates}/pdf-generator.mdx +0 -0
  84. /package/reference/{templates → sdk/templates}/recurring-job.mdx +0 -0
  85. /package/reference/{templates → sdk/templates}/text-classifier.mdx +0 -0
  86. /package/reference/{templates → sdk/templates}/web-scraper.mdx +0 -0
  87. /package/reference/{troubleshooting.mdx → sdk/troubleshooting.mdx} +0 -0
@@ -6886,6 +6886,7 @@ var ORGANIZATION_MODEL_ICON_TOKENS = [
6886
6886
  "view",
6887
6887
  "launch",
6888
6888
  "message",
6889
+ "message-plus",
6889
6890
  "escalate",
6890
6891
  "promote",
6891
6892
  "submit",
@@ -6923,7 +6924,7 @@ var LabelSchema = z.string().trim().min(1).max(120);
6923
6924
  var DescriptionSchema = z.string().trim().min(1).max(2e3);
6924
6925
  var ColorTokenSchema = z.string().trim().min(1).max(50);
6925
6926
  var IconNameSchema = OrganizationModelIconTokenSchema;
6926
- z.string().trim().startsWith("/").max(300);
6927
+ var PathSchema = z.string().trim().startsWith("/").max(300);
6927
6928
  var ReferenceIdsSchema = z.array(ModelIdSchema).default([]);
6928
6929
  var DisplayMetadataSchema = z.object({
6929
6930
  label: LabelSchema,
@@ -6995,6 +6996,89 @@ function listAllSystems(model) {
6995
6996
  return results;
6996
6997
  }
6997
6998
 
6999
+ // ../core/src/organization-model/domains/entities.ts
7000
+ var EntityIdSchema = ModelIdSchema;
7001
+ var EntityLinkKindSchema = z.enum(["belongs-to", "has-many", "has-one", "many-to-many"]).meta({ label: "Link kind" });
7002
+ var EntityLinkSchema = z.object({
7003
+ toEntity: EntityIdSchema.meta({ ref: "entity" }),
7004
+ kind: EntityLinkKindSchema,
7005
+ via: z.string().trim().min(1).max(255).optional(),
7006
+ label: LabelSchema.optional()
7007
+ });
7008
+ var EntitySchema = z.object({
7009
+ id: EntityIdSchema,
7010
+ /** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
7011
+ order: z.number(),
7012
+ label: LabelSchema,
7013
+ description: DescriptionSchema.optional(),
7014
+ ownedBySystemId: ModelIdSchema.meta({ ref: "system" }),
7015
+ table: z.string().trim().min(1).max(255).optional(),
7016
+ rowSchema: ModelIdSchema.optional(),
7017
+ stateCatalogId: ModelIdSchema.optional(),
7018
+ links: z.array(EntityLinkSchema).optional()
7019
+ });
7020
+ z.record(z.string(), EntitySchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
7021
+ message: "Each entity entry id must match its map key"
7022
+ }).default({});
7023
+
7024
+ // ../core/src/organization-model/domains/actions.ts
7025
+ var ActionResourceIdSchema = z.string().trim().min(1).max(255).regex(/^[A-Za-z0-9]+(?:[-._][A-Za-z0-9]+)*$/, "Resource IDs must use letters, numbers, -, _, or . separators");
7026
+ z.enum(["slash-command", "mcp-tool", "api-endpoint", "script-execution"]).meta({ label: "Invocation kind" });
7027
+ var ActionIdSchema = ModelIdSchema;
7028
+ var ActionScopeSchema = z.union([
7029
+ z.literal("global"),
7030
+ z.object({
7031
+ domain: ModelIdSchema
7032
+ })
7033
+ ]);
7034
+ var ActionRefSchema = z.object({
7035
+ actionId: ActionIdSchema.meta({ ref: "action" }),
7036
+ intent: z.enum(["exposes", "consumes"]).meta({ label: "Intent" })
7037
+ });
7038
+ var SlashCommandInvocationSchema = z.object({
7039
+ kind: z.literal("slash-command"),
7040
+ command: z.string().trim().min(1).max(200).regex(/^\/[^\s].*$/, "Slash commands must start with /"),
7041
+ toolFactory: ModelIdSchema.optional()
7042
+ });
7043
+ var McpToolInvocationSchema = z.object({
7044
+ kind: z.literal("mcp-tool"),
7045
+ server: ModelIdSchema,
7046
+ name: ModelIdSchema
7047
+ });
7048
+ var ApiEndpointInvocationSchema = z.object({
7049
+ kind: z.literal("api-endpoint"),
7050
+ method: z.enum(["GET", "POST", "PATCH", "DELETE"]).meta({ label: "HTTP method" }),
7051
+ path: z.string().trim().startsWith("/").max(500),
7052
+ requestSchema: ModelIdSchema.optional(),
7053
+ responseSchema: ModelIdSchema.optional()
7054
+ });
7055
+ var ScriptExecutionInvocationSchema = z.object({
7056
+ kind: z.literal("script-execution"),
7057
+ resourceId: ActionResourceIdSchema
7058
+ });
7059
+ var ActionInvocationSchema = z.discriminatedUnion("kind", [
7060
+ SlashCommandInvocationSchema,
7061
+ McpToolInvocationSchema,
7062
+ ApiEndpointInvocationSchema,
7063
+ ScriptExecutionInvocationSchema
7064
+ ]);
7065
+ var ActionSchema = z.object({
7066
+ id: ActionIdSchema,
7067
+ /** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
7068
+ order: z.number(),
7069
+ label: LabelSchema,
7070
+ description: DescriptionSchema.optional(),
7071
+ scope: ActionScopeSchema.default("global"),
7072
+ resourceId: ActionResourceIdSchema.optional(),
7073
+ affects: z.array(EntityIdSchema.meta({ ref: "entity" })).optional(),
7074
+ invocations: z.array(ActionInvocationSchema).default([]),
7075
+ knowledge: z.array(ModelIdSchema.meta({ ref: "knowledge" })).default([]).optional(),
7076
+ lifecycle: z.enum(["draft", "beta", "active", "deprecated", "archived"]).meta({ label: "Lifecycle", color: "teal" }).default("active")
7077
+ });
7078
+ z.record(z.string(), ActionSchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
7079
+ message: "Each action entry id must match its map key"
7080
+ }).default({});
7081
+
6998
7082
  // ../core/src/organization-model/domains/prospecting.ts
6999
7083
  DisplayMetadataSchema.extend({
7000
7084
  id: ModelIdSchema,
@@ -8316,7 +8400,7 @@ var OntologyGroupSchema = OntologyRecordBaseSchema.extend({
8316
8400
  var OntologySurfaceTypeSchema = OntologyRecordBaseSchema.extend({
8317
8401
  route: z.string().trim().min(1).max(500).optional()
8318
8402
  });
8319
- z.object({
8403
+ var OntologyScopeSchema = z.object({
8320
8404
  objectTypes: z.record(OntologyIdSchema, OntologyObjectTypeSchema).default({}).optional(),
8321
8405
  linkTypes: z.record(OntologyIdSchema, OntologyLinkTypeSchema).default({}).optional(),
8322
8406
  actionTypes: z.record(OntologyIdSchema, OntologyActionTypeSchema).default({}).optional(),
@@ -8549,6 +8633,152 @@ function compileOrganizationOntology(model) {
8549
8633
  addLegacyActionProjections(ontology, diagnostics, sourcesById, model.actions ?? {}, model.entities ?? {});
8550
8634
  return { ontology: sortResolvedOntologyIndex(ontology), diagnostics };
8551
8635
  }
8636
+ var SystemKindSchema = z.enum(["product", "operational", "platform", "diagnostic"]).meta({ label: "System kind", color: "blue" });
8637
+ var SystemLifecycleSchema = z.enum(["draft", "beta", "active", "deprecated", "archived"]).meta({ label: "Lifecycle", color: "teal" });
8638
+ var SystemStatusSchema = z.enum(["active", "deprecated", "archived"]).meta({ label: "Status", color: "teal" });
8639
+ var SystemIdSchema = ModelIdSchema;
8640
+ var SystemPathSchema = z.string().trim().min(1).regex(
8641
+ /^[a-z0-9][a-z0-9-]*(?:\.[a-z0-9][a-z0-9-]*)*$/,
8642
+ 'must be a dotted lowercase path (e.g. "sales.lead-gen" or "sales.crm")'
8643
+ );
8644
+ var UiPositionSchema = z.enum(["sidebar-primary", "sidebar-bottom"]).meta({ label: "UI position" });
8645
+ z.string().trim().min(1).max(200).regex(
8646
+ /^[a-z][a-z-]*:([a-z0-9-]+)(\.[a-z0-9-]+)*(:[a-z0-9.-]+)*$/,
8647
+ "Node references must use kind:dotted-path (e.g. system:sales.crm or resource:lead-gen.company.qualify)"
8648
+ );
8649
+ var SystemUiSchema = z.object({
8650
+ path: PathSchema,
8651
+ surfaces: ReferenceIdsSchema,
8652
+ icon: IconNameSchema.optional(),
8653
+ order: z.number().int().optional()
8654
+ });
8655
+ var SystemInterfaceKeySchema = ModelIdSchema;
8656
+ var SystemInterfaceLifecycleSchema = z.enum(["draft", "active", "disabled", "deprecated", "archived"]).meta({ label: "System interface lifecycle", color: "teal" });
8657
+ var SYSTEM_INTERFACE_PROFILES = [
8658
+ {
8659
+ systemPath: "sales.lead-gen",
8660
+ interfaceKey: "api",
8661
+ readinessProfile: "sales.lead-gen.api"
8662
+ },
8663
+ {
8664
+ systemPath: "sales.crm",
8665
+ interfaceKey: "api",
8666
+ readinessProfile: "sales.crm.api"
8667
+ },
8668
+ {
8669
+ systemPath: "sales.lead-gen",
8670
+ interfaceKey: "crm-handoff",
8671
+ readinessProfile: "sales.lead-gen.crm-handoff"
8672
+ }
8673
+ ];
8674
+ var SYSTEM_INTERFACE_READINESS_PROFILES = SYSTEM_INTERFACE_PROFILES.map(
8675
+ (profile) => profile.readinessProfile
8676
+ );
8677
+ var SystemInterfaceReadinessProfileSchema = z.enum(SYSTEM_INTERFACE_READINESS_PROFILES);
8678
+ var SystemInterfaceResourceScopeSchema = z.array(ModelIdSchema).default([]);
8679
+ var SystemApiInterfaceSchema = z.object({
8680
+ lifecycle: SystemInterfaceLifecycleSchema.default("active"),
8681
+ readinessProfile: SystemInterfaceReadinessProfileSchema.optional(),
8682
+ /**
8683
+ * Resource ids that participate in this API interface. This scopes readiness
8684
+ * derivation without duplicating authored required/provided contract refs.
8685
+ */
8686
+ resourceIds: SystemInterfaceResourceScopeSchema.optional()
8687
+ }).strict();
8688
+ z.object({
8689
+ systemPath: SystemPathSchema,
8690
+ interfaceKey: SystemInterfaceKeySchema
8691
+ }).strict();
8692
+ var JsonValueSchema = z.lazy(
8693
+ () => z.union([
8694
+ z.string(),
8695
+ z.number(),
8696
+ z.boolean(),
8697
+ z.null(),
8698
+ z.array(JsonValueSchema),
8699
+ z.record(z.string(), JsonValueSchema)
8700
+ ])
8701
+ );
8702
+ var SystemConfigSchema = z.record(z.string().trim().min(1).max(200), JsonValueSchema).default({}).optional();
8703
+ var SystemEntrySchema = z.object({
8704
+ /** Stable tenant-defined system id (e.g. "sys.lead-gen" or "sales.crm"). */
8705
+ id: SystemIdSchema,
8706
+ /** Human-readable system label shown in UI, governance, and operations surfaces. */
8707
+ label: LabelSchema.optional(),
8708
+ /** @deprecated Use label. Accepted for pre-consolidation System declarations. */
8709
+ title: LabelSchema.optional(),
8710
+ /** One-paragraph purpose statement for the bounded context. */
8711
+ description: DescriptionSchema.optional(),
8712
+ /** Closed system shape enum; catalog values remain tenant-defined. */
8713
+ kind: SystemKindSchema.optional(),
8714
+ /** Optional self-reference for System hierarchy. */
8715
+ parentSystemId: SystemIdSchema.optional(),
8716
+ /** Optional UI presence. Systems without UI omit this. */
8717
+ ui: SystemUiSchema.optional(),
8718
+ /** Canonical lifecycle state. Replaces Feature.enabled/devOnly and System.status. */
8719
+ lifecycle: SystemLifecycleSchema.optional(),
8720
+ /** Optional role responsible for this system. */
8721
+ responsibleRoleId: ModelIdSchema.meta({ ref: "role" }).optional(),
8722
+ /** Optional knowledge nodes that govern this system. */
8723
+ governedByKnowledge: z.array(ModelIdSchema.meta({ ref: "knowledge" })).default([]).optional(),
8724
+ /** Optional actions this system exposes or consumes. */
8725
+ actions: z.array(ActionRefSchema).optional(),
8726
+ /** Optional operational policies that apply to this system. */
8727
+ policies: z.array(ModelIdSchema.meta({ ref: "policy" })).default([]).optional(),
8728
+ /** Optional goals this system contributes to. */
8729
+ drivesGoals: z.array(ModelIdSchema.meta({ ref: "goal" })).default([]).optional(),
8730
+ /** Thin API runtime-boundary marker. Readiness is derived from scoped resources and topology. */
8731
+ apiInterface: SystemApiInterfaceSchema.optional(),
8732
+ /** @deprecated Use lifecycle. Accepted for one publish cycle. */
8733
+ status: SystemStatusSchema.optional(),
8734
+ /** @deprecated Use ui.path. Kept for one-cycle Feature compatibility. */
8735
+ path: PathSchema.optional(),
8736
+ /** @deprecated Use ui.icon. Kept for one-cycle Feature compatibility. */
8737
+ icon: IconNameSchema.optional(),
8738
+ /** @deprecated Feature color token, retained for one-cycle compatibility. */
8739
+ color: ColorTokenSchema.optional(),
8740
+ /** @deprecated UI placement hint, retained for one-cycle compatibility. */
8741
+ uiPosition: UiPositionSchema.optional(),
8742
+ /** @deprecated Use lifecycle. */
8743
+ enabled: z.boolean().optional(),
8744
+ /** @deprecated Use lifecycle: "beta". */
8745
+ devOnly: z.boolean().optional(),
8746
+ requiresAdmin: z.boolean().optional(),
8747
+ /** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
8748
+ order: z.number(),
8749
+ /**
8750
+ * System-local JSON settings and defaults. Strongly typed OM fields,
8751
+ * secrets, credentials, and runtime state stay outside this bucket.
8752
+ */
8753
+ config: SystemConfigSchema,
8754
+ /**
8755
+ * System-owned ontology declarations. `systems` is now the canonical child
8756
+ * key; this scope holds the object, action, catalog, link, event, and
8757
+ * shared contract records owned by this system.
8758
+ */
8759
+ ontology: OntologyScopeSchema.optional(),
8760
+ /**
8761
+ * Recursive child systems, authored via nesting (per L11).
8762
+ * The key is the local system id; the full path is computed by joining
8763
+ * ancestor keys with `.` (e.g. parent key `'sales'` + child key `'crm'` → `'sales.crm'`).
8764
+ * Per Phase 4: `id` and `parentSystemId` fields will be removed in favour of
8765
+ * position-derived paths. Both still exist on this schema for backward compat.
8766
+ */
8767
+ systems: z.lazy(() => z.record(z.string().trim().min(1).max(100), SystemEntrySchema)).optional(),
8768
+ /** @deprecated Use systems. Accepted as a compatibility alias during the ontology bridge. */
8769
+ subsystems: z.lazy(() => z.record(z.string().trim().min(1).max(100), SystemEntrySchema)).optional()
8770
+ }).strict().refine((system) => system.label !== void 0 || system.title !== void 0, {
8771
+ path: ["label"],
8772
+ message: "System must provide label or title"
8773
+ }).transform((system) => {
8774
+ const normalizedSystem = system.systems !== void 0 && system.subsystems === void 0 ? { ...system, subsystems: system.systems } : system;
8775
+ if (normalizedSystem.status === void 0) return normalizedSystem;
8776
+ console.warn("[organization-model] System.status is deprecated; use System.lifecycle instead.");
8777
+ return normalizedSystem.lifecycle === void 0 ? { ...normalizedSystem, lifecycle: normalizedSystem.status } : normalizedSystem;
8778
+ });
8779
+ z.record(z.string(), SystemEntrySchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
8780
+ message: "Each system entry id must match its map key"
8781
+ }).default({});
8552
8782
 
8553
8783
  // ../core/src/organization-model/migration-helpers.ts
8554
8784
  function catalogRecords(model) {
@@ -8626,21 +8856,12 @@ z.object({
8626
8856
  });
8627
8857
 
8628
8858
  // ../core/src/business/acquisition/ontology-validation.ts
8629
- var LEAD_GEN_API_INTERFACE = {
8630
- interfaceKey: "api",
8631
- readinessProfile: "sales.lead-gen.api"
8632
- };
8633
- var CRM_API_INTERFACE = {
8634
- systemPath: "sales.crm",
8635
- interfaceKey: "api",
8636
- readinessProfile: "sales.crm.api"
8637
- };
8638
- var LEAD_GEN_CRM_HANDOFF_INTERFACE = {
8639
- systemPath: "sales.lead-gen",
8640
- interfaceKey: "crm-handoff",
8641
- readinessProfile: "sales.lead-gen.crm-handoff"
8642
- };
8859
+ var LEAD_GEN_API_INTERFACE = SYSTEM_INTERFACE_PROFILES[0];
8860
+ var CRM_API_INTERFACE = SYSTEM_INTERFACE_PROFILES[1];
8861
+ var LEAD_GEN_CRM_HANDOFF_INTERFACE = SYSTEM_INTERFACE_PROFILES[2];
8862
+ LEAD_GEN_API_INTERFACE.readinessProfile;
8643
8863
  CRM_API_INTERFACE.readinessProfile;
8864
+ LEAD_GEN_CRM_HANDOFF_INTERFACE.readinessProfile;
8644
8865
  var LEAD_GEN_LIST_OBJECT_ONTOLOGY_ID = formatOntologyId({
8645
8866
  scope: "sales.lead-gen",
8646
8867
  kind: "object",
@@ -8718,6 +8939,9 @@ function profileForInterface(systemPath, interfaceKey, readinessProfile) {
8718
8939
  function readinessMarkerPath(context) {
8719
8940
  return context.interfaceKey === "api" ? `systems.${context.systemPath}.apiInterface` : `systems.${context.systemPath}.derivedCrmHandoffReadiness`;
8720
8941
  }
8942
+ function formatSupportedReadinessProfiles() {
8943
+ return SYSTEM_INTERFACE_READINESS_PROFILES.map((profile) => `"${profile}"`).join(", ");
8944
+ }
8721
8945
  function getActiveScopedResources(model, resourceIds, issues, context) {
8722
8946
  const resources = [];
8723
8947
  for (const [index2, resourceId] of resourceIds.entries()) {
@@ -8997,18 +9221,13 @@ function computeInterfaceReadiness(model, request) {
8997
9221
  { path: `${readinessMarkerPath(request)}.lifecycle` }
8998
9222
  );
8999
9223
  }
9000
- const supportedProfiles = [
9001
- LEAD_GEN_API_INTERFACE.readinessProfile,
9002
- CRM_API_INTERFACE.readinessProfile,
9003
- LEAD_GEN_CRM_HANDOFF_INTERFACE.readinessProfile
9004
- ];
9005
- const supportedProfile = readinessProfile !== void 0 && supportedProfiles.some((profile) => profile === readinessProfile);
9224
+ const supportedProfile = readinessProfile !== void 0 && SYSTEM_INTERFACE_PROFILES.some((profile) => profile.readinessProfile === readinessProfile);
9006
9225
  if (!supportedProfile) {
9007
9226
  addReadinessIssue(
9008
9227
  issues,
9009
9228
  "SYSTEM_INTERFACE_INVALID",
9010
9229
  "unknown-readiness-profile",
9011
- `System Interface "${formatInterfaceIdentity(request.systemPath, request.interfaceKey)}" references unknown readiness profile "${readinessProfile}".`,
9230
+ `System Interface "${formatInterfaceIdentity(request.systemPath, request.interfaceKey)}" references unknown readiness profile "${readinessProfile}". Supported profiles: ${formatSupportedReadinessProfiles()}. Custom Systems should not declare apiInterface; route custom behavior through workflows/operations plus ontology, resources, and topology.`,
9012
9231
  { path: `${readinessMarkerPath(request)}.readinessProfile`, ref: readinessProfile }
9013
9232
  );
9014
9233
  return {
@@ -4978,6 +4978,7 @@ var ORGANIZATION_MODEL_ICON_TOKENS = [
4978
4978
  "view",
4979
4979
  "launch",
4980
4980
  "message",
4981
+ "message-plus",
4981
4982
  "escalate",
4982
4983
  "promote",
4983
4984
  "submit",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elevasis/sdk",
3
- "version": "1.28.1",
3
+ "version": "1.30.0",
4
4
  "description": "SDK for building Elevasis organization resources",
5
5
  "type": "module",
6
6
  "bin": {
@@ -58,9 +58,9 @@
58
58
  "tsup": "^8.0.0",
59
59
  "typescript": "5.9.2",
60
60
  "zod": "^4.1.0",
61
- "@repo/core": "0.35.1",
62
- "@repo/typescript-config": "0.0.0",
63
- "@repo/eslint-config": "0.0.0"
61
+ "@repo/core": "0.38.0",
62
+ "@repo/eslint-config": "0.0.0",
63
+ "@repo/typescript-config": "0.0.0"
64
64
  },
65
65
  "scripts": {
66
66
  "lint": "eslint src --max-warnings 0",
@@ -46,25 +46,25 @@ Package entries indexed: 60.
46
46
 
47
47
  | Resource | Location | Description | When to Load |
48
48
  | --- | --- | --- | --- |
49
- | SDK | `index.mdx` | Root SDK types, config, runtime errors, and registry surface. | (not specified) |
49
+ | SDK | `sdk/index.mdx` | Root SDK types, config, runtime errors, and registry surface. | (not specified) |
50
50
 
51
51
  ## @elevasis/sdk / Runtime
52
52
 
53
53
  | Resource | Location | Description | When to Load |
54
54
  | --- | --- | --- | --- |
55
- | Worker Runtime | `runtime.mdx` | Worker runtime entrypoint, adapters, and platform execution surface. | (not specified) |
55
+ | Worker Runtime | `sdk/runtime.mdx` | Worker runtime entrypoint, adapters, and platform execution surface. | (not specified) |
56
56
 
57
57
  ## @elevasis/sdk / Testing
58
58
 
59
59
  | Resource | Location | Description | When to Load |
60
60
  | --- | --- | --- | --- |
61
- | Test Utils | `runtime.mdx` | Workflow runner, registry assertion, and typed adapter mocks for SDK consumers. | (not specified) |
61
+ | Test Utils | `sdk/runtime.mdx` | Workflow runner, registry assertion, and typed adapter mocks for SDK consumers. | (not specified) |
62
62
 
63
63
  ## @elevasis/sdk / Tooling
64
64
 
65
65
  | Resource | Location | Description | When to Load |
66
66
  | --- | --- | --- | --- |
67
- | Node Build Tooling | `cli.mdx` | Node-only build helpers: knowledge codegen and other fs/path/process utilities. Not browser-safe. | (not specified) |
67
+ | Node Build Tooling | `sdk/cli.mdx` | Node-only build helpers: knowledge codegen and other fs/path/process utilities. Not browser-safe. | (not specified) |
68
68
 
69
69
  ## @elevasis/ui / Build
70
70
 
@@ -95,8 +95,8 @@
95
95
  "group": "Getting Started",
96
96
  "order": 1,
97
97
  "sourcePath": "packages/sdk/src/index.ts",
98
- "docPath": "apps/docs/content/docs/sdk/index.mdx",
99
- "referencePath": "index.mdx",
98
+ "docPath": "apps/docs/content/docs/sdk/sdk/index.mdx",
99
+ "referencePath": "sdk/index.mdx",
100
100
  "publishedExportPath": "./dist/index.js"
101
101
  },
102
102
  {
@@ -109,8 +109,8 @@
109
109
  "group": "Runtime",
110
110
  "order": 1,
111
111
  "sourcePath": "packages/sdk/src/worker/index.ts",
112
- "docPath": "apps/docs/content/docs/sdk/runtime.mdx",
113
- "referencePath": "runtime.mdx",
112
+ "docPath": "apps/docs/content/docs/sdk/sdk/runtime.mdx",
113
+ "referencePath": "sdk/runtime.mdx",
114
114
  "publishedExportPath": "./dist/worker/index.js"
115
115
  },
116
116
  {
@@ -123,8 +123,8 @@
123
123
  "group": "Testing",
124
124
  "order": 1,
125
125
  "sourcePath": "packages/sdk/src/test-utils/index.ts",
126
- "docPath": "apps/docs/content/docs/sdk/runtime.mdx",
127
- "referencePath": "runtime.mdx",
126
+ "docPath": "apps/docs/content/docs/sdk/sdk/runtime.mdx",
127
+ "referencePath": "sdk/runtime.mdx",
128
128
  "publishedExportPath": "./dist/test-utils/index.js"
129
129
  },
130
130
  {
@@ -137,8 +137,8 @@
137
137
  "group": "Tooling",
138
138
  "order": 1,
139
139
  "sourcePath": "packages/sdk/src/node/index.ts",
140
- "docPath": "apps/docs/content/docs/sdk/cli.mdx",
141
- "referencePath": "cli.mdx",
140
+ "docPath": "apps/docs/content/docs/sdk/sdk/cli.mdx",
141
+ "referencePath": "sdk/cli.mdx",
142
142
  "publishedExportPath": "./dist/node/index.js"
143
143
  },
144
144
  {
@@ -16,7 +16,7 @@ const ROOT = process.env.CLAUDE_PROJECT_DIR ?? process.cwd()
16
16
  const LOG_DIR = join(ROOT, '.claude', 'logs')
17
17
  const LOG_FILE = join(LOG_DIR, 'scaffold-registry-reminder.log')
18
18
  const STATE_FILE = join(LOG_DIR, 'scaffold-registry-reminder.state.json')
19
- const REGISTRY_FILE = join(ROOT, '.claude', 'scaffold-registry.compiled.json')
19
+ const REGISTRY_FILE = join(ROOT, '.claude', 'registries', 'scaffold-registry.compiled.json')
20
20
 
21
21
  const DEFAULT_COOLDOWN_MS = 300_000 // 5 minutes
22
22
 
@@ -89,7 +89,7 @@ function emitReminder(entry, relFilePath) {
89
89
  lines.push(formatDependentLine(dep))
90
90
  }
91
91
  lines.push(
92
- ` If this is a scaffold-sensitive pattern not in the registry, also add an entry to .claude/scaffold-registry.yml.`
92
+ ` If this is a scaffold-sensitive pattern not in the registry, also add an entry to .claude/registries/scaffold-registry.yml.`
93
93
  )
94
94
  return lines.join('\n')
95
95
  }
@@ -98,7 +98,7 @@ function emitMissingEntryHint(relFilePath) {
98
98
  return [
99
99
  `\uD83D\uDD14 Scaffold reminder -- unregistered generated path (${relFilePath})`,
100
100
  ` This path looks scaffold-generated but has no registry entry.`,
101
- ` If it is scaffold-sensitive, add a new entry to .claude/scaffold-registry.yml`,
101
+ ` If it is scaffold-sensitive, add a new entry to .claude/registries/scaffold-registry.yml`,
102
102
  ` so the reminder hook and /work handoff can track it.`
103
103
  ].join('\n')
104
104
  }
@@ -0,0 +1,70 @@
1
+ ---
2
+ description: OM-declared topbar actions — navigation.topbar field and TOPBAR_ACTION_MANIFESTS registry pattern
3
+ paths:
4
+ - ui/src/lib/components/AppTopbar*
5
+ - ui/src/routes/__root*
6
+ - core/config/organization-model/**
7
+ ---
8
+
9
+ # Topbar Actions (Template Mirror Discipline — Tier 1 Note)
10
+
11
+ > **Scope:** This note documents substrate that has landed in the monorepo but is not yet published
12
+ > to `@elevasis/sdk/reference/rules/`. It will be superseded by the bundled rule once the
13
+ > `@elevasis/ui` minor that carries the topbar substrate ships. Until then, use this file.
14
+
15
+ ## navigation.topbar OM Field
16
+
17
+ The Organization Model now has a `navigation.topbar` region for declaring topbar action items.
18
+ Each entry is a distinct node type — OM owns data and visibility; a registry binds behavior.
19
+
20
+ ```ts
21
+ // core/config/organization-model.ts (navigation section)
22
+ navigation: {
23
+ topbar: {
24
+ request: {
25
+ id: 'request',
26
+ label: 'Request a feature or report an issue',
27
+ tooltip: 'Request a feature or report an issue',
28
+ icon: 'message-plus',
29
+ order: 10,
30
+ enabled: true
31
+ }
32
+ }
33
+ }
34
+ ```
35
+
36
+ Topbar items are toggled via `/org-os manage` exactly like sidebar surfaces. The `surfaceType`
37
+ enum (`page | dashboard | list | detail | graph | settings`) does NOT apply to topbar items —
38
+ they are a separate node type, not surfaces.
39
+
40
+ ## TOPBAR_ACTION_MANIFESTS Registry
41
+
42
+ Behavior for each `navigation.topbar` key is bound through a manifest registry in
43
+ `@elevasis/ui`. Each manifest maps a key to a render function:
44
+
45
+ ```ts
46
+ // Registered in packages/ui/src/features/registry/manifests.ts
47
+ TOPBAR_ACTION_MANIFESTS = {
48
+ request: requestTopbarActionManifest
49
+ }
50
+ ```
51
+
52
+ The `requestTopbarActionManifest` renders `<RequestActionIcon />` from
53
+ `@elevasis/ui/features/monitoring/requests`. It owns its own disclosure state and modal —
54
+ no wiring needed at the call site.
55
+
56
+ ## Template Authoring (Tier 2 — Post-Publish)
57
+
58
+ Declaring `navigation.topbar.request` in the template OM and rendering `<TopbarActions />`
59
+ in `AppTopbar` is **Tier 2 post-publish authoring** — it runs after the `@elevasis/ui` minor
60
+ bump lands in `external/_template`. Do NOT edit `core/config/organization-model/**` for this
61
+ until the publish + baseline bump step completes.
62
+
63
+ The requests-page `RequestButton` (entry point C) is a CC-level app-local addition in the
64
+ platform `apps/command-center` routes. Template projects add their own equivalent in
65
+ `ui/src/routes/monitoring/requests.index.tsx` after the surface is present in their navigation.
66
+
67
+ ## Related Rules
68
+
69
+ - `node_modules/@elevasis/sdk/reference/rules/organization-model.md` — OM schema and authoring ceremony
70
+ - `node_modules/@elevasis/sdk/reference/rules/organization-os.md` — `/org-os manage` toggle surface
@@ -47,6 +47,8 @@ metadata:
47
47
  - knowledge graph
48
48
  - knowledge browser
49
49
  - ontology
50
+ - apiInterface
51
+ - interface readiness
50
52
  - by-ontology
51
53
  - list my roles
52
54
  - what is our
@@ -95,7 +97,7 @@ primitive. When two buckets fit, prefer the higher one (more specific → more g
95
97
  | --- | ------------------------------ | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
96
98
  | 1 | Named knowledge/role/policy id | User names `knowledge.<id>`, `role.<id>`, `policy.<id>` directly | `om:cat <id>` for body, `om:describe <id>` for neighborhood |
97
99
  | 2 | Named system | User names a system path (`sales.crm`, `sales.lead-gen`) | `om:describe <id>` |
98
- | 3 | Named ontology id | Id contains `:object/`, `:action/`, `:event/`, `:catalog/`, `:link/`, `:surface/` | `om:describe <id>` (or `om:ls /by-ontology/<id> --ids-only` then `om:cat` each) |
100
+ | 3 | Named ontology id | Id contains `:object/`, `:action/`, `:event/`, `:catalog/`, `:interface/`, `:link/`, `:surface/` | `om:describe <id>` (or `om:ls /by-ontology/<id> --ids-only` then `om:cat` each) |
99
101
  | 4 | Kind keyword | "playbooks", "strategies", "all references", "list policies" | `om:ls /by-kind/<kind> --ids-only` then `om:cat` each |
100
102
  | 5 | Free-text discovery | Anything else ("lead gen", "outreach", "what governs X?") | `om:search "<query>"` then drill into top hit with `om:describe` |
101
103
 
@@ -198,6 +200,7 @@ what adjacent context may matter:
198
200
  | What resources belong to a System? | the id-keyed `organizationModel.resources` map and `getResourcesForSystem(model, systemPath)` | use `{ includeDescendants: true }` only for parent-scope rollups |
199
201
  | What can a System do? | system action refs and the actions domain | `action.resourceId`, invocation metadata, affected entities, policies |
200
202
  | What data does it own? | entities domain | owning System refs, state catalogs, entity links, emitted/projected events |
203
+ | Is a platform API interface ready? | the System's `apiInterface` marker and `node_modules/@elevasis/sdk/reference/scaffold/reference/system-interface-capabilities.md` | matching convention-locked System path, cataloged `readinessProfile`, derived resource ontology bindings, and scoped topology grants |
201
204
  | What UI surface exposes it? | `navigation.sidebar` plus `SystemModule` manifests | route files, surface targets, route-prefix modules, guards |
202
205
  | What knowledge applies? | `om:ls /by-system/<id>` plus graph edges | `om:cat`, `om:graph`, `/graph/<id>/governed-by` |
203
206
 
@@ -207,6 +210,20 @@ follow the relationship that matches the work. Prefer structured helpers from
207
210
 
208
211
  ---
209
212
 
213
+ ## API Interface Readiness
214
+
215
+ `system.apiInterface` is adopt-only in tenant projects. It declares intent to adopt a platform-provided API capability from the installed `@elevasis/core` / `@elevasis/sdk` version; it is not a tenant extension point.
216
+
217
+ Use only readiness profiles listed in `node_modules/@elevasis/sdk/reference/scaffold/reference/system-interface-capabilities.md`. The profile also fixes the required System path, such as `sales.lead-gen` or `sales.crm`. Do not invent a profile, and do not repoint a cataloged profile to a custom System path.
218
+
219
+ Readiness is derived, not hand-authored. After the marker is present, the validator checks ontology object/catalog types, scoped resources and their `resource.ontology` bindings, and any required scoped topology `uses` grants. Lead-gen to CRM handoff is represented as a scoped topology relationship under the cross-System boundary invariant, not as an authored bridge object.
220
+
221
+ Custom Systems should not carry `apiInterface`. Build custom behavior through `System.ontology`, `System.config`, resources, catalogs, topology, navigation, and workflows/operations. Runtime business logic belongs in workflows and agents registered by `operations/src/index.ts`; the tenant project does not add platform API routes.
222
+
223
+ Do not confuse ontology `interface` records with `system.apiInterface`. Ontology ids such as `<system>:interface/<local-id>` describe semantic model records under `System.ontology`; `system.apiInterface` is a flat System-level marker for closed platform API readiness.
224
+
225
+ ---
226
+
210
227
  ## Shared Layering Preview
211
228
 
212
229
  When opening a domain that uses a closed stage, status, or catalog vocabulary -- especially
@@ -494,7 +494,7 @@ how data flows between steps.
494
494
  **Estimated time:** 25 min
495
495
 
496
496
  **Files referenced:** `node_modules/@elevasis/sdk/reference/scaffold/operations/workflow-recipes.md`,
497
- `apps/docs/content/docs/sdk/concepts.mdx` (design decisions section)
497
+ `apps/docs/content/docs/sdk/sdk/concepts.mdx` (design decisions section)
498
498
 
499
499
  **Flow:**
500
500
 
@@ -1044,7 +1044,7 @@ result) and understands when to use an agent definition vs a workflow definition
1044
1044
  **Estimated time:** 25 min
1045
1045
 
1046
1046
  **Files referenced:** `node_modules/@elevasis/sdk/reference/scaffold/operations/workflow-recipes.md`,
1047
- `apps/docs/content/docs/sdk/concepts.mdx` (workflow vs agent section)
1047
+ `apps/docs/content/docs/sdk/sdk/concepts.mdx` (workflow vs agent section)
1048
1048
 
1049
1049
  **Flow:**
1050
1050
 
@@ -1076,7 +1076,7 @@ The SDK converts the Zod schema to JSON Schema internally. The LLM is instructed
1076
1076
  matching that shape. The result is validated and returned as the inferred TypeScript type.
1077
1077
 
1078
1078
  **Agent definition vs workflow definition.** Read the glossary entries from
1079
- `apps/docs/content/docs/sdk/concepts.mdx`:
1079
+ `apps/docs/content/docs/sdk/sdk/concepts.mdx`:
1080
1080
 
1081
1081
  - **Workflow** -- deterministic, step-by-step, 300s timeout. Use when inputs and outputs are
1082
1082
  known and the process is predefined.
@@ -1171,7 +1171,7 @@ understands the scaffold registry's purpose.
1171
1171
  **Estimated time:** 20 min
1172
1172
 
1173
1173
  **Files referenced:** `.claude/rules/` (all files), `.claude/memory/` (layout),
1174
- `.claude/scaffold-registry.yml` (reference, monorepo-side concept)
1174
+ `.claude/registries/scaffold-registry.yml` (reference, monorepo-side concept)
1175
1175
 
1176
1176
  **Flow:**
1177
1177
 
@@ -1205,7 +1205,7 @@ glob of files it applies to. The rules system discovers it automatically -- no r
1205
1205
  Memory files are readable by the agent at session start. The `profile.md` file is particularly
1206
1206
  important: it sets the project-wide tone for all sessions after the tutorial track is selected.
1207
1207
 
1208
- **Scaffold registry (monorepo-side concept).** `.claude/scaffold-registry.yml` is the
1208
+ **Scaffold registry (monorepo-side concept).** `.claude/registries/scaffold-registry.yml` is the
1209
1209
  monorepo's source-of-truth for scaffold dependencies -- it maps source paths to generated or
1210
1210
  manual scaffolds that depend on them. It drives the PostToolUse reminder hook and `/work handoff`
1211
1211
  preflight in the monorepo. In an external project you are a consumer, not a contributor, of that