@elevasis/sdk 1.47.0 → 1.49.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 (54) hide show
  1. package/dist/cli.cjs +1034 -319
  2. package/dist/index.d.ts +687 -49
  3. package/dist/index.js +297 -47
  4. package/dist/node/index.d.ts +110 -26
  5. package/dist/test-utils/index.d.ts +649 -36
  6. package/dist/test-utils/index.js +275 -45
  7. package/dist/worker/index.d.ts +687 -53
  8. package/dist/worker/index.js +121 -6
  9. package/package.json +2 -2
  10. package/reference/_navigation.md +7 -6
  11. package/reference/_reference-manifest.json +12 -2
  12. package/reference/core/index.mdx +6 -4
  13. package/reference/index.mdx +11 -5
  14. package/reference/packages/core/src/README.md +46 -44
  15. package/reference/packages/core/src/content/README.md +13 -12
  16. package/reference/packages/core/src/organization-model/README.md +9 -6
  17. package/reference/rules/content.md +27 -0
  18. package/reference/rules/organization-model.md +9 -3
  19. package/reference/rules/organization-os.md +2 -2
  20. package/reference/rules/ui.md +1 -1
  21. package/reference/rules/vibe-intents.md +19 -16
  22. package/reference/rules/vibe.md +32 -12
  23. package/reference/scaffold/recipes/add-a-feature.md +1 -1
  24. package/reference/scaffold/recipes/customize-organization-model.md +2 -2
  25. package/reference/scaffold/recipes/extend-content.md +172 -30
  26. package/reference/scaffold/reference/glossary.md +2 -2
  27. package/reference/scaffold/reference/system-interface-capabilities.md +26 -6
  28. package/reference/sdk/cli-management.mdx +246 -41
  29. package/reference/sdk/cli.mdx +103 -64
  30. package/reference/sdk/define-builders.mdx +1 -1
  31. package/reference/sdk/deployment/command-center.mdx +2 -2
  32. package/reference/sdk/deployment/index.mdx +1 -1
  33. package/reference/sdk/exports.mdx +4 -4
  34. package/reference/sdk/framework/agent.mdx +4 -3
  35. package/reference/sdk/framework/index.mdx +1 -1
  36. package/reference/sdk/framework/project-structure.mdx +34 -23
  37. package/reference/sdk/framework/tutorial-system.mdx +1 -1
  38. package/reference/sdk/getting-started.mdx +25 -52
  39. package/reference/sdk/index.mdx +3 -3
  40. package/reference/sdk/platform-tools/adapters-integration.mdx +1 -1
  41. package/reference/sdk/platform-tools/adapters-platform.mdx +5 -5
  42. package/reference/sdk/platform-tools/type-safety.mdx +1 -1
  43. package/reference/sdk/resources/patterns.mdx +10 -11
  44. package/reference/sdk/resources/types.mdx +15 -9
  45. package/reference/sdk/templates/data-enrichment.mdx +1 -1
  46. package/reference/sdk/templates/email-sender.mdx +1 -1
  47. package/reference/sdk/templates/index.mdx +47 -47
  48. package/reference/sdk/templates/lead-scorer.mdx +1 -1
  49. package/reference/sdk/templates/pdf-generator.mdx +42 -24
  50. package/reference/sdk/templates/recurring-job.mdx +20 -15
  51. package/reference/sdk/templates/text-classifier.mdx +1 -1
  52. package/reference/sdk/templates/web-scraper.mdx +9 -5
  53. package/reference/ui/exports.mdx +1 -1
  54. package/reference/ui/index.mdx +2 -2
package/dist/cli.cjs CHANGED
@@ -22654,44 +22654,64 @@ var init_ontology = __esm({
22654
22654
  }).passthrough();
22655
22655
  OntologyObjectTypeSchema = OntologyRecordBaseSchema.extend({
22656
22656
  properties: external_exports.record(external_exports.string().trim().min(1).max(200), external_exports.unknown()).optional(),
22657
- storage: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
22658
- });
22657
+ storage: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
22658
+ // Carried by the legacy entity projection (`addLegacyEntityProjections`); not
22659
+ // authored directly, but a real key an authored record must not collide with.
22660
+ rowSchema: external_exports.string().trim().min(1).optional(),
22661
+ stateCatalogId: external_exports.string().trim().min(1).optional()
22662
+ }).strict();
22659
22663
  OntologyLinkTypeSchema = OntologyRecordBaseSchema.extend({
22660
22664
  from: OntologyIdSchema,
22661
22665
  to: OntologyIdSchema,
22662
22666
  cardinality: external_exports.string().trim().min(1).max(80).optional(),
22663
22667
  via: external_exports.string().trim().min(1).max(255).optional()
22664
- });
22668
+ }).strict();
22665
22669
  OntologyActionTypeSchema = OntologyRecordBaseSchema.extend({
22666
22670
  actsOn: OntologyReferenceListSchema,
22667
22671
  input: external_exports.record(external_exports.string().trim().min(1).max(200), external_exports.unknown()).optional(),
22668
- effects: external_exports.array(external_exports.record(external_exports.string(), external_exports.unknown())).optional()
22669
- });
22672
+ effects: external_exports.array(external_exports.record(external_exports.string(), external_exports.unknown())).optional(),
22673
+ resourceId: external_exports.string().trim().min(1).optional(),
22674
+ invocations: external_exports.array(external_exports.unknown()).optional(),
22675
+ lifecycle: external_exports.string().trim().min(1).optional(),
22676
+ // Carried by the legacy action projection (`addLegacyActionProjections`); not
22677
+ // authored directly, but a real key an authored record must not collide with.
22678
+ legacyActionId: external_exports.string().trim().min(1).optional()
22679
+ }).strict();
22670
22680
  OntologyCatalogTypeSchema = OntologyRecordBaseSchema.extend({
22671
22681
  kind: external_exports.string().trim().min(1).max(120).optional(),
22672
22682
  appliesTo: OntologyIdSchema.optional(),
22673
- entries: external_exports.record(external_exports.string().trim().min(1).max(200), external_exports.unknown()).optional()
22674
- });
22683
+ entries: external_exports.record(external_exports.string().trim().min(1).max(200), external_exports.unknown()).optional(),
22684
+ // Carried by lead-gen's legacy stage-catalog projection
22685
+ // (`createLeadGenStageCatalog`); not authored directly, but a real key an
22686
+ // authored record must not collide with.
22687
+ legacyCatalogKey: external_exports.string().trim().min(1).optional(),
22688
+ // Carried in live tenant configs (Elevasis, `nirvana-marketing`, and the
22689
+ // `_template` scaffold all author these on `sales.crm:catalog/crm.pipeline`)
22690
+ // as a cross-reference to the pre-ontology CRM pipeline key/entity id. No
22691
+ // code currently reads them back — do not silently normalize them away.
22692
+ legacyPipelineKey: external_exports.string().trim().min(1).optional(),
22693
+ legacyEntityKey: external_exports.string().trim().min(1).optional()
22694
+ }).strict();
22675
22695
  OntologyEventTypeSchema = OntologyRecordBaseSchema.extend({
22676
22696
  payload: external_exports.record(external_exports.string().trim().min(1).max(200), external_exports.unknown()).optional()
22677
- });
22697
+ }).strict();
22678
22698
  OntologyInterfaceTypeSchema = OntologyRecordBaseSchema.extend({
22679
22699
  properties: external_exports.record(external_exports.string().trim().min(1).max(200), external_exports.unknown()).optional()
22680
- });
22700
+ }).strict();
22681
22701
  OntologyValueTypeSchema = OntologyRecordBaseSchema.extend({
22682
22702
  primitive: external_exports.string().trim().min(1).max(120).optional()
22683
- });
22703
+ }).strict();
22684
22704
  OntologySharedPropertySchema = OntologyRecordBaseSchema.extend({
22685
22705
  valueType: OntologyIdSchema.optional(),
22686
22706
  searchable: external_exports.boolean().optional(),
22687
22707
  pii: external_exports.boolean().optional()
22688
- });
22708
+ }).strict();
22689
22709
  OntologyGroupSchema = OntologyRecordBaseSchema.extend({
22690
22710
  members: OntologyReferenceListSchema
22691
- });
22711
+ }).strict();
22692
22712
  OntologyEndpointTypeSchema = OntologyRecordBaseSchema.extend({
22693
22713
  route: external_exports.string().trim().min(1).max(500).optional()
22694
- });
22714
+ }).strict();
22695
22715
  OntologyScopeSchema = external_exports.object({
22696
22716
  objectTypes: external_exports.record(OntologyIdSchema, OntologyObjectTypeSchema).default({}).optional(),
22697
22717
  linkTypes: external_exports.record(OntologyIdSchema, OntologyLinkTypeSchema).default({}).optional(),
@@ -22703,7 +22723,7 @@ var init_ontology = __esm({
22703
22723
  sharedProperties: external_exports.record(OntologyIdSchema, OntologySharedPropertySchema).default({}).optional(),
22704
22724
  groups: external_exports.record(OntologyIdSchema, OntologyGroupSchema).default({}).optional(),
22705
22725
  endpoints: external_exports.record(OntologyIdSchema, OntologyEndpointTypeSchema).default({}).optional()
22706
- }).default({});
22726
+ }).strict().default({});
22707
22727
  DEFAULT_ONTOLOGY_SCOPE = {
22708
22728
  valueTypes: {
22709
22729
  "global:value-type/uuid": {
@@ -23551,12 +23571,12 @@ var init_profile_registry = __esm({
23551
23571
 
23552
23572
  // ../core/src/organization-model/domains/systems.ts
23553
23573
  function isReservedPlatformProfileId(profileId) {
23554
- return SYSTEM_INTERFACE_READINESS_PROFILES.includes(profileId);
23574
+ return BUILT_IN_VALIDATED_PROFILE_IDS.includes(profileId);
23555
23575
  }
23556
23576
  function isBuiltInReadinessProfile(profileId) {
23557
23577
  return isReservedPlatformProfileId(profileId) || getBuiltInReadinessProfile(profileId) !== void 0;
23558
23578
  }
23559
- var SystemKindSchema, SystemLifecycleSchema, SystemIdSchema, SystemPathSchema, UiPositionSchema, NodeIdStringSchema, SystemUiSchema, SystemInterfaceKeySchema, SystemInterfaceLifecycleSchema, SYSTEM_INTERFACE_PROFILES, SYSTEM_INTERFACE_READINESS_PROFILES, SystemInterfaceReadinessProfileSchema, SystemInterfaceResourceScopeSchema, SystemApiInterfaceReadinessContractSchema, SystemApiInterfaceSchema, SystemInterfaceRefSchema, JsonValueSchema, SystemConfigSchema, SystemEntrySchema, SystemsDomainSchema, DEFAULT_ORGANIZATION_MODEL_SYSTEMS;
23579
+ var SystemKindSchema, SystemLifecycleSchema, SystemIdSchema, SystemPathSchema, UiPositionSchema, NodeIdStringSchema, SystemUiSchema, SystemInterfaceKeySchema, SystemInterfaceLifecycleSchema, SYSTEM_INTERFACE_PROFILES, SYSTEM_INTERFACE_READINESS_PROFILES, BUILT_IN_VALIDATED_PROFILE_IDS, SystemInterfaceReadinessProfileSchema, SystemInterfaceResourceScopeSchema, SystemApiInterfaceReadinessContractSchema, SystemApiInterfaceSchema, SystemInterfaceRefSchema, JsonValueSchema, SystemConfigSchema, SystemEntrySchema, SystemsDomainSchema, DEFAULT_ORGANIZATION_MODEL_SYSTEMS;
23560
23580
  var init_systems = __esm({
23561
23581
  "../core/src/organization-model/domains/systems.ts"() {
23562
23582
  "use strict";
@@ -23581,29 +23601,45 @@ var init_systems = __esm({
23581
23601
  path: PathSchema,
23582
23602
  surfaces: ReferenceIdsSchema,
23583
23603
  icon: IconNameSchema.optional()
23584
- });
23604
+ }).strict();
23585
23605
  SystemInterfaceKeySchema = ModelIdSchema;
23586
23606
  SystemInterfaceLifecycleSchema = external_exports.enum(["draft", "active", "disabled", "deprecated", "archived"]).meta({ label: "System interface lifecycle", color: "teal" });
23587
23607
  SYSTEM_INTERFACE_PROFILES = [
23588
23608
  {
23589
23609
  systemPath: "sales.lead-gen",
23590
23610
  interfaceKey: "api",
23591
- readinessProfile: "sales.lead-gen.api"
23611
+ readinessProfile: "sales.lead-gen.api",
23612
+ validation: "built-in"
23592
23613
  },
23593
23614
  {
23594
23615
  systemPath: "sales.crm",
23595
23616
  interfaceKey: "api",
23596
- readinessProfile: "sales.crm.api"
23617
+ readinessProfile: "sales.crm.api",
23618
+ validation: "built-in"
23597
23619
  },
23598
23620
  {
23599
23621
  systemPath: "sales.lead-gen",
23600
23622
  interfaceKey: "crm-handoff",
23601
- readinessProfile: "sales.lead-gen.crm-handoff"
23623
+ readinessProfile: "sales.lead-gen.crm-handoff",
23624
+ validation: "built-in"
23625
+ },
23626
+ {
23627
+ // Gated by `CONTENT_API_INTERFACE` in `apps/api/src/business/content/organization-model.ts`,
23628
+ // which every `/api/content/*` and `/api/external/content/*` route asserts. Contract-validated
23629
+ // rather than built-in because the required step catalog is per-adopter: Elevasis declares
23630
+ // `content:catalog/long-form-to-shorts-steps`, a tenant declares its own.
23631
+ systemPath: "content",
23632
+ interfaceKey: "api",
23633
+ readinessProfile: "content.api",
23634
+ validation: "contract"
23602
23635
  }
23603
23636
  ];
23604
23637
  SYSTEM_INTERFACE_READINESS_PROFILES = SYSTEM_INTERFACE_PROFILES.map(
23605
23638
  (profile) => profile.readinessProfile
23606
23639
  );
23640
+ BUILT_IN_VALIDATED_PROFILE_IDS = SYSTEM_INTERFACE_PROFILES.filter(
23641
+ (profile) => profile.validation === "built-in"
23642
+ ).map((profile) => profile.readinessProfile);
23607
23643
  SystemInterfaceReadinessProfileSchema = external_exports.string().trim().min(1);
23608
23644
  SystemInterfaceResourceScopeSchema = external_exports.array(ModelIdSchema).default([]);
23609
23645
  SystemApiInterfaceReadinessContractSchema = external_exports.object({
@@ -25013,13 +25049,13 @@ var init_foundation = __esm({
25013
25049
  });
25014
25050
 
25015
25051
  // ../core/src/organization-model/catalogs/content.ts
25016
- var ContentPipelineStepActorSchema, ContentPipelineStepReviewModeSchema, ContentPayloadFieldTypeSchema, ContentPayloadFieldDeclarationSchema, ContentPipelineStepDeclarationSchema, ContentSourceAssetKindDeclarationSchema;
25052
+ var ContentPipelineStepActorSchema, ContentPipelineStepReviewModeSchema, ContentPayloadFieldTypeSchema, ContentPayloadFieldDeclarationSchema, ContentWorkspaceRouteSchema, ContentPipelineStepDeclarationSchema, ContentSourceAssetKindDeclarationSchema;
25017
25053
  var init_content = __esm({
25018
25054
  "../core/src/organization-model/catalogs/content.ts"() {
25019
25055
  "use strict";
25020
25056
  init_zod();
25021
25057
  ContentPipelineStepActorSchema = external_exports.enum(["workflow", "agent", "vendor"]);
25022
- ContentPipelineStepReviewModeSchema = external_exports.enum(["live", "queued", "none"]);
25058
+ ContentPipelineStepReviewModeSchema = external_exports.enum(["none", "required"]);
25023
25059
  ContentPayloadFieldTypeSchema = external_exports.enum(["string", "text", "number", "boolean", "url", "string-array"]);
25024
25060
  ContentPayloadFieldDeclarationSchema = external_exports.object({
25025
25061
  key: external_exports.string().trim().min(1).max(200),
@@ -25027,6 +25063,7 @@ var init_content = __esm({
25027
25063
  type: ContentPayloadFieldTypeSchema,
25028
25064
  required: external_exports.boolean().optional()
25029
25065
  });
25066
+ ContentWorkspaceRouteSchema = external_exports.string().trim().min(1).max(400).regex(/^\//, 'workspaceRoute must be an app-relative path beginning with "/"');
25030
25067
  ContentPipelineStepDeclarationSchema = external_exports.object({
25031
25068
  label: external_exports.string().trim().min(1).max(160).optional(),
25032
25069
  description: external_exports.string().trim().min(1).max(2e3).optional(),
@@ -25052,6 +25089,16 @@ var init_content = __esm({
25052
25089
  * Resource at all.
25053
25090
  */
25054
25091
  actionId: external_exports.string().trim().min(1).max(200).optional(),
25092
+ /**
25093
+ * Per-step override of the pipeline's `workspaceRoute`. Absent on almost every
25094
+ * step -- the pipeline-level route is the common case, and this exists for the
25095
+ * chains whose gates are genuinely different screens (the video pipeline
25096
+ * reviews text candidates, then rendered video, then copy plus a schedule).
25097
+ *
25098
+ * Resolution is override-then-fallback: a display surface takes this when the
25099
+ * step declares one and the pipeline's otherwise. See `ContentWorkspaceRouteSchema`.
25100
+ */
25101
+ workspaceRoute: ContentWorkspaceRouteSchema.optional(),
25055
25102
  payloadFields: external_exports.array(ContentPayloadFieldDeclarationSchema).default([])
25056
25103
  });
25057
25104
  ContentSourceAssetKindDeclarationSchema = external_exports.object({
@@ -26244,6 +26291,13 @@ var init_lead_gen = __esm({
26244
26291
  }
26245
26292
  });
26246
26293
 
26294
+ // ../core/src/organization-model/catalogs/define-content-pipeline.ts
26295
+ var init_define_content_pipeline = __esm({
26296
+ "../core/src/organization-model/catalogs/define-content-pipeline.ts"() {
26297
+ "use strict";
26298
+ }
26299
+ });
26300
+
26247
26301
  // ../core/src/organization-model/readiness/engine.ts
26248
26302
  function addReadinessIssue(issues, family, code, message, details = {}) {
26249
26303
  issues.push({
@@ -26584,6 +26638,7 @@ var init_organization_model = __esm({
26584
26638
  init_graph();
26585
26639
  init_lead_gen();
26586
26640
  init_content();
26641
+ init_define_content_pipeline();
26587
26642
  init_branding();
26588
26643
  init_systems();
26589
26644
  init_resources();
@@ -44068,7 +44123,7 @@ function getModelInfo(model) {
44068
44123
  return MODEL_INFO[model];
44069
44124
  }
44070
44125
  for (const knownModel of MODEL_KEYS_BY_SPECIFICITY) {
44071
- if (model.startsWith(knownModel)) {
44126
+ if (model.startsWith(`${knownModel}-`)) {
44072
44127
  return MODEL_INFO[knownModel];
44073
44128
  }
44074
44129
  }
@@ -44094,7 +44149,7 @@ function validateModelConfig(config3) {
44094
44149
  throw new ModelConfigError(`Invalid config for ${model}: ${firstError.message}`, fieldName, model);
44095
44150
  }
44096
44151
  }
44097
- var GPT5OptionsSchema, GPT5ConfigSchema, MockConfigSchema, OpenRouterOptionsSchema, OpenRouterConfigSchema, AnthropicOptionsSchema, AnthropicStandardConfigSchema, AnthropicClaude5ConfigSchema, AnthropicConfigSchema, MODEL_INFO, MODEL_KEYS_BY_SPECIFICITY;
44152
+ var GPT5OptionsSchema, GPT5ConfigSchema, GPT56OptionsSchema, GPT56ConfigSchema, MockConfigSchema, OpenRouterOptionsSchema, OpenRouterConfigSchema, AnthropicOptionsSchema, AnthropicStandardConfigSchema, AnthropicClaude5ConfigSchema, AnthropicConfigSchema, GPT56_CACHE_READ_RATE_MULTIPLIER, CACHE_CREATION_RATE_MULTIPLIER, MODEL_INFO, MODEL_KEYS_BY_SPECIFICITY;
44098
44153
  var init_model_info = __esm({
44099
44154
  "../core/src/execution/engine/llm/model-info.ts"() {
44100
44155
  "use strict";
@@ -44114,6 +44169,19 @@ var init_model_info = __esm({
44114
44169
  topP: external_exports.number().min(0).max(1).optional(),
44115
44170
  modelOptions: GPT5OptionsSchema.optional()
44116
44171
  });
44172
+ GPT56OptionsSchema = external_exports.object({
44173
+ reasoning_effort: external_exports.enum(["none", "low", "medium", "high", "xhigh", "max"]).optional(),
44174
+ verbosity: external_exports.enum(["low", "medium", "high"]).optional()
44175
+ });
44176
+ GPT56ConfigSchema = external_exports.object({
44177
+ model: external_exports.enum(["gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna"]),
44178
+ provider: external_exports.enum(["openai"]),
44179
+ apiKey: external_exports.string(),
44180
+ temperature: external_exports.literal(1).optional(),
44181
+ maxOutputTokens: external_exports.number().min(4e3).optional(),
44182
+ topP: external_exports.number().min(0).max(1).optional(),
44183
+ modelOptions: GPT56OptionsSchema.optional()
44184
+ });
44117
44185
  MockConfigSchema = external_exports.object({
44118
44186
  model: external_exports.enum(["mock"]),
44119
44187
  provider: external_exports.enum(["mock"]),
@@ -44166,9 +44234,12 @@ var init_model_info = __esm({
44166
44234
  AnthropicClaude5ConfigSchema,
44167
44235
  AnthropicStandardConfigSchema
44168
44236
  ]);
44237
+ GPT56_CACHE_READ_RATE_MULTIPLIER = 0.1;
44238
+ CACHE_CREATION_RATE_MULTIPLIER = 1.25;
44169
44239
  MODEL_INFO = {
44170
44240
  // OpenAI GPT-5 (Reasoning Models)
44171
44241
  "gpt-5": {
44242
+ provider: "openai",
44172
44243
  inputCostPer1M: 125,
44173
44244
  // $1.25 per 1M tokens
44174
44245
  outputCostPer1M: 1e3,
@@ -44182,6 +44253,7 @@ var init_model_info = __esm({
44182
44253
  configSchema: GPT5ConfigSchema
44183
44254
  },
44184
44255
  "gpt-5.4-mini": {
44256
+ provider: "openai",
44185
44257
  inputCostPer1M: 75,
44186
44258
  // $0.75 per 1M tokens
44187
44259
  outputCostPer1M: 450,
@@ -44195,6 +44267,7 @@ var init_model_info = __esm({
44195
44267
  configSchema: GPT5ConfigSchema
44196
44268
  },
44197
44269
  "gpt-5.4-nano": {
44270
+ provider: "openai",
44198
44271
  inputCostPer1M: 20,
44199
44272
  // $0.20 per 1M tokens
44200
44273
  outputCostPer1M: 125,
@@ -44206,8 +44279,60 @@ var init_model_info = __esm({
44206
44279
  category: "standard",
44207
44280
  configSchema: GPT5ConfigSchema
44208
44281
  },
44282
+ // OpenAI GPT-5.6 family (GA 2026-07-09). All three tiers share 1.05M context, 128K max output,
44283
+ // image input, tool use, structured outputs, and prompt caching -- they differ in reasoning depth
44284
+ // and price, not capability. The bare `gpt-5.6` alias is deliberately unregistered; see OpenAIModel.
44285
+ "gpt-5.6-sol": {
44286
+ provider: "openai",
44287
+ inputCostPer1M: 500,
44288
+ // $5.00 per 1M tokens
44289
+ outputCostPer1M: 3e3,
44290
+ // $30.00 per 1M tokens
44291
+ minTokens: 4e3,
44292
+ recommendedTokens: 8e3,
44293
+ maxTokens: 105e4,
44294
+ // 1.05M context window
44295
+ maxOutputTokens: 128e3,
44296
+ category: "reasoning",
44297
+ configSchema: GPT56ConfigSchema,
44298
+ cacheReadRateMultiplier: GPT56_CACHE_READ_RATE_MULTIPLIER,
44299
+ cacheCreationRateMultiplier: CACHE_CREATION_RATE_MULTIPLIER
44300
+ },
44301
+ "gpt-5.6-terra": {
44302
+ provider: "openai",
44303
+ inputCostPer1M: 250,
44304
+ // $2.50 per 1M tokens
44305
+ outputCostPer1M: 1500,
44306
+ // $15.00 per 1M tokens
44307
+ minTokens: 4e3,
44308
+ recommendedTokens: 8e3,
44309
+ maxTokens: 105e4,
44310
+ // 1.05M context window
44311
+ maxOutputTokens: 128e3,
44312
+ category: "standard",
44313
+ configSchema: GPT56ConfigSchema,
44314
+ cacheReadRateMultiplier: GPT56_CACHE_READ_RATE_MULTIPLIER,
44315
+ cacheCreationRateMultiplier: CACHE_CREATION_RATE_MULTIPLIER
44316
+ },
44317
+ "gpt-5.6-luna": {
44318
+ provider: "openai",
44319
+ inputCostPer1M: 100,
44320
+ // $1.00 per 1M tokens
44321
+ outputCostPer1M: 600,
44322
+ // $6.00 per 1M tokens
44323
+ minTokens: 4e3,
44324
+ recommendedTokens: 8e3,
44325
+ maxTokens: 105e4,
44326
+ // 1.05M context window
44327
+ maxOutputTokens: 128e3,
44328
+ category: "standard",
44329
+ configSchema: GPT56ConfigSchema,
44330
+ cacheReadRateMultiplier: GPT56_CACHE_READ_RATE_MULTIPLIER,
44331
+ cacheCreationRateMultiplier: CACHE_CREATION_RATE_MULTIPLIER
44332
+ },
44209
44333
  // Mock model for testing
44210
44334
  mock: {
44335
+ provider: "mock",
44211
44336
  inputCostPer1M: 0,
44212
44337
  // Free for tests
44213
44338
  outputCostPer1M: 0,
@@ -44221,6 +44346,7 @@ var init_model_info = __esm({
44221
44346
  },
44222
44347
  // OpenRouter Models (via openrouter.ai)
44223
44348
  "openrouter/z-ai/glm-5": {
44349
+ provider: "openrouter",
44224
44350
  inputCostPer1M: 72,
44225
44351
  // $0.72 per 1M tokens
44226
44352
  outputCostPer1M: 230,
@@ -44234,6 +44360,7 @@ var init_model_info = __esm({
44234
44360
  },
44235
44361
  // Anthropic Claude Models (direct SDK access via @anthropic-ai/sdk)
44236
44362
  "claude-opus-5": {
44363
+ provider: "anthropic",
44237
44364
  inputCostPer1M: 500,
44238
44365
  // $5.00 per 1M tokens
44239
44366
  outputCostPer1M: 2500,
@@ -44247,6 +44374,7 @@ var init_model_info = __esm({
44247
44374
  configSchema: AnthropicConfigSchema
44248
44375
  },
44249
44376
  "claude-sonnet-5": {
44377
+ provider: "anthropic",
44250
44378
  // List pricing. An introductory rate of $2.00/$10.00 runs through 2026-08-31; encoding the
44251
44379
  // temporary rate would make historical cost analytics wrong once it lapses.
44252
44380
  inputCostPer1M: 300,
@@ -44262,6 +44390,7 @@ var init_model_info = __esm({
44262
44390
  configSchema: AnthropicConfigSchema
44263
44391
  },
44264
44392
  "claude-haiku-4-5-20251001": {
44393
+ provider: "anthropic",
44265
44394
  inputCostPer1M: 100,
44266
44395
  // $1.00 per 1M tokens
44267
44396
  outputCostPer1M: 500,
@@ -44275,6 +44404,7 @@ var init_model_info = __esm({
44275
44404
  configSchema: AnthropicConfigSchema
44276
44405
  },
44277
44406
  "claude-haiku-4-5": {
44407
+ provider: "anthropic",
44278
44408
  inputCostPer1M: 100,
44279
44409
  // $1.00 per 1M tokens
44280
44410
  outputCostPer1M: 500,
@@ -44663,6 +44793,138 @@ var init_response_schema = __esm({
44663
44793
  }
44664
44794
  });
44665
44795
 
44796
+ // ../core/src/execution/engine/workflow/types.ts
44797
+ var StepType;
44798
+ var init_types5 = __esm({
44799
+ "../core/src/execution/engine/workflow/types.ts"() {
44800
+ "use strict";
44801
+ StepType = {
44802
+ LINEAR: "linear",
44803
+ CONDITIONAL: "conditional"
44804
+ };
44805
+ }
44806
+ });
44807
+
44808
+ // ../core/src/execution/engine/workflow/errors.ts
44809
+ var WorkflowStepError, WorkflowValidationError;
44810
+ var init_errors5 = __esm({
44811
+ "../core/src/execution/engine/workflow/errors.ts"() {
44812
+ "use strict";
44813
+ init_errors3();
44814
+ WorkflowStepError = class extends ExecutionError {
44815
+ type = "workflow_step_error";
44816
+ severity = "critical";
44817
+ category = "workflow";
44818
+ /**
44819
+ * @param cause - The error the step actually threw. Kept so the original stack and any
44820
+ * non-`ExecutionError` throw survive the wrap; its classification is additionally copied into
44821
+ * `context` by the caller, because `type`/`severity`/`category` are fixed on this class.
44822
+ */
44823
+ constructor(message, context, cause) {
44824
+ super(message, context);
44825
+ if (cause !== void 0) this.cause = cause;
44826
+ }
44827
+ };
44828
+ WorkflowValidationError = class extends ExecutionError {
44829
+ type = "workflow_validation_error";
44830
+ severity = "info";
44831
+ category = "validation";
44832
+ constructor(message, context) {
44833
+ super(message, context);
44834
+ }
44835
+ };
44836
+ }
44837
+ });
44838
+
44839
+ // ../core/src/execution/engine/workflow/utils.ts
44840
+ function validateEntryPoint(steps, entryPoint) {
44841
+ if (!(entryPoint in steps)) {
44842
+ throw new WorkflowValidationError(`Entry point step '${entryPoint}' not found in workflow`, {
44843
+ entryPoint
44844
+ });
44845
+ }
44846
+ }
44847
+ function findTerminalSteps(steps) {
44848
+ return Object.values(steps).filter((step) => step.next === null);
44849
+ }
44850
+ function validateTerminalSteps(steps, workflowId) {
44851
+ const terminalSteps = findTerminalSteps(steps);
44852
+ if (terminalSteps.length === 0) {
44853
+ throw new WorkflowValidationError(`Workflow '${workflowId}' must have at least one terminal step (next: null)`, {
44854
+ workflowId
44855
+ });
44856
+ }
44857
+ }
44858
+ function validateStepReferences(steps) {
44859
+ for (const [id, step] of Object.entries(steps)) {
44860
+ if (step.next === null) {
44861
+ continue;
44862
+ }
44863
+ if (step.next.type === StepType.LINEAR) {
44864
+ if (!(step.next.target in steps)) {
44865
+ throw new WorkflowValidationError(`Step '${id}' references non-existent target '${step.next.target}'`, {
44866
+ stepId: id,
44867
+ target: step.next.target
44868
+ });
44869
+ }
44870
+ } else if (step.next.type === StepType.CONDITIONAL) {
44871
+ const targets = [...step.next.routes.map((r) => r.target), step.next.default];
44872
+ for (const target of targets) {
44873
+ if (!(target in steps)) {
44874
+ throw new WorkflowValidationError(`Step '${id}' references non-existent target '${target}'`, {
44875
+ stepId: id,
44876
+ target
44877
+ });
44878
+ }
44879
+ }
44880
+ }
44881
+ }
44882
+ }
44883
+ function detectCycle(visited, executionPath, currentStepId) {
44884
+ if (visited.has(currentStepId)) {
44885
+ const cycle = executionPath.slice(executionPath.indexOf(currentStepId));
44886
+ throw new WorkflowStepError(`Cycle detected in workflow: ${cycle.join(" -> ")} -> ${currentStepId}`, {
44887
+ stepId: currentStepId,
44888
+ cycle: [...cycle, currentStepId]
44889
+ });
44890
+ }
44891
+ }
44892
+ function validateWorkflowGraph(steps, entryPoint, workflowId) {
44893
+ const onPath = /* @__PURE__ */ new Set();
44894
+ const executionPath = [];
44895
+ const reached = /* @__PURE__ */ new Set();
44896
+ const walk = (stepId) => {
44897
+ detectCycle(onPath, executionPath, stepId);
44898
+ onPath.add(stepId);
44899
+ executionPath.push(stepId);
44900
+ reached.add(stepId);
44901
+ const step = steps[stepId];
44902
+ if (step && step.next !== null) {
44903
+ const targets = step.next.type === StepType.LINEAR ? [step.next.target] : [...step.next.routes.map((route) => route.target), step.next.default];
44904
+ for (const target of targets) {
44905
+ if (target in steps) walk(target);
44906
+ }
44907
+ }
44908
+ executionPath.pop();
44909
+ onPath.delete(stepId);
44910
+ };
44911
+ if (entryPoint in steps) walk(entryPoint);
44912
+ const orphanIds = Object.keys(steps).filter((id) => !reached.has(id));
44913
+ if (orphanIds.length > 0) {
44914
+ throw new WorkflowValidationError(
44915
+ `Workflow '${workflowId}' has step(s) unreachable from entry point '${entryPoint}': ${orphanIds.join(", ")}`,
44916
+ { workflowId, entryPoint, orphanIds }
44917
+ );
44918
+ }
44919
+ }
44920
+ var init_utils3 = __esm({
44921
+ "../core/src/execution/engine/workflow/utils.ts"() {
44922
+ "use strict";
44923
+ init_types5();
44924
+ init_errors5();
44925
+ }
44926
+ });
44927
+
44666
44928
  // ../core/src/platform/registry/validation.ts
44667
44929
  function getResourceValidatorMode(explicitMode) {
44668
44930
  if (explicitMode) return explicitMode;
@@ -44681,7 +44943,14 @@ function emitGovernanceIssues(issues, mode, onWarning) {
44681
44943
  if (issues.length === 0) return;
44682
44944
  if (mode === "strict") {
44683
44945
  const first = issues[0];
44684
- throw new RegistryValidationError(first.orgName, first.resourceId, "organizationModel.resources", first.message);
44946
+ const messages = issues.map((issue2) => issue2.message);
44947
+ throw new RegistryValidationError(
44948
+ first.orgName,
44949
+ first.resourceId,
44950
+ "organizationModel.resources",
44951
+ messages.join("\n"),
44952
+ messages
44953
+ );
44685
44954
  }
44686
44955
  const warn2 = onWarning ?? ((issue2) => console.warn(issue2.message));
44687
44956
  for (const issue2 of issues) {
@@ -44842,7 +45111,7 @@ function addTopologyIssues(issues, orgName, deployment, organizationModel, syste
44842
45111
  if (ref.kind === "humanCheckpoint") return humanCheckpointIds.has(ref.id);
44843
45112
  if (ref.kind === "externalResource") return externalResourceIds.has(ref.id);
44844
45113
  if (ref.kind === "ontology") {
44845
- if (ontologyIndex === void 0) return true;
45114
+ if (ontologyIndex === void 0) return false;
44846
45115
  return Object.values(ontologyIndex).some((records) => records[ref.id] !== void 0);
44847
45116
  }
44848
45117
  return false;
@@ -45032,7 +45301,8 @@ function detectMissingApiInterfaceDeclarations(orgName, organizationModel) {
45032
45301
  }
45033
45302
  return gaps;
45034
45303
  }
45035
- function validateDeclaredSystemInterfaceReadiness(orgName, organizationModel) {
45304
+ function validateDeclaredSystemInterfaceReadiness(orgName, organizationModel, options = {}) {
45305
+ const mode = getResourceValidatorMode(options.mode);
45036
45306
  const issues = [];
45037
45307
  if (organizationModel === void 0) return { valid: true, issues };
45038
45308
  const model = organizationModel;
@@ -45058,17 +45328,27 @@ function validateDeclaredSystemInterfaceReadiness(orgName, organizationModel) {
45058
45328
  }
45059
45329
  }
45060
45330
  if (issues.length > 0) {
45061
- const first = issues[0];
45062
- throw new RegistryValidationError(
45063
- first.orgName,
45064
- `${first.systemPath}/${first.interfaceKey}`,
45065
- first.path ?? "organizationModel.systems.apiInterface",
45066
- first.message
45067
- );
45331
+ if (mode === "strict") {
45332
+ const first = issues[0];
45333
+ const messages = issues.map((issue2) => issue2.message);
45334
+ throw new RegistryValidationError(
45335
+ first.orgName,
45336
+ `${first.systemPath}/${first.interfaceKey}`,
45337
+ first.path ?? "organizationModel.systems.apiInterface",
45338
+ messages.join("\n"),
45339
+ messages
45340
+ );
45341
+ }
45342
+ const warn2 = options.onWarning ?? ((issue2) => console.warn(issue2.message));
45343
+ for (const issue2 of issues) {
45344
+ warn2(issue2);
45345
+ }
45346
+ return { valid: false, issues };
45068
45347
  }
45069
45348
  return { valid: true, issues };
45070
45349
  }
45071
- function validateDeploymentSpec(orgName, resources) {
45350
+ function validateDeploymentSpec(orgName, resources, options = {}) {
45351
+ const warn2 = options.onWarning ?? ((message) => console.warn(message));
45072
45352
  const seenIds = /* @__PURE__ */ new Set();
45073
45353
  resources.workflows?.forEach((workflow) => {
45074
45354
  const id = workflow.config.resourceId;
@@ -45087,6 +45367,14 @@ function validateDeploymentSpec(orgName, resources) {
45087
45367
  if (workflow.interface) {
45088
45368
  validateExecutionInterface(orgName, id, workflow.interface, workflow.contract.inputSchema);
45089
45369
  }
45370
+ try {
45371
+ validateEntryPoint(workflow.steps, workflow.entryPoint);
45372
+ validateTerminalSteps(workflow.steps, id);
45373
+ validateStepReferences(workflow.steps);
45374
+ validateWorkflowGraph(workflow.steps, workflow.entryPoint, id);
45375
+ } catch (error46) {
45376
+ warn2(`[${orgName}] Workflow '${id}' graph validation: ${error46 instanceof Error ? error46.message : String(error46)}`);
45377
+ }
45090
45378
  });
45091
45379
  resources.agents?.forEach((agent) => {
45092
45380
  const id = agent.config.resourceId;
@@ -45100,14 +45388,20 @@ function validateDeploymentSpec(orgName, resources) {
45100
45388
  }
45101
45389
  seenIds.add(id);
45102
45390
  validateResourceModelConfig(orgName, id, agent.modelConfig);
45103
- validateAgentGrammar(orgName, id, agent);
45104
- validateAgentCheapAssertions(orgName, id, agent);
45391
+ validateAgentGrammar(orgName, id, agent, options.mode);
45392
+ validateAgentCheapAssertions(orgName, id, agent, options.mode);
45105
45393
  if (agent.interface) {
45106
45394
  validateExecutionInterface(orgName, id, agent.interface, agent.contract.inputSchema);
45107
45395
  }
45108
45396
  });
45109
- validateResourceGovernance(orgName, resources);
45110
- validateDeclaredSystemInterfaceReadiness(orgName, resources.organizationModel);
45397
+ validateResourceGovernance(orgName, resources, void 0, {
45398
+ mode: options.mode,
45399
+ onWarning: (issue2) => warn2(issue2.message)
45400
+ });
45401
+ validateDeclaredSystemInterfaceReadiness(orgName, resources.organizationModel, {
45402
+ mode: options.mode,
45403
+ onWarning: (issue2) => warn2(issue2.message)
45404
+ });
45111
45405
  }
45112
45406
  function validateResourceModelConfig(orgName, resourceId, modelConfig) {
45113
45407
  try {
@@ -45182,7 +45476,7 @@ function describeGrammarRefusal(reasons, toolInputSchema) {
45182
45476
  }
45183
45477
  return `refused strict mode: ${reasons.join(", ")}`;
45184
45478
  }
45185
- function validateAgentGrammar(orgName, agentId, agent) {
45479
+ function validateAgentGrammar(orgName, agentId, agent, mode) {
45186
45480
  const dialect = dialectForProvider(agent.modelConfig.provider);
45187
45481
  if (!dialect) return;
45188
45482
  const capabilities = agentCapabilitiesForGrammarCheck(agent.config);
@@ -45203,12 +45497,12 @@ function validateAgentGrammar(orgName, agentId, agent) {
45203
45497
  compileSchema(offending.inputSchema, dialect).refusalReasons,
45204
45498
  offending.inputSchema
45205
45499
  )}. This silently drops strict-mode enforcement for the agent's ENTIRE iteration schema on every call, not just this tool -- compileSchema refuses whole-schema, never per-tool.` : `[${orgName}] Agent '${agentId}' iteration schema refused strict mode for provider '${agent.modelConfig.provider}': ${compiled.refusalReasons.join(", ")}. No single tool is independently responsible -- this is a whole-schema limit (e.g. total optional properties across every tool exceeding the provider's cap).`;
45206
- if (getResourceValidatorMode() === "strict") {
45500
+ if (getResourceValidatorMode(mode) === "strict") {
45207
45501
  throw new RegistryValidationError(orgName, agentId, "tools", message);
45208
45502
  }
45209
45503
  console.warn(message);
45210
45504
  }
45211
- function validateAgentCheapAssertions(orgName, agentId, agent) {
45505
+ function validateAgentCheapAssertions(orgName, agentId, agent, mode) {
45212
45506
  const issues = [];
45213
45507
  const config3 = agent.config;
45214
45508
  if (config3.sessionCapable && config3.securityLevel === "none") {
@@ -45238,7 +45532,7 @@ function validateAgentCheapAssertions(orgName, agentId, agent) {
45238
45532
  }
45239
45533
  if (issues.length === 0) return;
45240
45534
  const message = `[${orgName}] Agent '${agentId}': ${issues.join(" ")}`;
45241
- if (getResourceValidatorMode() === "strict") {
45535
+ if (getResourceValidatorMode(mode) === "strict") {
45242
45536
  throw new RegistryValidationError(orgName, agentId, "config", message);
45243
45537
  }
45244
45538
  console.warn(message);
@@ -45505,34 +45799,24 @@ var init_validation2 = __esm({
45505
45799
  init_compile();
45506
45800
  init_dialect();
45507
45801
  init_response_schema();
45802
+ init_utils3();
45508
45803
  init_helpers();
45509
45804
  init_ontology();
45510
45805
  init_readiness();
45511
45806
  init_systems();
45512
45807
  RegistryValidationError = class extends Error {
45513
- constructor(orgName, resourceId, field2, message) {
45808
+ constructor(orgName, resourceId, field2, message, issues) {
45514
45809
  super(message);
45515
45810
  this.orgName = orgName;
45516
45811
  this.resourceId = resourceId;
45517
45812
  this.field = field2;
45813
+ this.issues = issues;
45518
45814
  this.name = "RegistryValidationError";
45519
45815
  }
45520
45816
  };
45521
45817
  }
45522
45818
  });
45523
45819
 
45524
- // ../core/src/execution/engine/workflow/types.ts
45525
- var StepType;
45526
- var init_types5 = __esm({
45527
- "../core/src/execution/engine/workflow/types.ts"() {
45528
- "use strict";
45529
- StepType = {
45530
- LINEAR: "linear",
45531
- CONDITIONAL: "conditional"
45532
- };
45533
- }
45534
- });
45535
-
45536
45820
  // ../core/src/execution/engine/base/serialization.ts
45537
45821
  function serializeDefinition(definition, options) {
45538
45822
  const opts = {
@@ -47268,7 +47552,7 @@ var init_croner = __esm({
47268
47552
  });
47269
47553
 
47270
47554
  // ../core/src/execution/scheduler/utils.ts
47271
- var init_utils3 = __esm({
47555
+ var init_utils4 = __esm({
47272
47556
  "../core/src/execution/scheduler/utils.ts"() {
47273
47557
  "use strict";
47274
47558
  init_esm2();
@@ -47282,7 +47566,7 @@ var init_scheduler = __esm({
47282
47566
  "use strict";
47283
47567
  init_types8();
47284
47568
  init_schemas3();
47285
- init_utils3();
47569
+ init_utils4();
47286
47570
  }
47287
47571
  });
47288
47572
 
@@ -47675,7 +47959,7 @@ var init_schemas6 = __esm({
47675
47959
  });
47676
47960
 
47677
47961
  // ../core/src/operations/observability/utils.ts
47678
- var init_utils4 = __esm({
47962
+ var init_utils5 = __esm({
47679
47963
  "../core/src/operations/observability/utils.ts"() {
47680
47964
  "use strict";
47681
47965
  }
@@ -47687,7 +47971,7 @@ var init_observability = __esm({
47687
47971
  "use strict";
47688
47972
  init_types13();
47689
47973
  init_schemas6();
47690
- init_utils4();
47974
+ init_utils5();
47691
47975
  }
47692
47976
  });
47693
47977
 
@@ -48555,6 +48839,21 @@ var init_credentials2 = __esm({
48555
48839
  }
48556
48840
  });
48557
48841
 
48842
+ // ../core/src/integrations/cloud-storage/types.ts
48843
+ var init_types20 = __esm({
48844
+ "../core/src/integrations/cloud-storage/types.ts"() {
48845
+ "use strict";
48846
+ }
48847
+ });
48848
+
48849
+ // ../core/src/integrations/cloud-storage/index.ts
48850
+ var init_cloud_storage = __esm({
48851
+ "../core/src/integrations/cloud-storage/index.ts"() {
48852
+ "use strict";
48853
+ init_types20();
48854
+ }
48855
+ });
48856
+
48558
48857
  // ../core/src/index.ts
48559
48858
  var init_src = __esm({
48560
48859
  "../core/src/index.ts"() {
@@ -48571,6 +48870,7 @@ var init_src = __esm({
48571
48870
  init_forms();
48572
48871
  init_oauth();
48573
48872
  init_credentials2();
48873
+ init_cloud_storage();
48574
48874
  }
48575
48875
  });
48576
48876
 
@@ -48627,6 +48927,12 @@ function resolveApiKey(prod) {
48627
48927
  }
48628
48928
  return process.env.ELEVASIS_PLATFORM_KEY ?? "";
48629
48929
  }
48930
+ function isProdApiUrl(apiUrl) {
48931
+ return !apiUrl.includes("localhost");
48932
+ }
48933
+ function resolveApiKeyForUrl(apiUrl) {
48934
+ return resolveApiKey(isProdApiUrl(apiUrl));
48935
+ }
48630
48936
  function tryFindProjectRoot(startDir) {
48631
48937
  const raw = (0, import_path.resolve)(startDir);
48632
48938
  let dir;
@@ -48711,12 +49017,89 @@ var init_config2 = __esm({
48711
49017
  }
48712
49018
  });
48713
49019
 
49020
+ // src/cli/readiness-failure.ts
49021
+ function isReadinessFailureDetails(details) {
49022
+ if (!details || typeof details !== "object") return false;
49023
+ const candidate = details;
49024
+ return typeof candidate.systemPath === "string" && typeof candidate.interfaceKey === "string" && // Deliberately `string`, not a check against the known families. Narrowing
49025
+ // it here would reject a readiness refusal carrying a family this build has
49026
+ // not learned yet, and `request()` would fall through to the gateway
49027
+ // message -- which tells the operator the API did not reject the request and
49028
+ // it may still be running server-side. That is false for every readiness
49029
+ // refusal, familiar family or not. An unrecognized code is handled where it
49030
+ // can be handled honestly, in `guidanceForFamily`.
49031
+ typeof candidate.readinessCode === "string" && Array.isArray(candidate.issues);
49032
+ }
49033
+ function parseReadinessFailureDetails(errorText) {
49034
+ let parsed;
49035
+ try {
49036
+ parsed = JSON.parse(errorText);
49037
+ } catch {
49038
+ return void 0;
49039
+ }
49040
+ if (parsed.code !== "SERVICE_UNAVAILABLE") return void 0;
49041
+ return isReadinessFailureDetails(parsed.details) ? parsed.details : void 0;
49042
+ }
49043
+ function formatIssue(issue2) {
49044
+ let line = ` - [${issue2.code}] ${issue2.message}`;
49045
+ if (issue2.path) line += ` (path: ${issue2.path})`;
49046
+ if (issue2.ref) line += ` (ref: ${issue2.ref})`;
49047
+ return line;
49048
+ }
49049
+ function describeUnknownFamily(readinessCode) {
49050
+ return `This CLI does not recognize readiness code "${readinessCode}", so it cannot describe the general shape of the fix. The issues below are the API's own explanation and are the authoritative part of this message.
49051
+ The likely cause is version skew -- this @elevasis/sdk is older than the API it just called. Update it (pnpm update @elevasis/sdk) and run this again.`;
49052
+ }
49053
+ function guidanceForFamily(details) {
49054
+ const lookup = FAMILY_GUIDANCE;
49055
+ return lookup[details.readinessCode]?.(details) ?? describeUnknownFamily(details.readinessCode);
49056
+ }
49057
+ function describeReadinessFailure(details, endpoint) {
49058
+ const profileSuffix = details.readinessProfile ? ` (readiness profile: ${details.readinessProfile})` : "";
49059
+ const lines = [
49060
+ `API request refused (503): ${details.systemPath}/${details.interfaceKey} is not ready for this API surface${profileSuffix}.`,
49061
+ `This IS the API rejecting the request -- it is not a gateway hiccup, and re-running it will not help.`,
49062
+ ` Endpoint: ${endpoint}`,
49063
+ ""
49064
+ ];
49065
+ lines.push(
49066
+ details.readinessCode === "STALE_OM_SNAPSHOT" ? details.issues[0]?.message ?? "The deployed organization model snapshot is stale. Deploy again to fix this: elevasis-sdk deploy" : guidanceForFamily(details)
49067
+ );
49068
+ if (details.issues.length > 0) {
49069
+ lines.push("", " Issues:", ...details.issues.map(formatIssue));
49070
+ }
49071
+ lines.push("", ` Run 'elevasis-sdk doctor' to see what else is not ready.`);
49072
+ return lines.join("\n");
49073
+ }
49074
+ var FAMILY_GUIDANCE;
49075
+ var init_readiness_failure = __esm({
49076
+ "src/cli/readiness-failure.ts"() {
49077
+ "use strict";
49078
+ FAMILY_GUIDANCE = {
49079
+ SYSTEM_INTERFACE_MISSING: ({ systemPath }) => `This organization has not adopted the "${systemPath}" System. Declare it in this project's core/config/organization-model/systems.ts with an apiInterface block, then deploy (elevasis-sdk deploy or pnpm operations:deploy).
49080
+ Known trap: an empty apiInterface.resourceIds throws -- omit the apiInterface block entirely for the supported opt-out.`,
49081
+ SYSTEM_INTERFACE_DISABLED: ({ systemPath }) => `The "${systemPath}" System declares an apiInterface but it is not active. Re-enable it (apiInterface.lifecycle: 'active') and redeploy.`,
49082
+ // Two failures share this family and they need opposite advice.
49083
+ //
49084
+ // A validator that rejected a declaration emits a `path`, and pointing at it
49085
+ // is the whole fix. A stored snapshot that would not parse emits no `path` --
49086
+ // the API sets `ref` (a deployment or organization id) and never `path` --
49087
+ // and the broken thing is the deployed copy, not the source the operator
49088
+ // would go and edit. Sending them after a "path" that is not in the payload,
49089
+ // to fix a declaration that may be perfectly fine, was the failure this
49090
+ // wording had before.
49091
+ SYSTEM_INTERFACE_INVALID: ({ systemPath, issues }) => issues.some((issue2) => issue2.path) ? `The "${systemPath}" System's apiInterface / readinessContract declaration is malformed. See the "path" on each issue below for the offending field.` : `The "${systemPath}" System's stored organization model snapshot could not be read. No field of your declaration is known to be wrong -- it is the deployed copy that failed, so deploy again first (elevasis-sdk deploy). If that does not clear it, the declaration is the next place to look.`,
49092
+ SYSTEM_INTERFACE_NOT_READY: ({ systemPath }) => `The "${systemPath}" System's readinessContract is unsatisfied. See the issues below for the missing requiredObjects / requiredCatalogs refs.`,
49093
+ SYSTEM_BRIDGE_NOT_READY: ({ systemPath }) => `The counterpart System of "${systemPath}"'s cross-System handoff is not ready. Check readiness on both sides of the bridge.`
49094
+ };
49095
+ }
49096
+ });
49097
+
48714
49098
  // src/cli/api-client.ts
48715
49099
  function getApiKey(apiUrl) {
48716
- const isProd = !apiUrl.includes("localhost");
48717
- const key = resolveApiKey(isProd);
49100
+ const key = resolveApiKeyForUrl(apiUrl);
48718
49101
  if (!key) {
48719
- const varName = isProd ? "ELEVASIS_PLATFORM_KEY" : "ELEVASIS_PLATFORM_KEY_DEV";
49102
+ const varName = isProdApiUrl(apiUrl) ? "ELEVASIS_PLATFORM_KEY" : "ELEVASIS_PLATFORM_KEY_DEV";
48720
49103
  throw new Error(`${varName} environment variable is required.
48721
49104
  Set it in your .env file: ${varName}=sk_...`);
48722
49105
  }
@@ -48778,6 +49161,10 @@ async function request(method, endpoint, apiUrl, body) {
48778
49161
  if (response.status === 401) {
48779
49162
  throw new Error(`401 Unauthorized: Invalid or missing ELEVASIS_PLATFORM_KEY. Check your .env file.`);
48780
49163
  }
49164
+ const readinessDetails = parseReadinessFailureDetails(errorText);
49165
+ if (readinessDetails) {
49166
+ throw new Error(describeReadinessFailure(readinessDetails, endpoint));
49167
+ }
48781
49168
  if (GATEWAY_STATUSES.has(response.status)) {
48782
49169
  throw new Error(describeGatewayFailure(response.status, endpoint, elapsedMs));
48783
49170
  }
@@ -48805,6 +49192,7 @@ var init_api_client = __esm({
48805
49192
  "src/cli/api-client.ts"() {
48806
49193
  "use strict";
48807
49194
  init_config2();
49195
+ init_readiness_failure();
48808
49196
  DEFAULT_TIMEOUT_MS = 2 * 60 * 60 * 1e3;
48809
49197
  GATEWAY_STATUSES = /* @__PURE__ */ new Set([502, 503, 504]);
48810
49198
  }
@@ -48837,7 +49225,7 @@ var init_package = __esm({
48837
49225
  "package.json"() {
48838
49226
  package_default = {
48839
49227
  name: "@elevasis/sdk",
48840
- version: "1.47.0",
49228
+ version: "1.49.0",
48841
49229
  description: "SDK for building Elevasis organization resources",
48842
49230
  type: "module",
48843
49231
  bin: {
@@ -49042,7 +49430,15 @@ function extractResourceMetadata(resource, schemaWarnings) {
49042
49430
  return meta;
49043
49431
  }
49044
49432
  function bumpVersion(current, type) {
49045
- const [major, minor, patch] = current.split(".").map(Number);
49433
+ const match = PLAIN_SEMVER_RE.exec(current);
49434
+ if (!match) {
49435
+ throw new Error(
49436
+ `Cannot bump version: "${current}" is not a plain "major.minor.patch" version (e.g. "1.0.0"). Set the deployment spec's version to a plain semver value before using --major/--minor/--patch.`
49437
+ );
49438
+ }
49439
+ const major = Number(match[1]);
49440
+ const minor = Number(match[2]);
49441
+ const patch = Number(match[3]);
49046
49442
  switch (type) {
49047
49443
  case "major":
49048
49444
  return `${major + 1}.0.0`;
@@ -49053,36 +49449,55 @@ function bumpVersion(current, type) {
49053
49449
  }
49054
49450
  }
49055
49451
  function updateDeploymentVersionSource(source, newVersion) {
49056
- let offset = 0;
49452
+ const exportIndex = source.indexOf("export default");
49453
+ if (exportIndex === -1) {
49454
+ throw new Error('Unable to find "export default" in the deployment entry file');
49455
+ }
49456
+ const rootBraceIndex = source.indexOf("{", exportIndex);
49457
+ if (rootBraceIndex === -1) {
49458
+ throw new Error("Unable to find the default-exported object in the deployment entry file");
49459
+ }
49460
+ let depth = 0;
49461
+ let offset = rootBraceIndex;
49057
49462
  while (offset < source.length) {
49058
- const keyIndex = source.indexOf("version", offset);
49059
- if (keyIndex === -1) break;
49060
- const before = source[keyIndex - 1];
49061
- const after = source[keyIndex + "version".length];
49062
- const isIdentifierBoundary = (before === void 0 || !/[A-Za-z0-9_$]/.test(before)) && (after === void 0 || !/[A-Za-z0-9_$]/.test(after));
49063
- if (!isIdentifierBoundary) {
49064
- offset = keyIndex + "version".length;
49463
+ const char = source[offset];
49464
+ if (char === "{" || char === "[" || char === "(") {
49465
+ depth += 1;
49466
+ offset += 1;
49065
49467
  continue;
49066
49468
  }
49067
- let cursor = keyIndex + "version".length;
49068
- while (/\s/.test(source[cursor] ?? "")) cursor += 1;
49069
- if (source[cursor] !== ":") {
49070
- offset = cursor;
49469
+ if (char === "}" || char === "]" || char === ")") {
49470
+ depth -= 1;
49471
+ offset += 1;
49472
+ if (depth === 0) break;
49071
49473
  continue;
49072
49474
  }
49073
- cursor += 1;
49074
- while (/\s/.test(source[cursor] ?? "")) cursor += 1;
49075
- const quote = source[cursor];
49076
- if (quote !== "'" && quote !== '"') {
49077
- offset = cursor;
49078
- continue;
49475
+ if (depth === 1 && char === "v" && source.startsWith("version", offset)) {
49476
+ const before = source[offset - 1];
49477
+ const after = source[offset + "version".length];
49478
+ const isIdentifierBoundary = (before === void 0 || !/[A-Za-z0-9_$]/.test(before)) && (after === void 0 || !/[A-Za-z0-9_$]/.test(after));
49479
+ if (isIdentifierBoundary) {
49480
+ let cursor = offset + "version".length;
49481
+ while (/\s/.test(source[cursor] ?? "")) cursor += 1;
49482
+ if (source[cursor] === ":") {
49483
+ cursor += 1;
49484
+ while (/\s/.test(source[cursor] ?? "")) cursor += 1;
49485
+ const quote = source[cursor];
49486
+ if (quote === "'" || quote === '"') {
49487
+ const valueStart = cursor + 1;
49488
+ const valueEnd = source.indexOf(quote, valueStart);
49489
+ if (valueEnd !== -1) {
49490
+ return `${source.slice(0, valueStart)}${newVersion}${source.slice(valueEnd)}`;
49491
+ }
49492
+ }
49493
+ }
49494
+ }
49079
49495
  }
49080
- const valueStart = cursor + 1;
49081
- const valueEnd = source.indexOf(quote, valueStart);
49082
- if (valueEnd === -1) break;
49083
- return `${source.slice(0, valueStart)}${newVersion}${source.slice(valueEnd)}`;
49496
+ offset += 1;
49084
49497
  }
49085
- throw new Error("Unable to find a quoted version property in the deployment entry file");
49498
+ throw new Error(
49499
+ "Unable to find a quoted version property on the default-exported deployment spec (not nested inside a resource config) in the entry file"
49500
+ );
49086
49501
  }
49087
49502
  function listOrganizationModelContractRefs(org) {
49088
49503
  return Object.values(org.organizationModel?.resources ?? {}).flatMap((resource) => {
@@ -49094,7 +49509,7 @@ function listOrganizationModelContractRefs(org) {
49094
49509
  ].filter((entry) => entry[1] !== void 0).map(([side, ref]) => ({ resourceId: resource.id, side, ref }));
49095
49510
  });
49096
49511
  }
49097
- function validateResourceGovernancePreflight(orgName, org, contractRegistry) {
49512
+ function validateResourceGovernancePreflight(orgName, org, contractRegistry, onWarning = (message) => console.warn(message)) {
49098
49513
  if (org.organizationModel !== void 0) {
49099
49514
  OrganizationModelSchema.parse(org.organizationModel);
49100
49515
  }
@@ -49114,24 +49529,43 @@ Run \`pnpm exec elevasis-sdk om:scaffold:fill --gaps <path>\` to scaffold the mi
49114
49529
  );
49115
49530
  }
49116
49531
  validateDeclaredSystemInterfaceReadiness(orgName, org.organizationModel);
49117
- if (process.env.ELEVASIS_RESOURCE_VALIDATOR === "warn-only") return;
49118
- validateResourceGovernance(orgName, org, org.organizationModel, { mode: "strict" });
49532
+ const mode = process.env.ELEVASIS_RESOURCE_VALIDATOR === "warn-only" ? "warn-only" : "strict";
49533
+ validateResourceGovernance(orgName, org, org.organizationModel, {
49534
+ mode,
49535
+ onWarning: (issue2) => onWarning(issue2.message)
49536
+ });
49119
49537
  const contractRefs = listOrganizationModelContractRefs(org);
49120
- if (contractRefs.length === 0 || contractRegistry === void 0) return;
49538
+ if (contractRefs.length === 0) return;
49539
+ if (contractRegistry === void 0) {
49540
+ onWarning(
49541
+ `[${orgName}] ${contractRefs.length} contract ref${contractRefs.length !== 1 ? "s" : ""} declared in organizationModel but no \`contractRegistry\` (or \`ELEVASIS_CONTRACT_REGISTRY\`) was exported from the entry file -- contract-ref resolution skipped.`
49542
+ );
49543
+ return;
49544
+ }
49121
49545
  for (const { resourceId, side, ref } of contractRefs) {
49122
49546
  try {
49123
49547
  resolveContractRef(ref, contractRegistry);
49124
49548
  } catch (error46) {
49125
49549
  const message = error46 instanceof Error ? error46.message : String(error46);
49126
- throw new RegistryValidationError(
49127
- orgName,
49128
- resourceId,
49129
- `organizationModel.resources.${resourceId}.ontology.contract.${side}`,
49130
- message
49131
- );
49550
+ const field2 = `organizationModel.resources.${resourceId}.ontology.contract.${side}`;
49551
+ if (mode === "warn-only") {
49552
+ onWarning(`[${orgName}] ${field2}: ${message}`);
49553
+ continue;
49554
+ }
49555
+ throw new RegistryValidationError(orgName, resourceId, field2, message);
49132
49556
  }
49133
49557
  }
49134
49558
  }
49559
+ function formatZodValidationError(error46) {
49560
+ return error46.issues.map((issue2) => {
49561
+ const path3 = issue2.path.length > 0 ? issue2.path.join(".") : "(root)";
49562
+ return `${path3}: ${issue2.message}`;
49563
+ });
49564
+ }
49565
+ function formatRegistryValidationError(error46) {
49566
+ if (error46.issues && error46.issues.length > 1) return error46.issues;
49567
+ return [error46.message];
49568
+ }
49135
49569
  function registerDeployCommand(program3) {
49136
49570
  program3.command("deploy").description(
49137
49571
  "Validate, bundle, upload, and deploy project resources\n Example: elevasis-sdk deploy --api-url http://localhost:5170"
@@ -49155,7 +49589,7 @@ function registerDeployCommand(program3) {
49155
49589
  authSpinner.fail(source_default.red("Authentication failed"));
49156
49590
  const errMsg = error46 instanceof Error ? error46.message : String(error46);
49157
49591
  if (errMsg.includes("401") || errMsg.toLowerCase().includes("unauthorized")) {
49158
- const keyVar = !options.prod && process.env.NODE_ENV === "development" && process.env.ELEVASIS_PLATFORM_KEY_DEV ? "ELEVASIS_PLATFORM_KEY_DEV" : "ELEVASIS_PLATFORM_KEY";
49592
+ const keyVar = !isProdApiUrl(apiUrl) && process.env.NODE_ENV === "development" && process.env.ELEVASIS_PLATFORM_KEY_DEV ? "ELEVASIS_PLATFORM_KEY_DEV" : "ELEVASIS_PLATFORM_KEY";
49159
49593
  console.error(source_default.red(" Invalid API key."));
49160
49594
  console.error(source_default.gray(` Your ${keyVar} was rejected by the server.`));
49161
49595
  console.error(source_default.gray(" Check your .env file and verify the key in the Elevasis dashboard."));
@@ -49179,7 +49613,13 @@ function registerDeployCommand(program3) {
49179
49613
  throw new Error("Invalid entry: no default export found");
49180
49614
  }
49181
49615
  const contractRegistry = deploymentModule.contractRegistry ?? deploymentModule.ELEVASIS_CONTRACT_REGISTRY;
49182
- validateResourceGovernancePreflight(orgName, org, contractRegistry);
49616
+ const governanceWarnings = [];
49617
+ validateResourceGovernancePreflight(
49618
+ orgName,
49619
+ org,
49620
+ contractRegistry,
49621
+ (message) => governanceWarnings.push(message)
49622
+ );
49183
49623
  new ResourceRegistry({ [orgName]: org });
49184
49624
  activeWorkflows = (org.workflows ?? []).filter((w) => !w.config.archived);
49185
49625
  activeAgents = (org.agents ?? []).filter((a) => !a.config.archived);
@@ -49188,6 +49628,12 @@ function registerDeployCommand(program3) {
49188
49628
  validateSpinner.succeed(
49189
49629
  source_default.green("Validating...") + source_default.white(" done") + source_default.gray(` (${totalCount} resource${totalCount !== 1 ? "s" : ""}, 0 errors)`)
49190
49630
  );
49631
+ if (governanceWarnings.length > 0) {
49632
+ for (const warning of governanceWarnings) {
49633
+ console.log(source_default.yellow(` warn ${warning}`));
49634
+ }
49635
+ console.log("");
49636
+ }
49191
49637
  if (archivedCount > 0) {
49192
49638
  console.log(source_default.gray(` Skipping ${archivedCount} archived resource${archivedCount !== 1 ? "s" : ""}`));
49193
49639
  }
@@ -49221,12 +49667,30 @@ function registerDeployCommand(program3) {
49221
49667
  if (error46 instanceof RegistryValidationError) {
49222
49668
  validateSpinner.fail(source_default.red("Validation failed"));
49223
49669
  console.error("");
49224
- console.error(source_default.red(` ERROR ${error46.message}`));
49670
+ const issues = formatRegistryValidationError(error46);
49671
+ if (issues.length > 1) {
49672
+ console.error(source_default.red(` ${issues.length} issues:`));
49673
+ for (const issue2 of issues) {
49674
+ console.error(source_default.red(` - ${issue2}`));
49675
+ }
49676
+ } else {
49677
+ console.error(source_default.red(` ERROR ${issues[0]}`));
49678
+ }
49225
49679
  if (error46.resourceId) {
49226
49680
  console.error(source_default.gray(` Resource: ${error46.resourceId}`));
49227
49681
  }
49228
49682
  console.error("");
49229
49683
  console.error(source_default.gray(" Deploy aborted."));
49684
+ } else if (error46 instanceof external_exports.ZodError) {
49685
+ validateSpinner.fail(source_default.red("Validation failed: organization model does not match the expected shape"));
49686
+ console.error("");
49687
+ for (const line of formatZodValidationError(error46)) {
49688
+ console.error(source_default.red(` ERROR ${line}`));
49689
+ }
49690
+ console.error("");
49691
+ console.error(source_default.gray(" Deploy aborted."));
49692
+ } else if (validateSpinner.isSpinning) {
49693
+ validateSpinner.fail(source_default.red("Validation failed"));
49230
49694
  }
49231
49695
  throw error46;
49232
49696
  }
@@ -49291,11 +49755,11 @@ import { startWorker } from '@elevasis/sdk/worker'
49291
49755
  const uploadSpinner = ora("Uploading...").start();
49292
49756
  try {
49293
49757
  const bundleBuffer = await (0, import_promises.readFile)(bundleOutfile);
49294
- const apiKey = resolveApiKey(options.prod);
49758
+ const apiKey = resolveApiKeyForUrl(apiUrl);
49295
49759
  if (!apiKey) {
49296
49760
  uploadSpinner.fail(source_default.red("Missing API key environment variable"));
49297
49761
  console.error(source_default.gray(" Set it in your .env file or shell environment:"));
49298
- if (!options.prod && process.env.NODE_ENV === "development") {
49762
+ if (!isProdApiUrl(apiUrl) && process.env.NODE_ENV === "development") {
49299
49763
  console.error(
49300
49764
  source_default.gray(" ELEVASIS_PLATFORM_KEY_DEV=sk_... (or ELEVASIS_PLATFORM_KEY as fallback)")
49301
49765
  );
@@ -49363,7 +49827,7 @@ import { startWorker } from '@elevasis/sdk/worker'
49363
49827
  )
49364
49828
  );
49365
49829
  }
49366
- var import_path2, import_promises, import_fs2, import_crypto, import_url, import_module;
49830
+ var import_path2, import_promises, import_fs2, import_crypto, import_url, import_module, PLAIN_SEMVER_RE;
49367
49831
  var init_deploy = __esm({
49368
49832
  "src/cli/commands/deploy.ts"() {
49369
49833
  "use strict";
@@ -49384,6 +49848,7 @@ var init_deploy = __esm({
49384
49848
  init_api_client();
49385
49849
  init_wrap_action();
49386
49850
  init_version();
49851
+ PLAIN_SEMVER_RE = /^(\d+)\.(\d+)\.(\d+)$/;
49387
49852
  }
49388
49853
  });
49389
49854
 
@@ -49441,18 +49906,18 @@ function getOrganizationModelDir(projectDir) {
49441
49906
  }
49442
49907
  function assertSplitLayout(projectDir) {
49443
49908
  const omDir = getOrganizationModelDir(projectDir);
49444
- const missing = REQUIRED_FILES.filter((f) => !(0, import_node_fs13.existsSync)((0, import_node_path11.join)(omDir, f)));
49909
+ const missing = REQUIRED_FILES.filter((f) => !(0, import_node_fs14.existsSync)((0, import_node_path11.join)(omDir, f)));
49445
49910
  if (missing.length > 0) {
49446
49911
  throw new Error(
49447
49912
  "Legacy single-file OM layout detected. Split into `core/config/organization-model/{profile.ts, systems.ts, navigation.ts}` before scaffolding."
49448
49913
  );
49449
49914
  }
49450
49915
  }
49451
- var import_node_fs13, import_node_path11, REQUIRED_FILES;
49916
+ var import_node_fs14, import_node_path11, REQUIRED_FILES;
49452
49917
  var init_project_layout = __esm({
49453
49918
  "src/cli/commands/om/project-layout.ts"() {
49454
49919
  "use strict";
49455
- import_node_fs13 = require("node:fs");
49920
+ import_node_fs14 = require("node:fs");
49456
49921
  import_node_path11 = require("node:path");
49457
49922
  REQUIRED_FILES = ["profile.ts", "systems.ts", "navigation.ts"];
49458
49923
  }
@@ -49552,8 +50017,9 @@ function emitSystemEntry(opts) {
49552
50017
  lifecycle: 'active',${apiInterfaceBlock}
49553
50018
  },
49554
50019
  `;
50020
+ const startAnchor = /^(?!\s*(?:\/\/|\*|\/\*)).*\bexport const templateSystems\s*=/m;
49555
50021
  const anchor = /^\] as const\s*$/m;
49556
- return { code, anchor, apiInterfaceNote };
50022
+ return { code, startAnchor, anchor, apiInterfaceNote };
49557
50023
  }
49558
50024
  var init_emit_system = __esm({
49559
50025
  "src/cli/commands/om/emit-system.ts"() {
@@ -49567,7 +50033,7 @@ async function withSnapshotRollback(filePaths, op) {
49567
50033
  const snapshots = /* @__PURE__ */ new Map();
49568
50034
  for (const filePath of filePaths) {
49569
50035
  try {
49570
- snapshots.set(filePath, (0, import_node_fs14.readFileSync)(filePath, "utf8"));
50036
+ snapshots.set(filePath, (0, import_node_fs15.readFileSync)(filePath, "utf8"));
49571
50037
  } catch {
49572
50038
  snapshots.set(filePath, null);
49573
50039
  }
@@ -49578,7 +50044,7 @@ async function withSnapshotRollback(filePaths, op) {
49578
50044
  for (const [filePath, snapshot] of snapshots) {
49579
50045
  if (snapshot !== null) {
49580
50046
  try {
49581
- (0, import_node_fs14.writeFileSync)(filePath, snapshot, "utf8");
50047
+ (0, import_node_fs15.writeFileSync)(filePath, snapshot, "utf8");
49582
50048
  } catch {
49583
50049
  }
49584
50050
  }
@@ -49615,9 +50081,9 @@ function reindent(code, baseIndent, extraIndent) {
49615
50081
  return lines.map((line) => line.trim() === "" ? line : baseIndent + extraIndent + line.slice(firstIndent.length)).join("\n");
49616
50082
  }
49617
50083
  async function appendBeforeAnchor(filePath, code, anchor, startAnchor) {
49618
- const content = (0, import_node_fs14.readFileSync)(filePath, "utf8");
50084
+ const content = (0, import_node_fs15.readFileSync)(filePath, "utf8");
49619
50085
  if (startAnchor === void 0) {
49620
- (0, import_node_fs14.writeFileSync)(filePath, insertBeforeAnchorInContent(content, code, anchor), "utf8");
50086
+ (0, import_node_fs15.writeFileSync)(filePath, insertBeforeAnchorInContent(content, code, anchor), "utf8");
49621
50087
  return;
49622
50088
  }
49623
50089
  const lines = content.split("\n");
@@ -49647,12 +50113,12 @@ async function appendBeforeAnchor(filePath, code, anchor, startAnchor) {
49647
50113
  lines[previousIndex] = previous.trimEnd() + ",";
49648
50114
  }
49649
50115
  lines.splice(anchorIndex, 0, ...indented.split("\n"));
49650
- (0, import_node_fs14.writeFileSync)(filePath, lines.join("\n"), "utf8");
50116
+ (0, import_node_fs15.writeFileSync)(filePath, lines.join("\n"), "utf8");
49651
50117
  }
49652
50118
  async function applyConstImport(systemsFilePath, importLine, fieldLine, importAnchor, fieldAnchor, newConstFilePath, newConstFileCode) {
49653
- (0, import_node_fs14.mkdirSync)((0, import_node_path12.dirname)(newConstFilePath), { recursive: true });
49654
- (0, import_node_fs14.writeFileSync)(newConstFilePath, newConstFileCode, "utf8");
49655
- const systemsContent = (0, import_node_fs14.readFileSync)(systemsFilePath, "utf8");
50119
+ (0, import_node_fs15.mkdirSync)((0, import_node_path12.dirname)(newConstFilePath), { recursive: true });
50120
+ (0, import_node_fs15.writeFileSync)(newConstFilePath, newConstFileCode, "utf8");
50121
+ const systemsContent = (0, import_node_fs15.readFileSync)(systemsFilePath, "utf8");
49656
50122
  const afterImport = insertBeforeAnchorInContent(systemsContent, importLine + "\n", importAnchor);
49657
50123
  const lines = afterImport.split("\n");
49658
50124
  const fieldAnchorIndex = findAnchorLineIndex(lines, afterImport, fieldAnchor);
@@ -49662,13 +50128,13 @@ async function applyConstImport(systemsFilePath, importLine, fieldLine, importAn
49662
50128
  );
49663
50129
  }
49664
50130
  lines.splice(fieldAnchorIndex + 1, 0, fieldLine);
49665
- (0, import_node_fs14.writeFileSync)(systemsFilePath, lines.join("\n"), "utf8");
50131
+ (0, import_node_fs15.writeFileSync)(systemsFilePath, lines.join("\n"), "utf8");
49666
50132
  }
49667
- var import_node_fs14, import_node_path12;
50133
+ var import_node_fs15, import_node_path12;
49668
50134
  var init_splice = __esm({
49669
50135
  "src/cli/commands/om/splice.ts"() {
49670
50136
  "use strict";
49671
- import_node_fs14 = require("node:fs");
50137
+ import_node_fs15 = require("node:fs");
49672
50138
  import_node_path12 = require("node:path");
49673
50139
  }
49674
50140
  });
@@ -49720,7 +50186,7 @@ async function scaffoldSystem(opts) {
49720
50186
  });
49721
50187
  apiBacked = answer.trim().toLowerCase() === "y";
49722
50188
  }
49723
- const { code, anchor, apiInterfaceNote } = emitSystemEntry({ id, title, kind, apiBacked });
50189
+ const { code, anchor, startAnchor, apiInterfaceNote } = emitSystemEntry({ id, title, kind, apiBacked });
49724
50190
  const shouldWrite = options.write === true || options.dryRun === false;
49725
50191
  if (!shouldWrite) {
49726
50192
  console.log(source_default.cyan("Dry-run mode (default) \u2014 no files written. Pass --write to apply.\n"));
@@ -49734,7 +50200,7 @@ async function scaffoldSystem(opts) {
49734
50200
  const systemsFilePath = (0, import_node_path13.join)(getOrganizationModelDir(projectDir), "systems.ts");
49735
50201
  try {
49736
50202
  await withSnapshotRollback([systemsFilePath], async () => {
49737
- await appendBeforeAnchor(systemsFilePath, code, anchor);
50203
+ await appendBeforeAnchor(systemsFilePath, code, anchor, startAnchor);
49738
50204
  const validationError = runValidation(projectDir);
49739
50205
  if (validationError !== null) {
49740
50206
  throw new Error(validationError);
@@ -49786,8 +50252,9 @@ function emitResourceEntry(opts) {
49786
50252
  ${ontologyBlock} codeRefs: []
49787
50253
  },
49788
50254
  `;
49789
- const anchor = /^export const templateResources\s*=/m;
49790
- return { code, anchor };
50255
+ const startAnchor = /^(?!\s*(?:\/\/|\*|\/\*)).*\btemplateResourceDescriptors\s*=/m;
50256
+ const anchor = /^\}/m;
50257
+ return { code, startAnchor, anchor };
49791
50258
  }
49792
50259
  var init_emit_resource = __esm({
49793
50260
  "src/cli/commands/om/emit-resource.ts"() {
@@ -49841,7 +50308,7 @@ async function scaffoldResource(opts) {
49841
50308
  { default: "" }
49842
50309
  );
49843
50310
  const primaryAction = rawPrimaryAction || void 0;
49844
- const { code, anchor } = emitResourceEntry({ id, systemPath, title, primaryAction });
50311
+ const { code, anchor, startAnchor } = emitResourceEntry({ id, systemPath, title, primaryAction });
49845
50312
  const shouldWrite = options.write === true || options.dryRun === false;
49846
50313
  if (!shouldWrite) {
49847
50314
  console.log(source_default.cyan("Dry-run mode (default) \u2014 no files written. Pass --write to apply.\n"));
@@ -49852,7 +50319,7 @@ async function scaffoldResource(opts) {
49852
50319
  const systemsFilePath = (0, import_node_path14.join)(getOrganizationModelDir(projectDir), "systems.ts");
49853
50320
  try {
49854
50321
  await withSnapshotRollback([systemsFilePath], async () => {
49855
- await appendBeforeAnchor(systemsFilePath, code, anchor);
50322
+ await appendBeforeAnchor(systemsFilePath, code, anchor, startAnchor);
49856
50323
  const validationError = runValidation2(projectDir);
49857
50324
  if (validationError !== null) {
49858
50325
  const systemPathHint = /systemPath.*not assignable/i.test(validationError) ? `
@@ -50123,7 +50590,7 @@ async function scaffoldKnowledge(opts) {
50123
50590
  }
50124
50591
  const rawKind = await promptIfAbsent(
50125
50592
  options.kind,
50126
- "Node kind (playbook / strategy / reference / policy)",
50593
+ "Node kind (playbook / strategy / reference)",
50127
50594
  { default: "reference" }
50128
50595
  );
50129
50596
  const kind = rawKind || "reference";
@@ -50148,30 +50615,30 @@ async function scaffoldKnowledge(opts) {
50148
50615
  return;
50149
50616
  }
50150
50617
  const absoluteFilePath = (0, import_node_path16.join)(projectDir, relativeFilePath);
50151
- if ((0, import_node_fs15.existsSync)(absoluteFilePath)) {
50618
+ if ((0, import_node_fs16.existsSync)(absoluteFilePath)) {
50152
50619
  process.stderr.write(
50153
50620
  source_default.red(`Knowledge node file already exists at \`${relativeFilePath}\`. Choose a different id.
50154
50621
  `)
50155
50622
  );
50156
50623
  process.exit(1);
50157
50624
  }
50158
- (0, import_node_fs15.mkdirSync)((0, import_node_path16.join)(projectDir, "core", "config", "knowledge", "nodes"), { recursive: true });
50159
- (0, import_node_fs15.writeFileSync)(absoluteFilePath, content, "utf8");
50625
+ (0, import_node_fs16.mkdirSync)((0, import_node_path16.join)(projectDir, "core", "config", "knowledge", "nodes"), { recursive: true });
50626
+ (0, import_node_fs16.writeFileSync)(absoluteFilePath, content, "utf8");
50160
50627
  console.log(source_default.green(`Knowledge node \`${id}\` written to \`${relativeFilePath}\``));
50161
50628
  console.log(source_default.yellow("Run `elevasis-sdk knowledge:generate` to register this node."));
50162
50629
  }
50163
- var import_node_path16, import_node_fs15, VALID_KINDS;
50630
+ var import_node_path16, import_node_fs16, VALID_KINDS;
50164
50631
  var init_scaffold_knowledge = __esm({
50165
50632
  "src/cli/commands/om/scaffold-knowledge.ts"() {
50166
50633
  "use strict";
50167
50634
  import_node_path16 = require("node:path");
50168
- import_node_fs15 = require("node:fs");
50635
+ import_node_fs16 = require("node:fs");
50169
50636
  init_source();
50170
50637
  init_config2();
50171
50638
  init_project_layout();
50172
50639
  init_prompt_helpers();
50173
50640
  init_emit_knowledge();
50174
- VALID_KINDS = ["playbook", "strategy", "reference", "policy"];
50641
+ VALID_KINDS = ["playbook", "strategy", "reference"];
50175
50642
  }
50176
50643
  });
50177
50644
 
@@ -50184,7 +50651,13 @@ function emitApiInterfaceBlock(gap) {
50184
50651
  const cataloged = SYSTEM_INTERFACE_PROFILES.find(
50185
50652
  (profile) => profile.systemPath === gap.systemPath && profile.interfaceKey === "api"
50186
50653
  );
50187
- const readinessProfile = cataloged?.readinessProfile ?? `${gap.systemPath}.api`;
50654
+ if (cataloged === void 0) {
50655
+ const adoptable = SYSTEM_INTERFACE_PROFILES.filter((profile) => profile.interfaceKey === "api").map((profile) => `"${profile.systemPath}"`).join(", ");
50656
+ throw new Error(
50657
+ `Cannot emit an apiInterface for system path "${gap.systemPath}": it adopts no cataloged platform API capability, so any readinessProfile emitted for it would name a route the API does not serve. Adoptable system paths are ${adoptable}. A custom System extends behavior through workflows/operations plus ontology, resources, and topology \u2014 omitting apiInterface entirely is the designed opt-out.`
50658
+ );
50659
+ }
50660
+ const readinessProfile = cataloged.readinessProfile;
50188
50661
  const resourceIdsField = gap.resourceIds.length === 0 ? "" : `,
50189
50662
  resourceIds: [
50190
50663
  ${gap.resourceIds.map((id) => `'${id}'`).join(",\n ")}
@@ -50247,7 +50720,7 @@ async function scaffoldFill(opts) {
50247
50720
  process.stderr.write(source_default.red("Missing gaps file. Pass --gaps <path> pointing to a conformance gap JSON file.\n"));
50248
50721
  process.exit(1);
50249
50722
  }
50250
- if (!(0, import_node_fs16.existsSync)(options.gaps)) {
50723
+ if (!(0, import_node_fs17.existsSync)(options.gaps)) {
50251
50724
  process.stderr.write(
50252
50725
  source_default.red(
50253
50726
  `Missing gaps file. Pass --gaps <path> pointing to a conformance gap JSON file.
@@ -50259,7 +50732,7 @@ async function scaffoldFill(opts) {
50259
50732
  }
50260
50733
  let payload;
50261
50734
  try {
50262
- const raw = (0, import_node_fs16.readFileSync)(options.gaps, "utf8");
50735
+ const raw = (0, import_node_fs17.readFileSync)(options.gaps, "utf8");
50263
50736
  payload = JSON.parse(raw);
50264
50737
  } catch {
50265
50738
  process.stderr.write(
@@ -50367,7 +50840,7 @@ async function scaffoldFill(opts) {
50367
50840
  }
50368
50841
  if (skippedGaps.length > 0) {
50369
50842
  const skippedPath = options.skipped ?? (0, import_node_path17.join)(os2.tmpdir(), `elevasis-fill-skipped-${systemPath}-${Date.now()}.json`);
50370
- (0, import_node_fs16.writeFileSync)(skippedPath, JSON.stringify({ systemPath, skipped: skippedGaps }, null, 2), "utf8");
50843
+ (0, import_node_fs17.writeFileSync)(skippedPath, JSON.stringify({ systemPath, skipped: skippedGaps }, null, 2), "utf8");
50371
50844
  console.log(
50372
50845
  source_default.yellow(
50373
50846
  `Partial fill: ${appliedGaps.length} gap(s) applied, ${skippedGaps.length} skipped \u2014 see \`${skippedPath}\` for fields requiring manual input.`
@@ -50381,13 +50854,13 @@ async function scaffoldFill(opts) {
50381
50854
  )
50382
50855
  );
50383
50856
  }
50384
- var import_node_path17, os2, import_node_fs16, import_node_child_process5;
50857
+ var import_node_path17, os2, import_node_fs17, import_node_child_process5;
50385
50858
  var init_scaffold_fill = __esm({
50386
50859
  "src/cli/commands/om/scaffold-fill.ts"() {
50387
50860
  "use strict";
50388
50861
  import_node_path17 = require("node:path");
50389
50862
  os2 = __toESM(require("node:os"), 1);
50390
- import_node_fs16 = require("node:fs");
50863
+ import_node_fs17 = require("node:fs");
50391
50864
  import_node_child_process5 = require("node:child_process");
50392
50865
  init_source();
50393
50866
  init_config2();
@@ -55279,7 +55752,129 @@ function registerUiCommands(program3) {
55279
55752
  var import_node_fs9 = require("node:fs");
55280
55753
  var import_node_path8 = __toESM(require("node:path"), 1);
55281
55754
  init_source();
55755
+ init_organization_model();
55282
55756
  init_config2();
55757
+ init_load_org_model();
55758
+
55759
+ // src/cli/commands/om/deployed-readiness.ts
55760
+ init_organization_model();
55761
+ init_api_client();
55762
+ function listApiInterfaceSystemPaths(model) {
55763
+ return listAllSystems(model).filter(({ system }) => system.apiInterface !== void 0).map(({ path: path3 }) => path3);
55764
+ }
55765
+ function listDeployedReadinessTargets(model) {
55766
+ const declared = new Set(listApiInterfaceSystemPaths(model));
55767
+ const targets = SYSTEM_INTERFACE_PROFILES.map((profile) => ({
55768
+ systemPath: profile.systemPath,
55769
+ interfaceKey: profile.interfaceKey,
55770
+ declaredLocally: declared.has(profile.systemPath)
55771
+ }));
55772
+ const covered = new Set(targets.map((target) => `${target.systemPath}::${target.interfaceKey}`));
55773
+ for (const systemPath of declared) {
55774
+ const key = `${systemPath}::api`;
55775
+ if (covered.has(key)) continue;
55776
+ covered.add(key);
55777
+ targets.push({ systemPath, interfaceKey: "api", declaredLocally: true });
55778
+ }
55779
+ return targets;
55780
+ }
55781
+ async function fetchDeployedReadiness(model, options = {}) {
55782
+ const targets = listDeployedReadinessTargets(model);
55783
+ const report = {
55784
+ activeDeploymentId: null,
55785
+ snapshotHash: null,
55786
+ kind: null,
55787
+ entries: []
55788
+ };
55789
+ if (targets.length === 0) {
55790
+ report.unavailableReason = "no System-interface profile to check \u2014 neither the platform catalog nor the project model declares one";
55791
+ return report;
55792
+ }
55793
+ for (const target of targets) {
55794
+ let response;
55795
+ try {
55796
+ const endpoint = `/api/external/organization-model/readiness?systemPath=${encodeURIComponent(target.systemPath)}&interfaceKey=${encodeURIComponent(target.interfaceKey)}`;
55797
+ response = await apiGet(endpoint, options.apiUrl);
55798
+ } catch (error46) {
55799
+ report.unavailableReason = error46 instanceof Error ? error46.message : String(error46);
55800
+ return report;
55801
+ }
55802
+ report.activeDeploymentId = response.activeDeploymentId;
55803
+ report.snapshotHash = response.snapshotHash;
55804
+ report.kind = response.kind;
55805
+ report.entries.push({
55806
+ systemPath: response.readiness.systemPath,
55807
+ interfaceKey: response.readiness.interfaceKey,
55808
+ ready: response.readiness.ready,
55809
+ issues: response.readiness.issues,
55810
+ declaredLocally: target.declaredLocally
55811
+ });
55812
+ }
55813
+ return report;
55814
+ }
55815
+ function isUnadoptedNotDeclared(entry) {
55816
+ return !entry.declaredLocally && entry.issues.every((issue2) => issue2.family === "SYSTEM_INTERFACE_MISSING");
55817
+ }
55818
+ function readinessDiagnostics(report) {
55819
+ const diagnostics = [];
55820
+ for (const entry of report.entries) {
55821
+ if (entry.ready) {
55822
+ diagnostics.push({
55823
+ severity: "info",
55824
+ code: "deployed-interface-ready",
55825
+ systemPath: entry.systemPath,
55826
+ message: `${entry.systemPath}/${entry.interfaceKey} is ready in the deployed snapshot.`
55827
+ });
55828
+ continue;
55829
+ }
55830
+ const unadopted = isUnadoptedNotDeclared(entry);
55831
+ for (const issue2 of entry.issues) {
55832
+ diagnostics.push({
55833
+ severity: unadopted ? "info" : "error",
55834
+ code: `deployed-${issue2.code}`,
55835
+ systemPath: entry.systemPath,
55836
+ ...issue2.ref !== void 0 && { targetId: issue2.ref },
55837
+ message: `${entry.systemPath}/${entry.interfaceKey} ${unadopted ? "not adopted" : "not ready"} [${issue2.family}]: ${issue2.message}`,
55838
+ source: "deployed-snapshot"
55839
+ });
55840
+ }
55841
+ }
55842
+ return diagnostics;
55843
+ }
55844
+ function readinessRoster(report) {
55845
+ return report.entries.map((entry) => {
55846
+ if (entry.ready) {
55847
+ return {
55848
+ systemPath: entry.systemPath,
55849
+ interfaceKey: entry.interfaceKey,
55850
+ status: "ready",
55851
+ detail: "ready",
55852
+ issues: []
55853
+ };
55854
+ }
55855
+ if (isUnadoptedNotDeclared(entry)) {
55856
+ return {
55857
+ systemPath: entry.systemPath,
55858
+ interfaceKey: entry.interfaceKey,
55859
+ status: "not-adopted",
55860
+ detail: "not adopted",
55861
+ issues: entry.issues
55862
+ };
55863
+ }
55864
+ return {
55865
+ systemPath: entry.systemPath,
55866
+ interfaceKey: entry.interfaceKey,
55867
+ status: "not-ready",
55868
+ detail: entry.issues[0]?.message ?? "not ready",
55869
+ issues: entry.issues
55870
+ };
55871
+ });
55872
+ }
55873
+ function countReadinessRosterFailures(rows) {
55874
+ return rows.filter((row) => row.status === "not-ready").length;
55875
+ }
55876
+
55877
+ // src/cli/commands/doctor.ts
55283
55878
  function ok(label, detail) {
55284
55879
  console.log(`${source_default.green("[OK]")} ${source_default.bold(label)}: ${detail}`);
55285
55880
  }
@@ -55387,6 +55982,38 @@ function registerDoctorCommand(program3) {
55387
55982
  if (isVerbose) verbose(`Error: ${networkError}`);
55388
55983
  failCount++;
55389
55984
  }
55985
+ let model = DEFAULT_ORGANIZATION_MODEL;
55986
+ try {
55987
+ model = await loadOrgModel(projectRoot);
55988
+ } catch (err) {
55989
+ if (isVerbose) {
55990
+ const msg = err instanceof Error ? err.message : String(err);
55991
+ verbose(`Organization model load failed, roster limited to the platform catalog: ${msg}`);
55992
+ }
55993
+ }
55994
+ const readiness = await fetchDeployedReadiness(model, { apiUrl });
55995
+ if (readiness.unavailableReason !== void 0) {
55996
+ warn("Systems", `Readiness unavailable \u2014 ${readiness.unavailableReason}`);
55997
+ if (isVerbose) verbose(`GET ${apiUrl}/api/external/organization-model/readiness`);
55998
+ } else {
55999
+ const rows = readinessRoster(readiness);
56000
+ for (const row of rows) {
56001
+ const label = `Systems: ${row.systemPath}/${row.interfaceKey}`;
56002
+ if (row.status === "ready") {
56003
+ ok(label, row.detail);
56004
+ } else if (row.status === "not-adopted") {
56005
+ warn(label, row.detail);
56006
+ } else {
56007
+ fail(label, row.detail);
56008
+ }
56009
+ if (isVerbose) {
56010
+ for (const issue2 of row.issues) {
56011
+ verbose(`${issue2.code}: ${issue2.message}`);
56012
+ }
56013
+ }
56014
+ }
56015
+ failCount += countReadinessRosterFailures(rows);
56016
+ }
55390
56017
  console.log();
55391
56018
  printSummary(failCount);
55392
56019
  if (failCount > 0) {
@@ -55883,6 +56510,12 @@ Content item: ${item.title}`));
55883
56510
  // src/cli/commands/content/board.ts
55884
56511
  init_source();
55885
56512
 
56513
+ // ../core/src/content/review-gates.ts
56514
+ function isAwaitingReview(item, step) {
56515
+ if (!step) return false;
56516
+ return step.reviewMode !== "none" && item.reviewedAt === null;
56517
+ }
56518
+
55886
56519
  // ../core/src/content/derive-board.ts
55887
56520
  function sortPipelineSteps(steps) {
55888
56521
  return [...steps].sort((a, b) => {
@@ -55890,7 +56523,8 @@ function sortPipelineSteps(steps) {
55890
56523
  return a.key < b.key ? -1 : a.key > b.key ? 1 : 0;
55891
56524
  });
55892
56525
  }
55893
- function deriveItemPlacement(processingState, sortedSteps) {
56526
+ function deriveItemPlacement(item, sortedSteps) {
56527
+ const processingState = item.processingState;
55894
56528
  const stateKeys = Object.keys(processingState);
55895
56529
  if (stateKeys.length > 0) {
55896
56530
  const catalogKeys = new Set(sortedSteps.map((step) => step.key));
@@ -55904,14 +56538,14 @@ function deriveItemPlacement(processingState, sortedSteps) {
55904
56538
  return !entry || entry.status !== "success";
55905
56539
  });
55906
56540
  if (!currentStep) {
56541
+ const lastStep = sortedSteps[sortedSteps.length - 1];
56542
+ if (lastStep !== void 0 && isAwaitingReview(item, lastStep)) {
56543
+ return { bucket: "column", stepKey: lastStep.key };
56544
+ }
55907
56545
  return { bucket: "done", stepKey: null };
55908
56546
  }
55909
56547
  return { bucket: "column", stepKey: currentStep.key };
55910
56548
  }
55911
- function deriveAwaitingReview(step, item) {
55912
- if (!step) return false;
55913
- return step.reviewMode !== "none" && item.reviewedAt === null;
55914
- }
55915
56549
  function deriveContentBoard(items, pipeline, now) {
55916
56550
  const sortedSteps = sortPipelineSteps(pipeline.steps);
55917
56551
  const stepsByKey = new Map(sortedSteps.map((step) => [step.key, step]));
@@ -55919,13 +56553,13 @@ function deriveContentBoard(items, pipeline, now) {
55919
56553
  const done = [];
55920
56554
  const unplaced = [];
55921
56555
  for (const item of items) {
55922
- const placement = deriveItemPlacement(item.processingState, sortedSteps);
56556
+ const placement = deriveItemPlacement(item, sortedSteps);
55923
56557
  const step = placement.stepKey ? stepsByKey.get(placement.stepKey) : void 0;
55924
56558
  const card = {
55925
56559
  item,
55926
56560
  stepKey: placement.stepKey,
55927
56561
  ageMs: now - Date.parse(item.updatedAt),
55928
- awaitingReview: deriveAwaitingReview(step, item)
56562
+ awaitingReview: isAwaitingReview(item, step)
55929
56563
  };
55930
56564
  if (placement.bucket === "done") {
55931
56565
  done.push(card);
@@ -55949,9 +56583,9 @@ function deriveContentBoard(items, pipeline, now) {
55949
56583
  const columns = sortedSteps.map((step) => {
55950
56584
  const cards = cardsByStepKey.get(step.key) ?? [];
55951
56585
  const column = { step, cards };
55952
- if (step.reviewMode === "live" || step.reviewMode === "queued") {
56586
+ if (step.reviewVenue !== "none") {
55953
56587
  column.gate = {
55954
- reviewMode: step.reviewMode,
56588
+ venue: step.reviewVenue,
55955
56589
  waitingCount: cards.filter((card) => card.awaitingReview).length
55956
56590
  };
55957
56591
  }
@@ -56068,7 +56702,9 @@ Board: ${pipelineId} ${source_default.gray(`${items.data.length} of ${items.tot
56068
56702
  }
56069
56703
  console.log();
56070
56704
  for (const column of board.columns) {
56071
- const gate = column.gate ? source_default.yellow(` [${column.gate.reviewMode} gate -- ${column.gate.waitingCount} waiting]`) : "";
56705
+ const gate = column.gate ? source_default.yellow(
56706
+ ` [${column.gate.venue === "workspace" ? "workspace" : "queue"} gate -- ${column.gate.waitingCount} waiting]`
56707
+ ) : "";
56072
56708
  console.log(` ${source_default.bold(column.step.label)} ${source_default.gray(column.step.key)}${gate}`);
56073
56709
  printCards(column.cards, stepsByKey);
56074
56710
  }
@@ -56130,7 +56766,7 @@ Pipeline: ${pipeline.id}`));
56130
56766
  const steps = Array.isArray(pipeline.steps) ? pipeline.steps : [];
56131
56767
  console.log(source_default.gray(` Steps (${steps.length}):`));
56132
56768
  for (const step of steps) {
56133
- console.log(source_default.gray(` - ${step.key} (reviewMode: ${step.reviewMode})`));
56769
+ console.log(source_default.gray(` - ${step.key} (review: ${step.reviewMode}, venue: ${step.reviewVenue})`));
56134
56770
  }
56135
56771
  console.log();
56136
56772
  }
@@ -56267,6 +56903,203 @@ Content item ${itemId} ${verb} at step ${options.step}`));
56267
56903
  );
56268
56904
  }
56269
56905
 
56906
+ // src/cli/commands/content/source-assets.ts
56907
+ init_source();
56908
+ init_api_client();
56909
+ init_config2();
56910
+ init_wrap_action();
56911
+ function appendQuery6(params, key, value) {
56912
+ if (value === void 0 || value === null || value === "") return;
56913
+ params.set(key, String(value));
56914
+ }
56915
+ function registerContentSourceAssets(program3) {
56916
+ program3.command("content:source-assets").description(
56917
+ "List content source assets (raw material)\n Example: elevasis-sdk content:source-assets --kind transcript --limit 10"
56918
+ ).option("--kind <kind>", "Filter by source asset kind (e.g. transcript)").option("--limit <n>", "Maximum number of results").option("--offset <n>", "Pagination offset").option("--prod", "Target production (overrides NODE_ENV=development)").option("--api-url <url>", "API base URL").option("--pretty", "Render human-readable output instead of raw JSON").action(
56919
+ wrapAction("content:source-assets", async (options) => {
56920
+ const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
56921
+ const params = new URLSearchParams();
56922
+ appendQuery6(params, "kind", options.kind);
56923
+ appendQuery6(params, "limit", options.limit);
56924
+ appendQuery6(params, "offset", options.offset);
56925
+ const query = params.toString();
56926
+ const endpoint = query ? `/api/external/content/source-assets?${query}` : "/api/external/content/source-assets";
56927
+ const result = await apiGet(endpoint, apiUrl);
56928
+ if (!options.pretty) {
56929
+ console.log(JSON.stringify(result, null, 2));
56930
+ return;
56931
+ }
56932
+ if (result.data.length === 0) {
56933
+ console.log(source_default.yellow("No content source assets found."));
56934
+ return;
56935
+ }
56936
+ console.log(source_default.cyan(`
56937
+ Content source assets (${result.data.length} of ${result.total}):
56938
+ `));
56939
+ for (const asset of result.data) {
56940
+ console.log(` ${source_default.bold(asset.title)} ${source_default.gray(asset.kind)}`);
56941
+ console.log(source_default.gray(` ID: ${asset.id}`));
56942
+ if (asset.externalUrl) console.log(source_default.gray(` URL: ${asset.externalUrl}`));
56943
+ if (asset.durationSeconds) console.log(source_default.gray(` Duration: ${asset.durationSeconds}s`));
56944
+ }
56945
+ console.log();
56946
+ })
56947
+ );
56948
+ }
56949
+
56950
+ // src/cli/commands/content/source-asset.ts
56951
+ init_source();
56952
+ init_api_client();
56953
+ init_config2();
56954
+ init_wrap_action();
56955
+ function registerContentSourceAsset(program3) {
56956
+ program3.command("content:source-asset <sourceAssetId>").description(
56957
+ "Get one content source asset, including its payload\n Example: elevasis-sdk content:source-asset <uuid>"
56958
+ ).option("--prod", "Target production (overrides NODE_ENV=development)").option("--api-url <url>", "API base URL").option("--pretty", "Render human-readable output instead of raw JSON").action(
56959
+ wrapAction("content:source-asset", async (sourceAssetId, options) => {
56960
+ const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
56961
+ const asset = await apiGet(`/api/external/content/source-assets/${sourceAssetId}`, apiUrl);
56962
+ if (!options.pretty) {
56963
+ console.log(JSON.stringify(asset, null, 2));
56964
+ return;
56965
+ }
56966
+ console.log(source_default.cyan(`
56967
+ ${asset.title}`));
56968
+ console.log(source_default.gray(` ID: ${asset.id}`));
56969
+ console.log(source_default.gray(` Kind: ${asset.kind}`));
56970
+ if (asset.externalUrl) console.log(source_default.gray(` URL: ${asset.externalUrl}`));
56971
+ if (asset.durationSeconds) console.log(source_default.gray(` Duration: ${asset.durationSeconds}s`));
56972
+ const payloadKeys = Object.keys(asset.payload ?? {});
56973
+ if (payloadKeys.length > 0) {
56974
+ console.log(source_default.cyan("\n Payload:"));
56975
+ for (const key of payloadKeys) {
56976
+ const value = asset.payload[key];
56977
+ const rendered = typeof value === "string" ? value : JSON.stringify(value);
56978
+ console.log(source_default.gray(` ${key}:`));
56979
+ console.log(` ${rendered.split("\n").join("\n ")}`);
56980
+ }
56981
+ }
56982
+ console.log();
56983
+ })
56984
+ );
56985
+ }
56986
+
56987
+ // src/cli/commands/content/source-asset-create.ts
56988
+ var import_node_fs10 = require("node:fs");
56989
+ init_source();
56990
+ init_api_client();
56991
+ init_config2();
56992
+ init_wrap_action();
56993
+ var PAYLOAD_MAX_BYTES = 5e5;
56994
+ function resolveTextArgument(value) {
56995
+ if (!value.startsWith("@")) return value;
56996
+ const path3 = value.slice(1);
56997
+ try {
56998
+ return (0, import_node_fs10.readFileSync)(path3, "utf8");
56999
+ } catch (error46) {
57000
+ throw new Error(`Could not read --text file "${path3}": ${error46 instanceof Error ? error46.message : String(error46)}`);
57001
+ }
57002
+ }
57003
+ function resolveMetadataOption(options) {
57004
+ if (options.metadata !== void 0 && options.metadataFile !== void 0) {
57005
+ throw new Error("Pass exactly one of --metadata or --metadata-file, not both");
57006
+ }
57007
+ let raw;
57008
+ if (options.metadataFile !== void 0) {
57009
+ const path3 = resolveProjectRelative(options.metadataFile);
57010
+ try {
57011
+ raw = (0, import_node_fs10.readFileSync)(path3, "utf8");
57012
+ } catch (error46) {
57013
+ throw new Error(
57014
+ `Could not read --metadata-file "${options.metadataFile}": ${error46 instanceof Error ? error46.message : String(error46)}`
57015
+ );
57016
+ }
57017
+ } else {
57018
+ raw = options.metadata;
57019
+ }
57020
+ if (raw === void 0) return void 0;
57021
+ let parsed;
57022
+ try {
57023
+ parsed = JSON.parse(raw);
57024
+ } catch (error46) {
57025
+ const source = options.metadataFile !== void 0 ? "--metadata-file" : "--metadata";
57026
+ throw new Error(`${source} must be valid JSON: ${error46 instanceof Error ? error46.message : String(error46)}`);
57027
+ }
57028
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
57029
+ const source = options.metadataFile !== void 0 ? "--metadata-file" : "--metadata";
57030
+ throw new Error(`${source} must be a JSON object, e.g. {"key":"value"}`);
57031
+ }
57032
+ return parsed;
57033
+ }
57034
+ function registerContentSourceAssetCreate(program3) {
57035
+ program3.command("content:source-asset:create").description(
57036
+ 'Create a content source asset from inline text or a URL, optionally linking it to an item\n Example: elevasis-sdk content:source-asset:create --kind transcript --title "Episode 12" --text @transcript.txt --item <uuid>'
57037
+ ).requiredOption("--kind <kind>", "Source asset kind (e.g. transcript) -- validated against the org model catalog").requiredOption("--title <title>", "Human-readable title (1..500 chars)").option("--text <value>", "Inline text, or @path to read a local file. Mutually exclusive with --url").option(
57038
+ "--field <key>",
57039
+ "Payload field the --text content is written to. Defaults to the --kind value, matching the catalog declaration"
57040
+ ).option("--url <url>", "External URL the asset references. Mutually exclusive with --text").option("--duration <seconds>", "Duration in seconds, for time-based referenced media").option("--storage-path <path>", "Storage path the asset references (1..2000 chars)").option("--metadata <json>", "Arbitrary metadata as a JSON object string. Mutually exclusive with --metadata-file").option(
57041
+ "--metadata-file <path>",
57042
+ "Path to a JSON file containing metadata (project-relative unless absolute). Mutually exclusive with --metadata"
57043
+ ).option("--item <itemId>", "Link the new asset to this content item after creating it").option("--prod", "Target production (overrides NODE_ENV=development)").option("--api-url <url>", "API base URL").option("--pretty", "Render human-readable output instead of raw JSON").action(
57044
+ wrapAction("content:source-asset:create", async (options) => {
57045
+ if (options.text !== void 0 && options.url !== void 0) {
57046
+ throw new Error("Pass exactly one of --text or --url, not both");
57047
+ }
57048
+ if (options.text === void 0 && options.url === void 0) {
57049
+ throw new Error("Pass one of --text (inline content) or --url (a reference)");
57050
+ }
57051
+ if (options.field !== void 0 && options.text === void 0) {
57052
+ throw new Error("--field only applies to --text");
57053
+ }
57054
+ const body = { kind: options.kind, title: options.title };
57055
+ if (options.text !== void 0) {
57056
+ const text = resolveTextArgument(options.text);
57057
+ const field2 = options.field ?? options.kind;
57058
+ const size = Buffer.byteLength(text, "utf8");
57059
+ if (size > PAYLOAD_MAX_BYTES) {
57060
+ throw new Error(
57061
+ `--text content is ${size} bytes, over the ${PAYLOAD_MAX_BYTES}-byte payload limit. Split it or store it as a reference with --url`
57062
+ );
57063
+ }
57064
+ body.payload = { [field2]: text };
57065
+ }
57066
+ if (options.url !== void 0) body.externalUrl = options.url;
57067
+ if (options.duration !== void 0) {
57068
+ const duration3 = Number(options.duration);
57069
+ if (!Number.isInteger(duration3) || duration3 < 0) {
57070
+ throw new Error("--duration must be a non-negative integer number of seconds");
57071
+ }
57072
+ body.durationSeconds = duration3;
57073
+ }
57074
+ if (options.storagePath !== void 0) body.storagePath = options.storagePath;
57075
+ const metadata = resolveMetadataOption(options);
57076
+ if (metadata !== void 0) body.metadata = metadata;
57077
+ const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
57078
+ const asset = await apiPost("/api/external/content/source-assets", body, apiUrl);
57079
+ let linkedItem;
57080
+ if (options.item !== void 0) {
57081
+ linkedItem = await apiPatch(
57082
+ `/api/external/content/items/${options.item}`,
57083
+ { sourceAssetId: asset.id },
57084
+ apiUrl
57085
+ );
57086
+ }
57087
+ if (!options.pretty) {
57088
+ console.log(JSON.stringify(linkedItem ? { sourceAsset: asset, item: linkedItem } : asset, null, 2));
57089
+ return;
57090
+ }
57091
+ console.log(source_default.green(`
57092
+ Created source asset ${asset.id}`));
57093
+ console.log(source_default.gray(` Title: ${asset.title}`));
57094
+ console.log(source_default.gray(` Kind: ${asset.kind}`));
57095
+ if (asset.externalUrl) console.log(source_default.gray(` URL: ${asset.externalUrl}`));
57096
+ if (asset.storagePath) console.log(source_default.gray(` Storage path: ${asset.storagePath}`));
57097
+ if (linkedItem) console.log(source_default.cyan(` Linked to item ${linkedItem.id} (${linkedItem.title})`));
57098
+ console.log();
57099
+ })
57100
+ );
57101
+ }
57102
+
56270
57103
  // src/cli/commands/content/index.ts
56271
57104
  function registerContentCommands(program3) {
56272
57105
  registerContentList(program3);
@@ -56276,6 +57109,9 @@ function registerContentCommands(program3) {
56276
57109
  registerContentPipeline(program3);
56277
57110
  registerContentDistributions(program3);
56278
57111
  registerContentReview(program3);
57112
+ registerContentSourceAssets(program3);
57113
+ registerContentSourceAsset(program3);
57114
+ registerContentSourceAssetCreate(program3);
56279
57115
  }
56280
57116
 
56281
57117
  // src/cli/commands/queue/queue.ts
@@ -56286,7 +57122,7 @@ init_wrap_action();
56286
57122
  function printJson8(value) {
56287
57123
  console.log(JSON.stringify(value, null, 2));
56288
57124
  }
56289
- function appendQuery6(params, key, value) {
57125
+ function appendQuery7(params, key, value) {
56290
57126
  if (value === void 0 || value === null || value === "") return;
56291
57127
  params.set(key, String(value));
56292
57128
  }
@@ -56312,13 +57148,13 @@ function registerQueueList(program3) {
56312
57148
  async (options) => {
56313
57149
  const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
56314
57150
  const params = new URLSearchParams();
56315
- appendQuery6(params, "status", options.status);
56316
- appendQuery6(params, "humanCheckpoint", options.humanCheckpoint);
56317
- appendQuery6(params, "timeRange", options.timeRange);
56318
- appendQuery6(params, "priorityMin", options.priorityMin);
56319
- appendQuery6(params, "priorityMax", options.priorityMax);
56320
- appendQuery6(params, "limit", options.limit);
56321
- appendQuery6(params, "offset", options.offset);
57151
+ appendQuery7(params, "status", options.status);
57152
+ appendQuery7(params, "humanCheckpoint", options.humanCheckpoint);
57153
+ appendQuery7(params, "timeRange", options.timeRange);
57154
+ appendQuery7(params, "priorityMin", options.priorityMin);
57155
+ appendQuery7(params, "priorityMax", options.priorityMax);
57156
+ appendQuery7(params, "limit", options.limit);
57157
+ appendQuery7(params, "offset", options.offset);
56322
57158
  const result = await apiGet(
56323
57159
  endpointWithQuery4("/api/external/command-queue", params),
56324
57160
  apiUrl
@@ -56423,10 +57259,10 @@ function registerQueueStatus(program3) {
56423
57259
  async (options) => {
56424
57260
  const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
56425
57261
  const params = new URLSearchParams();
56426
- appendQuery6(params, "timeRange", options.timeRange);
56427
- appendQuery6(params, "priorityMin", options.priorityMin);
56428
- appendQuery6(params, "priorityMax", options.priorityMax);
56429
- appendQuery6(params, "status", options.status);
57262
+ appendQuery7(params, "timeRange", options.timeRange);
57263
+ appendQuery7(params, "priorityMin", options.priorityMin);
57264
+ appendQuery7(params, "priorityMax", options.priorityMax);
57265
+ appendQuery7(params, "status", options.status);
56430
57266
  const result = await apiGet(
56431
57267
  endpointWithQuery4("/api/external/command-queue/checkpoints", params),
56432
57268
  apiUrl
@@ -56475,7 +57311,7 @@ init_wrap_action();
56475
57311
  function printJson9(value) {
56476
57312
  console.log(JSON.stringify(value, null, 2));
56477
57313
  }
56478
- function appendQuery7(params, key, value) {
57314
+ function appendQuery8(params, key, value) {
56479
57315
  if (value === void 0 || value === null || value === "") return;
56480
57316
  params.set(key, String(value));
56481
57317
  }
@@ -56504,11 +57340,11 @@ function registerScheduleList(program3) {
56504
57340
  async (options) => {
56505
57341
  const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
56506
57342
  const params = new URLSearchParams();
56507
- appendQuery7(params, "status", options.status);
56508
- appendQuery7(params, "targetResourceType", options.targetResourceType);
56509
- appendQuery7(params, "targetResourceId", options.targetResourceId);
56510
- appendQuery7(params, "limit", options.limit);
56511
- appendQuery7(params, "offset", options.offset);
57343
+ appendQuery8(params, "status", options.status);
57344
+ appendQuery8(params, "targetResourceType", options.targetResourceType);
57345
+ appendQuery8(params, "targetResourceId", options.targetResourceId);
57346
+ appendQuery8(params, "limit", options.limit);
57347
+ appendQuery8(params, "offset", options.offset);
56512
57348
  const result = await apiGet(
56513
57349
  endpointWithQuery5("/api/external/task-scheduler/schedules", params),
56514
57350
  apiUrl
@@ -56856,7 +57692,7 @@ function registerAgentCommands(program3) {
56856
57692
  }
56857
57693
 
56858
57694
  // src/cli/commands/session/session.ts
56859
- var import_node_fs10 = require("node:fs");
57695
+ var import_node_fs11 = require("node:fs");
56860
57696
  init_source();
56861
57697
  init_api_client();
56862
57698
  init_config2();
@@ -56864,7 +57700,7 @@ init_wrap_action();
56864
57700
  function printJson11(value) {
56865
57701
  console.log(JSON.stringify(value, null, 2));
56866
57702
  }
56867
- function appendQuery8(params, key, value) {
57703
+ function appendQuery9(params, key, value) {
56868
57704
  if (value === void 0 || value === null || value === "") return;
56869
57705
  params.set(key, String(value));
56870
57706
  }
@@ -56882,7 +57718,7 @@ function parseJson(value, label) {
56882
57718
  }
56883
57719
  function readJsonFile(path3, label) {
56884
57720
  const resolved = resolveProjectRelative(path3);
56885
- return parseJson((0, import_node_fs10.readFileSync)(resolved, "utf8"), label);
57721
+ return parseJson((0, import_node_fs11.readFileSync)(resolved, "utf8"), label);
56886
57722
  }
56887
57723
  function resolveTurnInput(options) {
56888
57724
  if (options.input && options.inputFile) {
@@ -56898,8 +57734,8 @@ function resolveTurnInput(options) {
56898
57734
  }
56899
57735
  function messagesEndpoint(sessionId, limit, cursor) {
56900
57736
  const params = new URLSearchParams();
56901
- appendQuery8(params, "limit", limit);
56902
- appendQuery8(params, "cursor", cursor);
57737
+ appendQuery9(params, "limit", limit);
57738
+ appendQuery9(params, "cursor", cursor);
56903
57739
  return endpointWithQuery6(`/api/external/sessions/${sessionId}/messages`, params);
56904
57740
  }
56905
57741
  async function fetchSessionMessages(sessionId, apiUrl, options) {
@@ -56984,9 +57820,9 @@ function registerSessionList(program3) {
56984
57820
  wrapAction("session:list", async (options) => {
56985
57821
  const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
56986
57822
  const params = new URLSearchParams();
56987
- appendQuery8(params, "resourceId", options.resourceId);
56988
- appendQuery8(params, "userId", options.userId);
56989
- appendQuery8(params, "limit", options.limit);
57823
+ appendQuery9(params, "resourceId", options.resourceId);
57824
+ appendQuery9(params, "userId", options.userId);
57825
+ appendQuery9(params, "limit", options.limit);
56990
57826
  const result = await apiGet(endpointWithQuery6("/api/external/sessions", params), apiUrl);
56991
57827
  if (options.json) {
56992
57828
  printJson11(result);
@@ -57121,7 +57957,7 @@ init_wrap_action();
57121
57957
  function printJson12(value) {
57122
57958
  console.log(JSON.stringify(value, null, 2));
57123
57959
  }
57124
- function appendQuery9(params, key, value) {
57960
+ function appendQuery10(params, key, value) {
57125
57961
  if (value === void 0 || value === null || value === "" || value === false) return;
57126
57962
  params.set(key, String(value));
57127
57963
  }
@@ -57186,8 +58022,8 @@ function registerGrantList(program3) {
57186
58022
  wrapAction("grant:list", async (options) => {
57187
58023
  const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
57188
58024
  const params = new URLSearchParams();
57189
- appendQuery9(params, "resourceId", options.resourceId);
57190
- appendQuery9(params, "includeDisabled", options.includeDisabled ? "true" : void 0);
58025
+ appendQuery10(params, "resourceId", options.resourceId);
58026
+ appendQuery10(params, "includeDisabled", options.includeDisabled ? "true" : void 0);
57191
58027
  const result = await apiGet(
57192
58028
  endpointWithQuery7("/api/external/agent-access-grants", params),
57193
58029
  apiUrl
@@ -57634,71 +58470,6 @@ function formatOmDoctorReport(report) {
57634
58470
  return lines.join("\n");
57635
58471
  }
57636
58472
 
57637
- // src/cli/commands/om/deployed-readiness.ts
57638
- init_organization_model();
57639
- init_api_client();
57640
- function listApiInterfaceSystemPaths(model) {
57641
- return listAllSystems(model).filter(({ system }) => system.apiInterface !== void 0).map(({ path: path3 }) => path3);
57642
- }
57643
- async function fetchDeployedReadiness(model, options = {}) {
57644
- const systemPaths = listApiInterfaceSystemPaths(model);
57645
- const report = {
57646
- activeDeploymentId: null,
57647
- snapshotHash: null,
57648
- kind: null,
57649
- entries: []
57650
- };
57651
- if (systemPaths.length === 0) {
57652
- report.unavailableReason = "no System in the project model declares an apiInterface";
57653
- return report;
57654
- }
57655
- for (const systemPath of systemPaths) {
57656
- let response;
57657
- try {
57658
- const endpoint = `/api/external/organization-model/readiness?systemPath=${encodeURIComponent(systemPath)}&interfaceKey=api`;
57659
- response = await apiGet(endpoint, options.apiUrl);
57660
- } catch (error46) {
57661
- report.unavailableReason = error46 instanceof Error ? error46.message : String(error46);
57662
- return report;
57663
- }
57664
- report.activeDeploymentId = response.activeDeploymentId;
57665
- report.snapshotHash = response.snapshotHash;
57666
- report.kind = response.kind;
57667
- report.entries.push({
57668
- systemPath: response.readiness.systemPath,
57669
- interfaceKey: response.readiness.interfaceKey,
57670
- ready: response.readiness.ready,
57671
- issues: response.readiness.issues
57672
- });
57673
- }
57674
- return report;
57675
- }
57676
- function readinessDiagnostics(report) {
57677
- const diagnostics = [];
57678
- for (const entry of report.entries) {
57679
- if (entry.ready) {
57680
- diagnostics.push({
57681
- severity: "info",
57682
- code: "deployed-interface-ready",
57683
- systemPath: entry.systemPath,
57684
- message: `${entry.systemPath}/${entry.interfaceKey} is ready in the deployed snapshot.`
57685
- });
57686
- continue;
57687
- }
57688
- for (const issue2 of entry.issues) {
57689
- diagnostics.push({
57690
- severity: "error",
57691
- code: `deployed-${issue2.code}`,
57692
- systemPath: entry.systemPath,
57693
- ...issue2.ref !== void 0 && { targetId: issue2.ref },
57694
- message: `${entry.systemPath}/${entry.interfaceKey} not ready [${issue2.family}]: ${issue2.message}`,
57695
- source: "deployed-snapshot"
57696
- });
57697
- }
57698
- }
57699
- return diagnostics;
57700
- }
57701
-
57702
58473
  // src/cli/commands/om/doctor.ts
57703
58474
  function registerOmDoctorCommand(program3) {
57704
58475
  program3.command("om:doctor").description(
@@ -57762,7 +58533,7 @@ function registerOmDoctorCommand(program3) {
57762
58533
  }
57763
58534
 
57764
58535
  // src/cli/commands/om/rename.ts
57765
- var import_node_fs11 = require("node:fs");
58536
+ var import_node_fs12 = require("node:fs");
57766
58537
  var import_node_path9 = require("node:path");
57767
58538
  init_config2();
57768
58539
  init_wrap_action();
@@ -57800,10 +58571,10 @@ function absolutePath(sourceRoot, relativePath) {
57800
58571
  }
57801
58572
  function walkFiles(sourceRoot, relativeRoot, extension) {
57802
58573
  const root = absolutePath(sourceRoot, relativeRoot);
57803
- if (!(0, import_node_fs11.existsSync)(root)) return [];
58574
+ if (!(0, import_node_fs12.existsSync)(root)) return [];
57804
58575
  const targets = [];
57805
58576
  function visit(directory) {
57806
- for (const entry of (0, import_node_fs11.readdirSync)(directory, { withFileTypes: true })) {
58577
+ for (const entry of (0, import_node_fs12.readdirSync)(directory, { withFileTypes: true })) {
57807
58578
  const fullPath = (0, import_node_path9.join)(directory, entry.name);
57808
58579
  if (entry.isDirectory()) {
57809
58580
  visit(fullPath);
@@ -57885,8 +58656,8 @@ function createOmRenamePlan(oldPathArg, newPathArg, options = {}) {
57885
58656
  const edits = [];
57886
58657
  for (const target of buildTargets(sourceRoot)) {
57887
58658
  const path3 = absolutePath(sourceRoot, target.path);
57888
- if (!(0, import_node_fs11.existsSync)(path3)) continue;
57889
- const source = (0, import_node_fs11.readFileSync)(path3, "utf8");
58659
+ if (!(0, import_node_fs12.existsSync)(path3)) continue;
58660
+ const source = (0, import_node_fs12.readFileSync)(path3, "utf8");
57890
58661
  const transformed = transformContent(source, target.path, oldPath, newPath);
57891
58662
  if (transformed.count === 0) continue;
57892
58663
  edits.push({
@@ -57913,20 +58684,20 @@ function createOmRenamePlan(oldPathArg, newPathArg, options = {}) {
57913
58684
  function snapshotEdits(sourceRoot, edits) {
57914
58685
  return edits.map((edit) => {
57915
58686
  const path3 = absolutePath(sourceRoot, edit.path);
57916
- return { path: path3, content: (0, import_node_fs11.readFileSync)(path3, "utf8") };
58687
+ return { path: path3, content: (0, import_node_fs12.readFileSync)(path3, "utf8") };
57917
58688
  });
57918
58689
  }
57919
58690
  function restoreSnapshot(snapshot) {
57920
58691
  for (const entry of snapshot) {
57921
- (0, import_node_fs11.writeFileSync)(entry.path, entry.content);
58692
+ (0, import_node_fs12.writeFileSync)(entry.path, entry.content);
57922
58693
  }
57923
58694
  }
57924
58695
  function applyPlan(sourceRoot, plan) {
57925
58696
  for (const edit of plan.edits) {
57926
58697
  const path3 = absolutePath(sourceRoot, edit.path);
57927
- const source = (0, import_node_fs11.readFileSync)(path3, "utf8");
58698
+ const source = (0, import_node_fs12.readFileSync)(path3, "utf8");
57928
58699
  const transformed = transformContent(source, edit.path, plan.oldPath, plan.newPath);
57929
- (0, import_node_fs11.writeFileSync)(path3, transformed.output);
58700
+ (0, import_node_fs12.writeFileSync)(path3, transformed.output);
57930
58701
  }
57931
58702
  }
57932
58703
  async function defaultOmRenameValidator(plan, sourceRoot) {
@@ -57934,7 +58705,7 @@ async function defaultOmRenameValidator(plan, sourceRoot) {
57934
58705
  try {
57935
58706
  if (plan.edits.some((edit) => edit.path.endsWith(".mdx"))) {
57936
58707
  const sourceDir = absolutePath(sourceRoot, KNOWLEDGE_ROOT);
57937
- if ((0, import_node_fs11.existsSync)(sourceDir)) {
58708
+ if ((0, import_node_fs12.existsSync)(sourceDir)) {
57938
58709
  const generated = generateKnowledgeNodes({
57939
58710
  sourceDir,
57940
58711
  outputPath: absolutePath(sourceRoot, KNOWLEDGE_GENERATED_OUTPUT),
@@ -58022,7 +58793,7 @@ function registerOmRenameCommand(program3) {
58022
58793
  }
58023
58794
 
58024
58795
  // src/cli/commands/om/deprecate.ts
58025
- var import_node_fs12 = require("node:fs");
58796
+ var import_node_fs13 = require("node:fs");
58026
58797
  var import_node_path10 = require("node:path");
58027
58798
  init_src();
58028
58799
  init_config2();
@@ -58131,8 +58902,8 @@ function createOmDeprecatePlan(model, systemPathArg, options = {}) {
58131
58902
  const warnings = hasDependents && to === "deprecated" ? ["Live dependents were found. Deprecation is allowed, but plan the dependent wind-down before archiving."] : [];
58132
58903
  const blocked = to === "archived" && hasDependents && !confirmed;
58133
58904
  let edit = null;
58134
- if ((0, import_node_fs12.existsSync)(systemsPath)) {
58135
- const source = (0, import_node_fs12.readFileSync)(systemsPath, "utf8");
58905
+ if ((0, import_node_fs13.existsSync)(systemsPath)) {
58906
+ const source = (0, import_node_fs13.readFileSync)(systemsPath, "utf8");
58136
58907
  edit = {
58137
58908
  path: SYSTEMS_FILE2,
58138
58909
  replacements: transformSystemLifecycle(source, systemPath, to).replacements
@@ -58177,13 +58948,13 @@ async function executeOmDeprecatePlan(plan, options = {}) {
58177
58948
  return { plan, wrote: false, validation: { ok: true, output: "no lifecycle change needed" }, rolledBack: false };
58178
58949
  }
58179
58950
  const systemsPath = absolutePath2(sourceRoot, SYSTEMS_FILE2);
58180
- const before = (0, import_node_fs12.readFileSync)(systemsPath, "utf8");
58951
+ const before = (0, import_node_fs13.readFileSync)(systemsPath, "utf8");
58181
58952
  const transformed = transformSystemLifecycle(before, plan.systemPath, plan.to);
58182
- (0, import_node_fs12.writeFileSync)(systemsPath, transformed.output);
58953
+ (0, import_node_fs13.writeFileSync)(systemsPath, transformed.output);
58183
58954
  const validator = options.validator ?? defaultOmDeprecateValidator;
58184
58955
  const validation = await validator(plan, sourceRoot);
58185
58956
  if (!validation.ok) {
58186
- (0, import_node_fs12.writeFileSync)(systemsPath, before);
58957
+ (0, import_node_fs13.writeFileSync)(systemsPath, before);
58187
58958
  return { plan, wrote: true, validation, rolledBack: true };
58188
58959
  }
58189
58960
  return { plan, wrote: true, validation, rolledBack: false };
@@ -58278,7 +59049,7 @@ function registerOmScaffoldCommands(program3) {
58278
59049
  const mod = await Promise.resolve().then(() => (init_scaffold_ontology(), scaffold_ontology_exports));
58279
59050
  await mod.default(opts);
58280
59051
  });
58281
- program3.command("om:scaffold:knowledge").description("Create a new MDX knowledge node file in core/config/knowledge/nodes/").option("--id <id>", "knowledge node id, e.g. outreach-playbook (prompted if absent)").option("--kind <kind>", "node kind: playbook | strategy | reference | policy (prompted if absent)").option("--system-path <path>", "governing system path for mount (prompted; can be blank for global)").option("--write", "apply the change (default is a dry-run preview \u2014 no files written)").action(async (opts) => {
59052
+ program3.command("om:scaffold:knowledge").description("Create a new MDX knowledge node file in core/config/knowledge/nodes/").option("--id <id>", "knowledge node id, e.g. outreach-playbook (prompted if absent)").option("--kind <kind>", "node kind: playbook | strategy | reference (prompted if absent)").option("--system-path <path>", "governing system path for mount (prompted; can be blank for global)").option("--write", "apply the change (default is a dry-run preview \u2014 no files written)").action(async (opts) => {
58282
59053
  const mod = await Promise.resolve().then(() => (init_scaffold_knowledge(), scaffold_knowledge_exports));
58283
59054
  await mod.default(opts);
58284
59055
  });
@@ -58373,7 +59144,7 @@ function registerSkillScaffoldCommand(program3) {
58373
59144
  }
58374
59145
 
58375
59146
  // src/cli/json-file-argv.ts
58376
- var import_node_fs17 = require("node:fs");
59147
+ var import_node_fs18 = require("node:fs");
58377
59148
  var import_node_path18 = require("node:path");
58378
59149
  init_config2();
58379
59150
  var JSON_FILE_PREFIX = "@json:";
@@ -58404,7 +59175,7 @@ function resolveJsonFilePath(path3, options) {
58404
59175
  function readJsonFileReference(ref, options) {
58405
59176
  const relativeOrAbsolutePath = ref.slice(JSON_FILE_PREFIX.length);
58406
59177
  const resolvedPath = resolveJsonFilePath(relativeOrAbsolutePath, options);
58407
- const raw = (options.readFile ?? ((path3) => (0, import_node_fs17.readFileSync)(path3, "utf8")))(resolvedPath);
59178
+ const raw = (options.readFile ?? ((path3) => (0, import_node_fs18.readFileSync)(path3, "utf8")))(resolvedPath);
58408
59179
  try {
58409
59180
  JSON.parse(raw);
58410
59181
  } catch {
@@ -58512,63 +59283,7 @@ if (envPath) {
58512
59283
  }
58513
59284
  var program2 = new Command();
58514
59285
  program2.name("elevasis-sdk").description(
58515
- source_default.cyan("Elevasis SDK CLI") + `
58516
-
58517
- Commands:
58518
- elevasis-sdk check Validate project resources
58519
- elevasis-sdk deploy Bundle and deploy to platform
58520
- elevasis-sdk resources List deployed resources
58521
- elevasis-sdk describe <resourceId> Describe a resource
58522
- elevasis-sdk exec <resourceId> -i '{}' Execute a resource
58523
- elevasis-sdk executions <resourceId> List execution history
58524
- elevasis-sdk execution <resourceId> <id> Get execution details
58525
- elevasis-sdk execution:cancel <resourceId> <id> Cancel a running execution
58526
- elevasis-sdk executions:delete <resourceId> Delete execution history (destructive)
58527
- elevasis-sdk deployments List deployments
58528
- elevasis-sdk project:list [--search <query>] List projects with optional search
58529
- elevasis-sdk project:resolve <query> Resolve a project ID from a name or UUID
58530
- elevasis-sdk project:work <query> Open a lifecycle-aware project work brief
58531
- elevasis-sdk client:list [--search <query>] List clients with optional search
58532
- elevasis-sdk client:get <id> Get client detail and lineage
58533
- elevasis-sdk client:status Show client portfolio status
58534
- elevasis-sdk content:list [--status queued] List content pipeline items
58535
- elevasis-sdk content:get <itemId> Get an item, its attempts, and distributions
58536
- elevasis-sdk content:queue List items awaiting a queued-gate review
58537
- elevasis-sdk content:pipeline [id] List pipeline templates, or one step contract
58538
- elevasis-sdk content:distributions List content distributions
58539
- elevasis-sdk content:review <itemId> --step <key> --approve|--reject --user <email>
58540
- Clear a queued review gate on a content item
58541
- elevasis-sdk queue:list [--status pending] List HITL command queue tasks
58542
- elevasis-sdk queue:select <id> --action-id <id> Select and execute a HITL queue action
58543
- elevasis-sdk schedule:list [--status active] List task schedules
58544
- elevasis-sdk schedule:create --name <name> ... Create a task schedule
58545
- elevasis-sdk agent:list List deployed agents
58546
- elevasis-sdk agent:get <id> Get agent metadata and OM linkage
58547
- elevasis-sdk session:create <resourceId> Create an agent session
58548
- elevasis-sdk session:turn <id> -f tmp/turn.json Execute a session turn
58549
- elevasis-sdk session:messages <id> Export session transcript messages
58550
- elevasis-sdk session:list List agent sessions
58551
- elevasis-sdk session:get <id> Get session details
58552
- elevasis-sdk session:end <id> End an active agent session
58553
- elevasis-sdk grant:list List public/code-gated agent access grants
58554
- elevasis-sdk grant:create --resource <id> Create an agent access grant
58555
- elevasis-sdk grant:disable <slug> Disable an agent access grant
58556
- elevasis-sdk acquisition:list:list List acquisition lists
58557
- elevasis-sdk acquisition:deal:list List acquisition deals
58558
- elevasis-sdk knowledge:generate Generate knowledge nodes from MDX files
58559
- elevasis-sdk knowledge:ls <path> List knowledge nodes for a path
58560
- elevasis-sdk knowledge:cat <id> Print raw MDX body of a knowledge node
58561
- elevasis-sdk knowledge:graph <id> Show outgoing and incoming edges for a node
58562
- elevasis-sdk request:submit -f <path> Submit a structured request report
58563
- elevasis-sdk request:list [--status open] List reported requests
58564
- elevasis-sdk request:get <id> Get a reported request by id
58565
- elevasis-sdk ui:use-local Use a local @elevasis/ui tarball
58566
- elevasis-sdk ui:use-published Restore published @elevasis/ui
58567
- elevasis-sdk cli [domain] Generate a registered command catalog
58568
- elevasis-sdk rename <id> --to <newId> [--prod] Rename resource across platform tables
58569
- elevasis-sdk doctor [--verbose] Check project environment and API connectivity
58570
-
58571
- Use "elevasis-sdk <command> --help" for more information about a command.`
59286
+ source_default.cyan("Elevasis SDK CLI") + '\n\nRun `elevasis-sdk cli` for the full command catalog. It is built by scanning the\ncommands actually registered below, so it can never drift out of sync the way a\nhand-written list here would.\n\n elevasis-sdk cli Full catalog, grouped by domain\n elevasis-sdk cli --domain <domain> Filter to one domain, e.g. project, content, agent\n elevasis-sdk cli --format json Machine-readable catalog\n\nUse "elevasis-sdk <command> --help" for a specific command\'s options.'
58572
59287
  ).version(SDK_VERSION);
58573
59288
  program2.hook("preAction", () => {
58574
59289
  runPreflight();