@koda-sl/baker-cli 0.100.0 → 0.102.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/README.md CHANGED
@@ -2381,7 +2381,7 @@ baker actions unlink --blocker <id> --blocked <id>
2381
2381
  # Review and edit the ops staged in THIS chat before publish
2382
2382
  baker actions draft # show every staged op + footgun warnings
2383
2383
  baker actions draft remove temp_hero # drop a staged create (cascades its complete/link ops)
2384
- baker actions draft remove <id> --op complete # drop a staged op on a real action (--op update|complete|discard|tagAdd|tagRemove)
2384
+ baker actions draft remove <id> --op complete # drop a staged op on a real action (--op update|complete|discard)
2385
2385
  baker actions draft clear # drop everything staged in this chat
2386
2386
  ```
2387
2387
 
package/dist/cli.js CHANGED
@@ -861,7 +861,7 @@ var discardCommand = defineCommand4({
861
861
 
862
862
  // src/commands/actions/draft.ts
863
863
  import { defineCommand as defineCommand5 } from "citty";
864
- var REMOVE_OP_KINDS = ["update", "complete", "discard", "tagAdd", "tagRemove"];
864
+ var REMOVE_OP_KINDS = ["update", "complete", "discard"];
865
865
  registerSchema({
866
866
  command: "actions.draft.list",
867
867
  description: "Review the action ops staged in THIS chat's draft before publish (creates/updates/completes/discards/links). Staged ops are invisible to `actions list`/`status` until the chat publishes \u2014 use this to verify what will apply and catch duplicates.",
@@ -869,15 +869,14 @@ registerSchema({
869
869
  });
870
870
  registerSchema({
871
871
  command: "actions.draft.remove",
872
- description: "Drop a single staged action op from this chat's draft before publish. For a tempId, removing the create cascades into its complete/link/tagAdd ops. For a real action ID, pass --op to say which op to drop. Use this to UNDO a staged op \u2014 never stage `complete` to delete an action.",
872
+ description: "Drop a single staged action op from this chat's draft before publish. For a tempId, removing the create cascades into its complete/link ops. For a real action ID, pass --op to say which op to drop. Use this to UNDO a staged op \u2014 never stage `complete` to delete an action.",
873
873
  args: {
874
874
  ref: { type: "string", description: "tempId (temp_*) or real action ID to drop from the draft", required: true },
875
875
  op: {
876
876
  type: "string",
877
- description: "Required for real action IDs: which op to drop (update|complete|discard|tagAdd|tagRemove)",
877
+ description: "Required for real action IDs: which op to drop (update|complete|discard)",
878
878
  required: false
879
- },
880
- "tag-slug": { type: "string", description: "Tag slug (only for --op tagAdd|tagRemove)", required: false }
879
+ }
881
880
  }
882
881
  });
883
882
  registerSchema({
@@ -909,10 +908,9 @@ var removeCommand = defineCommand5({
909
908
  ref: { type: "positional", description: "tempId or real action ID", required: false },
910
909
  op: {
911
910
  type: "string",
912
- description: "Op kind for real IDs: update|complete|discard|tagAdd|tagRemove",
911
+ description: "Op kind for real IDs: update|complete|discard",
913
912
  required: false
914
- },
915
- "tag-slug": { type: "string", description: "Tag slug (for tagAdd|tagRemove)", required: false }
913
+ }
916
914
  },
917
915
  run: async ({ args }) => {
918
916
  try {
@@ -936,10 +934,9 @@ var removeCommand = defineCommand5({
936
934
  `Removing a staged op for a real action ID requires --op (one of: ${REMOVE_OP_KINDS.join("|")}).`
937
935
  );
938
936
  }
939
- const tagSlug = args["tag-slug"];
940
937
  await apiPost("/api/actions/draft-op/remove", {
941
938
  chatId,
942
- target: { kind: "actionId", actionId: ref, opKind: op, ...tagSlug ? { tagSlug } : {} }
939
+ target: { kind: "actionId", actionId: ref, opKind: op }
943
940
  });
944
941
  writeJson({ ok: true, data: { removed: ref, kind: "actionId", op } });
945
942
  } catch (err) {
@@ -12144,8 +12141,8 @@ async function uploadLocalImage(args, deps = defaultImageApiDeps) {
12144
12141
  function getImage(deps, imageId) {
12145
12142
  return deps.get("/api/images/get", { id: imageId });
12146
12143
  }
12147
- function updateImageTags(deps, args) {
12148
- return deps.post("/api/images/tag", args);
12144
+ function publishImageAsCreative(deps, args) {
12145
+ return deps.post("/api/creatives/publish", args);
12149
12146
  }
12150
12147
  async function waitForReadyImage(deps, imageId, opts = {}) {
12151
12148
  const timeoutMs = opts.timeoutMs ?? imageProcessingTimeoutMs;
@@ -12167,15 +12164,19 @@ async function waitForReadyImage(deps, imageId, opts = {}) {
12167
12164
  }
12168
12165
 
12169
12166
  // src/commands/creatives/publish.ts
12170
- var creativeTag = "creative";
12171
12167
  var creativeContentTypes = ["image/png", "image/jpeg", "image/webp"];
12172
12168
  registerSchema({
12173
12169
  command: "creatives.publish",
12174
- description: "Publish a final static creative image to Baker Images, apply the official creative tag, and return an image reference.",
12170
+ description: "Publish a final static creative image to Baker Creatives and return a creative reference.",
12175
12171
  args: {
12176
12172
  file: { type: "string", description: "Local PNG/JPG/WebP creative image path", required: true },
12177
12173
  title: { type: "string", description: "Human title for the creative output", required: true },
12178
- context: { type: "string", description: "Optional describe context for the image row", required: false }
12174
+ context: { type: "string", description: "Optional describe context for the image asset", required: false },
12175
+ sourceReferenceUrl: {
12176
+ type: "string",
12177
+ description: "Optional URL of the original reference ad",
12178
+ required: false
12179
+ }
12179
12180
  }
12180
12181
  });
12181
12182
  function detectCreativeContentType(filePath) {
@@ -12184,29 +12185,22 @@ function detectCreativeContentType(filePath) {
12184
12185
  unsupportedMessage: "Unsupported creative image extension. Use PNG, JPG, or WebP."
12185
12186
  });
12186
12187
  }
12187
- function imageToCreativeReference(image, title) {
12188
- if (!image.imageUrl) {
12189
- throw new ApiError("IMAGE_PROCESSING_ERROR", "Published image is missing imageUrl");
12188
+ function parseOptionalUrl(value) {
12189
+ if (value === void 0 || value.trim() === "") {
12190
+ return void 0;
12191
+ }
12192
+ try {
12193
+ return new URL(value).toString();
12194
+ } catch {
12195
+ throw new ApiError("VALIDATION_ERROR", "--source-reference-url must be a valid URL");
12190
12196
  }
12191
- return {
12192
- type: "image",
12193
- slug: image._id,
12194
- title,
12195
- tags: image.tags?.includes(creativeTag) ? image.tags : [...image.tags ?? [], creativeTag],
12196
- imageUrl: image.imageUrl,
12197
- thumbnailUrl: image.thumbnailUrl ?? image.imageUrl,
12198
- storageKey: image.storageKey,
12199
- width: image.width,
12200
- height: image.height,
12201
- aspectRatio: image.aspectRatio,
12202
- source: image.source
12203
- };
12204
12197
  }
12205
12198
  async function publishCreative(args, deps = defaultImageApiDeps) {
12206
12199
  const title = args.title.trim();
12207
12200
  if (!title) {
12208
12201
  throw new ApiError("VALIDATION_ERROR", "--title is required");
12209
12202
  }
12203
+ const sourceReferenceUrl = parseOptionalUrl(args.sourceReferenceUrl);
12210
12204
  const contentType = detectCreativeContentType(args.file);
12211
12205
  const upload = await uploadLocalImage(
12212
12206
  {
@@ -12217,24 +12211,27 @@ async function publishCreative(args, deps = defaultImageApiDeps) {
12217
12211
  },
12218
12212
  deps
12219
12213
  );
12220
- const readyImage = await waitForReadyImage(deps, upload.imageId, { timeoutMs: imageProcessingTimeoutMs });
12221
- await updateImageTags(deps, {
12222
- imageIds: [upload.imageId],
12223
- addTags: [creativeTag],
12224
- removeTags: []
12214
+ await waitForReadyImage(deps, upload.imageId, { timeoutMs: imageProcessingTimeoutMs });
12215
+ return publishImageAsCreative(deps, {
12216
+ imageId: upload.imageId,
12217
+ title,
12218
+ sourceReferenceUrl
12225
12219
  });
12226
- const taggedImage = await getImage(deps, upload.imageId);
12227
- return { imageId: upload.imageId, reference: imageToCreativeReference({ ...readyImage, ...taggedImage }, title) };
12228
12220
  }
12229
12221
  var publishCommand = defineCommand87({
12230
12222
  meta: {
12231
12223
  name: "publish",
12232
- description: "Publish a final static creative image to Baker Images, deterministically tag it as creative, and print the image reference JSON."
12224
+ description: "Publish a final static creative image to Baker Creatives and print the creative reference JSON."
12233
12225
  },
12234
12226
  args: {
12235
12227
  file: { type: "positional", description: "Local PNG/JPG/WebP creative image path", required: false },
12236
12228
  title: { type: "string", description: "Human title for the creative output", required: false },
12237
- context: { type: "string", description: "Optional describe context for the image row", required: false }
12229
+ context: { type: "string", description: "Optional describe context for the image asset", required: false },
12230
+ sourceReferenceUrl: {
12231
+ type: "string",
12232
+ description: "Optional URL of the original reference ad",
12233
+ required: false
12234
+ }
12238
12235
  },
12239
12236
  run: async ({ args }) => {
12240
12237
  try {
@@ -12248,7 +12245,12 @@ var publishCommand = defineCommand87({
12248
12245
  writeJson({ ok: false, error: { code: "VALIDATION_ERROR", message: "--title is required" } });
12249
12246
  process.exit(1);
12250
12247
  }
12251
- const data = await publishCreative({ file, title, context: args.context });
12248
+ const data = await publishCreative({
12249
+ file,
12250
+ title,
12251
+ context: args.context,
12252
+ sourceReferenceUrl: args.sourceReferenceUrl
12253
+ });
12252
12254
  writeJson({ ok: true, data });
12253
12255
  } catch (err) {
12254
12256
  if (err instanceof ApiError) {