@elevasis/sdk 1.48.0 → 1.50.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.
- package/dist/chunk-MGZZ4HL4.js +4399 -0
- package/dist/chunk-VYWGWJRW.js +130 -0
- package/dist/chunk-YJDXRHNP.js +7901 -0
- package/dist/cli.cjs +949 -281
- package/dist/index.d.ts +1031 -48
- package/dist/index.js +2 -7597
- package/dist/node/index.d.ts +3 -3675
- package/dist/node/index.js +2 -124
- package/dist/test-utils/index.d.ts +2 -12051
- package/dist/test-utils/index.js +113 -27891
- package/dist/worker/index.d.ts +548 -12264
- package/dist/worker/index.js +3 -7400
- package/package.json +12 -4
- package/reference/_navigation.md +4 -4
- package/reference/_reference-manifest.json +1 -1
- package/reference/core/index.mdx +6 -4
- package/reference/index.mdx +11 -5
- package/reference/packages/core/src/README.md +46 -44
- package/reference/packages/core/src/content/README.md +16 -12
- package/reference/rules/agent-start-here.md +1 -1
- package/reference/rules/frontend.md +3 -1
- package/reference/rules/package-taxonomy.md +7 -5
- package/reference/rules/ui.md +31 -5
- package/reference/rules/vibe-intents.md +2 -2
- package/reference/rules/vibe.md +30 -10
- package/reference/scaffold/recipes/extend-content.md +82 -3
- package/reference/scaffold/recipes/gate-by-feature-or-admin.md +8 -6
- package/reference/scaffold/ui/feature-flags-and-gating.md +11 -1
- package/reference/sdk/cli-management.mdx +284 -139
- package/reference/sdk/cli.mdx +136 -88
- package/reference/sdk/define-builders.mdx +1 -1
- package/reference/sdk/deployment/command-center.mdx +2 -2
- package/reference/sdk/deployment/index.mdx +24 -7
- package/reference/sdk/exports.mdx +4 -4
- package/reference/sdk/framework/agent.mdx +4 -3
- package/reference/sdk/framework/index.mdx +1 -1
- package/reference/sdk/framework/project-structure.mdx +34 -23
- package/reference/sdk/framework/tutorial-system.mdx +1 -1
- package/reference/sdk/getting-started.mdx +25 -52
- package/reference/sdk/index.mdx +3 -3
- package/reference/sdk/platform-tools/adapters-integration.mdx +1 -1
- package/reference/sdk/platform-tools/adapters-platform.mdx +1 -1
- package/reference/sdk/platform-tools/type-safety.mdx +1 -1
- package/reference/sdk/resources/patterns.mdx +10 -11
- package/reference/sdk/resources/types.mdx +15 -9
- package/reference/sdk/templates/data-enrichment.mdx +1 -1
- package/reference/sdk/templates/email-sender.mdx +1 -1
- package/reference/sdk/templates/index.mdx +47 -47
- package/reference/sdk/templates/lead-scorer.mdx +1 -1
- package/reference/sdk/templates/pdf-generator.mdx +42 -24
- package/reference/sdk/templates/recurring-job.mdx +20 -15
- package/reference/sdk/templates/text-classifier.mdx +1 -1
- package/reference/sdk/templates/web-scraper.mdx +9 -5
- package/reference/sdk/troubleshooting.mdx +72 -1
- package/reference/ui/exports.mdx +1 -1
- 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(),
|
|
@@ -23550,6 +23570,10 @@ var init_profile_registry = __esm({
|
|
|
23550
23570
|
});
|
|
23551
23571
|
|
|
23552
23572
|
// ../core/src/organization-model/domains/systems.ts
|
|
23573
|
+
function isSystemLifecycleVisible(lifecycle, enabled) {
|
|
23574
|
+
if (enabled === false) return false;
|
|
23575
|
+
return lifecycle !== "draft" && lifecycle !== "deprecated" && lifecycle !== "archived";
|
|
23576
|
+
}
|
|
23553
23577
|
function isReservedPlatformProfileId(profileId) {
|
|
23554
23578
|
return BUILT_IN_VALIDATED_PROFILE_IDS.includes(profileId);
|
|
23555
23579
|
}
|
|
@@ -23566,7 +23590,10 @@ var init_systems = __esm({
|
|
|
23566
23590
|
init_ontology();
|
|
23567
23591
|
init_profile_registry();
|
|
23568
23592
|
SystemKindSchema = external_exports.enum(["product", "operational", "platform", "diagnostic"]).meta({ label: "System kind", color: "blue" });
|
|
23569
|
-
SystemLifecycleSchema = external_exports.enum(["draft", "beta", "active", "deprecated", "archived"]).meta({
|
|
23593
|
+
SystemLifecycleSchema = external_exports.enum(["draft", "beta", "active", "deprecated", "archived"]).meta({
|
|
23594
|
+
label: "Lifecycle",
|
|
23595
|
+
color: "teal"
|
|
23596
|
+
});
|
|
23570
23597
|
SystemIdSchema = ModelIdSchema;
|
|
23571
23598
|
SystemPathSchema = external_exports.string().trim().min(1).regex(
|
|
23572
23599
|
/^[a-z0-9][a-z0-9-]*(?:\.[a-z0-9][a-z0-9-]*)*$/,
|
|
@@ -23686,8 +23713,13 @@ var init_systems = __esm({
|
|
|
23686
23713
|
parentSystemId: SystemIdSchema.optional(),
|
|
23687
23714
|
/** Optional UI presence. Systems without UI omit this. */
|
|
23688
23715
|
ui: SystemUiSchema.optional(),
|
|
23689
|
-
/**
|
|
23690
|
-
|
|
23716
|
+
/**
|
|
23717
|
+
* Canonical lifecycle state. `beta` is what gates a System to dev-mode
|
|
23718
|
+
* viewers. Defaults to `active` (not `.optional()`) so an omitted field
|
|
23719
|
+
* never reaches a consumer as `undefined` -- see `isSystemLifecycleVisible`
|
|
23720
|
+
* and `systemLifecycleAllowsAccess` above.
|
|
23721
|
+
*/
|
|
23722
|
+
lifecycle: SystemLifecycleSchema.default("active"),
|
|
23691
23723
|
/** Optional role responsible for this system. */
|
|
23692
23724
|
responsibleRoleId: ModelIdSchema.meta({ ref: "role" }).optional(),
|
|
23693
23725
|
/** Optional knowledge nodes that govern this system. */
|
|
@@ -24209,10 +24241,6 @@ function addIssue(ctx, path3, message) {
|
|
|
24209
24241
|
message
|
|
24210
24242
|
});
|
|
24211
24243
|
}
|
|
24212
|
-
function isLifecycleEnabled(lifecycle, enabled) {
|
|
24213
|
-
if (enabled === false) return false;
|
|
24214
|
-
return lifecycle !== "deprecated" && lifecycle !== "archived";
|
|
24215
|
-
}
|
|
24216
24244
|
function defaultSystemPathFor(id) {
|
|
24217
24245
|
return `/${id.replaceAll(".", "/")}`;
|
|
24218
24246
|
}
|
|
@@ -24283,11 +24311,11 @@ function refineOrganizationModel(model, ctx) {
|
|
|
24283
24311
|
systemIdsByEffectivePath.set(effectivePath, path3);
|
|
24284
24312
|
}
|
|
24285
24313
|
}
|
|
24286
|
-
if (hasChildren &&
|
|
24314
|
+
if (hasChildren && isSystemLifecycleVisible(system.lifecycle, system.enabled)) {
|
|
24287
24315
|
const hasEnabledDescendant = Object.values(system.systems ?? system.subsystems ?? {}).some(
|
|
24288
|
-
(candidate) =>
|
|
24316
|
+
(candidate) => isSystemLifecycleVisible(candidate.lifecycle, candidate.enabled)
|
|
24289
24317
|
) || allSystems.some(
|
|
24290
|
-
(candidate) => candidate.path.startsWith(`${path3}.`) && !candidate.path.slice(path3.length + 1).includes(".") &&
|
|
24318
|
+
(candidate) => candidate.path.startsWith(`${path3}.`) && !candidate.path.slice(path3.length + 1).includes(".") && isSystemLifecycleVisible(candidate.system.lifecycle, candidate.system.enabled)
|
|
24291
24319
|
);
|
|
24292
24320
|
if (!hasEnabledDescendant) {
|
|
24293
24321
|
addIssue(ctx, [...schemaPath, "lifecycle"], `System "${path3}" is active but has no active descendants`);
|
|
@@ -24702,6 +24730,7 @@ var init_schema_refinements = __esm({
|
|
|
24702
24730
|
"use strict";
|
|
24703
24731
|
init_zod();
|
|
24704
24732
|
init_resources();
|
|
24733
|
+
init_systems();
|
|
24705
24734
|
init_cross_ref();
|
|
24706
24735
|
init_ontology();
|
|
24707
24736
|
}
|
|
@@ -25034,8 +25063,8 @@ var init_content = __esm({
|
|
|
25034
25063
|
"../core/src/organization-model/catalogs/content.ts"() {
|
|
25035
25064
|
"use strict";
|
|
25036
25065
|
init_zod();
|
|
25037
|
-
ContentPipelineStepActorSchema = external_exports.enum(["workflow", "agent", "vendor"]);
|
|
25038
|
-
ContentPipelineStepReviewModeSchema = external_exports.enum(["
|
|
25066
|
+
ContentPipelineStepActorSchema = external_exports.enum(["workflow", "agent", "vendor", "human"]);
|
|
25067
|
+
ContentPipelineStepReviewModeSchema = external_exports.enum(["none", "required"]);
|
|
25039
25068
|
ContentPayloadFieldTypeSchema = external_exports.enum(["string", "text", "number", "boolean", "url", "string-array"]);
|
|
25040
25069
|
ContentPayloadFieldDeclarationSchema = external_exports.object({
|
|
25041
25070
|
key: external_exports.string().trim().min(1).max(200),
|
|
@@ -26271,6 +26300,63 @@ var init_lead_gen = __esm({
|
|
|
26271
26300
|
}
|
|
26272
26301
|
});
|
|
26273
26302
|
|
|
26303
|
+
// ../core/src/organization-model/catalogs/content-producer-factory.ts
|
|
26304
|
+
var init_content_producer_factory = __esm({
|
|
26305
|
+
"../core/src/organization-model/catalogs/content-producer-factory.ts"() {
|
|
26306
|
+
"use strict";
|
|
26307
|
+
}
|
|
26308
|
+
});
|
|
26309
|
+
|
|
26310
|
+
// ../core/src/organization-model/catalogs/define-content-pipeline.ts
|
|
26311
|
+
var init_define_content_pipeline = __esm({
|
|
26312
|
+
"../core/src/organization-model/catalogs/define-content-pipeline.ts"() {
|
|
26313
|
+
"use strict";
|
|
26314
|
+
}
|
|
26315
|
+
});
|
|
26316
|
+
|
|
26317
|
+
// ../core/src/organization-model/catalogs/define-system-api-interface.ts
|
|
26318
|
+
function formatAdoptableProfiles() {
|
|
26319
|
+
return SYSTEM_INTERFACE_PROFILES.map((profile) => `"${profile.readinessProfile}"`).join(", ");
|
|
26320
|
+
}
|
|
26321
|
+
function defineSystemApiInterface(input) {
|
|
26322
|
+
const interfaceKey = input.interfaceKey ?? "api";
|
|
26323
|
+
const identity = `${input.systemPath}/${interfaceKey}`;
|
|
26324
|
+
const catalogEntry = SYSTEM_INTERFACE_PROFILES.find((profile) => profile.readinessProfile === input.readinessProfile);
|
|
26325
|
+
if (catalogEntry === void 0) {
|
|
26326
|
+
throw new Error(
|
|
26327
|
+
`System Interface "${identity}" declares readinessProfile "${input.readinessProfile}", which is not a member of SYSTEM_INTERFACE_PROFILES. Adoptable profiles: ${formatAdoptableProfiles()}. An uncataloged id names no route platform code actually serves -- it computes as ready and answers every request with a 503. Add an entry to SYSTEM_INTERFACE_PROFILES (packages/core/src/organization-model/domains/systems.ts) before declaring it on System "${input.systemPath}", or use one of the ids above.`
|
|
26328
|
+
);
|
|
26329
|
+
}
|
|
26330
|
+
if (input.resourceIds.length === 0) {
|
|
26331
|
+
throw new Error(
|
|
26332
|
+
`System Interface "${identity}" declares an empty resourceIds list. An interface with no scoped active resource computes as ready and answers every route with a 503 -- scope at least one active resource for System "${input.systemPath}".`
|
|
26333
|
+
);
|
|
26334
|
+
}
|
|
26335
|
+
const isBuiltIn = catalogEntry.validation === "built-in";
|
|
26336
|
+
if (!isBuiltIn && input.readinessContract === void 0) {
|
|
26337
|
+
throw new Error(
|
|
26338
|
+
`System Interface "${identity}" adopts contract-validated profile "${input.readinessProfile}" but declares no readinessContract. Contract-validated profiles have no registered platform validator -- each adopter's structural requirements differ, so System "${input.systemPath}" must pass a readinessContract with at least one requiredCatalogs entry.`
|
|
26339
|
+
);
|
|
26340
|
+
}
|
|
26341
|
+
if (isBuiltIn && input.readinessContract !== void 0) {
|
|
26342
|
+
throw new Error(
|
|
26343
|
+
`System Interface "${identity}" declares a readinessContract against built-in profile "${input.readinessProfile}". Built-in profiles derive their requirements from platform code registered via registerBuiltInReadinessProfile, and the readiness engine never reads an authored contract against one -- it is silently ignored (the "else if (readinessContract)" branch in readiness/engine.ts is unreachable for a built-in profile). Delete the readinessContract on System "${input.systemPath}"; it asserts nothing today.`
|
|
26344
|
+
);
|
|
26345
|
+
}
|
|
26346
|
+
return {
|
|
26347
|
+
lifecycle: input.lifecycle ?? "active",
|
|
26348
|
+
readinessProfile: input.readinessProfile,
|
|
26349
|
+
resourceIds: input.resourceIds,
|
|
26350
|
+
...input.readinessContract !== void 0 ? { readinessContract: input.readinessContract } : {}
|
|
26351
|
+
};
|
|
26352
|
+
}
|
|
26353
|
+
var init_define_system_api_interface = __esm({
|
|
26354
|
+
"../core/src/organization-model/catalogs/define-system-api-interface.ts"() {
|
|
26355
|
+
"use strict";
|
|
26356
|
+
init_systems();
|
|
26357
|
+
}
|
|
26358
|
+
});
|
|
26359
|
+
|
|
26274
26360
|
// ../core/src/organization-model/readiness/engine.ts
|
|
26275
26361
|
function addReadinessIssue(issues, family, code, message, details = {}) {
|
|
26276
26362
|
issues.push({
|
|
@@ -26611,6 +26697,9 @@ var init_organization_model = __esm({
|
|
|
26611
26697
|
init_graph();
|
|
26612
26698
|
init_lead_gen();
|
|
26613
26699
|
init_content();
|
|
26700
|
+
init_content_producer_factory();
|
|
26701
|
+
init_define_content_pipeline();
|
|
26702
|
+
init_define_system_api_interface();
|
|
26614
26703
|
init_branding();
|
|
26615
26704
|
init_systems();
|
|
26616
26705
|
init_resources();
|
|
@@ -44095,7 +44184,7 @@ function getModelInfo(model) {
|
|
|
44095
44184
|
return MODEL_INFO[model];
|
|
44096
44185
|
}
|
|
44097
44186
|
for (const knownModel of MODEL_KEYS_BY_SPECIFICITY) {
|
|
44098
|
-
if (model.startsWith(knownModel)) {
|
|
44187
|
+
if (model.startsWith(`${knownModel}-`)) {
|
|
44099
44188
|
return MODEL_INFO[knownModel];
|
|
44100
44189
|
}
|
|
44101
44190
|
}
|
|
@@ -44121,7 +44210,7 @@ function validateModelConfig(config3) {
|
|
|
44121
44210
|
throw new ModelConfigError(`Invalid config for ${model}: ${firstError.message}`, fieldName, model);
|
|
44122
44211
|
}
|
|
44123
44212
|
}
|
|
44124
|
-
var GPT5OptionsSchema, GPT5ConfigSchema, MockConfigSchema, OpenRouterOptionsSchema, OpenRouterConfigSchema, AnthropicOptionsSchema, AnthropicStandardConfigSchema, AnthropicClaude5ConfigSchema, AnthropicConfigSchema, MODEL_INFO, MODEL_KEYS_BY_SPECIFICITY;
|
|
44213
|
+
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;
|
|
44125
44214
|
var init_model_info = __esm({
|
|
44126
44215
|
"../core/src/execution/engine/llm/model-info.ts"() {
|
|
44127
44216
|
"use strict";
|
|
@@ -44141,6 +44230,19 @@ var init_model_info = __esm({
|
|
|
44141
44230
|
topP: external_exports.number().min(0).max(1).optional(),
|
|
44142
44231
|
modelOptions: GPT5OptionsSchema.optional()
|
|
44143
44232
|
});
|
|
44233
|
+
GPT56OptionsSchema = external_exports.object({
|
|
44234
|
+
reasoning_effort: external_exports.enum(["none", "low", "medium", "high", "xhigh", "max"]).optional(),
|
|
44235
|
+
verbosity: external_exports.enum(["low", "medium", "high"]).optional()
|
|
44236
|
+
});
|
|
44237
|
+
GPT56ConfigSchema = external_exports.object({
|
|
44238
|
+
model: external_exports.enum(["gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna"]),
|
|
44239
|
+
provider: external_exports.enum(["openai"]),
|
|
44240
|
+
apiKey: external_exports.string(),
|
|
44241
|
+
temperature: external_exports.literal(1).optional(),
|
|
44242
|
+
maxOutputTokens: external_exports.number().min(4e3).optional(),
|
|
44243
|
+
topP: external_exports.number().min(0).max(1).optional(),
|
|
44244
|
+
modelOptions: GPT56OptionsSchema.optional()
|
|
44245
|
+
});
|
|
44144
44246
|
MockConfigSchema = external_exports.object({
|
|
44145
44247
|
model: external_exports.enum(["mock"]),
|
|
44146
44248
|
provider: external_exports.enum(["mock"]),
|
|
@@ -44193,9 +44295,12 @@ var init_model_info = __esm({
|
|
|
44193
44295
|
AnthropicClaude5ConfigSchema,
|
|
44194
44296
|
AnthropicStandardConfigSchema
|
|
44195
44297
|
]);
|
|
44298
|
+
GPT56_CACHE_READ_RATE_MULTIPLIER = 0.1;
|
|
44299
|
+
CACHE_CREATION_RATE_MULTIPLIER = 1.25;
|
|
44196
44300
|
MODEL_INFO = {
|
|
44197
44301
|
// OpenAI GPT-5 (Reasoning Models)
|
|
44198
44302
|
"gpt-5": {
|
|
44303
|
+
provider: "openai",
|
|
44199
44304
|
inputCostPer1M: 125,
|
|
44200
44305
|
// $1.25 per 1M tokens
|
|
44201
44306
|
outputCostPer1M: 1e3,
|
|
@@ -44209,6 +44314,7 @@ var init_model_info = __esm({
|
|
|
44209
44314
|
configSchema: GPT5ConfigSchema
|
|
44210
44315
|
},
|
|
44211
44316
|
"gpt-5.4-mini": {
|
|
44317
|
+
provider: "openai",
|
|
44212
44318
|
inputCostPer1M: 75,
|
|
44213
44319
|
// $0.75 per 1M tokens
|
|
44214
44320
|
outputCostPer1M: 450,
|
|
@@ -44222,6 +44328,7 @@ var init_model_info = __esm({
|
|
|
44222
44328
|
configSchema: GPT5ConfigSchema
|
|
44223
44329
|
},
|
|
44224
44330
|
"gpt-5.4-nano": {
|
|
44331
|
+
provider: "openai",
|
|
44225
44332
|
inputCostPer1M: 20,
|
|
44226
44333
|
// $0.20 per 1M tokens
|
|
44227
44334
|
outputCostPer1M: 125,
|
|
@@ -44233,8 +44340,60 @@ var init_model_info = __esm({
|
|
|
44233
44340
|
category: "standard",
|
|
44234
44341
|
configSchema: GPT5ConfigSchema
|
|
44235
44342
|
},
|
|
44343
|
+
// OpenAI GPT-5.6 family (GA 2026-07-09). All three tiers share 1.05M context, 128K max output,
|
|
44344
|
+
// image input, tool use, structured outputs, and prompt caching -- they differ in reasoning depth
|
|
44345
|
+
// and price, not capability. The bare `gpt-5.6` alias is deliberately unregistered; see OpenAIModel.
|
|
44346
|
+
"gpt-5.6-sol": {
|
|
44347
|
+
provider: "openai",
|
|
44348
|
+
inputCostPer1M: 500,
|
|
44349
|
+
// $5.00 per 1M tokens
|
|
44350
|
+
outputCostPer1M: 3e3,
|
|
44351
|
+
// $30.00 per 1M tokens
|
|
44352
|
+
minTokens: 4e3,
|
|
44353
|
+
recommendedTokens: 8e3,
|
|
44354
|
+
maxTokens: 105e4,
|
|
44355
|
+
// 1.05M context window
|
|
44356
|
+
maxOutputTokens: 128e3,
|
|
44357
|
+
category: "reasoning",
|
|
44358
|
+
configSchema: GPT56ConfigSchema,
|
|
44359
|
+
cacheReadRateMultiplier: GPT56_CACHE_READ_RATE_MULTIPLIER,
|
|
44360
|
+
cacheCreationRateMultiplier: CACHE_CREATION_RATE_MULTIPLIER
|
|
44361
|
+
},
|
|
44362
|
+
"gpt-5.6-terra": {
|
|
44363
|
+
provider: "openai",
|
|
44364
|
+
inputCostPer1M: 250,
|
|
44365
|
+
// $2.50 per 1M tokens
|
|
44366
|
+
outputCostPer1M: 1500,
|
|
44367
|
+
// $15.00 per 1M tokens
|
|
44368
|
+
minTokens: 4e3,
|
|
44369
|
+
recommendedTokens: 8e3,
|
|
44370
|
+
maxTokens: 105e4,
|
|
44371
|
+
// 1.05M context window
|
|
44372
|
+
maxOutputTokens: 128e3,
|
|
44373
|
+
category: "standard",
|
|
44374
|
+
configSchema: GPT56ConfigSchema,
|
|
44375
|
+
cacheReadRateMultiplier: GPT56_CACHE_READ_RATE_MULTIPLIER,
|
|
44376
|
+
cacheCreationRateMultiplier: CACHE_CREATION_RATE_MULTIPLIER
|
|
44377
|
+
},
|
|
44378
|
+
"gpt-5.6-luna": {
|
|
44379
|
+
provider: "openai",
|
|
44380
|
+
inputCostPer1M: 100,
|
|
44381
|
+
// $1.00 per 1M tokens
|
|
44382
|
+
outputCostPer1M: 600,
|
|
44383
|
+
// $6.00 per 1M tokens
|
|
44384
|
+
minTokens: 4e3,
|
|
44385
|
+
recommendedTokens: 8e3,
|
|
44386
|
+
maxTokens: 105e4,
|
|
44387
|
+
// 1.05M context window
|
|
44388
|
+
maxOutputTokens: 128e3,
|
|
44389
|
+
category: "standard",
|
|
44390
|
+
configSchema: GPT56ConfigSchema,
|
|
44391
|
+
cacheReadRateMultiplier: GPT56_CACHE_READ_RATE_MULTIPLIER,
|
|
44392
|
+
cacheCreationRateMultiplier: CACHE_CREATION_RATE_MULTIPLIER
|
|
44393
|
+
},
|
|
44236
44394
|
// Mock model for testing
|
|
44237
44395
|
mock: {
|
|
44396
|
+
provider: "mock",
|
|
44238
44397
|
inputCostPer1M: 0,
|
|
44239
44398
|
// Free for tests
|
|
44240
44399
|
outputCostPer1M: 0,
|
|
@@ -44248,6 +44407,7 @@ var init_model_info = __esm({
|
|
|
44248
44407
|
},
|
|
44249
44408
|
// OpenRouter Models (via openrouter.ai)
|
|
44250
44409
|
"openrouter/z-ai/glm-5": {
|
|
44410
|
+
provider: "openrouter",
|
|
44251
44411
|
inputCostPer1M: 72,
|
|
44252
44412
|
// $0.72 per 1M tokens
|
|
44253
44413
|
outputCostPer1M: 230,
|
|
@@ -44261,6 +44421,7 @@ var init_model_info = __esm({
|
|
|
44261
44421
|
},
|
|
44262
44422
|
// Anthropic Claude Models (direct SDK access via @anthropic-ai/sdk)
|
|
44263
44423
|
"claude-opus-5": {
|
|
44424
|
+
provider: "anthropic",
|
|
44264
44425
|
inputCostPer1M: 500,
|
|
44265
44426
|
// $5.00 per 1M tokens
|
|
44266
44427
|
outputCostPer1M: 2500,
|
|
@@ -44274,6 +44435,7 @@ var init_model_info = __esm({
|
|
|
44274
44435
|
configSchema: AnthropicConfigSchema
|
|
44275
44436
|
},
|
|
44276
44437
|
"claude-sonnet-5": {
|
|
44438
|
+
provider: "anthropic",
|
|
44277
44439
|
// List pricing. An introductory rate of $2.00/$10.00 runs through 2026-08-31; encoding the
|
|
44278
44440
|
// temporary rate would make historical cost analytics wrong once it lapses.
|
|
44279
44441
|
inputCostPer1M: 300,
|
|
@@ -44289,6 +44451,7 @@ var init_model_info = __esm({
|
|
|
44289
44451
|
configSchema: AnthropicConfigSchema
|
|
44290
44452
|
},
|
|
44291
44453
|
"claude-haiku-4-5-20251001": {
|
|
44454
|
+
provider: "anthropic",
|
|
44292
44455
|
inputCostPer1M: 100,
|
|
44293
44456
|
// $1.00 per 1M tokens
|
|
44294
44457
|
outputCostPer1M: 500,
|
|
@@ -44302,6 +44465,7 @@ var init_model_info = __esm({
|
|
|
44302
44465
|
configSchema: AnthropicConfigSchema
|
|
44303
44466
|
},
|
|
44304
44467
|
"claude-haiku-4-5": {
|
|
44468
|
+
provider: "anthropic",
|
|
44305
44469
|
inputCostPer1M: 100,
|
|
44306
44470
|
// $1.00 per 1M tokens
|
|
44307
44471
|
outputCostPer1M: 500,
|
|
@@ -44690,6 +44854,138 @@ var init_response_schema = __esm({
|
|
|
44690
44854
|
}
|
|
44691
44855
|
});
|
|
44692
44856
|
|
|
44857
|
+
// ../core/src/execution/engine/workflow/types.ts
|
|
44858
|
+
var StepType;
|
|
44859
|
+
var init_types5 = __esm({
|
|
44860
|
+
"../core/src/execution/engine/workflow/types.ts"() {
|
|
44861
|
+
"use strict";
|
|
44862
|
+
StepType = {
|
|
44863
|
+
LINEAR: "linear",
|
|
44864
|
+
CONDITIONAL: "conditional"
|
|
44865
|
+
};
|
|
44866
|
+
}
|
|
44867
|
+
});
|
|
44868
|
+
|
|
44869
|
+
// ../core/src/execution/engine/workflow/errors.ts
|
|
44870
|
+
var WorkflowStepError, WorkflowValidationError;
|
|
44871
|
+
var init_errors5 = __esm({
|
|
44872
|
+
"../core/src/execution/engine/workflow/errors.ts"() {
|
|
44873
|
+
"use strict";
|
|
44874
|
+
init_errors3();
|
|
44875
|
+
WorkflowStepError = class extends ExecutionError {
|
|
44876
|
+
type = "workflow_step_error";
|
|
44877
|
+
severity = "critical";
|
|
44878
|
+
category = "workflow";
|
|
44879
|
+
/**
|
|
44880
|
+
* @param cause - The error the step actually threw. Kept so the original stack and any
|
|
44881
|
+
* non-`ExecutionError` throw survive the wrap; its classification is additionally copied into
|
|
44882
|
+
* `context` by the caller, because `type`/`severity`/`category` are fixed on this class.
|
|
44883
|
+
*/
|
|
44884
|
+
constructor(message, context, cause) {
|
|
44885
|
+
super(message, context);
|
|
44886
|
+
if (cause !== void 0) this.cause = cause;
|
|
44887
|
+
}
|
|
44888
|
+
};
|
|
44889
|
+
WorkflowValidationError = class extends ExecutionError {
|
|
44890
|
+
type = "workflow_validation_error";
|
|
44891
|
+
severity = "info";
|
|
44892
|
+
category = "validation";
|
|
44893
|
+
constructor(message, context) {
|
|
44894
|
+
super(message, context);
|
|
44895
|
+
}
|
|
44896
|
+
};
|
|
44897
|
+
}
|
|
44898
|
+
});
|
|
44899
|
+
|
|
44900
|
+
// ../core/src/execution/engine/workflow/utils.ts
|
|
44901
|
+
function validateEntryPoint(steps, entryPoint) {
|
|
44902
|
+
if (!(entryPoint in steps)) {
|
|
44903
|
+
throw new WorkflowValidationError(`Entry point step '${entryPoint}' not found in workflow`, {
|
|
44904
|
+
entryPoint
|
|
44905
|
+
});
|
|
44906
|
+
}
|
|
44907
|
+
}
|
|
44908
|
+
function findTerminalSteps(steps) {
|
|
44909
|
+
return Object.values(steps).filter((step) => step.next === null);
|
|
44910
|
+
}
|
|
44911
|
+
function validateTerminalSteps(steps, workflowId) {
|
|
44912
|
+
const terminalSteps = findTerminalSteps(steps);
|
|
44913
|
+
if (terminalSteps.length === 0) {
|
|
44914
|
+
throw new WorkflowValidationError(`Workflow '${workflowId}' must have at least one terminal step (next: null)`, {
|
|
44915
|
+
workflowId
|
|
44916
|
+
});
|
|
44917
|
+
}
|
|
44918
|
+
}
|
|
44919
|
+
function validateStepReferences(steps) {
|
|
44920
|
+
for (const [id, step] of Object.entries(steps)) {
|
|
44921
|
+
if (step.next === null) {
|
|
44922
|
+
continue;
|
|
44923
|
+
}
|
|
44924
|
+
if (step.next.type === StepType.LINEAR) {
|
|
44925
|
+
if (!(step.next.target in steps)) {
|
|
44926
|
+
throw new WorkflowValidationError(`Step '${id}' references non-existent target '${step.next.target}'`, {
|
|
44927
|
+
stepId: id,
|
|
44928
|
+
target: step.next.target
|
|
44929
|
+
});
|
|
44930
|
+
}
|
|
44931
|
+
} else if (step.next.type === StepType.CONDITIONAL) {
|
|
44932
|
+
const targets = [...step.next.routes.map((r) => r.target), step.next.default];
|
|
44933
|
+
for (const target of targets) {
|
|
44934
|
+
if (!(target in steps)) {
|
|
44935
|
+
throw new WorkflowValidationError(`Step '${id}' references non-existent target '${target}'`, {
|
|
44936
|
+
stepId: id,
|
|
44937
|
+
target
|
|
44938
|
+
});
|
|
44939
|
+
}
|
|
44940
|
+
}
|
|
44941
|
+
}
|
|
44942
|
+
}
|
|
44943
|
+
}
|
|
44944
|
+
function detectCycle(visited, executionPath, currentStepId) {
|
|
44945
|
+
if (visited.has(currentStepId)) {
|
|
44946
|
+
const cycle = executionPath.slice(executionPath.indexOf(currentStepId));
|
|
44947
|
+
throw new WorkflowStepError(`Cycle detected in workflow: ${cycle.join(" -> ")} -> ${currentStepId}`, {
|
|
44948
|
+
stepId: currentStepId,
|
|
44949
|
+
cycle: [...cycle, currentStepId]
|
|
44950
|
+
});
|
|
44951
|
+
}
|
|
44952
|
+
}
|
|
44953
|
+
function validateWorkflowGraph(steps, entryPoint, workflowId) {
|
|
44954
|
+
const onPath = /* @__PURE__ */ new Set();
|
|
44955
|
+
const executionPath = [];
|
|
44956
|
+
const reached = /* @__PURE__ */ new Set();
|
|
44957
|
+
const walk = (stepId) => {
|
|
44958
|
+
detectCycle(onPath, executionPath, stepId);
|
|
44959
|
+
onPath.add(stepId);
|
|
44960
|
+
executionPath.push(stepId);
|
|
44961
|
+
reached.add(stepId);
|
|
44962
|
+
const step = steps[stepId];
|
|
44963
|
+
if (step && step.next !== null) {
|
|
44964
|
+
const targets = step.next.type === StepType.LINEAR ? [step.next.target] : [...step.next.routes.map((route) => route.target), step.next.default];
|
|
44965
|
+
for (const target of targets) {
|
|
44966
|
+
if (target in steps) walk(target);
|
|
44967
|
+
}
|
|
44968
|
+
}
|
|
44969
|
+
executionPath.pop();
|
|
44970
|
+
onPath.delete(stepId);
|
|
44971
|
+
};
|
|
44972
|
+
if (entryPoint in steps) walk(entryPoint);
|
|
44973
|
+
const orphanIds = Object.keys(steps).filter((id) => !reached.has(id));
|
|
44974
|
+
if (orphanIds.length > 0) {
|
|
44975
|
+
throw new WorkflowValidationError(
|
|
44976
|
+
`Workflow '${workflowId}' has step(s) unreachable from entry point '${entryPoint}': ${orphanIds.join(", ")}`,
|
|
44977
|
+
{ workflowId, entryPoint, orphanIds }
|
|
44978
|
+
);
|
|
44979
|
+
}
|
|
44980
|
+
}
|
|
44981
|
+
var init_utils3 = __esm({
|
|
44982
|
+
"../core/src/execution/engine/workflow/utils.ts"() {
|
|
44983
|
+
"use strict";
|
|
44984
|
+
init_types5();
|
|
44985
|
+
init_errors5();
|
|
44986
|
+
}
|
|
44987
|
+
});
|
|
44988
|
+
|
|
44693
44989
|
// ../core/src/platform/registry/validation.ts
|
|
44694
44990
|
function getResourceValidatorMode(explicitMode) {
|
|
44695
44991
|
if (explicitMode) return explicitMode;
|
|
@@ -44708,7 +45004,14 @@ function emitGovernanceIssues(issues, mode, onWarning) {
|
|
|
44708
45004
|
if (issues.length === 0) return;
|
|
44709
45005
|
if (mode === "strict") {
|
|
44710
45006
|
const first = issues[0];
|
|
44711
|
-
|
|
45007
|
+
const messages = issues.map((issue2) => issue2.message);
|
|
45008
|
+
throw new RegistryValidationError(
|
|
45009
|
+
first.orgName,
|
|
45010
|
+
first.resourceId,
|
|
45011
|
+
"organizationModel.resources",
|
|
45012
|
+
messages.join("\n"),
|
|
45013
|
+
messages
|
|
45014
|
+
);
|
|
44712
45015
|
}
|
|
44713
45016
|
const warn2 = onWarning ?? ((issue2) => console.warn(issue2.message));
|
|
44714
45017
|
for (const issue2 of issues) {
|
|
@@ -44869,7 +45172,7 @@ function addTopologyIssues(issues, orgName, deployment, organizationModel, syste
|
|
|
44869
45172
|
if (ref.kind === "humanCheckpoint") return humanCheckpointIds.has(ref.id);
|
|
44870
45173
|
if (ref.kind === "externalResource") return externalResourceIds.has(ref.id);
|
|
44871
45174
|
if (ref.kind === "ontology") {
|
|
44872
|
-
if (ontologyIndex === void 0) return
|
|
45175
|
+
if (ontologyIndex === void 0) return false;
|
|
44873
45176
|
return Object.values(ontologyIndex).some((records) => records[ref.id] !== void 0);
|
|
44874
45177
|
}
|
|
44875
45178
|
return false;
|
|
@@ -45034,7 +45337,7 @@ function detectMissingApiInterfaceDeclarations(orgName, organizationModel) {
|
|
|
45034
45337
|
for (const resource of Object.values(organizationModel.resources ?? {})) {
|
|
45035
45338
|
const ontology = resource.ontology;
|
|
45036
45339
|
if (ontology === void 0) continue;
|
|
45037
|
-
const hasOntologyBindings = ontology.actions !== void 0 && ontology.actions.length > 0 || ontology.writes !== void 0 && ontology.writes.length > 0;
|
|
45340
|
+
const hasOntologyBindings = ontology.actions !== void 0 && ontology.actions.length > 0 || ontology.writes !== void 0 && ontology.writes.length > 0 || ontology.reads !== void 0 && ontology.reads.length > 0 || ontology.usesCatalogs !== void 0 && ontology.usesCatalogs.length > 0;
|
|
45038
45341
|
if (!hasOntologyBindings) continue;
|
|
45039
45342
|
const existing = apiBoundResourcesBySystemPath.get(resource.systemPath);
|
|
45040
45343
|
if (existing) {
|
|
@@ -45059,25 +45362,23 @@ function detectMissingApiInterfaceDeclarations(orgName, organizationModel) {
|
|
|
45059
45362
|
}
|
|
45060
45363
|
return gaps;
|
|
45061
45364
|
}
|
|
45062
|
-
function validateDeclaredSystemInterfaceReadiness(orgName, organizationModel) {
|
|
45365
|
+
function validateDeclaredSystemInterfaceReadiness(orgName, organizationModel, options = {}) {
|
|
45366
|
+
const mode = getResourceValidatorMode(options.mode);
|
|
45063
45367
|
const issues = [];
|
|
45064
45368
|
if (organizationModel === void 0) return { valid: true, issues };
|
|
45065
45369
|
const model = organizationModel;
|
|
45066
45370
|
for (const { path: path3, system } of listAllSystems(model)) {
|
|
45067
45371
|
if (system.apiInterface === void 0) continue;
|
|
45068
45372
|
const interfaceKey = "api";
|
|
45069
|
-
const
|
|
45070
|
-
if (
|
|
45071
|
-
|
|
45072
|
-
|
|
45073
|
-
|
|
45074
|
-
|
|
45075
|
-
|
|
45076
|
-
|
|
45077
|
-
|
|
45078
|
-
message: `System Interface "${path3}/${interfaceKey}" references unknown readiness profile "${readinessProfile}".`
|
|
45079
|
-
});
|
|
45080
|
-
}
|
|
45373
|
+
const readinessProfile = system.apiInterface.readinessProfile;
|
|
45374
|
+
if (readinessProfile !== void 0 && !SYSTEM_INTERFACE_PROFILES.some((profile) => profile.readinessProfile === readinessProfile)) {
|
|
45375
|
+
addSystemInterfaceIssue(issues, orgName, path3, interfaceKey, {
|
|
45376
|
+
family: "SYSTEM_INTERFACE_INVALID",
|
|
45377
|
+
code: "unknown-readiness-profile",
|
|
45378
|
+
path: `systems.${path3}.apiInterface.readinessProfile`,
|
|
45379
|
+
ref: readinessProfile,
|
|
45380
|
+
message: `System Interface "${path3}/${interfaceKey}" references unknown readiness profile "${readinessProfile}".`
|
|
45381
|
+
});
|
|
45081
45382
|
}
|
|
45082
45383
|
const result = computeInterfaceReadiness(model, { systemPath: path3, interfaceKey });
|
|
45083
45384
|
for (const issue2 of result.issues) {
|
|
@@ -45085,17 +45386,27 @@ function validateDeclaredSystemInterfaceReadiness(orgName, organizationModel) {
|
|
|
45085
45386
|
}
|
|
45086
45387
|
}
|
|
45087
45388
|
if (issues.length > 0) {
|
|
45088
|
-
|
|
45089
|
-
|
|
45090
|
-
|
|
45091
|
-
|
|
45092
|
-
|
|
45093
|
-
|
|
45094
|
-
|
|
45389
|
+
if (mode === "strict") {
|
|
45390
|
+
const first = issues[0];
|
|
45391
|
+
const messages = issues.map((issue2) => issue2.message);
|
|
45392
|
+
throw new RegistryValidationError(
|
|
45393
|
+
first.orgName,
|
|
45394
|
+
`${first.systemPath}/${first.interfaceKey}`,
|
|
45395
|
+
first.path ?? "organizationModel.systems.apiInterface",
|
|
45396
|
+
messages.join("\n"),
|
|
45397
|
+
messages
|
|
45398
|
+
);
|
|
45399
|
+
}
|
|
45400
|
+
const warn2 = options.onWarning ?? ((issue2) => console.warn(issue2.message));
|
|
45401
|
+
for (const issue2 of issues) {
|
|
45402
|
+
warn2(issue2);
|
|
45403
|
+
}
|
|
45404
|
+
return { valid: false, issues };
|
|
45095
45405
|
}
|
|
45096
45406
|
return { valid: true, issues };
|
|
45097
45407
|
}
|
|
45098
|
-
function validateDeploymentSpec(orgName, resources) {
|
|
45408
|
+
function validateDeploymentSpec(orgName, resources, options = {}) {
|
|
45409
|
+
const warn2 = options.onWarning ?? ((message) => console.warn(message));
|
|
45099
45410
|
const seenIds = /* @__PURE__ */ new Set();
|
|
45100
45411
|
resources.workflows?.forEach((workflow) => {
|
|
45101
45412
|
const id = workflow.config.resourceId;
|
|
@@ -45114,6 +45425,14 @@ function validateDeploymentSpec(orgName, resources) {
|
|
|
45114
45425
|
if (workflow.interface) {
|
|
45115
45426
|
validateExecutionInterface(orgName, id, workflow.interface, workflow.contract.inputSchema);
|
|
45116
45427
|
}
|
|
45428
|
+
try {
|
|
45429
|
+
validateEntryPoint(workflow.steps, workflow.entryPoint);
|
|
45430
|
+
validateTerminalSteps(workflow.steps, id);
|
|
45431
|
+
validateStepReferences(workflow.steps);
|
|
45432
|
+
validateWorkflowGraph(workflow.steps, workflow.entryPoint, id);
|
|
45433
|
+
} catch (error46) {
|
|
45434
|
+
warn2(`[${orgName}] Workflow '${id}' graph validation: ${error46 instanceof Error ? error46.message : String(error46)}`);
|
|
45435
|
+
}
|
|
45117
45436
|
});
|
|
45118
45437
|
resources.agents?.forEach((agent) => {
|
|
45119
45438
|
const id = agent.config.resourceId;
|
|
@@ -45127,14 +45446,20 @@ function validateDeploymentSpec(orgName, resources) {
|
|
|
45127
45446
|
}
|
|
45128
45447
|
seenIds.add(id);
|
|
45129
45448
|
validateResourceModelConfig(orgName, id, agent.modelConfig);
|
|
45130
|
-
validateAgentGrammar(orgName, id, agent);
|
|
45131
|
-
validateAgentCheapAssertions(orgName, id, agent);
|
|
45449
|
+
validateAgentGrammar(orgName, id, agent, options.mode);
|
|
45450
|
+
validateAgentCheapAssertions(orgName, id, agent, options.mode);
|
|
45132
45451
|
if (agent.interface) {
|
|
45133
45452
|
validateExecutionInterface(orgName, id, agent.interface, agent.contract.inputSchema);
|
|
45134
45453
|
}
|
|
45135
45454
|
});
|
|
45136
|
-
validateResourceGovernance(orgName, resources
|
|
45137
|
-
|
|
45455
|
+
validateResourceGovernance(orgName, resources, void 0, {
|
|
45456
|
+
mode: options.mode,
|
|
45457
|
+
onWarning: (issue2) => warn2(issue2.message)
|
|
45458
|
+
});
|
|
45459
|
+
validateDeclaredSystemInterfaceReadiness(orgName, resources.organizationModel, {
|
|
45460
|
+
mode: options.mode,
|
|
45461
|
+
onWarning: (issue2) => warn2(issue2.message)
|
|
45462
|
+
});
|
|
45138
45463
|
}
|
|
45139
45464
|
function validateResourceModelConfig(orgName, resourceId, modelConfig) {
|
|
45140
45465
|
try {
|
|
@@ -45209,7 +45534,7 @@ function describeGrammarRefusal(reasons, toolInputSchema) {
|
|
|
45209
45534
|
}
|
|
45210
45535
|
return `refused strict mode: ${reasons.join(", ")}`;
|
|
45211
45536
|
}
|
|
45212
|
-
function validateAgentGrammar(orgName, agentId, agent) {
|
|
45537
|
+
function validateAgentGrammar(orgName, agentId, agent, mode) {
|
|
45213
45538
|
const dialect = dialectForProvider(agent.modelConfig.provider);
|
|
45214
45539
|
if (!dialect) return;
|
|
45215
45540
|
const capabilities = agentCapabilitiesForGrammarCheck(agent.config);
|
|
@@ -45230,12 +45555,12 @@ function validateAgentGrammar(orgName, agentId, agent) {
|
|
|
45230
45555
|
compileSchema(offending.inputSchema, dialect).refusalReasons,
|
|
45231
45556
|
offending.inputSchema
|
|
45232
45557
|
)}. 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).`;
|
|
45233
|
-
if (getResourceValidatorMode() === "strict") {
|
|
45558
|
+
if (getResourceValidatorMode(mode) === "strict") {
|
|
45234
45559
|
throw new RegistryValidationError(orgName, agentId, "tools", message);
|
|
45235
45560
|
}
|
|
45236
45561
|
console.warn(message);
|
|
45237
45562
|
}
|
|
45238
|
-
function validateAgentCheapAssertions(orgName, agentId, agent) {
|
|
45563
|
+
function validateAgentCheapAssertions(orgName, agentId, agent, mode) {
|
|
45239
45564
|
const issues = [];
|
|
45240
45565
|
const config3 = agent.config;
|
|
45241
45566
|
if (config3.sessionCapable && config3.securityLevel === "none") {
|
|
@@ -45265,7 +45590,7 @@ function validateAgentCheapAssertions(orgName, agentId, agent) {
|
|
|
45265
45590
|
}
|
|
45266
45591
|
if (issues.length === 0) return;
|
|
45267
45592
|
const message = `[${orgName}] Agent '${agentId}': ${issues.join(" ")}`;
|
|
45268
|
-
if (getResourceValidatorMode() === "strict") {
|
|
45593
|
+
if (getResourceValidatorMode(mode) === "strict") {
|
|
45269
45594
|
throw new RegistryValidationError(orgName, agentId, "config", message);
|
|
45270
45595
|
}
|
|
45271
45596
|
console.warn(message);
|
|
@@ -45532,34 +45857,24 @@ var init_validation2 = __esm({
|
|
|
45532
45857
|
init_compile();
|
|
45533
45858
|
init_dialect();
|
|
45534
45859
|
init_response_schema();
|
|
45860
|
+
init_utils3();
|
|
45535
45861
|
init_helpers();
|
|
45536
45862
|
init_ontology();
|
|
45537
45863
|
init_readiness();
|
|
45538
45864
|
init_systems();
|
|
45539
45865
|
RegistryValidationError = class extends Error {
|
|
45540
|
-
constructor(orgName, resourceId, field2, message) {
|
|
45866
|
+
constructor(orgName, resourceId, field2, message, issues) {
|
|
45541
45867
|
super(message);
|
|
45542
45868
|
this.orgName = orgName;
|
|
45543
45869
|
this.resourceId = resourceId;
|
|
45544
45870
|
this.field = field2;
|
|
45871
|
+
this.issues = issues;
|
|
45545
45872
|
this.name = "RegistryValidationError";
|
|
45546
45873
|
}
|
|
45547
45874
|
};
|
|
45548
45875
|
}
|
|
45549
45876
|
});
|
|
45550
45877
|
|
|
45551
|
-
// ../core/src/execution/engine/workflow/types.ts
|
|
45552
|
-
var StepType;
|
|
45553
|
-
var init_types5 = __esm({
|
|
45554
|
-
"../core/src/execution/engine/workflow/types.ts"() {
|
|
45555
|
-
"use strict";
|
|
45556
|
-
StepType = {
|
|
45557
|
-
LINEAR: "linear",
|
|
45558
|
-
CONDITIONAL: "conditional"
|
|
45559
|
-
};
|
|
45560
|
-
}
|
|
45561
|
-
});
|
|
45562
|
-
|
|
45563
45878
|
// ../core/src/execution/engine/base/serialization.ts
|
|
45564
45879
|
function serializeDefinition(definition, options) {
|
|
45565
45880
|
const opts = {
|
|
@@ -47295,7 +47610,7 @@ var init_croner = __esm({
|
|
|
47295
47610
|
});
|
|
47296
47611
|
|
|
47297
47612
|
// ../core/src/execution/scheduler/utils.ts
|
|
47298
|
-
var
|
|
47613
|
+
var init_utils4 = __esm({
|
|
47299
47614
|
"../core/src/execution/scheduler/utils.ts"() {
|
|
47300
47615
|
"use strict";
|
|
47301
47616
|
init_esm2();
|
|
@@ -47309,7 +47624,7 @@ var init_scheduler = __esm({
|
|
|
47309
47624
|
"use strict";
|
|
47310
47625
|
init_types8();
|
|
47311
47626
|
init_schemas3();
|
|
47312
|
-
|
|
47627
|
+
init_utils4();
|
|
47313
47628
|
}
|
|
47314
47629
|
});
|
|
47315
47630
|
|
|
@@ -47404,6 +47719,13 @@ var init_clickup = __esm({
|
|
|
47404
47719
|
}
|
|
47405
47720
|
});
|
|
47406
47721
|
|
|
47722
|
+
// ../core/src/execution/engine/tools/integration/types/instagram.ts
|
|
47723
|
+
var init_instagram = __esm({
|
|
47724
|
+
"../core/src/execution/engine/tools/integration/types/instagram.ts"() {
|
|
47725
|
+
"use strict";
|
|
47726
|
+
}
|
|
47727
|
+
});
|
|
47728
|
+
|
|
47407
47729
|
// ../core/src/execution/engine/tools/integration/types/index.ts
|
|
47408
47730
|
var init_types9 = __esm({
|
|
47409
47731
|
"../core/src/execution/engine/tools/integration/types/index.ts"() {
|
|
@@ -47421,6 +47743,7 @@ var init_types9 = __esm({
|
|
|
47421
47743
|
init_tomba();
|
|
47422
47744
|
init_millionverifier();
|
|
47423
47745
|
init_clickup();
|
|
47746
|
+
init_instagram();
|
|
47424
47747
|
}
|
|
47425
47748
|
});
|
|
47426
47749
|
|
|
@@ -47702,7 +48025,7 @@ var init_schemas6 = __esm({
|
|
|
47702
48025
|
});
|
|
47703
48026
|
|
|
47704
48027
|
// ../core/src/operations/observability/utils.ts
|
|
47705
|
-
var
|
|
48028
|
+
var init_utils5 = __esm({
|
|
47706
48029
|
"../core/src/operations/observability/utils.ts"() {
|
|
47707
48030
|
"use strict";
|
|
47708
48031
|
}
|
|
@@ -47714,7 +48037,7 @@ var init_observability = __esm({
|
|
|
47714
48037
|
"use strict";
|
|
47715
48038
|
init_types13();
|
|
47716
48039
|
init_schemas6();
|
|
47717
|
-
|
|
48040
|
+
init_utils5();
|
|
47718
48041
|
}
|
|
47719
48042
|
});
|
|
47720
48043
|
|
|
@@ -48514,7 +48837,14 @@ var init_api_schemas5 = __esm({
|
|
|
48514
48837
|
"use strict";
|
|
48515
48838
|
init_zod();
|
|
48516
48839
|
init_validation();
|
|
48517
|
-
CredentialTypeSchema = external_exports.enum([
|
|
48840
|
+
CredentialTypeSchema = external_exports.enum([
|
|
48841
|
+
"oauth",
|
|
48842
|
+
"api-key",
|
|
48843
|
+
"webhook-secret",
|
|
48844
|
+
"api-key-secret",
|
|
48845
|
+
"clickup",
|
|
48846
|
+
"instagram"
|
|
48847
|
+
]);
|
|
48518
48848
|
CredentialValueSchema = external_exports.record(external_exports.string(), external_exports.unknown()).refine((val) => Object.keys(val).length > 0, { message: "Credential value must not be empty" }).refine((val) => Object.keys(val).length <= 50, { message: "Credential value has too many keys (max 50)" }).refine(
|
|
48519
48849
|
(val) => {
|
|
48520
48850
|
for (const v of Object.values(val)) {
|
|
@@ -48582,6 +48912,21 @@ var init_credentials2 = __esm({
|
|
|
48582
48912
|
}
|
|
48583
48913
|
});
|
|
48584
48914
|
|
|
48915
|
+
// ../core/src/integrations/cloud-storage/types.ts
|
|
48916
|
+
var init_types20 = __esm({
|
|
48917
|
+
"../core/src/integrations/cloud-storage/types.ts"() {
|
|
48918
|
+
"use strict";
|
|
48919
|
+
}
|
|
48920
|
+
});
|
|
48921
|
+
|
|
48922
|
+
// ../core/src/integrations/cloud-storage/index.ts
|
|
48923
|
+
var init_cloud_storage = __esm({
|
|
48924
|
+
"../core/src/integrations/cloud-storage/index.ts"() {
|
|
48925
|
+
"use strict";
|
|
48926
|
+
init_types20();
|
|
48927
|
+
}
|
|
48928
|
+
});
|
|
48929
|
+
|
|
48585
48930
|
// ../core/src/index.ts
|
|
48586
48931
|
var init_src = __esm({
|
|
48587
48932
|
"../core/src/index.ts"() {
|
|
@@ -48598,6 +48943,7 @@ var init_src = __esm({
|
|
|
48598
48943
|
init_forms();
|
|
48599
48944
|
init_oauth();
|
|
48600
48945
|
init_credentials2();
|
|
48946
|
+
init_cloud_storage();
|
|
48601
48947
|
}
|
|
48602
48948
|
});
|
|
48603
48949
|
|
|
@@ -48654,6 +49000,12 @@ function resolveApiKey(prod) {
|
|
|
48654
49000
|
}
|
|
48655
49001
|
return process.env.ELEVASIS_PLATFORM_KEY ?? "";
|
|
48656
49002
|
}
|
|
49003
|
+
function isProdApiUrl(apiUrl) {
|
|
49004
|
+
return !apiUrl.includes("localhost");
|
|
49005
|
+
}
|
|
49006
|
+
function resolveApiKeyForUrl(apiUrl) {
|
|
49007
|
+
return resolveApiKey(isProdApiUrl(apiUrl));
|
|
49008
|
+
}
|
|
48657
49009
|
function tryFindProjectRoot(startDir) {
|
|
48658
49010
|
const raw = (0, import_path.resolve)(startDir);
|
|
48659
49011
|
let dir;
|
|
@@ -48738,12 +49090,89 @@ var init_config2 = __esm({
|
|
|
48738
49090
|
}
|
|
48739
49091
|
});
|
|
48740
49092
|
|
|
49093
|
+
// src/cli/readiness-failure.ts
|
|
49094
|
+
function isReadinessFailureDetails(details) {
|
|
49095
|
+
if (!details || typeof details !== "object") return false;
|
|
49096
|
+
const candidate = details;
|
|
49097
|
+
return typeof candidate.systemPath === "string" && typeof candidate.interfaceKey === "string" && // Deliberately `string`, not a check against the known families. Narrowing
|
|
49098
|
+
// it here would reject a readiness refusal carrying a family this build has
|
|
49099
|
+
// not learned yet, and `request()` would fall through to the gateway
|
|
49100
|
+
// message -- which tells the operator the API did not reject the request and
|
|
49101
|
+
// it may still be running server-side. That is false for every readiness
|
|
49102
|
+
// refusal, familiar family or not. An unrecognized code is handled where it
|
|
49103
|
+
// can be handled honestly, in `guidanceForFamily`.
|
|
49104
|
+
typeof candidate.readinessCode === "string" && Array.isArray(candidate.issues);
|
|
49105
|
+
}
|
|
49106
|
+
function parseReadinessFailureDetails(errorText) {
|
|
49107
|
+
let parsed;
|
|
49108
|
+
try {
|
|
49109
|
+
parsed = JSON.parse(errorText);
|
|
49110
|
+
} catch {
|
|
49111
|
+
return void 0;
|
|
49112
|
+
}
|
|
49113
|
+
if (parsed.code !== "SERVICE_UNAVAILABLE") return void 0;
|
|
49114
|
+
return isReadinessFailureDetails(parsed.details) ? parsed.details : void 0;
|
|
49115
|
+
}
|
|
49116
|
+
function formatIssue(issue2) {
|
|
49117
|
+
let line = ` - [${issue2.code}] ${issue2.message}`;
|
|
49118
|
+
if (issue2.path) line += ` (path: ${issue2.path})`;
|
|
49119
|
+
if (issue2.ref) line += ` (ref: ${issue2.ref})`;
|
|
49120
|
+
return line;
|
|
49121
|
+
}
|
|
49122
|
+
function describeUnknownFamily(readinessCode) {
|
|
49123
|
+
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.
|
|
49124
|
+
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.`;
|
|
49125
|
+
}
|
|
49126
|
+
function guidanceForFamily(details) {
|
|
49127
|
+
const lookup = FAMILY_GUIDANCE;
|
|
49128
|
+
return lookup[details.readinessCode]?.(details) ?? describeUnknownFamily(details.readinessCode);
|
|
49129
|
+
}
|
|
49130
|
+
function describeReadinessFailure(details, endpoint) {
|
|
49131
|
+
const profileSuffix = details.readinessProfile ? ` (readiness profile: ${details.readinessProfile})` : "";
|
|
49132
|
+
const lines = [
|
|
49133
|
+
`API request refused (503): ${details.systemPath}/${details.interfaceKey} is not ready for this API surface${profileSuffix}.`,
|
|
49134
|
+
`This IS the API rejecting the request -- it is not a gateway hiccup, and re-running it will not help.`,
|
|
49135
|
+
` Endpoint: ${endpoint}`,
|
|
49136
|
+
""
|
|
49137
|
+
];
|
|
49138
|
+
lines.push(
|
|
49139
|
+
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)
|
|
49140
|
+
);
|
|
49141
|
+
if (details.issues.length > 0) {
|
|
49142
|
+
lines.push("", " Issues:", ...details.issues.map(formatIssue));
|
|
49143
|
+
}
|
|
49144
|
+
lines.push("", ` Run 'elevasis-sdk doctor' to see what else is not ready.`);
|
|
49145
|
+
return lines.join("\n");
|
|
49146
|
+
}
|
|
49147
|
+
var FAMILY_GUIDANCE;
|
|
49148
|
+
var init_readiness_failure = __esm({
|
|
49149
|
+
"src/cli/readiness-failure.ts"() {
|
|
49150
|
+
"use strict";
|
|
49151
|
+
FAMILY_GUIDANCE = {
|
|
49152
|
+
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).
|
|
49153
|
+
Known trap: an empty apiInterface.resourceIds throws -- omit the apiInterface block entirely for the supported opt-out.`,
|
|
49154
|
+
SYSTEM_INTERFACE_DISABLED: ({ systemPath }) => `The "${systemPath}" System declares an apiInterface but it is not active. Re-enable it (apiInterface.lifecycle: 'active') and redeploy.`,
|
|
49155
|
+
// Two failures share this family and they need opposite advice.
|
|
49156
|
+
//
|
|
49157
|
+
// A validator that rejected a declaration emits a `path`, and pointing at it
|
|
49158
|
+
// is the whole fix. A stored snapshot that would not parse emits no `path` --
|
|
49159
|
+
// the API sets `ref` (a deployment or organization id) and never `path` --
|
|
49160
|
+
// and the broken thing is the deployed copy, not the source the operator
|
|
49161
|
+
// would go and edit. Sending them after a "path" that is not in the payload,
|
|
49162
|
+
// to fix a declaration that may be perfectly fine, was the failure this
|
|
49163
|
+
// wording had before.
|
|
49164
|
+
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.`,
|
|
49165
|
+
SYSTEM_INTERFACE_NOT_READY: ({ systemPath }) => `The "${systemPath}" System's readinessContract is unsatisfied. See the issues below for the missing requiredObjects / requiredCatalogs refs.`,
|
|
49166
|
+
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.`
|
|
49167
|
+
};
|
|
49168
|
+
}
|
|
49169
|
+
});
|
|
49170
|
+
|
|
48741
49171
|
// src/cli/api-client.ts
|
|
48742
49172
|
function getApiKey(apiUrl) {
|
|
48743
|
-
const
|
|
48744
|
-
const key = resolveApiKey(isProd);
|
|
49173
|
+
const key = resolveApiKeyForUrl(apiUrl);
|
|
48745
49174
|
if (!key) {
|
|
48746
|
-
const varName =
|
|
49175
|
+
const varName = isProdApiUrl(apiUrl) ? "ELEVASIS_PLATFORM_KEY" : "ELEVASIS_PLATFORM_KEY_DEV";
|
|
48747
49176
|
throw new Error(`${varName} environment variable is required.
|
|
48748
49177
|
Set it in your .env file: ${varName}=sk_...`);
|
|
48749
49178
|
}
|
|
@@ -48805,6 +49234,10 @@ async function request(method, endpoint, apiUrl, body) {
|
|
|
48805
49234
|
if (response.status === 401) {
|
|
48806
49235
|
throw new Error(`401 Unauthorized: Invalid or missing ELEVASIS_PLATFORM_KEY. Check your .env file.`);
|
|
48807
49236
|
}
|
|
49237
|
+
const readinessDetails = parseReadinessFailureDetails(errorText);
|
|
49238
|
+
if (readinessDetails) {
|
|
49239
|
+
throw new Error(describeReadinessFailure(readinessDetails, endpoint));
|
|
49240
|
+
}
|
|
48808
49241
|
if (GATEWAY_STATUSES.has(response.status)) {
|
|
48809
49242
|
throw new Error(describeGatewayFailure(response.status, endpoint, elapsedMs));
|
|
48810
49243
|
}
|
|
@@ -48832,6 +49265,7 @@ var init_api_client = __esm({
|
|
|
48832
49265
|
"src/cli/api-client.ts"() {
|
|
48833
49266
|
"use strict";
|
|
48834
49267
|
init_config2();
|
|
49268
|
+
init_readiness_failure();
|
|
48835
49269
|
DEFAULT_TIMEOUT_MS = 2 * 60 * 60 * 1e3;
|
|
48836
49270
|
GATEWAY_STATUSES = /* @__PURE__ */ new Set([502, 503, 504]);
|
|
48837
49271
|
}
|
|
@@ -48864,7 +49298,7 @@ var init_package = __esm({
|
|
|
48864
49298
|
"package.json"() {
|
|
48865
49299
|
package_default = {
|
|
48866
49300
|
name: "@elevasis/sdk",
|
|
48867
|
-
version: "1.
|
|
49301
|
+
version: "1.50.0",
|
|
48868
49302
|
description: "SDK for building Elevasis organization resources",
|
|
48869
49303
|
type: "module",
|
|
48870
49304
|
bin: {
|
|
@@ -48896,6 +49330,7 @@ var init_package = __esm({
|
|
|
48896
49330
|
"dist/test-utils/index.js",
|
|
48897
49331
|
"dist/test-utils/index.d.ts",
|
|
48898
49332
|
"dist/node/",
|
|
49333
|
+
"dist/chunk-*.js",
|
|
48899
49334
|
"dist/cli.cjs",
|
|
48900
49335
|
"reference/"
|
|
48901
49336
|
],
|
|
@@ -48915,8 +49350,14 @@ var init_package = __esm({
|
|
|
48915
49350
|
"remark-gfm": "^4.0.1"
|
|
48916
49351
|
},
|
|
48917
49352
|
peerDependencies: {
|
|
49353
|
+
vitest: ">=3",
|
|
48918
49354
|
zod: "^4.1.0"
|
|
48919
49355
|
},
|
|
49356
|
+
peerDependenciesMeta: {
|
|
49357
|
+
vitest: {
|
|
49358
|
+
optional: true
|
|
49359
|
+
}
|
|
49360
|
+
},
|
|
48920
49361
|
devDependencies: {
|
|
48921
49362
|
"@repo/core": "workspace:*",
|
|
48922
49363
|
"@repo/eslint-config": "workspace:*",
|
|
@@ -48931,6 +49372,7 @@ var init_package = __esm({
|
|
|
48931
49372
|
"rollup-plugin-dts": "^6.3.0",
|
|
48932
49373
|
tsup: "^8.0.0",
|
|
48933
49374
|
typescript: "5.9.2",
|
|
49375
|
+
vitest: "^3.2.4",
|
|
48934
49376
|
zod: "^4.1.0"
|
|
48935
49377
|
}
|
|
48936
49378
|
};
|
|
@@ -49069,7 +49511,15 @@ function extractResourceMetadata(resource, schemaWarnings) {
|
|
|
49069
49511
|
return meta;
|
|
49070
49512
|
}
|
|
49071
49513
|
function bumpVersion(current, type) {
|
|
49072
|
-
const
|
|
49514
|
+
const match = PLAIN_SEMVER_RE.exec(current);
|
|
49515
|
+
if (!match) {
|
|
49516
|
+
throw new Error(
|
|
49517
|
+
`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.`
|
|
49518
|
+
);
|
|
49519
|
+
}
|
|
49520
|
+
const major = Number(match[1]);
|
|
49521
|
+
const minor = Number(match[2]);
|
|
49522
|
+
const patch = Number(match[3]);
|
|
49073
49523
|
switch (type) {
|
|
49074
49524
|
case "major":
|
|
49075
49525
|
return `${major + 1}.0.0`;
|
|
@@ -49080,36 +49530,55 @@ function bumpVersion(current, type) {
|
|
|
49080
49530
|
}
|
|
49081
49531
|
}
|
|
49082
49532
|
function updateDeploymentVersionSource(source, newVersion) {
|
|
49083
|
-
|
|
49533
|
+
const exportIndex = source.indexOf("export default");
|
|
49534
|
+
if (exportIndex === -1) {
|
|
49535
|
+
throw new Error('Unable to find "export default" in the deployment entry file');
|
|
49536
|
+
}
|
|
49537
|
+
const rootBraceIndex = source.indexOf("{", exportIndex);
|
|
49538
|
+
if (rootBraceIndex === -1) {
|
|
49539
|
+
throw new Error("Unable to find the default-exported object in the deployment entry file");
|
|
49540
|
+
}
|
|
49541
|
+
let depth = 0;
|
|
49542
|
+
let offset = rootBraceIndex;
|
|
49084
49543
|
while (offset < source.length) {
|
|
49085
|
-
const
|
|
49086
|
-
if (
|
|
49087
|
-
|
|
49088
|
-
|
|
49089
|
-
const isIdentifierBoundary = (before === void 0 || !/[A-Za-z0-9_$]/.test(before)) && (after === void 0 || !/[A-Za-z0-9_$]/.test(after));
|
|
49090
|
-
if (!isIdentifierBoundary) {
|
|
49091
|
-
offset = keyIndex + "version".length;
|
|
49544
|
+
const char = source[offset];
|
|
49545
|
+
if (char === "{" || char === "[" || char === "(") {
|
|
49546
|
+
depth += 1;
|
|
49547
|
+
offset += 1;
|
|
49092
49548
|
continue;
|
|
49093
49549
|
}
|
|
49094
|
-
|
|
49095
|
-
|
|
49096
|
-
|
|
49097
|
-
|
|
49550
|
+
if (char === "}" || char === "]" || char === ")") {
|
|
49551
|
+
depth -= 1;
|
|
49552
|
+
offset += 1;
|
|
49553
|
+
if (depth === 0) break;
|
|
49098
49554
|
continue;
|
|
49099
49555
|
}
|
|
49100
|
-
|
|
49101
|
-
|
|
49102
|
-
|
|
49103
|
-
|
|
49104
|
-
|
|
49105
|
-
|
|
49556
|
+
if (depth === 1 && char === "v" && source.startsWith("version", offset)) {
|
|
49557
|
+
const before = source[offset - 1];
|
|
49558
|
+
const after = source[offset + "version".length];
|
|
49559
|
+
const isIdentifierBoundary = (before === void 0 || !/[A-Za-z0-9_$]/.test(before)) && (after === void 0 || !/[A-Za-z0-9_$]/.test(after));
|
|
49560
|
+
if (isIdentifierBoundary) {
|
|
49561
|
+
let cursor = offset + "version".length;
|
|
49562
|
+
while (/\s/.test(source[cursor] ?? "")) cursor += 1;
|
|
49563
|
+
if (source[cursor] === ":") {
|
|
49564
|
+
cursor += 1;
|
|
49565
|
+
while (/\s/.test(source[cursor] ?? "")) cursor += 1;
|
|
49566
|
+
const quote = source[cursor];
|
|
49567
|
+
if (quote === "'" || quote === '"') {
|
|
49568
|
+
const valueStart = cursor + 1;
|
|
49569
|
+
const valueEnd = source.indexOf(quote, valueStart);
|
|
49570
|
+
if (valueEnd !== -1) {
|
|
49571
|
+
return `${source.slice(0, valueStart)}${newVersion}${source.slice(valueEnd)}`;
|
|
49572
|
+
}
|
|
49573
|
+
}
|
|
49574
|
+
}
|
|
49575
|
+
}
|
|
49106
49576
|
}
|
|
49107
|
-
|
|
49108
|
-
const valueEnd = source.indexOf(quote, valueStart);
|
|
49109
|
-
if (valueEnd === -1) break;
|
|
49110
|
-
return `${source.slice(0, valueStart)}${newVersion}${source.slice(valueEnd)}`;
|
|
49577
|
+
offset += 1;
|
|
49111
49578
|
}
|
|
49112
|
-
throw new Error(
|
|
49579
|
+
throw new Error(
|
|
49580
|
+
"Unable to find a quoted version property on the default-exported deployment spec (not nested inside a resource config) in the entry file"
|
|
49581
|
+
);
|
|
49113
49582
|
}
|
|
49114
49583
|
function listOrganizationModelContractRefs(org) {
|
|
49115
49584
|
return Object.values(org.organizationModel?.resources ?? {}).flatMap((resource) => {
|
|
@@ -49121,7 +49590,7 @@ function listOrganizationModelContractRefs(org) {
|
|
|
49121
49590
|
].filter((entry) => entry[1] !== void 0).map(([side, ref]) => ({ resourceId: resource.id, side, ref }));
|
|
49122
49591
|
});
|
|
49123
49592
|
}
|
|
49124
|
-
function validateResourceGovernancePreflight(orgName, org, contractRegistry) {
|
|
49593
|
+
function validateResourceGovernancePreflight(orgName, org, contractRegistry, onWarning = (message) => console.warn(message)) {
|
|
49125
49594
|
if (org.organizationModel !== void 0) {
|
|
49126
49595
|
OrganizationModelSchema.parse(org.organizationModel);
|
|
49127
49596
|
}
|
|
@@ -49141,24 +49610,43 @@ Run \`pnpm exec elevasis-sdk om:scaffold:fill --gaps <path>\` to scaffold the mi
|
|
|
49141
49610
|
);
|
|
49142
49611
|
}
|
|
49143
49612
|
validateDeclaredSystemInterfaceReadiness(orgName, org.organizationModel);
|
|
49144
|
-
|
|
49145
|
-
validateResourceGovernance(orgName, org, org.organizationModel, {
|
|
49613
|
+
const mode = process.env.ELEVASIS_RESOURCE_VALIDATOR === "warn-only" ? "warn-only" : "strict";
|
|
49614
|
+
validateResourceGovernance(orgName, org, org.organizationModel, {
|
|
49615
|
+
mode,
|
|
49616
|
+
onWarning: (issue2) => onWarning(issue2.message)
|
|
49617
|
+
});
|
|
49146
49618
|
const contractRefs = listOrganizationModelContractRefs(org);
|
|
49147
|
-
if (contractRefs.length === 0
|
|
49619
|
+
if (contractRefs.length === 0) return;
|
|
49620
|
+
if (contractRegistry === void 0) {
|
|
49621
|
+
onWarning(
|
|
49622
|
+
`[${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.`
|
|
49623
|
+
);
|
|
49624
|
+
return;
|
|
49625
|
+
}
|
|
49148
49626
|
for (const { resourceId, side, ref } of contractRefs) {
|
|
49149
49627
|
try {
|
|
49150
49628
|
resolveContractRef(ref, contractRegistry);
|
|
49151
49629
|
} catch (error46) {
|
|
49152
49630
|
const message = error46 instanceof Error ? error46.message : String(error46);
|
|
49153
|
-
|
|
49154
|
-
|
|
49155
|
-
|
|
49156
|
-
|
|
49157
|
-
|
|
49158
|
-
);
|
|
49631
|
+
const field2 = `organizationModel.resources.${resourceId}.ontology.contract.${side}`;
|
|
49632
|
+
if (mode === "warn-only") {
|
|
49633
|
+
onWarning(`[${orgName}] ${field2}: ${message}`);
|
|
49634
|
+
continue;
|
|
49635
|
+
}
|
|
49636
|
+
throw new RegistryValidationError(orgName, resourceId, field2, message);
|
|
49159
49637
|
}
|
|
49160
49638
|
}
|
|
49161
49639
|
}
|
|
49640
|
+
function formatZodValidationError(error46) {
|
|
49641
|
+
return error46.issues.map((issue2) => {
|
|
49642
|
+
const path3 = issue2.path.length > 0 ? issue2.path.join(".") : "(root)";
|
|
49643
|
+
return `${path3}: ${issue2.message}`;
|
|
49644
|
+
});
|
|
49645
|
+
}
|
|
49646
|
+
function formatRegistryValidationError(error46) {
|
|
49647
|
+
if (error46.issues && error46.issues.length > 1) return error46.issues;
|
|
49648
|
+
return [error46.message];
|
|
49649
|
+
}
|
|
49162
49650
|
function registerDeployCommand(program3) {
|
|
49163
49651
|
program3.command("deploy").description(
|
|
49164
49652
|
"Validate, bundle, upload, and deploy project resources\n Example: elevasis-sdk deploy --api-url http://localhost:5170"
|
|
@@ -49182,7 +49670,7 @@ function registerDeployCommand(program3) {
|
|
|
49182
49670
|
authSpinner.fail(source_default.red("Authentication failed"));
|
|
49183
49671
|
const errMsg = error46 instanceof Error ? error46.message : String(error46);
|
|
49184
49672
|
if (errMsg.includes("401") || errMsg.toLowerCase().includes("unauthorized")) {
|
|
49185
|
-
const keyVar = !
|
|
49673
|
+
const keyVar = !isProdApiUrl(apiUrl) && process.env.NODE_ENV === "development" && process.env.ELEVASIS_PLATFORM_KEY_DEV ? "ELEVASIS_PLATFORM_KEY_DEV" : "ELEVASIS_PLATFORM_KEY";
|
|
49186
49674
|
console.error(source_default.red(" Invalid API key."));
|
|
49187
49675
|
console.error(source_default.gray(` Your ${keyVar} was rejected by the server.`));
|
|
49188
49676
|
console.error(source_default.gray(" Check your .env file and verify the key in the Elevasis dashboard."));
|
|
@@ -49206,7 +49694,13 @@ function registerDeployCommand(program3) {
|
|
|
49206
49694
|
throw new Error("Invalid entry: no default export found");
|
|
49207
49695
|
}
|
|
49208
49696
|
const contractRegistry = deploymentModule.contractRegistry ?? deploymentModule.ELEVASIS_CONTRACT_REGISTRY;
|
|
49209
|
-
|
|
49697
|
+
const governanceWarnings = [];
|
|
49698
|
+
validateResourceGovernancePreflight(
|
|
49699
|
+
orgName,
|
|
49700
|
+
org,
|
|
49701
|
+
contractRegistry,
|
|
49702
|
+
(message) => governanceWarnings.push(message)
|
|
49703
|
+
);
|
|
49210
49704
|
new ResourceRegistry({ [orgName]: org });
|
|
49211
49705
|
activeWorkflows = (org.workflows ?? []).filter((w) => !w.config.archived);
|
|
49212
49706
|
activeAgents = (org.agents ?? []).filter((a) => !a.config.archived);
|
|
@@ -49215,6 +49709,12 @@ function registerDeployCommand(program3) {
|
|
|
49215
49709
|
validateSpinner.succeed(
|
|
49216
49710
|
source_default.green("Validating...") + source_default.white(" done") + source_default.gray(` (${totalCount} resource${totalCount !== 1 ? "s" : ""}, 0 errors)`)
|
|
49217
49711
|
);
|
|
49712
|
+
if (governanceWarnings.length > 0) {
|
|
49713
|
+
for (const warning of governanceWarnings) {
|
|
49714
|
+
console.log(source_default.yellow(` warn ${warning}`));
|
|
49715
|
+
}
|
|
49716
|
+
console.log("");
|
|
49717
|
+
}
|
|
49218
49718
|
if (archivedCount > 0) {
|
|
49219
49719
|
console.log(source_default.gray(` Skipping ${archivedCount} archived resource${archivedCount !== 1 ? "s" : ""}`));
|
|
49220
49720
|
}
|
|
@@ -49248,12 +49748,30 @@ function registerDeployCommand(program3) {
|
|
|
49248
49748
|
if (error46 instanceof RegistryValidationError) {
|
|
49249
49749
|
validateSpinner.fail(source_default.red("Validation failed"));
|
|
49250
49750
|
console.error("");
|
|
49251
|
-
|
|
49751
|
+
const issues = formatRegistryValidationError(error46);
|
|
49752
|
+
if (issues.length > 1) {
|
|
49753
|
+
console.error(source_default.red(` ${issues.length} issues:`));
|
|
49754
|
+
for (const issue2 of issues) {
|
|
49755
|
+
console.error(source_default.red(` - ${issue2}`));
|
|
49756
|
+
}
|
|
49757
|
+
} else {
|
|
49758
|
+
console.error(source_default.red(` ERROR ${issues[0]}`));
|
|
49759
|
+
}
|
|
49252
49760
|
if (error46.resourceId) {
|
|
49253
49761
|
console.error(source_default.gray(` Resource: ${error46.resourceId}`));
|
|
49254
49762
|
}
|
|
49255
49763
|
console.error("");
|
|
49256
49764
|
console.error(source_default.gray(" Deploy aborted."));
|
|
49765
|
+
} else if (error46 instanceof external_exports.ZodError) {
|
|
49766
|
+
validateSpinner.fail(source_default.red("Validation failed: organization model does not match the expected shape"));
|
|
49767
|
+
console.error("");
|
|
49768
|
+
for (const line of formatZodValidationError(error46)) {
|
|
49769
|
+
console.error(source_default.red(` ERROR ${line}`));
|
|
49770
|
+
}
|
|
49771
|
+
console.error("");
|
|
49772
|
+
console.error(source_default.gray(" Deploy aborted."));
|
|
49773
|
+
} else if (validateSpinner.isSpinning) {
|
|
49774
|
+
validateSpinner.fail(source_default.red("Validation failed"));
|
|
49257
49775
|
}
|
|
49258
49776
|
throw error46;
|
|
49259
49777
|
}
|
|
@@ -49318,11 +49836,11 @@ import { startWorker } from '@elevasis/sdk/worker'
|
|
|
49318
49836
|
const uploadSpinner = ora("Uploading...").start();
|
|
49319
49837
|
try {
|
|
49320
49838
|
const bundleBuffer = await (0, import_promises.readFile)(bundleOutfile);
|
|
49321
|
-
const apiKey =
|
|
49839
|
+
const apiKey = resolveApiKeyForUrl(apiUrl);
|
|
49322
49840
|
if (!apiKey) {
|
|
49323
49841
|
uploadSpinner.fail(source_default.red("Missing API key environment variable"));
|
|
49324
49842
|
console.error(source_default.gray(" Set it in your .env file or shell environment:"));
|
|
49325
|
-
if (!
|
|
49843
|
+
if (!isProdApiUrl(apiUrl) && process.env.NODE_ENV === "development") {
|
|
49326
49844
|
console.error(
|
|
49327
49845
|
source_default.gray(" ELEVASIS_PLATFORM_KEY_DEV=sk_... (or ELEVASIS_PLATFORM_KEY as fallback)")
|
|
49328
49846
|
);
|
|
@@ -49390,7 +49908,7 @@ import { startWorker } from '@elevasis/sdk/worker'
|
|
|
49390
49908
|
)
|
|
49391
49909
|
);
|
|
49392
49910
|
}
|
|
49393
|
-
var import_path2, import_promises, import_fs2, import_crypto, import_url, import_module;
|
|
49911
|
+
var import_path2, import_promises, import_fs2, import_crypto, import_url, import_module, PLAIN_SEMVER_RE;
|
|
49394
49912
|
var init_deploy = __esm({
|
|
49395
49913
|
"src/cli/commands/deploy.ts"() {
|
|
49396
49914
|
"use strict";
|
|
@@ -49411,6 +49929,7 @@ var init_deploy = __esm({
|
|
|
49411
49929
|
init_api_client();
|
|
49412
49930
|
init_wrap_action();
|
|
49413
49931
|
init_version();
|
|
49932
|
+
PLAIN_SEMVER_RE = /^(\d+)\.(\d+)\.(\d+)$/;
|
|
49414
49933
|
}
|
|
49415
49934
|
});
|
|
49416
49935
|
|
|
@@ -49554,18 +50073,35 @@ function emitSystemEntry(opts) {
|
|
|
49554
50073
|
const order = opts.order ?? 10;
|
|
49555
50074
|
let apiInterfaceBlock = "";
|
|
49556
50075
|
let apiInterfaceNote;
|
|
50076
|
+
let importLine;
|
|
49557
50077
|
if (opts.apiBacked) {
|
|
49558
50078
|
const cataloged = SYSTEM_INTERFACE_PROFILES.find(
|
|
49559
50079
|
(profile) => profile.systemPath === opts.id && profile.interfaceKey === "api"
|
|
49560
50080
|
);
|
|
49561
|
-
|
|
50081
|
+
const resourceIds = (opts.resourceIds ?? []).filter((id) => id.trim().length > 0);
|
|
50082
|
+
if (cataloged !== void 0 && cataloged.validation === "built-in" && resourceIds.length > 0) {
|
|
50083
|
+
defineSystemApiInterface({
|
|
50084
|
+
systemPath: opts.id,
|
|
50085
|
+
readinessProfile: cataloged.readinessProfile,
|
|
50086
|
+
resourceIds
|
|
50087
|
+
});
|
|
50088
|
+
importLine = `import { defineSystemApiInterface } from '@elevasis/core/organization-model'`;
|
|
50089
|
+
const resourceIdsLines = resourceIds.map((id) => ` '${id}'`).join(",\n");
|
|
49562
50090
|
apiInterfaceBlock = `
|
|
49563
|
-
apiInterface: {
|
|
49564
|
-
|
|
49565
|
-
readinessProfile: '${cataloged.readinessProfile}'
|
|
49566
|
-
|
|
50091
|
+
apiInterface: defineSystemApiInterface({
|
|
50092
|
+
systemPath: '${opts.id}',
|
|
50093
|
+
readinessProfile: '${cataloged.readinessProfile}',
|
|
50094
|
+
resourceIds: [
|
|
50095
|
+
${resourceIdsLines}
|
|
50096
|
+
]
|
|
50097
|
+
}),`;
|
|
50098
|
+
} else if (cataloged !== void 0 && cataloged.validation === "built-in") {
|
|
50099
|
+
apiInterfaceNote = `System \`${opts.id}\` is cataloged for readiness profile "${cataloged.readinessProfile}", but a brand-new System has no scoped resources yet to back an \`apiInterface\`. \`apiInterface\` was NOT added. Once real resource ids exist for this system, declare it with \`defineSystemApiInterface\` from '@elevasis/core/organization-model' (or re-run \`om:scaffold:fill\`, which does this for you).`;
|
|
50100
|
+
} else if (cataloged !== void 0) {
|
|
50101
|
+
apiInterfaceNote = `System \`${opts.id}\` adopts contract-validated readiness profile "${cataloged.readinessProfile}". \`apiInterface\` was NOT added \u2014 declare it with \`defineContentSystem\` from '@elevasis/core/organization-model', which derives the readinessContract, content:object/item, and status catalog from your pipelines, item voice, and status vocabulary.`;
|
|
49567
50102
|
} else {
|
|
49568
|
-
|
|
50103
|
+
const adoptable = SYSTEM_INTERFACE_PROFILES.filter((profile) => profile.interfaceKey === "api").map((profile) => `"${profile.systemPath}"`).join(", ");
|
|
50104
|
+
apiInterfaceNote = `System \`${opts.id}\` is not on a cataloged readiness profile (adoptable system paths today: ${adoptable}). \`apiInterface\` was NOT added. A custom System extends behavior through workflows/operations plus ontology, resources, and topology \u2014 omitting apiInterface entirely is the designed opt-out.`;
|
|
49569
50105
|
}
|
|
49570
50106
|
}
|
|
49571
50107
|
const code = ` {
|
|
@@ -49581,7 +50117,8 @@ function emitSystemEntry(opts) {
|
|
|
49581
50117
|
`;
|
|
49582
50118
|
const startAnchor = /^(?!\s*(?:\/\/|\*|\/\*)).*\bexport const templateSystems\s*=/m;
|
|
49583
50119
|
const anchor = /^\] as const\s*$/m;
|
|
49584
|
-
|
|
50120
|
+
const importAnchor = /^\/\/ -{75,}\n\/\/ Feature/m;
|
|
50121
|
+
return { code, startAnchor, anchor, apiInterfaceNote, importLine, importAnchor };
|
|
49585
50122
|
}
|
|
49586
50123
|
var init_emit_system = __esm({
|
|
49587
50124
|
"src/cli/commands/om/emit-system.ts"() {
|
|
@@ -49748,10 +50285,20 @@ async function scaffoldSystem(opts) {
|
|
|
49748
50285
|
});
|
|
49749
50286
|
apiBacked = answer.trim().toLowerCase() === "y";
|
|
49750
50287
|
}
|
|
49751
|
-
const { code, anchor, startAnchor, apiInterfaceNote } = emitSystemEntry({
|
|
50288
|
+
const { code, anchor, startAnchor, apiInterfaceNote, importLine, importAnchor } = emitSystemEntry({
|
|
50289
|
+
id,
|
|
50290
|
+
title,
|
|
50291
|
+
kind,
|
|
50292
|
+
apiBacked,
|
|
50293
|
+
resourceIds: options.resourceIds
|
|
50294
|
+
});
|
|
49752
50295
|
const shouldWrite = options.write === true || options.dryRun === false;
|
|
49753
50296
|
if (!shouldWrite) {
|
|
49754
50297
|
console.log(source_default.cyan("Dry-run mode (default) \u2014 no files written. Pass --write to apply.\n"));
|
|
50298
|
+
if (importLine !== void 0) {
|
|
50299
|
+
console.log(source_default.gray("Import line to add near the top of core/config/organization-model/systems.ts:"));
|
|
50300
|
+
console.log(importLine);
|
|
50301
|
+
}
|
|
49755
50302
|
console.log(source_default.gray("Proposed addition to core/config/organization-model/systems.ts:"));
|
|
49756
50303
|
console.log(code);
|
|
49757
50304
|
if (apiInterfaceNote !== void 0) {
|
|
@@ -49762,6 +50309,9 @@ async function scaffoldSystem(opts) {
|
|
|
49762
50309
|
const systemsFilePath = (0, import_node_path13.join)(getOrganizationModelDir(projectDir), "systems.ts");
|
|
49763
50310
|
try {
|
|
49764
50311
|
await withSnapshotRollback([systemsFilePath], async () => {
|
|
50312
|
+
if (importLine !== void 0) {
|
|
50313
|
+
await appendBeforeAnchor(systemsFilePath, importLine + "\n", importAnchor);
|
|
50314
|
+
}
|
|
49765
50315
|
await appendBeforeAnchor(systemsFilePath, code, anchor, startAnchor);
|
|
49766
50316
|
const validationError = runValidation(projectDir);
|
|
49767
50317
|
if (validationError !== null) {
|
|
@@ -50208,6 +50758,14 @@ var init_scaffold_knowledge = __esm({
|
|
|
50208
50758
|
function toConstName(systemPath) {
|
|
50209
50759
|
return systemPath.split(/[.-]/).map((segment, index) => index === 0 ? segment : segment.charAt(0).toUpperCase() + segment.slice(1)).join("") + "ApiInterface";
|
|
50210
50760
|
}
|
|
50761
|
+
function buildContentPlaceholderReadinessContract(systemPath) {
|
|
50762
|
+
return {
|
|
50763
|
+
requiredObjects: [`${systemPath}:object/item`],
|
|
50764
|
+
requiredCatalogs: [
|
|
50765
|
+
"TODO -- replace with this System real pipeline, step, and status catalog ids (see defineContentPipeline and defineContentSystem in the organization-model subpath)"
|
|
50766
|
+
]
|
|
50767
|
+
};
|
|
50768
|
+
}
|
|
50211
50769
|
function emitApiInterfaceBlock(gap) {
|
|
50212
50770
|
const constName = toConstName(gap.systemPath);
|
|
50213
50771
|
const cataloged = SYSTEM_INTERFACE_PROFILES.find(
|
|
@@ -50220,17 +50778,44 @@ function emitApiInterfaceBlock(gap) {
|
|
|
50220
50778
|
);
|
|
50221
50779
|
}
|
|
50222
50780
|
const readinessProfile = cataloged.readinessProfile;
|
|
50223
|
-
|
|
50224
|
-
|
|
50225
|
-
|
|
50226
|
-
|
|
50781
|
+
if (gap.resourceIds.length === 0) {
|
|
50782
|
+
throw new Error(
|
|
50783
|
+
`Cannot emit an apiInterface for system path "${gap.systemPath}": the gap carries no resourceIds. defineSystemApiInterface requires at least one scoped resource id \u2014 an interface with none computes as ready and answers every route with a 503. Re-run this scaffolder once the system has at least one API-backed resource declared.`
|
|
50784
|
+
);
|
|
50785
|
+
}
|
|
50786
|
+
const resourceIds = gap.resourceIds;
|
|
50787
|
+
const isContractValidated = cataloged.validation === "contract";
|
|
50788
|
+
const readinessContract = isContractValidated ? buildContentPlaceholderReadinessContract(gap.systemPath) : void 0;
|
|
50789
|
+
defineSystemApiInterface({
|
|
50790
|
+
systemPath: gap.systemPath,
|
|
50791
|
+
readinessProfile,
|
|
50792
|
+
resourceIds,
|
|
50793
|
+
...readinessContract !== void 0 ? { readinessContract } : {}
|
|
50794
|
+
});
|
|
50795
|
+
const resourceIdsLines = resourceIds.map((id) => ` '${id}'`).join(",\n");
|
|
50796
|
+
const readinessContractField = readinessContract === void 0 ? "" : `,
|
|
50797
|
+
// TODO: requiredCatalogs below is a placeholder. Replace it with this System's actual pipeline,
|
|
50798
|
+
// step, and status catalog ids before deploying \u2014 see extend-content.md in the SDK scaffold docs.
|
|
50799
|
+
readinessContract: {
|
|
50800
|
+
requiredObjects: [
|
|
50801
|
+
${readinessContract.requiredObjects.map((id) => `'${id}'`).join(",\n ")}
|
|
50802
|
+
],
|
|
50803
|
+
requiredCatalogs: [
|
|
50804
|
+
${readinessContract.requiredCatalogs.map((id) => `'${id}'`).join(",\n ")}
|
|
50805
|
+
]
|
|
50806
|
+
}`;
|
|
50227
50807
|
const constFileCode = `// Auto-generated by om:scaffold:fill \u2014 do not edit manually.
|
|
50228
50808
|
// Regenerate by running: elevasis-sdk om:scaffold:fill --gaps <path>
|
|
50229
50809
|
|
|
50230
|
-
|
|
50231
|
-
|
|
50232
|
-
|
|
50233
|
-
}
|
|
50810
|
+
import { defineSystemApiInterface } from '@elevasis/core/organization-model'
|
|
50811
|
+
|
|
50812
|
+
export const ${constName} = defineSystemApiInterface({
|
|
50813
|
+
systemPath: '${gap.systemPath}',
|
|
50814
|
+
readinessProfile: '${readinessProfile}',
|
|
50815
|
+
resourceIds: [
|
|
50816
|
+
${resourceIdsLines}
|
|
50817
|
+
]${readinessContractField}
|
|
50818
|
+
})
|
|
50234
50819
|
`;
|
|
50235
50820
|
const importLine = `import { ${constName} } from './api-interfaces/${gap.systemPath}'`;
|
|
50236
50821
|
const fieldLine = ` apiInterface: ${constName},`;
|
|
@@ -50331,11 +50916,21 @@ async function scaffoldFill(opts) {
|
|
|
50331
50916
|
gap.resourceIds
|
|
50332
50917
|
) : gap.resourceId ? [gap.resourceId] : []
|
|
50333
50918
|
);
|
|
50334
|
-
|
|
50335
|
-
|
|
50336
|
-
|
|
50337
|
-
|
|
50338
|
-
|
|
50919
|
+
let emitResult;
|
|
50920
|
+
try {
|
|
50921
|
+
emitResult = emitApiInterfaceBlock({
|
|
50922
|
+
systemPath,
|
|
50923
|
+
resourceIds,
|
|
50924
|
+
message: gap.reason
|
|
50925
|
+
});
|
|
50926
|
+
} catch (err) {
|
|
50927
|
+
skippedGaps.push({
|
|
50928
|
+
field: gap.field,
|
|
50929
|
+
resourceId: gap.resourceId,
|
|
50930
|
+
reason: err instanceof Error ? err.message : String(err)
|
|
50931
|
+
});
|
|
50932
|
+
continue;
|
|
50933
|
+
}
|
|
50339
50934
|
const constFilePath = (0, import_node_path17.join)(getOrganizationModelDir(projectDir), "api-interfaces", `${systemPath}.ts`);
|
|
50340
50935
|
touchedFiles.push(constFilePath);
|
|
50341
50936
|
emitResults.push(emitResult);
|
|
@@ -55314,7 +55909,129 @@ function registerUiCommands(program3) {
|
|
|
55314
55909
|
var import_node_fs9 = require("node:fs");
|
|
55315
55910
|
var import_node_path8 = __toESM(require("node:path"), 1);
|
|
55316
55911
|
init_source();
|
|
55912
|
+
init_organization_model();
|
|
55317
55913
|
init_config2();
|
|
55914
|
+
init_load_org_model();
|
|
55915
|
+
|
|
55916
|
+
// src/cli/commands/om/deployed-readiness.ts
|
|
55917
|
+
init_organization_model();
|
|
55918
|
+
init_api_client();
|
|
55919
|
+
function listApiInterfaceSystemPaths(model) {
|
|
55920
|
+
return listAllSystems(model).filter(({ system }) => system.apiInterface !== void 0).map(({ path: path3 }) => path3);
|
|
55921
|
+
}
|
|
55922
|
+
function listDeployedReadinessTargets(model) {
|
|
55923
|
+
const declared = new Set(listApiInterfaceSystemPaths(model));
|
|
55924
|
+
const targets = SYSTEM_INTERFACE_PROFILES.map((profile) => ({
|
|
55925
|
+
systemPath: profile.systemPath,
|
|
55926
|
+
interfaceKey: profile.interfaceKey,
|
|
55927
|
+
declaredLocally: declared.has(profile.systemPath)
|
|
55928
|
+
}));
|
|
55929
|
+
const covered = new Set(targets.map((target) => `${target.systemPath}::${target.interfaceKey}`));
|
|
55930
|
+
for (const systemPath of declared) {
|
|
55931
|
+
const key = `${systemPath}::api`;
|
|
55932
|
+
if (covered.has(key)) continue;
|
|
55933
|
+
covered.add(key);
|
|
55934
|
+
targets.push({ systemPath, interfaceKey: "api", declaredLocally: true });
|
|
55935
|
+
}
|
|
55936
|
+
return targets;
|
|
55937
|
+
}
|
|
55938
|
+
async function fetchDeployedReadiness(model, options = {}) {
|
|
55939
|
+
const targets = listDeployedReadinessTargets(model);
|
|
55940
|
+
const report = {
|
|
55941
|
+
activeDeploymentId: null,
|
|
55942
|
+
snapshotHash: null,
|
|
55943
|
+
kind: null,
|
|
55944
|
+
entries: []
|
|
55945
|
+
};
|
|
55946
|
+
if (targets.length === 0) {
|
|
55947
|
+
report.unavailableReason = "no System-interface profile to check \u2014 neither the platform catalog nor the project model declares one";
|
|
55948
|
+
return report;
|
|
55949
|
+
}
|
|
55950
|
+
for (const target of targets) {
|
|
55951
|
+
let response;
|
|
55952
|
+
try {
|
|
55953
|
+
const endpoint = `/api/external/organization-model/readiness?systemPath=${encodeURIComponent(target.systemPath)}&interfaceKey=${encodeURIComponent(target.interfaceKey)}`;
|
|
55954
|
+
response = await apiGet(endpoint, options.apiUrl);
|
|
55955
|
+
} catch (error46) {
|
|
55956
|
+
report.unavailableReason = error46 instanceof Error ? error46.message : String(error46);
|
|
55957
|
+
return report;
|
|
55958
|
+
}
|
|
55959
|
+
report.activeDeploymentId = response.activeDeploymentId;
|
|
55960
|
+
report.snapshotHash = response.snapshotHash;
|
|
55961
|
+
report.kind = response.kind;
|
|
55962
|
+
report.entries.push({
|
|
55963
|
+
systemPath: response.readiness.systemPath,
|
|
55964
|
+
interfaceKey: response.readiness.interfaceKey,
|
|
55965
|
+
ready: response.readiness.ready,
|
|
55966
|
+
issues: response.readiness.issues,
|
|
55967
|
+
declaredLocally: target.declaredLocally
|
|
55968
|
+
});
|
|
55969
|
+
}
|
|
55970
|
+
return report;
|
|
55971
|
+
}
|
|
55972
|
+
function isUnadoptedNotDeclared(entry) {
|
|
55973
|
+
return !entry.declaredLocally && entry.issues.every((issue2) => issue2.family === "SYSTEM_INTERFACE_MISSING");
|
|
55974
|
+
}
|
|
55975
|
+
function readinessDiagnostics(report) {
|
|
55976
|
+
const diagnostics = [];
|
|
55977
|
+
for (const entry of report.entries) {
|
|
55978
|
+
if (entry.ready) {
|
|
55979
|
+
diagnostics.push({
|
|
55980
|
+
severity: "info",
|
|
55981
|
+
code: "deployed-interface-ready",
|
|
55982
|
+
systemPath: entry.systemPath,
|
|
55983
|
+
message: `${entry.systemPath}/${entry.interfaceKey} is ready in the deployed snapshot.`
|
|
55984
|
+
});
|
|
55985
|
+
continue;
|
|
55986
|
+
}
|
|
55987
|
+
const unadopted = isUnadoptedNotDeclared(entry);
|
|
55988
|
+
for (const issue2 of entry.issues) {
|
|
55989
|
+
diagnostics.push({
|
|
55990
|
+
severity: unadopted ? "info" : "error",
|
|
55991
|
+
code: `deployed-${issue2.code}`,
|
|
55992
|
+
systemPath: entry.systemPath,
|
|
55993
|
+
...issue2.ref !== void 0 && { targetId: issue2.ref },
|
|
55994
|
+
message: `${entry.systemPath}/${entry.interfaceKey} ${unadopted ? "not adopted" : "not ready"} [${issue2.family}]: ${issue2.message}`,
|
|
55995
|
+
source: "deployed-snapshot"
|
|
55996
|
+
});
|
|
55997
|
+
}
|
|
55998
|
+
}
|
|
55999
|
+
return diagnostics;
|
|
56000
|
+
}
|
|
56001
|
+
function readinessRoster(report) {
|
|
56002
|
+
return report.entries.map((entry) => {
|
|
56003
|
+
if (entry.ready) {
|
|
56004
|
+
return {
|
|
56005
|
+
systemPath: entry.systemPath,
|
|
56006
|
+
interfaceKey: entry.interfaceKey,
|
|
56007
|
+
status: "ready",
|
|
56008
|
+
detail: "ready",
|
|
56009
|
+
issues: []
|
|
56010
|
+
};
|
|
56011
|
+
}
|
|
56012
|
+
if (isUnadoptedNotDeclared(entry)) {
|
|
56013
|
+
return {
|
|
56014
|
+
systemPath: entry.systemPath,
|
|
56015
|
+
interfaceKey: entry.interfaceKey,
|
|
56016
|
+
status: "not-adopted",
|
|
56017
|
+
detail: "not adopted",
|
|
56018
|
+
issues: entry.issues
|
|
56019
|
+
};
|
|
56020
|
+
}
|
|
56021
|
+
return {
|
|
56022
|
+
systemPath: entry.systemPath,
|
|
56023
|
+
interfaceKey: entry.interfaceKey,
|
|
56024
|
+
status: "not-ready",
|
|
56025
|
+
detail: entry.issues[0]?.message ?? "not ready",
|
|
56026
|
+
issues: entry.issues
|
|
56027
|
+
};
|
|
56028
|
+
});
|
|
56029
|
+
}
|
|
56030
|
+
function countReadinessRosterFailures(rows) {
|
|
56031
|
+
return rows.filter((row) => row.status === "not-ready").length;
|
|
56032
|
+
}
|
|
56033
|
+
|
|
56034
|
+
// src/cli/commands/doctor.ts
|
|
55318
56035
|
function ok(label, detail) {
|
|
55319
56036
|
console.log(`${source_default.green("[OK]")} ${source_default.bold(label)}: ${detail}`);
|
|
55320
56037
|
}
|
|
@@ -55422,6 +56139,38 @@ function registerDoctorCommand(program3) {
|
|
|
55422
56139
|
if (isVerbose) verbose(`Error: ${networkError}`);
|
|
55423
56140
|
failCount++;
|
|
55424
56141
|
}
|
|
56142
|
+
let model = DEFAULT_ORGANIZATION_MODEL;
|
|
56143
|
+
try {
|
|
56144
|
+
model = await loadOrgModel(projectRoot);
|
|
56145
|
+
} catch (err) {
|
|
56146
|
+
if (isVerbose) {
|
|
56147
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
56148
|
+
verbose(`Organization model load failed, roster limited to the platform catalog: ${msg}`);
|
|
56149
|
+
}
|
|
56150
|
+
}
|
|
56151
|
+
const readiness = await fetchDeployedReadiness(model, { apiUrl });
|
|
56152
|
+
if (readiness.unavailableReason !== void 0) {
|
|
56153
|
+
warn("Systems", `Readiness unavailable \u2014 ${readiness.unavailableReason}`);
|
|
56154
|
+
if (isVerbose) verbose(`GET ${apiUrl}/api/external/organization-model/readiness`);
|
|
56155
|
+
} else {
|
|
56156
|
+
const rows = readinessRoster(readiness);
|
|
56157
|
+
for (const row of rows) {
|
|
56158
|
+
const label = `Systems: ${row.systemPath}/${row.interfaceKey}`;
|
|
56159
|
+
if (row.status === "ready") {
|
|
56160
|
+
ok(label, row.detail);
|
|
56161
|
+
} else if (row.status === "not-adopted") {
|
|
56162
|
+
warn(label, row.detail);
|
|
56163
|
+
} else {
|
|
56164
|
+
fail(label, row.detail);
|
|
56165
|
+
}
|
|
56166
|
+
if (isVerbose) {
|
|
56167
|
+
for (const issue2 of row.issues) {
|
|
56168
|
+
verbose(`${issue2.code}: ${issue2.message}`);
|
|
56169
|
+
}
|
|
56170
|
+
}
|
|
56171
|
+
}
|
|
56172
|
+
failCount += countReadinessRosterFailures(rows);
|
|
56173
|
+
}
|
|
55425
56174
|
console.log();
|
|
55426
56175
|
printSummary(failCount);
|
|
55427
56176
|
if (failCount > 0) {
|
|
@@ -55841,7 +56590,7 @@ function appendQuery4(params, key, value) {
|
|
|
55841
56590
|
}
|
|
55842
56591
|
function registerContentList(program3) {
|
|
55843
56592
|
program3.command("content:list").description(
|
|
55844
|
-
|
|
56593
|
+
'List content pipeline items\n Example: elevasis-sdk content:list --status <status> --pipeline-id <pipelineId>\n Note: both values come from the org model this project declares, not a platform enum --\n read them from the content:catalog/status catalog and content:pipeline.\n Note: "awaiting review" is not a status -- that read is content:queue.'
|
|
55845
56594
|
).option("--status <status>", "Filter by content item status").option("--pillar <pillar>", "Filter by content pillar").option("--pipeline-id <id>", "Filter by pipeline template id").option("--client-id <id>", "Filter by client id").option("--reviewed-by <id>", "Filter by reviewer user id").option("--search <query>", "Search by title").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(
|
|
55846
56595
|
wrapAction("content:list", async (options) => {
|
|
55847
56596
|
const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
|
|
@@ -55918,6 +56667,12 @@ Content item: ${item.title}`));
|
|
|
55918
56667
|
// src/cli/commands/content/board.ts
|
|
55919
56668
|
init_source();
|
|
55920
56669
|
|
|
56670
|
+
// ../core/src/content/review-gates.ts
|
|
56671
|
+
function isAwaitingReview(item, step) {
|
|
56672
|
+
if (!step) return false;
|
|
56673
|
+
return step.reviewMode !== "none" && item.reviewedAt === null;
|
|
56674
|
+
}
|
|
56675
|
+
|
|
55921
56676
|
// ../core/src/content/derive-board.ts
|
|
55922
56677
|
function sortPipelineSteps(steps) {
|
|
55923
56678
|
return [...steps].sort((a, b) => {
|
|
@@ -55941,17 +56696,13 @@ function deriveItemPlacement(item, sortedSteps) {
|
|
|
55941
56696
|
});
|
|
55942
56697
|
if (!currentStep) {
|
|
55943
56698
|
const lastStep = sortedSteps[sortedSteps.length - 1];
|
|
55944
|
-
if (lastStep !== void 0 &&
|
|
56699
|
+
if (lastStep !== void 0 && isAwaitingReview(item, lastStep)) {
|
|
55945
56700
|
return { bucket: "column", stepKey: lastStep.key };
|
|
55946
56701
|
}
|
|
55947
56702
|
return { bucket: "done", stepKey: null };
|
|
55948
56703
|
}
|
|
55949
56704
|
return { bucket: "column", stepKey: currentStep.key };
|
|
55950
56705
|
}
|
|
55951
|
-
function deriveAwaitingReview(step, item) {
|
|
55952
|
-
if (!step) return false;
|
|
55953
|
-
return step.reviewMode !== "none" && item.reviewedAt === null;
|
|
55954
|
-
}
|
|
55955
56706
|
function deriveContentBoard(items, pipeline, now) {
|
|
55956
56707
|
const sortedSteps = sortPipelineSteps(pipeline.steps);
|
|
55957
56708
|
const stepsByKey = new Map(sortedSteps.map((step) => [step.key, step]));
|
|
@@ -55965,7 +56716,7 @@ function deriveContentBoard(items, pipeline, now) {
|
|
|
55965
56716
|
item,
|
|
55966
56717
|
stepKey: placement.stepKey,
|
|
55967
56718
|
ageMs: now - Date.parse(item.updatedAt),
|
|
55968
|
-
awaitingReview:
|
|
56719
|
+
awaitingReview: isAwaitingReview(item, step)
|
|
55969
56720
|
};
|
|
55970
56721
|
if (placement.bucket === "done") {
|
|
55971
56722
|
done.push(card);
|
|
@@ -55989,9 +56740,9 @@ function deriveContentBoard(items, pipeline, now) {
|
|
|
55989
56740
|
const columns = sortedSteps.map((step) => {
|
|
55990
56741
|
const cards = cardsByStepKey.get(step.key) ?? [];
|
|
55991
56742
|
const column = { step, cards };
|
|
55992
|
-
if (step.
|
|
56743
|
+
if (step.reviewVenue !== "none") {
|
|
55993
56744
|
column.gate = {
|
|
55994
|
-
|
|
56745
|
+
venue: step.reviewVenue,
|
|
55995
56746
|
waitingCount: cards.filter((card) => card.awaitingReview).length
|
|
55996
56747
|
};
|
|
55997
56748
|
}
|
|
@@ -56077,7 +56828,7 @@ function printCards(cards, stepsByKey) {
|
|
|
56077
56828
|
}
|
|
56078
56829
|
function registerContentBoard(program3) {
|
|
56079
56830
|
program3.command("content:board <pipelineId>").description(
|
|
56080
|
-
"Render one pipeline as a board -- columns, review gates, and waiting counts\n Example: elevasis-sdk content:board
|
|
56831
|
+
"Render one pipeline as a board -- columns, review gates, and waiting counts\n Example: elevasis-sdk content:board <pipelineId> --pretty\n Note: pipeline ids come from the org model this project declares -- list them with content:pipeline."
|
|
56081
56832
|
).option("--limit <n>", `Items to pull before deriving (default and API maximum ${DEFAULT_ITEM_LIMIT})`).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(
|
|
56082
56833
|
wrapAction("content:board", async (pipelineId, options) => {
|
|
56083
56834
|
const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
|
|
@@ -56108,7 +56859,9 @@ Board: ${pipelineId} ${source_default.gray(`${items.data.length} of ${items.tot
|
|
|
56108
56859
|
}
|
|
56109
56860
|
console.log();
|
|
56110
56861
|
for (const column of board.columns) {
|
|
56111
|
-
const gate = column.gate ? source_default.yellow(
|
|
56862
|
+
const gate = column.gate ? source_default.yellow(
|
|
56863
|
+
` [${column.gate.venue === "workspace" ? "workspace" : "queue"} gate -- ${column.gate.waitingCount} waiting]`
|
|
56864
|
+
) : "";
|
|
56112
56865
|
console.log(` ${source_default.bold(column.step.label)} ${source_default.gray(column.step.key)}${gate}`);
|
|
56113
56866
|
printCards(column.cards, stepsByKey);
|
|
56114
56867
|
}
|
|
@@ -56170,13 +56923,13 @@ Pipeline: ${pipeline.id}`));
|
|
|
56170
56923
|
const steps = Array.isArray(pipeline.steps) ? pipeline.steps : [];
|
|
56171
56924
|
console.log(source_default.gray(` Steps (${steps.length}):`));
|
|
56172
56925
|
for (const step of steps) {
|
|
56173
|
-
console.log(source_default.gray(` - ${step.key} (
|
|
56926
|
+
console.log(source_default.gray(` - ${step.key} (review: ${step.reviewMode}, venue: ${step.reviewVenue})`));
|
|
56174
56927
|
}
|
|
56175
56928
|
console.log();
|
|
56176
56929
|
}
|
|
56177
56930
|
function registerContentPipeline(program3) {
|
|
56178
56931
|
program3.command("content:pipeline [id]").description(
|
|
56179
|
-
"List content pipeline templates, or show one pipeline's step contract\n Example: elevasis-sdk content:pipeline
|
|
56932
|
+
"List content pipeline templates, or show one pipeline's step contract\n Example: elevasis-sdk content:pipeline <pipelineId>\n Note: run without an id to list the pipeline ids this project declares in its org model."
|
|
56180
56933
|
).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(
|
|
56181
56934
|
wrapAction("content:pipeline", async (id, options) => {
|
|
56182
56935
|
const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
|
|
@@ -56221,7 +56974,7 @@ function appendQuery5(params, key, value) {
|
|
|
56221
56974
|
}
|
|
56222
56975
|
function registerContentDistributions(program3) {
|
|
56223
56976
|
program3.command("content:distributions").description(
|
|
56224
|
-
"List content distributions\n Example: elevasis-sdk content:distributions --pipeline-id
|
|
56977
|
+
"List content distributions\n Example: elevasis-sdk content:distributions --pipeline-id <pipelineId>\n Note: pipeline ids come from the org model this project declares -- list them with content:pipeline."
|
|
56225
56978
|
).option("--content-item-id <id>", "Filter by content item id").option("--pipeline-id <id>", "Filter by pipeline template id").option("--platform <platform>", "Filter by distribution platform").option("--status <status>", "Filter by distribution status").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(
|
|
56226
56979
|
wrapAction("content:distributions", async (options) => {
|
|
56227
56980
|
const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
|
|
@@ -56404,13 +57157,47 @@ function resolveTextArgument(value) {
|
|
|
56404
57157
|
throw new Error(`Could not read --text file "${path3}": ${error46 instanceof Error ? error46.message : String(error46)}`);
|
|
56405
57158
|
}
|
|
56406
57159
|
}
|
|
57160
|
+
function resolveMetadataOption(options) {
|
|
57161
|
+
if (options.metadata !== void 0 && options.metadataFile !== void 0) {
|
|
57162
|
+
throw new Error("Pass exactly one of --metadata or --metadata-file, not both");
|
|
57163
|
+
}
|
|
57164
|
+
let raw;
|
|
57165
|
+
if (options.metadataFile !== void 0) {
|
|
57166
|
+
const path3 = resolveProjectRelative(options.metadataFile);
|
|
57167
|
+
try {
|
|
57168
|
+
raw = (0, import_node_fs10.readFileSync)(path3, "utf8");
|
|
57169
|
+
} catch (error46) {
|
|
57170
|
+
throw new Error(
|
|
57171
|
+
`Could not read --metadata-file "${options.metadataFile}": ${error46 instanceof Error ? error46.message : String(error46)}`
|
|
57172
|
+
);
|
|
57173
|
+
}
|
|
57174
|
+
} else {
|
|
57175
|
+
raw = options.metadata;
|
|
57176
|
+
}
|
|
57177
|
+
if (raw === void 0) return void 0;
|
|
57178
|
+
let parsed;
|
|
57179
|
+
try {
|
|
57180
|
+
parsed = JSON.parse(raw);
|
|
57181
|
+
} catch (error46) {
|
|
57182
|
+
const source = options.metadataFile !== void 0 ? "--metadata-file" : "--metadata";
|
|
57183
|
+
throw new Error(`${source} must be valid JSON: ${error46 instanceof Error ? error46.message : String(error46)}`);
|
|
57184
|
+
}
|
|
57185
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
57186
|
+
const source = options.metadataFile !== void 0 ? "--metadata-file" : "--metadata";
|
|
57187
|
+
throw new Error(`${source} must be a JSON object, e.g. {"key":"value"}`);
|
|
57188
|
+
}
|
|
57189
|
+
return parsed;
|
|
57190
|
+
}
|
|
56407
57191
|
function registerContentSourceAssetCreate(program3) {
|
|
56408
57192
|
program3.command("content:source-asset:create").description(
|
|
56409
57193
|
'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>'
|
|
56410
57194
|
).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(
|
|
56411
57195
|
"--field <key>",
|
|
56412
57196
|
"Payload field the --text content is written to. Defaults to the --kind value, matching the catalog declaration"
|
|
56413
|
-
).option("--url <url>", "External URL the asset references. Mutually exclusive with --text").option("--duration <seconds>", "Duration in seconds, for time-based referenced media").option("--
|
|
57197
|
+
).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(
|
|
57198
|
+
"--metadata-file <path>",
|
|
57199
|
+
"Path to a JSON file containing metadata (project-relative unless absolute). Mutually exclusive with --metadata"
|
|
57200
|
+
).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(
|
|
56414
57201
|
wrapAction("content:source-asset:create", async (options) => {
|
|
56415
57202
|
if (options.text !== void 0 && options.url !== void 0) {
|
|
56416
57203
|
throw new Error("Pass exactly one of --text or --url, not both");
|
|
@@ -56441,6 +57228,9 @@ function registerContentSourceAssetCreate(program3) {
|
|
|
56441
57228
|
}
|
|
56442
57229
|
body.durationSeconds = duration3;
|
|
56443
57230
|
}
|
|
57231
|
+
if (options.storagePath !== void 0) body.storagePath = options.storagePath;
|
|
57232
|
+
const metadata = resolveMetadataOption(options);
|
|
57233
|
+
if (metadata !== void 0) body.metadata = metadata;
|
|
56444
57234
|
const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
|
|
56445
57235
|
const asset = await apiPost("/api/external/content/source-assets", body, apiUrl);
|
|
56446
57236
|
let linkedItem;
|
|
@@ -56460,6 +57250,7 @@ Created source asset ${asset.id}`));
|
|
|
56460
57250
|
console.log(source_default.gray(` Title: ${asset.title}`));
|
|
56461
57251
|
console.log(source_default.gray(` Kind: ${asset.kind}`));
|
|
56462
57252
|
if (asset.externalUrl) console.log(source_default.gray(` URL: ${asset.externalUrl}`));
|
|
57253
|
+
if (asset.storagePath) console.log(source_default.gray(` Storage path: ${asset.storagePath}`));
|
|
56463
57254
|
if (linkedItem) console.log(source_default.cyan(` Linked to item ${linkedItem.id} (${linkedItem.title})`));
|
|
56464
57255
|
console.log();
|
|
56465
57256
|
})
|
|
@@ -57836,71 +58627,6 @@ function formatOmDoctorReport(report) {
|
|
|
57836
58627
|
return lines.join("\n");
|
|
57837
58628
|
}
|
|
57838
58629
|
|
|
57839
|
-
// src/cli/commands/om/deployed-readiness.ts
|
|
57840
|
-
init_organization_model();
|
|
57841
|
-
init_api_client();
|
|
57842
|
-
function listApiInterfaceSystemPaths(model) {
|
|
57843
|
-
return listAllSystems(model).filter(({ system }) => system.apiInterface !== void 0).map(({ path: path3 }) => path3);
|
|
57844
|
-
}
|
|
57845
|
-
async function fetchDeployedReadiness(model, options = {}) {
|
|
57846
|
-
const systemPaths = listApiInterfaceSystemPaths(model);
|
|
57847
|
-
const report = {
|
|
57848
|
-
activeDeploymentId: null,
|
|
57849
|
-
snapshotHash: null,
|
|
57850
|
-
kind: null,
|
|
57851
|
-
entries: []
|
|
57852
|
-
};
|
|
57853
|
-
if (systemPaths.length === 0) {
|
|
57854
|
-
report.unavailableReason = "no System in the project model declares an apiInterface";
|
|
57855
|
-
return report;
|
|
57856
|
-
}
|
|
57857
|
-
for (const systemPath of systemPaths) {
|
|
57858
|
-
let response;
|
|
57859
|
-
try {
|
|
57860
|
-
const endpoint = `/api/external/organization-model/readiness?systemPath=${encodeURIComponent(systemPath)}&interfaceKey=api`;
|
|
57861
|
-
response = await apiGet(endpoint, options.apiUrl);
|
|
57862
|
-
} catch (error46) {
|
|
57863
|
-
report.unavailableReason = error46 instanceof Error ? error46.message : String(error46);
|
|
57864
|
-
return report;
|
|
57865
|
-
}
|
|
57866
|
-
report.activeDeploymentId = response.activeDeploymentId;
|
|
57867
|
-
report.snapshotHash = response.snapshotHash;
|
|
57868
|
-
report.kind = response.kind;
|
|
57869
|
-
report.entries.push({
|
|
57870
|
-
systemPath: response.readiness.systemPath,
|
|
57871
|
-
interfaceKey: response.readiness.interfaceKey,
|
|
57872
|
-
ready: response.readiness.ready,
|
|
57873
|
-
issues: response.readiness.issues
|
|
57874
|
-
});
|
|
57875
|
-
}
|
|
57876
|
-
return report;
|
|
57877
|
-
}
|
|
57878
|
-
function readinessDiagnostics(report) {
|
|
57879
|
-
const diagnostics = [];
|
|
57880
|
-
for (const entry of report.entries) {
|
|
57881
|
-
if (entry.ready) {
|
|
57882
|
-
diagnostics.push({
|
|
57883
|
-
severity: "info",
|
|
57884
|
-
code: "deployed-interface-ready",
|
|
57885
|
-
systemPath: entry.systemPath,
|
|
57886
|
-
message: `${entry.systemPath}/${entry.interfaceKey} is ready in the deployed snapshot.`
|
|
57887
|
-
});
|
|
57888
|
-
continue;
|
|
57889
|
-
}
|
|
57890
|
-
for (const issue2 of entry.issues) {
|
|
57891
|
-
diagnostics.push({
|
|
57892
|
-
severity: "error",
|
|
57893
|
-
code: `deployed-${issue2.code}`,
|
|
57894
|
-
systemPath: entry.systemPath,
|
|
57895
|
-
...issue2.ref !== void 0 && { targetId: issue2.ref },
|
|
57896
|
-
message: `${entry.systemPath}/${entry.interfaceKey} not ready [${issue2.family}]: ${issue2.message}`,
|
|
57897
|
-
source: "deployed-snapshot"
|
|
57898
|
-
});
|
|
57899
|
-
}
|
|
57900
|
-
}
|
|
57901
|
-
return diagnostics;
|
|
57902
|
-
}
|
|
57903
|
-
|
|
57904
58630
|
// src/cli/commands/om/doctor.ts
|
|
57905
58631
|
function registerOmDoctorCommand(program3) {
|
|
57906
58632
|
program3.command("om:doctor").description(
|
|
@@ -58714,65 +59440,7 @@ if (envPath) {
|
|
|
58714
59440
|
}
|
|
58715
59441
|
var program2 = new Command();
|
|
58716
59442
|
program2.name("elevasis-sdk").description(
|
|
58717
|
-
source_default.cyan("Elevasis SDK CLI") + `
|
|
58718
|
-
|
|
58719
|
-
Commands:
|
|
58720
|
-
elevasis-sdk check Validate project resources
|
|
58721
|
-
elevasis-sdk deploy Bundle and deploy to platform
|
|
58722
|
-
elevasis-sdk resources List deployed resources
|
|
58723
|
-
elevasis-sdk describe <resourceId> Describe a resource
|
|
58724
|
-
elevasis-sdk exec <resourceId> -i '{}' Execute a resource
|
|
58725
|
-
elevasis-sdk executions <resourceId> List execution history
|
|
58726
|
-
elevasis-sdk execution <resourceId> <id> Get execution details
|
|
58727
|
-
elevasis-sdk execution:cancel <resourceId> <id> Cancel a running execution
|
|
58728
|
-
elevasis-sdk executions:delete <resourceId> Delete execution history (destructive)
|
|
58729
|
-
elevasis-sdk deployments List deployments
|
|
58730
|
-
elevasis-sdk project:list [--search <query>] List projects with optional search
|
|
58731
|
-
elevasis-sdk project:resolve <query> Resolve a project ID from a name or UUID
|
|
58732
|
-
elevasis-sdk project:work <query> Open a lifecycle-aware project work brief
|
|
58733
|
-
elevasis-sdk client:list [--search <query>] List clients with optional search
|
|
58734
|
-
elevasis-sdk client:get <id> Get client detail and lineage
|
|
58735
|
-
elevasis-sdk client:status Show client portfolio status
|
|
58736
|
-
elevasis-sdk content:list [--status queued] List content pipeline items
|
|
58737
|
-
elevasis-sdk content:get <itemId> Get an item, its attempts, and distributions
|
|
58738
|
-
elevasis-sdk content:queue List items awaiting a queued-gate review
|
|
58739
|
-
elevasis-sdk content:pipeline [id] List pipeline templates, or one step contract
|
|
58740
|
-
elevasis-sdk content:distributions List content distributions
|
|
58741
|
-
elevasis-sdk content:review <itemId> --step <key> --approve|--reject --user <email>
|
|
58742
|
-
Clear a queued review gate on a content item
|
|
58743
|
-
elevasis-sdk queue:list [--status pending] List HITL command queue tasks
|
|
58744
|
-
elevasis-sdk queue:select <id> --action-id <id> Select and execute a HITL queue action
|
|
58745
|
-
elevasis-sdk schedule:list [--status active] List task schedules
|
|
58746
|
-
elevasis-sdk schedule:create --name <name> ... Create a task schedule
|
|
58747
|
-
elevasis-sdk agent:list List deployed agents
|
|
58748
|
-
elevasis-sdk agent:get <id> Get agent metadata and OM linkage
|
|
58749
|
-
elevasis-sdk session:create <resourceId> Create an agent session
|
|
58750
|
-
elevasis-sdk session:turn <id> -f tmp/turn.json Execute a session turn
|
|
58751
|
-
elevasis-sdk session:messages <id> Export session transcript messages
|
|
58752
|
-
elevasis-sdk session:list List agent sessions
|
|
58753
|
-
elevasis-sdk session:get <id> Get session details
|
|
58754
|
-
elevasis-sdk session:end <id> End an active agent session
|
|
58755
|
-
elevasis-sdk grant:list List public/code-gated agent access grants
|
|
58756
|
-
elevasis-sdk grant:create --resource <id> Create an agent access grant
|
|
58757
|
-
elevasis-sdk grant:disable <slug> Disable an agent access grant
|
|
58758
|
-
elevasis-sdk acquisition:list:list List acquisition lists
|
|
58759
|
-
elevasis-sdk acquisition:deal:list List acquisition deals
|
|
58760
|
-
elevasis-sdk knowledge:generate Generate knowledge nodes from MDX files
|
|
58761
|
-
elevasis-sdk knowledge:ls <path> List knowledge nodes for a path
|
|
58762
|
-
elevasis-sdk knowledge:cat <id> Print raw MDX body of a knowledge node
|
|
58763
|
-
elevasis-sdk knowledge:graph <id> Show outgoing and incoming edges for a node
|
|
58764
|
-
elevasis-sdk request:submit -f <path> Submit a structured request report
|
|
58765
|
-
elevasis-sdk request:list [--status open] List reported requests
|
|
58766
|
-
elevasis-sdk request:get <id> Get a reported request by id
|
|
58767
|
-
elevasis-sdk request:update <id> -i <json> Amend a request you filed
|
|
58768
|
-
elevasis-sdk request:delete <id> Withdraw a request you filed
|
|
58769
|
-
elevasis-sdk ui:use-local Use a local @elevasis/ui tarball
|
|
58770
|
-
elevasis-sdk ui:use-published Restore published @elevasis/ui
|
|
58771
|
-
elevasis-sdk cli [domain] Generate a registered command catalog
|
|
58772
|
-
elevasis-sdk rename <id> --to <newId> [--prod] Rename resource across platform tables
|
|
58773
|
-
elevasis-sdk doctor [--verbose] Check project environment and API connectivity
|
|
58774
|
-
|
|
58775
|
-
Use "elevasis-sdk <command> --help" for more information about a command.`
|
|
59443
|
+
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.'
|
|
58776
59444
|
).version(SDK_VERSION);
|
|
58777
59445
|
program2.hook("preAction", () => {
|
|
58778
59446
|
runPreflight();
|