@koda-sl/baker-cli 0.122.0-dev.3a1b48e85 → 0.122.0-dev.57a9836c5

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.js CHANGED
@@ -1,19 +1,25 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
+ BackendClient,
3
4
  ELEVENLABS_MAX_MUSIC_LENGTH_MS,
4
5
  IMAGE_GENERATE_MODELS,
5
6
  LayerExecutionError,
6
7
  MODEL_REGISTRY,
7
8
  SEEDANCE_DURATIONS,
8
9
  ValidationError,
10
+ collectAssetRefLikes,
9
11
  createEngineFromEnv,
10
12
  defaultRegistry,
11
13
  describeFailureReason,
12
14
  elementMentionKeywords,
13
15
  generateCatalog,
16
+ isPersistedAssetRef,
17
+ requireCredentialsFromEnv,
14
18
  resolveConcurrency,
19
+ sha256Hex,
20
+ ulid,
15
21
  validateCanvasDeep
16
- } from "./chunk-MWFJ5NOP.js";
22
+ } from "./chunk-SH6L4BCQ.js";
17
23
  import {
18
24
  csvOrJson,
19
25
  daysAgoIso,
@@ -49,7 +55,7 @@ import {
49
55
  import "./chunk-5WRI5ZAA.js";
50
56
 
51
57
  // src/cli.ts
52
- import { defineCommand as defineCommand161, runMain } from "citty";
58
+ import { defineCommand as defineCommand160, runMain } from "citty";
53
59
 
54
60
  // src/commands/actions/index.ts
55
61
  import { defineCommand as defineCommand18 } from "citty";
@@ -848,6 +854,7 @@ var LINKEDIN_LIMITS = {
848
854
  choiceOptionsMax: 30,
849
855
  choiceOptionTextMax: 100,
850
856
  thankYouMessageMax: 300,
857
+ privacyPolicyTextMax: 2e3,
851
858
  legalDisclaimerMax: 2e3,
852
859
  consentsMax: 5,
853
860
  // Campaign Manager caps disclosure checkboxes at 5
@@ -1442,6 +1449,7 @@ var leadFormFields = {
1442
1449
  /** Form language, e.g. { country: "US", language: "en" }. Defaults to the account locale on LinkedIn. */
1443
1450
  locale: z2.object({ country: z2.string().length(2), language: z2.string().length(2) }).optional(),
1444
1451
  privacyPolicyUrl: httpsUrlSchema,
1452
+ privacyPolicyText: z2.string().max(LEAD.privacyPolicyTextMax).optional(),
1445
1453
  questions: z2.array(leadFormQuestionSchema).min(1).max(LEAD.questionsMax),
1446
1454
  consents: z2.array(leadFormConsentSchema).max(LEAD.consentsMax).optional(),
1447
1455
  hiddenFields: z2.array(leadFormHiddenFieldSchema).max(LEAD.hiddenFieldsMax).optional(),
@@ -1916,241 +1924,142 @@ var imagesIngestResponseSchema = z4.object({
1916
1924
  contentHash: z4.string()
1917
1925
  });
1918
1926
 
1919
- // ../api/src/tags.ts
1920
- import { z as z5 } from "zod";
1921
- var TAG_TYPES = [
1922
- "meta",
1923
- "amplitude",
1924
- "googleAds",
1925
- "tiktok",
1926
- "vwo",
1927
- "hotjar",
1928
- "clarity",
1929
- "pinterest",
1930
- "code",
1931
- "googleAnalytics",
1932
- "googleTagManager",
1933
- "hubspot",
1934
- "linkedinInsightTag",
1935
- "onetrust",
1936
- "posthog",
1937
- "datafast",
1938
- "recaptcha",
1939
- "twitterAds"
1940
- ];
1941
- var tagTypeSchema = z5.enum(TAG_TYPES);
1942
- var tagDraftOpKindSchema = z5.enum(["create", "update", "delete"]);
1943
- var tagDraftOpViewSchema = z5.object({
1944
- /** `tag_temp_*` for staged creates; the real tag id for update/delete ops. */
1945
- ref: z5.string(),
1946
- kind: tagDraftOpKindSchema,
1947
- type: tagTypeSchema,
1948
- /** Present on update/delete ops — the real tag this op targets. */
1949
- tagId: z5.string().optional(),
1950
- /** Non-secret config (create: full; update: the staged patch). Secrets are structurally absent. */
1951
- config: z5.record(z5.string(), z5.string()),
1952
- /** Update only — fields the op explicitly clears. */
1953
- clearFields: z5.array(z5.string()).optional(),
1954
- /** Names of secret fields already provided via the dashboard secure form. Never values. */
1955
- secretsSet: z5.array(z5.string()),
1956
- /** Names of secret fields still awaiting user input. */
1957
- secretsPending: z5.array(z5.string()),
1958
- summary: z5.string(),
1959
- stagedAt: z5.number()
1960
- });
1961
- var tagsEffectiveEntrySchema = z5.object({
1962
- /** Real tag id, or `tag_temp_*` for staged creates. Use as flow side-effect `tagIds` value. */
1963
- ref: z5.string(),
1964
- tagId: z5.string().optional(),
1965
- type: tagTypeSchema,
1966
- /** Value of the type's identifying field, when set. */
1967
- identifier: z5.string().optional(),
1968
- /** Redacted config; for staged updates, production config with the patch merged. */
1969
- config: z5.record(z5.string(), z5.string()),
1970
- /** Absent = live production tag with no staged changes in this chat. */
1971
- staged: tagDraftOpKindSchema.optional(),
1972
- secretsSet: z5.array(z5.string()),
1973
- secretsPending: z5.array(z5.string())
1974
- });
1975
- var tagsListRequestSchema = z5.object({ chatId: z5.string() });
1976
- var tagsListResponseSchema = z5.object({ tags: z5.array(tagsEffectiveEntrySchema) });
1977
- var tagsDraftListRequestSchema = z5.object({ chatId: z5.string() });
1978
- var tagsDraftListResponseSchema = z5.object({
1979
- status: z5.enum(["active", "publishing", "applied", "discarded", "none"]),
1980
- ops: z5.array(tagDraftOpViewSchema)
1981
- });
1982
- var tagInputRequestSchema = z5.object({
1983
- // Every tag change is a tab in the approval form: create/edit show the full
1984
- // body; delete shows a confirm. No tag change bypasses this approval.
1985
- mode: z5.enum(["create", "edit", "delete"]),
1986
- tagType: tagTypeSchema,
1987
- /** Edit/delete mode — the real tag id or `tag_temp_*` ref being changed. */
1988
- ref: z5.string().optional(),
1989
- /** Non-secret values the agent proposes to prefill. Secret keys are stripped at every boundary. */
1990
- prefilledConfig: z5.record(z5.string(), z5.string()).optional(),
1991
- /** Secret field names the agent asks the user to provide. */
1992
- requestedSecretFields: z5.array(z5.string()).optional(),
1993
- /** Short message shown above the form explaining why the input is needed. */
1994
- message: z5.string().optional()
1995
- });
1996
- var tagChangeToolInputSchema = z5.object({
1997
- changes: z5.array(tagInputRequestSchema).min(1).max(8)
1998
- });
1999
- var tagInputResultSchema = z5.discriminatedUnion("status", [
2000
- z5.object({
2001
- status: z5.literal("submitted"),
2002
- ref: z5.string(),
2003
- type: tagTypeSchema,
2004
- /** Identifying field name → value (non-secret), when the type has one. */
2005
- identifier: z5.record(z5.string(), z5.string()).optional(),
2006
- secretFieldsSet: z5.array(z5.string()),
2007
- note: z5.string().optional()
2008
- }),
2009
- z5.object({
2010
- status: z5.literal("declined"),
2011
- reason: z5.string().optional()
2012
- })
2013
- ]);
2014
- var tagChangeToolResultSchema = z5.object({
2015
- results: z5.array(tagInputResultSchema)
2016
- });
2017
-
2018
1927
  // ../api/src/testimonials.ts
2019
- import { z as z6 } from "zod";
2020
- var testimonialSourceTypeSchema = z6.enum(["google", "trustpilot"]);
2021
- var testimonialStatusSchema = z6.enum(["pending", "processing", "ready", "error"]);
2022
- var testimonialSentimentSchema = z6.enum(["positive", "neutral", "negative"]);
2023
- var testimonialDocSchema = z6.object({
2024
- _id: z6.string(),
2025
- _creationTime: z6.number(),
2026
- companyId: z6.string(),
2027
- sourceId: z6.string(),
1928
+ import { z as z5 } from "zod";
1929
+ var testimonialSourceTypeSchema = z5.enum(["google", "trustpilot"]);
1930
+ var testimonialStatusSchema = z5.enum(["pending", "processing", "ready", "error"]);
1931
+ var testimonialSentimentSchema = z5.enum(["positive", "neutral", "negative"]);
1932
+ var testimonialDocSchema = z5.object({
1933
+ _id: z5.string(),
1934
+ _creationTime: z5.number(),
1935
+ companyId: z5.string(),
1936
+ sourceId: z5.string(),
2028
1937
  sourceType: testimonialSourceTypeSchema,
2029
- reviewText: z6.string(),
2030
- reviewTitle: z6.string().optional(),
2031
- searchText: z6.string().optional(),
2032
- reviewerName: z6.string().optional(),
2033
- reviewerImageUrl: z6.string().optional(),
2034
- reviewerImageId: z6.string().optional(),
2035
- reviewerLocation: z6.string().optional(),
2036
- rating: z6.number().optional(),
2037
- reviewDate: z6.number().optional(),
2038
- ownerAnswer: z6.string().optional(),
2039
- mediaUrls: z6.array(z6.string()).optional(),
2040
- imageIds: z6.array(z6.string()).optional(),
2041
- videoIds: z6.array(z6.string()).optional(),
2042
- sourceUrl: z6.string().optional(),
2043
- rawData: z6.unknown().optional(),
2044
- tags: z6.array(z6.string()),
2045
- highlight: z6.string().optional(),
2046
- language: z6.string().optional(),
2047
- summary: z6.string().optional(),
1938
+ reviewText: z5.string(),
1939
+ reviewTitle: z5.string().optional(),
1940
+ searchText: z5.string().optional(),
1941
+ reviewerName: z5.string().optional(),
1942
+ reviewerImageUrl: z5.string().optional(),
1943
+ reviewerImageId: z5.string().optional(),
1944
+ reviewerLocation: z5.string().optional(),
1945
+ rating: z5.number().optional(),
1946
+ reviewDate: z5.number().optional(),
1947
+ ownerAnswer: z5.string().optional(),
1948
+ mediaUrls: z5.array(z5.string()).optional(),
1949
+ imageIds: z5.array(z5.string()).optional(),
1950
+ videoIds: z5.array(z5.string()).optional(),
1951
+ sourceUrl: z5.string().optional(),
1952
+ rawData: z5.unknown().optional(),
1953
+ tags: z5.array(z5.string()),
1954
+ highlight: z5.string().optional(),
1955
+ language: z5.string().optional(),
1956
+ summary: z5.string().optional(),
2048
1957
  sentiment: testimonialSentimentSchema.optional(),
2049
- textEmbedding: z6.array(z6.number()).optional(),
2050
- externalId: z6.string().optional(),
2051
- contentHash: z6.string().optional(),
1958
+ textEmbedding: z5.array(z5.number()).optional(),
1959
+ externalId: z5.string().optional(),
1960
+ contentHash: z5.string().optional(),
2052
1961
  status: testimonialStatusSchema,
2053
- errorMessage: z6.string().optional(),
2054
- createdAt: z6.number(),
2055
- updatedAt: z6.number()
1962
+ errorMessage: z5.string().optional(),
1963
+ createdAt: z5.number(),
1964
+ updatedAt: z5.number()
2056
1965
  });
2057
- var testimonialsListRequestSchema = z6.object({
1966
+ var testimonialsListRequestSchema = z5.object({
2058
1967
  source: testimonialSourceTypeSchema.optional(),
2059
- rating_min: z6.coerce.number().int().min(1).max(5).optional(),
2060
- rating_max: z6.coerce.number().int().min(1).max(5).optional(),
2061
- tags: z6.string().transform((s) => s.split(",").filter(Boolean)).optional(),
1968
+ rating_min: z5.coerce.number().int().min(1).max(5).optional(),
1969
+ rating_max: z5.coerce.number().int().min(1).max(5).optional(),
1970
+ tags: z5.string().transform((s) => s.split(",").filter(Boolean)).optional(),
2062
1971
  status: testimonialStatusSchema.optional(),
2063
1972
  sentiment: testimonialSentimentSchema.optional(),
2064
- language: z6.string().min(2).max(5).optional(),
2065
- limit: z6.coerce.number().int().positive().max(200).optional()
2066
- });
2067
- var testimonialsListResponseSchema = z6.array(testimonialDocSchema);
2068
- var testimonialsGetRequestSchema = z6.object({ id: z6.string().min(1, "Missing id parameter") });
2069
- var testimonialsSearchRequestSchema = z6.object({
2070
- query: z6.string().min(1),
2071
- limit: z6.coerce.number().int().positive().max(100).optional(),
1973
+ language: z5.string().min(2).max(5).optional(),
1974
+ limit: z5.coerce.number().int().positive().max(200).optional()
1975
+ });
1976
+ var testimonialsListResponseSchema = z5.array(testimonialDocSchema);
1977
+ var testimonialsGetRequestSchema = z5.object({ id: z5.string().min(1, "Missing id parameter") });
1978
+ var testimonialsSearchRequestSchema = z5.object({
1979
+ query: z5.string().min(1),
1980
+ limit: z5.coerce.number().int().positive().max(100).optional(),
2072
1981
  source: testimonialSourceTypeSchema.optional(),
2073
- rating_min: z6.coerce.number().int().min(1).max(5).optional(),
2074
- rating_max: z6.coerce.number().int().min(1).max(5).optional(),
2075
- tags: z6.array(z6.string()).optional(),
1982
+ rating_min: z5.coerce.number().int().min(1).max(5).optional(),
1983
+ rating_max: z5.coerce.number().int().min(1).max(5).optional(),
1984
+ tags: z5.array(z5.string()).optional(),
2076
1985
  status: testimonialStatusSchema.optional(),
2077
1986
  sentiment: testimonialSentimentSchema.optional(),
2078
- language: z6.string().min(2).max(5).optional()
1987
+ language: z5.string().min(2).max(5).optional()
2079
1988
  }).refine(
2080
1989
  (data) => data.rating_min === void 0 || data.rating_max === void 0 || data.rating_min <= data.rating_max,
2081
1990
  { message: "rating_min must be less than or equal to rating_max" }
2082
1991
  );
2083
- var testimonialsSearchResponseSchema = z6.array(testimonialDocSchema);
2084
- var testimonialsOutscraperWebhookResponseSchema = z6.object({
2085
- ok: z6.literal(true),
2086
- note: z6.string().optional()
1992
+ var testimonialsSearchResponseSchema = z5.array(testimonialDocSchema);
1993
+ var testimonialsOutscraperWebhookResponseSchema = z5.object({
1994
+ ok: z5.literal(true),
1995
+ note: z5.string().optional()
2087
1996
  });
2088
1997
 
2089
1998
  // ../api/src/videos.ts
2090
- import { z as z7 } from "zod";
2091
- var videoStatusSchema = z7.enum(["uploading", "uploaded", "processing", "ready", "error"]);
2092
- var videoTranscriptSegmentSchema = z7.object({
2093
- text: z7.string(),
2094
- startSecond: z7.number(),
2095
- endSecond: z7.number()
2096
- });
2097
- var videoSceneSchema = z7.object({
2098
- title: z7.string(),
2099
- description: z7.string(),
2100
- startSecond: z7.number(),
2101
- endSecond: z7.number(),
2102
- thumbnailTime: z7.number()
2103
- });
2104
- var videoDocSchema = z7.object({
2105
- _id: z7.string(),
2106
- _creationTime: z7.number(),
2107
- companyId: z7.string(),
2108
- muxAssetId: z7.string(),
2109
- muxPlaybackId: z7.string(),
2110
- muxUploadId: z7.string(),
2111
- name: z7.string(),
2112
- description: z7.string(),
2113
- tags: z7.array(z7.string()),
2114
- source: z7.string(),
2115
- externalId: z7.string().optional(),
2116
- sourceId: z7.string().optional(),
2117
- width: z7.number().optional(),
2118
- height: z7.number().optional(),
2119
- aspectRatio: z7.number().optional(),
2120
- duration: z7.number().optional(),
2121
- transcript: z7.string().optional(),
2122
- transcriptSegments: z7.array(videoTranscriptSegmentSchema).optional(),
2123
- scenes: z7.array(videoSceneSchema).optional(),
2124
- descriptionEmbedding: z7.array(z7.number()).optional(),
2125
- searchText: z7.string().optional(),
1999
+ import { z as z6 } from "zod";
2000
+ var videoStatusSchema = z6.enum(["uploading", "uploaded", "processing", "ready", "error"]);
2001
+ var videoTranscriptSegmentSchema = z6.object({
2002
+ text: z6.string(),
2003
+ startSecond: z6.number(),
2004
+ endSecond: z6.number()
2005
+ });
2006
+ var videoSceneSchema = z6.object({
2007
+ title: z6.string(),
2008
+ description: z6.string(),
2009
+ startSecond: z6.number(),
2010
+ endSecond: z6.number(),
2011
+ thumbnailTime: z6.number()
2012
+ });
2013
+ var videoDocSchema = z6.object({
2014
+ _id: z6.string(),
2015
+ _creationTime: z6.number(),
2016
+ companyId: z6.string(),
2017
+ muxAssetId: z6.string(),
2018
+ muxPlaybackId: z6.string(),
2019
+ muxUploadId: z6.string(),
2020
+ name: z6.string(),
2021
+ description: z6.string(),
2022
+ tags: z6.array(z6.string()),
2023
+ source: z6.string(),
2024
+ externalId: z6.string().optional(),
2025
+ sourceId: z6.string().optional(),
2026
+ width: z6.number().optional(),
2027
+ height: z6.number().optional(),
2028
+ aspectRatio: z6.number().optional(),
2029
+ duration: z6.number().optional(),
2030
+ transcript: z6.string().optional(),
2031
+ transcriptSegments: z6.array(videoTranscriptSegmentSchema).optional(),
2032
+ scenes: z6.array(videoSceneSchema).optional(),
2033
+ descriptionEmbedding: z6.array(z6.number()).optional(),
2034
+ searchText: z6.string().optional(),
2126
2035
  status: videoStatusSchema,
2127
- errorMessage: z7.string().optional(),
2128
- createdAt: z7.number(),
2129
- updatedAt: z7.number(),
2130
- thumbnailUrl: z7.string()
2131
- });
2132
- var videosWebhookResponseSchema = z7.object({ ok: z7.literal(true) });
2133
- var videosGetRequestSchema = z7.object({ id: z7.string().min(1, "Missing id parameter") });
2134
- var videosSearchRequestSchema = z7.object({
2135
- query: z7.string().min(1),
2136
- limit: z7.coerce.number().int().positive().max(100).optional(),
2137
- tags: z7.array(z7.string()).optional()
2138
- });
2139
- var videoSearchResultSchema = z7.object({
2140
- _id: z7.string(),
2141
- thumbnailUrl: z7.string(),
2142
- name: z7.string(),
2143
- description: z7.string(),
2144
- tags: z7.array(z7.string()),
2145
- status: z7.string(),
2146
- duration: z7.number().optional(),
2147
- muxPlaybackId: z7.string(),
2148
- createdAt: z7.number()
2149
- });
2150
- var videosSearchResponseSchema = z7.array(videoSearchResultSchema);
2151
- var videosUploadResponseSchema = z7.object({ uploadUrl: z7.string(), videoId: z7.string() });
2152
- var videosDeleteRequestSchema = z7.object({ id: z7.string().min(1, "Missing video ID") });
2153
- var videosDeleteResponseSchema = z7.object({ ok: z7.literal(true) });
2036
+ errorMessage: z6.string().optional(),
2037
+ createdAt: z6.number(),
2038
+ updatedAt: z6.number(),
2039
+ thumbnailUrl: z6.string()
2040
+ });
2041
+ var videosWebhookResponseSchema = z6.object({ ok: z6.literal(true) });
2042
+ var videosGetRequestSchema = z6.object({ id: z6.string().min(1, "Missing id parameter") });
2043
+ var videosSearchRequestSchema = z6.object({
2044
+ query: z6.string().min(1),
2045
+ limit: z6.coerce.number().int().positive().max(100).optional(),
2046
+ tags: z6.array(z6.string()).optional()
2047
+ });
2048
+ var videoSearchResultSchema = z6.object({
2049
+ _id: z6.string(),
2050
+ thumbnailUrl: z6.string(),
2051
+ name: z6.string(),
2052
+ description: z6.string(),
2053
+ tags: z6.array(z6.string()),
2054
+ status: z6.string(),
2055
+ duration: z6.number().optional(),
2056
+ muxPlaybackId: z6.string(),
2057
+ createdAt: z6.number()
2058
+ });
2059
+ var videosSearchResponseSchema = z6.array(videoSearchResultSchema);
2060
+ var videosUploadResponseSchema = z6.object({ uploadUrl: z6.string(), videoId: z6.string() });
2061
+ var videosDeleteRequestSchema = z6.object({ id: z6.string().min(1, "Missing video ID") });
2062
+ var videosDeleteResponseSchema = z6.object({ ok: z6.literal(true) });
2154
2063
 
2155
2064
  // src/commands/actions/complete.ts
2156
2065
  import { defineCommand as defineCommand2 } from "citty";
@@ -3963,37 +3872,37 @@ var GEO_TARGET_CONSTANT_REGEX = /^geoTargetConstants\/\d+$/;
3963
3872
  var LANGUAGE_CONSTANT_REGEX = /^languageConstants\/\d+$/;
3964
3873
 
3965
3874
  // ../api/src/ads-google/ops.ts
3966
- import { z as z8 } from "zod";
3967
- var tempRefSchema2 = z8.string().regex(TEMP_REF_REGEX2, "expected a g_temp_* reference");
3968
- var refSchema = z8.union([
3969
- z8.string().regex(RESOURCE_NAME_REGEX, "expected a customers/\u2026/\u2026/\u2026 resource name"),
3970
- z8.string().regex(NUMERIC_ID_REGEX2, "expected a numeric id"),
3875
+ import { z as z7 } from "zod";
3876
+ var tempRefSchema2 = z7.string().regex(TEMP_REF_REGEX2, "expected a g_temp_* reference");
3877
+ var refSchema = z7.union([
3878
+ z7.string().regex(RESOURCE_NAME_REGEX, "expected a customers/\u2026/\u2026/\u2026 resource name"),
3879
+ z7.string().regex(NUMERIC_ID_REGEX2, "expected a numeric id"),
3971
3880
  tempRefSchema2
3972
3881
  ]);
3973
3882
  var targetRefSchema = refSchema;
3974
- var microsSchema = z8.number().int().positive("expected a positive micros amount");
3975
- var httpsUrlSchema2 = z8.string().url().refine((u) => u.startsWith("https://"), "final URLs must be https");
3976
- var customerIdSchema = z8.string().regex(NUMERIC_ID_REGEX2, "customerId must be the bare numeric customer id");
3977
- var stageableStatusSchema2 = z8.enum(STAGEABLE_CREATE_STATUSES2);
3978
- var matchTypeSchema = z8.enum(KEYWORD_MATCH_TYPES);
3979
- var keywordTextSchema = z8.string().min(1).max(GOOGLE_ADS_LIMITS.keyword.textMax).refine((t) => t.trim().split(/\s+/).length <= GOOGLE_ADS_LIMITS.keyword.wordsMax, "keyword exceeds 10 words");
3980
- var budgetCreateSchema = z8.object({
3981
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.budget.nameMax),
3883
+ var microsSchema = z7.number().int().positive("expected a positive micros amount");
3884
+ var httpsUrlSchema2 = z7.string().url().refine((u) => u.startsWith("https://"), "final URLs must be https");
3885
+ var customerIdSchema = z7.string().regex(NUMERIC_ID_REGEX2, "customerId must be the bare numeric customer id");
3886
+ var stageableStatusSchema2 = z7.enum(STAGEABLE_CREATE_STATUSES2);
3887
+ var matchTypeSchema = z7.enum(KEYWORD_MATCH_TYPES);
3888
+ var keywordTextSchema = z7.string().min(1).max(GOOGLE_ADS_LIMITS.keyword.textMax).refine((t) => t.trim().split(/\s+/).length <= GOOGLE_ADS_LIMITS.keyword.wordsMax, "keyword exceeds 10 words");
3889
+ var budgetCreateSchema = z7.object({
3890
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.budget.nameMax),
3982
3891
  amountMicros: microsSchema,
3983
- deliveryMethod: z8.enum(BUDGET_DELIVERY_METHODS).default("STANDARD"),
3984
- explicitlyShared: z8.boolean().default(false)
3892
+ deliveryMethod: z7.enum(BUDGET_DELIVERY_METHODS).default("STANDARD"),
3893
+ explicitlyShared: z7.boolean().default(false)
3985
3894
  });
3986
- var budgetUpdateSchema = z8.object({
3987
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.budget.nameMax).optional(),
3895
+ var budgetUpdateSchema = z7.object({
3896
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.budget.nameMax).optional(),
3988
3897
  amountMicros: microsSchema.optional(),
3989
- deliveryMethod: z8.enum(BUDGET_DELIVERY_METHODS).optional()
3898
+ deliveryMethod: z7.enum(BUDGET_DELIVERY_METHODS).optional()
3990
3899
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
3991
- var biddingConfigSchema = z8.object({
3992
- type: z8.enum(BIDDING_STRATEGY_TYPES),
3900
+ var biddingConfigSchema = z7.object({
3901
+ type: z7.enum(BIDDING_STRATEGY_TYPES),
3993
3902
  targetCpaMicros: microsSchema.optional(),
3994
- targetRoas: z8.number().positive().optional(),
3903
+ targetRoas: z7.number().positive().optional(),
3995
3904
  cpcBidCeilingMicros: microsSchema.optional(),
3996
- enhancedCpcEnabled: z8.boolean().optional()
3905
+ enhancedCpcEnabled: z7.boolean().optional()
3997
3906
  }).superRefine((p, ctx) => {
3998
3907
  if (p.type === "TARGET_CPA" && p.targetCpaMicros === void 0) {
3999
3908
  ctx.addIssue({ code: "custom", path: ["targetCpaMicros"], message: "TARGET_CPA needs targetCpaMicros" });
@@ -4002,17 +3911,17 @@ var biddingConfigSchema = z8.object({
4002
3911
  ctx.addIssue({ code: "custom", path: ["targetRoas"], message: "TARGET_ROAS needs targetRoas" });
4003
3912
  }
4004
3913
  });
4005
- var networkSettingsSchema = z8.object({
4006
- targetGoogleSearch: z8.boolean().optional(),
4007
- targetSearchNetwork: z8.boolean().optional(),
4008
- targetContentNetwork: z8.boolean().optional(),
4009
- targetPartnerSearchNetwork: z8.boolean().optional()
3914
+ var networkSettingsSchema = z7.object({
3915
+ targetGoogleSearch: z7.boolean().optional(),
3916
+ targetSearchNetwork: z7.boolean().optional(),
3917
+ targetContentNetwork: z7.boolean().optional(),
3918
+ targetPartnerSearchNetwork: z7.boolean().optional()
4010
3919
  });
4011
- var dateSchema = z8.string().regex(/^\d{4}-\d{2}-\d{2}$/, "expected a YYYY-MM-DD date");
4012
- var campaignCreateSchema2 = z8.object({
4013
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.campaign.nameMax),
4014
- channelType: z8.enum(ADVERTISING_CHANNEL_TYPES),
4015
- channelSubType: z8.enum(ADVERTISING_CHANNEL_SUB_TYPES).optional(),
3920
+ var dateSchema = z7.string().regex(/^\d{4}-\d{2}-\d{2}$/, "expected a YYYY-MM-DD date");
3921
+ var campaignCreateSchema2 = z7.object({
3922
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.campaign.nameMax),
3923
+ channelType: z7.enum(ADVERTISING_CHANNEL_TYPES),
3924
+ channelSubType: z7.enum(ADVERTISING_CHANNEL_SUB_TYPES).optional(),
4016
3925
  budget: refSchema,
4017
3926
  /** Inline standard bidding, or a portfolio strategy ref via biddingStrategy. */
4018
3927
  bidding: biddingConfigSchema.optional(),
@@ -4021,7 +3930,7 @@ var campaignCreateSchema2 = z8.object({
4021
3930
  startDate: dateSchema.optional(),
4022
3931
  endDate: dateSchema.optional(),
4023
3932
  /** Advisory Google Ads UI objective — drives warnings, not sent to the API. */
4024
- objective: z8.enum(CAMPAIGN_OBJECTIVES).optional(),
3933
+ objective: z7.enum(CAMPAIGN_OBJECTIVES).optional(),
4025
3934
  status: stageableStatusSchema2.default("PAUSED")
4026
3935
  }).superRefine((p, ctx) => {
4027
3936
  if (!p.bidding && !p.biddingStrategy) {
@@ -4045,129 +3954,129 @@ var campaignCreateSchema2 = z8.object({
4045
3954
  ctx.addIssue({ code: "custom", path: ["endDate"], message: "endDate must be after startDate" });
4046
3955
  }
4047
3956
  });
4048
- var campaignUpdateSchema2 = z8.object({
4049
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.campaign.nameMax).optional(),
3957
+ var campaignUpdateSchema2 = z7.object({
3958
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.campaign.nameMax).optional(),
4050
3959
  budget: refSchema.optional(),
4051
3960
  bidding: biddingConfigSchema.optional(),
4052
3961
  networkSettings: networkSettingsSchema.optional(),
4053
3962
  startDate: dateSchema.optional(),
4054
3963
  endDate: dateSchema.optional(),
4055
- status: z8.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
3964
+ status: z7.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
4056
3965
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
4057
- var adGroupCreateSchema = z8.object({
4058
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.adGroup.nameMax),
3966
+ var adGroupCreateSchema = z7.object({
3967
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.adGroup.nameMax),
4059
3968
  campaign: refSchema,
4060
- type: z8.enum(AD_GROUP_TYPES).default("SEARCH_STANDARD"),
3969
+ type: z7.enum(AD_GROUP_TYPES).default("SEARCH_STANDARD"),
4061
3970
  cpcBidMicros: microsSchema.optional(),
4062
3971
  status: stageableStatusSchema2.default("PAUSED")
4063
3972
  });
4064
- var adGroupUpdateSchema = z8.object({
4065
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.adGroup.nameMax).optional(),
3973
+ var adGroupUpdateSchema = z7.object({
3974
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.adGroup.nameMax).optional(),
4066
3975
  cpcBidMicros: microsSchema.optional(),
4067
- status: z8.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
3976
+ status: z7.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
4068
3977
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
4069
- var keywordAddSchema = z8.object({
3978
+ var keywordAddSchema = z7.object({
4070
3979
  adGroup: refSchema,
4071
3980
  text: keywordTextSchema,
4072
3981
  matchType: matchTypeSchema,
4073
3982
  cpcBidMicros: microsSchema.optional(),
4074
- finalUrls: z8.array(httpsUrlSchema2).optional(),
3983
+ finalUrls: z7.array(httpsUrlSchema2).optional(),
4075
3984
  status: stageableStatusSchema2.default("ENABLED")
4076
3985
  });
4077
- var keywordUpdateSchema = z8.object({
3986
+ var keywordUpdateSchema = z7.object({
4078
3987
  cpcBidMicros: microsSchema.optional(),
4079
- finalUrls: z8.array(httpsUrlSchema2).optional(),
4080
- status: z8.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
3988
+ finalUrls: z7.array(httpsUrlSchema2).optional(),
3989
+ status: z7.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
4081
3990
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
4082
- var negativeKeywordAddSchema = z8.object({
4083
- level: z8.enum(["adGroup", "campaign"]),
3991
+ var negativeKeywordAddSchema = z7.object({
3992
+ level: z7.enum(["adGroup", "campaign"]),
4084
3993
  parent: refSchema,
4085
3994
  text: keywordTextSchema,
4086
3995
  matchType: matchTypeSchema
4087
3996
  });
4088
- var sharedSetCreateSchema = z8.object({
4089
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.sharedSet.nameMax),
4090
- type: z8.enum(SHARED_SET_TYPES).default("NEGATIVE_KEYWORDS")
3997
+ var sharedSetCreateSchema = z7.object({
3998
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.sharedSet.nameMax),
3999
+ type: z7.enum(SHARED_SET_TYPES).default("NEGATIVE_KEYWORDS")
4091
4000
  });
4092
- var sharedSetMemberAddSchema = z8.object({
4001
+ var sharedSetMemberAddSchema = z7.object({
4093
4002
  sharedSet: refSchema,
4094
4003
  text: keywordTextSchema,
4095
4004
  matchType: matchTypeSchema
4096
4005
  });
4097
- var campaignSharedSetAttachSchema = z8.object({
4006
+ var campaignSharedSetAttachSchema = z7.object({
4098
4007
  campaign: refSchema,
4099
4008
  sharedSet: refSchema
4100
4009
  });
4101
- var adTextAssetSchema = z8.object({
4102
- text: z8.string().min(1),
4103
- pinnedField: z8.enum(PINNED_FIELDS).optional()
4010
+ var adTextAssetSchema = z7.object({
4011
+ text: z7.string().min(1),
4012
+ pinnedField: z7.enum(PINNED_FIELDS).optional()
4104
4013
  });
4105
- var responsiveSearchAdSchema = z8.object({
4106
- format: z8.literal("responsiveSearch"),
4107
- headlines: z8.array(
4014
+ var responsiveSearchAdSchema = z7.object({
4015
+ format: z7.literal("responsiveSearch"),
4016
+ headlines: z7.array(
4108
4017
  adTextAssetSchema.refine(
4109
4018
  (a) => a.text.length <= GOOGLE_ADS_LIMITS.responsiveSearchAd.headlineTextMax,
4110
4019
  "headline exceeds 30 chars"
4111
4020
  )
4112
4021
  ).min(GOOGLE_ADS_LIMITS.responsiveSearchAd.headlinesMin).max(GOOGLE_ADS_LIMITS.responsiveSearchAd.headlinesMax),
4113
- descriptions: z8.array(
4022
+ descriptions: z7.array(
4114
4023
  adTextAssetSchema.refine(
4115
4024
  (a) => a.text.length <= GOOGLE_ADS_LIMITS.responsiveSearchAd.descriptionTextMax,
4116
4025
  "description exceeds 90 chars"
4117
4026
  )
4118
4027
  ).min(GOOGLE_ADS_LIMITS.responsiveSearchAd.descriptionsMin).max(GOOGLE_ADS_LIMITS.responsiveSearchAd.descriptionsMax),
4119
- path1: z8.string().max(GOOGLE_ADS_LIMITS.responsiveSearchAd.pathMax).optional(),
4120
- path2: z8.string().max(GOOGLE_ADS_LIMITS.responsiveSearchAd.pathMax).optional(),
4121
- finalUrls: z8.array(httpsUrlSchema2).min(1)
4122
- });
4123
- var responsiveDisplayAdSchema = z8.object({
4124
- format: z8.literal("responsiveDisplay"),
4125
- headlines: z8.array(z8.object({ text: z8.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.headlineTextMax) })).min(1).max(5),
4126
- longHeadline: z8.object({ text: z8.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.longHeadlineTextMax) }),
4127
- descriptions: z8.array(z8.object({ text: z8.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.descriptionTextMax) })).min(1).max(5),
4128
- businessName: z8.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.businessNameMax),
4028
+ path1: z7.string().max(GOOGLE_ADS_LIMITS.responsiveSearchAd.pathMax).optional(),
4029
+ path2: z7.string().max(GOOGLE_ADS_LIMITS.responsiveSearchAd.pathMax).optional(),
4030
+ finalUrls: z7.array(httpsUrlSchema2).min(1)
4031
+ });
4032
+ var responsiveDisplayAdSchema = z7.object({
4033
+ format: z7.literal("responsiveDisplay"),
4034
+ headlines: z7.array(z7.object({ text: z7.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.headlineTextMax) })).min(1).max(5),
4035
+ longHeadline: z7.object({ text: z7.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.longHeadlineTextMax) }),
4036
+ descriptions: z7.array(z7.object({ text: z7.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.descriptionTextMax) })).min(1).max(5),
4037
+ businessName: z7.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.businessNameMax),
4129
4038
  // A Responsive Display Ad's images are fields on the ad's own content (never campaign-level
4130
4039
  // asset links). Google requires ≥1 landscape marketing image (1.91:1) AND ≥1 square marketing
4131
4040
  // image (1:1) to serve; the logo images are optional.
4132
- marketingImageAssets: z8.array(refSchema).optional(),
4133
- squareMarketingImageAssets: z8.array(refSchema).optional(),
4134
- logoImageAssets: z8.array(refSchema).optional(),
4135
- finalUrls: z8.array(httpsUrlSchema2).min(1)
4136
- });
4137
- var callAdSchema = z8.object({
4138
- format: z8.literal("call"),
4139
- countryCode: z8.string().length(2),
4140
- phoneNumber: z8.string().min(3),
4141
- headline1: z8.string().min(1).max(30),
4142
- headline2: z8.string().min(1).max(30),
4143
- description1: z8.string().min(1).max(90),
4144
- description2: z8.string().min(1).max(90),
4145
- businessName: z8.string().min(1).max(25),
4146
- finalUrls: z8.array(httpsUrlSchema2).min(1)
4147
- });
4148
- var appAdSchema = z8.object({
4149
- format: z8.literal("app"),
4150
- headlines: z8.array(z8.object({ text: z8.string().min(1).max(30) })).min(1),
4151
- descriptions: z8.array(z8.object({ text: z8.string().min(1).max(90) })).min(1)
4152
- });
4153
- var videoAdSchema = z8.object({
4154
- format: z8.literal("video"),
4041
+ marketingImageAssets: z7.array(refSchema).optional(),
4042
+ squareMarketingImageAssets: z7.array(refSchema).optional(),
4043
+ logoImageAssets: z7.array(refSchema).optional(),
4044
+ finalUrls: z7.array(httpsUrlSchema2).min(1)
4045
+ });
4046
+ var callAdSchema = z7.object({
4047
+ format: z7.literal("call"),
4048
+ countryCode: z7.string().length(2),
4049
+ phoneNumber: z7.string().min(3),
4050
+ headline1: z7.string().min(1).max(30),
4051
+ headline2: z7.string().min(1).max(30),
4052
+ description1: z7.string().min(1).max(90),
4053
+ description2: z7.string().min(1).max(90),
4054
+ businessName: z7.string().min(1).max(25),
4055
+ finalUrls: z7.array(httpsUrlSchema2).min(1)
4056
+ });
4057
+ var appAdSchema = z7.object({
4058
+ format: z7.literal("app"),
4059
+ headlines: z7.array(z7.object({ text: z7.string().min(1).max(30) })).min(1),
4060
+ descriptions: z7.array(z7.object({ text: z7.string().min(1).max(90) })).min(1)
4061
+ });
4062
+ var videoAdSchema = z7.object({
4063
+ format: z7.literal("video"),
4155
4064
  // A raw YouTube id is not a publishable Google Ads reference — the video must be staged as
4156
4065
  // its own `google.asset.create` (type: youtubeVideo) first, then referenced here by asset ref.
4157
- videoAssets: z8.array(refSchema).min(1),
4158
- finalUrls: z8.array(httpsUrlSchema2).min(1)
4159
- });
4160
- var demandGenAdSchema = z8.object({
4161
- format: z8.literal("demandGen"),
4162
- headlines: z8.array(z8.object({ text: z8.string().min(1).max(40) })).min(1).max(5),
4163
- descriptions: z8.array(z8.object({ text: z8.string().min(1).max(90) })).min(1).max(5),
4164
- businessName: z8.string().min(1).max(25),
4165
- finalUrls: z8.array(httpsUrlSchema2).min(1),
4166
- imageAssets: z8.array(refSchema).optional(),
4167
- squareImageAssets: z8.array(refSchema).optional(),
4168
- logoImageAssets: z8.array(refSchema).optional()
4169
- });
4170
- var adContentSchema = z8.discriminatedUnion("format", [
4066
+ videoAssets: z7.array(refSchema).min(1),
4067
+ finalUrls: z7.array(httpsUrlSchema2).min(1)
4068
+ });
4069
+ var demandGenAdSchema = z7.object({
4070
+ format: z7.literal("demandGen"),
4071
+ headlines: z7.array(z7.object({ text: z7.string().min(1).max(40) })).min(1).max(5),
4072
+ descriptions: z7.array(z7.object({ text: z7.string().min(1).max(90) })).min(1).max(5),
4073
+ businessName: z7.string().min(1).max(25),
4074
+ finalUrls: z7.array(httpsUrlSchema2).min(1),
4075
+ imageAssets: z7.array(refSchema).optional(),
4076
+ squareImageAssets: z7.array(refSchema).optional(),
4077
+ logoImageAssets: z7.array(refSchema).optional()
4078
+ });
4079
+ var adContentSchema = z7.discriminatedUnion("format", [
4171
4080
  responsiveSearchAdSchema,
4172
4081
  responsiveDisplayAdSchema,
4173
4082
  callAdSchema,
@@ -4175,45 +4084,45 @@ var adContentSchema = z8.discriminatedUnion("format", [
4175
4084
  videoAdSchema,
4176
4085
  demandGenAdSchema
4177
4086
  ]);
4178
- var adCreateSchema = z8.object({
4087
+ var adCreateSchema = z7.object({
4179
4088
  adGroup: refSchema,
4180
4089
  status: stageableStatusSchema2.default("PAUSED"),
4181
4090
  content: adContentSchema
4182
4091
  });
4183
- var adUpdateSchema = z8.object({
4184
- status: z8.enum(["ENABLED", "PAUSED", "REMOVED"]).optional(),
4092
+ var adUpdateSchema = z7.object({
4093
+ status: z7.enum(["ENABLED", "PAUSED", "REMOVED"]).optional(),
4185
4094
  /** Whole-content replacement for RSA-like formats; re-validated against adContentSchema. */
4186
- content: z8.record(z8.string(), z8.unknown()).optional()
4095
+ content: z7.record(z7.string(), z7.unknown()).optional()
4187
4096
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
4188
- var textAssetSchema = z8.object({ type: z8.literal("text"), text: z8.string().min(1) });
4189
- var imageAssetSchema = z8.object({
4190
- type: z8.literal("image"),
4191
- imageId: z8.string().min(1),
4192
- name: z8.string().optional()
4193
- });
4194
- var youtubeVideoAssetSchema = z8.object({
4195
- type: z8.literal("youtubeVideo"),
4196
- youtubeVideoId: z8.string().min(1),
4197
- name: z8.string().optional()
4198
- });
4199
- var sitelinkAssetSchema = z8.object({
4200
- type: z8.literal("sitelink"),
4201
- linkText: z8.string().min(1).max(GOOGLE_ADS_LIMITS.asset.sitelinkLinkTextMax),
4202
- description1: z8.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
4203
- description2: z8.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
4204
- finalUrls: z8.array(httpsUrlSchema2).min(1)
4205
- });
4206
- var calloutAssetSchema = z8.object({
4207
- type: z8.literal("callout"),
4208
- calloutText: z8.string().min(1).max(GOOGLE_ADS_LIMITS.asset.calloutTextMax)
4209
- });
4210
- var structuredSnippetAssetSchema = z8.object({
4211
- type: z8.literal("structuredSnippet"),
4212
- header: z8.string().min(1).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetHeaderMax),
4213
- values: z8.array(z8.string().min(1)).min(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMin).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMax)
4214
- });
4215
- var callToActionAssetSchema = z8.object({ type: z8.literal("callToAction"), callToAction: z8.string().min(1) });
4216
- var assetCreateSchema = z8.discriminatedUnion("type", [
4097
+ var textAssetSchema = z7.object({ type: z7.literal("text"), text: z7.string().min(1) });
4098
+ var imageAssetSchema = z7.object({
4099
+ type: z7.literal("image"),
4100
+ imageId: z7.string().min(1),
4101
+ name: z7.string().optional()
4102
+ });
4103
+ var youtubeVideoAssetSchema = z7.object({
4104
+ type: z7.literal("youtubeVideo"),
4105
+ youtubeVideoId: z7.string().min(1),
4106
+ name: z7.string().optional()
4107
+ });
4108
+ var sitelinkAssetSchema = z7.object({
4109
+ type: z7.literal("sitelink"),
4110
+ linkText: z7.string().min(1).max(GOOGLE_ADS_LIMITS.asset.sitelinkLinkTextMax),
4111
+ description1: z7.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
4112
+ description2: z7.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
4113
+ finalUrls: z7.array(httpsUrlSchema2).min(1)
4114
+ });
4115
+ var calloutAssetSchema = z7.object({
4116
+ type: z7.literal("callout"),
4117
+ calloutText: z7.string().min(1).max(GOOGLE_ADS_LIMITS.asset.calloutTextMax)
4118
+ });
4119
+ var structuredSnippetAssetSchema = z7.object({
4120
+ type: z7.literal("structuredSnippet"),
4121
+ header: z7.string().min(1).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetHeaderMax),
4122
+ values: z7.array(z7.string().min(1)).min(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMin).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMax)
4123
+ });
4124
+ var callToActionAssetSchema = z7.object({ type: z7.literal("callToAction"), callToAction: z7.string().min(1) });
4125
+ var assetCreateSchema = z7.discriminatedUnion("type", [
4217
4126
  textAssetSchema,
4218
4127
  imageAssetSchema,
4219
4128
  youtubeVideoAssetSchema,
@@ -4222,136 +4131,136 @@ var assetCreateSchema = z8.discriminatedUnion("type", [
4222
4131
  structuredSnippetAssetSchema,
4223
4132
  callToActionAssetSchema
4224
4133
  ]);
4225
- var assetUpdateSchema = z8.object({
4226
- name: z8.string().min(1).optional(),
4227
- linkText: z8.string().min(1).max(GOOGLE_ADS_LIMITS.asset.sitelinkLinkTextMax).optional(),
4228
- description1: z8.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
4229
- description2: z8.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
4230
- finalUrls: z8.array(httpsUrlSchema2).min(1).optional(),
4231
- calloutText: z8.string().min(1).max(GOOGLE_ADS_LIMITS.asset.calloutTextMax).optional(),
4232
- header: z8.string().min(1).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetHeaderMax).optional(),
4233
- values: z8.array(z8.string().min(1)).min(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMin).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMax).optional(),
4234
- callToAction: z8.string().min(1).optional(),
4235
- text: z8.string().min(1).optional()
4134
+ var assetUpdateSchema = z7.object({
4135
+ name: z7.string().min(1).optional(),
4136
+ linkText: z7.string().min(1).max(GOOGLE_ADS_LIMITS.asset.sitelinkLinkTextMax).optional(),
4137
+ description1: z7.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
4138
+ description2: z7.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
4139
+ finalUrls: z7.array(httpsUrlSchema2).min(1).optional(),
4140
+ calloutText: z7.string().min(1).max(GOOGLE_ADS_LIMITS.asset.calloutTextMax).optional(),
4141
+ header: z7.string().min(1).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetHeaderMax).optional(),
4142
+ values: z7.array(z7.string().min(1)).min(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMin).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMax).optional(),
4143
+ callToAction: z7.string().min(1).optional(),
4144
+ text: z7.string().min(1).optional()
4236
4145
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
4237
- var assetLinkAttachSchema = z8.object({
4238
- level: z8.enum(["campaign", "adGroup", "customer"]),
4146
+ var assetLinkAttachSchema = z7.object({
4147
+ level: z7.enum(["campaign", "adGroup", "customer"]),
4239
4148
  parent: refSchema.optional(),
4240
4149
  asset: refSchema,
4241
- fieldType: z8.enum(ASSET_FIELD_TYPES)
4150
+ fieldType: z7.enum(ASSET_FIELD_TYPES)
4242
4151
  }).superRefine((value, ctx) => {
4243
4152
  if (value.level !== "customer" && !value.parent) {
4244
4153
  ctx.addIssue({
4245
- code: z8.ZodIssueCode.custom,
4154
+ code: z7.ZodIssueCode.custom,
4246
4155
  path: ["parent"],
4247
4156
  message: `parent is required for a ${value.level}-level asset link (--parent-ref)`
4248
4157
  });
4249
4158
  }
4250
4159
  });
4251
- var assetGroupCreateSchema = z8.object({
4160
+ var assetGroupCreateSchema = z7.object({
4252
4161
  campaign: refSchema,
4253
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.nameMax),
4254
- finalUrls: z8.array(httpsUrlSchema2).min(1),
4255
- headlines: z8.array(z8.object({ text: z8.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.headlineTextMax) })).min(GOOGLE_ADS_LIMITS.assetGroup.headlinesMin).max(GOOGLE_ADS_LIMITS.assetGroup.headlinesMax),
4256
- longHeadlines: z8.array(z8.object({ text: z8.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.longHeadlineTextMax) })).min(GOOGLE_ADS_LIMITS.assetGroup.longHeadlinesMin).max(GOOGLE_ADS_LIMITS.assetGroup.longHeadlinesMax),
4257
- descriptions: z8.array(z8.object({ text: z8.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.descriptionTextMax) })).min(GOOGLE_ADS_LIMITS.assetGroup.descriptionsMin).max(GOOGLE_ADS_LIMITS.assetGroup.descriptionsMax),
4258
- businessName: z8.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.businessNameMax),
4259
- imageAssets: z8.array(refSchema).optional(),
4260
- squareImageAssets: z8.array(refSchema).optional(),
4261
- logoAssets: z8.array(refSchema).optional(),
4262
- status: z8.enum(["ENABLED", "PAUSED"]).default("PAUSED")
4263
- });
4264
- var assetGroupUpdateSchema = z8.object({
4265
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.nameMax).optional(),
4266
- finalUrls: z8.array(httpsUrlSchema2).min(1).optional(),
4267
- status: z8.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
4162
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.nameMax),
4163
+ finalUrls: z7.array(httpsUrlSchema2).min(1),
4164
+ headlines: z7.array(z7.object({ text: z7.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.headlineTextMax) })).min(GOOGLE_ADS_LIMITS.assetGroup.headlinesMin).max(GOOGLE_ADS_LIMITS.assetGroup.headlinesMax),
4165
+ longHeadlines: z7.array(z7.object({ text: z7.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.longHeadlineTextMax) })).min(GOOGLE_ADS_LIMITS.assetGroup.longHeadlinesMin).max(GOOGLE_ADS_LIMITS.assetGroup.longHeadlinesMax),
4166
+ descriptions: z7.array(z7.object({ text: z7.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.descriptionTextMax) })).min(GOOGLE_ADS_LIMITS.assetGroup.descriptionsMin).max(GOOGLE_ADS_LIMITS.assetGroup.descriptionsMax),
4167
+ businessName: z7.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.businessNameMax),
4168
+ imageAssets: z7.array(refSchema).optional(),
4169
+ squareImageAssets: z7.array(refSchema).optional(),
4170
+ logoAssets: z7.array(refSchema).optional(),
4171
+ status: z7.enum(["ENABLED", "PAUSED"]).default("PAUSED")
4172
+ });
4173
+ var assetGroupUpdateSchema = z7.object({
4174
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.nameMax).optional(),
4175
+ finalUrls: z7.array(httpsUrlSchema2).min(1).optional(),
4176
+ status: z7.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
4268
4177
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
4269
- var audienceCreateSchema2 = z8.object({
4270
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.audience.nameMax),
4271
- type: z8.enum(USER_LIST_TYPES).default("BASIC"),
4272
- description: z8.string().optional(),
4178
+ var audienceCreateSchema2 = z7.object({
4179
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.audience.nameMax),
4180
+ type: z7.enum(USER_LIST_TYPES).default("BASIC"),
4181
+ description: z7.string().optional(),
4273
4182
  /** Customer-match members (crm-based) — file-first for large lists. */
4274
- members: z8.array(z8.record(z8.string(), z8.string())).optional(),
4275
- sourceFileRef: z8.string().optional()
4183
+ members: z7.array(z7.record(z7.string(), z7.string())).optional(),
4184
+ sourceFileRef: z7.string().optional()
4276
4185
  });
4277
- var audienceCriterionAttachSchema = z8.object({
4278
- level: z8.enum(["campaign", "adGroup"]),
4186
+ var audienceCriterionAttachSchema = z7.object({
4187
+ level: z7.enum(["campaign", "adGroup"]),
4279
4188
  parent: refSchema,
4280
4189
  userList: refSchema,
4281
- negative: z8.boolean().default(false)
4190
+ negative: z7.boolean().default(false)
4282
4191
  });
4283
- var conversionActionCreateSchema = z8.object({
4284
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.conversionAction.nameMax),
4285
- type: z8.enum(CONVERSION_ACTION_TYPES).default("WEBPAGE"),
4286
- category: z8.enum(CONVERSION_ACTION_CATEGORIES).default("DEFAULT"),
4287
- countingType: z8.enum(CONVERSION_COUNTING_TYPES).default("ONE_PER_CLICK"),
4192
+ var conversionActionCreateSchema = z7.object({
4193
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.conversionAction.nameMax),
4194
+ type: z7.enum(CONVERSION_ACTION_TYPES).default("WEBPAGE"),
4195
+ category: z7.enum(CONVERSION_ACTION_CATEGORIES).default("DEFAULT"),
4196
+ countingType: z7.enum(CONVERSION_COUNTING_TYPES).default("ONE_PER_CLICK"),
4288
4197
  defaultValueMicros: microsSchema.optional(),
4289
- defaultCurrencyCode: z8.string().length(3).optional(),
4290
- clickThroughLookbackWindowDays: z8.number().int().positive().optional(),
4291
- viewThroughLookbackWindowDays: z8.number().int().positive().optional(),
4292
- status: z8.enum(["ENABLED", "PAUSED"]).default("ENABLED")
4293
- });
4294
- var conversionActionUpdateSchema = z8.object({
4295
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.conversionAction.nameMax).optional(),
4296
- category: z8.enum(CONVERSION_ACTION_CATEGORIES).optional(),
4297
- countingType: z8.enum(CONVERSION_COUNTING_TYPES).optional(),
4198
+ defaultCurrencyCode: z7.string().length(3).optional(),
4199
+ clickThroughLookbackWindowDays: z7.number().int().positive().optional(),
4200
+ viewThroughLookbackWindowDays: z7.number().int().positive().optional(),
4201
+ status: z7.enum(["ENABLED", "PAUSED"]).default("ENABLED")
4202
+ });
4203
+ var conversionActionUpdateSchema = z7.object({
4204
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.conversionAction.nameMax).optional(),
4205
+ category: z7.enum(CONVERSION_ACTION_CATEGORIES).optional(),
4206
+ countingType: z7.enum(CONVERSION_COUNTING_TYPES).optional(),
4298
4207
  defaultValueMicros: microsSchema.optional(),
4299
- defaultCurrencyCode: z8.string().length(3).optional(),
4300
- clickThroughLookbackWindowDays: z8.number().int().positive().optional(),
4301
- viewThroughLookbackWindowDays: z8.number().int().positive().optional(),
4302
- status: z8.enum(["ENABLED", "REMOVED", "HIDDEN"]).optional()
4208
+ defaultCurrencyCode: z7.string().length(3).optional(),
4209
+ clickThroughLookbackWindowDays: z7.number().int().positive().optional(),
4210
+ viewThroughLookbackWindowDays: z7.number().int().positive().optional(),
4211
+ status: z7.enum(["ENABLED", "REMOVED", "HIDDEN"]).optional()
4303
4212
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
4304
- var biddingStrategyCreateSchema = z8.object({
4305
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.biddingStrategy.nameMax),
4213
+ var biddingStrategyCreateSchema = z7.object({
4214
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.biddingStrategy.nameMax),
4306
4215
  config: biddingConfigSchema
4307
4216
  }).superRefine((p, ctx) => {
4308
4217
  if (p.config.type === "MANUAL_CPC") {
4309
4218
  ctx.addIssue({ code: "custom", path: ["config", "type"], message: "portfolio strategies cannot be Manual CPC" });
4310
4219
  }
4311
4220
  });
4312
- var biddingStrategyUpdateSchema = z8.object({
4313
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.biddingStrategy.nameMax).optional(),
4221
+ var biddingStrategyUpdateSchema = z7.object({
4222
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.biddingStrategy.nameMax).optional(),
4314
4223
  config: biddingConfigSchema.optional()
4315
4224
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
4316
- var labelCreateSchema = z8.object({
4317
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.label.nameMax),
4318
- backgroundColor: z8.string().regex(/^#[0-9A-Fa-f]{6}$/).optional(),
4319
- description: z8.string().optional()
4225
+ var labelCreateSchema = z7.object({
4226
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.label.nameMax),
4227
+ backgroundColor: z7.string().regex(/^#[0-9A-Fa-f]{6}$/).optional(),
4228
+ description: z7.string().optional()
4320
4229
  });
4321
- var labelAttachSchema = z8.object({
4322
- level: z8.enum(["campaign", "adGroup", "ad"]),
4230
+ var labelAttachSchema = z7.object({
4231
+ level: z7.enum(["campaign", "adGroup", "ad"]),
4323
4232
  parent: refSchema,
4324
4233
  label: refSchema
4325
4234
  });
4326
- var locationCriterionSchema = z8.object({
4327
- criterionType: z8.literal("location"),
4328
- geoTargetConstant: z8.union([z8.string().regex(GEO_TARGET_CONSTANT_REGEX), z8.string().regex(NUMERIC_ID_REGEX2)])
4329
- });
4330
- var languageCriterionSchema = z8.object({
4331
- criterionType: z8.literal("language"),
4332
- languageConstant: z8.union([z8.string().regex(LANGUAGE_CONSTANT_REGEX), z8.string().regex(NUMERIC_ID_REGEX2)])
4333
- });
4334
- var adScheduleCriterionSchema = z8.object({
4335
- criterionType: z8.literal("adSchedule"),
4336
- dayOfWeek: z8.enum(DAYS_OF_WEEK),
4337
- startHour: z8.number().int().min(0).max(23),
4338
- startMinute: z8.enum(["ZERO", "FIFTEEN", "THIRTY", "FORTY_FIVE"]).default("ZERO"),
4339
- endHour: z8.number().int().min(0).max(24),
4340
- endMinute: z8.enum(["ZERO", "FIFTEEN", "THIRTY", "FORTY_FIVE"]).default("ZERO")
4341
- });
4342
- var deviceCriterionSchema = z8.object({
4343
- criterionType: z8.literal("device"),
4344
- device: z8.enum(DEVICE_TYPES),
4235
+ var locationCriterionSchema = z7.object({
4236
+ criterionType: z7.literal("location"),
4237
+ geoTargetConstant: z7.union([z7.string().regex(GEO_TARGET_CONSTANT_REGEX), z7.string().regex(NUMERIC_ID_REGEX2)])
4238
+ });
4239
+ var languageCriterionSchema = z7.object({
4240
+ criterionType: z7.literal("language"),
4241
+ languageConstant: z7.union([z7.string().regex(LANGUAGE_CONSTANT_REGEX), z7.string().regex(NUMERIC_ID_REGEX2)])
4242
+ });
4243
+ var adScheduleCriterionSchema = z7.object({
4244
+ criterionType: z7.literal("adSchedule"),
4245
+ dayOfWeek: z7.enum(DAYS_OF_WEEK),
4246
+ startHour: z7.number().int().min(0).max(23),
4247
+ startMinute: z7.enum(["ZERO", "FIFTEEN", "THIRTY", "FORTY_FIVE"]).default("ZERO"),
4248
+ endHour: z7.number().int().min(0).max(24),
4249
+ endMinute: z7.enum(["ZERO", "FIFTEEN", "THIRTY", "FORTY_FIVE"]).default("ZERO")
4250
+ });
4251
+ var deviceCriterionSchema = z7.object({
4252
+ criterionType: z7.literal("device"),
4253
+ device: z7.enum(DEVICE_TYPES),
4345
4254
  // Google's `CampaignCriterion.bid_modifier`: "The modifier must be in the range 0.1 - 10.0. Use 0
4346
4255
  // to opt out of a Device type." So 0 (exclude the device) and 0.1–10.0 are valid; the (0, 0.1) gap is not.
4347
- bidModifier: z8.number().min(0).max(10).optional().refine((v) => v === void 0 || v === 0 || v >= 0.1, {
4256
+ bidModifier: z7.number().min(0).max(10).optional().refine((v) => v === void 0 || v === 0 || v >= 0.1, {
4348
4257
  message: "bid modifier must be 0 (exclude the device) or between 0.1 and 10.0"
4349
4258
  })
4350
4259
  });
4351
- var campaignCriterionAddSchema = z8.object({
4260
+ var campaignCriterionAddSchema = z7.object({
4352
4261
  campaign: refSchema,
4353
- negative: z8.boolean().default(false),
4354
- criterion: z8.discriminatedUnion("criterionType", [
4262
+ negative: z7.boolean().default(false),
4263
+ criterion: z7.discriminatedUnion("criterionType", [
4355
4264
  locationCriterionSchema,
4356
4265
  languageCriterionSchema,
4357
4266
  adScheduleCriterionSchema,
@@ -4361,7 +4270,7 @@ var campaignCriterionAddSchema = z8.object({
4361
4270
  const c = val.criterion;
4362
4271
  if (c.criterionType === "adSchedule" && c.endHour === 24 && c.endMinute !== "ZERO") {
4363
4272
  ctx.addIssue({
4364
- code: z8.ZodIssueCode.custom,
4273
+ code: z7.ZodIssueCode.custom,
4365
4274
  message: "endHour 24 (midnight) cannot have a non-zero endMinute",
4366
4275
  path: ["criterion", "endMinute"]
4367
4276
  });
@@ -4413,17 +4322,17 @@ var GOOGLE_DRAFT_OP_KINDS = [
4413
4322
  "google.campaignCriterion.add",
4414
4323
  "google.campaignCriterion.remove"
4415
4324
  ];
4416
- var googleDraftOpKindSchema = z8.enum(GOOGLE_DRAFT_OP_KINDS);
4325
+ var googleDraftOpKindSchema = z7.enum(GOOGLE_DRAFT_OP_KINDS);
4417
4326
  function createOp2(kind, payload) {
4418
- return z8.object({ kind: z8.literal(kind), customerId: customerIdSchema, payload });
4327
+ return z7.object({ kind: z7.literal(kind), customerId: customerIdSchema, payload });
4419
4328
  }
4420
4329
  function updateOp2(kind, payload) {
4421
- return z8.object({ kind: z8.literal(kind), customerId: customerIdSchema, target: targetRefSchema, payload });
4330
+ return z7.object({ kind: z7.literal(kind), customerId: customerIdSchema, target: targetRefSchema, payload });
4422
4331
  }
4423
4332
  function targetOp(kind) {
4424
- return z8.object({ kind: z8.literal(kind), customerId: customerIdSchema, target: targetRefSchema });
4333
+ return z7.object({ kind: z7.literal(kind), customerId: customerIdSchema, target: targetRefSchema });
4425
4334
  }
4426
- var googleDraftOpInputSchema = z8.discriminatedUnion("kind", [
4335
+ var googleDraftOpInputSchema = z7.discriminatedUnion("kind", [
4427
4336
  createOp2("google.budget.create", budgetCreateSchema),
4428
4337
  updateOp2("google.budget.update", budgetUpdateSchema),
4429
4338
  createOp2("google.campaign.create", campaignCreateSchema2),
@@ -4471,132 +4380,132 @@ var googleDraftOpInputSchema = z8.discriminatedUnion("kind", [
4471
4380
  ]);
4472
4381
 
4473
4382
  // ../api/src/ads-google/wire.ts
4474
- import { z as z9 } from "zod";
4475
- var googleWriteModeSchema = z9.enum(["live", "simulated"]);
4476
- var googleDraftOpResultSchema = z9.object({
4477
- status: z9.enum(["applied", "simulated", "failed", "skipped"]),
4478
- resourceName: z9.string().optional(),
4479
- error: z9.string().optional(),
4480
- skippedBecause: z9.string().optional(),
4481
- executedAt: z9.number().optional()
4482
- });
4483
- var googleDraftStageRequestSchema = z9.object({
4484
- chatId: z9.string(),
4383
+ import { z as z8 } from "zod";
4384
+ var googleWriteModeSchema = z8.enum(["live", "simulated"]);
4385
+ var googleDraftOpResultSchema = z8.object({
4386
+ status: z8.enum(["applied", "simulated", "failed", "skipped"]),
4387
+ resourceName: z8.string().optional(),
4388
+ error: z8.string().optional(),
4389
+ skippedBecause: z8.string().optional(),
4390
+ executedAt: z8.number().optional()
4391
+ });
4392
+ var googleDraftStageRequestSchema = z8.object({
4393
+ chatId: z8.string(),
4485
4394
  op: googleDraftOpInputSchema
4486
4395
  });
4487
- var googleDraftStageResponseSchema = z9.object({
4488
- staged: z9.literal(true),
4489
- ref: z9.string(),
4396
+ var googleDraftStageResponseSchema = z8.object({
4397
+ staged: z8.literal(true),
4398
+ ref: z8.string(),
4490
4399
  kind: googleDraftOpKindSchema,
4491
4400
  mode: googleWriteModeSchema,
4492
- dependsOn: z9.array(z9.string()),
4493
- summary: z9.string(),
4494
- warnings: z9.array(z9.string()),
4401
+ dependsOn: z8.array(z8.string()),
4402
+ summary: z8.string(),
4403
+ warnings: z8.array(z8.string()),
4495
4404
  /** True when the op amended an already-staged op in place instead of appending a new one. */
4496
- amended: z9.boolean().optional()
4405
+ amended: z8.boolean().optional()
4497
4406
  });
4498
- var googleDraftAmendRequestSchema = z9.object({
4499
- chatId: z9.string(),
4500
- ref: z9.string(),
4501
- patch: z9.record(z9.string(), z9.unknown())
4407
+ var googleDraftAmendRequestSchema = z8.object({
4408
+ chatId: z8.string(),
4409
+ ref: z8.string(),
4410
+ patch: z8.record(z8.string(), z8.unknown())
4502
4411
  });
4503
- var googleDraftShowRequestSchema = z9.object({
4504
- chatId: z9.string(),
4505
- ref: z9.string()
4412
+ var googleDraftShowRequestSchema = z8.object({
4413
+ chatId: z8.string(),
4414
+ ref: z8.string()
4506
4415
  });
4507
4416
  var GOOGLE_DRAFT_BATCH_MAX = 500;
4508
- var googleDraftStageBatchRequestSchema = z9.object({
4509
- chatId: z9.string(),
4510
- ops: z9.array(googleDraftOpInputSchema).min(1).max(GOOGLE_DRAFT_BATCH_MAX)
4417
+ var googleDraftStageBatchRequestSchema = z8.object({
4418
+ chatId: z8.string(),
4419
+ ops: z8.array(googleDraftOpInputSchema).min(1).max(GOOGLE_DRAFT_BATCH_MAX)
4511
4420
  });
4512
- var googleDraftStageBatchResponseSchema = z9.object({
4513
- staged: z9.literal(true),
4421
+ var googleDraftStageBatchResponseSchema = z8.object({
4422
+ staged: z8.literal(true),
4514
4423
  mode: googleWriteModeSchema,
4515
- count: z9.number(),
4516
- ops: z9.array(
4517
- z9.object({
4518
- ref: z9.string(),
4424
+ count: z8.number(),
4425
+ ops: z8.array(
4426
+ z8.object({
4427
+ ref: z8.string(),
4519
4428
  kind: googleDraftOpKindSchema,
4520
- dependsOn: z9.array(z9.string()),
4521
- summary: z9.string(),
4522
- warnings: z9.array(z9.string())
4429
+ dependsOn: z8.array(z8.string()),
4430
+ summary: z8.string(),
4431
+ warnings: z8.array(z8.string())
4523
4432
  })
4524
4433
  )
4525
4434
  });
4526
- var googleDraftOpViewSchema = z9.object({
4527
- ref: z9.string(),
4435
+ var googleDraftOpViewSchema = z8.object({
4436
+ ref: z8.string(),
4528
4437
  kind: googleDraftOpKindSchema,
4529
- customerId: z9.string(),
4530
- target: z9.string().optional(),
4531
- dependsOn: z9.array(z9.string()),
4532
- summary: z9.string(),
4533
- stagedAt: z9.number(),
4438
+ customerId: z8.string(),
4439
+ target: z8.string().optional(),
4440
+ dependsOn: z8.array(z8.string()),
4441
+ summary: z8.string(),
4442
+ stagedAt: z8.number(),
4534
4443
  result: googleDraftOpResultSchema.optional()
4535
4444
  });
4536
- var googleDraftShowResponseSchema = z9.object({
4445
+ var googleDraftShowResponseSchema = z8.object({
4537
4446
  op: googleDraftOpViewSchema.extend({
4538
- payload: z9.unknown().optional(),
4539
- warnings: z9.array(z9.string()).optional(),
4540
- annotations: z9.unknown().optional()
4447
+ payload: z8.unknown().optional(),
4448
+ warnings: z8.array(z8.string()).optional(),
4449
+ annotations: z8.unknown().optional()
4541
4450
  })
4542
4451
  });
4543
- var googleDraftListRequestSchema = z9.object({
4544
- chatId: z9.string()
4452
+ var googleDraftListRequestSchema = z8.object({
4453
+ chatId: z8.string()
4545
4454
  });
4546
- var googleDraftAdvisorySchema = z9.object({
4547
- scope: z9.enum(["campaign", "adGroup"]),
4548
- message: z9.string()
4455
+ var googleDraftAdvisorySchema = z8.object({
4456
+ scope: z8.enum(["campaign", "adGroup"]),
4457
+ message: z8.string()
4549
4458
  });
4550
- var googleDraftStatusCollectionSchema = z9.object({
4551
- label: z9.string(),
4552
- added: z9.number(),
4553
- removed: z9.number(),
4554
- existing: z9.number()
4459
+ var googleDraftStatusCollectionSchema = z8.object({
4460
+ label: z8.string(),
4461
+ added: z8.number(),
4462
+ removed: z8.number(),
4463
+ existing: z8.number()
4555
4464
  });
4556
- var googleDraftChangeOperationSchema = z9.enum(["create", "update", "pause", "resume", "remove"]);
4557
- var googleDraftStatusNodeSchema = z9.lazy(
4558
- () => z9.object({
4559
- entity: z9.string(),
4560
- name: z9.string(),
4465
+ var googleDraftChangeOperationSchema = z8.enum(["create", "update", "pause", "resume", "remove"]);
4466
+ var googleDraftStatusNodeSchema = z8.lazy(
4467
+ () => z8.object({
4468
+ entity: z8.string(),
4469
+ name: z8.string(),
4561
4470
  operation: googleDraftChangeOperationSchema.optional(),
4562
- existing: z9.boolean(),
4563
- collections: z9.array(googleDraftStatusCollectionSchema),
4564
- children: z9.array(googleDraftStatusNodeSchema),
4565
- warnings: z9.array(z9.string()).optional()
4471
+ existing: z8.boolean(),
4472
+ collections: z8.array(googleDraftStatusCollectionSchema),
4473
+ children: z8.array(googleDraftStatusNodeSchema),
4474
+ warnings: z8.array(z8.string()).optional()
4566
4475
  })
4567
4476
  );
4568
- var googleDraftListResponseSchema = z9.object({
4569
- status: z9.enum(["active", "publishing", "applied", "discarded", "none"]),
4477
+ var googleDraftListResponseSchema = z8.object({
4478
+ status: z8.enum(["active", "publishing", "applied", "discarded", "none"]),
4570
4479
  mode: googleWriteModeSchema,
4571
- count: z9.number(),
4572
- ops: z9.array(googleDraftOpViewSchema),
4480
+ count: z8.number(),
4481
+ ops: z8.array(googleDraftOpViewSchema),
4573
4482
  /** Grouped campaign ▸ ad group ▸ ad tree for the readable CLI status view. */
4574
- tree: z9.array(googleDraftStatusNodeSchema).optional(),
4483
+ tree: z8.array(googleDraftStatusNodeSchema).optional(),
4575
4484
  /** Non-blocking completeness advisories for the whole draft. */
4576
- advisories: z9.array(googleDraftAdvisorySchema).optional()
4485
+ advisories: z8.array(googleDraftAdvisorySchema).optional()
4577
4486
  });
4578
- var googleDraftRemoveRequestSchema = z9.object({
4579
- chatId: z9.string(),
4580
- ref: z9.string()
4487
+ var googleDraftRemoveRequestSchema = z8.object({
4488
+ chatId: z8.string(),
4489
+ ref: z8.string()
4581
4490
  });
4582
- var googleDraftRemoveResponseSchema = z9.object({
4491
+ var googleDraftRemoveResponseSchema = z8.object({
4583
4492
  /** The requested ref plus any dependents removed by cascade. */
4584
- removed: z9.array(z9.string())
4493
+ removed: z8.array(z8.string())
4585
4494
  });
4586
- var googleDraftClearRequestSchema = z9.object({
4587
- chatId: z9.string()
4495
+ var googleDraftClearRequestSchema = z8.object({
4496
+ chatId: z8.string()
4588
4497
  });
4589
- var googleDraftClearResponseSchema = z9.object({
4590
- cleared: z9.number()
4498
+ var googleDraftClearResponseSchema = z8.object({
4499
+ cleared: z8.number()
4591
4500
  });
4592
- var googleFieldErrorSchema = z9.object({
4593
- path: z9.string(),
4594
- message: z9.string()
4501
+ var googleFieldErrorSchema = z8.object({
4502
+ path: z8.string(),
4503
+ message: z8.string()
4595
4504
  });
4596
- var googleDraftErrorResponseSchema = z9.object({
4597
- code: z9.string(),
4598
- error: z9.string(),
4599
- fields: z9.array(googleFieldErrorSchema).optional()
4505
+ var googleDraftErrorResponseSchema = z8.object({
4506
+ code: z8.string(),
4507
+ error: z8.string(),
4508
+ fields: z8.array(googleFieldErrorSchema).optional()
4600
4509
  });
4601
4510
 
4602
4511
  // src/commands/ads/google/draft-status.ts
@@ -4761,11 +4670,11 @@ function rawTextEntries(value) {
4761
4670
  const values = Array.isArray(value) ? value : typeof value === "string" ? [value] : [];
4762
4671
  return values.filter((v) => typeof v === "string").flatMap((v) => v.split(",")).map((v) => v.trim()).filter(Boolean);
4763
4672
  }
4764
- function rawFileEntries(path12) {
4765
- if (typeof path12 !== "string" || path12.length === 0) {
4673
+ function rawFileEntries(path14) {
4674
+ if (typeof path14 !== "string" || path14.length === 0) {
4766
4675
  return [];
4767
4676
  }
4768
- return readFileSync2(path12, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
4677
+ return readFileSync2(path14, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
4769
4678
  }
4770
4679
  function keywordEntries(args) {
4771
4680
  const defaultMatch = typeof args["match-type"] === "string" ? args["match-type"].toUpperCase() : void 0;
@@ -4788,19 +4697,19 @@ function keywordEntries(args) {
4788
4697
  }
4789
4698
  return entries;
4790
4699
  }
4791
- function loadJsonFileArg(path12) {
4792
- if (typeof path12 !== "string" || path12.length === 0) {
4700
+ function loadJsonFileArg(path14) {
4701
+ if (typeof path14 !== "string" || path14.length === 0) {
4793
4702
  return {};
4794
4703
  }
4795
4704
  try {
4796
- const parsed = JSON.parse(readFileSync2(path12, "utf8"));
4705
+ const parsed = JSON.parse(readFileSync2(path14, "utf8"));
4797
4706
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
4798
- failWriteValidation(`${path12} must contain a JSON object`);
4707
+ failWriteValidation(`${path14} must contain a JSON object`);
4799
4708
  }
4800
4709
  return parsed;
4801
4710
  } catch (err) {
4802
4711
  if (err instanceof SyntaxError) {
4803
- failWriteValidation(`${path12} is not valid JSON: ${err.message}`);
4712
+ failWriteValidation(`${path14} is not valid JSON: ${err.message}`);
4804
4713
  }
4805
4714
  throw err;
4806
4715
  }
@@ -4911,10 +4820,10 @@ async function stageUpdate(kind, customerId, target, payload) {
4911
4820
  async function stageTarget(kind, customerId, target) {
4912
4821
  await stageGoogleOp({ kind, customerId, target });
4913
4822
  }
4914
- async function draftAction(path12, body) {
4823
+ async function draftAction(path14, body) {
4915
4824
  try {
4916
4825
  const chatId = requireChatId();
4917
- const response = await apiPost(path12, { chatId, ...body });
4826
+ const response = await apiPost(path14, { chatId, ...body });
4918
4827
  writeJsonEnvelope(response);
4919
4828
  } catch (err) {
4920
4829
  handleGoogleError(err);
@@ -8669,19 +8578,19 @@ function failWriteValidation2(message) {
8669
8578
  writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
8670
8579
  process.exit(1);
8671
8580
  }
8672
- function loadJsonFileArg2(path12) {
8673
- if (typeof path12 !== "string" || path12.length === 0) {
8581
+ function loadJsonFileArg2(path14) {
8582
+ if (typeof path14 !== "string" || path14.length === 0) {
8674
8583
  return {};
8675
8584
  }
8676
8585
  try {
8677
- const parsed = JSON.parse(readFileSync6(path12, "utf8"));
8586
+ const parsed = JSON.parse(readFileSync6(path14, "utf8"));
8678
8587
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
8679
- failWriteValidation2(`${path12} must contain a JSON object`);
8588
+ failWriteValidation2(`${path14} must contain a JSON object`);
8680
8589
  }
8681
8590
  return parsed;
8682
8591
  } catch (err) {
8683
8592
  if (err instanceof SyntaxError) {
8684
- failWriteValidation2(`${path12} is not valid JSON: ${err.message}`);
8593
+ failWriteValidation2(`${path14} is not valid JSON: ${err.message}`);
8685
8594
  }
8686
8595
  throw err;
8687
8596
  }
@@ -8766,15 +8675,15 @@ function parseLocaleFlag(value) {
8766
8675
  }
8767
8676
  return { language: match[1], country: match[2].toUpperCase() };
8768
8677
  }
8769
- function loadTargetingFileArg(path12) {
8770
- if (typeof path12 !== "string" || path12.length === 0) {
8678
+ function loadTargetingFileArg(path14) {
8679
+ if (typeof path14 !== "string" || path14.length === 0) {
8771
8680
  return void 0;
8772
8681
  }
8773
- const parsed = loadJsonFileArg2(path12);
8682
+ const parsed = loadJsonFileArg2(path14);
8774
8683
  const criteria = parsed.targetingCriteria ?? parsed;
8775
8684
  if (!criteria.include) {
8776
8685
  failWriteValidation2(
8777
- `${path12} must contain targeting criteria with an "include" block (see baker schema ads.linkedin.campaigns.create)`
8686
+ `${path14} must contain targeting criteria with an "include" block (see baker schema ads.linkedin.campaigns.create)`
8778
8687
  );
8779
8688
  }
8780
8689
  return criteria;
@@ -8809,14 +8718,14 @@ function parseCsvLine(line) {
8809
8718
  cells.push(current);
8810
8719
  return cells.map((cell) => cell.trim());
8811
8720
  }
8812
- function parseListFileArg(path12, maxRows) {
8813
- if (typeof path12 !== "string" || path12.length === 0) {
8721
+ function parseListFileArg(path14, maxRows) {
8722
+ if (typeof path14 !== "string" || path14.length === 0) {
8814
8723
  return void 0;
8815
8724
  }
8816
- const raw = readFileSync6(path12, "utf8");
8725
+ const raw = readFileSync6(path14, "utf8");
8817
8726
  const lines = raw.split(/\r?\n/).filter((line) => line.trim().length > 0);
8818
8727
  if (lines.length < 2) {
8819
- failWriteValidation2(`${path12} needs a header row and at least one data row`);
8728
+ failWriteValidation2(`${path14} needs a header row and at least one data row`);
8820
8729
  }
8821
8730
  const columns = parseCsvLine(lines[0]).map((column) => column.trim());
8822
8731
  const rows = [];
@@ -8835,7 +8744,7 @@ function parseListFileArg(path12, maxRows) {
8835
8744
  }
8836
8745
  }
8837
8746
  if (rows.length > maxRows) {
8838
- failWriteValidation2(`${path12} has ${rows.length} rows \u2014 the inline limit is ${maxRows}. Split the list.`);
8747
+ failWriteValidation2(`${path14} has ${rows.length} rows \u2014 the inline limit is ${maxRows}. Split the list.`);
8839
8748
  }
8840
8749
  return { columns, rows };
8841
8750
  }
@@ -9480,7 +9389,7 @@ var leadFormsCreateCommand = defineCommand38({
9480
9389
  Required: name, headline (\u226460), privacyPolicyUrl, questions[] (\u226412; playbook: \u22644 for completion).
9481
9390
  Each question is a predefined profile field ({ name, predefinedField: "EMAIL" }) or a custom question ({ name, questionType: "MULTIPLE_CHOICE", options: [...] }; \u22643 custom).
9482
9391
  Best-practice fields the preview will nudge for if missing: 1-3 qualifying questions, consents[] (disclosure checkboxes), thankYou.message + thankYou.landingUrl|appointmentUrl.
9483
- Also supported: locale, formImageId|formImageUrn, hiddenFields[], legalDisclaimer, thankYou.cta. Example: baker ads linkedin lead-forms create --file form.json`
9392
+ Also supported: locale, formImageId|formImageUrn, privacyPolicyText, hiddenFields[], legalDisclaimer, thankYou.cta. Example: baker ads linkedin lead-forms create --file form.json`
9484
9393
  },
9485
9394
  args: {
9486
9395
  ...accountArgs,
@@ -10904,72 +10813,72 @@ var NUMERIC_ID_REGEX3 = /^\d+$/;
10904
10813
  var IMAGE_HASH_REGEX = /^[A-Fa-f0-9]{16,}$/;
10905
10814
 
10906
10815
  // ../api/src/ads-meta/ops.ts
10907
- import { z as z10 } from "zod";
10908
- var tempRefSchema3 = z10.string().regex(TEMP_REF_REGEX3, "expected a meta_temp_* reference");
10909
- var parentRefSchema2 = z10.union([z10.string().regex(NUMERIC_ID_REGEX3, "expected a numeric id"), tempRefSchema3]);
10910
- var moneySchema2 = z10.object({
10911
- amount: z10.string().regex(/^\d+(\.\d{1,2})?$/, "expected a decimal amount like 50 or 50.00").refine((val) => Number(val) > 0, "amount must be greater than zero"),
10912
- currencyCode: z10.string().length(3).optional()
10913
- });
10914
- var httpsUrlSchema3 = z10.string().url().refine((u) => u.startsWith("https://"), "destination URLs must be https");
10915
- var bakerMediaIdSchema2 = z10.string().min(1);
10916
- var stageableStatusSchema3 = z10.enum(STAGEABLE_CREATE_STATUSES3);
10917
- var updateStatusSchema = z10.enum(UPDATE_STATUSES);
10816
+ import { z as z9 } from "zod";
10817
+ var tempRefSchema3 = z9.string().regex(TEMP_REF_REGEX3, "expected a meta_temp_* reference");
10818
+ var parentRefSchema2 = z9.union([z9.string().regex(NUMERIC_ID_REGEX3, "expected a numeric id"), tempRefSchema3]);
10819
+ var moneySchema2 = z9.object({
10820
+ amount: z9.string().regex(/^\d+(\.\d{1,2})?$/, "expected a decimal amount like 50 or 50.00").refine((val) => Number(val) > 0, "amount must be greater than zero"),
10821
+ currencyCode: z9.string().length(3).optional()
10822
+ });
10823
+ var httpsUrlSchema3 = z9.string().url().refine((u) => u.startsWith("https://"), "destination URLs must be https");
10824
+ var bakerMediaIdSchema2 = z9.string().min(1);
10825
+ var stageableStatusSchema3 = z9.enum(STAGEABLE_CREATE_STATUSES3);
10826
+ var updateStatusSchema = z9.enum(UPDATE_STATUSES);
10918
10827
  function currencyMinimums2(currencyCode) {
10919
10828
  return CURRENCY_MINIMUMS2[currencyCode] ?? DEFAULT_CURRENCY_MINIMUM2;
10920
10829
  }
10921
- function validateDailyBudgetFloor(money, ctx, path12) {
10830
+ function validateDailyBudgetFloor(money, ctx, path14) {
10922
10831
  if (money?.currencyCode) {
10923
10832
  const min = currencyMinimums2(money.currencyCode).dailyBudgetMin;
10924
10833
  if (Number(money.amount) < min) {
10925
- ctx.addIssue({ code: "custom", path: path12, message: `below the ${min} ${money.currencyCode} daily minimum` });
10834
+ ctx.addIssue({ code: "custom", path: path14, message: `below the ${min} ${money.currencyCode} daily minimum` });
10926
10835
  }
10927
10836
  }
10928
10837
  }
10929
- var geoLocationsSchema = z10.object({
10930
- countries: z10.array(z10.string().length(2)).optional(),
10931
- regions: z10.array(z10.object({ key: z10.string() })).optional(),
10932
- cities: z10.array(z10.object({ key: z10.string(), radius: z10.number().optional(), distance_unit: z10.string().optional() })).optional(),
10933
- zips: z10.array(z10.object({ key: z10.string() })).optional(),
10934
- location_types: z10.array(z10.string()).optional()
10935
- }).catchall(z10.unknown());
10936
- var idNameSchema = z10.object({ id: z10.string(), name: z10.string().optional() });
10937
- var metaTargetingSchema = z10.object({
10838
+ var geoLocationsSchema = z9.object({
10839
+ countries: z9.array(z9.string().length(2)).optional(),
10840
+ regions: z9.array(z9.object({ key: z9.string() })).optional(),
10841
+ cities: z9.array(z9.object({ key: z9.string(), radius: z9.number().optional(), distance_unit: z9.string().optional() })).optional(),
10842
+ zips: z9.array(z9.object({ key: z9.string() })).optional(),
10843
+ location_types: z9.array(z9.string()).optional()
10844
+ }).catchall(z9.unknown());
10845
+ var idNameSchema = z9.object({ id: z9.string(), name: z9.string().optional() });
10846
+ var metaTargetingSchema = z9.object({
10938
10847
  geo_locations: geoLocationsSchema.optional(),
10939
10848
  excluded_geo_locations: geoLocationsSchema.optional(),
10940
- age_min: z10.number().int().min(13).max(65).optional(),
10941
- age_max: z10.number().int().min(13).max(65).optional(),
10942
- genders: z10.array(z10.union([z10.literal(1), z10.literal(2)])).optional(),
10943
- locales: z10.array(z10.number().int()).optional(),
10944
- interests: z10.array(idNameSchema).optional(),
10945
- behaviors: z10.array(idNameSchema).optional(),
10946
- custom_audiences: z10.array(z10.object({ id: parentRefSchema2 })).optional(),
10947
- excluded_custom_audiences: z10.array(z10.object({ id: parentRefSchema2 })).optional(),
10948
- flexible_spec: z10.array(z10.record(z10.string(), z10.unknown())).optional(),
10949
- exclusions: z10.record(z10.string(), z10.unknown()).optional(),
10950
- publisher_platforms: z10.array(z10.string()).optional(),
10951
- facebook_positions: z10.array(z10.string()).optional(),
10952
- instagram_positions: z10.array(z10.string()).optional(),
10953
- audience_network_positions: z10.array(z10.string()).optional(),
10954
- messenger_positions: z10.array(z10.string()).optional(),
10955
- device_platforms: z10.array(z10.string()).optional(),
10956
- targeting_automation: z10.object({ advantage_audience: z10.union([z10.literal(0), z10.literal(1)]) }).partial().optional()
10957
- }).catchall(z10.unknown());
10958
- var specialAdCategoriesSchema = z10.array(z10.enum(SPECIAL_AD_CATEGORIES)).default(["NONE"]);
10959
- var campaignCreateSchema3 = z10.object({
10960
- name: z10.string().min(1).max(META_LIMITS.campaign.nameMax),
10961
- objective: z10.enum(OBJECTIVES),
10849
+ age_min: z9.number().int().min(13).max(65).optional(),
10850
+ age_max: z9.number().int().min(13).max(65).optional(),
10851
+ genders: z9.array(z9.union([z9.literal(1), z9.literal(2)])).optional(),
10852
+ locales: z9.array(z9.number().int()).optional(),
10853
+ interests: z9.array(idNameSchema).optional(),
10854
+ behaviors: z9.array(idNameSchema).optional(),
10855
+ custom_audiences: z9.array(z9.object({ id: parentRefSchema2 })).optional(),
10856
+ excluded_custom_audiences: z9.array(z9.object({ id: parentRefSchema2 })).optional(),
10857
+ flexible_spec: z9.array(z9.record(z9.string(), z9.unknown())).optional(),
10858
+ exclusions: z9.record(z9.string(), z9.unknown()).optional(),
10859
+ publisher_platforms: z9.array(z9.string()).optional(),
10860
+ facebook_positions: z9.array(z9.string()).optional(),
10861
+ instagram_positions: z9.array(z9.string()).optional(),
10862
+ audience_network_positions: z9.array(z9.string()).optional(),
10863
+ messenger_positions: z9.array(z9.string()).optional(),
10864
+ device_platforms: z9.array(z9.string()).optional(),
10865
+ targeting_automation: z9.object({ advantage_audience: z9.union([z9.literal(0), z9.literal(1)]) }).partial().optional()
10866
+ }).catchall(z9.unknown());
10867
+ var specialAdCategoriesSchema = z9.array(z9.enum(SPECIAL_AD_CATEGORIES)).default(["NONE"]);
10868
+ var campaignCreateSchema3 = z9.object({
10869
+ name: z9.string().min(1).max(META_LIMITS.campaign.nameMax),
10870
+ objective: z9.enum(OBJECTIVES),
10962
10871
  status: stageableStatusSchema3.default("PAUSED"),
10963
10872
  special_ad_categories: specialAdCategoriesSchema,
10964
- special_ad_category_country: z10.array(z10.string().length(2)).optional(),
10965
- buying_type: z10.enum(BUYING_TYPES).default("AUCTION"),
10966
- bid_strategy: z10.enum(BID_STRATEGIES).optional(),
10873
+ special_ad_category_country: z9.array(z9.string().length(2)).optional(),
10874
+ buying_type: z9.enum(BUYING_TYPES).default("AUCTION"),
10875
+ bid_strategy: z9.enum(BID_STRATEGIES).optional(),
10967
10876
  /** Campaign Budget Optimization (Advantage campaign budget) — mutually exclusive with ad-set budgets. */
10968
10877
  dailyBudget: moneySchema2.optional(),
10969
10878
  lifetimeBudget: moneySchema2.optional(),
10970
10879
  spendCap: moneySchema2.optional(),
10971
- start_time: z10.number().int().positive().optional(),
10972
- stop_time: z10.number().int().positive().optional()
10880
+ start_time: z9.number().int().positive().optional(),
10881
+ stop_time: z9.number().int().positive().optional()
10973
10882
  }).superRefine((p, ctx) => {
10974
10883
  if (p.dailyBudget && p.lifetimeBudget) {
10975
10884
  ctx.addIssue({ code: "custom", path: ["dailyBudget"], message: "set only one of dailyBudget or lifetimeBudget" });
@@ -10979,15 +10888,15 @@ var campaignCreateSchema3 = z10.object({
10979
10888
  ctx.addIssue({ code: "custom", path: ["stop_time"], message: "stop_time must be after start_time" });
10980
10889
  }
10981
10890
  });
10982
- var campaignUpdateSchema3 = z10.object({
10983
- name: z10.string().min(1).max(META_LIMITS.campaign.nameMax).optional(),
10891
+ var campaignUpdateSchema3 = z9.object({
10892
+ name: z9.string().min(1).max(META_LIMITS.campaign.nameMax).optional(),
10984
10893
  status: updateStatusSchema.optional(),
10985
- bid_strategy: z10.enum(BID_STRATEGIES).optional(),
10894
+ bid_strategy: z9.enum(BID_STRATEGIES).optional(),
10986
10895
  dailyBudget: moneySchema2.optional(),
10987
10896
  lifetimeBudget: moneySchema2.optional(),
10988
10897
  spendCap: moneySchema2.optional(),
10989
- start_time: z10.number().int().positive().optional(),
10990
- stop_time: z10.number().int().positive().optional()
10898
+ start_time: z9.number().int().positive().optional(),
10899
+ stop_time: z9.number().int().positive().optional()
10991
10900
  }).superRefine((p, ctx) => {
10992
10901
  if (!Object.values(p).some((val) => val !== void 0)) {
10993
10902
  ctx.addIssue({ code: "custom", message: "update needs at least one field" });
@@ -10997,38 +10906,38 @@ var campaignUpdateSchema3 = z10.object({
10997
10906
  }
10998
10907
  validateDailyBudgetFloor(p.dailyBudget, ctx, ["dailyBudget", "amount"]);
10999
10908
  });
11000
- var promotedObjectSchema = z10.object({
10909
+ var promotedObjectSchema = z9.object({
11001
10910
  page_id: parentRefSchema2.optional(),
11002
- pixel_id: z10.string().regex(NUMERIC_ID_REGEX3).optional(),
11003
- custom_event_type: z10.enum(CUSTOM_EVENT_TYPES).optional(),
11004
- application_id: z10.string().regex(NUMERIC_ID_REGEX3).optional(),
11005
- object_store_url: z10.string().url().optional(),
11006
- product_catalog_id: z10.string().regex(NUMERIC_ID_REGEX3).optional(),
11007
- product_set_id: z10.string().regex(NUMERIC_ID_REGEX3).optional(),
11008
- whatsapp_phone_number: z10.string().optional(),
11009
- offline_conversion_data_set_id: z10.string().regex(NUMERIC_ID_REGEX3).optional()
10911
+ pixel_id: z9.string().regex(NUMERIC_ID_REGEX3).optional(),
10912
+ custom_event_type: z9.enum(CUSTOM_EVENT_TYPES).optional(),
10913
+ application_id: z9.string().regex(NUMERIC_ID_REGEX3).optional(),
10914
+ object_store_url: z9.string().url().optional(),
10915
+ product_catalog_id: z9.string().regex(NUMERIC_ID_REGEX3).optional(),
10916
+ product_set_id: z9.string().regex(NUMERIC_ID_REGEX3).optional(),
10917
+ whatsapp_phone_number: z9.string().optional(),
10918
+ offline_conversion_data_set_id: z9.string().regex(NUMERIC_ID_REGEX3).optional()
11010
10919
  }).partial();
11011
- var attributionSpecSchema = z10.array(
11012
- z10.object({
11013
- event_type: z10.enum(ATTRIBUTION_EVENT_TYPES),
11014
- window_days: z10.union([z10.literal(1), z10.literal(7), z10.literal(28)])
10920
+ var attributionSpecSchema = z9.array(
10921
+ z9.object({
10922
+ event_type: z9.enum(ATTRIBUTION_EVENT_TYPES),
10923
+ window_days: z9.union([z9.literal(1), z9.literal(7), z9.literal(28)])
11015
10924
  })
11016
10925
  );
11017
10926
  var adSetFields = {
11018
- name: z10.string().min(1).max(META_LIMITS.adSet.nameMax),
10927
+ name: z9.string().min(1).max(META_LIMITS.adSet.nameMax),
11019
10928
  campaign_id: parentRefSchema2,
11020
10929
  status: stageableStatusSchema3.default("PAUSED"),
11021
10930
  dailyBudget: moneySchema2.optional(),
11022
10931
  lifetimeBudget: moneySchema2.optional(),
11023
10932
  bidAmount: moneySchema2.optional(),
11024
- bid_strategy: z10.enum(BID_STRATEGIES).optional(),
11025
- billing_event: z10.enum(BILLING_EVENTS),
11026
- optimization_goal: z10.enum(OPTIMIZATION_GOALS),
11027
- destination_type: z10.enum(DESTINATION_TYPES).optional(),
10933
+ bid_strategy: z9.enum(BID_STRATEGIES).optional(),
10934
+ billing_event: z9.enum(BILLING_EVENTS),
10935
+ optimization_goal: z9.enum(OPTIMIZATION_GOALS),
10936
+ destination_type: z9.enum(DESTINATION_TYPES).optional(),
11028
10937
  promoted_object: promotedObjectSchema.optional(),
11029
10938
  attribution_spec: attributionSpecSchema.optional(),
11030
- start_time: z10.number().int().positive().optional(),
11031
- end_time: z10.number().int().positive().optional(),
10939
+ start_time: z9.number().int().positive().optional(),
10940
+ end_time: z9.number().int().positive().optional(),
11032
10941
  targeting: metaTargetingSchema
11033
10942
  };
11034
10943
  function validateAdSetBudgetAndBid(p, ctx) {
@@ -11046,22 +10955,22 @@ function validateAdSetBudgetAndBid(p, ctx) {
11046
10955
  ctx.addIssue({ code: "custom", path: ["end_time"], message: "end_time must be after start_time" });
11047
10956
  }
11048
10957
  }
11049
- var adSetCreateSchema = z10.object(adSetFields).superRefine((p, ctx) => {
10958
+ var adSetCreateSchema = z9.object(adSetFields).superRefine((p, ctx) => {
11050
10959
  validateAdSetBudgetAndBid(p, ctx);
11051
10960
  });
11052
- var adSetUpdateSchema = z10.object({
10961
+ var adSetUpdateSchema = z9.object({
11053
10962
  name: adSetFields.name.optional(),
11054
10963
  status: updateStatusSchema.optional(),
11055
10964
  dailyBudget: moneySchema2.optional(),
11056
10965
  lifetimeBudget: moneySchema2.optional(),
11057
10966
  bidAmount: moneySchema2.optional(),
11058
- bid_strategy: z10.enum(BID_STRATEGIES).optional(),
11059
- optimization_goal: z10.enum(OPTIMIZATION_GOALS).optional(),
11060
- destination_type: z10.enum(DESTINATION_TYPES).optional(),
10967
+ bid_strategy: z9.enum(BID_STRATEGIES).optional(),
10968
+ optimization_goal: z9.enum(OPTIMIZATION_GOALS).optional(),
10969
+ destination_type: z9.enum(DESTINATION_TYPES).optional(),
11061
10970
  promoted_object: promotedObjectSchema.optional(),
11062
10971
  attribution_spec: attributionSpecSchema.optional(),
11063
- start_time: z10.number().int().positive().optional(),
11064
- end_time: z10.number().int().positive().optional(),
10972
+ start_time: z9.number().int().positive().optional(),
10973
+ end_time: z9.number().int().positive().optional(),
11065
10974
  targeting: metaTargetingSchema.optional()
11066
10975
  }).superRefine((p, ctx) => {
11067
10976
  if (!Object.values(p).some((val) => val !== void 0)) {
@@ -11069,38 +10978,38 @@ var adSetUpdateSchema = z10.object({
11069
10978
  }
11070
10979
  validateAdSetBudgetAndBid(p, ctx);
11071
10980
  });
11072
- var messageSchema = z10.string().min(1).max(META_LIMITS.creative.messageHardMax);
11073
- var headlineSchema2 = z10.string().min(1).max(META_LIMITS.creative.headlineMax);
11074
- var descriptionSchema = z10.string().min(1).max(META_LIMITS.creative.descriptionMax);
11075
- var callToActionSchema = z10.object({
11076
- type: z10.enum(CTA_TYPES2),
10981
+ var messageSchema = z9.string().min(1).max(META_LIMITS.creative.messageHardMax);
10982
+ var headlineSchema2 = z9.string().min(1).max(META_LIMITS.creative.headlineMax);
10983
+ var descriptionSchema = z9.string().min(1).max(META_LIMITS.creative.descriptionMax);
10984
+ var callToActionSchema = z9.object({
10985
+ type: z9.enum(CTA_TYPES2),
11077
10986
  /** Overrides the base link for the CTA button; defaults to the ad's link. */
11078
10987
  link: httpsUrlSchema3.optional()
11079
10988
  });
11080
- var creativeEnhancementsSchema = z10.object({
11081
- standardEnhancements: z10.enum(ENROLL_STATUSES).optional(),
11082
- features: z10.record(z10.string(), z10.enum(ENROLL_STATUSES)).optional()
10989
+ var creativeEnhancementsSchema = z9.object({
10990
+ standardEnhancements: z9.enum(ENROLL_STATUSES).optional(),
10991
+ features: z9.record(z9.string(), z9.enum(ENROLL_STATUSES)).optional()
11083
10992
  });
11084
10993
  var creativeSharedFields = {
11085
- name: z10.string().max(META_LIMITS.creative.nameMax).optional(),
10994
+ name: z9.string().max(META_LIMITS.creative.nameMax).optional(),
11086
10995
  /** Facebook Page id backing the ad's identity. */
11087
10996
  page_id: parentRefSchema2,
11088
10997
  /** Instagram account id for IG placements (aka instagram_actor_id on read). */
11089
- instagram_user_id: z10.string().regex(NUMERIC_ID_REGEX3).optional(),
10998
+ instagram_user_id: z9.string().regex(NUMERIC_ID_REGEX3).optional(),
11090
10999
  /** URL tracking parameters appended to the destination, e.g. "utm_source=fb&utm_campaign=x". */
11091
- url_tags: z10.string().max(1e3).optional(),
11000
+ url_tags: z9.string().max(1e3).optional(),
11092
11001
  enhancements: creativeEnhancementsSchema.optional()
11093
11002
  };
11094
11003
  var imageMediaFields = {
11095
- imageHash: z10.string().regex(IMAGE_HASH_REGEX).optional(),
11004
+ imageHash: z9.string().regex(IMAGE_HASH_REGEX).optional(),
11096
11005
  imageRef: tempRefSchema3.optional()
11097
11006
  };
11098
11007
  var videoMediaFields = {
11099
- videoId: z10.string().regex(NUMERIC_ID_REGEX3).optional(),
11008
+ videoId: z9.string().regex(NUMERIC_ID_REGEX3).optional(),
11100
11009
  videoRef: tempRefSchema3.optional(),
11101
11010
  /** Thumbnail for a video creative — image hash, ref, or public url. */
11102
- thumbnailHash: z10.string().regex(IMAGE_HASH_REGEX).optional(),
11103
- imageUrl: z10.string().url().optional()
11011
+ thumbnailHash: z9.string().regex(IMAGE_HASH_REGEX).optional(),
11012
+ imageUrl: z9.string().url().optional()
11104
11013
  };
11105
11014
  function countImageRefs(p) {
11106
11015
  return [p.imageHash, p.imageRef].filter(Boolean).length;
@@ -11108,8 +11017,8 @@ function countImageRefs(p) {
11108
11017
  function countVideoRefs(p) {
11109
11018
  return [p.videoId, p.videoRef].filter(Boolean).length;
11110
11019
  }
11111
- var singleCreativeSchema = z10.object({
11112
- creativeType: z10.literal("single"),
11020
+ var singleCreativeSchema = z9.object({
11021
+ creativeType: z9.literal("single"),
11113
11022
  ...creativeSharedFields,
11114
11023
  /** Primary text. */
11115
11024
  message: messageSchema,
@@ -11118,7 +11027,7 @@ var singleCreativeSchema = z10.object({
11118
11027
  headline: headlineSchema2.optional(),
11119
11028
  description: descriptionSchema.optional(),
11120
11029
  /** Display URL / caption shown under the headline. */
11121
- caption: z10.string().max(255).optional(),
11030
+ caption: z9.string().max(255).optional(),
11122
11031
  call_to_action: callToActionSchema.optional(),
11123
11032
  ...imageMediaFields,
11124
11033
  ...videoMediaFields
@@ -11142,10 +11051,10 @@ var singleCreativeSchema = z10.object({
11142
11051
  });
11143
11052
  }
11144
11053
  });
11145
- var carouselCardSchema = z10.object({
11054
+ var carouselCardSchema = z9.object({
11146
11055
  link: httpsUrlSchema3,
11147
- headline: z10.string().max(META_LIMITS.creative.headlineMax).optional(),
11148
- description: z10.string().max(META_LIMITS.creative.descriptionMax).optional(),
11056
+ headline: z9.string().max(META_LIMITS.creative.headlineMax).optional(),
11057
+ description: z9.string().max(META_LIMITS.creative.descriptionMax).optional(),
11149
11058
  call_to_action: callToActionSchema.optional(),
11150
11059
  ...imageMediaFields,
11151
11060
  ...videoMediaFields
@@ -11165,35 +11074,35 @@ var carouselCardSchema = z10.object({
11165
11074
  ctx.addIssue({ code: "custom", path: ["videoId"], message: "each card is an image OR a video, not both" });
11166
11075
  }
11167
11076
  });
11168
- var carouselCreativeSchema2 = z10.object({
11169
- creativeType: z10.literal("carousel"),
11077
+ var carouselCreativeSchema2 = z9.object({
11078
+ creativeType: z9.literal("carousel"),
11170
11079
  ...creativeSharedFields,
11171
11080
  message: messageSchema,
11172
11081
  /** Optional "see more" card destination applied when a card has no own link. */
11173
11082
  link: httpsUrlSchema3.optional(),
11174
11083
  call_to_action: callToActionSchema.optional(),
11175
- cards: z10.array(carouselCardSchema).min(META_LIMITS.creative.carouselCardsMin).max(META_LIMITS.creative.carouselCardsMax)
11084
+ cards: z9.array(carouselCardSchema).min(META_LIMITS.creative.carouselCardsMin).max(META_LIMITS.creative.carouselCardsMax)
11176
11085
  });
11177
- var dynamicImageSchema = z10.object({ ...imageMediaFields }).refine((p) => countImageRefs(p) === 1, "each dynamic image needs exactly one reference");
11178
- var dynamicVideoSchema = z10.object({
11086
+ var dynamicImageSchema = z9.object({ ...imageMediaFields }).refine((p) => countImageRefs(p) === 1, "each dynamic image needs exactly one reference");
11087
+ var dynamicVideoSchema = z9.object({
11179
11088
  videoId: videoMediaFields.videoId,
11180
11089
  videoRef: videoMediaFields.videoRef,
11181
11090
  thumbnailHash: videoMediaFields.thumbnailHash
11182
11091
  }).refine((p) => countVideoRefs(p) === 1, "each dynamic video needs exactly one reference");
11183
11092
  var DYN = META_LIMITS.creative;
11184
- var dynamicCreativeSchema = z10.object({
11185
- creativeType: z10.literal("dynamic"),
11093
+ var dynamicCreativeSchema = z9.object({
11094
+ creativeType: z9.literal("dynamic"),
11186
11095
  ...creativeSharedFields,
11187
- bodies: z10.array(z10.object({ text: messageSchema })).min(DYN.dynamicTextsMin).max(DYN.dynamicTextsMax),
11188
- titles: z10.array(z10.object({ text: headlineSchema2 })).min(DYN.dynamicTextsMin).max(DYN.dynamicTextsMax),
11189
- descriptions: z10.array(z10.object({ text: descriptionSchema })).max(DYN.dynamicTextsMax).optional(),
11190
- images: z10.array(dynamicImageSchema).optional(),
11191
- videos: z10.array(dynamicVideoSchema).optional(),
11192
- ad_formats: z10.array(z10.enum(AD_FORMATS2)).min(1),
11193
- call_to_action_types: z10.array(z10.enum(CTA_TYPES2)).optional(),
11194
- link_urls: z10.array(z10.object({ website_url: httpsUrlSchema3, display_url: z10.string().optional() })).min(1),
11096
+ bodies: z9.array(z9.object({ text: messageSchema })).min(DYN.dynamicTextsMin).max(DYN.dynamicTextsMax),
11097
+ titles: z9.array(z9.object({ text: headlineSchema2 })).min(DYN.dynamicTextsMin).max(DYN.dynamicTextsMax),
11098
+ descriptions: z9.array(z9.object({ text: descriptionSchema })).max(DYN.dynamicTextsMax).optional(),
11099
+ images: z9.array(dynamicImageSchema).optional(),
11100
+ videos: z9.array(dynamicVideoSchema).optional(),
11101
+ ad_formats: z9.array(z9.enum(AD_FORMATS2)).min(1),
11102
+ call_to_action_types: z9.array(z9.enum(CTA_TYPES2)).optional(),
11103
+ link_urls: z9.array(z9.object({ website_url: httpsUrlSchema3, display_url: z9.string().optional() })).min(1),
11195
11104
  /** Multi-language / placement customization — structural passthrough for v1. */
11196
- asset_customization_rules: z10.array(z10.record(z10.string(), z10.unknown())).optional()
11105
+ asset_customization_rules: z9.array(z9.record(z9.string(), z9.unknown())).optional()
11197
11106
  }).superRefine((p, ctx) => {
11198
11107
  if (!(p.images?.length || p.videos?.length)) {
11199
11108
  ctx.addIssue({
@@ -11203,57 +11112,57 @@ var dynamicCreativeSchema = z10.object({
11203
11112
  });
11204
11113
  }
11205
11114
  });
11206
- var existingPostCreativeSchema = z10.object({
11207
- creativeType: z10.literal("existing_post"),
11115
+ var existingPostCreativeSchema = z9.object({
11116
+ creativeType: z9.literal("existing_post"),
11208
11117
  name: creativeSharedFields.name,
11209
11118
  /** "<page_id>_<post_id>" object story id of the post to promote. */
11210
- object_story_id: z10.string().regex(/^\d+_\d+$/, 'expected "<page_id>_<post_id>"'),
11119
+ object_story_id: z9.string().regex(/^\d+_\d+$/, 'expected "<page_id>_<post_id>"'),
11211
11120
  instagram_user_id: creativeSharedFields.instagram_user_id,
11212
11121
  url_tags: creativeSharedFields.url_tags,
11213
11122
  enhancements: creativeSharedFields.enhancements
11214
11123
  });
11215
- var creativeContentSchema2 = z10.discriminatedUnion("creativeType", [
11124
+ var creativeContentSchema2 = z9.discriminatedUnion("creativeType", [
11216
11125
  singleCreativeSchema,
11217
11126
  carouselCreativeSchema2,
11218
11127
  dynamicCreativeSchema,
11219
11128
  existingPostCreativeSchema
11220
11129
  ]);
11221
11130
  var adCreativeCreateSchema = creativeContentSchema2;
11222
- var adCreativeUpdateSchema = z10.object({
11223
- name: z10.string().max(META_LIMITS.creative.nameMax).optional(),
11131
+ var adCreativeUpdateSchema = z9.object({
11132
+ name: z9.string().max(META_LIMITS.creative.nameMax).optional(),
11224
11133
  status: updateStatusSchema.optional(),
11225
11134
  /** Content patch — only honored when the target is a staged meta_temp_* creative. */
11226
- content: z10.record(z10.string(), z10.unknown()).optional()
11135
+ content: z9.record(z9.string(), z9.unknown()).optional()
11227
11136
  }).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
11228
- var adCreateSchema2 = z10.object({
11229
- name: z10.string().min(1).max(META_LIMITS.ad.nameMax),
11137
+ var adCreateSchema2 = z9.object({
11138
+ name: z9.string().min(1).max(META_LIMITS.ad.nameMax),
11230
11139
  adset_id: parentRefSchema2,
11231
11140
  status: stageableStatusSchema3.default("PAUSED"),
11232
- creative: z10.object({ creative_id: parentRefSchema2 }),
11141
+ creative: z9.object({ creative_id: parentRefSchema2 }),
11233
11142
  /** Conversion pixel / offline event set / view tags — structural passthrough. */
11234
- tracking_specs: z10.array(z10.record(z10.string(), z10.unknown())).optional()
11143
+ tracking_specs: z9.array(z9.record(z9.string(), z9.unknown())).optional()
11235
11144
  });
11236
- var adUpdateSchema2 = z10.object({
11237
- name: z10.string().min(1).max(META_LIMITS.ad.nameMax).optional(),
11145
+ var adUpdateSchema2 = z9.object({
11146
+ name: z9.string().min(1).max(META_LIMITS.ad.nameMax).optional(),
11238
11147
  status: updateStatusSchema.optional(),
11239
11148
  /** Swapping the creative is the Meta way to "edit" an ad's creative. */
11240
- creative: z10.object({ creative_id: parentRefSchema2 }).optional(),
11241
- tracking_specs: z10.array(z10.record(z10.string(), z10.unknown())).optional()
11149
+ creative: z9.object({ creative_id: parentRefSchema2 }).optional(),
11150
+ tracking_specs: z9.array(z9.record(z9.string(), z9.unknown())).optional()
11242
11151
  }).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
11243
- var lookalikeSpecSchema = z10.object({
11244
- origin: z10.array(z10.object({ id: parentRefSchema2 })).min(1),
11245
- ratio: z10.number().min(0.01).max(0.2).optional(),
11246
- country: z10.string().length(2).optional()
11247
- });
11248
- var customAudienceCreateSchema = z10.object({
11249
- name: z10.string().min(1).max(META_LIMITS.audience.nameMax),
11250
- subtype: z10.enum(CUSTOM_AUDIENCE_SUBTYPES),
11251
- description: z10.string().max(500).optional(),
11252
- customer_file_source: z10.string().optional(),
11253
- retention_days: z10.number().int().min(1).max(META_LIMITS.audience.retentionDaysMax).optional(),
11152
+ var lookalikeSpecSchema = z9.object({
11153
+ origin: z9.array(z9.object({ id: parentRefSchema2 })).min(1),
11154
+ ratio: z9.number().min(0.01).max(0.2).optional(),
11155
+ country: z9.string().length(2).optional()
11156
+ });
11157
+ var customAudienceCreateSchema = z9.object({
11158
+ name: z9.string().min(1).max(META_LIMITS.audience.nameMax),
11159
+ subtype: z9.enum(CUSTOM_AUDIENCE_SUBTYPES),
11160
+ description: z9.string().max(500).optional(),
11161
+ customer_file_source: z9.string().optional(),
11162
+ retention_days: z9.number().int().min(1).max(META_LIMITS.audience.retentionDaysMax).optional(),
11254
11163
  lookalike_spec: lookalikeSpecSchema.optional(),
11255
11164
  /** Website/engagement rule — structural passthrough validated by Meta. */
11256
- rule: z10.record(z10.string(), z10.unknown()).optional()
11165
+ rule: z9.record(z9.string(), z9.unknown()).optional()
11257
11166
  }).superRefine((p, ctx) => {
11258
11167
  if (p.subtype === "LOOKALIKE" && !p.lookalike_spec) {
11259
11168
  ctx.addIssue({ code: "custom", path: ["lookalike_spec"], message: "LOOKALIKE audiences need a lookalike_spec" });
@@ -11262,16 +11171,16 @@ var customAudienceCreateSchema = z10.object({
11262
11171
  ctx.addIssue({ code: "custom", path: ["rule"], message: `${p.subtype} audiences need a rule (use --file)` });
11263
11172
  }
11264
11173
  });
11265
- var customAudienceUpdateSchema = z10.object({
11266
- name: z10.string().min(1).max(META_LIMITS.audience.nameMax).optional(),
11267
- description: z10.string().max(500).optional()
11174
+ var customAudienceUpdateSchema = z9.object({
11175
+ name: z9.string().min(1).max(META_LIMITS.audience.nameMax).optional(),
11176
+ description: z9.string().max(500).optional()
11268
11177
  }).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
11269
- var mediaUploadSchema = z10.object({
11270
- kind: z10.enum(MEDIA_KINDS),
11178
+ var mediaUploadSchema = z9.object({
11179
+ kind: z9.enum(MEDIA_KINDS),
11271
11180
  bakerImageId: bakerMediaIdSchema2.optional(),
11272
11181
  bakerVideoId: bakerMediaIdSchema2.optional(),
11273
11182
  /** Optional display name / filename hint. */
11274
- name: z10.string().max(255).optional()
11183
+ name: z9.string().max(255).optional()
11275
11184
  }).superRefine((p, ctx) => {
11276
11185
  if (p.kind === "image" && !p.bakerImageId) {
11277
11186
  ctx.addIssue({ code: "custom", path: ["bakerImageId"], message: "image uploads need a bakerImageId" });
@@ -11293,16 +11202,16 @@ var META_DRAFT_OP_KINDS = [
11293
11202
  "customAudience.update",
11294
11203
  "media.upload"
11295
11204
  ];
11296
- var metaDraftOpKindSchema = z10.enum(META_DRAFT_OP_KINDS);
11297
- var accountIdSchema2 = z10.string().regex(NUMERIC_ID_REGEX3, "accountId must be the bare numeric ad account id");
11298
- var updateTargetSchema2 = z10.union([z10.string().regex(NUMERIC_ID_REGEX3), tempRefSchema3]);
11205
+ var metaDraftOpKindSchema = z9.enum(META_DRAFT_OP_KINDS);
11206
+ var accountIdSchema2 = z9.string().regex(NUMERIC_ID_REGEX3, "accountId must be the bare numeric ad account id");
11207
+ var updateTargetSchema2 = z9.union([z9.string().regex(NUMERIC_ID_REGEX3), tempRefSchema3]);
11299
11208
  function createOp3(kind, payload) {
11300
- return z10.object({ kind: z10.literal(kind), accountId: accountIdSchema2, payload });
11209
+ return z9.object({ kind: z9.literal(kind), accountId: accountIdSchema2, payload });
11301
11210
  }
11302
11211
  function updateOp3(kind, payload) {
11303
- return z10.object({ kind: z10.literal(kind), accountId: accountIdSchema2, target: updateTargetSchema2, payload });
11212
+ return z9.object({ kind: z9.literal(kind), accountId: accountIdSchema2, target: updateTargetSchema2, payload });
11304
11213
  }
11305
- var metaDraftOpInputSchema = z10.discriminatedUnion("kind", [
11214
+ var metaDraftOpInputSchema = z9.discriminatedUnion("kind", [
11306
11215
  createOp3("campaign.create", campaignCreateSchema3),
11307
11216
  updateOp3("campaign.update", campaignUpdateSchema3),
11308
11217
  createOp3("adSet.create", adSetCreateSchema),
@@ -11317,89 +11226,89 @@ var metaDraftOpInputSchema = z10.discriminatedUnion("kind", [
11317
11226
  ]);
11318
11227
 
11319
11228
  // ../api/src/ads-meta/wire.ts
11320
- import { z as z11 } from "zod";
11321
- var metaWriteModeSchema = z11.enum(["live", "simulated"]);
11322
- var metaDraftOpResultSchema = z11.object({
11323
- status: z11.enum(["applied", "simulated", "failed", "skipped"]),
11229
+ import { z as z10 } from "zod";
11230
+ var metaWriteModeSchema = z10.enum(["live", "simulated"]);
11231
+ var metaDraftOpResultSchema = z10.object({
11232
+ status: z10.enum(["applied", "simulated", "failed", "skipped"]),
11324
11233
  /** The resulting Meta node id (campaign/adset/creative/ad/audience) or simulated id. */
11325
- id: z11.string().optional(),
11234
+ id: z10.string().optional(),
11326
11235
  /** For media.upload ops: the resulting image hash. */
11327
- hash: z11.string().optional(),
11328
- error: z11.string().optional(),
11329
- skippedBecause: z11.string().optional(),
11330
- executedAt: z11.number().optional()
11236
+ hash: z10.string().optional(),
11237
+ error: z10.string().optional(),
11238
+ skippedBecause: z10.string().optional(),
11239
+ executedAt: z10.number().optional()
11331
11240
  });
11332
- var metaDraftStageRequestSchema = z11.object({
11333
- chatId: z11.string(),
11241
+ var metaDraftStageRequestSchema = z10.object({
11242
+ chatId: z10.string(),
11334
11243
  op: metaDraftOpInputSchema
11335
11244
  });
11336
- var metaDraftStageResponseSchema = z11.object({
11337
- staged: z11.literal(true),
11338
- ref: z11.string(),
11245
+ var metaDraftStageResponseSchema = z10.object({
11246
+ staged: z10.literal(true),
11247
+ ref: z10.string(),
11339
11248
  kind: metaDraftOpKindSchema,
11340
11249
  mode: metaWriteModeSchema,
11341
- dependsOn: z11.array(z11.string()),
11342
- summary: z11.string(),
11343
- warnings: z11.array(z11.string()),
11250
+ dependsOn: z10.array(z10.string()),
11251
+ summary: z10.string(),
11252
+ warnings: z10.array(z10.string()),
11344
11253
  /** True when the op amended an already-staged op in place instead of appending a new one. */
11345
- amended: z11.boolean().optional()
11346
- });
11347
- var metaDraftDuplicateRequestSchema = z11.object({
11348
- chatId: z11.string(),
11349
- accountId: z11.string(),
11350
- entity: z11.enum(["campaign", "adSet", "ad"]),
11351
- sourceId: z11.string(),
11352
- overrides: z11.record(z11.string(), z11.unknown()).optional(),
11254
+ amended: z10.boolean().optional()
11255
+ });
11256
+ var metaDraftDuplicateRequestSchema = z10.object({
11257
+ chatId: z10.string(),
11258
+ accountId: z10.string(),
11259
+ entity: z10.enum(["campaign", "adSet", "ad"]),
11260
+ sourceId: z10.string(),
11261
+ overrides: z10.record(z10.string(), z10.unknown()).optional(),
11353
11262
  /** Pause the original after the copy publishes. */
11354
- replace: z11.boolean().optional()
11263
+ replace: z10.boolean().optional()
11355
11264
  });
11356
- var metaDraftOpViewSchema = z11.object({
11357
- ref: z11.string(),
11265
+ var metaDraftOpViewSchema = z10.object({
11266
+ ref: z10.string(),
11358
11267
  kind: metaDraftOpKindSchema,
11359
- accountId: z11.string(),
11360
- target: z11.string().optional(),
11361
- dependsOn: z11.array(z11.string()),
11362
- summary: z11.string(),
11363
- stagedAt: z11.number(),
11268
+ accountId: z10.string(),
11269
+ target: z10.string().optional(),
11270
+ dependsOn: z10.array(z10.string()),
11271
+ summary: z10.string(),
11272
+ stagedAt: z10.number(),
11364
11273
  result: metaDraftOpResultSchema.optional()
11365
11274
  });
11366
- var metaDraftListRequestSchema = z11.object({
11367
- chatId: z11.string()
11275
+ var metaDraftListRequestSchema = z10.object({
11276
+ chatId: z10.string()
11368
11277
  });
11369
- var metaDraftAdvisorySchema = z11.object({
11370
- ref: z11.string(),
11371
- message: z11.string()
11278
+ var metaDraftAdvisorySchema = z10.object({
11279
+ ref: z10.string(),
11280
+ message: z10.string()
11372
11281
  });
11373
- var metaDraftListResponseSchema = z11.object({
11374
- status: z11.enum(["active", "publishing", "applied", "discarded", "none"]),
11282
+ var metaDraftListResponseSchema = z10.object({
11283
+ status: z10.enum(["active", "publishing", "applied", "discarded", "none"]),
11375
11284
  mode: metaWriteModeSchema,
11376
- count: z11.number(),
11377
- ops: z11.array(metaDraftOpViewSchema),
11285
+ count: z10.number(),
11286
+ ops: z10.array(metaDraftOpViewSchema),
11378
11287
  /** Non-blocking cross-op quality advisories — "good campaign, not just valid". */
11379
- advisories: z11.array(metaDraftAdvisorySchema)
11288
+ advisories: z10.array(metaDraftAdvisorySchema)
11380
11289
  });
11381
- var metaDraftRemoveRequestSchema = z11.object({
11382
- chatId: z11.string(),
11383
- ref: z11.string()
11290
+ var metaDraftRemoveRequestSchema = z10.object({
11291
+ chatId: z10.string(),
11292
+ ref: z10.string()
11384
11293
  });
11385
- var metaDraftRemoveResponseSchema = z11.object({
11294
+ var metaDraftRemoveResponseSchema = z10.object({
11386
11295
  /** The requested ref plus any dependents removed by cascade. */
11387
- removed: z11.array(z11.string())
11296
+ removed: z10.array(z10.string())
11388
11297
  });
11389
- var metaDraftClearRequestSchema = z11.object({
11390
- chatId: z11.string()
11298
+ var metaDraftClearRequestSchema = z10.object({
11299
+ chatId: z10.string()
11391
11300
  });
11392
- var metaDraftClearResponseSchema = z11.object({
11393
- cleared: z11.number()
11301
+ var metaDraftClearResponseSchema = z10.object({
11302
+ cleared: z10.number()
11394
11303
  });
11395
- var metaFieldErrorSchema = z11.object({
11396
- path: z11.string(),
11397
- message: z11.string()
11304
+ var metaFieldErrorSchema = z10.object({
11305
+ path: z10.string(),
11306
+ message: z10.string()
11398
11307
  });
11399
- var metaDraftErrorResponseSchema = z11.object({
11400
- code: z11.string(),
11401
- error: z11.string(),
11402
- fields: z11.array(metaFieldErrorSchema).optional()
11308
+ var metaDraftErrorResponseSchema = z10.object({
11309
+ code: z10.string(),
11310
+ error: z10.string(),
11311
+ fields: z10.array(metaFieldErrorSchema).optional()
11403
11312
  });
11404
11313
 
11405
11314
  // src/commands/ads/meta/write-shared.ts
@@ -11410,19 +11319,19 @@ function failWriteValidation3(message) {
11410
11319
  writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
11411
11320
  process.exit(1);
11412
11321
  }
11413
- function loadJsonFileArg3(path12) {
11414
- if (typeof path12 !== "string" || path12.length === 0) {
11322
+ function loadJsonFileArg3(path14) {
11323
+ if (typeof path14 !== "string" || path14.length === 0) {
11415
11324
  return {};
11416
11325
  }
11417
11326
  try {
11418
- const parsed = JSON.parse(readFileSync8(path12, "utf8"));
11327
+ const parsed = JSON.parse(readFileSync8(path14, "utf8"));
11419
11328
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
11420
- failWriteValidation3(`${path12} must contain a JSON object`);
11329
+ failWriteValidation3(`${path14} must contain a JSON object`);
11421
11330
  }
11422
11331
  return parsed;
11423
11332
  } catch (err) {
11424
11333
  if (err instanceof SyntaxError) {
11425
- failWriteValidation3(`${path12} is not valid JSON: ${err.message}`);
11334
+ failWriteValidation3(`${path14} is not valid JSON: ${err.message}`);
11426
11335
  }
11427
11336
  throw err;
11428
11337
  }
@@ -14485,7 +14394,7 @@ async function probeDuration(filePath) {
14485
14394
 
14486
14395
  // src/commands/canvas/run.ts
14487
14396
  import { readFile as readFile2 } from "fs/promises";
14488
- import path4 from "path";
14397
+ import path5 from "path";
14489
14398
  import { defineCommand as defineCommand88 } from "citty";
14490
14399
 
14491
14400
  // src/commands/canvas/placeholders.ts
@@ -14529,9 +14438,260 @@ function isResolvableRelative(value) {
14529
14438
  return typeof value === "string" && value.length > 0 && !value.includes("[TODO") && !path2.isAbsolute(value);
14530
14439
  }
14531
14440
 
14441
+ // src/commands/canvas/run-record.ts
14442
+ import path3 from "path";
14443
+ var MAX_RUN_NODES = 200;
14444
+ var MAX_OUTPUTS_PER_NODE = 10;
14445
+ var MAX_FINAL_OUTPUTS = 10;
14446
+ var MAX_PARAMS_PREVIEW_LENGTH = 1e3;
14447
+ function paramsPreviewFromParams(params) {
14448
+ if (params === void 0 || params === null) return void 0;
14449
+ const prompt = params.prompt;
14450
+ const text = typeof prompt === "string" && prompt.trim() ? prompt.trim() : compactJson(params);
14451
+ if (!text) return void 0;
14452
+ return text.length > MAX_PARAMS_PREVIEW_LENGTH ? `${text.slice(0, MAX_PARAMS_PREVIEW_LENGTH - 1)}\u2026` : text;
14453
+ }
14454
+ function compactJson(params) {
14455
+ try {
14456
+ const json = JSON.stringify(params);
14457
+ return json && json !== "{}" ? json : void 0;
14458
+ } catch {
14459
+ return void 0;
14460
+ }
14461
+ }
14462
+ var MAX_CREATIVE_SLUG_LENGTH = 100;
14463
+ function creativeSlugFromCanvasPath(filePath) {
14464
+ const normalized = filePath.split(path3.sep).join("/");
14465
+ const match = normalized.match(/(?:^|\/)src\/creatives\/([a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\//);
14466
+ const slug = match?.[1] ?? null;
14467
+ return slug && slug.length <= MAX_CREATIVE_SLUG_LENGTH ? slug : null;
14468
+ }
14469
+ var OUTPUT_KINDS = /* @__PURE__ */ new Set(["image", "video", "audio", "json", "text", "font"]);
14470
+ function toRecordOutput(slot, value) {
14471
+ const refs = collectAssetRefLikes(value);
14472
+ const ref = refs.length === 1 ? refs[0] : null;
14473
+ if (!ref || !isPersistedAssetRef(ref)) return null;
14474
+ const kind = typeof ref.kind === "string" && OUTPUT_KINDS.has(ref.kind) ? ref.kind : null;
14475
+ if (!kind) return null;
14476
+ return {
14477
+ slot,
14478
+ kind,
14479
+ sha256: ref.sha256,
14480
+ url: ref.url,
14481
+ mime: ref.mime,
14482
+ width: typeof ref.width === "number" ? ref.width : void 0,
14483
+ height: typeof ref.height === "number" ? ref.height : void 0,
14484
+ durationMs: typeof ref.duration_ms === "number" ? ref.duration_ms : void 0
14485
+ };
14486
+ }
14487
+ function nodeOutputsToRecord(nodeOutputs) {
14488
+ const out = [];
14489
+ for (const [slot, value] of Object.entries(nodeOutputs)) {
14490
+ if (Array.isArray(value)) {
14491
+ value.forEach((item, i) => {
14492
+ const rec = toRecordOutput(`${slot}#${i}`, item);
14493
+ if (rec) out.push(rec);
14494
+ });
14495
+ } else {
14496
+ const rec = toRecordOutput(slot, value);
14497
+ if (rec) out.push(rec);
14498
+ }
14499
+ }
14500
+ return out.slice(0, MAX_OUTPUTS_PER_NODE);
14501
+ }
14502
+ function finalOutputsToRecord(output) {
14503
+ if (Array.isArray(output)) {
14504
+ return output.map((item, i) => toRecordOutput(`final#${i}`, item)).filter((rec2) => rec2 !== null).slice(0, MAX_FINAL_OUTPUTS);
14505
+ }
14506
+ const rec = toRecordOutput("final", output);
14507
+ return rec ? [rec] : [];
14508
+ }
14509
+ function buildRunRecord(result, meta, plan) {
14510
+ const nodes = result.node_runs.slice(0, MAX_RUN_NODES).map((run) => {
14511
+ const planned = plan?.get(run.node_id);
14512
+ return {
14513
+ nodeId: run.node_id,
14514
+ nodeType: run.node_type,
14515
+ cached: run.cached,
14516
+ credits: run.credits,
14517
+ durationMs: run.duration_ms,
14518
+ outputs: nodeOutputsToRecord(result.outputs_by_node[run.node_id] ?? {}),
14519
+ deps: planned?.deps,
14520
+ status: plan ? "completed" : void 0,
14521
+ paramsPreview: planned?.paramsPreview
14522
+ };
14523
+ });
14524
+ const finalOutputs = finalOutputsToRecord(result.output);
14525
+ return {
14526
+ runId: result.run_id,
14527
+ creativeSlug: meta.creativeSlug,
14528
+ canvasPath: meta.canvasPath,
14529
+ canvasSha: meta.canvasSha,
14530
+ chatId: meta.chatId,
14531
+ status: "completed",
14532
+ stats: {
14533
+ totalNodes: result.stats.total_nodes,
14534
+ cachedNodes: result.stats.cached_nodes,
14535
+ totalCredits: result.stats.total_credits,
14536
+ durationMs: result.stats.duration_ms
14537
+ },
14538
+ nodes,
14539
+ finalOutputs: finalOutputs.length > 0 ? finalOutputs : void 0
14540
+ };
14541
+ }
14542
+ function buildFailedRunRecord(runId, errorMessage, meta) {
14543
+ return {
14544
+ runId,
14545
+ creativeSlug: meta.creativeSlug,
14546
+ canvasPath: meta.canvasPath,
14547
+ canvasSha: meta.canvasSha,
14548
+ chatId: meta.chatId,
14549
+ status: "failed",
14550
+ errorMessage: errorMessage.slice(0, 2e3),
14551
+ stats: { totalNodes: 0, cachedNodes: 0, totalCredits: 0, durationMs: 0 },
14552
+ nodes: []
14553
+ };
14554
+ }
14555
+
14556
+ // src/commands/canvas/run-progress.ts
14557
+ var RunProgressTracker = class {
14558
+ runId;
14559
+ meta;
14560
+ startedAt;
14561
+ nodes = /* @__PURE__ */ new Map();
14562
+ planned = false;
14563
+ constructor(runId, meta) {
14564
+ this.runId = runId;
14565
+ this.meta = meta;
14566
+ this.startedAt = Date.now();
14567
+ }
14568
+ apply(event) {
14569
+ if (event.kind === "plan") {
14570
+ for (const node of event.nodes) {
14571
+ this.nodes.set(node.node_id, {
14572
+ nodeId: node.node_id,
14573
+ nodeType: node.node_type,
14574
+ cached: false,
14575
+ credits: 0,
14576
+ durationMs: 0,
14577
+ outputs: [],
14578
+ deps: node.deps,
14579
+ status: "pending",
14580
+ paramsPreview: paramsPreviewFromParams(node.params)
14581
+ });
14582
+ }
14583
+ this.planned = true;
14584
+ return;
14585
+ }
14586
+ if (event.kind === "node_start") {
14587
+ this.patchNode(event.node_id, { status: "running" });
14588
+ return;
14589
+ }
14590
+ if (event.kind === "node_settled") {
14591
+ this.patchNode(event.run.node_id, {
14592
+ status: "completed",
14593
+ cached: event.run.cached,
14594
+ credits: event.run.credits,
14595
+ durationMs: event.run.duration_ms,
14596
+ outputs: nodeOutputsToRecord(event.outputs)
14597
+ });
14598
+ return;
14599
+ }
14600
+ this.patchNode(event.node_id, { status: "failed" });
14601
+ }
14602
+ /** True once the plan event landed — before that there is nothing worth posting. */
14603
+ hasPlan() {
14604
+ return this.planned;
14605
+ }
14606
+ /** Plan facts (deps + params preview) for stamping the terminal record's nodes. */
14607
+ planInfo() {
14608
+ const info = /* @__PURE__ */ new Map();
14609
+ for (const node of this.nodes.values()) {
14610
+ info.set(node.nodeId, { deps: node.deps ?? [], paramsPreview: node.paramsPreview });
14611
+ }
14612
+ return info;
14613
+ }
14614
+ /** The current in-flight state as a postable full record. */
14615
+ snapshot() {
14616
+ const nodes = [...this.nodes.values()];
14617
+ return {
14618
+ runId: this.runId,
14619
+ ...this.meta,
14620
+ status: "running",
14621
+ stats: {
14622
+ totalNodes: nodes.length,
14623
+ cachedNodes: nodes.filter((n) => n.cached).length,
14624
+ totalCredits: nodes.reduce((sum, n) => sum + n.credits, 0),
14625
+ durationMs: Date.now() - this.startedAt
14626
+ },
14627
+ nodes
14628
+ };
14629
+ }
14630
+ /**
14631
+ * Terminal record for a failed run, preserving what each node got to —
14632
+ * completed nodes keep their outputs so the graph shows exactly where the
14633
+ * run died instead of an empty husk.
14634
+ */
14635
+ failedSnapshot(errorMessage) {
14636
+ const snapshot = this.snapshot();
14637
+ return {
14638
+ ...snapshot,
14639
+ status: "failed",
14640
+ errorMessage: errorMessage.slice(0, 2e3),
14641
+ stats: { ...snapshot.stats, durationMs: Date.now() - this.startedAt }
14642
+ };
14643
+ }
14644
+ patchNode(nodeId, patch) {
14645
+ const existing = this.nodes.get(nodeId);
14646
+ if (!existing) return;
14647
+ this.nodes.set(nodeId, { ...existing, ...patch, status: patch.status ?? existing.status });
14648
+ }
14649
+ };
14650
+ var RunRecordPoster = class {
14651
+ post;
14652
+ latest = null;
14653
+ inflight = null;
14654
+ warned = false;
14655
+ constructor(post) {
14656
+ this.post = post;
14657
+ }
14658
+ /** Queue a progress snapshot; returns immediately. */
14659
+ enqueue(payload) {
14660
+ this.latest = payload;
14661
+ if (!this.inflight) this.inflight = this.pump();
14662
+ }
14663
+ /**
14664
+ * Post the terminal record (awaited, errors surfaced to the caller). Any
14665
+ * queued progress snapshot is superseded — the terminal record is the full
14666
+ * state — but an in-flight POST is awaited first so it can't land after.
14667
+ */
14668
+ async flush(terminal) {
14669
+ this.latest = null;
14670
+ if (this.inflight) await this.inflight;
14671
+ await this.post(terminal);
14672
+ }
14673
+ async pump() {
14674
+ while (this.latest) {
14675
+ const payload = this.latest;
14676
+ this.latest = null;
14677
+ try {
14678
+ await this.post(payload);
14679
+ } catch (e) {
14680
+ if (!this.warned) {
14681
+ this.warned = true;
14682
+ const msg = e instanceof Error ? e.message : String(e);
14683
+ process.stderr.write(`[warn] live run progress not streaming (${msg})
14684
+ `);
14685
+ }
14686
+ }
14687
+ }
14688
+ this.inflight = null;
14689
+ }
14690
+ };
14691
+
14532
14692
  // src/commands/canvas/run-retention.ts
14533
14693
  import { rm } from "fs/promises";
14534
- import path3 from "path";
14694
+ import path4 from "path";
14535
14695
  function runDirsToPrune(entries, keep, currentRunId) {
14536
14696
  const runs = entries.filter((e) => /^r_[0-9A-Za-z]+$/.test(e) && e !== currentRunId).sort();
14537
14697
  if (keep <= 0) return runs;
@@ -14548,7 +14708,7 @@ async function pruneOldRuns(outputsDir, keep, currentRunId, log) {
14548
14708
  const toPrune = runDirsToPrune(entries, keep, currentRunId);
14549
14709
  if (toPrune.length === 0) return;
14550
14710
  for (const dir of toPrune) {
14551
- await rm(path3.join(outputsDir, dir), { recursive: true, force: true }).catch(
14711
+ await rm(path4.join(outputsDir, dir), { recursive: true, force: true }).catch(
14552
14712
  (e) => log(`[prune ] could not remove ${dir}: ${e.message}`)
14553
14713
  );
14554
14714
  }
@@ -14575,10 +14735,22 @@ var runCommand = defineCommand88({
14575
14735
  "keep-runs": {
14576
14736
  type: "string",
14577
14737
  description: "After the run, prune old r_* run dirs, keeping the N newest (off by default)"
14738
+ },
14739
+ "remote-cache": {
14740
+ type: "string",
14741
+ description: "on | off \u2014 company-scoped remote cache + durable asset persistence (default on; env BAKER_CANVAS_REMOTE_CACHE)"
14742
+ },
14743
+ // citty consumes any `--no-<flag>` as a negation of `<flag>`, so the
14744
+ // opt-out spelling `--no-record` requires the flag to be named `record`
14745
+ // (a literal "no-record" arg would never receive a value).
14746
+ record: {
14747
+ type: "boolean",
14748
+ default: true,
14749
+ description: "Post the durable run-history record to Baker (disable with --no-record)"
14578
14750
  }
14579
14751
  },
14580
14752
  async run({ args }) {
14581
- const filePath = path4.resolve(String(args.file));
14753
+ const filePath = path5.resolve(String(args.file));
14582
14754
  const raw = await readFile2(filePath, "utf8");
14583
14755
  let parsed;
14584
14756
  try {
@@ -14589,7 +14761,7 @@ var runCommand = defineCommand88({
14589
14761
  `);
14590
14762
  process.exit(2);
14591
14763
  }
14592
- parsed = resolveRelativeCanvasPaths(parsed, path4.dirname(filePath));
14764
+ parsed = resolveRelativeCanvasPaths(parsed, path5.dirname(filePath));
14593
14765
  const pending = unsuppliedPlaceholderAssets(parsed);
14594
14766
  if (pending.length > 0) {
14595
14767
  process.stderr.write(
@@ -14609,26 +14781,43 @@ var runCommand = defineCommand88({
14609
14781
  );
14610
14782
  process.exit(2);
14611
14783
  }
14784
+ const remoteCache = args["remote-cache"] !== void 0 ? String(args["remote-cache"]) !== "off" : void 0;
14612
14785
  const engine = createEngineFromEnv({
14613
14786
  cacheDir: args["cache-dir"] ? String(args["cache-dir"]) : void 0,
14614
14787
  outputsDir: args["outputs-dir"] ? String(args["outputs-dir"]) : void 0,
14615
14788
  log: (line) => process.stdout.write(`${line}
14616
- `)
14789
+ `),
14790
+ remoteCache
14617
14791
  });
14792
+ const runId = args["run-id"] ? String(args["run-id"]) : `r_${ulid()}`;
14793
+ const recordMeta = {
14794
+ creativeSlug: creativeSlugFromCanvasPath(filePath) ?? void 0,
14795
+ canvasPath: path5.relative(process.cwd(), filePath) || void 0,
14796
+ canvasSha: sha256Hex(Buffer.from(raw)),
14797
+ chatId: getEnv().BAKER_CHAT_ID || void 0
14798
+ };
14799
+ const record = args.record === false ? null : buildRecorder();
14800
+ const progress = record ? new RunProgressTracker(runId, recordMeta) : null;
14801
+ const poster = record ? new RunRecordPoster(record) : null;
14618
14802
  try {
14619
14803
  const policy = args["cache-policy"] ?? "read_write";
14620
14804
  const result = await engine.run(parsed, {
14621
- run_id: args["run-id"] ? String(args["run-id"]) : void 0,
14805
+ run_id: runId,
14622
14806
  cache_policy: policy,
14623
14807
  concurrency: resolveConcurrency(
14624
14808
  // --concurrency wins; --parallel is the discoverable alias for the same bound.
14625
14809
  (args.concurrency ?? args.parallel) !== void 0 ? String(args.concurrency ?? args.parallel) : void 0,
14626
14810
  process.env.BAKER_CANVAS_CONCURRENCY
14627
- )
14811
+ ),
14812
+ onProgress: progress && poster ? (event) => {
14813
+ progress.apply(event);
14814
+ if (progress.hasPlan()) poster.enqueue(progress.snapshot());
14815
+ } : void 0
14628
14816
  });
14817
+ if (poster) await poster.flush(buildRunRecord(result, recordMeta, progress?.planInfo()));
14629
14818
  const keepRuns = args["keep-runs"] !== void 0 ? Number(args["keep-runs"]) : void 0;
14630
14819
  if (keepRuns !== void 0 && Number.isFinite(keepRuns)) {
14631
- const outputsDir = args["outputs-dir"] ? path4.resolve(String(args["outputs-dir"])) : path4.resolve("canvas");
14820
+ const outputsDir = args["outputs-dir"] ? path5.resolve(String(args["outputs-dir"])) : path5.resolve("canvas");
14632
14821
  await pruneOldRuns(outputsDir, keepRuns, result.run_id, (line) => process.stdout.write(`${line}
14633
14822
  `));
14634
14823
  }
@@ -14654,8 +14843,10 @@ var runCommand = defineCommand88({
14654
14843
  );
14655
14844
  process.exit(2);
14656
14845
  }
14846
+ const failedPayload = (message) => progress?.hasPlan() ? progress.failedSnapshot(message) : buildFailedRunRecord(runId, message, recordMeta);
14657
14847
  if (e instanceof LayerExecutionError) {
14658
14848
  const failures = e.failures.map((f) => ({ node_id: f.nodeId, message: describeFailureReason(f.reason) }));
14849
+ if (poster) await poster.flush(failedPayload(e.message));
14659
14850
  process.stderr.write(
14660
14851
  `${JSON.stringify({ ok: false, error: { code: "runtime", message: e.message, failures } }, null, 2)}
14661
14852
  `
@@ -14663,40 +14854,54 @@ var runCommand = defineCommand88({
14663
14854
  process.exit(1);
14664
14855
  }
14665
14856
  const msg = e instanceof Error ? e.message : String(e);
14857
+ if (poster) await poster.flush(failedPayload(msg));
14666
14858
  process.stderr.write(`${JSON.stringify({ ok: false, error: { code: "runtime", message: msg } }, null, 2)}
14667
14859
  `);
14668
14860
  process.exit(1);
14669
14861
  }
14670
14862
  }
14671
14863
  });
14864
+ function buildRecorder() {
14865
+ return async (payload) => {
14866
+ try {
14867
+ const creds = requireCredentialsFromEnv();
14868
+ const client = new BackendClient({ baseUrl: creds.url, apiKey: creds.apiKey });
14869
+ await client.recordRun(payload);
14870
+ } catch (e) {
14871
+ const msg = e instanceof Error ? e.message : String(e);
14872
+ process.stderr.write(`[warn] run record not persisted (${msg})
14873
+ `);
14874
+ }
14875
+ };
14876
+ }
14672
14877
 
14673
14878
  // src/commands/canvas/scaffold-static-ad.ts
14674
- import { readFile as readFile3, writeFile } from "fs/promises";
14675
- import path6 from "path";
14879
+ import { access, cp, mkdir, readFile as readFile3, writeFile } from "fs/promises";
14880
+ import path8 from "path";
14676
14881
  import { defineCommand as defineCommand89 } from "citty";
14677
14882
 
14678
14883
  // src/engine/scaffold/staticAd.ts
14679
- import { z as z12 } from "zod";
14884
+ import { z as z11 } from "zod";
14680
14885
  var GEN_ASPECT_RATIOS = /* @__PURE__ */ new Set(["1:1", "4:5", "9:16", "16:9", "4:3", "3:4", "2:3", "3:2", "21:9"]);
14681
14886
  var DEFAULT_ASPECT_RATIO = "9:16";
14682
- var Blueprint = z12.object({
14683
- meta: z12.object({ estimated_aspect_ratio: z12.string().optional() }).loose().optional(),
14684
- text_content: z12.array(z12.object({ text: z12.string().optional() }).loose()).optional()
14887
+ var Blueprint = z11.object({
14888
+ meta: z11.object({ estimated_aspect_ratio: z11.string().optional() }).loose().optional(),
14889
+ text_content: z11.array(z11.object({ text: z11.string().optional() }).loose()).optional()
14685
14890
  }).loose();
14686
- var ElementLocator = z12.object({
14687
- collection: z12.enum(["subjects", "people", "brands_logos"]),
14688
- index: z12.number().int().nonnegative()
14891
+ var ElementLocator = z11.object({
14892
+ collection: z11.enum(["subjects", "people", "brands_logos"]),
14893
+ index: z11.number().int().nonnegative()
14689
14894
  }).loose();
14690
- var MainElement = z12.object({
14895
+ var MainElement = z11.object({
14691
14896
  // logo | product | person | animal | badge | other
14692
- type: z12.string(),
14693
- label: z12.string().optional(),
14694
- description: z12.string().optional(),
14695
- expression: z12.string().nullable().optional(),
14696
- reason: z12.string().optional(),
14897
+ type: z11.string(),
14898
+ label: z11.string().optional(),
14899
+ description: z11.string().optional(),
14900
+ expression: z11.string().nullable().optional(),
14901
+ reason: z11.string().optional(),
14697
14902
  locator: ElementLocator.optional()
14698
14903
  }).loose();
14699
- var MainElements = z12.array(MainElement);
14904
+ var MainElements = z11.array(MainElement);
14700
14905
  function sanitizeId(raw, fallback) {
14701
14906
  const id = raw.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
14702
14907
  return /^[a-z]/.test(id) ? id : `${fallback}_${id}`.replace(/_+$/g, "") || fallback;
@@ -14858,18 +15063,106 @@ function staticAdReport(input, elementsInput, opts) {
14858
15063
  };
14859
15064
  }
14860
15065
 
15066
+ // src/commands/canvas/creative-definition.ts
15067
+ import path6 from "path";
15068
+ var PLATFORM_VALUES = ["meta", "google", "linkedin", "tiktok", "youtube", "x", "other"];
15069
+ var FORMAT_VALUES = ["1:1", "4:5", "9:16", "16:9", "1.91:1"];
15070
+ function titleFromSlug(slug) {
15071
+ const title = slug.split("-").filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
15072
+ return title || slug;
15073
+ }
15074
+ function resolvePlatform(platform) {
15075
+ const value = platform?.trim();
15076
+ return value && PLATFORM_VALUES.includes(value) ? value : "meta";
15077
+ }
15078
+ function resolveFormats(aspect) {
15079
+ const value = aspect?.trim();
15080
+ return value && FORMAT_VALUES.includes(value) ? [value] : ["4:5"];
15081
+ }
15082
+ function referenceRelativePath(kind, ext) {
15083
+ const name = kind === "video" ? "source" : "original";
15084
+ return `references/${name}${ext}`;
15085
+ }
15086
+ function sourceExtension(source, isUrl, kind) {
15087
+ const raw = isUrl ? urlPathname(source) : source;
15088
+ const ext = path6.extname(raw).toLowerCase();
15089
+ if (/^\.[a-z0-9]{1,5}$/.test(ext)) return ext;
15090
+ return kind === "video" ? ".mp4" : ".jpg";
15091
+ }
15092
+ function urlPathname(source) {
15093
+ try {
15094
+ return new URL(source).pathname;
15095
+ } catch {
15096
+ return source;
15097
+ }
15098
+ }
15099
+ function describeBlueprintIntent(blueprint) {
15100
+ const intent = blueprint?.ad_intent;
15101
+ if (typeof intent === "string" && intent.trim()) return intent.trim();
15102
+ if (intent && typeof intent === "object") {
15103
+ const summary = intent.summary ?? intent.feeling;
15104
+ if (typeof summary === "string" && summary.trim()) return summary.trim();
15105
+ }
15106
+ return void 0;
15107
+ }
15108
+ function yamlScalar(value) {
15109
+ return JSON.stringify(value);
15110
+ }
15111
+ function buildCreativeDefinition(input) {
15112
+ const lines = ["---", `title: ${yamlScalar(input.title)}`, `kind: ${input.kind}`, `platform: ${input.platform}`];
15113
+ lines.push(`formats: [${input.formats.map(yamlScalar).join(", ")}]`);
15114
+ lines.push(`status: ${input.status ?? "draft"}`);
15115
+ if (input.sourceReferenceUrl) lines.push(`sourceReferenceUrl: ${yamlScalar(input.sourceReferenceUrl)}`);
15116
+ if (input.sourceAdvertiser) lines.push(`sourceAdvertiser: ${yamlScalar(input.sourceAdvertiser)}`);
15117
+ if (input.sourceKind) lines.push(`sourceKind: ${input.sourceKind}`);
15118
+ if (input.sourcePath) lines.push(`sourcePath: ${yamlScalar(input.sourcePath)}`);
15119
+ lines.push("---", "");
15120
+ lines.push(input.description?.trim() || `${input.title} \u2014 canvas-built ${input.kind} ad for ${input.platform}.`);
15121
+ lines.push("");
15122
+ return lines.join("\n");
15123
+ }
15124
+
14861
15125
  // src/commands/canvas/scaffold-static-ad-paths.ts
14862
- import path5 from "path";
14863
- function resolveScaffoldStaticAdPaths(rawFile, out, cwd = process.cwd()) {
15126
+ import path7 from "path";
15127
+ function resolveScaffoldStaticAdPaths(rawFile, out, cwd = process.cwd(), slug) {
14864
15128
  const file = rawFile.trim();
14865
15129
  const imageIsUrl = /^https?:\/\//i.test(file);
14866
- const imageSource = imageIsUrl ? file : path5.resolve(cwd, file);
14867
- const outPath = out ? path5.resolve(cwd, out) : imageIsUrl ? path5.join(cwd, "static-ad.canvas.json") : path5.join(path5.dirname(imageSource), "static-ad.canvas.json");
14868
- const blueprintPath = path5.join(path5.dirname(outPath), "prompt.json");
14869
- return { imageIsUrl, imageSource, outPath, blueprintPath };
15130
+ const imageSource = imageIsUrl ? file : path7.resolve(cwd, file);
15131
+ const outPath = out ? path7.resolve(cwd, out) : slug ? path7.join(cwd, "src", "creatives", slug, `${slug}.canvas.json`) : imageIsUrl ? path7.join(cwd, "static-ad.canvas.json") : path7.join(path7.dirname(imageSource), "static-ad.canvas.json");
15132
+ const blueprintPath = path7.join(path7.dirname(outPath), "prompt.json");
15133
+ const creativeDir = slug ? path7.dirname(outPath) : null;
15134
+ const definitionPath = creativeDir ? path7.join(creativeDir, "_definition.md") : null;
15135
+ const referencesDir = creativeDir ? path7.join(creativeDir, "references") : null;
15136
+ return { imageIsUrl, imageSource, outPath, blueprintPath, creativeDir, definitionPath, referencesDir };
15137
+ }
15138
+ var SCAFFOLD_SLUG_PATTERN = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
15139
+ var SCAFFOLD_SLUG_MAX_LENGTH = 100;
15140
+ function isValidScaffoldSlug(slug) {
15141
+ return slug.length <= SCAFFOLD_SLUG_MAX_LENGTH && SCAFFOLD_SLUG_PATTERN.test(slug);
14870
15142
  }
14871
15143
 
14872
15144
  // src/commands/canvas/scaffold-static-ad.ts
15145
+ async function fileExists(target) {
15146
+ try {
15147
+ await access(target);
15148
+ return true;
15149
+ } catch {
15150
+ return false;
15151
+ }
15152
+ }
15153
+ async function copySourceIntoReferences(source, isUrl, referencesDir) {
15154
+ await mkdir(referencesDir, { recursive: true });
15155
+ const relPath = referenceRelativePath("image", sourceExtension(source, isUrl, "image"));
15156
+ const dest = path8.join(referencesDir, path8.basename(relPath));
15157
+ if (isUrl) {
15158
+ const res = await fetch(source);
15159
+ if (!res.ok) throw new Error(`failed to download source image (${res.status})`);
15160
+ await writeFile(dest, Buffer.from(await res.arrayBuffer()));
15161
+ } else {
15162
+ await cp(source, dest);
15163
+ }
15164
+ return relPath;
15165
+ }
14873
15166
  function resolveModel(kind, preferred) {
14874
15167
  const ids = Object.keys(MODEL_REGISTRY[kind]);
14875
15168
  return ids.includes(preferred) ? preferred : ids[0] ?? preferred;
@@ -15029,6 +15322,16 @@ var scaffoldStaticAdCommand = defineCommand89({
15029
15322
  file: { type: "positional", required: true, description: "Path or http(s) URL to the source/inspiration image" },
15030
15323
  context: { type: "string", description: "Known provenance (advertiser, category, market) to ground the describe" },
15031
15324
  out: { type: "string", description: "Output canvas path (default <image-dir>/static-ad.canvas.json)" },
15325
+ slug: {
15326
+ type: "string",
15327
+ description: "Creative slug \u2014 writes the canvas to src/creatives/<slug>/<slug>.canvas.json (repo convention)"
15328
+ },
15329
+ title: { type: "string", description: "Creative title for _definition.md (default: title-cased slug)" },
15330
+ platform: {
15331
+ type: "string",
15332
+ description: "Ad platform for _definition.md (meta|google|linkedin|tiktok|youtube|x|other; default meta)"
15333
+ },
15334
+ advertiser: { type: "string", description: "Source advertiser recorded in _definition.md" },
15032
15335
  "describe-model": { type: "string", description: "Override the image_describe model id" },
15033
15336
  "select-model": { type: "string", description: "Override the text_generate model id for element selection" },
15034
15337
  "layout-model": { type: "string", description: "Override the text_generate model id for the layout pass" },
@@ -15037,10 +15340,21 @@ var scaffoldStaticAdCommand = defineCommand89({
15037
15340
  "skip-font": { type: "boolean", description: "Skip the brand-font \u2192 type-specimen slot" }
15038
15341
  },
15039
15342
  async run({ args }) {
15040
- const { imageIsUrl, imageSource, outPath, blueprintPath } = resolveScaffoldStaticAdPaths(
15343
+ const slug = args.slug ? String(args.slug) : void 0;
15344
+ if (slug && !isValidScaffoldSlug(slug)) {
15345
+ process.stderr.write(
15346
+ `${JSON.stringify({ ok: false, error: { code: "invalid_slug", message: "--slug must be lowercase kebab (a-z, 0-9, hyphens), max 100 chars" } }, null, 2)}
15347
+ `
15348
+ );
15349
+ process.exit(2);
15350
+ }
15351
+ const { imageIsUrl, imageSource, outPath, blueprintPath, definitionPath, referencesDir } = resolveScaffoldStaticAdPaths(
15041
15352
  String(args.file),
15042
- args.out ? String(args.out) : void 0
15353
+ args.out ? String(args.out) : void 0,
15354
+ process.cwd(),
15355
+ slug
15043
15356
  );
15357
+ await mkdir(path8.dirname(outPath), { recursive: true });
15044
15358
  const { describeModel, selectModel, layoutModel, genModel } = resolveModels(args);
15045
15359
  const describeCanvas = buildDescribeCanvas(
15046
15360
  imageSource,
@@ -15057,11 +15371,21 @@ var scaffoldStaticAdCommand = defineCommand89({
15057
15371
  }
15058
15372
  await writeFile(blueprintPath, `${JSON.stringify(annotated, null, 2)}
15059
15373
  `, "utf8");
15374
+ let canvasImagePath = imageSource;
15375
+ let canvasImageIsUrl = imageIsUrl;
15376
+ let canvasBlueprintPath = blueprintPath;
15377
+ let sourceRelPath;
15378
+ if (referencesDir) {
15379
+ sourceRelPath = await copySourceIntoReferences(imageSource, imageIsUrl, referencesDir);
15380
+ canvasImagePath = sourceRelPath;
15381
+ canvasImageIsUrl = false;
15382
+ canvasBlueprintPath = "./prompt.json";
15383
+ }
15060
15384
  const opts = {
15061
15385
  genModel,
15062
- imagePath: imageSource,
15063
- imageIsUrl,
15064
- blueprintPath,
15386
+ imagePath: canvasImagePath,
15387
+ imageIsUrl: canvasImageIsUrl,
15388
+ blueprintPath: canvasBlueprintPath,
15065
15389
  aspectRatio: args.aspect ? String(args.aspect) : void 0,
15066
15390
  includeFont: !args["skip-font"]
15067
15391
  };
@@ -15083,12 +15407,31 @@ var scaffoldStaticAdCommand = defineCommand89({
15083
15407
  }
15084
15408
  await writeFile(outPath, `${JSON.stringify(canvas, null, 2)}
15085
15409
  `, "utf8");
15410
+ if (definitionPath && !await fileExists(definitionPath)) {
15411
+ await writeFile(
15412
+ definitionPath,
15413
+ buildCreativeDefinition({
15414
+ title: args.title ? String(args.title) : titleFromSlug(slug ?? ""),
15415
+ kind: "static",
15416
+ platform: resolvePlatform(args.platform ? String(args.platform) : void 0),
15417
+ formats: resolveFormats(args.aspect ? String(args.aspect) : report.aspect_ratio),
15418
+ sourceReferenceUrl: imageIsUrl ? imageSource : void 0,
15419
+ sourceAdvertiser: args.advertiser ? String(args.advertiser) : args.context ? String(args.context) : void 0,
15420
+ sourceKind: "image",
15421
+ sourcePath: sourceRelPath,
15422
+ description: describeBlueprintIntent(blueprint)
15423
+ }),
15424
+ "utf8"
15425
+ );
15426
+ }
15086
15427
  process.stdout.write(
15087
15428
  `${JSON.stringify(
15088
15429
  {
15089
15430
  ok: true,
15090
15431
  canvas_path: outPath,
15091
15432
  prompt_path: blueprintPath,
15433
+ definition_path: definitionPath ?? void 0,
15434
+ source_reference: sourceRelPath ?? void 0,
15092
15435
  output: canvas.output,
15093
15436
  models: { describe: describeModel, select: selectModel, layout: layoutModel, gen: opts.genModel },
15094
15437
  aspect_ratio: report.aspect_ratio,
@@ -15099,7 +15442,7 @@ var scaffoldStaticAdCommand = defineCommand89({
15099
15442
  run_estimated_credits: validation.estimatedCredits
15100
15443
  },
15101
15444
  checklist: {
15102
- edit_prompt: `Edit ${path6.basename(blueprintPath)} \u2014 it is the blueprint generated from your image; rewrite it into the ad you want (palette, copy, claims, subjects). It feeds the generator directly.`,
15445
+ edit_prompt: `Edit ${path8.basename(blueprintPath)} \u2014 it is the blueprint generated from your image; rewrite it into the ad you want (palette, copy, claims, subjects). It feeds the generator directly.`,
15103
15446
  assets_to_supply: report.elements,
15104
15447
  font_slot: report.includes_font ? "Drop a brand font at the [TODO] brandfont path, or delete the brandfont + type_ref nodes to skip it." : "skipped (--skip-font)",
15105
15448
  note: "Replace every [TODO] ingest path with a real file, then `baker canvas validate` and `baker canvas run`. Running generates a billed image \u2014 it is not free."
@@ -15114,8 +15457,8 @@ var scaffoldStaticAdCommand = defineCommand89({
15114
15457
  });
15115
15458
 
15116
15459
  // src/commands/canvas/scaffold-video.ts
15117
- import { cp, mkdir, readFile as readFile6, writeFile as writeFile2 } from "fs/promises";
15118
- import path9 from "path";
15460
+ import { cp as cp2, mkdir as mkdir2, readFile as readFile6, writeFile as writeFile2 } from "fs/promises";
15461
+ import path11 from "path";
15119
15462
  import { defineCommand as defineCommand90 } from "citty";
15120
15463
 
15121
15464
  // src/engine/nodes/local/lib/sceneDetect.ts
@@ -15232,7 +15575,7 @@ import { toCardinal as nwKo } from "n2words/ko-KR";
15232
15575
  import { toCardinal as nwNl } from "n2words/nl-NL";
15233
15576
  import { toCardinal as nwPl } from "n2words/pl-PL";
15234
15577
  import { toCardinal as nwPt } from "n2words/pt-PT";
15235
- import { z as z13 } from "zod";
15578
+ import { z as z12 } from "zod";
15236
15579
 
15237
15580
  // src/engine/scaffold/lib/shoot-modes.ts
15238
15581
  var SHOOT_MODES = [
@@ -15545,71 +15888,71 @@ function trimArgs(durationS, offsetS = 0, dims) {
15545
15888
  "{{out.video}}"
15546
15889
  ];
15547
15890
  }
15548
- var FrameAsset = z13.object({ url: z13.string().optional() }).loose().optional();
15549
- var DialogueLine = z13.object({
15550
- speaker: z13.string().optional(),
15551
- line: z13.string().optional(),
15891
+ var FrameAsset = z12.object({ url: z12.string().optional() }).loose().optional();
15892
+ var DialogueLine = z12.object({
15893
+ speaker: z12.string().optional(),
15894
+ line: z12.string().optional(),
15552
15895
  // Absolute seconds on the source timeline (the deconstruct emits both).
15553
- start_s: z13.number().optional(),
15554
- end_s: z13.number().optional(),
15555
- delivery: z13.string().optional(),
15556
- voice_description: z13.string().optional(),
15896
+ start_s: z12.number().optional(),
15897
+ end_s: z12.number().optional(),
15898
+ delivery: z12.string().optional(),
15899
+ voice_description: z12.string().optional(),
15557
15900
  // DECON-supplied: is this speaker's FACE visibly speaking in THIS scene? Element
15558
15901
  // presence alone can't answer that — a founder pictured in a polaroid close-up is
15559
15902
  // "present" yet the line is voiceover, and treating it as on-camera produced a
15560
15903
  // native Seedance lip-sync clip of a still photograph. `false` pins the line to
15561
15904
  // the VO path; absent keeps the presence-based decision (old blueprints).
15562
- on_camera: z13.boolean().optional()
15905
+ on_camera: z12.boolean().optional()
15563
15906
  }).loose();
15564
- var Sfx = z13.object({
15565
- at_s: z13.number().optional(),
15566
- duration_s: z13.number().optional(),
15567
- sound_effect_prompt: z13.string().optional(),
15568
- description: z13.string().optional()
15907
+ var Sfx = z12.object({
15908
+ at_s: z12.number().optional(),
15909
+ duration_s: z12.number().optional(),
15910
+ sound_effect_prompt: z12.string().optional(),
15911
+ description: z12.string().optional()
15569
15912
  }).loose();
15570
- var CompositionRegion = z13.object({
15913
+ var CompositionRegion = z12.object({
15571
15914
  // full | top | bottom | left | right | inset
15572
- panel: z13.string().optional(),
15915
+ panel: z12.string().optional(),
15573
15916
  // 9-grid anchor for an `inset` presenter box.
15574
- position: z13.string().optional(),
15575
- is_presenter: z13.boolean().optional(),
15917
+ position: z12.string().optional(),
15918
+ is_presenter: z12.boolean().optional(),
15576
15919
  // The cast id shown/speaking in this region (routes lip-sync + element refs).
15577
- cast_ref: z13.string().optional(),
15920
+ cast_ref: z12.string().optional(),
15578
15921
  // What the region's content IS: camera | screen_capture | static_graphic |
15579
15922
  // generated. Authoritative for routing when present (regex-over-prose fallback
15580
15923
  // otherwise): screen_capture/static_graphic are rebuilt from REAL surfaces on the
15581
15924
  // overlay layer, never AI-generated.
15582
- kind: z13.string().optional(),
15925
+ kind: z12.string().optional(),
15583
15926
  // Opaque id naming the SPECIFIC on-screen document/note/app-state this
15584
15927
  // screen_capture region shows. Two scenes share it only when they show the SAME
15585
15928
  // recording continuing (scrolling/typing/waiting within it) — a genuinely
15586
15929
  // DIFFERENT document/note/recording (a source video splicing two screen captures)
15587
15930
  // gets a different id. Breaks a persistent-layout run into separate surface stubs
15588
15931
  // instead of asking the operator for one screenshot that can't cover both.
15589
- surface_id: z13.string().optional(),
15932
+ surface_id: z12.string().optional(),
15590
15933
  // Camera bubble(s)/inset(s) embedded INSIDE this region's surface (a Loom-style
15591
15934
  // presenter bubble inside a screen recording) — video-in-video the reproduction
15592
15935
  // must re-composite, not paint into the surface.
15593
- nested: z13.array(z13.object({}).loose()).optional(),
15594
- summary: z13.string().optional(),
15595
- frame_prompt: z13.string().optional(),
15596
- motion_prompt: z13.string().optional()
15936
+ nested: z12.array(z12.object({}).loose()).optional(),
15937
+ summary: z12.string().optional(),
15938
+ frame_prompt: z12.string().optional(),
15939
+ motion_prompt: z12.string().optional()
15597
15940
  }).loose();
15598
- var SceneComposition = z13.object({
15941
+ var SceneComposition = z12.object({
15599
15942
  // full_frame (default) | split_screen | pip | keyed_overlay
15600
- layout: z13.string().optional(),
15943
+ layout: z12.string().optional(),
15601
15944
  // split_screen only: vertical (top/bottom) | horizontal (left/right).
15602
- split_axis: z13.string().optional(),
15603
- regions: z13.array(CompositionRegion).optional()
15945
+ split_axis: z12.string().optional(),
15946
+ regions: z12.array(CompositionRegion).optional()
15604
15947
  }).loose();
15605
- var CameraMotion = z13.object({ movement: z13.string().optional(), detail: z13.string().optional() }).loose();
15606
- var TranscriptWord = z13.object({ text: z13.string().optional() }).loose();
15607
- var Scene = z13.object({
15608
- start_s: z13.number().optional(),
15609
- end_s: z13.number().optional(),
15610
- duration_s: z13.number().optional(),
15611
- summary: z13.string().optional(),
15612
- action_detail: z13.string().optional(),
15948
+ var CameraMotion = z12.object({ movement: z12.string().optional(), detail: z12.string().optional() }).loose();
15949
+ var TranscriptWord = z12.object({ text: z12.string().optional() }).loose();
15950
+ var Scene = z12.object({
15951
+ start_s: z12.number().optional(),
15952
+ end_s: z12.number().optional(),
15953
+ duration_s: z12.number().optional(),
15954
+ summary: z12.string().optional(),
15955
+ action_detail: z12.string().optional(),
15613
15956
  // The scene's spatial layout. Absent/full_frame ⇒ one uncut shot (default path).
15614
15957
  // A layered layout (split_screen/pip/keyed_overlay) with regions ⇒ the scaffold
15615
15958
  // builds one clip per region and stacks/overlays them into the scene picture.
@@ -15617,82 +15960,82 @@ var Scene = z13.object({
15617
15960
  // The capture "look" for this scene — selected from the ad-native shoot-mode
15618
15961
  // grammar (see lib/shoot-modes.ts). When absent the scaffold auto-derives a
15619
15962
  // UGC/product mode; a human can override per scene by setting this.
15620
- shoot_mode: z13.string().optional(),
15963
+ shoot_mode: z12.string().optional(),
15621
15964
  // Diegetic ambient the clip's native audio should carry (no music). When
15622
15965
  // absent the scene falls back to its shoot mode's default ambience.
15623
- ambient: z13.string().optional(),
15966
+ ambient: z12.string().optional(),
15624
15967
  camera_motion: CameraMotion.optional(),
15625
- start_frame_prompt: z13.string().optional(),
15626
- end_frame_prompt: z13.string().optional(),
15627
- motion_prompt: z13.string().optional(),
15968
+ start_frame_prompt: z12.string().optional(),
15969
+ end_frame_prompt: z12.string().optional(),
15970
+ motion_prompt: z12.string().optional(),
15628
15971
  // The scene's role in the ad's persuasion arc (DECON-supplied); drives the
15629
15972
  // script re-craft checklist. Inferred from position when absent.
15630
- narrative_role: z13.string().optional(),
15973
+ narrative_role: z12.string().optional(),
15631
15974
  // DECON-supplied on the HOOK scene: the engineered physical/emotional state that
15632
15975
  // makes the first frame stop the scroll (sweaty/breathless/urgent …). Injected
15633
15976
  // into the hook's start-frame description so the generator renders that state,
15634
15977
  // not a calm influencer (CCA-11).
15635
- hook_mechanic: z13.object({ mechanic: z13.string().optional(), why_it_stops_scroll: z13.string().optional() }).loose().optional(),
15978
+ hook_mechanic: z12.object({ mechanic: z12.string().optional(), why_it_stops_scroll: z12.string().optional() }).loose().optional(),
15636
15979
  // DECON-supplied per-scene location (so a gym hook isn't flattened to "home").
15637
- scene_setting: z13.string().optional(),
15980
+ scene_setting: z12.string().optional(),
15638
15981
  // How this scene cuts to the next (DECON-supplied). A recognized non-cut type
15639
15982
  // (fade/whip/zoom/dissolve/swipe) is reproduced as an ffmpeg xfade at the
15640
15983
  // boundary; cut/match_cut/none/other stay hard cuts. The last scene's value is
15641
15984
  // ignored (nothing follows it).
15642
- transition_out: z13.object({ type: z13.string().optional(), description: z13.string().optional() }).loose().optional(),
15643
- dialogue: z13.array(DialogueLine).optional(),
15644
- sfx: z13.array(Sfx).optional(),
15645
- overlays: z13.array(z13.unknown()).optional(),
15646
- floating_elements: z13.array(z13.unknown()).optional(),
15985
+ transition_out: z12.object({ type: z12.string().optional(), description: z12.string().optional() }).loose().optional(),
15986
+ dialogue: z12.array(DialogueLine).optional(),
15987
+ sfx: z12.array(Sfx).optional(),
15988
+ overlays: z12.array(z12.unknown()).optional(),
15989
+ floating_elements: z12.array(z12.unknown()).optional(),
15647
15990
  // DECON-supplied: how much the picture itself moves within the shot. Gates the
15648
15991
  // flash-hold optimization — a sub-2s b-roll flash with REAL subject motion
15649
15992
  // (pouring, spreading, hands working) must stay a real clip; freezing it turns
15650
15993
  // a montage into a slideshow. Absent (old blueprints) keeps the cheap still.
15651
- motion_level: z13.enum(["static", "subtle", "dynamic"]).optional(),
15652
- transcript_slice: z13.array(TranscriptWord).optional(),
15994
+ motion_level: z12.enum(["static", "subtle", "dynamic"]).optional(),
15995
+ transcript_slice: z12.array(TranscriptWord).optional(),
15653
15996
  start_frame_asset: FrameAsset,
15654
15997
  end_frame_asset: FrameAsset,
15655
15998
  // DECON-supplied: true when this scene is a length-split CONTINUATION of the
15656
15999
  // previous one (the SAME physical shot, broken up only because it exceeded the
15657
16000
  // clip ceiling). The scaffold then shares the splice keyframe — this scene's
15658
16001
  // start frame IS the previous scene's end frame — so the join is seamless.
15659
- continues_previous: z13.boolean().optional()
16002
+ continues_previous: z12.boolean().optional()
15660
16003
  }).loose();
15661
- var VideoBlueprint = z13.object({
15662
- source: z13.object({ aspect_ratio: z13.string().optional(), duration_s: z13.number().optional() }).loose().optional(),
15663
- global: z13.object({
15664
- music: z13.object({
15665
- present: z13.boolean().optional(),
15666
- music_prompt: z13.string().optional(),
16004
+ var VideoBlueprint = z12.object({
16005
+ source: z12.object({ aspect_ratio: z12.string().optional(), duration_s: z12.number().optional() }).loose().optional(),
16006
+ global: z12.object({
16007
+ music: z12.object({
16008
+ present: z12.boolean().optional(),
16009
+ music_prompt: z12.string().optional(),
15667
16010
  // Absolute second the music enters in the reference (the bed often
15668
16011
  // kicks in mid-ad, after the hook). We start the regenerated track here
15669
16012
  // instead of at 0 so the timing matches.
15670
- starts_at_s: z13.number().optional(),
16013
+ starts_at_s: z12.number().optional(),
15671
16014
  // Populated by the deconstruct when AudD (Shazam-style) recognizes the
15672
16015
  // reference track. We never reuse it — only style the regenerated bed.
15673
- identified_track: z13.object({ title: z13.string().optional(), artist: z13.string().optional() }).loose().nullish()
16016
+ identified_track: z12.object({ title: z12.string().optional(), artist: z12.string().optional() }).loose().nullish()
15674
16017
  }).loose().optional(),
15675
- cast: z13.array(
15676
- z13.object({
15677
- id: z13.string().optional(),
15678
- description: z13.string().optional(),
16018
+ cast: z12.array(
16019
+ z12.object({
16020
+ id: z12.string().optional(),
16021
+ description: z12.string().optional(),
15679
16022
  // The deconstruct's note on the target-market localization (e.g. "native
15680
16023
  // French speaker") — read to derive the spoken-track language code.
15681
- market_localization_note: z13.string().optional()
16024
+ market_localization_note: z12.string().optional()
15682
16025
  }).loose()
15683
16026
  ).optional(),
15684
- voiceover: z13.object({
16027
+ voiceover: z12.object({
15685
16028
  // on_camera | mixed → mouths are on screen (lip-sync candidates);
15686
16029
  // voiceover | none → narration over the picture (no lip-sync).
15687
- mode: z13.string().optional(),
15688
- voice_description: z13.string().optional(),
15689
- persona: z13.string().optional()
16030
+ mode: z12.string().optional(),
16031
+ voice_description: z12.string().optional(),
16032
+ persona: z12.string().optional()
15690
16033
  }).loose().optional(),
15691
16034
  // Visual palette — read only to colour a clean brand-card/CTA plate (the
15692
16035
  // first hex is the dominant brand colour); never to drive frame generation.
15693
- style: z13.object({ palette: z13.array(z13.object({ hex: z13.string().optional() }).loose()).optional() }).loose().optional()
16036
+ style: z12.object({ palette: z12.array(z12.object({ hex: z12.string().optional() }).loose()).optional() }).loose().optional()
15694
16037
  }).loose().optional(),
15695
- scenes: z13.array(Scene).min(1)
16038
+ scenes: z12.array(Scene).min(1)
15696
16039
  }).loose();
15697
16040
  function injectHookPhysicality(blueprint) {
15698
16041
  for (const scene of blueprint.scenes) {
@@ -15702,26 +16045,26 @@ function injectHookPhysicality(blueprint) {
15702
16045
  scene.start_frame_prompt = `${prompt} The subject's physical state IS the scroll-stopper \u2014 render it explicitly, not a calm pose: ${why}.`;
15703
16046
  }
15704
16047
  }
15705
- var AppearsItem = z13.union([z13.number(), z13.object({ scene: z13.number(), edge: z13.string().optional() }).loose()]);
15706
- var RecurringElement = z13.object({
16048
+ var AppearsItem = z12.union([z12.number(), z12.object({ scene: z12.number(), edge: z12.string().optional() }).loose()]);
16049
+ var RecurringElement = z12.object({
15707
16050
  // person | animal | product | logo | badge | other
15708
- type: z13.string(),
15709
- label: z13.string().optional(),
15710
- description: z13.string().optional(),
15711
- expression: z13.string().nullable().optional(),
16051
+ type: z12.string(),
16052
+ label: z12.string().optional(),
16053
+ description: z12.string().optional(),
16054
+ expression: z12.string().nullable().optional(),
15712
16055
  // When the element maps to a global cast entry, its stable id (for annotation).
15713
- cast_id: z13.string().nullable().optional(),
16056
+ cast_id: z12.string().nullable().optional(),
15714
16057
  // The label of another element that is the SAME individual as this one, shown
15715
16058
  // in a DIFFERENT wardrobe/persona/state (e.g. one creator playing skeptic in a
15716
16059
  // pink shirt and believer in a white shirt). Each look gets its own reference
15717
16060
  // slot, but the face/identity must stay identical across them.
15718
- same_as: z13.string().nullable().optional(),
16061
+ same_as: z12.string().nullable().optional(),
15719
16062
  // Scenes the element appears in. Either a bare list of scene indices (both
15720
16063
  // edges) or per-{scene,edge} entries. Both forms are accepted and merged.
15721
- scenes: z13.array(z13.number()).optional(),
15722
- appears_in: z13.array(AppearsItem).optional()
16064
+ scenes: z12.array(z12.number()).optional(),
16065
+ appears_in: z12.array(AppearsItem).optional()
15723
16066
  }).loose();
15724
- var RecurringElements = z13.array(RecurringElement);
16067
+ var RecurringElements = z12.array(RecurringElement);
15725
16068
  function sanitizeId2(raw, fallback) {
15726
16069
  const id = raw.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
15727
16070
  return /^[a-z]/.test(id) ? id : `${fallback}_${id}`.replace(/_+$/g, "") || fallback;
@@ -16139,7 +16482,7 @@ function scrubFloatSentences(text, floatDescs) {
16139
16482
  return kept;
16140
16483
  }
16141
16484
  function sceneFloatDescs(scene) {
16142
- const floats = z13.array(FloatingElement).safeParse(scene.floating_elements ?? []);
16485
+ const floats = z12.array(FloatingElement).safeParse(scene.floating_elements ?? []);
16143
16486
  if (!floats.success) return [];
16144
16487
  return floats.data.map((f) => f.description?.trim() ?? "").filter(Boolean);
16145
16488
  }
@@ -17479,25 +17822,25 @@ function buildSfxMusic(blueprint, nodes) {
17479
17822
  }
17480
17823
  return tracks;
17481
17824
  }
17482
- var OverlayStyle = z13.object({ color_hex: z13.string().optional(), background: z13.string().optional(), size: z13.string().optional() }).loose();
17483
- var Overlay = z13.object({
17484
- text: z13.string().optional(),
17485
- appears_at_s: z13.number().optional(),
17486
- duration_s: z13.number().optional(),
17487
- position: z13.string().optional(),
17488
- role: z13.string().optional(),
17489
- animation: z13.string().optional(),
17490
- animation_detail: z13.string().optional(),
17825
+ var OverlayStyle = z12.object({ color_hex: z12.string().optional(), background: z12.string().optional(), size: z12.string().optional() }).loose();
17826
+ var Overlay = z12.object({
17827
+ text: z12.string().optional(),
17828
+ appears_at_s: z12.number().optional(),
17829
+ duration_s: z12.number().optional(),
17830
+ position: z12.string().optional(),
17831
+ role: z12.string().optional(),
17832
+ animation: z12.string().optional(),
17833
+ animation_detail: z12.string().optional(),
17491
17834
  style: OverlayStyle.optional()
17492
17835
  }).loose();
17493
- var FloatingElement = z13.object({
17494
- kind: z13.string().optional(),
17495
- description: z13.string().optional(),
17496
- brand_name: z13.string().nullish(),
17497
- what_it_represents: z13.string().optional(),
17498
- appears_at_s: z13.number().optional(),
17499
- duration_s: z13.number().optional(),
17500
- position: z13.string().optional()
17836
+ var FloatingElement = z12.object({
17837
+ kind: z12.string().optional(),
17838
+ description: z12.string().optional(),
17839
+ brand_name: z12.string().nullish(),
17840
+ what_it_represents: z12.string().optional(),
17841
+ appears_at_s: z12.number().optional(),
17842
+ duration_s: z12.number().optional(),
17843
+ position: z12.string().optional()
17501
17844
  }).loose();
17502
17845
  function escapeHtml(s) {
17503
17846
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
@@ -17529,7 +17872,7 @@ function positionClass(position) {
17529
17872
  function collectCaptions(blueprint) {
17530
17873
  return blueprint.scenes.flatMap((scene) => {
17531
17874
  const sceneStart = scene.start_s ?? 0;
17532
- const overlays = z13.array(Overlay).safeParse(scene.overlays ?? []);
17875
+ const overlays = z12.array(Overlay).safeParse(scene.overlays ?? []);
17533
17876
  return overlays.success ? overlays.data.filter((ov) => Boolean(ov.text?.trim())).map((ov) => {
17534
17877
  const at = ov.appears_at_s ?? sceneStart;
17535
17878
  return { text: ov.text.trim(), at, end: at + (ov.duration_s ?? 2.5), ov };
@@ -17609,7 +17952,7 @@ function collectFloatWindows(blueprint, uiRouted) {
17609
17952
  const windows = /* @__PURE__ */ new Map();
17610
17953
  blueprint.scenes.forEach((scene, i) => {
17611
17954
  const sceneStart = scene.start_s ?? 0;
17612
- const floats = z13.array(FloatingElement).safeParse(scene.floating_elements ?? []);
17955
+ const floats = z12.array(FloatingElement).safeParse(scene.floating_elements ?? []);
17613
17956
  if (!floats.success) return;
17614
17957
  for (const fe of floats.data) {
17615
17958
  const at = fe.appears_at_s ?? sceneStart;
@@ -17995,8 +18338,8 @@ function buildMotionBoard(blueprint) {
17995
18338
  const end_s = scene.end_s ?? start_s + sceneDurationS(scene);
17996
18339
  cursor = end_s;
17997
18340
  const spoken = sceneSpokenText(scene);
17998
- const overlays = z13.array(Overlay).safeParse(scene.overlays ?? []);
17999
- const floats = z13.array(FloatingElement).safeParse(scene.floating_elements ?? []);
18341
+ const overlays = z12.array(Overlay).safeParse(scene.overlays ?? []);
18342
+ const floats = z12.array(FloatingElement).safeParse(scene.floating_elements ?? []);
18000
18343
  const graphics = [
18001
18344
  ...(overlays.success ? overlays.data : []).filter((ov) => ov.text?.trim()).map((ov) => ({
18002
18345
  kind: "text",
@@ -18223,23 +18566,23 @@ function videoReport(input, elementsInput) {
18223
18566
 
18224
18567
  // src/commands/canvas/composition-path.ts
18225
18568
  import { existsSync as existsSync3 } from "fs";
18226
- import path7 from "path";
18569
+ import path9 from "path";
18227
18570
  function resolveShippedCanvasDir(name, startDir, exists = existsSync3, maxDepth = 8) {
18228
- const rel = path7.join("canvas", name);
18571
+ const rel = path9.join("canvas", name);
18229
18572
  let dir = startDir;
18230
18573
  for (let i = 0; i < maxDepth; i++) {
18231
- const candidate = path7.join(dir, rel);
18232
- if (exists(path7.join(candidate, "meta.json"))) return candidate;
18233
- const parent = path7.dirname(dir);
18574
+ const candidate = path9.join(dir, rel);
18575
+ if (exists(path9.join(candidate, "meta.json"))) return candidate;
18576
+ const parent = path9.dirname(dir);
18234
18577
  if (parent === dir) break;
18235
18578
  dir = parent;
18236
18579
  }
18237
- return path7.resolve(startDir, "../../../", rel);
18580
+ return path9.resolve(startDir, "../../../", rel);
18238
18581
  }
18239
18582
 
18240
18583
  // src/commands/canvas/gitignore.ts
18241
18584
  import { appendFile, readFile as readFile5 } from "fs/promises";
18242
- import path8 from "path";
18585
+ import path10 from "path";
18243
18586
  function missingGitignoreEntries(existing, entries) {
18244
18587
  const present = new Set(
18245
18588
  existing.split("\n").map((l) => l.trim().replace(/\/+$/, "")).filter((l) => l.length > 0 && !l.startsWith("#"))
@@ -18247,7 +18590,7 @@ function missingGitignoreEntries(existing, entries) {
18247
18590
  return entries.filter((e) => !present.has(e.trim().replace(/\/+$/, "")));
18248
18591
  }
18249
18592
  async function ensureGitignore(dir, entries) {
18250
- const file = path8.join(dir, ".gitignore");
18593
+ const file = path10.join(dir, ".gitignore");
18251
18594
  let existing;
18252
18595
  try {
18253
18596
  existing = await readFile5(file, "utf8");
@@ -18308,8 +18651,8 @@ async function loadTranscriptBestEffort(ref) {
18308
18651
  async function stageCaptions(outDir, transcript) {
18309
18652
  const text = transcript?.trim();
18310
18653
  if (!text || text === "[]") return {};
18311
- const compositionPath = path9.join(outDir, "tiktok-captions-composition");
18312
- await cp(SHIPPED_CAPTIONS_DIR, compositionPath, { recursive: true });
18654
+ const compositionPath = path11.join(outDir, "tiktok-captions-composition");
18655
+ await cp2(SHIPPED_CAPTIONS_DIR, compositionPath, { recursive: true });
18313
18656
  return { compositionPath };
18314
18657
  }
18315
18658
  function patchCompositionMeta(metaJson, dims) {
@@ -18326,10 +18669,10 @@ function patchCompositionHtml(html, dims) {
18326
18669
  return html.replace(/(<meta\s+name="viewport"\s+content="width=)\d+(,\s*height=)\d+(")/i, `$1${dims.w}$2${dims.h}$3`).replace(/(width:\s*)\d+(px;\s*height:\s*)\d+(px;)/i, `$1${dims.w}$2${dims.h}$3`).replace(/(data-width=")\d+(")/i, `$1${dims.w}$2`).replace(/(data-height=")\d+(")/i, `$1${dims.h}$2`);
18327
18670
  }
18328
18671
  async function stampCompositionDims(compositionDir, dims) {
18329
- const metaPath = path9.join(compositionDir, "meta.json");
18672
+ const metaPath = path11.join(compositionDir, "meta.json");
18330
18673
  const rawMeta = await readFile6(metaPath, "utf8");
18331
18674
  await writeFile2(metaPath, patchCompositionMeta(rawMeta, dims), "utf8");
18332
- const htmlPath = path9.join(compositionDir, "index.html");
18675
+ const htmlPath = path11.join(compositionDir, "index.html");
18333
18676
  const rawHtml = await readFile6(htmlPath, "utf8");
18334
18677
  await writeFile2(htmlPath, patchCompositionHtml(rawHtml, dims), "utf8");
18335
18678
  }
@@ -18469,6 +18812,10 @@ var scaffoldVideoCommand = defineCommand90({
18469
18812
  args: {
18470
18813
  file: { type: "positional", required: true, description: "Path to the reference video" },
18471
18814
  out: { type: "string", description: "Output canvas path (default <video-dir>/<name>.video.canvas.json)" },
18815
+ slug: {
18816
+ type: "string",
18817
+ description: "Creative slug \u2014 writes the canvas to src/creatives/<slug>/<slug>.canvas.json (repo convention)"
18818
+ },
18472
18819
  frames: { type: "string", description: '"generate" (default, anchored regen) or "reuse" (wire real frames in)' },
18473
18820
  ambient: {
18474
18821
  type: "boolean",
@@ -18495,11 +18842,19 @@ var scaffoldVideoCommand = defineCommand90({
18495
18842
  }
18496
18843
  },
18497
18844
  async run({ args }) {
18498
- const videoPath = path9.resolve(String(args.file));
18499
- const base = path9.basename(videoPath, path9.extname(videoPath));
18500
- const outPath = args.out ? path9.resolve(String(args.out)) : path9.join(path9.dirname(videoPath), `${base}.video.canvas.json`);
18501
- const outDir = path9.dirname(outPath);
18502
- const blueprintPath = path9.join(outDir, "prompt.json");
18845
+ const videoPath = path11.resolve(String(args.file));
18846
+ const base = path11.basename(videoPath, path11.extname(videoPath));
18847
+ const slug = args.slug ? String(args.slug) : void 0;
18848
+ if (slug && !isValidScaffoldSlug(slug)) {
18849
+ process.stderr.write(
18850
+ `${JSON.stringify({ ok: false, error: { code: "invalid_slug", message: "--slug must be lowercase kebab (a-z, 0-9, hyphens), max 100 chars" } }, null, 2)}
18851
+ `
18852
+ );
18853
+ process.exit(2);
18854
+ }
18855
+ const outPath = args.out ? path11.resolve(String(args.out)) : slug ? path11.join(process.cwd(), "src", "creatives", slug, `${slug}.canvas.json`) : path11.join(path11.dirname(videoPath), `${base}.video.canvas.json`);
18856
+ const outDir = path11.dirname(outPath);
18857
+ const blueprintPath = path11.join(outDir, "prompt.json");
18503
18858
  const frames = args.frames === "reuse" ? "reuse" : "generate";
18504
18859
  const maxScenes = args["max-scenes"] ? Number(args["max-scenes"]) : void 0;
18505
18860
  if (Number.isFinite(maxScenes)) {
@@ -18518,7 +18873,7 @@ var scaffoldVideoCommand = defineCommand90({
18518
18873
  shotCuts
18519
18874
  });
18520
18875
  const { blueprint, elements, transcript, creditsSpent } = await runAnalysisPasses(deconstructCanvas, selectModel);
18521
- await mkdir(outDir, { recursive: true });
18876
+ await mkdir2(outDir, { recursive: true });
18522
18877
  const annotated = annotateBlueprintWithElements(blueprint, elements);
18523
18878
  await writeFile2(blueprintPath, `${JSON.stringify(annotated, null, 2)}
18524
18879
  `, "utf8");
@@ -18539,10 +18894,10 @@ var scaffoldVideoCommand = defineCommand90({
18539
18894
  `
18540
18895
  );
18541
18896
  }
18542
- const compositionDest = path9.join(outDir, "video-overlay-composition");
18543
- await cp(SHIPPED_COMPOSITION_DIR, compositionDest, { recursive: true });
18897
+ const compositionDest = path11.join(outDir, "video-overlay-composition");
18898
+ await cp2(SHIPPED_COMPOSITION_DIR, compositionDest, { recursive: true });
18544
18899
  await stampCompositionDims(compositionDest, outDims);
18545
- const indexPath = path9.join(compositionDest, "index.html");
18900
+ const indexPath = path11.join(compositionDest, "index.html");
18546
18901
  const overlayHtml = buildOverlayHtml(blueprint, { captionsActive: Boolean(transcript) });
18547
18902
  const indexHtml = await readFile6(indexPath, "utf8");
18548
18903
  const injected = indexHtml.replace("<!--OVERLAYS-->", () => overlayHtml);
@@ -18558,9 +18913,9 @@ var scaffoldVideoCommand = defineCommand90({
18558
18913
  const opts = {
18559
18914
  imageModel,
18560
18915
  videoModel,
18561
- overlayCompositionPath: path9.relative(outDir, compositionDest),
18562
- captionsCompositionPath: captions.compositionPath ? path9.relative(outDir, captions.compositionPath) : void 0,
18563
- blueprintPath: path9.relative(outDir, blueprintPath),
18916
+ overlayCompositionPath: path11.relative(outDir, compositionDest),
18917
+ captionsCompositionPath: captions.compositionPath ? path11.relative(outDir, captions.compositionPath) : void 0,
18918
+ blueprintPath: path11.relative(outDir, blueprintPath),
18564
18919
  frames,
18565
18920
  ambient: Boolean(args.ambient),
18566
18921
  ...args.aspect ? { aspect: String(args.aspect) } : {},
@@ -18618,7 +18973,7 @@ var scaffoldVideoCommand = defineCommand90({
18618
18973
  run_estimated_credits: validation.estimatedCredits
18619
18974
  },
18620
18975
  checklist: {
18621
- edit_prompt: `Edit ${path9.basename(blueprintPath)} \u2014 the blueprint deconstructed from your video; rewrite it into the ad you want (cast, palette, copy, claims). Every scene frame reads it via target_blueprint.`,
18976
+ edit_prompt: `Edit ${path11.basename(blueprintPath)} \u2014 the blueprint deconstructed from your video; rewrite it into the ad you want (cast, palette, copy, claims). Every scene frame reads it via target_blueprint.`,
18622
18977
  recurring_elements_to_supply: report.elements,
18623
18978
  voices_to_confirm: report.dialogue.map((d) => ({
18624
18979
  scene: d.scene,
@@ -18645,7 +19000,7 @@ var scaffoldVideoCommand = defineCommand90({
18645
19000
 
18646
19001
  // src/commands/canvas/set-prompt.ts
18647
19002
  import { readFile as readFile7, writeFile as writeFile3 } from "fs/promises";
18648
- import path10 from "path";
19003
+ import path12 from "path";
18649
19004
  import { defineCommand as defineCommand91 } from "citty";
18650
19005
  function setNodePrompt(canvas, nodeId, text) {
18651
19006
  const nodes = canvas?.nodes;
@@ -18673,7 +19028,7 @@ var setPromptCommand = defineCommand91({
18673
19028
  "text-file": { type: "string", description: "Read the new prompt from a UTF-8 file (preserves accents/newlines)" }
18674
19029
  },
18675
19030
  async run({ args }) {
18676
- const filePath = path10.resolve(String(args.file));
19031
+ const filePath = path12.resolve(String(args.file));
18677
19032
  let canvas;
18678
19033
  try {
18679
19034
  canvas = JSON.parse(await readFile7(filePath, "utf8"));
@@ -18683,7 +19038,7 @@ var setPromptCommand = defineCommand91({
18683
19038
  process.exit(2);
18684
19039
  }
18685
19040
  let text;
18686
- if (args["text-file"]) text = await readFile7(path10.resolve(String(args["text-file"])), "utf8");
19041
+ if (args["text-file"]) text = await readFile7(path12.resolve(String(args["text-file"])), "utf8");
18687
19042
  else if (args.text !== void 0) text = String(args.text);
18688
19043
  else {
18689
19044
  process.stderr.write(
@@ -18704,7 +19059,7 @@ var setPromptCommand = defineCommand91({
18704
19059
  process.exit(2);
18705
19060
  return;
18706
19061
  }
18707
- const validation = await validateCanvasDeep(resolveRelativeCanvasPaths(updated, path10.dirname(filePath)), defaultRegistry());
19062
+ const validation = await validateCanvasDeep(resolveRelativeCanvasPaths(updated, path12.dirname(filePath)), defaultRegistry());
18708
19063
  if (!validation.ok) {
18709
19064
  process.stderr.write(`${JSON.stringify({ ok: false, error: { code: "validation", issues: validation.issues } }, null, 2)}
18710
19065
  `);
@@ -18720,7 +19075,7 @@ var setPromptCommand = defineCommand91({
18720
19075
 
18721
19076
  // src/commands/canvas/validate.ts
18722
19077
  import { readFile as readFile8 } from "fs/promises";
18723
- import path11 from "path";
19078
+ import path13 from "path";
18724
19079
  import { defineCommand as defineCommand92 } from "citty";
18725
19080
  var validateCommand = defineCommand92({
18726
19081
  meta: {
@@ -18729,7 +19084,7 @@ var validateCommand = defineCommand92({
18729
19084
  },
18730
19085
  args: { file: { type: "positional", required: true, description: "Path to canvas JSON" } },
18731
19086
  async run({ args }) {
18732
- const filePath = path11.resolve(String(args.file));
19087
+ const filePath = path13.resolve(String(args.file));
18733
19088
  const raw = await readFile8(filePath, "utf8");
18734
19089
  let parsed;
18735
19090
  try {
@@ -18740,7 +19095,7 @@ var validateCommand = defineCommand92({
18740
19095
  `);
18741
19096
  process.exit(2);
18742
19097
  }
18743
- parsed = resolveRelativeCanvasPaths(parsed, path11.dirname(filePath));
19098
+ parsed = resolveRelativeCanvasPaths(parsed, path13.dirname(filePath));
18744
19099
  const result = await validateCanvasDeep(parsed, defaultRegistry());
18745
19100
  if (!result.ok) {
18746
19101
  process.stderr.write(`${JSON.stringify({ ok: false, issues: result.issues }, null, 2)}
@@ -18877,6 +19232,16 @@ registerSchema({
18877
19232
  type: "string",
18878
19233
  description: "Optional URL of the original reference ad",
18879
19234
  required: false
19235
+ },
19236
+ slug: {
19237
+ type: "string",
19238
+ description: "Creative slug (src/creatives/<slug>/) \u2014 attaches the image to that creative's row",
19239
+ required: false
19240
+ },
19241
+ runId: {
19242
+ type: "string",
19243
+ description: "Canvas run id (r_\u2026) of the approved generation to pin as published",
19244
+ required: false
18880
19245
  }
18881
19246
  }
18882
19247
  });
@@ -18886,6 +19251,13 @@ function detectCreativeContentType(filePath) {
18886
19251
  unsupportedMessage: "Unsupported creative image extension. Use PNG, JPG, or WebP."
18887
19252
  });
18888
19253
  }
19254
+ function chatIdFromEnv() {
19255
+ try {
19256
+ return getEnv().BAKER_CHAT_ID || void 0;
19257
+ } catch {
19258
+ return void 0;
19259
+ }
19260
+ }
18889
19261
  function parseOptionalUrl(value) {
18890
19262
  if (value === void 0 || value.trim() === "") {
18891
19263
  return void 0;
@@ -18916,7 +19288,11 @@ async function publishCreative(args, deps = defaultImageApiDeps) {
18916
19288
  return publishImageAsCreative(deps, {
18917
19289
  imageId: upload.imageId,
18918
19290
  title,
18919
- sourceReferenceUrl
19291
+ sourceReferenceUrl,
19292
+ slug: args.slug,
19293
+ runId: args.runId,
19294
+ // Attribute the publish to the driving chat (injected by the bridge).
19295
+ chatId: chatIdFromEnv()
18920
19296
  });
18921
19297
  }
18922
19298
  var publishCommand = defineCommand94({
@@ -18932,6 +19308,16 @@ var publishCommand = defineCommand94({
18932
19308
  type: "string",
18933
19309
  description: "Optional URL of the original reference ad",
18934
19310
  required: false
19311
+ },
19312
+ slug: {
19313
+ type: "string",
19314
+ description: "Creative slug (src/creatives/<slug>/) \u2014 attaches the image to that creative's row",
19315
+ required: false
19316
+ },
19317
+ runId: {
19318
+ type: "string",
19319
+ description: "Canvas run id (r_\u2026) of the approved generation to pin as published",
19320
+ required: false
18935
19321
  }
18936
19322
  },
18937
19323
  run: async ({ args }) => {
@@ -18950,7 +19336,9 @@ var publishCommand = defineCommand94({
18950
19336
  file,
18951
19337
  title,
18952
19338
  context: args.context,
18953
- sourceReferenceUrl: args.sourceReferenceUrl
19339
+ sourceReferenceUrl: args.sourceReferenceUrl,
19340
+ slug: args.slug,
19341
+ runId: args.runId
18954
19342
  });
18955
19343
  writeJson({ ok: true, data });
18956
19344
  } catch (err) {
@@ -19848,9 +20236,9 @@ async function readImageBuffer(pathOrUrl) {
19848
20236
  }
19849
20237
  return readFile10(pathOrUrl);
19850
20238
  }
19851
- async function isDirectory(path12) {
20239
+ async function isDirectory(path14) {
19852
20240
  try {
19853
- const s = await stat2(path12);
20241
+ const s = await stat2(path14);
19854
20242
  return s.isDirectory();
19855
20243
  } catch {
19856
20244
  return false;
@@ -23912,121 +24300,11 @@ var schemaCommand = defineCommand147({
23912
24300
  }
23913
24301
  });
23914
24302
 
23915
- // src/commands/tags/index.ts
23916
- import { defineCommand as defineCommand148 } from "citty";
23917
-
23918
- // src/commands/tags/shared.ts
23919
- function failApi3(err) {
23920
- if (err instanceof ApiError) {
23921
- writeJson({ ok: false, error: { code: err.code, message: err.message } });
23922
- process.exit(1);
23923
- }
23924
- if (err instanceof Error) {
23925
- writeJson({ ok: false, error: { code: "INTERNAL_ERROR", message: err.message } });
23926
- process.exit(1);
23927
- }
23928
- writeJson({ ok: false, error: { code: "INTERNAL_ERROR", message: "Unexpected error" } });
23929
- process.exit(1);
23930
- }
23931
- function renderEffectiveEntry(entry) {
23932
- const parts = [entry.ref, entry.type];
23933
- if (entry.identifier !== void 0) {
23934
- parts.push(entry.identifier);
23935
- }
23936
- if (entry.staged !== void 0) {
23937
- parts.push(`[staged: ${entry.staged}]`);
23938
- }
23939
- const secretBits = [
23940
- ...entry.secretsSet.map((field) => `${field} \u2713 set`),
23941
- ...entry.secretsPending.map((field) => `${field} \u23F3 pending`)
23942
- ];
23943
- if (secretBits.length > 0) {
23944
- parts.push(`[secrets: ${secretBits.join(", ")}]`);
23945
- }
23946
- return parts.join(" ");
23947
- }
23948
-
23949
- // src/commands/tags/index.ts
23950
- registerSchema({
23951
- command: "tags.list",
23952
- description: "Effective marketing tags for this chat: production tags overlaid with the changes staged in this chat. The printed refs (tag ids or tag_temp_*) are exactly what flow side-effect tagIds should reference. Read-only \u2014 every tag change (create, edit, delete) goes through the request_tag_input approval tool.",
23953
- args: {
23954
- json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list", required: false }
23955
- }
23956
- });
23957
- async function listTags(json) {
23958
- try {
23959
- const chatId = requireChatId();
23960
- const response = await apiPost("/api/tags/list", { chatId });
23961
- if (json) {
23962
- writeJson({ ok: true, data: response });
23963
- return;
23964
- }
23965
- if (response.tags.length === 0) {
23966
- process.stdout.write("No tags configured. Propose one with the request_tag_input tool (baker_ui).\n");
23967
- return;
23968
- }
23969
- process.stdout.write(`${response.tags.map(renderEffectiveEntry).join("\n")}
23970
- `);
23971
- } catch (err) {
23972
- failApi3(err);
23973
- }
23974
- }
23975
- var listCommand7 = defineCommand148({
23976
- meta: {
23977
- name: "list",
23978
- description: "Effective tags for this chat (production + staged). Refs printed here are what flow side-effect tagIds should use. Example: baker tags list"
23979
- },
23980
- args: { json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list" } },
23981
- run: async ({ args }) => {
23982
- await listTags(args.json === true);
23983
- }
23984
- });
23985
- async function listDraft3() {
23986
- try {
23987
- const chatId = requireChatId();
23988
- const response = await apiPost("/api/tags/draft", { chatId });
23989
- writeJson({ ok: true, data: response });
23990
- } catch (err) {
23991
- failApi3(err);
23992
- }
23993
- }
23994
- var draftCommand3 = defineCommand148({
23995
- meta: {
23996
- name: "draft",
23997
- description: "Review the tag changes staged in this chat (read-only). Staged changes were approved via request_tag_input and apply when the chat is published; to amend or drop one, propose a follow-up change through the same tool (a delete on a tag_temp_* ref drops the staged create)."
23998
- },
23999
- run: async () => {
24000
- await listDraft3();
24001
- }
24002
- });
24003
- var tagsCommand3 = defineCommand148({
24004
- meta: {
24005
- name: "tags",
24006
- description: `Read the client's marketing/analytics tags (Meta pixel, GA4, Google Ads, GTM, Clarity, Hotjar, \u2026) \u2014 production tags plus the changes staged in this chat.
24007
-
24008
- This command is READ-ONLY. Every tag change \u2014 create, edit, or delete \u2014 goes through the request_tag_input tool (baker_ui MCP server): propose one or more changes (each becomes a tab in one approval form), pre-fill the non-secret fields you know, and the user reviews, fills secrets, and approves or skips each. Secret values (accessToken, apiSecret, authorizationToken, apiKey, conversionToken, OAuth connections) never pass through the CLI or the chat.
24009
-
24010
- Refs: \`baker tags list\` prints each tag's ref \u2014 a real tag id, or tag_temp_* for creates staged in this chat. Use these refs as flow side-effect tagIds; they keep resolving after publish.
24011
-
24012
- Examples:
24013
- baker tags list # production + staged, with secret status
24014
- baker tags draft # review the staged changes awaiting publish`
24015
- },
24016
- subCommands: {
24017
- list: listCommand7,
24018
- draft: draftCommand3
24019
- },
24020
- run: async () => {
24021
- await listTags(false);
24022
- }
24023
- });
24024
-
24025
24303
  // src/commands/testimonials/index.ts
24026
- import { defineCommand as defineCommand152 } from "citty";
24304
+ import { defineCommand as defineCommand151 } from "citty";
24027
24305
 
24028
24306
  // src/commands/testimonials/get.ts
24029
- import { defineCommand as defineCommand149 } from "citty";
24307
+ import { defineCommand as defineCommand148 } from "citty";
24030
24308
  registerSchema({
24031
24309
  command: "testimonials.get",
24032
24310
  description: "Get a single testimonial by ID",
@@ -24034,7 +24312,7 @@ registerSchema({
24034
24312
  id: { type: "string", description: "Testimonial ID", required: true }
24035
24313
  }
24036
24314
  });
24037
- var getCommand4 = defineCommand149({
24315
+ var getCommand4 = defineCommand148({
24038
24316
  meta: { name: "get", description: "Get a single testimonial by ID. Example: baker testimonials get j571abc123" },
24039
24317
  args: {
24040
24318
  id: { type: "positional", description: "Testimonial ID", required: false },
@@ -24071,7 +24349,7 @@ var getCommand4 = defineCommand149({
24071
24349
  });
24072
24350
 
24073
24351
  // src/commands/testimonials/list.ts
24074
- import { defineCommand as defineCommand150 } from "citty";
24352
+ import { defineCommand as defineCommand149 } from "citty";
24075
24353
  registerSchema({
24076
24354
  command: "testimonials.list",
24077
24355
  description: "List testimonials with optional filters.",
@@ -24101,7 +24379,7 @@ registerSchema({
24101
24379
  limit: { type: "number", description: "Max results (default 50)", required: false, default: 50 }
24102
24380
  }
24103
24381
  });
24104
- var listCommand8 = defineCommand150({
24382
+ var listCommand7 = defineCommand149({
24105
24383
  meta: {
24106
24384
  name: "list",
24107
24385
  description: "List testimonials with optional filters. Example: baker testimonials list --source google --sentiment positive"
@@ -24150,7 +24428,7 @@ var listCommand8 = defineCommand150({
24150
24428
  });
24151
24429
 
24152
24430
  // src/commands/testimonials/search.ts
24153
- import { defineCommand as defineCommand151 } from "citty";
24431
+ import { defineCommand as defineCommand150 } from "citty";
24154
24432
  registerSchema({
24155
24433
  command: "testimonials.search",
24156
24434
  description: "Search testimonials by text query. Uses hybrid BM25 + vector + reranking.",
@@ -24181,7 +24459,7 @@ registerSchema({
24181
24459
  tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
24182
24460
  }
24183
24461
  });
24184
- var searchCommand2 = defineCommand151({
24462
+ var searchCommand2 = defineCommand150({
24185
24463
  meta: {
24186
24464
  name: "search",
24187
24465
  description: "Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4"
@@ -24252,10 +24530,10 @@ var searchCommand2 = defineCommand151({
24252
24530
  });
24253
24531
 
24254
24532
  // src/commands/testimonials/tags.ts
24255
- var tagsCommand4 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
24533
+ var tagsCommand3 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
24256
24534
 
24257
24535
  // src/commands/testimonials/index.ts
24258
- var testimonialsCommand = defineCommand152({
24536
+ var testimonialsCommand = defineCommand151({
24259
24537
  meta: {
24260
24538
  name: "testimonials",
24261
24539
  description: `Find and browse testimonials in Baker. Subcommands: search, get, list, tags.
@@ -24270,16 +24548,16 @@ Examples:
24270
24548
  subCommands: {
24271
24549
  get: getCommand4,
24272
24550
  search: searchCommand2,
24273
- list: listCommand8,
24274
- tags: tagsCommand4
24551
+ list: listCommand7,
24552
+ tags: tagsCommand3
24275
24553
  }
24276
24554
  });
24277
24555
 
24278
24556
  // src/commands/videos/index.ts
24279
- import { defineCommand as defineCommand157 } from "citty";
24557
+ import { defineCommand as defineCommand156 } from "citty";
24280
24558
 
24281
24559
  // src/commands/videos/delete.ts
24282
- import { defineCommand as defineCommand153 } from "citty";
24560
+ import { defineCommand as defineCommand152 } from "citty";
24283
24561
  registerSchema({
24284
24562
  command: "videos.delete",
24285
24563
  description: "Delete a video by ID",
@@ -24293,7 +24571,7 @@ registerSchema({
24293
24571
  }
24294
24572
  }
24295
24573
  });
24296
- var deleteCommand3 = defineCommand153({
24574
+ var deleteCommand3 = defineCommand152({
24297
24575
  meta: {
24298
24576
  name: "delete",
24299
24577
  description: "Delete a video by ID. Use --dry-run to preview. Example: baker videos delete j571abc123 --dry-run"
@@ -24334,7 +24612,7 @@ var deleteCommand3 = defineCommand153({
24334
24612
  });
24335
24613
 
24336
24614
  // src/commands/videos/get.ts
24337
- import { defineCommand as defineCommand154 } from "citty";
24615
+ import { defineCommand as defineCommand153 } from "citty";
24338
24616
  registerSchema({
24339
24617
  command: "videos.get",
24340
24618
  description: "Get a single video by ID",
@@ -24342,7 +24620,7 @@ registerSchema({
24342
24620
  id: { type: "string", description: "Video ID", required: true }
24343
24621
  }
24344
24622
  });
24345
- var getCommand5 = defineCommand154({
24623
+ var getCommand5 = defineCommand153({
24346
24624
  meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
24347
24625
  args: {
24348
24626
  id: { type: "positional", description: "Video ID", required: false },
@@ -24379,7 +24657,7 @@ var getCommand5 = defineCommand154({
24379
24657
  });
24380
24658
 
24381
24659
  // src/commands/videos/search.ts
24382
- import { defineCommand as defineCommand155 } from "citty";
24660
+ import { defineCommand as defineCommand154 } from "citty";
24383
24661
  registerSchema({
24384
24662
  command: "videos.search",
24385
24663
  description: "Search videos by text query. Only returns ready videos.",
@@ -24389,7 +24667,7 @@ registerSchema({
24389
24667
  tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
24390
24668
  }
24391
24669
  });
24392
- var searchCommand3 = defineCommand155({
24670
+ var searchCommand3 = defineCommand154({
24393
24671
  meta: {
24394
24672
  name: "search",
24395
24673
  description: "Semantic search videos by text query. Uses hybrid BM25 + vector + reranking. Example: baker videos search 'product demo' --tags tutorial"
@@ -24436,12 +24714,12 @@ var searchCommand3 = defineCommand155({
24436
24714
  });
24437
24715
 
24438
24716
  // src/commands/videos/tags.ts
24439
- var tagsCommand5 = makeTagsCommand("videos", "video", "/api/videos/tags");
24717
+ var tagsCommand4 = makeTagsCommand("videos", "video", "/api/videos/tags");
24440
24718
 
24441
24719
  // src/commands/videos/upload.ts
24442
24720
  import { readFile as readFile12, stat as stat3 } from "fs/promises";
24443
24721
  import { extname as extname3 } from "path";
24444
- import { defineCommand as defineCommand156 } from "citty";
24722
+ import { defineCommand as defineCommand155 } from "citty";
24445
24723
  var MIME_MAP = {
24446
24724
  ".mp4": "video/mp4",
24447
24725
  ".mov": "video/quicktime",
@@ -24475,7 +24753,7 @@ function detectContentType(filePath) {
24475
24753
  }
24476
24754
  return mime;
24477
24755
  }
24478
- var uploadCommand2 = defineCommand156({
24756
+ var uploadCommand2 = defineCommand155({
24479
24757
  meta: {
24480
24758
  name: "upload",
24481
24759
  description: "Upload a video file to Baker via Mux direct upload. Auto-detects content type. Example: baker videos upload ./demo.mp4"
@@ -24529,7 +24807,7 @@ var uploadCommand2 = defineCommand156({
24529
24807
  });
24530
24808
 
24531
24809
  // src/commands/videos/index.ts
24532
- var videosCommand = defineCommand157({
24810
+ var videosCommand = defineCommand156({
24533
24811
  meta: {
24534
24812
  name: "videos",
24535
24813
  description: `Find and manage videos in Baker. Subcommands: search, get, upload, delete, tags.
@@ -24547,15 +24825,15 @@ Examples:
24547
24825
  search: searchCommand3,
24548
24826
  upload: uploadCommand2,
24549
24827
  delete: deleteCommand3,
24550
- tags: tagsCommand5
24828
+ tags: tagsCommand4
24551
24829
  }
24552
24830
  });
24553
24831
 
24554
24832
  // src/commands/winning-ads/index.ts
24555
- import { defineCommand as defineCommand160 } from "citty";
24833
+ import { defineCommand as defineCommand159 } from "citty";
24556
24834
 
24557
24835
  // src/commands/winning-ads/advertisers.ts
24558
- import { defineCommand as defineCommand158 } from "citty";
24836
+ import { defineCommand as defineCommand157 } from "citty";
24559
24837
  registerSchema({
24560
24838
  command: "winning-ads.advertisers",
24561
24839
  description: "Resolve a brand name to advertiser_id(s) in the ad-dna corpus \u2014 to find your OWN advertiser (to --exclude-advertiser) or a competitor (to --advertiser-id).",
@@ -24568,7 +24846,7 @@ registerSchema({
24568
24846
  function identity(record) {
24569
24847
  return record;
24570
24848
  }
24571
- var advertisersCommand2 = defineCommand158({
24849
+ var advertisersCommand2 = defineCommand157({
24572
24850
  meta: {
24573
24851
  name: "advertisers",
24574
24852
  description: 'Resolve a brand name to advertiser_id(s). Use it to find your own advertiser for --exclude-advertiser, or a competitor for --advertiser-id. Example: baker winning-ads advertisers "Deel" --output md'
@@ -24619,7 +24897,7 @@ var advertisersCommand2 = defineCommand158({
24619
24897
  });
24620
24898
 
24621
24899
  // src/commands/winning-ads/search.ts
24622
- import { defineCommand as defineCommand159 } from "citty";
24900
+ import { defineCommand as defineCommand158 } from "citty";
24623
24901
  registerSchema({
24624
24902
  command: "winning-ads.search",
24625
24903
  description: "Search the ad-dna corpus of scored winning ads. Returns a lean shortlist (advertiser, summary, scores, media_url) to pick a reference to reproduce.",
@@ -24727,7 +25005,7 @@ function buildSearchBody(args) {
24727
25005
  }
24728
25006
  return body;
24729
25007
  }
24730
- var searchCommand4 = defineCommand159({
25008
+ var searchCommand4 = defineCommand158({
24731
25009
  meta: {
24732
25010
  name: "search",
24733
25011
  description: "Search winning reference ads. Example: baker winning-ads search 'B2B SaaS before/after AI automation' --platform meta --format static --winner-category winner --exclude-advertiser adv_123 --output md"
@@ -24839,7 +25117,7 @@ var searchCommand4 = defineCommand159({
24839
25117
  });
24840
25118
 
24841
25119
  // src/commands/winning-ads/index.ts
24842
- var winningAdsCommand = defineCommand160({
25120
+ var winningAdsCommand = defineCommand159({
24843
25121
  meta: {
24844
25122
  name: "winning-ads",
24845
25123
  description: `Search the ad-dna corpus of scored "winning" ads for reference creatives to reproduce. Proxied through the Baker backend (BAKER_API_KEY) \u2014 no separate token needed.
@@ -24879,11 +25157,11 @@ function getCliVersion() {
24879
25157
  }
24880
25158
 
24881
25159
  // src/cli.ts
24882
- var main = defineCommand161({
25160
+ var main = defineCommand160({
24883
25161
  meta: {
24884
25162
  name: "baker",
24885
25163
  version: getCliVersion(),
24886
- description: `AI-agent CLI for finding and managing images, videos, testimonials, action items, scheduled actions, marketing tags, and ad platform data in Baker.
25164
+ description: `AI-agent CLI for finding and managing images, videos, testimonials, action items, scheduled actions, and ad platform data in Baker.
24887
25165
 
24888
25166
  Auth: Set BAKER_API_KEY (starts with bk_) and BAKER_API_URL environment variables.
24889
25167
  Chat: Set BAKER_CHAT_ID for action and scheduled-action commands that stage changes against a chat.
@@ -24903,7 +25181,6 @@ Introspection: Run 'baker schema <command>' to inspect argument schemas.`
24903
25181
  videos: videosCommand,
24904
25182
  testimonials: testimonialsCommand,
24905
25183
  canvas: canvasCommand,
24906
- tags: tagsCommand3,
24907
25184
  "winning-ads": winningAdsCommand,
24908
25185
  mcp: mcpCommand,
24909
25186
  schema: schemaCommand