makefx 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/makefx.mjs +707 -131
  3. package/package.json +1 -1
package/makefx.mjs CHANGED
@@ -838,8 +838,11 @@ function validateProjectConfig(config, configPath) {
838
838
  * makefx spaces --details Show asset counts per space
839
839
  * makefx spaces --id <space_id> Show details for a specific space
840
840
  * makefx spaces create <name> Create a new space
841
+ * makefx spaces delete <space_id> Archive a space for support recovery
842
+ * makefx spaces inspect-deleted <space_id> Inspect a soft-deleted space
843
+ * makefx spaces restore <space_id> Restore a soft-deleted space
841
844
  */
842
- var defaultDeps$12 = {
845
+ var defaultDeps$13 = {
843
846
  loadConfig: loadStoredConfig,
844
847
  resolveBaseUrl,
845
848
  saveProjectConfig,
@@ -854,7 +857,7 @@ async function handleSpaces(parsed) {
854
857
  process$1.exitCode = 1;
855
858
  }
856
859
  }
857
- async function executeSpaces(parsed, deps = defaultDeps$12) {
860
+ async function executeSpaces(parsed, deps = defaultDeps$13) {
858
861
  const env = resolveCommandEnvironment(parsed);
859
862
  const showDetails = parsed.options.details === "true";
860
863
  const spaceId = parsed.options.id;
@@ -892,6 +895,40 @@ async function executeSpaces(parsed, deps = defaultDeps$12) {
892
895
  project
893
896
  };
894
897
  }
898
+ if (subcommand === "delete" || subcommand === "archive") {
899
+ const targetSpaceId = parsed.positionals[1] || parsed.options.id;
900
+ if (!targetSpaceId) throw new Error("Space ID is required. Usage: makefx spaces delete <space_id>");
901
+ const deleted = await deleteSpace(ctx, deps, targetSpaceId);
902
+ if (jsonOutput) deps.print(JSON.stringify(deleted, null, 2));
903
+ else printDeletedSpace(targetSpaceId, deleted.message, deps.print);
904
+ return {
905
+ type: "delete",
906
+ spaceId: targetSpaceId,
907
+ message: deleted.message
908
+ };
909
+ }
910
+ if (subcommand === "inspect-deleted") {
911
+ const targetSpaceId = parsed.positionals[1] || parsed.options.id;
912
+ if (!targetSpaceId) throw new Error("Space ID is required. Usage: makefx spaces inspect-deleted <space_id>");
913
+ const details = await inspectDeletedSpace(ctx, deps, targetSpaceId);
914
+ if (jsonOutput) deps.print(JSON.stringify(details, null, 2));
915
+ else printSupportSpaceDetails(details, deps.print);
916
+ return {
917
+ type: "inspect-deleted",
918
+ details
919
+ };
920
+ }
921
+ if (subcommand === "restore") {
922
+ const targetSpaceId = parsed.positionals[1] || parsed.options.id;
923
+ if (!targetSpaceId) throw new Error("Space ID is required. Usage: makefx spaces restore <space_id>");
924
+ const restored = await restoreSpace(ctx, deps, targetSpaceId);
925
+ if (jsonOutput) deps.print(JSON.stringify(restored, null, 2));
926
+ else printRestoredSpace(restored, deps.print);
927
+ return {
928
+ type: "restore",
929
+ restored
930
+ };
931
+ }
895
932
  if (spaceId) {
896
933
  const details = await getSpaceDetails(ctx, deps, spaceId);
897
934
  if (jsonOutput) deps.print(JSON.stringify(details, null, 2));
@@ -934,6 +971,45 @@ async function createSpace(ctx, deps, name) {
934
971
  }
935
972
  return (await response.json()).space;
936
973
  }
974
+ async function deleteSpace(ctx, deps, spaceId) {
975
+ const response = await deps.fetch(`${ctx.baseUrl}/api/spaces/${encodeURIComponent(spaceId)}`, {
976
+ method: "DELETE",
977
+ headers: {
978
+ "Authorization": `Bearer ${ctx.accessToken}`,
979
+ "Content-Type": "application/json"
980
+ }
981
+ });
982
+ if (!response.ok) {
983
+ const error = await response.text();
984
+ throw new Error(`Failed to delete space: ${response.status} - ${error}`);
985
+ }
986
+ return await response.json();
987
+ }
988
+ async function inspectDeletedSpace(ctx, deps, spaceId) {
989
+ const response = await deps.fetch(`${ctx.baseUrl}/api/support/spaces/${encodeURIComponent(spaceId)}`, { headers: {
990
+ "Authorization": `Bearer ${ctx.accessToken}`,
991
+ "Content-Type": "application/json"
992
+ } });
993
+ if (!response.ok) {
994
+ const error = await response.text();
995
+ throw new Error(`Failed to inspect deleted space: ${response.status} - ${error}`);
996
+ }
997
+ return await response.json();
998
+ }
999
+ async function restoreSpace(ctx, deps, spaceId) {
1000
+ const response = await deps.fetch(`${ctx.baseUrl}/api/support/spaces/${encodeURIComponent(spaceId)}/restore`, {
1001
+ method: "POST",
1002
+ headers: {
1003
+ "Authorization": `Bearer ${ctx.accessToken}`,
1004
+ "Content-Type": "application/json"
1005
+ }
1006
+ });
1007
+ if (!response.ok) {
1008
+ const error = await response.text();
1009
+ throw new Error(`Failed to restore space: ${response.status} - ${error}`);
1010
+ }
1011
+ return await response.json();
1012
+ }
937
1013
  function printCreatedSpace(space, env, configPath, print) {
938
1014
  const envFlag = env === "production" ? "" : env === "local" ? " --local" : ` --env ${env}`;
939
1015
  print(`\nSpace created successfully!\n`);
@@ -946,6 +1022,22 @@ function printCreatedSpace(space, env, configPath, print) {
946
1022
  print(`\nTo listen for events:`);
947
1023
  print(` makefx listen --space ${space.id}${envFlag}`);
948
1024
  }
1025
+ function printDeletedSpace(spaceId, message, print) {
1026
+ print(`Space archived: ${spaceId}`);
1027
+ print(message);
1028
+ }
1029
+ function printSupportSpaceDetails(details, print) {
1030
+ print(`Space: ${details.space.name} (${details.space.id})`);
1031
+ print(`Deleted at: ${details.space.deleted_at ?? "not deleted"}`);
1032
+ print(`Visible memberships: ${details.memberships.filter((member) => member.deleted_at === null).length}`);
1033
+ print(`Total memberships: ${details.memberships.length}`);
1034
+ }
1035
+ function printRestoredSpace(restored, print) {
1036
+ print(`Space restored: ${restored.space.id}`);
1037
+ print(restored.message);
1038
+ print(`Visible memberships: ${restored.membershipsVisible}`);
1039
+ if (restored.auditLogId) print(`Audit log: ${restored.auditLogId}`);
1040
+ }
949
1041
  async function fetchSpaces(ctx, deps) {
950
1042
  const response = await deps.fetch(`${ctx.baseUrl}/api/spaces`, { headers: {
951
1043
  "Authorization": `Bearer ${ctx.accessToken}`,
@@ -5077,7 +5169,7 @@ function resolveMediaType(ext, requestedMediaKind) {
5077
5169
  * makefx upload <file> --space <id> --name <name> Upload as new asset
5078
5170
  * makefx upload <file> --space <id> --name <name> --type <type>
5079
5171
  */
5080
- var defaultDeps$11 = {
5172
+ var defaultDeps$12 = {
5081
5173
  loadConfig: loadStoredConfig,
5082
5174
  loadProjectConfig,
5083
5175
  resolveBaseUrl,
@@ -5092,11 +5184,11 @@ async function handleUpload(parsed) {
5092
5184
  await executeUpload(parsed);
5093
5185
  } catch (error) {
5094
5186
  console.error(error instanceof Error ? `Error: ${error.message}` : "Error: Upload failed");
5095
- if (error instanceof UploadUsageError) printUsage$11();
5187
+ if (error instanceof UploadUsageError) printUsage$12();
5096
5188
  process$1.exitCode = 1;
5097
5189
  }
5098
5190
  }
5099
- async function executeUpload(parsed, deps = defaultDeps$11) {
5191
+ async function executeUpload(parsed, deps = defaultDeps$12) {
5100
5192
  const filePath = parsed.positionals[0];
5101
5193
  if (!filePath) throw new UploadUsageError("File path is required");
5102
5194
  const projectConfig = await deps.loadProjectConfig();
@@ -5111,7 +5203,7 @@ async function executeUpload(parsed, deps = defaultDeps$11) {
5111
5203
  const provider = parsed.options.provider;
5112
5204
  const rawProviderMetadata = parsed.options["provider-metadata"] ?? parsed.options.providerMetadata ?? parsed.options.provider_metadata;
5113
5205
  const rawGenerationProvenance = parsed.options["generation-provenance"] ?? parsed.options.generationProvenance ?? parsed.options.generation_provenance;
5114
- const sourceVariantId = parsed.options["source-variant"] ?? parsed.options.sourceVariantId ?? parsed.options.parentVariantId;
5206
+ const rawSourceVariantIds = parsed.options["source-variants"] ?? parsed.options.sourceVariants ?? parsed.options.sourceVariantIds ?? parsed.options["source-variant"] ?? parsed.options.sourceVariantId ?? parsed.options.parentVariantId;
5115
5207
  const rawRelationType = parsed.options["relation-type"] ?? parsed.options.relationType;
5116
5208
  const rawActiveVariantBehavior = parsed.options["active-variant-behavior"] ?? parsed.options.activeVariantBehavior;
5117
5209
  const rawCollectionIds = parsed.options.collection ?? parsed.options.collections;
@@ -5128,11 +5220,12 @@ async function executeUpload(parsed, deps = defaultDeps$11) {
5128
5220
  if (parsed.options["dry-run"] === "true" || parsed.options.dryRun === "true") throw new UploadUsageError("--dry-run is not supported for direct file upload");
5129
5221
  if (!spaceId) throw new UploadUsageError("--space is required, or run: makefx init --space <id>");
5130
5222
  if (!assetId && !assetName) throw new UploadUsageError("Either --asset or --name is required");
5131
- if (!sourceVariantId && (parsed.options["relation-type"] || parsed.options.relationType)) throw new UploadUsageError("--relation-type requires --source-variant");
5132
5223
  const providerMetadata = parseJsonObjectOption(rawProviderMetadata, "--provider-metadata");
5133
5224
  const generationProvenance = parseJsonObjectOption(rawGenerationProvenance, "--generation-provenance");
5225
+ const sourceVariantIds = parseCsvOption$1(rawSourceVariantIds, "--source-variant");
5134
5226
  const relationType = normalizeRelationType(rawRelationType);
5135
5227
  const activeVariantBehavior = normalizeActiveVariantBehavior(rawActiveVariantBehavior);
5228
+ if (sourceVariantIds.length === 0 && (parsed.options["relation-type"] || parsed.options.relationType)) throw new UploadUsageError("--relation-type requires --source-variant or --source-variants");
5136
5229
  const collectionPlacements = parseCollectionPlacements({
5137
5230
  collectionIds: rawCollectionIds,
5138
5231
  collectionNames: rawCollectionNames,
@@ -5165,7 +5258,7 @@ async function executeUpload(parsed, deps = defaultDeps$11) {
5165
5258
  if (fileStat.size > 10485760) throw new Error(`File too large (${(fileStat.size / 1024 / 1024).toFixed(2)}MB). Maximum size: 10MB`);
5166
5259
  await preflightUploadOrganization(ctx, deps, {
5167
5260
  assetId,
5168
- sourceVariantId,
5261
+ sourceVariantIds,
5169
5262
  collectionPlacements,
5170
5263
  manualRelations
5171
5264
  });
@@ -5186,16 +5279,17 @@ async function executeUpload(parsed, deps = defaultDeps$11) {
5186
5279
  if (provider) formData.append("provider", provider);
5187
5280
  if (providerMetadata) formData.append("providerMetadata", JSON.stringify(providerMetadata));
5188
5281
  if (generationProvenance) formData.append("generationProvenance", JSON.stringify(generationProvenance));
5189
- if (sourceVariantId) formData.append("lineage", JSON.stringify([{
5190
- parentVariantId: sourceVariantId,
5282
+ if (sourceVariantIds.length > 0) formData.append("lineage", JSON.stringify(sourceVariantIds.map((parentVariantId) => ({
5283
+ parentVariantId,
5191
5284
  relationType
5192
- }]));
5285
+ }))));
5193
5286
  if (!jsonOutput) {
5194
5287
  deps.print(`\nUploading "${fileName}" to space ${spaceId}...`);
5195
5288
  deps.print(` Media kind: ${mediaType.mediaKind}`);
5196
5289
  if (assetId) deps.print(` Target asset: ${assetId}`);
5197
5290
  else deps.print(` Creating asset: "${assetName}" (${assetType})`);
5198
- if (sourceVariantId) deps.print(` Source variant: ${sourceVariantId} (${relationType})`);
5291
+ if (sourceVariantIds.length === 1) deps.print(` Source variant: ${sourceVariantIds[0]} (${relationType})`);
5292
+ else if (sourceVariantIds.length > 1) deps.print(` Source variants: ${sourceVariantIds.join(", ")} (${relationType})`);
5199
5293
  }
5200
5294
  const response = await deps.fetch(`${baseUrl}/api/spaces/${spaceId}/upload`, {
5201
5295
  method: "POST",
@@ -5372,7 +5466,7 @@ function parseManualRelations(input) {
5372
5466
  }
5373
5467
  async function preflightUploadOrganization(ctx, deps, options) {
5374
5468
  const needsCollections = options.collectionPlacements.length > 0;
5375
- const needsAssetState = Boolean(options.sourceVariantId) || options.manualRelations.length > 0 || options.collectionPlacements.some((placement) => placement.pinnedVariantId);
5469
+ const needsAssetState = options.sourceVariantIds.length > 0 || options.manualRelations.length > 0 || options.collectionPlacements.some((placement) => placement.pinnedVariantId);
5376
5470
  const [collections, state] = await Promise.all([needsCollections ? fetchJson$1(ctx, deps, `/api/spaces/${ctx.spaceId}/collections`) : void 0, needsAssetState ? fetchAssetState(ctx, deps) : void 0]);
5377
5471
  if (collections) {
5378
5472
  const collectionList = collections.collections ?? [];
@@ -5387,7 +5481,7 @@ async function preflightUploadOrganization(ctx, deps, options) {
5387
5481
  }
5388
5482
  }
5389
5483
  if (!state) return;
5390
- if (options.sourceVariantId && !state.variantsById.has(options.sourceVariantId)) throw new Error(`Source variant not found in space: ${options.sourceVariantId}`);
5484
+ for (const sourceVariantId of options.sourceVariantIds) if (!state.variantsById.has(sourceVariantId)) throw new Error(`Source variant not found in space: ${sourceVariantId}`);
5391
5485
  for (const placement of options.collectionPlacements) {
5392
5486
  if (!placement.pinnedVariantId) continue;
5393
5487
  const pinned = state.variantsById.get(placement.pinnedVariantId);
@@ -5483,7 +5577,7 @@ async function fetchJson$1(ctx, deps, requestPath) {
5483
5577
  function stripUndefined(value) {
5484
5578
  return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== void 0));
5485
5579
  }
5486
- function printUsage$11() {
5580
+ function printUsage$12() {
5487
5581
  console.log(`
5488
5582
  Usage:
5489
5583
  makefx upload <file> --asset <id> [--space <id>] Upload media to existing asset
@@ -5500,7 +5594,8 @@ Options:
5500
5594
  --provider <name> Provider provenance for uploaded media
5501
5595
  --provider-metadata <json> Provider metadata JSON object
5502
5596
  --generation-provenance <json> Extra provenance JSON object
5503
- --source-variant <id> Existing source variant for upload lineage
5597
+ --source-variant <ids> Comma-separated source variants for upload lineage
5598
+ --source-variants <ids> Alias for --source-variant
5504
5599
  --relation-type <type> Lineage type: derived, refined, or forked (default: derived)
5505
5600
  --active-variant-behavior <b> if-missing, set-active, or keep
5506
5601
  --collection <ids> Comma-separated collection IDs for the uploaded asset or variant
@@ -5525,6 +5620,7 @@ Examples:
5525
5620
  makefx upload hero.png --space abc123 --name "Hero Character"
5526
5621
  makefx upload hero.png --space abc123 --name "Hero" --prompt "external render" --provider blender
5527
5622
  makefx upload paintover.png --space abc123 --asset def456 --source-variant var123 --relation-type refined
5623
+ makefx upload scene.png --space abc123 --name "Cocina" --type scene --source-variants anna,roman,bg
5528
5624
  makefx upload hero.png --space abc123 --name "Hero" --collection collection_cast --collection-role character
5529
5625
  makefx upload hero.png --space abc123 --name "Hero" --collection-name "Cast" --collection-role character
5530
5626
  makefx upload thumbnail.png --space abc123 --asset asset_thumb --manual-relation thumbnail_for:asset:asset_target
@@ -19471,6 +19567,7 @@ var UserProfileSchema = object({
19471
19567
  var SessionConfigSchema = object({
19472
19568
  googleClientId: string$1(),
19473
19569
  environment: string$1(),
19570
+ mediaCdnBaseUrl: string$1().nullable().optional(),
19474
19571
  features: object({ rotation: boolean$1() })
19475
19572
  }).openapi("SessionConfig");
19476
19573
  var AuthSessionResponseSchema = object({
@@ -19526,6 +19623,19 @@ var ProviderKeyResponseSchema = object({
19526
19623
  success: literal(true),
19527
19624
  provider: ProviderKeySummarySchema
19528
19625
  }).openapi("ProviderKeyResponse");
19626
+ var DeleteAccountRequestSchema = object({
19627
+ email: string$1().email(),
19628
+ confirmation: string$1()
19629
+ }).openapi("DeleteAccountRequest");
19630
+ var DeleteAccountResponseSchema = object({
19631
+ success: literal(true),
19632
+ deleted: boolean$1(),
19633
+ ownedSpacesPurged: number$1().int(),
19634
+ spacePurgeFailures: number$1().int(),
19635
+ sharedMembershipsDeleted: number$1().int(),
19636
+ r2ObjectsDeleted: number$1().int(),
19637
+ d1RowsChanged: number$1().int()
19638
+ }).openapi("DeleteAccountResponse");
19529
19639
  var SpaceRoleSchema = _enum([
19530
19640
  "owner",
19531
19641
  "editor",
@@ -19538,6 +19648,25 @@ var SpaceSchema = object({
19538
19648
  role: SpaceRoleSchema,
19539
19649
  created_at: number$1()
19540
19650
  }).openapi("Space");
19651
+ var SupportSpaceMemberSchema = object({
19652
+ space_id: string$1(),
19653
+ user_id: string$1(),
19654
+ role: SpaceRoleSchema,
19655
+ joined_at: number$1(),
19656
+ deleted_at: string$1().nullable(),
19657
+ user: object({
19658
+ id: string$1(),
19659
+ email: string$1(),
19660
+ name: string$1().nullable()
19661
+ })
19662
+ }).openapi("SupportSpaceMember");
19663
+ var SupportSpaceSchema = object({
19664
+ id: string$1(),
19665
+ name: string$1(),
19666
+ owner_id: string$1(),
19667
+ created_at: number$1(),
19668
+ deleted_at: string$1().nullable()
19669
+ }).openapi("SupportSpace");
19541
19670
  var SpaceIdParamsSchema = object({ id: string$1().openapi({ param: {
19542
19671
  name: "id",
19543
19672
  in: "path"
@@ -19567,6 +19696,19 @@ var GetSpaceResponseSchema = object({
19567
19696
  success: literal(true),
19568
19697
  space: SpaceSchema
19569
19698
  }).openapi("GetSpaceResponse");
19699
+ var GetSupportSpaceResponseSchema = object({
19700
+ success: literal(true),
19701
+ space: SupportSpaceSchema,
19702
+ memberships: array(SupportSpaceMemberSchema)
19703
+ }).openapi("GetSupportSpaceResponse");
19704
+ var RestoreSupportSpaceResponseSchema = object({
19705
+ success: literal(true),
19706
+ space: SupportSpaceSchema,
19707
+ membershipsVisible: number$1().int(),
19708
+ previousDeletedAt: string$1(),
19709
+ auditLogId: string$1().nullable(),
19710
+ message: string$1()
19711
+ }).openapi("RestoreSupportSpaceResponse");
19570
19712
  var MediaKindSchema = _enum([
19571
19713
  "image",
19572
19714
  "audio",
@@ -20337,6 +20479,12 @@ var apiEndpoints = {
20337
20479
  paramsSchema: ProviderKeyParamsSchema,
20338
20480
  responseSchema: ProviderKeyResponseSchema
20339
20481
  },
20482
+ "DELETE /api/user/account": {
20483
+ method: "DELETE",
20484
+ path: "/api/user/account",
20485
+ jsonSchema: DeleteAccountRequestSchema,
20486
+ responseSchema: DeleteAccountResponseSchema
20487
+ },
20340
20488
  "POST /api/spaces": {
20341
20489
  method: "POST",
20342
20490
  path: "/api/spaces",
@@ -20354,6 +20502,18 @@ var apiEndpoints = {
20354
20502
  paramsSchema: SpaceIdParamsSchema,
20355
20503
  responseSchema: GetSpaceResponseSchema
20356
20504
  },
20505
+ "GET /api/support/spaces/:id": {
20506
+ method: "GET",
20507
+ path: "/api/support/spaces/:id",
20508
+ paramsSchema: SpaceIdParamsSchema,
20509
+ responseSchema: GetSupportSpaceResponseSchema
20510
+ },
20511
+ "POST /api/support/spaces/:id/restore": {
20512
+ method: "POST",
20513
+ path: "/api/support/spaces/:id/restore",
20514
+ paramsSchema: SpaceIdParamsSchema,
20515
+ responseSchema: RestoreSupportSpaceResponseSchema
20516
+ },
20357
20517
  "GET /api/spaces/:id/assets": {
20358
20518
  method: "GET",
20359
20519
  path: "/api/spaces/:id/assets",
@@ -20785,7 +20945,7 @@ async function apiFetch(key, ...args) {
20785
20945
  }
20786
20946
  //#endregion
20787
20947
  //#region src/cli/commands/productions.ts
20788
- var defaultDeps$10 = {
20948
+ var defaultDeps$11 = {
20789
20949
  loadConfig: loadStoredConfig,
20790
20950
  loadProjectConfig,
20791
20951
  resolveBaseUrl,
@@ -20799,12 +20959,12 @@ async function handleProductions(parsed) {
20799
20959
  await executeProductions(parsed);
20800
20960
  } catch (error) {
20801
20961
  console.error("Error:", error instanceof Error ? error.message : error);
20802
- printUsage$10();
20962
+ printUsage$11();
20803
20963
  process$1.exitCode = 1;
20804
20964
  }
20805
20965
  }
20806
- async function executeProductions(parsed, deps = defaultDeps$10) {
20807
- const ctx = await buildContext$7(parsed, deps);
20966
+ async function executeProductions(parsed, deps = defaultDeps$11) {
20967
+ const ctx = await buildContext$8(parsed, deps);
20808
20968
  const subcommand = parsed.positionals[0] || "list";
20809
20969
  if (subcommand === "list") {
20810
20970
  const records = await listProductionRecords(ctx, deps, readProductionId(parsed, 1));
@@ -20877,7 +21037,7 @@ async function placeProductionRecordForCli(input) {
20877
21037
  }
20878
21038
  })).record;
20879
21039
  }
20880
- async function buildContext$7(parsed, deps) {
21040
+ async function buildContext$8(parsed, deps) {
20881
21041
  const projectConfig = await deps.loadProjectConfig();
20882
21042
  const env = resolveCommandEnvironment(parsed, projectConfig);
20883
21043
  const spaceId = resolveCommandSpace(parsed, projectConfig);
@@ -20936,10 +21096,10 @@ function readProductionId(parsed, positionalIndex) {
20936
21096
  return productionId;
20937
21097
  }
20938
21098
  function parsePlaceRequest(parsed) {
20939
- const productionId = readRequiredOption$1(parsed, "production-id", "productionId");
20940
- const variantId = readRequiredOption$1(parsed, "variant", "variantId");
20941
- const sceneLabel = readRequiredOption$1(parsed, "scene-label", "sceneLabel");
20942
- const timelineStartMs = parseNonNegativeInteger$1(readRequiredOption$1(parsed, "timeline-start-ms", "timelineStartMs"), "--timeline-start-ms");
21099
+ const productionId = readRequiredOption$2(parsed, "production-id", "productionId");
21100
+ const variantId = readRequiredOption$2(parsed, "variant", "variantId");
21101
+ const sceneLabel = readRequiredOption$2(parsed, "scene-label", "sceneLabel");
21102
+ const timelineStartMs = parseNonNegativeInteger$1(readRequiredOption$2(parsed, "timeline-start-ms", "timelineStartMs"), "--timeline-start-ms");
20943
21103
  const durationValue = readOptionalOption$1(parsed, "duration-ms", "durationMs");
20944
21104
  return {
20945
21105
  id: readOptionalOption$1(parsed, "id", "id"),
@@ -20955,7 +21115,7 @@ function parsePlaceRequest(parsed) {
20955
21115
  metadata: parseMetadataJson(readOptionalOption$1(parsed, "metadata-json", "metadataJson"))
20956
21116
  };
20957
21117
  }
20958
- function readRequiredOption$1(parsed, kebabName, camelName) {
21118
+ function readRequiredOption$2(parsed, kebabName, camelName) {
20959
21119
  const value = readOptionalOption$1(parsed, kebabName, camelName);
20960
21120
  if (value === void 0) throw new Error(`--${kebabName} is required`);
20961
21121
  return value;
@@ -21100,7 +21260,7 @@ function parseJsonObject$1(value) {
21100
21260
  function shellQuote$1(value) {
21101
21261
  return `'${value.replace(/'/g, "'\\''")}'`;
21102
21262
  }
21103
- function printUsage$10() {
21263
+ function printUsage$11() {
21104
21264
  console.log(`
21105
21265
  Usage:
21106
21266
  makefx productions list --production-id <id>
@@ -22719,7 +22879,7 @@ function cliGenerationSupportsRefs(namespace) {
22719
22879
  //#endregion
22720
22880
  //#region src/cli/commands/forge.ts
22721
22881
  var CLI_GENERATION_MEDIA_KIND = getCliGenerationMediaKind("top-level");
22722
- var defaultDeps$9 = {
22882
+ var defaultDeps$10 = {
22723
22883
  loadConfig: loadStoredConfig,
22724
22884
  loadProjectConfig,
22725
22885
  resolveBaseUrl,
@@ -22792,18 +22952,18 @@ async function handleBatch(parsed) {
22792
22952
  }
22793
22953
  async function handleForgeCommand(command, parsed) {
22794
22954
  try {
22795
- await executeForgeCommand(command, parsed, defaultDeps$9);
22955
+ await executeForgeCommand(command, parsed, defaultDeps$10);
22796
22956
  } catch (error) {
22797
22957
  console.error("Error:", error instanceof Error ? error.message : error);
22798
- printUsage$9(command);
22958
+ printUsage$10(command);
22799
22959
  process$1.exitCode = 1;
22800
22960
  }
22801
22961
  }
22802
- async function executeForgeCommand(command, parsed, deps = defaultDeps$9, options = {}) {
22962
+ async function executeForgeCommand(command, parsed, deps = defaultDeps$10, options = {}) {
22803
22963
  const mediaKind = options.mediaKind || CLI_GENERATION_MEDIA_KIND;
22804
22964
  if (parsed.options.follow) {
22805
22965
  if (command === "batch") throw new Error("--follow is only supported for single-output generation commands");
22806
- const ctx = await buildContext$6(parsed, deps);
22966
+ const ctx = await buildContext$7(parsed, deps);
22807
22967
  const client = await deps.createClient(ctx.env, ctx.spaceId);
22808
22968
  try {
22809
22969
  await client.connect();
@@ -22817,7 +22977,7 @@ async function executeForgeCommand(command, parsed, deps = defaultDeps$9, option
22817
22977
  validateVideoAudioOptions(parsed, mediaKind);
22818
22978
  parseVideoGenerationOptions(parsed, mediaKind);
22819
22979
  if (command !== "batch") validateProductionMetadataOptions(parsed);
22820
- const ctx = await buildContext$6(parsed, deps);
22980
+ const ctx = await buildContext$7(parsed, deps);
22821
22981
  const client = await deps.createClient(ctx.env, ctx.spaceId);
22822
22982
  try {
22823
22983
  await client.connect();
@@ -22831,7 +22991,7 @@ async function executeForgeCommand(command, parsed, deps = defaultDeps$9, option
22831
22991
  client.disconnect();
22832
22992
  }
22833
22993
  }
22834
- async function executeAudioCommand(command, parsed, deps = defaultDeps$9, options = {}) {
22994
+ async function executeAudioCommand(command, parsed, deps = defaultDeps$10, options = {}) {
22835
22995
  const audioProfile = getCliGenerationProfile("audio");
22836
22996
  if (!audioProfile.commands.includes(command)) throw new Error(`Audio generation does not support ${command}`);
22837
22997
  const modeEntry = options.mode ? getMediaOperationEntry(options.mode) : void 0;
@@ -22844,7 +23004,7 @@ async function executeAudioCommand(command, parsed, deps = defaultDeps$9, option
22844
23004
  audioMode: options.mode
22845
23005
  });
22846
23006
  }
22847
- async function executeVideoCommand(command, parsed, deps = defaultDeps$9) {
23007
+ async function executeVideoCommand(command, parsed, deps = defaultDeps$10) {
22848
23008
  const videoProfile = getCliGenerationProfile("video");
22849
23009
  if (!videoProfile.commands.includes(command)) throw new Error(`Video generation does not support ${command}`);
22850
23010
  return executeForgeCommand(command, parsed, deps, {
@@ -23414,7 +23574,7 @@ async function placeProductionRecordFromScene(input) {
23414
23574
  record
23415
23575
  });
23416
23576
  }
23417
- async function buildContext$6(parsed, deps) {
23577
+ async function buildContext$7(parsed, deps) {
23418
23578
  const projectConfig = await deps.loadProjectConfig();
23419
23579
  const env = resolveCommandEnvironment(parsed, projectConfig);
23420
23580
  const spaceId = resolveCommandSpace(parsed, projectConfig);
@@ -23810,7 +23970,7 @@ function cliImageSizeValues() {
23810
23970
  function cliImageAspectValues() {
23811
23971
  return cliOptionValues(getImageModelCapabilities().supportedAspectRatios);
23812
23972
  }
23813
- function printUsage$9(command) {
23973
+ function printUsage$10(command) {
23814
23974
  if (command === "generate") {
23815
23975
  console.log(`
23816
23976
  Usage:
@@ -23863,7 +24023,7 @@ function printBatchResult(result, outputDir, manifestPath, ctx, mediaKind) {
23863
24023
  }
23864
24024
  //#endregion
23865
24025
  //#region src/cli/commands/audio.ts
23866
- var defaultDeps$8 = {
24026
+ var defaultDeps$9 = {
23867
24027
  loadConfig: loadStoredConfig,
23868
24028
  loadProjectConfig,
23869
24029
  resolveBaseUrl,
@@ -23876,11 +24036,11 @@ async function handleAudio(parsed) {
23876
24036
  await executeAudio(parsed);
23877
24037
  } catch (error) {
23878
24038
  console.error("Error:", error instanceof Error ? error.message : error);
23879
- printUsage$8();
24039
+ printUsage$9();
23880
24040
  process$1.exitCode = 1;
23881
24041
  }
23882
24042
  }
23883
- async function executeAudio(parsed, deps = defaultDeps$8) {
24043
+ async function executeAudio(parsed, deps = defaultDeps$9) {
23884
24044
  const invocation = parseAudioInvocation(parsed.positionals);
23885
24045
  if (invocation.command === "voices") return executeAudioVoices({
23886
24046
  ...parsed,
@@ -23953,7 +24113,7 @@ function printVoices(response, print) {
23953
24113
  function formatLabels(labels) {
23954
24114
  return Object.entries(labels).map(([key, value]) => `${key}:${value}`).join(", ");
23955
24115
  }
23956
- function printUsage$8() {
24116
+ function printUsage$9() {
23957
24117
  const modes = AUDIO_FORGE_MEDIA_MODES.join("|");
23958
24118
  console.log(`
23959
24119
  Usage:
@@ -23982,7 +24142,7 @@ async function handleVideo(parsed) {
23982
24142
  });
23983
24143
  } catch (error) {
23984
24144
  console.error("Error:", error instanceof Error ? error.message : error);
23985
- printUsage$7();
24145
+ printUsage$8();
23986
24146
  process$1.exitCode = 1;
23987
24147
  }
23988
24148
  }
@@ -23991,7 +24151,7 @@ function parseVideoCommand(value) {
23991
24151
  if (value && commands.includes(value)) return value;
23992
24152
  throw new Error("Video command is required: generate, refine, or derive");
23993
24153
  }
23994
- function printUsage$7() {
24154
+ function printUsage$8() {
23995
24155
  const aspectValues = VIDEO_GENERATION_ASPECT_RATIOS.join("|");
23996
24156
  const resolutionValues = Array.from(new Set(VIDEO_GENERATION_TIERS.flatMap((tier) => getVideoGenerationResolutionsForTier(tier)))).join("|");
23997
24157
  const durationValues = VIDEO_GENERATION_DURATION_SECONDS.join("|");
@@ -24023,17 +24183,17 @@ Production metadata:
24023
24183
  }
24024
24184
  //#endregion
24025
24185
  //#region src/cli/commands/init.ts
24026
- var defaultDeps$7 = { saveProjectConfig };
24186
+ var defaultDeps$8 = { saveProjectConfig };
24027
24187
  async function handleInit(parsed) {
24028
24188
  try {
24029
24189
  await executeInit(parsed);
24030
24190
  } catch (error) {
24031
24191
  console.error("Error:", error instanceof Error ? error.message : error);
24032
- printUsage$6();
24192
+ printUsage$7();
24033
24193
  process$1.exitCode = 1;
24034
24194
  }
24035
24195
  }
24036
- async function executeInit(parsed, deps = defaultDeps$7) {
24196
+ async function executeInit(parsed, deps = defaultDeps$8) {
24037
24197
  const environment = resolveCommandEnvironment(parsed);
24038
24198
  const spaceId = resolveCommandSpace(parsed);
24039
24199
  if (!spaceId) throw new Error("--space is required");
@@ -24059,7 +24219,7 @@ async function executeInit(parsed, deps = defaultDeps$7) {
24059
24219
  spaceId
24060
24220
  };
24061
24221
  }
24062
- function printUsage$6() {
24222
+ function printUsage$7() {
24063
24223
  console.log(`
24064
24224
  Usage:
24065
24225
  makefx init --space <id> [--env production|stage|local]
@@ -24068,7 +24228,7 @@ Usage:
24068
24228
  }
24069
24229
  //#endregion
24070
24230
  //#region src/cli/commands/runs.ts
24071
- var defaultDeps$6 = {
24231
+ var defaultDeps$7 = {
24072
24232
  loadProjectConfig,
24073
24233
  listRunManifests,
24074
24234
  readRunManifest,
@@ -24081,11 +24241,11 @@ async function handleRuns(parsed) {
24081
24241
  await executeRuns(parsed);
24082
24242
  } catch (error) {
24083
24243
  console.error("Error:", error instanceof Error ? error.message : error);
24084
- printUsage$5();
24244
+ printUsage$6();
24085
24245
  process$1.exitCode = 1;
24086
24246
  }
24087
24247
  }
24088
- async function executeRuns(parsed, deps = defaultDeps$6) {
24248
+ async function executeRuns(parsed, deps = defaultDeps$7) {
24089
24249
  const projectConfig = await deps.loadProjectConfig();
24090
24250
  if (!projectConfig?.projectRoot) throw new Error("Make Effects project config not found. Run: makefx init --space <id>");
24091
24251
  requireDebugAcknowledgement(parsed);
@@ -24203,7 +24363,7 @@ function formatCreated(value) {
24203
24363
  if (Number.isNaN(date.getTime())) return value;
24204
24364
  return value.replace("T", " ").replace(/\.\d{3}Z$/, "Z").slice(0, 20);
24205
24365
  }
24206
- function printUsage$5() {
24366
+ function printUsage$6() {
24207
24367
  console.log(`
24208
24368
  Usage:
24209
24369
  makefx runs --debug
@@ -24221,7 +24381,7 @@ For timed scene assembly, use:
24221
24381
  }
24222
24382
  //#endregion
24223
24383
  //#region src/cli/commands/assets.ts
24224
- var defaultDeps$5 = {
24384
+ var defaultDeps$6 = {
24225
24385
  loadConfig: loadStoredConfig,
24226
24386
  loadProjectConfig,
24227
24387
  resolveBaseUrl,
@@ -24244,12 +24404,12 @@ async function handleAssets(parsed) {
24244
24404
  await executeAssets(parsed);
24245
24405
  } catch (error) {
24246
24406
  console.error("Error:", error instanceof Error ? error.message : error);
24247
- printUsage$4();
24407
+ printUsage$5();
24248
24408
  process$1.exitCode = 1;
24249
24409
  }
24250
24410
  }
24251
- async function executeAssets(parsed, deps = defaultDeps$5) {
24252
- const ctx = await buildContext$5(parsed, deps);
24411
+ async function executeAssets(parsed, deps = defaultDeps$6) {
24412
+ const ctx = await buildContext$6(parsed, deps);
24253
24413
  const subcommand = parsed.positionals[0] || "list";
24254
24414
  if (subcommand === "list") {
24255
24415
  const assets = await listAssets$1(ctx, deps);
@@ -24328,7 +24488,7 @@ async function executeAssets(parsed, deps = defaultDeps$5) {
24328
24488
  function normalizeOption(value) {
24329
24489
  return !value || value === "true" ? void 0 : value;
24330
24490
  }
24331
- async function buildContext$5(parsed, deps) {
24491
+ async function buildContext$6(parsed, deps) {
24332
24492
  const projectConfig = await deps.loadProjectConfig();
24333
24493
  const env = resolveCommandEnvironment(parsed, projectConfig);
24334
24494
  const spaceId = resolveCommandSpace(parsed, projectConfig);
@@ -24507,7 +24667,7 @@ function formatTimestamp(value) {
24507
24667
  if (Number.isNaN(date.getTime())) return String(value);
24508
24668
  return date.toISOString().replace("T", " ").replace(/\.\d{3}Z$/, "Z").slice(0, 20);
24509
24669
  }
24510
- function printUsage$4() {
24670
+ function printUsage$5() {
24511
24671
  console.log(`
24512
24672
  Usage:
24513
24673
  makefx assets
@@ -24522,7 +24682,7 @@ Usage:
24522
24682
  }
24523
24683
  //#endregion
24524
24684
  //#region src/cli/commands/variants.ts
24525
- var defaultDeps$4 = {
24685
+ var defaultDeps$5 = {
24526
24686
  loadConfig: loadStoredConfig,
24527
24687
  loadProjectConfig,
24528
24688
  resolveBaseUrl,
@@ -24534,12 +24694,12 @@ async function handleVariants(parsed) {
24534
24694
  await executeVariants(parsed);
24535
24695
  } catch (error) {
24536
24696
  console.error("Error:", error instanceof Error ? error.message : error);
24537
- printUsage$3();
24697
+ printUsage$4();
24538
24698
  process$1.exitCode = 1;
24539
24699
  }
24540
24700
  }
24541
- async function executeVariants(parsed, deps = defaultDeps$4) {
24542
- const ctx = await buildContext$4(parsed, deps);
24701
+ async function executeVariants(parsed, deps = defaultDeps$5) {
24702
+ const ctx = await buildContext$5(parsed, deps);
24543
24703
  const subcommand = parsed.positionals[0];
24544
24704
  if (subcommand === "delete") {
24545
24705
  const variantId = requireVariantId(parsed, "delete");
@@ -24587,7 +24747,7 @@ function requireVariantId(parsed, verb) {
24587
24747
  if (!variantId) throw new Error(`Variant ID is required: makefx variants ${verb} <variant-id>`);
24588
24748
  return variantId;
24589
24749
  }
24590
- async function buildContext$4(parsed, deps) {
24750
+ async function buildContext$5(parsed, deps) {
24591
24751
  const projectConfig = await deps.loadProjectConfig();
24592
24752
  const env = resolveCommandEnvironment(parsed, projectConfig);
24593
24753
  const spaceId = resolveCommandSpace(parsed, projectConfig);
@@ -24610,7 +24770,7 @@ async function withVariantClient(ctx, deps, run) {
24610
24770
  client.disconnect();
24611
24771
  }
24612
24772
  }
24613
- function printUsage$3() {
24773
+ function printUsage$4() {
24614
24774
  console.log(`
24615
24775
  Usage:
24616
24776
  makefx variants delete <variant-id>
@@ -24627,7 +24787,7 @@ Options:
24627
24787
  }
24628
24788
  //#endregion
24629
24789
  //#region src/cli/commands/styles.ts
24630
- var defaultDeps$3 = {
24790
+ var defaultDeps$4 = {
24631
24791
  loadConfig: loadStoredConfig,
24632
24792
  loadProjectConfig,
24633
24793
  resolveBaseUrl,
@@ -24639,26 +24799,26 @@ async function handleStyles(parsed) {
24639
24799
  await executeStyles(parsed);
24640
24800
  } catch (error) {
24641
24801
  console.error("Error:", error instanceof Error ? error.message : error);
24642
- printUsage$2();
24802
+ printUsage$3();
24643
24803
  process$1.exitCode = 1;
24644
24804
  }
24645
24805
  }
24646
- async function executeStyles(parsed, deps = defaultDeps$3) {
24806
+ async function executeStyles(parsed, deps = defaultDeps$4) {
24647
24807
  const namespace = parsed.positionals[0] || "presets";
24648
24808
  if (namespace === "references" || namespace === "refs") return executeReferences(parsed, deps);
24649
- if (namespace === "collections" || namespace === "collection") return executeCollections(parsed, deps);
24809
+ if (namespace === "collections" || namespace === "collection") return executeCollections$1(parsed, deps);
24650
24810
  if (namespace === "presets" || namespace === "preset") return executePresets(parsed, deps);
24651
24811
  throw new Error(`Unknown styles command: ${namespace}`);
24652
24812
  }
24653
24813
  async function executeReferences(parsed, deps) {
24654
- const ctx = await buildContext$3(parsed, deps);
24655
- const collectionFilter = readOption(parsed, "collection", "collectionId") || parsed.positionals[1];
24814
+ const ctx = await buildContext$4(parsed, deps);
24815
+ const collectionFilter = readOption$1(parsed, "collection", "collectionId") || parsed.positionals[1];
24656
24816
  const collections = await listStyleReferenceCollections(ctx, deps);
24657
24817
  const selected = collectionFilter ? collections.filter((collection) => collection.id === collectionFilter || collection.name === collectionFilter) : collections;
24658
24818
  if (collectionFilter && selected.length === 0) throw new Error(`Style reference collection not found: ${collectionFilter}`);
24659
24819
  const references = [];
24660
24820
  for (const collection of selected) {
24661
- const items = await listCollectionItems(ctx, deps, collection.id);
24821
+ const items = await listCollectionItems$1(ctx, deps, collection.id);
24662
24822
  for (const item of items.filter((candidate) => candidate.role === "style_ref")) references.push({
24663
24823
  collectionId: collection.id,
24664
24824
  collectionName: collection.name,
@@ -24672,24 +24832,24 @@ async function executeReferences(parsed, deps) {
24672
24832
  references
24673
24833
  };
24674
24834
  }
24675
- async function executeCollections(parsed, deps) {
24676
- const ctx = await buildContext$3(parsed, deps);
24835
+ async function executeCollections$1(parsed, deps) {
24836
+ const ctx = await buildContext$4(parsed, deps);
24677
24837
  const action = parsed.positionals[1] || "list";
24678
24838
  if (action === "list") {
24679
24839
  const collections = await listStyleReferenceCollections(ctx, deps);
24680
24840
  if (parsed.options.json === "true") deps.print(JSON.stringify(collections, null, 2));
24681
- else printCollections(collections, deps.print);
24841
+ else printCollections$1(collections, deps.print);
24682
24842
  return {
24683
24843
  type: "collections",
24684
24844
  collections
24685
24845
  };
24686
24846
  }
24687
24847
  if (action === "create") {
24688
- const name = parsed.positionals[2] || readRequiredOption(parsed, "name", "name");
24689
- const collection = await createCollection(ctx, deps, {
24690
- id: readOption(parsed, "id", "id"),
24848
+ const name = parsed.positionals[2] || readRequiredOption$1(parsed, "name", "name");
24849
+ const collection = await createCollection$1(ctx, deps, {
24850
+ id: readOption$1(parsed, "id", "id"),
24691
24851
  name,
24692
- description: nullableOption(parsed, "description", "description")
24852
+ description: nullableOption$1(parsed, "description", "description")
24693
24853
  });
24694
24854
  const items = await upsertStyleReferenceItems(ctx, deps, collection.id, parsed, false);
24695
24855
  printCollectionMutation("Created", collection, items, deps.print, parsed.options.json === "true");
@@ -24700,16 +24860,16 @@ async function executeCollections(parsed, deps) {
24700
24860
  };
24701
24861
  }
24702
24862
  if (action === "update") {
24703
- const collectionId = parsed.positionals[2] || readRequiredOption(parsed, "id", "id");
24863
+ const collectionId = parsed.positionals[2] || readRequiredOption$1(parsed, "id", "id");
24704
24864
  const changes = {};
24705
- const name = readOption(parsed, "name", "name");
24706
- const description = nullableOption(parsed, "description", "description");
24865
+ const name = readOption$1(parsed, "name", "name");
24866
+ const description = nullableOption$1(parsed, "description", "description");
24707
24867
  if (name !== void 0) changes.name = name;
24708
24868
  if (description !== void 0) changes.description = description;
24709
24869
  let collection;
24710
- if (Object.keys(changes).length > 0) collection = await updateCollection(ctx, deps, collectionId, changes);
24870
+ if (Object.keys(changes).length > 0) collection = await updateCollection$1(ctx, deps, collectionId, changes);
24711
24871
  const items = hasReferenceOptions(parsed) ? await upsertStyleReferenceItems(ctx, deps, collectionId, parsed, parsed.options.append !== "true") : void 0;
24712
- if (!collection) collection = (await listCollections(ctx, deps)).find((candidate) => candidate.id === collectionId);
24872
+ if (!collection) collection = (await listCollections$1(ctx, deps)).find((candidate) => candidate.id === collectionId);
24713
24873
  if (!collection) throw new Error(`Collection not found: ${collectionId}`);
24714
24874
  printCollectionMutation("Updated", collection, items, deps.print, parsed.options.json === "true");
24715
24875
  return {
@@ -24721,7 +24881,7 @@ async function executeCollections(parsed, deps) {
24721
24881
  throw new Error(`Unknown styles collections command: ${action}`);
24722
24882
  }
24723
24883
  async function executePresets(parsed, deps) {
24724
- const ctx = await buildContext$3(parsed, deps);
24884
+ const ctx = await buildContext$4(parsed, deps);
24725
24885
  const action = parsed.positionals[1] || "list";
24726
24886
  if (action === "list") {
24727
24887
  const presets = await listStylePresets(ctx, deps);
@@ -24733,13 +24893,13 @@ async function executePresets(parsed, deps) {
24733
24893
  };
24734
24894
  }
24735
24895
  if (action === "create") {
24736
- const name = parsed.positionals[2] || readRequiredOption(parsed, "name", "name");
24896
+ const name = parsed.positionals[2] || readRequiredOption$1(parsed, "name", "name");
24737
24897
  const response = await createStylePreset(ctx, deps, {
24738
- id: readOption(parsed, "id", "id"),
24898
+ id: readOption$1(parsed, "id", "id"),
24739
24899
  name,
24740
- description: nullableOption(parsed, "description", "description"),
24741
- stylePrompt: readOption(parsed, "prompt", "stylePrompt") ?? "",
24742
- collectionId: nullableOption(parsed, "collection", "collectionId"),
24900
+ description: nullableOption$1(parsed, "description", "description"),
24901
+ stylePrompt: readOption$1(parsed, "prompt", "stylePrompt") ?? "",
24902
+ collectionId: nullableOption$1(parsed, "collection", "collectionId"),
24743
24903
  enabled: parsed.options.disable === "true" ? false : true,
24744
24904
  isDefault: parsed.options.default === "true"
24745
24905
  });
@@ -24750,7 +24910,7 @@ async function executePresets(parsed, deps) {
24750
24910
  };
24751
24911
  }
24752
24912
  if (action === "update") {
24753
- const response = await updateStylePreset(ctx, deps, parsed.positionals[2] || readRequiredOption(parsed, "id", "id"), buildPresetUpdate(parsed));
24913
+ const response = await updateStylePreset(ctx, deps, parsed.positionals[2] || readRequiredOption$1(parsed, "id", "id"), buildPresetUpdate(parsed));
24754
24914
  printPresetMutation("Updated", response.preset, deps.print, parsed.options.json === "true");
24755
24915
  return {
24756
24916
  type: "preset",
@@ -24758,7 +24918,7 @@ async function executePresets(parsed, deps) {
24758
24918
  };
24759
24919
  }
24760
24920
  if (action === "enable" || action === "disable") {
24761
- const response = await updateStylePreset(ctx, deps, parsed.positionals[2] || readRequiredOption(parsed, "id", "id"), { enabled: action === "enable" });
24921
+ const response = await updateStylePreset(ctx, deps, parsed.positionals[2] || readRequiredOption$1(parsed, "id", "id"), { enabled: action === "enable" });
24762
24922
  printPresetMutation(action === "enable" ? "Enabled" : "Disabled", response.preset, deps.print, parsed.options.json === "true");
24763
24923
  return {
24764
24924
  type: "preset",
@@ -24766,7 +24926,7 @@ async function executePresets(parsed, deps) {
24766
24926
  };
24767
24927
  }
24768
24928
  if (action === "delete" || action === "remove") {
24769
- const presetId = parsed.positionals[2] || readRequiredOption(parsed, "id", "id");
24929
+ const presetId = parsed.positionals[2] || readRequiredOption$1(parsed, "id", "id");
24770
24930
  await deleteStylePreset(ctx, deps, presetId);
24771
24931
  if (parsed.options.json === "true") deps.print(JSON.stringify({
24772
24932
  success: true,
@@ -24780,7 +24940,7 @@ async function executePresets(parsed, deps) {
24780
24940
  }
24781
24941
  throw new Error(`Unknown styles presets command: ${action}`);
24782
24942
  }
24783
- async function buildContext$3(parsed, deps) {
24943
+ async function buildContext$4(parsed, deps) {
24784
24944
  const projectConfig = await deps.loadProjectConfig();
24785
24945
  const env = resolveCommandEnvironment(parsed, projectConfig);
24786
24946
  const spaceId = resolveCommandSpace(parsed, projectConfig);
@@ -24801,15 +24961,15 @@ async function listAssets(ctx, deps) {
24801
24961
  baseUrl: ctx.baseUrl,
24802
24962
  fetch: deps.fetch,
24803
24963
  params: { id: ctx.spaceId },
24804
- headers: authHeaders(ctx)
24964
+ headers: authHeaders$1(ctx)
24805
24965
  })).assets;
24806
24966
  }
24807
- async function listCollections(ctx, deps) {
24967
+ async function listCollections$1(ctx, deps) {
24808
24968
  return (await apiFetch("GET /api/spaces/:id/collections", {
24809
24969
  baseUrl: ctx.baseUrl,
24810
24970
  fetch: deps.fetch,
24811
24971
  params: { id: ctx.spaceId },
24812
- headers: authHeaders(ctx)
24972
+ headers: authHeaders$1(ctx)
24813
24973
  })).collections;
24814
24974
  }
24815
24975
  async function listStyleReferenceCollections(ctx, deps) {
@@ -24817,10 +24977,10 @@ async function listStyleReferenceCollections(ctx, deps) {
24817
24977
  baseUrl: ctx.baseUrl,
24818
24978
  fetch: deps.fetch,
24819
24979
  params: { id: ctx.spaceId },
24820
- headers: authHeaders(ctx)
24980
+ headers: authHeaders$1(ctx)
24821
24981
  })).collections;
24822
24982
  }
24823
- async function listCollectionItems(ctx, deps, collectionId) {
24983
+ async function listCollectionItems$1(ctx, deps, collectionId) {
24824
24984
  return (await apiFetch("GET /api/spaces/:id/collections/:collectionId/items", {
24825
24985
  baseUrl: ctx.baseUrl,
24826
24986
  fetch: deps.fetch,
@@ -24828,19 +24988,19 @@ async function listCollectionItems(ctx, deps, collectionId) {
24828
24988
  id: ctx.spaceId,
24829
24989
  collectionId
24830
24990
  },
24831
- headers: authHeaders(ctx)
24991
+ headers: authHeaders$1(ctx)
24832
24992
  })).items;
24833
24993
  }
24834
- async function createCollection(ctx, deps, json) {
24994
+ async function createCollection$1(ctx, deps, json) {
24835
24995
  return (await apiFetch("POST /api/spaces/:id/collections", {
24836
24996
  baseUrl: ctx.baseUrl,
24837
24997
  fetch: deps.fetch,
24838
24998
  params: { id: ctx.spaceId },
24839
24999
  json,
24840
- headers: authHeaders(ctx)
25000
+ headers: authHeaders$1(ctx)
24841
25001
  })).collection;
24842
25002
  }
24843
- async function updateCollection(ctx, deps, collectionId, json) {
25003
+ async function updateCollection$1(ctx, deps, collectionId, json) {
24844
25004
  return (await apiFetch("PATCH /api/spaces/:id/collections/:collectionId", {
24845
25005
  baseUrl: ctx.baseUrl,
24846
25006
  fetch: deps.fetch,
@@ -24849,10 +25009,10 @@ async function updateCollection(ctx, deps, collectionId, json) {
24849
25009
  collectionId
24850
25010
  },
24851
25011
  json,
24852
- headers: authHeaders(ctx)
25012
+ headers: authHeaders$1(ctx)
24853
25013
  })).collection;
24854
25014
  }
24855
- async function createCollectionItem(ctx, deps, collectionId, json) {
25015
+ async function createCollectionItem$1(ctx, deps, collectionId, json) {
24856
25016
  return (await apiFetch("POST /api/spaces/:id/collections/:collectionId/items", {
24857
25017
  baseUrl: ctx.baseUrl,
24858
25018
  fetch: deps.fetch,
@@ -24861,10 +25021,10 @@ async function createCollectionItem(ctx, deps, collectionId, json) {
24861
25021
  collectionId
24862
25022
  },
24863
25023
  json,
24864
- headers: authHeaders(ctx)
25024
+ headers: authHeaders$1(ctx)
24865
25025
  })).item;
24866
25026
  }
24867
- async function deleteCollectionItem(ctx, deps, collectionId, itemId) {
25027
+ async function deleteCollectionItem$1(ctx, deps, collectionId, itemId) {
24868
25028
  await apiFetch("DELETE /api/spaces/:id/collections/:collectionId/items/:itemId", {
24869
25029
  baseUrl: ctx.baseUrl,
24870
25030
  fetch: deps.fetch,
@@ -24873,7 +25033,7 @@ async function deleteCollectionItem(ctx, deps, collectionId, itemId) {
24873
25033
  collectionId,
24874
25034
  itemId
24875
25035
  },
24876
- headers: authHeaders(ctx)
25036
+ headers: authHeaders$1(ctx)
24877
25037
  });
24878
25038
  }
24879
25039
  async function listStylePresets(ctx, deps) {
@@ -24881,7 +25041,7 @@ async function listStylePresets(ctx, deps) {
24881
25041
  baseUrl: ctx.baseUrl,
24882
25042
  fetch: deps.fetch,
24883
25043
  params: { id: ctx.spaceId },
24884
- headers: authHeaders(ctx)
25044
+ headers: authHeaders$1(ctx)
24885
25045
  })).presets;
24886
25046
  }
24887
25047
  async function createStylePreset(ctx, deps, json) {
@@ -24890,7 +25050,7 @@ async function createStylePreset(ctx, deps, json) {
24890
25050
  fetch: deps.fetch,
24891
25051
  params: { id: ctx.spaceId },
24892
25052
  json,
24893
- headers: authHeaders(ctx)
25053
+ headers: authHeaders$1(ctx)
24894
25054
  });
24895
25055
  }
24896
25056
  async function updateStylePreset(ctx, deps, presetId, json) {
@@ -24902,7 +25062,7 @@ async function updateStylePreset(ctx, deps, presetId, json) {
24902
25062
  presetId
24903
25063
  },
24904
25064
  json,
24905
- headers: authHeaders(ctx)
25065
+ headers: authHeaders$1(ctx)
24906
25066
  });
24907
25067
  }
24908
25068
  async function deleteStylePreset(ctx, deps, presetId) {
@@ -24913,18 +25073,18 @@ async function deleteStylePreset(ctx, deps, presetId) {
24913
25073
  id: ctx.spaceId,
24914
25074
  presetId
24915
25075
  },
24916
- headers: authHeaders(ctx)
25076
+ headers: authHeaders$1(ctx)
24917
25077
  });
24918
25078
  }
24919
25079
  async function upsertStyleReferenceItems(ctx, deps, collectionId, parsed, replaceExisting) {
24920
25080
  const refs = await buildStyleReferenceItemRequests(ctx, deps, parsed);
24921
25081
  if (refs.length === 0) return [];
24922
25082
  if (replaceExisting) {
24923
- const existing = await listCollectionItems(ctx, deps, collectionId);
24924
- await Promise.all(existing.filter((item) => item.role === "style_ref").map((item) => deleteCollectionItem(ctx, deps, collectionId, item.id)));
25083
+ const existing = await listCollectionItems$1(ctx, deps, collectionId);
25084
+ await Promise.all(existing.filter((item) => item.role === "style_ref").map((item) => deleteCollectionItem$1(ctx, deps, collectionId, item.id)));
24925
25085
  }
24926
25086
  const created = [];
24927
- for (let index = 0; index < refs.length; index += 1) created.push(await createCollectionItem(ctx, deps, collectionId, {
25087
+ for (let index = 0; index < refs.length; index += 1) created.push(await createCollectionItem$1(ctx, deps, collectionId, {
24928
25088
  ...refs[index],
24929
25089
  role: "style_ref",
24930
25090
  sortIndex: index
@@ -24932,9 +25092,9 @@ async function upsertStyleReferenceItems(ctx, deps, collectionId, parsed, replac
24932
25092
  return created;
24933
25093
  }
24934
25094
  async function buildStyleReferenceItemRequests(ctx, deps, parsed) {
24935
- const assets = parseCsvOptions(parsed, ["assets", "asset"]);
24936
- const variants = parseCsvOptions(parsed, ["variants", "variant"]);
24937
- const refs = parseCsvOptions(parsed, ["refs", "ref"]);
25095
+ const assets = parseCsvOptions$1(parsed, ["assets", "asset"]);
25096
+ const variants = parseCsvOptions$1(parsed, ["variants", "variant"]);
25097
+ const refs = parseCsvOptions$1(parsed, ["refs", "ref"]);
24938
25098
  if (assets.length === 0 && variants.length === 0 && refs.length === 0) return [];
24939
25099
  const allAssets = await listAssets(ctx, deps);
24940
25100
  const assetById = new Map(allAssets.map((asset) => [asset.id, asset]));
@@ -24966,10 +25126,10 @@ function dedupeItemRequests(requests) {
24966
25126
  }
24967
25127
  function buildPresetUpdate(parsed) {
24968
25128
  const update = {};
24969
- const name = readOption(parsed, "name", "name");
24970
- const description = nullableOption(parsed, "description", "description");
24971
- const stylePrompt = readOption(parsed, "prompt", "stylePrompt");
24972
- const collectionId = nullableOption(parsed, "collection", "collectionId");
25129
+ const name = readOption$1(parsed, "name", "name");
25130
+ const description = nullableOption$1(parsed, "description", "description");
25131
+ const stylePrompt = readOption$1(parsed, "prompt", "stylePrompt");
25132
+ const collectionId = nullableOption$1(parsed, "collection", "collectionId");
24973
25133
  if (name !== void 0) update.name = name;
24974
25134
  if (description !== void 0) update.description = description;
24975
25135
  if (stylePrompt !== void 0) update.stylePrompt = stylePrompt;
@@ -24981,7 +25141,7 @@ function buildPresetUpdate(parsed) {
24981
25141
  if (Object.keys(update).length === 0) throw new Error("No preset updates provided");
24982
25142
  return update;
24983
25143
  }
24984
- function authHeaders(ctx) {
25144
+ function authHeaders$1(ctx) {
24985
25145
  return {
24986
25146
  "Authorization": `Bearer ${ctx.accessToken}`,
24987
25147
  "Accept": "application/json"
@@ -24997,28 +25157,28 @@ function hasReferenceOptions(parsed) {
24997
25157
  "variant"
24998
25158
  ].some((key) => Boolean(readRawOption(parsed, key)));
24999
25159
  }
25000
- function parseCsvOptions(parsed, keys) {
25160
+ function parseCsvOptions$1(parsed, keys) {
25001
25161
  return keys.flatMap((key) => parseCsv(readRawOption(parsed, key)));
25002
25162
  }
25003
25163
  function parseCsv(value) {
25004
25164
  if (!value || value === "true") return [];
25005
25165
  return value.split(",").map((item) => item.trim()).filter(Boolean);
25006
25166
  }
25007
- function readRequiredOption(parsed, kebabName, camelName) {
25008
- const value = readOption(parsed, kebabName, camelName);
25167
+ function readRequiredOption$1(parsed, kebabName, camelName) {
25168
+ const value = readOption$1(parsed, kebabName, camelName);
25009
25169
  if (value === void 0) throw new Error(`--${kebabName} is required`);
25010
25170
  return value;
25011
25171
  }
25012
- function readOption(parsed, kebabName, camelName) {
25172
+ function readOption$1(parsed, kebabName, camelName) {
25013
25173
  const value = readRawOption(parsed, kebabName) ?? readRawOption(parsed, camelName);
25014
25174
  return !value || value === "true" ? void 0 : value;
25015
25175
  }
25016
25176
  function readRawOption(parsed, key) {
25017
25177
  return parsed.options[key];
25018
25178
  }
25019
- function nullableOption(parsed, kebabName, camelName) {
25179
+ function nullableOption$1(parsed, kebabName, camelName) {
25020
25180
  if (parsed.options["no-collection"] === "true" && (kebabName === "collection" || camelName === "collectionId")) return null;
25021
- const value = readOption(parsed, kebabName, camelName);
25181
+ const value = readOption$1(parsed, kebabName, camelName);
25022
25182
  if (value === void 0) return void 0;
25023
25183
  return value === "null" || value === "-" ? null : value;
25024
25184
  }
@@ -25038,7 +25198,7 @@ function printReferences(references, print) {
25038
25198
  print(truncate(reference.collectionName, 26).padEnd(28) + item.subject_type.padEnd(10) + truncate(item.asset_id || "-", 26).padEnd(28) + truncate(item.pinned_variant_id || item.variant_id || "-", 26).padEnd(28) + truncate(item.id, 26));
25039
25199
  }
25040
25200
  }
25041
- function printCollections(collections, print) {
25201
+ function printCollections$1(collections, print) {
25042
25202
  if (collections.length === 0) {
25043
25203
  print("No style reference collections found.");
25044
25204
  return;
@@ -25082,7 +25242,7 @@ function printPresetMutation(verb, preset, print, asJson) {
25082
25242
  print(` Collection: ${preset.collection_name || preset.collection_id || "-"}`);
25083
25243
  print(` References: ${preset.reference_count}`);
25084
25244
  }
25085
- function printUsage$2() {
25245
+ function printUsage$3() {
25086
25246
  console.log(`
25087
25247
  Usage:
25088
25248
  makefx styles references [--collection <id-or-name>] [--json]
@@ -25107,6 +25267,376 @@ Options:
25107
25267
  `);
25108
25268
  }
25109
25269
  //#endregion
25270
+ //#region src/cli/commands/collections.ts
25271
+ var defaultDeps$3 = {
25272
+ loadConfig: loadStoredConfig,
25273
+ loadProjectConfig,
25274
+ resolveBaseUrl,
25275
+ fetch,
25276
+ print: console.log
25277
+ };
25278
+ async function handleCollections(parsed) {
25279
+ try {
25280
+ await executeCollections(parsed);
25281
+ } catch (error) {
25282
+ console.error("Error:", error instanceof Error ? error.message : error);
25283
+ printUsage$2();
25284
+ process$1.exitCode = 1;
25285
+ }
25286
+ }
25287
+ async function executeCollections(parsed, deps = defaultDeps$3) {
25288
+ const action = parsed.positionals[0] || "list";
25289
+ const ctx = await buildContext$3(parsed, deps);
25290
+ const json = parsed.options.json === "true";
25291
+ if (action === "list") {
25292
+ const collections = await listCollections(ctx, deps);
25293
+ if (json) printJson(collections, deps.print);
25294
+ else printCollections(collections, deps.print);
25295
+ return {
25296
+ type: "list",
25297
+ collections
25298
+ };
25299
+ }
25300
+ if (action === "create") {
25301
+ const collection = await createCollection(ctx, deps, buildCollectionCreateRequest(parsed, parsed.positionals[1] || readRequiredOption(parsed, "name")));
25302
+ if (json) printJson(collection, deps.print);
25303
+ else deps.print(`Created collection ${collection.id} (${collection.name})`);
25304
+ return {
25305
+ type: "collection",
25306
+ collection
25307
+ };
25308
+ }
25309
+ if (action === "update") {
25310
+ const collection = await updateCollection(ctx, deps, parsed.positionals[1] || readRequiredOption(parsed, "id"), buildCollectionUpdateRequest(parsed));
25311
+ if (json) printJson(collection, deps.print);
25312
+ else deps.print(`Updated collection ${collection.id} (${collection.name})`);
25313
+ return {
25314
+ type: "collection",
25315
+ collection
25316
+ };
25317
+ }
25318
+ if (action === "delete" || action === "remove-collection") {
25319
+ const collectionId = parsed.positionals[1] || readRequiredOption(parsed, "id");
25320
+ await deleteCollection(ctx, deps, collectionId);
25321
+ if (json) printJson({
25322
+ success: true,
25323
+ collectionId
25324
+ }, deps.print);
25325
+ else deps.print(`Deleted collection ${collectionId}`);
25326
+ return {
25327
+ type: "delete",
25328
+ collectionId
25329
+ };
25330
+ }
25331
+ if (action === "items" || action === "list-items") {
25332
+ const collectionId = parsed.positionals[1] || readRequiredOption(parsed, "collection");
25333
+ const items = await listCollectionItems(ctx, deps, collectionId);
25334
+ if (json) printJson(items, deps.print);
25335
+ else printItems(collectionId, items, deps.print);
25336
+ return {
25337
+ type: "items",
25338
+ collectionId,
25339
+ items
25340
+ };
25341
+ }
25342
+ if (action === "add") {
25343
+ const collectionId = parsed.positionals[1] || readRequiredOption(parsed, "collection");
25344
+ const requests = buildCollectionItemCreateRequests(parsed);
25345
+ if (requests.length === 0) throw new Error("Provide at least one --asset/--assets or --variant/--variants value");
25346
+ const items = [];
25347
+ for (const request of requests) items.push(await createCollectionItem(ctx, deps, collectionId, request));
25348
+ if (json) printJson(items, deps.print);
25349
+ else deps.print(`Added ${items.length} item${items.length === 1 ? "" : "s"} to ${collectionId}`);
25350
+ return {
25351
+ type: "items-added",
25352
+ collectionId,
25353
+ items
25354
+ };
25355
+ }
25356
+ if (action === "update-item") {
25357
+ const collectionId = parsed.positionals[1] || readRequiredOption(parsed, "collection");
25358
+ const item = await updateCollectionItem(ctx, deps, collectionId, parsed.positionals[2] || readRequiredOption(parsed, "item"), buildItemUpdateRequest(parsed));
25359
+ if (json) printJson(item, deps.print);
25360
+ else deps.print(`Updated collection item ${item.id}`);
25361
+ return {
25362
+ type: "item",
25363
+ collectionId,
25364
+ item
25365
+ };
25366
+ }
25367
+ if (action === "reorder") {
25368
+ const collectionId = parsed.positionals[1] || readRequiredOption(parsed, "collection");
25369
+ const itemIds = parseCsvOptions(parsed, ["items", "item-ids"]);
25370
+ if (itemIds.length === 0) throw new Error("Provide --items <item-id,item-id>");
25371
+ const items = await reorderCollectionItems(ctx, deps, collectionId, { itemIds });
25372
+ if (json) printJson(items, deps.print);
25373
+ else deps.print(`Reordered ${items.length} item${items.length === 1 ? "" : "s"} in ${collectionId}`);
25374
+ return {
25375
+ type: "items",
25376
+ collectionId,
25377
+ items
25378
+ };
25379
+ }
25380
+ if (action === "remove" || action === "delete-item") {
25381
+ const collectionId = parsed.positionals[1] || readRequiredOption(parsed, "collection");
25382
+ const itemId = parsed.positionals[2] || readRequiredOption(parsed, "item");
25383
+ await deleteCollectionItem(ctx, deps, collectionId, itemId);
25384
+ if (json) printJson({
25385
+ success: true,
25386
+ collectionId,
25387
+ itemId
25388
+ }, deps.print);
25389
+ else deps.print(`Removed collection item ${itemId}`);
25390
+ return {
25391
+ type: "item-delete",
25392
+ collectionId,
25393
+ itemId
25394
+ };
25395
+ }
25396
+ throw new Error(`Unknown collections command: ${action}`);
25397
+ }
25398
+ async function buildContext$3(parsed, deps) {
25399
+ const projectConfig = await deps.loadProjectConfig();
25400
+ const env = resolveCommandEnvironment(parsed, projectConfig);
25401
+ const spaceId = resolveCommandSpace(parsed, projectConfig);
25402
+ if (!spaceId) throw new Error("--space is required, or run: makefx init --space <id>");
25403
+ const config = await deps.loadConfig(env);
25404
+ if (!config) throw new Error(`Not logged in to ${env} environment. Run: ${loginCommandForEnvironment(env)}`);
25405
+ if (config.token.expiresAt < Date.now()) throw new Error(`Token expired for ${env} environment. Run: ${loginCommandForEnvironment(env)}`);
25406
+ if (env === "local") process$1.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
25407
+ return {
25408
+ env,
25409
+ spaceId,
25410
+ baseUrl: deps.resolveBaseUrl(env),
25411
+ accessToken: config.token.accessToken
25412
+ };
25413
+ }
25414
+ function buildCollectionCreateRequest(parsed, name) {
25415
+ const request = { name };
25416
+ const id = readOption(parsed, "id");
25417
+ if (id !== void 0) request.id = id;
25418
+ applyCollectionOptions(request, parsed);
25419
+ return request;
25420
+ }
25421
+ function buildCollectionUpdateRequest(parsed) {
25422
+ const request = {};
25423
+ const name = readOption(parsed, "name");
25424
+ if (name !== void 0) request.name = name;
25425
+ applyCollectionOptions(request, parsed);
25426
+ if (Object.keys(request).length === 0) throw new Error("No collection updates provided");
25427
+ return request;
25428
+ }
25429
+ function applyCollectionOptions(request, parsed) {
25430
+ const kind = readOption(parsed, "kind");
25431
+ const color = nullableOption(parsed, "color");
25432
+ const description = nullableOption(parsed, "description");
25433
+ const sortIndex = numberOption(parsed, "sort-index", "sortIndex");
25434
+ if (kind !== void 0) request.kind = kind;
25435
+ if (color !== void 0) request.color = color;
25436
+ if (description !== void 0) request.description = description;
25437
+ if (sortIndex !== void 0) request.sortIndex = sortIndex;
25438
+ }
25439
+ function buildCollectionItemCreateRequests(parsed) {
25440
+ const role = readOption(parsed, "role");
25441
+ const pinnedVariantId = nullableOption(parsed, "pinned-variant", "pinnedVariantId");
25442
+ const sortIndex = numberOption(parsed, "sort-index", "sortIndex");
25443
+ const base = {};
25444
+ if (role !== void 0) base.role = role;
25445
+ if (pinnedVariantId !== void 0) base.pinnedVariantId = pinnedVariantId;
25446
+ if (sortIndex !== void 0) base.sortIndex = sortIndex;
25447
+ return [...parseCsvOptions(parsed, ["asset", "assets"]).map((assetId) => ({
25448
+ ...base,
25449
+ subjectType: "asset",
25450
+ assetId
25451
+ })), ...parseCsvOptions(parsed, ["variant", "variants"]).map((variantId) => ({
25452
+ ...base,
25453
+ subjectType: "variant",
25454
+ variantId
25455
+ }))];
25456
+ }
25457
+ function buildItemUpdateRequest(parsed) {
25458
+ const request = {};
25459
+ const role = readOption(parsed, "role");
25460
+ const pinnedVariantId = nullableOption(parsed, "pinned-variant", "pinnedVariantId");
25461
+ const sortIndex = numberOption(parsed, "sort-index", "sortIndex");
25462
+ if (role !== void 0) request.role = role;
25463
+ if (pinnedVariantId !== void 0) request.pinnedVariantId = pinnedVariantId;
25464
+ if (sortIndex !== void 0) request.sortIndex = sortIndex;
25465
+ if (Object.keys(request).length === 0) throw new Error("No collection item updates provided");
25466
+ return request;
25467
+ }
25468
+ async function listCollections(ctx, deps) {
25469
+ return (await apiFetch("GET /api/spaces/:id/collections", {
25470
+ baseUrl: ctx.baseUrl,
25471
+ fetch: deps.fetch,
25472
+ params: { id: ctx.spaceId },
25473
+ headers: authHeaders(ctx)
25474
+ })).collections;
25475
+ }
25476
+ async function createCollection(ctx, deps, json) {
25477
+ return (await apiFetch("POST /api/spaces/:id/collections", {
25478
+ baseUrl: ctx.baseUrl,
25479
+ fetch: deps.fetch,
25480
+ params: { id: ctx.spaceId },
25481
+ json,
25482
+ headers: authHeaders(ctx)
25483
+ })).collection;
25484
+ }
25485
+ async function updateCollection(ctx, deps, collectionId, json) {
25486
+ return (await apiFetch("PATCH /api/spaces/:id/collections/:collectionId", {
25487
+ baseUrl: ctx.baseUrl,
25488
+ fetch: deps.fetch,
25489
+ params: {
25490
+ id: ctx.spaceId,
25491
+ collectionId
25492
+ },
25493
+ json,
25494
+ headers: authHeaders(ctx)
25495
+ })).collection;
25496
+ }
25497
+ async function deleteCollection(ctx, deps, collectionId) {
25498
+ await apiFetch("DELETE /api/spaces/:id/collections/:collectionId", {
25499
+ baseUrl: ctx.baseUrl,
25500
+ fetch: deps.fetch,
25501
+ params: {
25502
+ id: ctx.spaceId,
25503
+ collectionId
25504
+ },
25505
+ headers: authHeaders(ctx)
25506
+ });
25507
+ }
25508
+ async function listCollectionItems(ctx, deps, collectionId) {
25509
+ return (await apiFetch("GET /api/spaces/:id/collections/:collectionId/items", {
25510
+ baseUrl: ctx.baseUrl,
25511
+ fetch: deps.fetch,
25512
+ params: {
25513
+ id: ctx.spaceId,
25514
+ collectionId
25515
+ },
25516
+ headers: authHeaders(ctx)
25517
+ })).items;
25518
+ }
25519
+ async function createCollectionItem(ctx, deps, collectionId, json) {
25520
+ return (await apiFetch("POST /api/spaces/:id/collections/:collectionId/items", {
25521
+ baseUrl: ctx.baseUrl,
25522
+ fetch: deps.fetch,
25523
+ params: {
25524
+ id: ctx.spaceId,
25525
+ collectionId
25526
+ },
25527
+ json,
25528
+ headers: authHeaders(ctx)
25529
+ })).item;
25530
+ }
25531
+ async function updateCollectionItem(ctx, deps, collectionId, itemId, json) {
25532
+ return (await apiFetch("PATCH /api/spaces/:id/collections/:collectionId/items/:itemId", {
25533
+ baseUrl: ctx.baseUrl,
25534
+ fetch: deps.fetch,
25535
+ params: {
25536
+ id: ctx.spaceId,
25537
+ collectionId,
25538
+ itemId
25539
+ },
25540
+ json,
25541
+ headers: authHeaders(ctx)
25542
+ })).item;
25543
+ }
25544
+ async function reorderCollectionItems(ctx, deps, collectionId, json) {
25545
+ return (await apiFetch("POST /api/spaces/:id/collections/:collectionId/items/reorder", {
25546
+ baseUrl: ctx.baseUrl,
25547
+ fetch: deps.fetch,
25548
+ params: {
25549
+ id: ctx.spaceId,
25550
+ collectionId
25551
+ },
25552
+ json,
25553
+ headers: authHeaders(ctx)
25554
+ })).items;
25555
+ }
25556
+ async function deleteCollectionItem(ctx, deps, collectionId, itemId) {
25557
+ await apiFetch("DELETE /api/spaces/:id/collections/:collectionId/items/:itemId", {
25558
+ baseUrl: ctx.baseUrl,
25559
+ fetch: deps.fetch,
25560
+ params: {
25561
+ id: ctx.spaceId,
25562
+ collectionId,
25563
+ itemId
25564
+ },
25565
+ headers: authHeaders(ctx)
25566
+ });
25567
+ }
25568
+ function printCollections(collections, print) {
25569
+ if (collections.length === 0) {
25570
+ print("No collections found.");
25571
+ return;
25572
+ }
25573
+ for (const collection of collections) {
25574
+ const suffix = collection.description ? ` - ${collection.description}` : "";
25575
+ print(`${collection.id}\t${collection.name}\t${collection.kind}${suffix}`);
25576
+ }
25577
+ }
25578
+ function printItems(collectionId, items, print) {
25579
+ if (items.length === 0) {
25580
+ print(`No items found in ${collectionId}.`);
25581
+ return;
25582
+ }
25583
+ for (const item of items) {
25584
+ const subject = item.subject_type === "asset" ? `asset:${item.asset_id}` : `variant:${item.variant_id}`;
25585
+ const pinned = item.pinned_variant_id ? ` pinned:${item.pinned_variant_id}` : "";
25586
+ print(`${item.id}\t${subject}\t${item.role}${pinned}`);
25587
+ }
25588
+ }
25589
+ function printJson(value, print) {
25590
+ print(JSON.stringify(value, null, 2));
25591
+ }
25592
+ function authHeaders(ctx) {
25593
+ return {
25594
+ "Authorization": `Bearer ${ctx.accessToken}`,
25595
+ "Accept": "application/json"
25596
+ };
25597
+ }
25598
+ function readOption(parsed, ...keys) {
25599
+ for (const key of keys) {
25600
+ const value = parsed.options[key];
25601
+ if (value !== void 0 && value !== "true") return value;
25602
+ }
25603
+ }
25604
+ function readRequiredOption(parsed, ...keys) {
25605
+ const value = readOption(parsed, ...keys);
25606
+ if (!value) throw new Error(`Missing required option --${keys[0]}`);
25607
+ return value;
25608
+ }
25609
+ function nullableOption(parsed, ...keys) {
25610
+ for (const key of keys) {
25611
+ if (!(key in parsed.options)) continue;
25612
+ const value = parsed.options[key];
25613
+ if (value === "null" || value === "none" || value === "") return null;
25614
+ if (value !== "true") return value;
25615
+ }
25616
+ }
25617
+ function numberOption(parsed, ...keys) {
25618
+ const value = readOption(parsed, ...keys);
25619
+ if (value === void 0) return void 0;
25620
+ const number = Number(value);
25621
+ if (!Number.isInteger(number)) throw new Error(`Expected integer for --${keys[0]}`);
25622
+ return number;
25623
+ }
25624
+ function parseCsvOptions(parsed, keys) {
25625
+ return keys.flatMap((key) => (parsed.options[key] || "").split(",").map((value) => value.trim()).filter(Boolean));
25626
+ }
25627
+ function printUsage$2() {
25628
+ console.error(`Usage:
25629
+ makefx collections list [--json]
25630
+ makefx collections create <name> [--kind <kind>] [--description <text>] [--json]
25631
+ makefx collections update <collection-id> [--name <name>] [--description <text>] [--json]
25632
+ makefx collections delete <collection-id> [--json]
25633
+ makefx collections items <collection-id> [--json]
25634
+ makefx collections add <collection-id> --asset <asset-id>[,<asset-id>] [--variant <variant-id>] [--role <role>] [--json]
25635
+ makefx collections update-item <collection-id> <item-id> [--role <role>] [--pinned-variant <variant-id|none>] [--sort-index <n>] [--json]
25636
+ makefx collections reorder <collection-id> --items <item-id,item-id> [--json]
25637
+ makefx collections remove <collection-id> <item-id> [--json]`);
25638
+ }
25639
+ //#endregion
25110
25640
  //#region src/cli/commands/usage.ts
25111
25641
  var defaultDeps$2 = {
25112
25642
  loadConfig: loadStoredConfig,
@@ -25717,7 +26247,7 @@ Options:
25717
26247
  }
25718
26248
  //#endregion
25719
26249
  //#region src/cli/index.ts
25720
- var CLI_VERSION = "0.2.1+2f99bf2b725b";
26250
+ var CLI_VERSION = "0.2.3+5e6f9cfaba00";
25721
26251
  async function main() {
25722
26252
  const argv = process$1.argv.slice(2);
25723
26253
  if (argv[0] === "--") argv.shift();
@@ -25858,6 +26388,10 @@ function printCommandHelp(command, positionals) {
25858
26388
  case "style":
25859
26389
  printStylesHelp();
25860
26390
  return;
26391
+ case "collections":
26392
+ case "collection":
26393
+ printCollectionsHelp();
26394
+ return;
25861
26395
  case "rotation":
25862
26396
  printRotationHelp();
25863
26397
  return;
@@ -25911,6 +26445,7 @@ Project:
25911
26445
  styles presets List style presets
25912
26446
  styles collections List style reference collections
25913
26447
  styles references List style reference assets
26448
+ collections Manage normal Space collections
25914
26449
  ${rotationHelp}
25915
26450
  tileset "prompt" --type terrain --grid 3x3
25916
26451
  Generate a consistent tile set
@@ -25935,6 +26470,10 @@ Spaces:
25935
26470
  spaces --details [--json] List spaces with asset summaries
25936
26471
  spaces --id <id> [--json] Show details for a specific space
25937
26472
  spaces create <name> Create a new space
26473
+ spaces delete <id> [--json] Archive a space for support recovery
26474
+ spaces inspect-deleted <id> [--json]
26475
+ Inspect an archived space as an admin
26476
+ spaces restore <id> [--json] Restore an archived space as an admin
25938
26477
 
25939
26478
  Listen:
25940
26479
  listen --space <id> Connect to space WebSocket and stream all events
@@ -25989,6 +26528,7 @@ Examples:
25989
26528
  makefx productions export --production-id s01e01-a2
25990
26529
  makefx upload hero.png --name "Hero" --collection collection_cast
25991
26530
  makefx upload hero.png --name "Hero" --collection-name "Cast" --json
26531
+ makefx collections add collection_cast --asset asset_123 --role character
25992
26532
  makefx upload thumbnail.png --asset asset_thumb --manual-relation thumbnail_for:asset:asset_target
25993
26533
  makefx assets
25994
26534
  makefx usage --from 2026-06-01
@@ -26053,6 +26593,9 @@ Usage:
26053
26593
  makefx spaces --id <space_id> [--json]
26054
26594
  makefx spaces create <name>
26055
26595
  makefx spaces create --name "My Space" [--init] [--json]
26596
+ makefx spaces delete <space_id> [--json]
26597
+ makefx spaces inspect-deleted <space_id> [--json]
26598
+ makefx spaces restore <space_id> [--json]
26056
26599
  `);
26057
26600
  }
26058
26601
  function printListenHelp() {
@@ -26079,7 +26622,8 @@ Options:
26079
26622
  --provider <name> Provider provenance for uploaded media
26080
26623
  --provider-metadata <json> Provider metadata JSON object
26081
26624
  --generation-provenance <json> Extra provenance JSON object
26082
- --source-variant <id> Existing source variant for upload lineage
26625
+ --source-variant <ids> Comma-separated source variants for upload lineage
26626
+ --source-variants <ids> Alias for --source-variant
26083
26627
  --relation-type <type> Lineage type: derived, refined, or forked (default: derived)
26084
26628
  --active-variant-behavior <b> if-missing, set-active, or keep
26085
26629
  --collection <ids> Comma-separated collection IDs for the uploaded asset or variant
@@ -26391,6 +26935,34 @@ Options:
26391
26935
  --local Shortcut for --env local
26392
26936
  `);
26393
26937
  }
26938
+ function printCollectionsHelp() {
26939
+ console.log(`
26940
+ Usage:
26941
+ makefx collections list [--json]
26942
+ makefx collections create <name> [--kind cast|backgrounds|scenes|thumbnails|maps|deliverables|custom] [--color <hex>] [--description <text>] [--sort-index <n>] [--json]
26943
+ makefx collections update <collection-id> [--name <name>] [--kind cast|backgrounds|scenes|thumbnails|maps|deliverables|custom] [--color <hex|none>] [--description <text|none>] [--sort-index <n>] [--json]
26944
+ makefx collections delete <collection-id> [--json]
26945
+ makefx collections items <collection-id> [--json]
26946
+ makefx collections add <collection-id> --asset <asset-id>[,<asset-id>] [--variant <variant-id>[,<variant-id>]] [--role <role>] [--pinned-variant <variant-id|none>] [--sort-index <n>] [--json]
26947
+ makefx collections update-item <collection-id> <item-id> [--role <role>] [--pinned-variant <variant-id|none>] [--sort-index <n>] [--json]
26948
+ makefx collections reorder <collection-id> --items <item-id,item-id> [--json]
26949
+ makefx collections remove <collection-id> <item-id> [--json]
26950
+
26951
+ Model:
26952
+ Collections organize existing Space assets or exact variants. They do not
26953
+ change generation lineage.
26954
+
26955
+ Options:
26956
+ --space <id> Target space ID; defaults from the initialized project
26957
+ --asset <ids> Comma-separated asset IDs to add
26958
+ --assets <ids> Alias for --asset
26959
+ --variant <ids> Comma-separated variant IDs to add
26960
+ --variants <ids> Alias for --variant
26961
+ --json Print machine-readable output
26962
+ --env <env> Environment (production|stage|local)
26963
+ --local Shortcut for --env local
26964
+ `);
26965
+ }
26394
26966
  function printRotationHelp() {
26395
26967
  if (!isCliRotationEnabled()) {
26396
26968
  console.log(rotationDisabledMessage());
@@ -26554,6 +27126,10 @@ async function dispatchCommand(command, parsed) {
26554
27126
  case "style":
26555
27127
  await handleStyles(parsed);
26556
27128
  break;
27129
+ case "collections":
27130
+ case "collection":
27131
+ await handleCollections(parsed);
27132
+ break;
26557
27133
  case "rotation":
26558
27134
  await handleRotation(parsed);
26559
27135
  break;