@elevasis/sdk 1.46.0 → 1.48.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/cli.cjs CHANGED
@@ -22703,7 +22703,7 @@ var init_ontology = __esm({
22703
22703
  sharedProperties: external_exports.record(OntologyIdSchema, OntologySharedPropertySchema).default({}).optional(),
22704
22704
  groups: external_exports.record(OntologyIdSchema, OntologyGroupSchema).default({}).optional(),
22705
22705
  endpoints: external_exports.record(OntologyIdSchema, OntologyEndpointTypeSchema).default({}).optional()
22706
- }).default({});
22706
+ }).strict().default({});
22707
22707
  DEFAULT_ONTOLOGY_SCOPE = {
22708
22708
  valueTypes: {
22709
22709
  "global:value-type/uuid": {
@@ -23551,12 +23551,12 @@ var init_profile_registry = __esm({
23551
23551
 
23552
23552
  // ../core/src/organization-model/domains/systems.ts
23553
23553
  function isReservedPlatformProfileId(profileId) {
23554
- return SYSTEM_INTERFACE_READINESS_PROFILES.includes(profileId);
23554
+ return BUILT_IN_VALIDATED_PROFILE_IDS.includes(profileId);
23555
23555
  }
23556
23556
  function isBuiltInReadinessProfile(profileId) {
23557
23557
  return isReservedPlatformProfileId(profileId) || getBuiltInReadinessProfile(profileId) !== void 0;
23558
23558
  }
23559
- var SystemKindSchema, SystemLifecycleSchema, SystemIdSchema, SystemPathSchema, UiPositionSchema, NodeIdStringSchema, SystemUiSchema, SystemInterfaceKeySchema, SystemInterfaceLifecycleSchema, SYSTEM_INTERFACE_PROFILES, SYSTEM_INTERFACE_READINESS_PROFILES, SystemInterfaceReadinessProfileSchema, SystemInterfaceResourceScopeSchema, SystemApiInterfaceReadinessContractSchema, SystemApiInterfaceSchema, SystemInterfaceRefSchema, JsonValueSchema, SystemConfigSchema, SystemEntrySchema, SystemsDomainSchema, DEFAULT_ORGANIZATION_MODEL_SYSTEMS;
23559
+ var SystemKindSchema, SystemLifecycleSchema, SystemIdSchema, SystemPathSchema, UiPositionSchema, NodeIdStringSchema, SystemUiSchema, SystemInterfaceKeySchema, SystemInterfaceLifecycleSchema, SYSTEM_INTERFACE_PROFILES, SYSTEM_INTERFACE_READINESS_PROFILES, BUILT_IN_VALIDATED_PROFILE_IDS, SystemInterfaceReadinessProfileSchema, SystemInterfaceResourceScopeSchema, SystemApiInterfaceReadinessContractSchema, SystemApiInterfaceSchema, SystemInterfaceRefSchema, JsonValueSchema, SystemConfigSchema, SystemEntrySchema, SystemsDomainSchema, DEFAULT_ORGANIZATION_MODEL_SYSTEMS;
23560
23560
  var init_systems = __esm({
23561
23561
  "../core/src/organization-model/domains/systems.ts"() {
23562
23562
  "use strict";
@@ -23581,29 +23581,45 @@ var init_systems = __esm({
23581
23581
  path: PathSchema,
23582
23582
  surfaces: ReferenceIdsSchema,
23583
23583
  icon: IconNameSchema.optional()
23584
- });
23584
+ }).strict();
23585
23585
  SystemInterfaceKeySchema = ModelIdSchema;
23586
23586
  SystemInterfaceLifecycleSchema = external_exports.enum(["draft", "active", "disabled", "deprecated", "archived"]).meta({ label: "System interface lifecycle", color: "teal" });
23587
23587
  SYSTEM_INTERFACE_PROFILES = [
23588
23588
  {
23589
23589
  systemPath: "sales.lead-gen",
23590
23590
  interfaceKey: "api",
23591
- readinessProfile: "sales.lead-gen.api"
23591
+ readinessProfile: "sales.lead-gen.api",
23592
+ validation: "built-in"
23592
23593
  },
23593
23594
  {
23594
23595
  systemPath: "sales.crm",
23595
23596
  interfaceKey: "api",
23596
- readinessProfile: "sales.crm.api"
23597
+ readinessProfile: "sales.crm.api",
23598
+ validation: "built-in"
23597
23599
  },
23598
23600
  {
23599
23601
  systemPath: "sales.lead-gen",
23600
23602
  interfaceKey: "crm-handoff",
23601
- readinessProfile: "sales.lead-gen.crm-handoff"
23603
+ readinessProfile: "sales.lead-gen.crm-handoff",
23604
+ validation: "built-in"
23605
+ },
23606
+ {
23607
+ // Gated by `CONTENT_API_INTERFACE` in `apps/api/src/business/content/organization-model.ts`,
23608
+ // which every `/api/content/*` and `/api/external/content/*` route asserts. Contract-validated
23609
+ // rather than built-in because the required step catalog is per-adopter: Elevasis declares
23610
+ // `content:catalog/long-form-to-shorts-steps`, a tenant declares its own.
23611
+ systemPath: "content",
23612
+ interfaceKey: "api",
23613
+ readinessProfile: "content.api",
23614
+ validation: "contract"
23602
23615
  }
23603
23616
  ];
23604
23617
  SYSTEM_INTERFACE_READINESS_PROFILES = SYSTEM_INTERFACE_PROFILES.map(
23605
23618
  (profile) => profile.readinessProfile
23606
23619
  );
23620
+ BUILT_IN_VALIDATED_PROFILE_IDS = SYSTEM_INTERFACE_PROFILES.filter(
23621
+ (profile) => profile.validation === "built-in"
23622
+ ).map((profile) => profile.readinessProfile);
23607
23623
  SystemInterfaceReadinessProfileSchema = external_exports.string().trim().min(1);
23608
23624
  SystemInterfaceResourceScopeSchema = external_exports.array(ModelIdSchema).default([]);
23609
23625
  SystemApiInterfaceReadinessContractSchema = external_exports.object({
@@ -25013,7 +25029,7 @@ var init_foundation = __esm({
25013
25029
  });
25014
25030
 
25015
25031
  // ../core/src/organization-model/catalogs/content.ts
25016
- var ContentPipelineStepActorSchema, ContentPipelineStepReviewModeSchema, ContentPayloadFieldTypeSchema, ContentPayloadFieldDeclarationSchema, ContentPipelineStepDeclarationSchema;
25032
+ var ContentPipelineStepActorSchema, ContentPipelineStepReviewModeSchema, ContentPayloadFieldTypeSchema, ContentPayloadFieldDeclarationSchema, ContentWorkspaceRouteSchema, ContentPipelineStepDeclarationSchema, ContentSourceAssetKindDeclarationSchema;
25017
25033
  var init_content = __esm({
25018
25034
  "../core/src/organization-model/catalogs/content.ts"() {
25019
25035
  "use strict";
@@ -25027,6 +25043,7 @@ var init_content = __esm({
25027
25043
  type: ContentPayloadFieldTypeSchema,
25028
25044
  required: external_exports.boolean().optional()
25029
25045
  });
25046
+ ContentWorkspaceRouteSchema = external_exports.string().trim().min(1).max(400).regex(/^\//, 'workspaceRoute must be an app-relative path beginning with "/"');
25030
25047
  ContentPipelineStepDeclarationSchema = external_exports.object({
25031
25048
  label: external_exports.string().trim().min(1).max(160).optional(),
25032
25049
  description: external_exports.string().trim().min(1).max(2e3).optional(),
@@ -25052,6 +25069,22 @@ var init_content = __esm({
25052
25069
  * Resource at all.
25053
25070
  */
25054
25071
  actionId: external_exports.string().trim().min(1).max(200).optional(),
25072
+ /**
25073
+ * Per-step override of the pipeline's `workspaceRoute`. Absent on almost every
25074
+ * step -- the pipeline-level route is the common case, and this exists for the
25075
+ * chains whose gates are genuinely different screens (the video pipeline
25076
+ * reviews text candidates, then rendered video, then copy plus a schedule).
25077
+ *
25078
+ * Resolution is override-then-fallback: a display surface takes this when the
25079
+ * step declares one and the pipeline's otherwise. See `ContentWorkspaceRouteSchema`.
25080
+ */
25081
+ workspaceRoute: ContentWorkspaceRouteSchema.optional(),
25082
+ payloadFields: external_exports.array(ContentPayloadFieldDeclarationSchema).default([])
25083
+ });
25084
+ ContentSourceAssetKindDeclarationSchema = external_exports.object({
25085
+ label: external_exports.string().trim().min(1).max(160).optional(),
25086
+ description: external_exports.string().trim().min(1).max(2e3).optional(),
25087
+ /** D17: the template-declared serializable field list for this kind's payload. */
25055
25088
  payloadFields: external_exports.array(ContentPayloadFieldDeclarationSchema).default([])
25056
25089
  });
25057
25090
  }
@@ -46716,7 +46749,7 @@ var init_permissions = __esm({
46716
46749
  },
46717
46750
  {
46718
46751
  key: "content.manage",
46719
- description: "Create, update, and delete content pipeline records (content_source_assets, content_items, content_item_attempts, content_distributions, artifacts)",
46752
+ description: "Create, update, and delete content pipeline records (content_source_assets, content_items, content_item_attempts, content_distributions)",
46720
46753
  isOrgGrantable: false
46721
46754
  }
46722
46755
  ];
@@ -47686,20 +47719,11 @@ var init_observability = __esm({
47686
47719
  });
47687
47720
 
47688
47721
  // ../core/src/operations/activities/types.ts
47722
+ var ACTIVITY_TYPES, ACTIVITY_STATUSES, ACTOR_TYPES;
47689
47723
  var init_types14 = __esm({
47690
47724
  "../core/src/operations/activities/types.ts"() {
47691
47725
  "use strict";
47692
- }
47693
- });
47694
-
47695
- // ../core/src/operations/activities/api-schemas.ts
47696
- var ActivityTypeSchema, ActivityStatusSchema, MetadataSchema, CreateActivitySchema, ActivityTrendQuerySchema, ListActivitiesQuerySchema;
47697
- var init_api_schemas3 = __esm({
47698
- "../core/src/operations/activities/api-schemas.ts"() {
47699
- "use strict";
47700
- init_zod();
47701
- init_validation();
47702
- ActivityTypeSchema = external_exports.enum([
47726
+ ACTIVITY_TYPES = [
47703
47727
  "workflow_execution",
47704
47728
  "agent_run",
47705
47729
  "hitl_action",
@@ -47712,8 +47736,22 @@ var init_api_schemas3 = __esm({
47712
47736
  "agent_access_grant_change",
47713
47737
  "deployment_change",
47714
47738
  "membership_change"
47715
- ]);
47716
- ActivityStatusSchema = external_exports.enum(["success", "failure", "pending", "approved", "rejected", "completed"]);
47739
+ ];
47740
+ ACTIVITY_STATUSES = ["success", "failure", "pending", "approved", "rejected", "completed"];
47741
+ ACTOR_TYPES = ["user", "system", "api_key"];
47742
+ }
47743
+ });
47744
+
47745
+ // ../core/src/operations/activities/api-schemas.ts
47746
+ var ActivityTypeSchema, ActivityStatusSchema, MetadataSchema, CreateActivitySchema, ActivityTrendQuerySchema, ListActivitiesQuerySchema;
47747
+ var init_api_schemas3 = __esm({
47748
+ "../core/src/operations/activities/api-schemas.ts"() {
47749
+ "use strict";
47750
+ init_zod();
47751
+ init_validation();
47752
+ init_types14();
47753
+ ActivityTypeSchema = external_exports.enum(ACTIVITY_TYPES);
47754
+ ActivityStatusSchema = external_exports.enum(ACTIVITY_STATUSES);
47717
47755
  MetadataSchema = external_exports.record(external_exports.string(), external_exports.unknown()).refine((val) => JSON.stringify(val).length <= 5e4, "Metadata exceeds 50KB limit").optional();
47718
47756
  CreateActivitySchema = external_exports.object({
47719
47757
  activityType: ActivityTypeSchema,
@@ -47726,8 +47764,11 @@ var init_api_schemas3 = __esm({
47726
47764
  metadata: MetadataSchema,
47727
47765
  occurredAt: external_exports.string().datetime().optional(),
47728
47766
  actorId: external_exports.string().uuid().optional(),
47729
- actorType: external_exports.enum(["user", "system", "api_key"]).optional()
47767
+ actorType: external_exports.enum(ACTOR_TYPES).optional()
47730
47768
  // NO organizationId (always from JWT/API key context)
47769
+ // NO actorApiKeyId — an API-key actor is always server-derived from the authenticated
47770
+ // key (request.apiKeyContext), never caller-asserted. Accepting it here would let any
47771
+ // caller stamp an arbitrary key as the actor.
47731
47772
  }).strict();
47732
47773
  ActivityTrendQuerySchema = external_exports.object({
47733
47774
  activityType: ActivityTypeSchema.optional(),
@@ -48823,7 +48864,7 @@ var init_package = __esm({
48823
48864
  "package.json"() {
48824
48865
  package_default = {
48825
48866
  name: "@elevasis/sdk",
48826
- version: "1.46.0",
48867
+ version: "1.48.0",
48827
48868
  description: "SDK for building Elevasis organization resources",
48828
48869
  type: "module",
48829
48870
  bin: {
@@ -49427,18 +49468,18 @@ function getOrganizationModelDir(projectDir) {
49427
49468
  }
49428
49469
  function assertSplitLayout(projectDir) {
49429
49470
  const omDir = getOrganizationModelDir(projectDir);
49430
- const missing = REQUIRED_FILES.filter((f) => !(0, import_node_fs13.existsSync)((0, import_node_path11.join)(omDir, f)));
49471
+ const missing = REQUIRED_FILES.filter((f) => !(0, import_node_fs14.existsSync)((0, import_node_path11.join)(omDir, f)));
49431
49472
  if (missing.length > 0) {
49432
49473
  throw new Error(
49433
49474
  "Legacy single-file OM layout detected. Split into `core/config/organization-model/{profile.ts, systems.ts, navigation.ts}` before scaffolding."
49434
49475
  );
49435
49476
  }
49436
49477
  }
49437
- var import_node_fs13, import_node_path11, REQUIRED_FILES;
49478
+ var import_node_fs14, import_node_path11, REQUIRED_FILES;
49438
49479
  var init_project_layout = __esm({
49439
49480
  "src/cli/commands/om/project-layout.ts"() {
49440
49481
  "use strict";
49441
- import_node_fs13 = require("node:fs");
49482
+ import_node_fs14 = require("node:fs");
49442
49483
  import_node_path11 = require("node:path");
49443
49484
  REQUIRED_FILES = ["profile.ts", "systems.ts", "navigation.ts"];
49444
49485
  }
@@ -49538,8 +49579,9 @@ function emitSystemEntry(opts) {
49538
49579
  lifecycle: 'active',${apiInterfaceBlock}
49539
49580
  },
49540
49581
  `;
49582
+ const startAnchor = /^(?!\s*(?:\/\/|\*|\/\*)).*\bexport const templateSystems\s*=/m;
49541
49583
  const anchor = /^\] as const\s*$/m;
49542
- return { code, anchor, apiInterfaceNote };
49584
+ return { code, startAnchor, anchor, apiInterfaceNote };
49543
49585
  }
49544
49586
  var init_emit_system = __esm({
49545
49587
  "src/cli/commands/om/emit-system.ts"() {
@@ -49553,7 +49595,7 @@ async function withSnapshotRollback(filePaths, op) {
49553
49595
  const snapshots = /* @__PURE__ */ new Map();
49554
49596
  for (const filePath of filePaths) {
49555
49597
  try {
49556
- snapshots.set(filePath, (0, import_node_fs14.readFileSync)(filePath, "utf8"));
49598
+ snapshots.set(filePath, (0, import_node_fs15.readFileSync)(filePath, "utf8"));
49557
49599
  } catch {
49558
49600
  snapshots.set(filePath, null);
49559
49601
  }
@@ -49564,7 +49606,7 @@ async function withSnapshotRollback(filePaths, op) {
49564
49606
  for (const [filePath, snapshot] of snapshots) {
49565
49607
  if (snapshot !== null) {
49566
49608
  try {
49567
- (0, import_node_fs14.writeFileSync)(filePath, snapshot, "utf8");
49609
+ (0, import_node_fs15.writeFileSync)(filePath, snapshot, "utf8");
49568
49610
  } catch {
49569
49611
  }
49570
49612
  }
@@ -49601,9 +49643,9 @@ function reindent(code, baseIndent, extraIndent) {
49601
49643
  return lines.map((line) => line.trim() === "" ? line : baseIndent + extraIndent + line.slice(firstIndent.length)).join("\n");
49602
49644
  }
49603
49645
  async function appendBeforeAnchor(filePath, code, anchor, startAnchor) {
49604
- const content = (0, import_node_fs14.readFileSync)(filePath, "utf8");
49646
+ const content = (0, import_node_fs15.readFileSync)(filePath, "utf8");
49605
49647
  if (startAnchor === void 0) {
49606
- (0, import_node_fs14.writeFileSync)(filePath, insertBeforeAnchorInContent(content, code, anchor), "utf8");
49648
+ (0, import_node_fs15.writeFileSync)(filePath, insertBeforeAnchorInContent(content, code, anchor), "utf8");
49607
49649
  return;
49608
49650
  }
49609
49651
  const lines = content.split("\n");
@@ -49633,12 +49675,12 @@ async function appendBeforeAnchor(filePath, code, anchor, startAnchor) {
49633
49675
  lines[previousIndex] = previous.trimEnd() + ",";
49634
49676
  }
49635
49677
  lines.splice(anchorIndex, 0, ...indented.split("\n"));
49636
- (0, import_node_fs14.writeFileSync)(filePath, lines.join("\n"), "utf8");
49678
+ (0, import_node_fs15.writeFileSync)(filePath, lines.join("\n"), "utf8");
49637
49679
  }
49638
49680
  async function applyConstImport(systemsFilePath, importLine, fieldLine, importAnchor, fieldAnchor, newConstFilePath, newConstFileCode) {
49639
- (0, import_node_fs14.mkdirSync)((0, import_node_path12.dirname)(newConstFilePath), { recursive: true });
49640
- (0, import_node_fs14.writeFileSync)(newConstFilePath, newConstFileCode, "utf8");
49641
- const systemsContent = (0, import_node_fs14.readFileSync)(systemsFilePath, "utf8");
49681
+ (0, import_node_fs15.mkdirSync)((0, import_node_path12.dirname)(newConstFilePath), { recursive: true });
49682
+ (0, import_node_fs15.writeFileSync)(newConstFilePath, newConstFileCode, "utf8");
49683
+ const systemsContent = (0, import_node_fs15.readFileSync)(systemsFilePath, "utf8");
49642
49684
  const afterImport = insertBeforeAnchorInContent(systemsContent, importLine + "\n", importAnchor);
49643
49685
  const lines = afterImport.split("\n");
49644
49686
  const fieldAnchorIndex = findAnchorLineIndex(lines, afterImport, fieldAnchor);
@@ -49648,13 +49690,13 @@ async function applyConstImport(systemsFilePath, importLine, fieldLine, importAn
49648
49690
  );
49649
49691
  }
49650
49692
  lines.splice(fieldAnchorIndex + 1, 0, fieldLine);
49651
- (0, import_node_fs14.writeFileSync)(systemsFilePath, lines.join("\n"), "utf8");
49693
+ (0, import_node_fs15.writeFileSync)(systemsFilePath, lines.join("\n"), "utf8");
49652
49694
  }
49653
- var import_node_fs14, import_node_path12;
49695
+ var import_node_fs15, import_node_path12;
49654
49696
  var init_splice = __esm({
49655
49697
  "src/cli/commands/om/splice.ts"() {
49656
49698
  "use strict";
49657
- import_node_fs14 = require("node:fs");
49699
+ import_node_fs15 = require("node:fs");
49658
49700
  import_node_path12 = require("node:path");
49659
49701
  }
49660
49702
  });
@@ -49706,7 +49748,7 @@ async function scaffoldSystem(opts) {
49706
49748
  });
49707
49749
  apiBacked = answer.trim().toLowerCase() === "y";
49708
49750
  }
49709
- const { code, anchor, apiInterfaceNote } = emitSystemEntry({ id, title, kind, apiBacked });
49751
+ const { code, anchor, startAnchor, apiInterfaceNote } = emitSystemEntry({ id, title, kind, apiBacked });
49710
49752
  const shouldWrite = options.write === true || options.dryRun === false;
49711
49753
  if (!shouldWrite) {
49712
49754
  console.log(source_default.cyan("Dry-run mode (default) \u2014 no files written. Pass --write to apply.\n"));
@@ -49720,7 +49762,7 @@ async function scaffoldSystem(opts) {
49720
49762
  const systemsFilePath = (0, import_node_path13.join)(getOrganizationModelDir(projectDir), "systems.ts");
49721
49763
  try {
49722
49764
  await withSnapshotRollback([systemsFilePath], async () => {
49723
- await appendBeforeAnchor(systemsFilePath, code, anchor);
49765
+ await appendBeforeAnchor(systemsFilePath, code, anchor, startAnchor);
49724
49766
  const validationError = runValidation(projectDir);
49725
49767
  if (validationError !== null) {
49726
49768
  throw new Error(validationError);
@@ -49772,8 +49814,9 @@ function emitResourceEntry(opts) {
49772
49814
  ${ontologyBlock} codeRefs: []
49773
49815
  },
49774
49816
  `;
49775
- const anchor = /^export const templateResources\s*=/m;
49776
- return { code, anchor };
49817
+ const startAnchor = /^(?!\s*(?:\/\/|\*|\/\*)).*\btemplateResourceDescriptors\s*=/m;
49818
+ const anchor = /^\}/m;
49819
+ return { code, startAnchor, anchor };
49777
49820
  }
49778
49821
  var init_emit_resource = __esm({
49779
49822
  "src/cli/commands/om/emit-resource.ts"() {
@@ -49827,7 +49870,7 @@ async function scaffoldResource(opts) {
49827
49870
  { default: "" }
49828
49871
  );
49829
49872
  const primaryAction = rawPrimaryAction || void 0;
49830
- const { code, anchor } = emitResourceEntry({ id, systemPath, title, primaryAction });
49873
+ const { code, anchor, startAnchor } = emitResourceEntry({ id, systemPath, title, primaryAction });
49831
49874
  const shouldWrite = options.write === true || options.dryRun === false;
49832
49875
  if (!shouldWrite) {
49833
49876
  console.log(source_default.cyan("Dry-run mode (default) \u2014 no files written. Pass --write to apply.\n"));
@@ -49838,7 +49881,7 @@ async function scaffoldResource(opts) {
49838
49881
  const systemsFilePath = (0, import_node_path14.join)(getOrganizationModelDir(projectDir), "systems.ts");
49839
49882
  try {
49840
49883
  await withSnapshotRollback([systemsFilePath], async () => {
49841
- await appendBeforeAnchor(systemsFilePath, code, anchor);
49884
+ await appendBeforeAnchor(systemsFilePath, code, anchor, startAnchor);
49842
49885
  const validationError = runValidation2(projectDir);
49843
49886
  if (validationError !== null) {
49844
49887
  const systemPathHint = /systemPath.*not assignable/i.test(validationError) ? `
@@ -50109,7 +50152,7 @@ async function scaffoldKnowledge(opts) {
50109
50152
  }
50110
50153
  const rawKind = await promptIfAbsent(
50111
50154
  options.kind,
50112
- "Node kind (playbook / strategy / reference / policy)",
50155
+ "Node kind (playbook / strategy / reference)",
50113
50156
  { default: "reference" }
50114
50157
  );
50115
50158
  const kind = rawKind || "reference";
@@ -50134,30 +50177,30 @@ async function scaffoldKnowledge(opts) {
50134
50177
  return;
50135
50178
  }
50136
50179
  const absoluteFilePath = (0, import_node_path16.join)(projectDir, relativeFilePath);
50137
- if ((0, import_node_fs15.existsSync)(absoluteFilePath)) {
50180
+ if ((0, import_node_fs16.existsSync)(absoluteFilePath)) {
50138
50181
  process.stderr.write(
50139
50182
  source_default.red(`Knowledge node file already exists at \`${relativeFilePath}\`. Choose a different id.
50140
50183
  `)
50141
50184
  );
50142
50185
  process.exit(1);
50143
50186
  }
50144
- (0, import_node_fs15.mkdirSync)((0, import_node_path16.join)(projectDir, "core", "config", "knowledge", "nodes"), { recursive: true });
50145
- (0, import_node_fs15.writeFileSync)(absoluteFilePath, content, "utf8");
50187
+ (0, import_node_fs16.mkdirSync)((0, import_node_path16.join)(projectDir, "core", "config", "knowledge", "nodes"), { recursive: true });
50188
+ (0, import_node_fs16.writeFileSync)(absoluteFilePath, content, "utf8");
50146
50189
  console.log(source_default.green(`Knowledge node \`${id}\` written to \`${relativeFilePath}\``));
50147
50190
  console.log(source_default.yellow("Run `elevasis-sdk knowledge:generate` to register this node."));
50148
50191
  }
50149
- var import_node_path16, import_node_fs15, VALID_KINDS;
50192
+ var import_node_path16, import_node_fs16, VALID_KINDS;
50150
50193
  var init_scaffold_knowledge = __esm({
50151
50194
  "src/cli/commands/om/scaffold-knowledge.ts"() {
50152
50195
  "use strict";
50153
50196
  import_node_path16 = require("node:path");
50154
- import_node_fs15 = require("node:fs");
50197
+ import_node_fs16 = require("node:fs");
50155
50198
  init_source();
50156
50199
  init_config2();
50157
50200
  init_project_layout();
50158
50201
  init_prompt_helpers();
50159
50202
  init_emit_knowledge();
50160
- VALID_KINDS = ["playbook", "strategy", "reference", "policy"];
50203
+ VALID_KINDS = ["playbook", "strategy", "reference"];
50161
50204
  }
50162
50205
  });
50163
50206
 
@@ -50170,7 +50213,13 @@ function emitApiInterfaceBlock(gap) {
50170
50213
  const cataloged = SYSTEM_INTERFACE_PROFILES.find(
50171
50214
  (profile) => profile.systemPath === gap.systemPath && profile.interfaceKey === "api"
50172
50215
  );
50173
- const readinessProfile = cataloged?.readinessProfile ?? `${gap.systemPath}.api`;
50216
+ if (cataloged === void 0) {
50217
+ const adoptable = SYSTEM_INTERFACE_PROFILES.filter((profile) => profile.interfaceKey === "api").map((profile) => `"${profile.systemPath}"`).join(", ");
50218
+ throw new Error(
50219
+ `Cannot emit an apiInterface for system path "${gap.systemPath}": it adopts no cataloged platform API capability, so any readinessProfile emitted for it would name a route the API does not serve. Adoptable system paths are ${adoptable}. A custom System extends behavior through workflows/operations plus ontology, resources, and topology \u2014 omitting apiInterface entirely is the designed opt-out.`
50220
+ );
50221
+ }
50222
+ const readinessProfile = cataloged.readinessProfile;
50174
50223
  const resourceIdsField = gap.resourceIds.length === 0 ? "" : `,
50175
50224
  resourceIds: [
50176
50225
  ${gap.resourceIds.map((id) => `'${id}'`).join(",\n ")}
@@ -50233,7 +50282,7 @@ async function scaffoldFill(opts) {
50233
50282
  process.stderr.write(source_default.red("Missing gaps file. Pass --gaps <path> pointing to a conformance gap JSON file.\n"));
50234
50283
  process.exit(1);
50235
50284
  }
50236
- if (!(0, import_node_fs16.existsSync)(options.gaps)) {
50285
+ if (!(0, import_node_fs17.existsSync)(options.gaps)) {
50237
50286
  process.stderr.write(
50238
50287
  source_default.red(
50239
50288
  `Missing gaps file. Pass --gaps <path> pointing to a conformance gap JSON file.
@@ -50245,7 +50294,7 @@ async function scaffoldFill(opts) {
50245
50294
  }
50246
50295
  let payload;
50247
50296
  try {
50248
- const raw = (0, import_node_fs16.readFileSync)(options.gaps, "utf8");
50297
+ const raw = (0, import_node_fs17.readFileSync)(options.gaps, "utf8");
50249
50298
  payload = JSON.parse(raw);
50250
50299
  } catch {
50251
50300
  process.stderr.write(
@@ -50353,7 +50402,7 @@ async function scaffoldFill(opts) {
50353
50402
  }
50354
50403
  if (skippedGaps.length > 0) {
50355
50404
  const skippedPath = options.skipped ?? (0, import_node_path17.join)(os2.tmpdir(), `elevasis-fill-skipped-${systemPath}-${Date.now()}.json`);
50356
- (0, import_node_fs16.writeFileSync)(skippedPath, JSON.stringify({ systemPath, skipped: skippedGaps }, null, 2), "utf8");
50405
+ (0, import_node_fs17.writeFileSync)(skippedPath, JSON.stringify({ systemPath, skipped: skippedGaps }, null, 2), "utf8");
50357
50406
  console.log(
50358
50407
  source_default.yellow(
50359
50408
  `Partial fill: ${appliedGaps.length} gap(s) applied, ${skippedGaps.length} skipped \u2014 see \`${skippedPath}\` for fields requiring manual input.`
@@ -50367,13 +50416,13 @@ async function scaffoldFill(opts) {
50367
50416
  )
50368
50417
  );
50369
50418
  }
50370
- var import_node_path17, os2, import_node_fs16, import_node_child_process5;
50419
+ var import_node_path17, os2, import_node_fs17, import_node_child_process5;
50371
50420
  var init_scaffold_fill = __esm({
50372
50421
  "src/cli/commands/om/scaffold-fill.ts"() {
50373
50422
  "use strict";
50374
50423
  import_node_path17 = require("node:path");
50375
50424
  os2 = __toESM(require("node:os"), 1);
50376
- import_node_fs16 = require("node:fs");
50425
+ import_node_fs17 = require("node:fs");
50377
50426
  import_node_child_process5 = require("node:child_process");
50378
50427
  init_source();
50379
50428
  init_config2();
@@ -55781,6 +55830,656 @@ function registerClientCommands(program3) {
55781
55830
  registerClientDelete(program3);
55782
55831
  }
55783
55832
 
55833
+ // src/cli/commands/content/list.ts
55834
+ init_source();
55835
+ init_api_client();
55836
+ init_config2();
55837
+ init_wrap_action();
55838
+ function appendQuery4(params, key, value) {
55839
+ if (value === void 0 || value === null || value === "") return;
55840
+ params.set(key, String(value));
55841
+ }
55842
+ function registerContentList(program3) {
55843
+ program3.command("content:list").description(
55844
+ "List content pipeline items\n Example: elevasis-sdk content:list --status queued --pipeline-id short-form-repurpose"
55845
+ ).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
+ wrapAction("content:list", async (options) => {
55847
+ const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
55848
+ const params = new URLSearchParams();
55849
+ appendQuery4(params, "status", options.status);
55850
+ appendQuery4(params, "pillar", options.pillar);
55851
+ appendQuery4(params, "pipelineId", options.pipelineId);
55852
+ appendQuery4(params, "clientId", options.clientId);
55853
+ appendQuery4(params, "reviewedBy", options.reviewedBy);
55854
+ appendQuery4(params, "search", options.search);
55855
+ appendQuery4(params, "limit", options.limit);
55856
+ appendQuery4(params, "offset", options.offset);
55857
+ const query = params.toString();
55858
+ const endpoint = query ? `/api/external/content/items?${query}` : "/api/external/content/items";
55859
+ const result = await apiGet(endpoint, apiUrl);
55860
+ if (!options.pretty) {
55861
+ console.log(JSON.stringify(result, null, 2));
55862
+ return;
55863
+ }
55864
+ if (result.data.length === 0) {
55865
+ console.log(source_default.yellow("No content items found."));
55866
+ return;
55867
+ }
55868
+ console.log(source_default.cyan(`
55869
+ Content items (${result.data.length} of ${result.total}):
55870
+ `));
55871
+ for (const item of result.data) {
55872
+ console.log(` ${source_default.bold(item.title)} ${source_default.gray(item.status)}`);
55873
+ console.log(source_default.gray(` ID: ${item.id}`));
55874
+ if (item.pipelineId) console.log(source_default.gray(` Pipeline: ${item.pipelineId}`));
55875
+ if (item.pillar) console.log(source_default.gray(` Pillar: ${item.pillar}`));
55876
+ }
55877
+ console.log();
55878
+ })
55879
+ );
55880
+ }
55881
+
55882
+ // src/cli/commands/content/get.ts
55883
+ init_source();
55884
+ init_api_client();
55885
+ init_config2();
55886
+ init_wrap_action();
55887
+ function registerContentGet(program3) {
55888
+ program3.command("content:get <itemId>").description(
55889
+ "Get a content item, its attempts, and its distributions in one call\n Example: elevasis-sdk content:get <uuid>"
55890
+ ).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(
55891
+ wrapAction("content:get", async (itemId, options) => {
55892
+ const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
55893
+ const result = await apiGet(`/api/external/content/items/${itemId}`, apiUrl);
55894
+ if (!options.pretty) {
55895
+ console.log(JSON.stringify(result, null, 2));
55896
+ return;
55897
+ }
55898
+ const { item, attempts, distributions } = result;
55899
+ console.log(source_default.cyan(`
55900
+ Content item: ${item.title}`));
55901
+ console.log(source_default.gray(` ID: ${item.id}`));
55902
+ console.log(source_default.gray(` Status: ${item.status}`));
55903
+ if (item.pipelineId) console.log(source_default.gray(` Pipeline: ${item.pipelineId}`));
55904
+ console.log(source_default.gray(` Attempts (${attempts.length}):`));
55905
+ for (const attempt of attempts) {
55906
+ const execution = attempt.sourceExecutionId ? ` execution=${attempt.sourceExecutionId}` : "";
55907
+ console.log(source_default.gray(` - ${attempt.stepKey ?? "(no step)"}: ${attempt.status}${execution}`));
55908
+ }
55909
+ console.log(source_default.gray(` Distributions (${distributions.length}):`));
55910
+ for (const distribution of distributions) {
55911
+ console.log(source_default.gray(` - ${distribution.platform}/${distribution.format}: ${distribution.status}`));
55912
+ }
55913
+ console.log();
55914
+ })
55915
+ );
55916
+ }
55917
+
55918
+ // src/cli/commands/content/board.ts
55919
+ init_source();
55920
+
55921
+ // ../core/src/content/derive-board.ts
55922
+ function sortPipelineSteps(steps) {
55923
+ return [...steps].sort((a, b) => {
55924
+ if (a.order !== b.order) return a.order - b.order;
55925
+ return a.key < b.key ? -1 : a.key > b.key ? 1 : 0;
55926
+ });
55927
+ }
55928
+ function deriveItemPlacement(item, sortedSteps) {
55929
+ const processingState = item.processingState;
55930
+ const stateKeys = Object.keys(processingState);
55931
+ if (stateKeys.length > 0) {
55932
+ const catalogKeys = new Set(sortedSteps.map((step) => step.key));
55933
+ const hasKnownKey = stateKeys.some((key) => catalogKeys.has(key));
55934
+ if (!hasKnownKey) {
55935
+ return { bucket: "unplaced", stepKey: null };
55936
+ }
55937
+ }
55938
+ const currentStep = sortedSteps.find((step) => {
55939
+ const entry = processingState[step.key];
55940
+ return !entry || entry.status !== "success";
55941
+ });
55942
+ if (!currentStep) {
55943
+ const lastStep = sortedSteps[sortedSteps.length - 1];
55944
+ if (lastStep !== void 0 && lastStep.reviewMode !== "none" && item.reviewedAt === null) {
55945
+ return { bucket: "column", stepKey: lastStep.key };
55946
+ }
55947
+ return { bucket: "done", stepKey: null };
55948
+ }
55949
+ return { bucket: "column", stepKey: currentStep.key };
55950
+ }
55951
+ function deriveAwaitingReview(step, item) {
55952
+ if (!step) return false;
55953
+ return step.reviewMode !== "none" && item.reviewedAt === null;
55954
+ }
55955
+ function deriveContentBoard(items, pipeline, now) {
55956
+ const sortedSteps = sortPipelineSteps(pipeline.steps);
55957
+ const stepsByKey = new Map(sortedSteps.map((step) => [step.key, step]));
55958
+ const cardsByStepKey = /* @__PURE__ */ new Map();
55959
+ const done = [];
55960
+ const unplaced = [];
55961
+ for (const item of items) {
55962
+ const placement = deriveItemPlacement(item, sortedSteps);
55963
+ const step = placement.stepKey ? stepsByKey.get(placement.stepKey) : void 0;
55964
+ const card = {
55965
+ item,
55966
+ stepKey: placement.stepKey,
55967
+ ageMs: now - Date.parse(item.updatedAt),
55968
+ awaitingReview: deriveAwaitingReview(step, item)
55969
+ };
55970
+ if (placement.bucket === "done") {
55971
+ done.push(card);
55972
+ } else if (placement.bucket === "unplaced") {
55973
+ unplaced.push(card);
55974
+ } else if (placement.stepKey) {
55975
+ const existing = cardsByStepKey.get(placement.stepKey);
55976
+ if (existing) {
55977
+ existing.push(card);
55978
+ } else {
55979
+ cardsByStepKey.set(placement.stepKey, [card]);
55980
+ }
55981
+ }
55982
+ }
55983
+ const byAgeDescending = (a, b) => b.ageMs - a.ageMs;
55984
+ for (const cards of cardsByStepKey.values()) {
55985
+ cards.sort(byAgeDescending);
55986
+ }
55987
+ done.sort(byAgeDescending);
55988
+ unplaced.sort(byAgeDescending);
55989
+ const columns = sortedSteps.map((step) => {
55990
+ const cards = cardsByStepKey.get(step.key) ?? [];
55991
+ const column = { step, cards };
55992
+ if (step.reviewMode === "live" || step.reviewMode === "queued") {
55993
+ column.gate = {
55994
+ reviewMode: step.reviewMode,
55995
+ waitingCount: cards.filter((card) => card.awaitingReview).length
55996
+ };
55997
+ }
55998
+ return column;
55999
+ });
56000
+ return {
56001
+ columns,
56002
+ done,
56003
+ unplaced,
56004
+ isCollapsed: pipeline.steps.length <= 1
56005
+ };
56006
+ }
56007
+
56008
+ // ../core/src/content/item-identity.ts
56009
+ function getContentItemIdentity(item, payloadFields, maxLength = 80) {
56010
+ const candidate = resolveIdentityCandidate(item, payloadFields);
56011
+ return normalizeIdentity(candidate, maxLength);
56012
+ }
56013
+ function resolveIdentityCandidate(item, payloadFields) {
56014
+ const firstBodyLine = getFirstNonBlankLine(item.body);
56015
+ if (firstBodyLine) return firstBodyLine;
56016
+ const payloadField = getFirstStringPayloadValue(item.payload, payloadFields);
56017
+ if (payloadField) return payloadField;
56018
+ if (isNonBlank(item.title)) return item.title;
56019
+ return "Untitled";
56020
+ }
56021
+ function getFirstNonBlankLine(text) {
56022
+ if (!text) return void 0;
56023
+ for (const line of text.split("\n")) {
56024
+ if (isNonBlank(line)) return line.trim();
56025
+ }
56026
+ return void 0;
56027
+ }
56028
+ function getFirstStringPayloadValue(payload, payloadFields) {
56029
+ if (typeof payload !== "object" || payload === null || Array.isArray(payload)) return void 0;
56030
+ const record2 = payload;
56031
+ const keys = payloadFields && payloadFields.length > 0 ? payloadFields.map((field2) => field2.key) : Object.keys(record2);
56032
+ for (const key of keys) {
56033
+ const value = record2[key];
56034
+ if (typeof value === "string" && isNonBlank(value)) return value;
56035
+ }
56036
+ return void 0;
56037
+ }
56038
+ function isNonBlank(value) {
56039
+ return value.trim().length > 0;
56040
+ }
56041
+ function normalizeIdentity(candidate, maxLength) {
56042
+ const collapsed = candidate.replace(/\s+/g, " ").trim();
56043
+ if (collapsed.length <= maxLength) return collapsed;
56044
+ const truncated = collapsed.slice(0, maxLength);
56045
+ const lastSpace = truncated.lastIndexOf(" ");
56046
+ const cut = lastSpace > 0 ? truncated.slice(0, lastSpace) : truncated;
56047
+ return `${cut}\u2026`;
56048
+ }
56049
+
56050
+ // src/cli/commands/content/board.ts
56051
+ init_api_client();
56052
+ init_config2();
56053
+ init_wrap_action();
56054
+ var DEFAULT_ITEM_LIMIT = 100;
56055
+ function formatAge(ageMs) {
56056
+ if (!Number.isFinite(ageMs) || ageMs < 0) return "--";
56057
+ const minutes = Math.floor(ageMs / 6e4);
56058
+ if (minutes < 60) return `${minutes}m`;
56059
+ const hours = Math.floor(minutes / 60);
56060
+ if (hours < 24) return `${hours}h`;
56061
+ const days = Math.floor(hours / 24);
56062
+ return `${days}d ${hours % 24}h`;
56063
+ }
56064
+ function printCards(cards, stepsByKey) {
56065
+ if (cards.length === 0) {
56066
+ console.log(source_default.gray(" (empty)"));
56067
+ return;
56068
+ }
56069
+ for (const card of cards) {
56070
+ const payloadFields = card.stepKey ? stepsByKey.get(card.stepKey)?.payloadFields : void 0;
56071
+ const identity = getContentItemIdentity(card.item, payloadFields);
56072
+ const age = source_default.gray(formatAge(card.ageMs));
56073
+ const waiting = card.awaitingReview ? source_default.yellow(" [awaiting review]") : "";
56074
+ console.log(` ${identity}${waiting} ${age}`);
56075
+ console.log(source_default.gray(` ${card.item.id}`));
56076
+ }
56077
+ }
56078
+ function registerContentBoard(program3) {
56079
+ 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 short-form-repurpose --pretty"
56081
+ ).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
+ wrapAction("content:board", async (pipelineId, options) => {
56083
+ const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
56084
+ const limit = options.limit ?? String(DEFAULT_ITEM_LIMIT);
56085
+ const pipeline = await apiGet(`/api/external/content/pipelines/${pipelineId}`, apiUrl);
56086
+ const params = new URLSearchParams({ pipelineId, limit });
56087
+ const items = await apiGet(`/api/external/content/items?${params.toString()}`, apiUrl);
56088
+ const board = deriveContentBoard(items.data, pipeline, Date.now());
56089
+ const stepsByKey = new Map(pipeline.steps.map((step) => [step.key, step]));
56090
+ const truncated = items.total > items.data.length;
56091
+ if (!options.pretty) {
56092
+ console.log(JSON.stringify({ pipelineId, total: items.total, truncated, board }, null, 2));
56093
+ return;
56094
+ }
56095
+ console.log(
56096
+ source_default.cyan(`
56097
+ Board: ${pipelineId} ${source_default.gray(`${items.data.length} of ${items.total} item(s)`)}`)
56098
+ );
56099
+ if (truncated) {
56100
+ console.log(
56101
+ source_default.yellow(
56102
+ ` Showing ${items.data.length} of ${items.total} items -- this board is PARTIAL. ${DEFAULT_ITEM_LIMIT} is the API's page ceiling, so the rest are not on it. Narrow with content:list, or read the remainder with content:list --offset.`
56103
+ )
56104
+ );
56105
+ }
56106
+ if (board.isCollapsed) {
56107
+ console.log(source_default.gray(" This pipeline declares 0 or 1 steps, so it has no columns to speak of."));
56108
+ }
56109
+ console.log();
56110
+ for (const column of board.columns) {
56111
+ const gate = column.gate ? source_default.yellow(` [${column.gate.reviewMode} gate -- ${column.gate.waitingCount} waiting]`) : "";
56112
+ console.log(` ${source_default.bold(column.step.label)} ${source_default.gray(column.step.key)}${gate}`);
56113
+ printCards(column.cards, stepsByKey);
56114
+ }
56115
+ console.log(`
56116
+ ${source_default.bold("Done")} ${source_default.gray(`(${board.done.length})`)}`);
56117
+ printCards(board.done, stepsByKey);
56118
+ if (board.unplaced.length > 0) {
56119
+ console.log(
56120
+ `
56121
+ ${source_default.bold("Unplaced")} ${source_default.gray(`(${board.unplaced.length}) -- processingState names no step this pipeline declares`)}`
56122
+ );
56123
+ printCards(board.unplaced, stepsByKey);
56124
+ }
56125
+ console.log();
56126
+ })
56127
+ );
56128
+ }
56129
+
56130
+ // src/cli/commands/content/queue.ts
56131
+ init_source();
56132
+ init_api_client();
56133
+ init_config2();
56134
+ init_wrap_action();
56135
+ function registerContentQueue(program3) {
56136
+ program3.command("content:queue").description("List content items awaiting a `queued`-gate review\n Example: elevasis-sdk content:queue --pretty").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(
56137
+ wrapAction("content:queue", async (options) => {
56138
+ const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
56139
+ const result = await apiGet("/api/external/content/queue", apiUrl);
56140
+ if (!options.pretty) {
56141
+ console.log(JSON.stringify(result, null, 2));
56142
+ return;
56143
+ }
56144
+ if (result.data.length === 0) {
56145
+ console.log(source_default.yellow("No content items are awaiting review."));
56146
+ return;
56147
+ }
56148
+ console.log(source_default.cyan(`
56149
+ Queued for review (${result.data.length}):
56150
+ `));
56151
+ for (const entry of result.data) {
56152
+ console.log(` ${source_default.bold(entry.item.title)} ${source_default.gray(entry.stepKey)}`);
56153
+ console.log(source_default.gray(` Item ID: ${entry.item.id}`));
56154
+ console.log(source_default.gray(` Attempt ID: ${entry.attemptId}`));
56155
+ console.log(source_default.gray(` Attempted: ${entry.attemptedAt}`));
56156
+ }
56157
+ console.log();
56158
+ })
56159
+ );
56160
+ }
56161
+
56162
+ // src/cli/commands/content/pipeline.ts
56163
+ init_source();
56164
+ init_api_client();
56165
+ init_config2();
56166
+ init_wrap_action();
56167
+ function printPipelineSummary(pipeline) {
56168
+ console.log(source_default.cyan(`
56169
+ Pipeline: ${pipeline.id}`));
56170
+ const steps = Array.isArray(pipeline.steps) ? pipeline.steps : [];
56171
+ console.log(source_default.gray(` Steps (${steps.length}):`));
56172
+ for (const step of steps) {
56173
+ console.log(source_default.gray(` - ${step.key} (reviewMode: ${step.reviewMode})`));
56174
+ }
56175
+ console.log();
56176
+ }
56177
+ function registerContentPipeline(program3) {
56178
+ program3.command("content:pipeline [id]").description(
56179
+ "List content pipeline templates, or show one pipeline's step contract\n Example: elevasis-sdk content:pipeline short-form-repurpose"
56180
+ ).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
+ wrapAction("content:pipeline", async (id, options) => {
56182
+ const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
56183
+ if (!id) {
56184
+ const result = await apiGet("/api/external/content/pipelines", apiUrl);
56185
+ if (!options.pretty) {
56186
+ console.log(JSON.stringify(result, null, 2));
56187
+ return;
56188
+ }
56189
+ if (result.data.length === 0) {
56190
+ console.log(source_default.yellow("No content pipelines found."));
56191
+ return;
56192
+ }
56193
+ console.log(source_default.cyan(`
56194
+ Content pipelines (${result.data.length}):
56195
+ `));
56196
+ for (const pipeline2 of result.data) {
56197
+ const steps = Array.isArray(pipeline2.steps) ? pipeline2.steps : [];
56198
+ console.log(` ${source_default.bold(pipeline2.id)} ${source_default.gray(`${steps.length} step(s)`)}`);
56199
+ }
56200
+ console.log();
56201
+ return;
56202
+ }
56203
+ const pipeline = await apiGet(`/api/external/content/pipelines/${id}`, apiUrl);
56204
+ if (!options.pretty) {
56205
+ console.log(JSON.stringify(pipeline, null, 2));
56206
+ return;
56207
+ }
56208
+ printPipelineSummary(pipeline);
56209
+ })
56210
+ );
56211
+ }
56212
+
56213
+ // src/cli/commands/content/distributions.ts
56214
+ init_source();
56215
+ init_api_client();
56216
+ init_config2();
56217
+ init_wrap_action();
56218
+ function appendQuery5(params, key, value) {
56219
+ if (value === void 0 || value === null || value === "") return;
56220
+ params.set(key, String(value));
56221
+ }
56222
+ function registerContentDistributions(program3) {
56223
+ program3.command("content:distributions").description(
56224
+ "List content distributions\n Example: elevasis-sdk content:distributions --pipeline-id short-form-repurpose"
56225
+ ).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
+ wrapAction("content:distributions", async (options) => {
56227
+ const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
56228
+ const params = new URLSearchParams();
56229
+ appendQuery5(params, "contentItemId", options.contentItemId);
56230
+ appendQuery5(params, "pipelineId", options.pipelineId);
56231
+ appendQuery5(params, "platform", options.platform);
56232
+ appendQuery5(params, "status", options.status);
56233
+ appendQuery5(params, "limit", options.limit);
56234
+ appendQuery5(params, "offset", options.offset);
56235
+ const query = params.toString();
56236
+ const endpoint = query ? `/api/external/content/distributions?${query}` : "/api/external/content/distributions";
56237
+ const result = await apiGet(endpoint, apiUrl);
56238
+ if (!options.pretty) {
56239
+ console.log(JSON.stringify(result, null, 2));
56240
+ return;
56241
+ }
56242
+ if (result.data.length === 0) {
56243
+ console.log(source_default.yellow("No content distributions found."));
56244
+ return;
56245
+ }
56246
+ console.log(source_default.cyan(`
56247
+ Content distributions (${result.data.length}):
56248
+ `));
56249
+ for (const distribution of result.data) {
56250
+ console.log(
56251
+ ` ${source_default.bold(`${distribution.platform}/${distribution.format}`)} ${source_default.gray(distribution.status)}`
56252
+ );
56253
+ console.log(source_default.gray(` ID: ${distribution.id}`));
56254
+ console.log(source_default.gray(` Item ID: ${distribution.contentItemId}`));
56255
+ }
56256
+ console.log();
56257
+ })
56258
+ );
56259
+ }
56260
+
56261
+ // src/cli/commands/content/review.ts
56262
+ init_source();
56263
+ init_api_client();
56264
+ init_config2();
56265
+ init_wrap_action();
56266
+ function registerContentReview(program3) {
56267
+ program3.command("content:review <itemId>").description(
56268
+ "Clear a queued review gate on a content item\n Example: elevasis-sdk content:review <uuid> --step draft-review --approve --user reviewer@example.com"
56269
+ ).requiredOption("--step <key>", "The stepKey of the queued gate to clear (from `content:queue`)").requiredOption(
56270
+ "--user <email>",
56271
+ "The acting reviewer\u2019s email -- must be an active member of the API key\u2019s organization"
56272
+ ).option("--approve", "Approve the item at this step").option("--reject", "Reject the item at this step (requires --reason)").option("--feedback <text>", "Optional reviewer feedback (1..5000 chars)").option("--reason <text>", "Reason for rejection -- required when --reject is set").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(
56273
+ wrapAction("content:review", async (itemId, options) => {
56274
+ if (options.approve && options.reject) {
56275
+ throw new Error("Pass exactly one of --approve or --reject, not both");
56276
+ }
56277
+ if (!options.approve && !options.reject) {
56278
+ throw new Error("Pass one of --approve or --reject");
56279
+ }
56280
+ if (options.reject && !options.reason) {
56281
+ throw new Error("--reject requires --reason");
56282
+ }
56283
+ const decision = options.approve ? "approved" : "rejected";
56284
+ const body = {
56285
+ user_email: options.user,
56286
+ stepKey: options.step,
56287
+ decision
56288
+ };
56289
+ if (options.feedback !== void 0) body.reviewerFeedback = options.feedback;
56290
+ if (options.reject) body.rejectReason = options.reason;
56291
+ const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
56292
+ const result = await apiPost(
56293
+ `/api/external/content/items/${itemId}/review`,
56294
+ body,
56295
+ apiUrl
56296
+ );
56297
+ if (!options.pretty) {
56298
+ console.log(JSON.stringify(result, null, 2));
56299
+ return;
56300
+ }
56301
+ const verb = decision === "approved" ? source_default.green("approved") : source_default.red("rejected");
56302
+ console.log(source_default.cyan(`
56303
+ Content item ${itemId} ${verb} at step ${options.step}`));
56304
+ if (result.item?.status) console.log(source_default.gray(` Status: ${result.item.status}`));
56305
+ console.log();
56306
+ })
56307
+ );
56308
+ }
56309
+
56310
+ // src/cli/commands/content/source-assets.ts
56311
+ init_source();
56312
+ init_api_client();
56313
+ init_config2();
56314
+ init_wrap_action();
56315
+ function appendQuery6(params, key, value) {
56316
+ if (value === void 0 || value === null || value === "") return;
56317
+ params.set(key, String(value));
56318
+ }
56319
+ function registerContentSourceAssets(program3) {
56320
+ program3.command("content:source-assets").description(
56321
+ "List content source assets (raw material)\n Example: elevasis-sdk content:source-assets --kind transcript --limit 10"
56322
+ ).option("--kind <kind>", "Filter by source asset kind (e.g. transcript)").option("--limit <n>", "Maximum number of results").option("--offset <n>", "Pagination offset").option("--prod", "Target production (overrides NODE_ENV=development)").option("--api-url <url>", "API base URL").option("--pretty", "Render human-readable output instead of raw JSON").action(
56323
+ wrapAction("content:source-assets", async (options) => {
56324
+ const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
56325
+ const params = new URLSearchParams();
56326
+ appendQuery6(params, "kind", options.kind);
56327
+ appendQuery6(params, "limit", options.limit);
56328
+ appendQuery6(params, "offset", options.offset);
56329
+ const query = params.toString();
56330
+ const endpoint = query ? `/api/external/content/source-assets?${query}` : "/api/external/content/source-assets";
56331
+ const result = await apiGet(endpoint, apiUrl);
56332
+ if (!options.pretty) {
56333
+ console.log(JSON.stringify(result, null, 2));
56334
+ return;
56335
+ }
56336
+ if (result.data.length === 0) {
56337
+ console.log(source_default.yellow("No content source assets found."));
56338
+ return;
56339
+ }
56340
+ console.log(source_default.cyan(`
56341
+ Content source assets (${result.data.length} of ${result.total}):
56342
+ `));
56343
+ for (const asset of result.data) {
56344
+ console.log(` ${source_default.bold(asset.title)} ${source_default.gray(asset.kind)}`);
56345
+ console.log(source_default.gray(` ID: ${asset.id}`));
56346
+ if (asset.externalUrl) console.log(source_default.gray(` URL: ${asset.externalUrl}`));
56347
+ if (asset.durationSeconds) console.log(source_default.gray(` Duration: ${asset.durationSeconds}s`));
56348
+ }
56349
+ console.log();
56350
+ })
56351
+ );
56352
+ }
56353
+
56354
+ // src/cli/commands/content/source-asset.ts
56355
+ init_source();
56356
+ init_api_client();
56357
+ init_config2();
56358
+ init_wrap_action();
56359
+ function registerContentSourceAsset(program3) {
56360
+ program3.command("content:source-asset <sourceAssetId>").description(
56361
+ "Get one content source asset, including its payload\n Example: elevasis-sdk content:source-asset <uuid>"
56362
+ ).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(
56363
+ wrapAction("content:source-asset", async (sourceAssetId, options) => {
56364
+ const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
56365
+ const asset = await apiGet(`/api/external/content/source-assets/${sourceAssetId}`, apiUrl);
56366
+ if (!options.pretty) {
56367
+ console.log(JSON.stringify(asset, null, 2));
56368
+ return;
56369
+ }
56370
+ console.log(source_default.cyan(`
56371
+ ${asset.title}`));
56372
+ console.log(source_default.gray(` ID: ${asset.id}`));
56373
+ console.log(source_default.gray(` Kind: ${asset.kind}`));
56374
+ if (asset.externalUrl) console.log(source_default.gray(` URL: ${asset.externalUrl}`));
56375
+ if (asset.durationSeconds) console.log(source_default.gray(` Duration: ${asset.durationSeconds}s`));
56376
+ const payloadKeys = Object.keys(asset.payload ?? {});
56377
+ if (payloadKeys.length > 0) {
56378
+ console.log(source_default.cyan("\n Payload:"));
56379
+ for (const key of payloadKeys) {
56380
+ const value = asset.payload[key];
56381
+ const rendered = typeof value === "string" ? value : JSON.stringify(value);
56382
+ console.log(source_default.gray(` ${key}:`));
56383
+ console.log(` ${rendered.split("\n").join("\n ")}`);
56384
+ }
56385
+ }
56386
+ console.log();
56387
+ })
56388
+ );
56389
+ }
56390
+
56391
+ // src/cli/commands/content/source-asset-create.ts
56392
+ var import_node_fs10 = require("node:fs");
56393
+ init_source();
56394
+ init_api_client();
56395
+ init_config2();
56396
+ init_wrap_action();
56397
+ var PAYLOAD_MAX_BYTES = 5e5;
56398
+ function resolveTextArgument(value) {
56399
+ if (!value.startsWith("@")) return value;
56400
+ const path3 = value.slice(1);
56401
+ try {
56402
+ return (0, import_node_fs10.readFileSync)(path3, "utf8");
56403
+ } catch (error46) {
56404
+ throw new Error(`Could not read --text file "${path3}": ${error46 instanceof Error ? error46.message : String(error46)}`);
56405
+ }
56406
+ }
56407
+ function registerContentSourceAssetCreate(program3) {
56408
+ program3.command("content:source-asset:create").description(
56409
+ '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
+ ).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
+ "--field <key>",
56412
+ "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("--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
+ wrapAction("content:source-asset:create", async (options) => {
56415
+ if (options.text !== void 0 && options.url !== void 0) {
56416
+ throw new Error("Pass exactly one of --text or --url, not both");
56417
+ }
56418
+ if (options.text === void 0 && options.url === void 0) {
56419
+ throw new Error("Pass one of --text (inline content) or --url (a reference)");
56420
+ }
56421
+ if (options.field !== void 0 && options.text === void 0) {
56422
+ throw new Error("--field only applies to --text");
56423
+ }
56424
+ const body = { kind: options.kind, title: options.title };
56425
+ if (options.text !== void 0) {
56426
+ const text = resolveTextArgument(options.text);
56427
+ const field2 = options.field ?? options.kind;
56428
+ const size = Buffer.byteLength(text, "utf8");
56429
+ if (size > PAYLOAD_MAX_BYTES) {
56430
+ throw new Error(
56431
+ `--text content is ${size} bytes, over the ${PAYLOAD_MAX_BYTES}-byte payload limit. Split it or store it as a reference with --url`
56432
+ );
56433
+ }
56434
+ body.payload = { [field2]: text };
56435
+ }
56436
+ if (options.url !== void 0) body.externalUrl = options.url;
56437
+ if (options.duration !== void 0) {
56438
+ const duration3 = Number(options.duration);
56439
+ if (!Number.isInteger(duration3) || duration3 < 0) {
56440
+ throw new Error("--duration must be a non-negative integer number of seconds");
56441
+ }
56442
+ body.durationSeconds = duration3;
56443
+ }
56444
+ const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
56445
+ const asset = await apiPost("/api/external/content/source-assets", body, apiUrl);
56446
+ let linkedItem;
56447
+ if (options.item !== void 0) {
56448
+ linkedItem = await apiPatch(
56449
+ `/api/external/content/items/${options.item}`,
56450
+ { sourceAssetId: asset.id },
56451
+ apiUrl
56452
+ );
56453
+ }
56454
+ if (!options.pretty) {
56455
+ console.log(JSON.stringify(linkedItem ? { sourceAsset: asset, item: linkedItem } : asset, null, 2));
56456
+ return;
56457
+ }
56458
+ console.log(source_default.green(`
56459
+ Created source asset ${asset.id}`));
56460
+ console.log(source_default.gray(` Title: ${asset.title}`));
56461
+ console.log(source_default.gray(` Kind: ${asset.kind}`));
56462
+ if (asset.externalUrl) console.log(source_default.gray(` URL: ${asset.externalUrl}`));
56463
+ if (linkedItem) console.log(source_default.cyan(` Linked to item ${linkedItem.id} (${linkedItem.title})`));
56464
+ console.log();
56465
+ })
56466
+ );
56467
+ }
56468
+
56469
+ // src/cli/commands/content/index.ts
56470
+ function registerContentCommands(program3) {
56471
+ registerContentList(program3);
56472
+ registerContentGet(program3);
56473
+ registerContentBoard(program3);
56474
+ registerContentQueue(program3);
56475
+ registerContentPipeline(program3);
56476
+ registerContentDistributions(program3);
56477
+ registerContentReview(program3);
56478
+ registerContentSourceAssets(program3);
56479
+ registerContentSourceAsset(program3);
56480
+ registerContentSourceAssetCreate(program3);
56481
+ }
56482
+
55784
56483
  // src/cli/commands/queue/queue.ts
55785
56484
  init_source();
55786
56485
  init_api_client();
@@ -55789,7 +56488,7 @@ init_wrap_action();
55789
56488
  function printJson8(value) {
55790
56489
  console.log(JSON.stringify(value, null, 2));
55791
56490
  }
55792
- function appendQuery4(params, key, value) {
56491
+ function appendQuery7(params, key, value) {
55793
56492
  if (value === void 0 || value === null || value === "") return;
55794
56493
  params.set(key, String(value));
55795
56494
  }
@@ -55815,13 +56514,13 @@ function registerQueueList(program3) {
55815
56514
  async (options) => {
55816
56515
  const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
55817
56516
  const params = new URLSearchParams();
55818
- appendQuery4(params, "status", options.status);
55819
- appendQuery4(params, "humanCheckpoint", options.humanCheckpoint);
55820
- appendQuery4(params, "timeRange", options.timeRange);
55821
- appendQuery4(params, "priorityMin", options.priorityMin);
55822
- appendQuery4(params, "priorityMax", options.priorityMax);
55823
- appendQuery4(params, "limit", options.limit);
55824
- appendQuery4(params, "offset", options.offset);
56517
+ appendQuery7(params, "status", options.status);
56518
+ appendQuery7(params, "humanCheckpoint", options.humanCheckpoint);
56519
+ appendQuery7(params, "timeRange", options.timeRange);
56520
+ appendQuery7(params, "priorityMin", options.priorityMin);
56521
+ appendQuery7(params, "priorityMax", options.priorityMax);
56522
+ appendQuery7(params, "limit", options.limit);
56523
+ appendQuery7(params, "offset", options.offset);
55825
56524
  const result = await apiGet(
55826
56525
  endpointWithQuery4("/api/external/command-queue", params),
55827
56526
  apiUrl
@@ -55926,10 +56625,10 @@ function registerQueueStatus(program3) {
55926
56625
  async (options) => {
55927
56626
  const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
55928
56627
  const params = new URLSearchParams();
55929
- appendQuery4(params, "timeRange", options.timeRange);
55930
- appendQuery4(params, "priorityMin", options.priorityMin);
55931
- appendQuery4(params, "priorityMax", options.priorityMax);
55932
- appendQuery4(params, "status", options.status);
56628
+ appendQuery7(params, "timeRange", options.timeRange);
56629
+ appendQuery7(params, "priorityMin", options.priorityMin);
56630
+ appendQuery7(params, "priorityMax", options.priorityMax);
56631
+ appendQuery7(params, "status", options.status);
55933
56632
  const result = await apiGet(
55934
56633
  endpointWithQuery4("/api/external/command-queue/checkpoints", params),
55935
56634
  apiUrl
@@ -55978,7 +56677,7 @@ init_wrap_action();
55978
56677
  function printJson9(value) {
55979
56678
  console.log(JSON.stringify(value, null, 2));
55980
56679
  }
55981
- function appendQuery5(params, key, value) {
56680
+ function appendQuery8(params, key, value) {
55982
56681
  if (value === void 0 || value === null || value === "") return;
55983
56682
  params.set(key, String(value));
55984
56683
  }
@@ -56007,11 +56706,11 @@ function registerScheduleList(program3) {
56007
56706
  async (options) => {
56008
56707
  const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
56009
56708
  const params = new URLSearchParams();
56010
- appendQuery5(params, "status", options.status);
56011
- appendQuery5(params, "targetResourceType", options.targetResourceType);
56012
- appendQuery5(params, "targetResourceId", options.targetResourceId);
56013
- appendQuery5(params, "limit", options.limit);
56014
- appendQuery5(params, "offset", options.offset);
56709
+ appendQuery8(params, "status", options.status);
56710
+ appendQuery8(params, "targetResourceType", options.targetResourceType);
56711
+ appendQuery8(params, "targetResourceId", options.targetResourceId);
56712
+ appendQuery8(params, "limit", options.limit);
56713
+ appendQuery8(params, "offset", options.offset);
56015
56714
  const result = await apiGet(
56016
56715
  endpointWithQuery5("/api/external/task-scheduler/schedules", params),
56017
56716
  apiUrl
@@ -56211,7 +56910,7 @@ var PRIORITY_HELP = "low | normal | high | urgent";
56211
56910
  function registerNoteCreate2(program3) {
56212
56911
  program3.command("note:create").description(
56213
56912
  'Create a personal note for a user\n Example: elevasis-sdk note:create --content "Deal X stalled" --user agent@example.com'
56214
- ).requiredOption("--content <text>", "Note content").option("--user <email>", "Target user email (default: API key owner)").option("--title <text>", "Optional note title").option("--priority <priority>", `Priority: ${PRIORITY_HELP}`).option("--pinned", "Pin the note to the top of the panel").option("--source <id>", "Source identifier (e.g. workflow or agent ID)").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(
56913
+ ).requiredOption("--content <text>", "Note content").option("--user <email>", "Target user email (required -- the API rejects the call without it)").option("--title <text>", "Optional note title").option("--priority <priority>", `Priority: ${PRIORITY_HELP}`).option("--pinned", "Pin the note to the top of the panel").option("--source <id>", "Source identifier (e.g. workflow or agent ID)").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(
56215
56914
  wrapAction(
56216
56915
  "note:create",
56217
56916
  async (options) => {
@@ -56359,7 +57058,7 @@ function registerAgentCommands(program3) {
56359
57058
  }
56360
57059
 
56361
57060
  // src/cli/commands/session/session.ts
56362
- var import_node_fs10 = require("node:fs");
57061
+ var import_node_fs11 = require("node:fs");
56363
57062
  init_source();
56364
57063
  init_api_client();
56365
57064
  init_config2();
@@ -56367,7 +57066,7 @@ init_wrap_action();
56367
57066
  function printJson11(value) {
56368
57067
  console.log(JSON.stringify(value, null, 2));
56369
57068
  }
56370
- function appendQuery6(params, key, value) {
57069
+ function appendQuery9(params, key, value) {
56371
57070
  if (value === void 0 || value === null || value === "") return;
56372
57071
  params.set(key, String(value));
56373
57072
  }
@@ -56385,7 +57084,7 @@ function parseJson(value, label) {
56385
57084
  }
56386
57085
  function readJsonFile(path3, label) {
56387
57086
  const resolved = resolveProjectRelative(path3);
56388
- return parseJson((0, import_node_fs10.readFileSync)(resolved, "utf8"), label);
57087
+ return parseJson((0, import_node_fs11.readFileSync)(resolved, "utf8"), label);
56389
57088
  }
56390
57089
  function resolveTurnInput(options) {
56391
57090
  if (options.input && options.inputFile) {
@@ -56401,8 +57100,8 @@ function resolveTurnInput(options) {
56401
57100
  }
56402
57101
  function messagesEndpoint(sessionId, limit, cursor) {
56403
57102
  const params = new URLSearchParams();
56404
- appendQuery6(params, "limit", limit);
56405
- appendQuery6(params, "cursor", cursor);
57103
+ appendQuery9(params, "limit", limit);
57104
+ appendQuery9(params, "cursor", cursor);
56406
57105
  return endpointWithQuery6(`/api/external/sessions/${sessionId}/messages`, params);
56407
57106
  }
56408
57107
  async function fetchSessionMessages(sessionId, apiUrl, options) {
@@ -56487,9 +57186,9 @@ function registerSessionList(program3) {
56487
57186
  wrapAction("session:list", async (options) => {
56488
57187
  const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
56489
57188
  const params = new URLSearchParams();
56490
- appendQuery6(params, "resourceId", options.resourceId);
56491
- appendQuery6(params, "userId", options.userId);
56492
- appendQuery6(params, "limit", options.limit);
57189
+ appendQuery9(params, "resourceId", options.resourceId);
57190
+ appendQuery9(params, "userId", options.userId);
57191
+ appendQuery9(params, "limit", options.limit);
56493
57192
  const result = await apiGet(endpointWithQuery6("/api/external/sessions", params), apiUrl);
56494
57193
  if (options.json) {
56495
57194
  printJson11(result);
@@ -56624,7 +57323,7 @@ init_wrap_action();
56624
57323
  function printJson12(value) {
56625
57324
  console.log(JSON.stringify(value, null, 2));
56626
57325
  }
56627
- function appendQuery7(params, key, value) {
57326
+ function appendQuery10(params, key, value) {
56628
57327
  if (value === void 0 || value === null || value === "" || value === false) return;
56629
57328
  params.set(key, String(value));
56630
57329
  }
@@ -56689,8 +57388,8 @@ function registerGrantList(program3) {
56689
57388
  wrapAction("grant:list", async (options) => {
56690
57389
  const apiUrl = resolveApiUrl(options.apiUrl, options.prod);
56691
57390
  const params = new URLSearchParams();
56692
- appendQuery7(params, "resourceId", options.resourceId);
56693
- appendQuery7(params, "includeDisabled", options.includeDisabled ? "true" : void 0);
57391
+ appendQuery10(params, "resourceId", options.resourceId);
57392
+ appendQuery10(params, "includeDisabled", options.includeDisabled ? "true" : void 0);
56694
57393
  const result = await apiGet(
56695
57394
  endpointWithQuery7("/api/external/agent-access-grants", params),
56696
57395
  apiUrl
@@ -57265,7 +57964,7 @@ function registerOmDoctorCommand(program3) {
57265
57964
  }
57266
57965
 
57267
57966
  // src/cli/commands/om/rename.ts
57268
- var import_node_fs11 = require("node:fs");
57967
+ var import_node_fs12 = require("node:fs");
57269
57968
  var import_node_path9 = require("node:path");
57270
57969
  init_config2();
57271
57970
  init_wrap_action();
@@ -57303,10 +58002,10 @@ function absolutePath(sourceRoot, relativePath) {
57303
58002
  }
57304
58003
  function walkFiles(sourceRoot, relativeRoot, extension) {
57305
58004
  const root = absolutePath(sourceRoot, relativeRoot);
57306
- if (!(0, import_node_fs11.existsSync)(root)) return [];
58005
+ if (!(0, import_node_fs12.existsSync)(root)) return [];
57307
58006
  const targets = [];
57308
58007
  function visit(directory) {
57309
- for (const entry of (0, import_node_fs11.readdirSync)(directory, { withFileTypes: true })) {
58008
+ for (const entry of (0, import_node_fs12.readdirSync)(directory, { withFileTypes: true })) {
57310
58009
  const fullPath = (0, import_node_path9.join)(directory, entry.name);
57311
58010
  if (entry.isDirectory()) {
57312
58011
  visit(fullPath);
@@ -57388,8 +58087,8 @@ function createOmRenamePlan(oldPathArg, newPathArg, options = {}) {
57388
58087
  const edits = [];
57389
58088
  for (const target of buildTargets(sourceRoot)) {
57390
58089
  const path3 = absolutePath(sourceRoot, target.path);
57391
- if (!(0, import_node_fs11.existsSync)(path3)) continue;
57392
- const source = (0, import_node_fs11.readFileSync)(path3, "utf8");
58090
+ if (!(0, import_node_fs12.existsSync)(path3)) continue;
58091
+ const source = (0, import_node_fs12.readFileSync)(path3, "utf8");
57393
58092
  const transformed = transformContent(source, target.path, oldPath, newPath);
57394
58093
  if (transformed.count === 0) continue;
57395
58094
  edits.push({
@@ -57416,20 +58115,20 @@ function createOmRenamePlan(oldPathArg, newPathArg, options = {}) {
57416
58115
  function snapshotEdits(sourceRoot, edits) {
57417
58116
  return edits.map((edit) => {
57418
58117
  const path3 = absolutePath(sourceRoot, edit.path);
57419
- return { path: path3, content: (0, import_node_fs11.readFileSync)(path3, "utf8") };
58118
+ return { path: path3, content: (0, import_node_fs12.readFileSync)(path3, "utf8") };
57420
58119
  });
57421
58120
  }
57422
58121
  function restoreSnapshot(snapshot) {
57423
58122
  for (const entry of snapshot) {
57424
- (0, import_node_fs11.writeFileSync)(entry.path, entry.content);
58123
+ (0, import_node_fs12.writeFileSync)(entry.path, entry.content);
57425
58124
  }
57426
58125
  }
57427
58126
  function applyPlan(sourceRoot, plan) {
57428
58127
  for (const edit of plan.edits) {
57429
58128
  const path3 = absolutePath(sourceRoot, edit.path);
57430
- const source = (0, import_node_fs11.readFileSync)(path3, "utf8");
58129
+ const source = (0, import_node_fs12.readFileSync)(path3, "utf8");
57431
58130
  const transformed = transformContent(source, edit.path, plan.oldPath, plan.newPath);
57432
- (0, import_node_fs11.writeFileSync)(path3, transformed.output);
58131
+ (0, import_node_fs12.writeFileSync)(path3, transformed.output);
57433
58132
  }
57434
58133
  }
57435
58134
  async function defaultOmRenameValidator(plan, sourceRoot) {
@@ -57437,7 +58136,7 @@ async function defaultOmRenameValidator(plan, sourceRoot) {
57437
58136
  try {
57438
58137
  if (plan.edits.some((edit) => edit.path.endsWith(".mdx"))) {
57439
58138
  const sourceDir = absolutePath(sourceRoot, KNOWLEDGE_ROOT);
57440
- if ((0, import_node_fs11.existsSync)(sourceDir)) {
58139
+ if ((0, import_node_fs12.existsSync)(sourceDir)) {
57441
58140
  const generated = generateKnowledgeNodes({
57442
58141
  sourceDir,
57443
58142
  outputPath: absolutePath(sourceRoot, KNOWLEDGE_GENERATED_OUTPUT),
@@ -57525,7 +58224,7 @@ function registerOmRenameCommand(program3) {
57525
58224
  }
57526
58225
 
57527
58226
  // src/cli/commands/om/deprecate.ts
57528
- var import_node_fs12 = require("node:fs");
58227
+ var import_node_fs13 = require("node:fs");
57529
58228
  var import_node_path10 = require("node:path");
57530
58229
  init_src();
57531
58230
  init_config2();
@@ -57634,8 +58333,8 @@ function createOmDeprecatePlan(model, systemPathArg, options = {}) {
57634
58333
  const warnings = hasDependents && to === "deprecated" ? ["Live dependents were found. Deprecation is allowed, but plan the dependent wind-down before archiving."] : [];
57635
58334
  const blocked = to === "archived" && hasDependents && !confirmed;
57636
58335
  let edit = null;
57637
- if ((0, import_node_fs12.existsSync)(systemsPath)) {
57638
- const source = (0, import_node_fs12.readFileSync)(systemsPath, "utf8");
58336
+ if ((0, import_node_fs13.existsSync)(systemsPath)) {
58337
+ const source = (0, import_node_fs13.readFileSync)(systemsPath, "utf8");
57639
58338
  edit = {
57640
58339
  path: SYSTEMS_FILE2,
57641
58340
  replacements: transformSystemLifecycle(source, systemPath, to).replacements
@@ -57680,13 +58379,13 @@ async function executeOmDeprecatePlan(plan, options = {}) {
57680
58379
  return { plan, wrote: false, validation: { ok: true, output: "no lifecycle change needed" }, rolledBack: false };
57681
58380
  }
57682
58381
  const systemsPath = absolutePath2(sourceRoot, SYSTEMS_FILE2);
57683
- const before = (0, import_node_fs12.readFileSync)(systemsPath, "utf8");
58382
+ const before = (0, import_node_fs13.readFileSync)(systemsPath, "utf8");
57684
58383
  const transformed = transformSystemLifecycle(before, plan.systemPath, plan.to);
57685
- (0, import_node_fs12.writeFileSync)(systemsPath, transformed.output);
58384
+ (0, import_node_fs13.writeFileSync)(systemsPath, transformed.output);
57686
58385
  const validator = options.validator ?? defaultOmDeprecateValidator;
57687
58386
  const validation = await validator(plan, sourceRoot);
57688
58387
  if (!validation.ok) {
57689
- (0, import_node_fs12.writeFileSync)(systemsPath, before);
58388
+ (0, import_node_fs13.writeFileSync)(systemsPath, before);
57690
58389
  return { plan, wrote: true, validation, rolledBack: true };
57691
58390
  }
57692
58391
  return { plan, wrote: true, validation, rolledBack: false };
@@ -57781,7 +58480,7 @@ function registerOmScaffoldCommands(program3) {
57781
58480
  const mod = await Promise.resolve().then(() => (init_scaffold_ontology(), scaffold_ontology_exports));
57782
58481
  await mod.default(opts);
57783
58482
  });
57784
- program3.command("om:scaffold:knowledge").description("Create a new MDX knowledge node file in core/config/knowledge/nodes/").option("--id <id>", "knowledge node id, e.g. outreach-playbook (prompted if absent)").option("--kind <kind>", "node kind: playbook | strategy | reference | policy (prompted if absent)").option("--system-path <path>", "governing system path for mount (prompted; can be blank for global)").option("--write", "apply the change (default is a dry-run preview \u2014 no files written)").action(async (opts) => {
58483
+ program3.command("om:scaffold:knowledge").description("Create a new MDX knowledge node file in core/config/knowledge/nodes/").option("--id <id>", "knowledge node id, e.g. outreach-playbook (prompted if absent)").option("--kind <kind>", "node kind: playbook | strategy | reference (prompted if absent)").option("--system-path <path>", "governing system path for mount (prompted; can be blank for global)").option("--write", "apply the change (default is a dry-run preview \u2014 no files written)").action(async (opts) => {
57785
58484
  const mod = await Promise.resolve().then(() => (init_scaffold_knowledge(), scaffold_knowledge_exports));
57786
58485
  await mod.default(opts);
57787
58486
  });
@@ -57876,7 +58575,7 @@ function registerSkillScaffoldCommand(program3) {
57876
58575
  }
57877
58576
 
57878
58577
  // src/cli/json-file-argv.ts
57879
- var import_node_fs17 = require("node:fs");
58578
+ var import_node_fs18 = require("node:fs");
57880
58579
  var import_node_path18 = require("node:path");
57881
58580
  init_config2();
57882
58581
  var JSON_FILE_PREFIX = "@json:";
@@ -57907,7 +58606,7 @@ function resolveJsonFilePath(path3, options) {
57907
58606
  function readJsonFileReference(ref, options) {
57908
58607
  const relativeOrAbsolutePath = ref.slice(JSON_FILE_PREFIX.length);
57909
58608
  const resolvedPath = resolveJsonFilePath(relativeOrAbsolutePath, options);
57910
- const raw = (options.readFile ?? ((path3) => (0, import_node_fs17.readFileSync)(path3, "utf8")))(resolvedPath);
58609
+ const raw = (options.readFile ?? ((path3) => (0, import_node_fs18.readFileSync)(path3, "utf8")))(resolvedPath);
57911
58610
  try {
57912
58611
  JSON.parse(raw);
57913
58612
  } catch {
@@ -58034,6 +58733,13 @@ Commands:
58034
58733
  elevasis-sdk client:list [--search <query>] List clients with optional search
58035
58734
  elevasis-sdk client:get <id> Get client detail and lineage
58036
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
58037
58743
  elevasis-sdk queue:list [--status pending] List HITL command queue tasks
58038
58744
  elevasis-sdk queue:select <id> --action-id <id> Select and execute a HITL queue action
58039
58745
  elevasis-sdk schedule:list [--status active] List task schedules
@@ -58058,6 +58764,8 @@ Commands:
58058
58764
  elevasis-sdk request:submit -f <path> Submit a structured request report
58059
58765
  elevasis-sdk request:list [--status open] List reported requests
58060
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
58061
58769
  elevasis-sdk ui:use-local Use a local @elevasis/ui tarball
58062
58770
  elevasis-sdk ui:use-published Restore published @elevasis/ui
58063
58771
  elevasis-sdk cli [domain] Generate a registered command catalog
@@ -58084,6 +58792,7 @@ registerErrorCommand(program2);
58084
58792
  registerRenameCommand(program2);
58085
58793
  registerProjectCommands(program2);
58086
58794
  registerClientCommands(program2);
58795
+ registerContentCommands(program2);
58087
58796
  registerQueueCommands(program2);
58088
58797
  registerScheduleCommands(program2);
58089
58798
  registerAgentCommands(program2);