@koda-sl/baker-cli 0.121.0-dev.3b02f951b → 0.121.0-dev.4a71225ab

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,25 +1,19 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- BackendClient,
4
3
  ELEVENLABS_MAX_MUSIC_LENGTH_MS,
5
4
  IMAGE_GENERATE_MODELS,
6
5
  LayerExecutionError,
7
6
  MODEL_REGISTRY,
8
7
  SEEDANCE_DURATIONS,
9
8
  ValidationError,
10
- collectAssetRefLikes,
11
9
  createEngineFromEnv,
12
10
  defaultRegistry,
13
11
  describeFailureReason,
14
12
  elementMentionKeywords,
15
13
  generateCatalog,
16
- isPersistedAssetRef,
17
- requireCredentialsFromEnv,
18
14
  resolveConcurrency,
19
- sha256Hex,
20
- ulid,
21
15
  validateCanvasDeep
22
- } from "./chunk-7WLX7E7H.js";
16
+ } from "./chunk-MWFJ5NOP.js";
23
17
  import {
24
18
  csvOrJson,
25
19
  daysAgoIso,
@@ -55,7 +49,7 @@ import {
55
49
  import "./chunk-5WRI5ZAA.js";
56
50
 
57
51
  // src/cli.ts
58
- import { defineCommand as defineCommand160, runMain } from "citty";
52
+ import { defineCommand as defineCommand161, runMain } from "citty";
59
53
 
60
54
  // src/commands/actions/index.ts
61
55
  import { defineCommand as defineCommand18 } from "citty";
@@ -854,7 +848,6 @@ var LINKEDIN_LIMITS = {
854
848
  choiceOptionsMax: 30,
855
849
  choiceOptionTextMax: 100,
856
850
  thankYouMessageMax: 300,
857
- privacyPolicyTextMax: 2e3,
858
851
  legalDisclaimerMax: 2e3,
859
852
  consentsMax: 5,
860
853
  // Campaign Manager caps disclosure checkboxes at 5
@@ -1449,7 +1442,6 @@ var leadFormFields = {
1449
1442
  /** Form language, e.g. { country: "US", language: "en" }. Defaults to the account locale on LinkedIn. */
1450
1443
  locale: z2.object({ country: z2.string().length(2), language: z2.string().length(2) }).optional(),
1451
1444
  privacyPolicyUrl: httpsUrlSchema,
1452
- privacyPolicyText: z2.string().max(LEAD.privacyPolicyTextMax).optional(),
1453
1445
  questions: z2.array(leadFormQuestionSchema).min(1).max(LEAD.questionsMax),
1454
1446
  consents: z2.array(leadFormConsentSchema).max(LEAD.consentsMax).optional(),
1455
1447
  hiddenFields: z2.array(leadFormHiddenFieldSchema).max(LEAD.hiddenFieldsMax).optional(),
@@ -1924,142 +1916,241 @@ var imagesIngestResponseSchema = z4.object({
1924
1916
  contentHash: z4.string()
1925
1917
  });
1926
1918
 
1927
- // ../api/src/testimonials.ts
1919
+ // ../api/src/tags.ts
1928
1920
  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(),
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
+ // ../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(),
1937
2028
  sourceType: testimonialSourceTypeSchema,
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(),
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(),
1957
2048
  sentiment: testimonialSentimentSchema.optional(),
1958
- textEmbedding: z5.array(z5.number()).optional(),
1959
- externalId: z5.string().optional(),
1960
- contentHash: z5.string().optional(),
2049
+ textEmbedding: z6.array(z6.number()).optional(),
2050
+ externalId: z6.string().optional(),
2051
+ contentHash: z6.string().optional(),
1961
2052
  status: testimonialStatusSchema,
1962
- errorMessage: z5.string().optional(),
1963
- createdAt: z5.number(),
1964
- updatedAt: z5.number()
2053
+ errorMessage: z6.string().optional(),
2054
+ createdAt: z6.number(),
2055
+ updatedAt: z6.number()
1965
2056
  });
1966
- var testimonialsListRequestSchema = z5.object({
2057
+ var testimonialsListRequestSchema = z6.object({
1967
2058
  source: testimonialSourceTypeSchema.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(),
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(),
1971
2062
  status: testimonialStatusSchema.optional(),
1972
2063
  sentiment: testimonialSentimentSchema.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(),
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(),
1981
2072
  source: testimonialSourceTypeSchema.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(),
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(),
1985
2076
  status: testimonialStatusSchema.optional(),
1986
2077
  sentiment: testimonialSentimentSchema.optional(),
1987
- language: z5.string().min(2).max(5).optional()
2078
+ language: z6.string().min(2).max(5).optional()
1988
2079
  }).refine(
1989
2080
  (data) => data.rating_min === void 0 || data.rating_max === void 0 || data.rating_min <= data.rating_max,
1990
2081
  { message: "rating_min must be less than or equal to rating_max" }
1991
2082
  );
1992
- var testimonialsSearchResponseSchema = z5.array(testimonialDocSchema);
1993
- var testimonialsOutscraperWebhookResponseSchema = z5.object({
1994
- ok: z5.literal(true),
1995
- note: z5.string().optional()
2083
+ var testimonialsSearchResponseSchema = z6.array(testimonialDocSchema);
2084
+ var testimonialsOutscraperWebhookResponseSchema = z6.object({
2085
+ ok: z6.literal(true),
2086
+ note: z6.string().optional()
1996
2087
  });
1997
2088
 
1998
2089
  // ../api/src/videos.ts
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(),
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(),
2035
2126
  status: videoStatusSchema,
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) });
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) });
2063
2154
 
2064
2155
  // src/commands/actions/complete.ts
2065
2156
  import { defineCommand as defineCommand2 } from "citty";
@@ -3872,37 +3963,37 @@ var GEO_TARGET_CONSTANT_REGEX = /^geoTargetConstants\/\d+$/;
3872
3963
  var LANGUAGE_CONSTANT_REGEX = /^languageConstants\/\d+$/;
3873
3964
 
3874
3965
  // ../api/src/ads-google/ops.ts
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"),
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"),
3880
3971
  tempRefSchema2
3881
3972
  ]);
3882
3973
  var targetRefSchema = refSchema;
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),
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),
3891
3982
  amountMicros: microsSchema,
3892
- deliveryMethod: z7.enum(BUDGET_DELIVERY_METHODS).default("STANDARD"),
3893
- explicitlyShared: z7.boolean().default(false)
3983
+ deliveryMethod: z8.enum(BUDGET_DELIVERY_METHODS).default("STANDARD"),
3984
+ explicitlyShared: z8.boolean().default(false)
3894
3985
  });
3895
- var budgetUpdateSchema = z7.object({
3896
- name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.budget.nameMax).optional(),
3986
+ var budgetUpdateSchema = z8.object({
3987
+ name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.budget.nameMax).optional(),
3897
3988
  amountMicros: microsSchema.optional(),
3898
- deliveryMethod: z7.enum(BUDGET_DELIVERY_METHODS).optional()
3989
+ deliveryMethod: z8.enum(BUDGET_DELIVERY_METHODS).optional()
3899
3990
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
3900
- var biddingConfigSchema = z7.object({
3901
- type: z7.enum(BIDDING_STRATEGY_TYPES),
3991
+ var biddingConfigSchema = z8.object({
3992
+ type: z8.enum(BIDDING_STRATEGY_TYPES),
3902
3993
  targetCpaMicros: microsSchema.optional(),
3903
- targetRoas: z7.number().positive().optional(),
3994
+ targetRoas: z8.number().positive().optional(),
3904
3995
  cpcBidCeilingMicros: microsSchema.optional(),
3905
- enhancedCpcEnabled: z7.boolean().optional()
3996
+ enhancedCpcEnabled: z8.boolean().optional()
3906
3997
  }).superRefine((p, ctx) => {
3907
3998
  if (p.type === "TARGET_CPA" && p.targetCpaMicros === void 0) {
3908
3999
  ctx.addIssue({ code: "custom", path: ["targetCpaMicros"], message: "TARGET_CPA needs targetCpaMicros" });
@@ -3911,17 +4002,17 @@ var biddingConfigSchema = z7.object({
3911
4002
  ctx.addIssue({ code: "custom", path: ["targetRoas"], message: "TARGET_ROAS needs targetRoas" });
3912
4003
  }
3913
4004
  });
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()
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()
3919
4010
  });
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(),
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(),
3925
4016
  budget: refSchema,
3926
4017
  /** Inline standard bidding, or a portfolio strategy ref via biddingStrategy. */
3927
4018
  bidding: biddingConfigSchema.optional(),
@@ -3930,7 +4021,7 @@ var campaignCreateSchema2 = z7.object({
3930
4021
  startDate: dateSchema.optional(),
3931
4022
  endDate: dateSchema.optional(),
3932
4023
  /** Advisory Google Ads UI objective — drives warnings, not sent to the API. */
3933
- objective: z7.enum(CAMPAIGN_OBJECTIVES).optional(),
4024
+ objective: z8.enum(CAMPAIGN_OBJECTIVES).optional(),
3934
4025
  status: stageableStatusSchema2.default("PAUSED")
3935
4026
  }).superRefine((p, ctx) => {
3936
4027
  if (!p.bidding && !p.biddingStrategy) {
@@ -3954,129 +4045,129 @@ var campaignCreateSchema2 = z7.object({
3954
4045
  ctx.addIssue({ code: "custom", path: ["endDate"], message: "endDate must be after startDate" });
3955
4046
  }
3956
4047
  });
3957
- var campaignUpdateSchema2 = z7.object({
3958
- name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.campaign.nameMax).optional(),
4048
+ var campaignUpdateSchema2 = z8.object({
4049
+ name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.campaign.nameMax).optional(),
3959
4050
  budget: refSchema.optional(),
3960
4051
  bidding: biddingConfigSchema.optional(),
3961
4052
  networkSettings: networkSettingsSchema.optional(),
3962
4053
  startDate: dateSchema.optional(),
3963
4054
  endDate: dateSchema.optional(),
3964
- status: z7.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
4055
+ status: z8.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
3965
4056
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
3966
- var adGroupCreateSchema = z7.object({
3967
- name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.adGroup.nameMax),
4057
+ var adGroupCreateSchema = z8.object({
4058
+ name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.adGroup.nameMax),
3968
4059
  campaign: refSchema,
3969
- type: z7.enum(AD_GROUP_TYPES).default("SEARCH_STANDARD"),
4060
+ type: z8.enum(AD_GROUP_TYPES).default("SEARCH_STANDARD"),
3970
4061
  cpcBidMicros: microsSchema.optional(),
3971
4062
  status: stageableStatusSchema2.default("PAUSED")
3972
4063
  });
3973
- var adGroupUpdateSchema = z7.object({
3974
- name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.adGroup.nameMax).optional(),
4064
+ var adGroupUpdateSchema = z8.object({
4065
+ name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.adGroup.nameMax).optional(),
3975
4066
  cpcBidMicros: microsSchema.optional(),
3976
- status: z7.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
4067
+ status: z8.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
3977
4068
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
3978
- var keywordAddSchema = z7.object({
4069
+ var keywordAddSchema = z8.object({
3979
4070
  adGroup: refSchema,
3980
4071
  text: keywordTextSchema,
3981
4072
  matchType: matchTypeSchema,
3982
4073
  cpcBidMicros: microsSchema.optional(),
3983
- finalUrls: z7.array(httpsUrlSchema2).optional(),
4074
+ finalUrls: z8.array(httpsUrlSchema2).optional(),
3984
4075
  status: stageableStatusSchema2.default("ENABLED")
3985
4076
  });
3986
- var keywordUpdateSchema = z7.object({
4077
+ var keywordUpdateSchema = z8.object({
3987
4078
  cpcBidMicros: microsSchema.optional(),
3988
- finalUrls: z7.array(httpsUrlSchema2).optional(),
3989
- status: z7.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
4079
+ finalUrls: z8.array(httpsUrlSchema2).optional(),
4080
+ status: z8.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
3990
4081
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
3991
- var negativeKeywordAddSchema = z7.object({
3992
- level: z7.enum(["adGroup", "campaign"]),
4082
+ var negativeKeywordAddSchema = z8.object({
4083
+ level: z8.enum(["adGroup", "campaign"]),
3993
4084
  parent: refSchema,
3994
4085
  text: keywordTextSchema,
3995
4086
  matchType: matchTypeSchema
3996
4087
  });
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")
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")
4000
4091
  });
4001
- var sharedSetMemberAddSchema = z7.object({
4092
+ var sharedSetMemberAddSchema = z8.object({
4002
4093
  sharedSet: refSchema,
4003
4094
  text: keywordTextSchema,
4004
4095
  matchType: matchTypeSchema
4005
4096
  });
4006
- var campaignSharedSetAttachSchema = z7.object({
4097
+ var campaignSharedSetAttachSchema = z8.object({
4007
4098
  campaign: refSchema,
4008
4099
  sharedSet: refSchema
4009
4100
  });
4010
- var adTextAssetSchema = z7.object({
4011
- text: z7.string().min(1),
4012
- pinnedField: z7.enum(PINNED_FIELDS).optional()
4101
+ var adTextAssetSchema = z8.object({
4102
+ text: z8.string().min(1),
4103
+ pinnedField: z8.enum(PINNED_FIELDS).optional()
4013
4104
  });
4014
- var responsiveSearchAdSchema = z7.object({
4015
- format: z7.literal("responsiveSearch"),
4016
- headlines: z7.array(
4105
+ var responsiveSearchAdSchema = z8.object({
4106
+ format: z8.literal("responsiveSearch"),
4107
+ headlines: z8.array(
4017
4108
  adTextAssetSchema.refine(
4018
4109
  (a) => a.text.length <= GOOGLE_ADS_LIMITS.responsiveSearchAd.headlineTextMax,
4019
4110
  "headline exceeds 30 chars"
4020
4111
  )
4021
4112
  ).min(GOOGLE_ADS_LIMITS.responsiveSearchAd.headlinesMin).max(GOOGLE_ADS_LIMITS.responsiveSearchAd.headlinesMax),
4022
- descriptions: z7.array(
4113
+ descriptions: z8.array(
4023
4114
  adTextAssetSchema.refine(
4024
4115
  (a) => a.text.length <= GOOGLE_ADS_LIMITS.responsiveSearchAd.descriptionTextMax,
4025
4116
  "description exceeds 90 chars"
4026
4117
  )
4027
4118
  ).min(GOOGLE_ADS_LIMITS.responsiveSearchAd.descriptionsMin).max(GOOGLE_ADS_LIMITS.responsiveSearchAd.descriptionsMax),
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),
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),
4038
4129
  // A Responsive Display Ad's images are fields on the ad's own content (never campaign-level
4039
4130
  // asset links). Google requires ≥1 landscape marketing image (1.91:1) AND ≥1 square marketing
4040
4131
  // image (1:1) to serve; the logo images are optional.
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"),
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"),
4064
4155
  // A raw YouTube id is not a publishable Google Ads reference — the video must be staged as
4065
4156
  // its own `google.asset.create` (type: youtubeVideo) first, then referenced here by asset ref.
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", [
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", [
4080
4171
  responsiveSearchAdSchema,
4081
4172
  responsiveDisplayAdSchema,
4082
4173
  callAdSchema,
@@ -4084,45 +4175,45 @@ var adContentSchema = z7.discriminatedUnion("format", [
4084
4175
  videoAdSchema,
4085
4176
  demandGenAdSchema
4086
4177
  ]);
4087
- var adCreateSchema = z7.object({
4178
+ var adCreateSchema = z8.object({
4088
4179
  adGroup: refSchema,
4089
4180
  status: stageableStatusSchema2.default("PAUSED"),
4090
4181
  content: adContentSchema
4091
4182
  });
4092
- var adUpdateSchema = z7.object({
4093
- status: z7.enum(["ENABLED", "PAUSED", "REMOVED"]).optional(),
4183
+ var adUpdateSchema = z8.object({
4184
+ status: z8.enum(["ENABLED", "PAUSED", "REMOVED"]).optional(),
4094
4185
  /** Whole-content replacement for RSA-like formats; re-validated against adContentSchema. */
4095
- content: z7.record(z7.string(), z7.unknown()).optional()
4186
+ content: z8.record(z8.string(), z8.unknown()).optional()
4096
4187
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
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", [
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", [
4126
4217
  textAssetSchema,
4127
4218
  imageAssetSchema,
4128
4219
  youtubeVideoAssetSchema,
@@ -4131,136 +4222,136 @@ var assetCreateSchema = z7.discriminatedUnion("type", [
4131
4222
  structuredSnippetAssetSchema,
4132
4223
  callToActionAssetSchema
4133
4224
  ]);
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()
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()
4145
4236
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
4146
- var assetLinkAttachSchema = z7.object({
4147
- level: z7.enum(["campaign", "adGroup", "customer"]),
4237
+ var assetLinkAttachSchema = z8.object({
4238
+ level: z8.enum(["campaign", "adGroup", "customer"]),
4148
4239
  parent: refSchema.optional(),
4149
4240
  asset: refSchema,
4150
- fieldType: z7.enum(ASSET_FIELD_TYPES)
4241
+ fieldType: z8.enum(ASSET_FIELD_TYPES)
4151
4242
  }).superRefine((value, ctx) => {
4152
4243
  if (value.level !== "customer" && !value.parent) {
4153
4244
  ctx.addIssue({
4154
- code: z7.ZodIssueCode.custom,
4245
+ code: z8.ZodIssueCode.custom,
4155
4246
  path: ["parent"],
4156
4247
  message: `parent is required for a ${value.level}-level asset link (--parent-ref)`
4157
4248
  });
4158
4249
  }
4159
4250
  });
4160
- var assetGroupCreateSchema = z7.object({
4251
+ var assetGroupCreateSchema = z8.object({
4161
4252
  campaign: refSchema,
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()
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()
4177
4268
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
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(),
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(),
4182
4273
  /** Customer-match members (crm-based) — file-first for large lists. */
4183
- members: z7.array(z7.record(z7.string(), z7.string())).optional(),
4184
- sourceFileRef: z7.string().optional()
4274
+ members: z8.array(z8.record(z8.string(), z8.string())).optional(),
4275
+ sourceFileRef: z8.string().optional()
4185
4276
  });
4186
- var audienceCriterionAttachSchema = z7.object({
4187
- level: z7.enum(["campaign", "adGroup"]),
4277
+ var audienceCriterionAttachSchema = z8.object({
4278
+ level: z8.enum(["campaign", "adGroup"]),
4188
4279
  parent: refSchema,
4189
4280
  userList: refSchema,
4190
- negative: z7.boolean().default(false)
4281
+ negative: z8.boolean().default(false)
4191
4282
  });
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"),
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"),
4197
4288
  defaultValueMicros: microsSchema.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(),
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(),
4207
4298
  defaultValueMicros: microsSchema.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()
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()
4212
4303
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
4213
- var biddingStrategyCreateSchema = z7.object({
4214
- name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.biddingStrategy.nameMax),
4304
+ var biddingStrategyCreateSchema = z8.object({
4305
+ name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.biddingStrategy.nameMax),
4215
4306
  config: biddingConfigSchema
4216
4307
  }).superRefine((p, ctx) => {
4217
4308
  if (p.config.type === "MANUAL_CPC") {
4218
4309
  ctx.addIssue({ code: "custom", path: ["config", "type"], message: "portfolio strategies cannot be Manual CPC" });
4219
4310
  }
4220
4311
  });
4221
- var biddingStrategyUpdateSchema = z7.object({
4222
- name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.biddingStrategy.nameMax).optional(),
4312
+ var biddingStrategyUpdateSchema = z8.object({
4313
+ name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.biddingStrategy.nameMax).optional(),
4223
4314
  config: biddingConfigSchema.optional()
4224
4315
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
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()
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()
4229
4320
  });
4230
- var labelAttachSchema = z7.object({
4231
- level: z7.enum(["campaign", "adGroup", "ad"]),
4321
+ var labelAttachSchema = z8.object({
4322
+ level: z8.enum(["campaign", "adGroup", "ad"]),
4232
4323
  parent: refSchema,
4233
4324
  label: refSchema
4234
4325
  });
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),
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),
4254
4345
  // Google's `CampaignCriterion.bid_modifier`: "The modifier must be in the range 0.1 - 10.0. Use 0
4255
4346
  // 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.
4256
- bidModifier: z7.number().min(0).max(10).optional().refine((v) => v === void 0 || v === 0 || v >= 0.1, {
4347
+ bidModifier: z8.number().min(0).max(10).optional().refine((v) => v === void 0 || v === 0 || v >= 0.1, {
4257
4348
  message: "bid modifier must be 0 (exclude the device) or between 0.1 and 10.0"
4258
4349
  })
4259
4350
  });
4260
- var campaignCriterionAddSchema = z7.object({
4351
+ var campaignCriterionAddSchema = z8.object({
4261
4352
  campaign: refSchema,
4262
- negative: z7.boolean().default(false),
4263
- criterion: z7.discriminatedUnion("criterionType", [
4353
+ negative: z8.boolean().default(false),
4354
+ criterion: z8.discriminatedUnion("criterionType", [
4264
4355
  locationCriterionSchema,
4265
4356
  languageCriterionSchema,
4266
4357
  adScheduleCriterionSchema,
@@ -4270,7 +4361,7 @@ var campaignCriterionAddSchema = z7.object({
4270
4361
  const c = val.criterion;
4271
4362
  if (c.criterionType === "adSchedule" && c.endHour === 24 && c.endMinute !== "ZERO") {
4272
4363
  ctx.addIssue({
4273
- code: z7.ZodIssueCode.custom,
4364
+ code: z8.ZodIssueCode.custom,
4274
4365
  message: "endHour 24 (midnight) cannot have a non-zero endMinute",
4275
4366
  path: ["criterion", "endMinute"]
4276
4367
  });
@@ -4322,17 +4413,17 @@ var GOOGLE_DRAFT_OP_KINDS = [
4322
4413
  "google.campaignCriterion.add",
4323
4414
  "google.campaignCriterion.remove"
4324
4415
  ];
4325
- var googleDraftOpKindSchema = z7.enum(GOOGLE_DRAFT_OP_KINDS);
4416
+ var googleDraftOpKindSchema = z8.enum(GOOGLE_DRAFT_OP_KINDS);
4326
4417
  function createOp2(kind, payload) {
4327
- return z7.object({ kind: z7.literal(kind), customerId: customerIdSchema, payload });
4418
+ return z8.object({ kind: z8.literal(kind), customerId: customerIdSchema, payload });
4328
4419
  }
4329
4420
  function updateOp2(kind, payload) {
4330
- return z7.object({ kind: z7.literal(kind), customerId: customerIdSchema, target: targetRefSchema, payload });
4421
+ return z8.object({ kind: z8.literal(kind), customerId: customerIdSchema, target: targetRefSchema, payload });
4331
4422
  }
4332
4423
  function targetOp(kind) {
4333
- return z7.object({ kind: z7.literal(kind), customerId: customerIdSchema, target: targetRefSchema });
4424
+ return z8.object({ kind: z8.literal(kind), customerId: customerIdSchema, target: targetRefSchema });
4334
4425
  }
4335
- var googleDraftOpInputSchema = z7.discriminatedUnion("kind", [
4426
+ var googleDraftOpInputSchema = z8.discriminatedUnion("kind", [
4336
4427
  createOp2("google.budget.create", budgetCreateSchema),
4337
4428
  updateOp2("google.budget.update", budgetUpdateSchema),
4338
4429
  createOp2("google.campaign.create", campaignCreateSchema2),
@@ -4380,132 +4471,132 @@ var googleDraftOpInputSchema = z7.discriminatedUnion("kind", [
4380
4471
  ]);
4381
4472
 
4382
4473
  // ../api/src/ads-google/wire.ts
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(),
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(),
4394
4485
  op: googleDraftOpInputSchema
4395
4486
  });
4396
- var googleDraftStageResponseSchema = z8.object({
4397
- staged: z8.literal(true),
4398
- ref: z8.string(),
4487
+ var googleDraftStageResponseSchema = z9.object({
4488
+ staged: z9.literal(true),
4489
+ ref: z9.string(),
4399
4490
  kind: googleDraftOpKindSchema,
4400
4491
  mode: googleWriteModeSchema,
4401
- dependsOn: z8.array(z8.string()),
4402
- summary: z8.string(),
4403
- warnings: z8.array(z8.string()),
4492
+ dependsOn: z9.array(z9.string()),
4493
+ summary: z9.string(),
4494
+ warnings: z9.array(z9.string()),
4404
4495
  /** True when the op amended an already-staged op in place instead of appending a new one. */
4405
- amended: z8.boolean().optional()
4496
+ amended: z9.boolean().optional()
4406
4497
  });
4407
- var googleDraftAmendRequestSchema = z8.object({
4408
- chatId: z8.string(),
4409
- ref: z8.string(),
4410
- patch: z8.record(z8.string(), z8.unknown())
4498
+ var googleDraftAmendRequestSchema = z9.object({
4499
+ chatId: z9.string(),
4500
+ ref: z9.string(),
4501
+ patch: z9.record(z9.string(), z9.unknown())
4411
4502
  });
4412
- var googleDraftShowRequestSchema = z8.object({
4413
- chatId: z8.string(),
4414
- ref: z8.string()
4503
+ var googleDraftShowRequestSchema = z9.object({
4504
+ chatId: z9.string(),
4505
+ ref: z9.string()
4415
4506
  });
4416
4507
  var GOOGLE_DRAFT_BATCH_MAX = 500;
4417
- var googleDraftStageBatchRequestSchema = z8.object({
4418
- chatId: z8.string(),
4419
- ops: z8.array(googleDraftOpInputSchema).min(1).max(GOOGLE_DRAFT_BATCH_MAX)
4508
+ var googleDraftStageBatchRequestSchema = z9.object({
4509
+ chatId: z9.string(),
4510
+ ops: z9.array(googleDraftOpInputSchema).min(1).max(GOOGLE_DRAFT_BATCH_MAX)
4420
4511
  });
4421
- var googleDraftStageBatchResponseSchema = z8.object({
4422
- staged: z8.literal(true),
4512
+ var googleDraftStageBatchResponseSchema = z9.object({
4513
+ staged: z9.literal(true),
4423
4514
  mode: googleWriteModeSchema,
4424
- count: z8.number(),
4425
- ops: z8.array(
4426
- z8.object({
4427
- ref: z8.string(),
4515
+ count: z9.number(),
4516
+ ops: z9.array(
4517
+ z9.object({
4518
+ ref: z9.string(),
4428
4519
  kind: googleDraftOpKindSchema,
4429
- dependsOn: z8.array(z8.string()),
4430
- summary: z8.string(),
4431
- warnings: z8.array(z8.string())
4520
+ dependsOn: z9.array(z9.string()),
4521
+ summary: z9.string(),
4522
+ warnings: z9.array(z9.string())
4432
4523
  })
4433
4524
  )
4434
4525
  });
4435
- var googleDraftOpViewSchema = z8.object({
4436
- ref: z8.string(),
4526
+ var googleDraftOpViewSchema = z9.object({
4527
+ ref: z9.string(),
4437
4528
  kind: googleDraftOpKindSchema,
4438
- customerId: z8.string(),
4439
- target: z8.string().optional(),
4440
- dependsOn: z8.array(z8.string()),
4441
- summary: z8.string(),
4442
- stagedAt: z8.number(),
4529
+ customerId: z9.string(),
4530
+ target: z9.string().optional(),
4531
+ dependsOn: z9.array(z9.string()),
4532
+ summary: z9.string(),
4533
+ stagedAt: z9.number(),
4443
4534
  result: googleDraftOpResultSchema.optional()
4444
4535
  });
4445
- var googleDraftShowResponseSchema = z8.object({
4536
+ var googleDraftShowResponseSchema = z9.object({
4446
4537
  op: googleDraftOpViewSchema.extend({
4447
- payload: z8.unknown().optional(),
4448
- warnings: z8.array(z8.string()).optional(),
4449
- annotations: z8.unknown().optional()
4538
+ payload: z9.unknown().optional(),
4539
+ warnings: z9.array(z9.string()).optional(),
4540
+ annotations: z9.unknown().optional()
4450
4541
  })
4451
4542
  });
4452
- var googleDraftListRequestSchema = z8.object({
4453
- chatId: z8.string()
4543
+ var googleDraftListRequestSchema = z9.object({
4544
+ chatId: z9.string()
4454
4545
  });
4455
- var googleDraftAdvisorySchema = z8.object({
4456
- scope: z8.enum(["campaign", "adGroup"]),
4457
- message: z8.string()
4546
+ var googleDraftAdvisorySchema = z9.object({
4547
+ scope: z9.enum(["campaign", "adGroup"]),
4548
+ message: z9.string()
4458
4549
  });
4459
- var googleDraftStatusCollectionSchema = z8.object({
4460
- label: z8.string(),
4461
- added: z8.number(),
4462
- removed: z8.number(),
4463
- existing: z8.number()
4550
+ var googleDraftStatusCollectionSchema = z9.object({
4551
+ label: z9.string(),
4552
+ added: z9.number(),
4553
+ removed: z9.number(),
4554
+ existing: z9.number()
4464
4555
  });
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(),
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(),
4470
4561
  operation: googleDraftChangeOperationSchema.optional(),
4471
- existing: z8.boolean(),
4472
- collections: z8.array(googleDraftStatusCollectionSchema),
4473
- children: z8.array(googleDraftStatusNodeSchema),
4474
- warnings: z8.array(z8.string()).optional()
4562
+ existing: z9.boolean(),
4563
+ collections: z9.array(googleDraftStatusCollectionSchema),
4564
+ children: z9.array(googleDraftStatusNodeSchema),
4565
+ warnings: z9.array(z9.string()).optional()
4475
4566
  })
4476
4567
  );
4477
- var googleDraftListResponseSchema = z8.object({
4478
- status: z8.enum(["active", "publishing", "applied", "discarded", "none"]),
4568
+ var googleDraftListResponseSchema = z9.object({
4569
+ status: z9.enum(["active", "publishing", "applied", "discarded", "none"]),
4479
4570
  mode: googleWriteModeSchema,
4480
- count: z8.number(),
4481
- ops: z8.array(googleDraftOpViewSchema),
4571
+ count: z9.number(),
4572
+ ops: z9.array(googleDraftOpViewSchema),
4482
4573
  /** Grouped campaign ▸ ad group ▸ ad tree for the readable CLI status view. */
4483
- tree: z8.array(googleDraftStatusNodeSchema).optional(),
4574
+ tree: z9.array(googleDraftStatusNodeSchema).optional(),
4484
4575
  /** Non-blocking completeness advisories for the whole draft. */
4485
- advisories: z8.array(googleDraftAdvisorySchema).optional()
4576
+ advisories: z9.array(googleDraftAdvisorySchema).optional()
4486
4577
  });
4487
- var googleDraftRemoveRequestSchema = z8.object({
4488
- chatId: z8.string(),
4489
- ref: z8.string()
4578
+ var googleDraftRemoveRequestSchema = z9.object({
4579
+ chatId: z9.string(),
4580
+ ref: z9.string()
4490
4581
  });
4491
- var googleDraftRemoveResponseSchema = z8.object({
4582
+ var googleDraftRemoveResponseSchema = z9.object({
4492
4583
  /** The requested ref plus any dependents removed by cascade. */
4493
- removed: z8.array(z8.string())
4584
+ removed: z9.array(z9.string())
4494
4585
  });
4495
- var googleDraftClearRequestSchema = z8.object({
4496
- chatId: z8.string()
4586
+ var googleDraftClearRequestSchema = z9.object({
4587
+ chatId: z9.string()
4497
4588
  });
4498
- var googleDraftClearResponseSchema = z8.object({
4499
- cleared: z8.number()
4589
+ var googleDraftClearResponseSchema = z9.object({
4590
+ cleared: z9.number()
4500
4591
  });
4501
- var googleFieldErrorSchema = z8.object({
4502
- path: z8.string(),
4503
- message: z8.string()
4592
+ var googleFieldErrorSchema = z9.object({
4593
+ path: z9.string(),
4594
+ message: z9.string()
4504
4595
  });
4505
- var googleDraftErrorResponseSchema = z8.object({
4506
- code: z8.string(),
4507
- error: z8.string(),
4508
- fields: z8.array(googleFieldErrorSchema).optional()
4596
+ var googleDraftErrorResponseSchema = z9.object({
4597
+ code: z9.string(),
4598
+ error: z9.string(),
4599
+ fields: z9.array(googleFieldErrorSchema).optional()
4509
4600
  });
4510
4601
 
4511
4602
  // src/commands/ads/google/draft-status.ts
@@ -4670,11 +4761,11 @@ function rawTextEntries(value) {
4670
4761
  const values = Array.isArray(value) ? value : typeof value === "string" ? [value] : [];
4671
4762
  return values.filter((v) => typeof v === "string").flatMap((v) => v.split(",")).map((v) => v.trim()).filter(Boolean);
4672
4763
  }
4673
- function rawFileEntries(path14) {
4674
- if (typeof path14 !== "string" || path14.length === 0) {
4764
+ function rawFileEntries(path12) {
4765
+ if (typeof path12 !== "string" || path12.length === 0) {
4675
4766
  return [];
4676
4767
  }
4677
- return readFileSync2(path14, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
4768
+ return readFileSync2(path12, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
4678
4769
  }
4679
4770
  function keywordEntries(args) {
4680
4771
  const defaultMatch = typeof args["match-type"] === "string" ? args["match-type"].toUpperCase() : void 0;
@@ -4697,19 +4788,19 @@ function keywordEntries(args) {
4697
4788
  }
4698
4789
  return entries;
4699
4790
  }
4700
- function loadJsonFileArg(path14) {
4701
- if (typeof path14 !== "string" || path14.length === 0) {
4791
+ function loadJsonFileArg(path12) {
4792
+ if (typeof path12 !== "string" || path12.length === 0) {
4702
4793
  return {};
4703
4794
  }
4704
4795
  try {
4705
- const parsed = JSON.parse(readFileSync2(path14, "utf8"));
4796
+ const parsed = JSON.parse(readFileSync2(path12, "utf8"));
4706
4797
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
4707
- failWriteValidation(`${path14} must contain a JSON object`);
4798
+ failWriteValidation(`${path12} must contain a JSON object`);
4708
4799
  }
4709
4800
  return parsed;
4710
4801
  } catch (err) {
4711
4802
  if (err instanceof SyntaxError) {
4712
- failWriteValidation(`${path14} is not valid JSON: ${err.message}`);
4803
+ failWriteValidation(`${path12} is not valid JSON: ${err.message}`);
4713
4804
  }
4714
4805
  throw err;
4715
4806
  }
@@ -4820,10 +4911,10 @@ async function stageUpdate(kind, customerId, target, payload) {
4820
4911
  async function stageTarget(kind, customerId, target) {
4821
4912
  await stageGoogleOp({ kind, customerId, target });
4822
4913
  }
4823
- async function draftAction(path14, body) {
4914
+ async function draftAction(path12, body) {
4824
4915
  try {
4825
4916
  const chatId = requireChatId();
4826
- const response = await apiPost(path14, { chatId, ...body });
4917
+ const response = await apiPost(path12, { chatId, ...body });
4827
4918
  writeJsonEnvelope(response);
4828
4919
  } catch (err) {
4829
4920
  handleGoogleError(err);
@@ -8578,19 +8669,19 @@ function failWriteValidation2(message) {
8578
8669
  writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
8579
8670
  process.exit(1);
8580
8671
  }
8581
- function loadJsonFileArg2(path14) {
8582
- if (typeof path14 !== "string" || path14.length === 0) {
8672
+ function loadJsonFileArg2(path12) {
8673
+ if (typeof path12 !== "string" || path12.length === 0) {
8583
8674
  return {};
8584
8675
  }
8585
8676
  try {
8586
- const parsed = JSON.parse(readFileSync6(path14, "utf8"));
8677
+ const parsed = JSON.parse(readFileSync6(path12, "utf8"));
8587
8678
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
8588
- failWriteValidation2(`${path14} must contain a JSON object`);
8679
+ failWriteValidation2(`${path12} must contain a JSON object`);
8589
8680
  }
8590
8681
  return parsed;
8591
8682
  } catch (err) {
8592
8683
  if (err instanceof SyntaxError) {
8593
- failWriteValidation2(`${path14} is not valid JSON: ${err.message}`);
8684
+ failWriteValidation2(`${path12} is not valid JSON: ${err.message}`);
8594
8685
  }
8595
8686
  throw err;
8596
8687
  }
@@ -8675,15 +8766,15 @@ function parseLocaleFlag(value) {
8675
8766
  }
8676
8767
  return { language: match[1], country: match[2].toUpperCase() };
8677
8768
  }
8678
- function loadTargetingFileArg(path14) {
8679
- if (typeof path14 !== "string" || path14.length === 0) {
8769
+ function loadTargetingFileArg(path12) {
8770
+ if (typeof path12 !== "string" || path12.length === 0) {
8680
8771
  return void 0;
8681
8772
  }
8682
- const parsed = loadJsonFileArg2(path14);
8773
+ const parsed = loadJsonFileArg2(path12);
8683
8774
  const criteria = parsed.targetingCriteria ?? parsed;
8684
8775
  if (!criteria.include) {
8685
8776
  failWriteValidation2(
8686
- `${path14} must contain targeting criteria with an "include" block (see baker schema ads.linkedin.campaigns.create)`
8777
+ `${path12} must contain targeting criteria with an "include" block (see baker schema ads.linkedin.campaigns.create)`
8687
8778
  );
8688
8779
  }
8689
8780
  return criteria;
@@ -8718,14 +8809,14 @@ function parseCsvLine(line) {
8718
8809
  cells.push(current);
8719
8810
  return cells.map((cell) => cell.trim());
8720
8811
  }
8721
- function parseListFileArg(path14, maxRows) {
8722
- if (typeof path14 !== "string" || path14.length === 0) {
8812
+ function parseListFileArg(path12, maxRows) {
8813
+ if (typeof path12 !== "string" || path12.length === 0) {
8723
8814
  return void 0;
8724
8815
  }
8725
- const raw = readFileSync6(path14, "utf8");
8816
+ const raw = readFileSync6(path12, "utf8");
8726
8817
  const lines = raw.split(/\r?\n/).filter((line) => line.trim().length > 0);
8727
8818
  if (lines.length < 2) {
8728
- failWriteValidation2(`${path14} needs a header row and at least one data row`);
8819
+ failWriteValidation2(`${path12} needs a header row and at least one data row`);
8729
8820
  }
8730
8821
  const columns = parseCsvLine(lines[0]).map((column) => column.trim());
8731
8822
  const rows = [];
@@ -8744,7 +8835,7 @@ function parseListFileArg(path14, maxRows) {
8744
8835
  }
8745
8836
  }
8746
8837
  if (rows.length > maxRows) {
8747
- failWriteValidation2(`${path14} has ${rows.length} rows \u2014 the inline limit is ${maxRows}. Split the list.`);
8838
+ failWriteValidation2(`${path12} has ${rows.length} rows \u2014 the inline limit is ${maxRows}. Split the list.`);
8748
8839
  }
8749
8840
  return { columns, rows };
8750
8841
  }
@@ -9389,7 +9480,7 @@ var leadFormsCreateCommand = defineCommand38({
9389
9480
  Required: name, headline (\u226460), privacyPolicyUrl, questions[] (\u226412; playbook: \u22644 for completion).
9390
9481
  Each question is a predefined profile field ({ name, predefinedField: "EMAIL" }) or a custom question ({ name, questionType: "MULTIPLE_CHOICE", options: [...] }; \u22643 custom).
9391
9482
  Best-practice fields the preview will nudge for if missing: 1-3 qualifying questions, consents[] (disclosure checkboxes), thankYou.message + thankYou.landingUrl|appointmentUrl.
9392
- Also supported: locale, formImageId|formImageUrn, privacyPolicyText, hiddenFields[], legalDisclaimer, thankYou.cta. Example: baker ads linkedin lead-forms create --file form.json`
9483
+ Also supported: locale, formImageId|formImageUrn, hiddenFields[], legalDisclaimer, thankYou.cta. Example: baker ads linkedin lead-forms create --file form.json`
9393
9484
  },
9394
9485
  args: {
9395
9486
  ...accountArgs,
@@ -10813,72 +10904,72 @@ var NUMERIC_ID_REGEX3 = /^\d+$/;
10813
10904
  var IMAGE_HASH_REGEX = /^[A-Fa-f0-9]{16,}$/;
10814
10905
 
10815
10906
  // ../api/src/ads-meta/ops.ts
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);
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);
10827
10918
  function currencyMinimums2(currencyCode) {
10828
10919
  return CURRENCY_MINIMUMS2[currencyCode] ?? DEFAULT_CURRENCY_MINIMUM2;
10829
10920
  }
10830
- function validateDailyBudgetFloor(money, ctx, path14) {
10921
+ function validateDailyBudgetFloor(money, ctx, path12) {
10831
10922
  if (money?.currencyCode) {
10832
10923
  const min = currencyMinimums2(money.currencyCode).dailyBudgetMin;
10833
10924
  if (Number(money.amount) < min) {
10834
- ctx.addIssue({ code: "custom", path: path14, message: `below the ${min} ${money.currencyCode} daily minimum` });
10925
+ ctx.addIssue({ code: "custom", path: path12, message: `below the ${min} ${money.currencyCode} daily minimum` });
10835
10926
  }
10836
10927
  }
10837
10928
  }
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({
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({
10847
10938
  geo_locations: geoLocationsSchema.optional(),
10848
10939
  excluded_geo_locations: geoLocationsSchema.optional(),
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),
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),
10871
10962
  status: stageableStatusSchema3.default("PAUSED"),
10872
10963
  special_ad_categories: specialAdCategoriesSchema,
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(),
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(),
10876
10967
  /** Campaign Budget Optimization (Advantage campaign budget) — mutually exclusive with ad-set budgets. */
10877
10968
  dailyBudget: moneySchema2.optional(),
10878
10969
  lifetimeBudget: moneySchema2.optional(),
10879
10970
  spendCap: moneySchema2.optional(),
10880
- start_time: z9.number().int().positive().optional(),
10881
- stop_time: z9.number().int().positive().optional()
10971
+ start_time: z10.number().int().positive().optional(),
10972
+ stop_time: z10.number().int().positive().optional()
10882
10973
  }).superRefine((p, ctx) => {
10883
10974
  if (p.dailyBudget && p.lifetimeBudget) {
10884
10975
  ctx.addIssue({ code: "custom", path: ["dailyBudget"], message: "set only one of dailyBudget or lifetimeBudget" });
@@ -10888,15 +10979,15 @@ var campaignCreateSchema3 = z9.object({
10888
10979
  ctx.addIssue({ code: "custom", path: ["stop_time"], message: "stop_time must be after start_time" });
10889
10980
  }
10890
10981
  });
10891
- var campaignUpdateSchema3 = z9.object({
10892
- name: z9.string().min(1).max(META_LIMITS.campaign.nameMax).optional(),
10982
+ var campaignUpdateSchema3 = z10.object({
10983
+ name: z10.string().min(1).max(META_LIMITS.campaign.nameMax).optional(),
10893
10984
  status: updateStatusSchema.optional(),
10894
- bid_strategy: z9.enum(BID_STRATEGIES).optional(),
10985
+ bid_strategy: z10.enum(BID_STRATEGIES).optional(),
10895
10986
  dailyBudget: moneySchema2.optional(),
10896
10987
  lifetimeBudget: moneySchema2.optional(),
10897
10988
  spendCap: moneySchema2.optional(),
10898
- start_time: z9.number().int().positive().optional(),
10899
- stop_time: z9.number().int().positive().optional()
10989
+ start_time: z10.number().int().positive().optional(),
10990
+ stop_time: z10.number().int().positive().optional()
10900
10991
  }).superRefine((p, ctx) => {
10901
10992
  if (!Object.values(p).some((val) => val !== void 0)) {
10902
10993
  ctx.addIssue({ code: "custom", message: "update needs at least one field" });
@@ -10906,38 +10997,38 @@ var campaignUpdateSchema3 = z9.object({
10906
10997
  }
10907
10998
  validateDailyBudgetFloor(p.dailyBudget, ctx, ["dailyBudget", "amount"]);
10908
10999
  });
10909
- var promotedObjectSchema = z9.object({
11000
+ var promotedObjectSchema = z10.object({
10910
11001
  page_id: parentRefSchema2.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()
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()
10919
11010
  }).partial();
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)])
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)])
10924
11015
  })
10925
11016
  );
10926
11017
  var adSetFields = {
10927
- name: z9.string().min(1).max(META_LIMITS.adSet.nameMax),
11018
+ name: z10.string().min(1).max(META_LIMITS.adSet.nameMax),
10928
11019
  campaign_id: parentRefSchema2,
10929
11020
  status: stageableStatusSchema3.default("PAUSED"),
10930
11021
  dailyBudget: moneySchema2.optional(),
10931
11022
  lifetimeBudget: moneySchema2.optional(),
10932
11023
  bidAmount: moneySchema2.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(),
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(),
10937
11028
  promoted_object: promotedObjectSchema.optional(),
10938
11029
  attribution_spec: attributionSpecSchema.optional(),
10939
- start_time: z9.number().int().positive().optional(),
10940
- end_time: z9.number().int().positive().optional(),
11030
+ start_time: z10.number().int().positive().optional(),
11031
+ end_time: z10.number().int().positive().optional(),
10941
11032
  targeting: metaTargetingSchema
10942
11033
  };
10943
11034
  function validateAdSetBudgetAndBid(p, ctx) {
@@ -10955,22 +11046,22 @@ function validateAdSetBudgetAndBid(p, ctx) {
10955
11046
  ctx.addIssue({ code: "custom", path: ["end_time"], message: "end_time must be after start_time" });
10956
11047
  }
10957
11048
  }
10958
- var adSetCreateSchema = z9.object(adSetFields).superRefine((p, ctx) => {
11049
+ var adSetCreateSchema = z10.object(adSetFields).superRefine((p, ctx) => {
10959
11050
  validateAdSetBudgetAndBid(p, ctx);
10960
11051
  });
10961
- var adSetUpdateSchema = z9.object({
11052
+ var adSetUpdateSchema = z10.object({
10962
11053
  name: adSetFields.name.optional(),
10963
11054
  status: updateStatusSchema.optional(),
10964
11055
  dailyBudget: moneySchema2.optional(),
10965
11056
  lifetimeBudget: moneySchema2.optional(),
10966
11057
  bidAmount: moneySchema2.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(),
11058
+ bid_strategy: z10.enum(BID_STRATEGIES).optional(),
11059
+ optimization_goal: z10.enum(OPTIMIZATION_GOALS).optional(),
11060
+ destination_type: z10.enum(DESTINATION_TYPES).optional(),
10970
11061
  promoted_object: promotedObjectSchema.optional(),
10971
11062
  attribution_spec: attributionSpecSchema.optional(),
10972
- start_time: z9.number().int().positive().optional(),
10973
- end_time: z9.number().int().positive().optional(),
11063
+ start_time: z10.number().int().positive().optional(),
11064
+ end_time: z10.number().int().positive().optional(),
10974
11065
  targeting: metaTargetingSchema.optional()
10975
11066
  }).superRefine((p, ctx) => {
10976
11067
  if (!Object.values(p).some((val) => val !== void 0)) {
@@ -10978,38 +11069,38 @@ var adSetUpdateSchema = z9.object({
10978
11069
  }
10979
11070
  validateAdSetBudgetAndBid(p, ctx);
10980
11071
  });
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),
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),
10986
11077
  /** Overrides the base link for the CTA button; defaults to the ad's link. */
10987
11078
  link: httpsUrlSchema3.optional()
10988
11079
  });
10989
- var creativeEnhancementsSchema = z9.object({
10990
- standardEnhancements: z9.enum(ENROLL_STATUSES).optional(),
10991
- features: z9.record(z9.string(), z9.enum(ENROLL_STATUSES)).optional()
11080
+ var creativeEnhancementsSchema = z10.object({
11081
+ standardEnhancements: z10.enum(ENROLL_STATUSES).optional(),
11082
+ features: z10.record(z10.string(), z10.enum(ENROLL_STATUSES)).optional()
10992
11083
  });
10993
11084
  var creativeSharedFields = {
10994
- name: z9.string().max(META_LIMITS.creative.nameMax).optional(),
11085
+ name: z10.string().max(META_LIMITS.creative.nameMax).optional(),
10995
11086
  /** Facebook Page id backing the ad's identity. */
10996
11087
  page_id: parentRefSchema2,
10997
11088
  /** Instagram account id for IG placements (aka instagram_actor_id on read). */
10998
- instagram_user_id: z9.string().regex(NUMERIC_ID_REGEX3).optional(),
11089
+ instagram_user_id: z10.string().regex(NUMERIC_ID_REGEX3).optional(),
10999
11090
  /** URL tracking parameters appended to the destination, e.g. "utm_source=fb&utm_campaign=x". */
11000
- url_tags: z9.string().max(1e3).optional(),
11091
+ url_tags: z10.string().max(1e3).optional(),
11001
11092
  enhancements: creativeEnhancementsSchema.optional()
11002
11093
  };
11003
11094
  var imageMediaFields = {
11004
- imageHash: z9.string().regex(IMAGE_HASH_REGEX).optional(),
11095
+ imageHash: z10.string().regex(IMAGE_HASH_REGEX).optional(),
11005
11096
  imageRef: tempRefSchema3.optional()
11006
11097
  };
11007
11098
  var videoMediaFields = {
11008
- videoId: z9.string().regex(NUMERIC_ID_REGEX3).optional(),
11099
+ videoId: z10.string().regex(NUMERIC_ID_REGEX3).optional(),
11009
11100
  videoRef: tempRefSchema3.optional(),
11010
11101
  /** Thumbnail for a video creative — image hash, ref, or public url. */
11011
- thumbnailHash: z9.string().regex(IMAGE_HASH_REGEX).optional(),
11012
- imageUrl: z9.string().url().optional()
11102
+ thumbnailHash: z10.string().regex(IMAGE_HASH_REGEX).optional(),
11103
+ imageUrl: z10.string().url().optional()
11013
11104
  };
11014
11105
  function countImageRefs(p) {
11015
11106
  return [p.imageHash, p.imageRef].filter(Boolean).length;
@@ -11017,8 +11108,8 @@ function countImageRefs(p) {
11017
11108
  function countVideoRefs(p) {
11018
11109
  return [p.videoId, p.videoRef].filter(Boolean).length;
11019
11110
  }
11020
- var singleCreativeSchema = z9.object({
11021
- creativeType: z9.literal("single"),
11111
+ var singleCreativeSchema = z10.object({
11112
+ creativeType: z10.literal("single"),
11022
11113
  ...creativeSharedFields,
11023
11114
  /** Primary text. */
11024
11115
  message: messageSchema,
@@ -11027,7 +11118,7 @@ var singleCreativeSchema = z9.object({
11027
11118
  headline: headlineSchema2.optional(),
11028
11119
  description: descriptionSchema.optional(),
11029
11120
  /** Display URL / caption shown under the headline. */
11030
- caption: z9.string().max(255).optional(),
11121
+ caption: z10.string().max(255).optional(),
11031
11122
  call_to_action: callToActionSchema.optional(),
11032
11123
  ...imageMediaFields,
11033
11124
  ...videoMediaFields
@@ -11051,10 +11142,10 @@ var singleCreativeSchema = z9.object({
11051
11142
  });
11052
11143
  }
11053
11144
  });
11054
- var carouselCardSchema = z9.object({
11145
+ var carouselCardSchema = z10.object({
11055
11146
  link: httpsUrlSchema3,
11056
- headline: z9.string().max(META_LIMITS.creative.headlineMax).optional(),
11057
- description: z9.string().max(META_LIMITS.creative.descriptionMax).optional(),
11147
+ headline: z10.string().max(META_LIMITS.creative.headlineMax).optional(),
11148
+ description: z10.string().max(META_LIMITS.creative.descriptionMax).optional(),
11058
11149
  call_to_action: callToActionSchema.optional(),
11059
11150
  ...imageMediaFields,
11060
11151
  ...videoMediaFields
@@ -11074,35 +11165,35 @@ var carouselCardSchema = z9.object({
11074
11165
  ctx.addIssue({ code: "custom", path: ["videoId"], message: "each card is an image OR a video, not both" });
11075
11166
  }
11076
11167
  });
11077
- var carouselCreativeSchema2 = z9.object({
11078
- creativeType: z9.literal("carousel"),
11168
+ var carouselCreativeSchema2 = z10.object({
11169
+ creativeType: z10.literal("carousel"),
11079
11170
  ...creativeSharedFields,
11080
11171
  message: messageSchema,
11081
11172
  /** Optional "see more" card destination applied when a card has no own link. */
11082
11173
  link: httpsUrlSchema3.optional(),
11083
11174
  call_to_action: callToActionSchema.optional(),
11084
- cards: z9.array(carouselCardSchema).min(META_LIMITS.creative.carouselCardsMin).max(META_LIMITS.creative.carouselCardsMax)
11175
+ cards: z10.array(carouselCardSchema).min(META_LIMITS.creative.carouselCardsMin).max(META_LIMITS.creative.carouselCardsMax)
11085
11176
  });
11086
- var dynamicImageSchema = z9.object({ ...imageMediaFields }).refine((p) => countImageRefs(p) === 1, "each dynamic image needs exactly one reference");
11087
- var dynamicVideoSchema = z9.object({
11177
+ var dynamicImageSchema = z10.object({ ...imageMediaFields }).refine((p) => countImageRefs(p) === 1, "each dynamic image needs exactly one reference");
11178
+ var dynamicVideoSchema = z10.object({
11088
11179
  videoId: videoMediaFields.videoId,
11089
11180
  videoRef: videoMediaFields.videoRef,
11090
11181
  thumbnailHash: videoMediaFields.thumbnailHash
11091
11182
  }).refine((p) => countVideoRefs(p) === 1, "each dynamic video needs exactly one reference");
11092
11183
  var DYN = META_LIMITS.creative;
11093
- var dynamicCreativeSchema = z9.object({
11094
- creativeType: z9.literal("dynamic"),
11184
+ var dynamicCreativeSchema = z10.object({
11185
+ creativeType: z10.literal("dynamic"),
11095
11186
  ...creativeSharedFields,
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),
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),
11104
11195
  /** Multi-language / placement customization — structural passthrough for v1. */
11105
- asset_customization_rules: z9.array(z9.record(z9.string(), z9.unknown())).optional()
11196
+ asset_customization_rules: z10.array(z10.record(z10.string(), z10.unknown())).optional()
11106
11197
  }).superRefine((p, ctx) => {
11107
11198
  if (!(p.images?.length || p.videos?.length)) {
11108
11199
  ctx.addIssue({
@@ -11112,57 +11203,57 @@ var dynamicCreativeSchema = z9.object({
11112
11203
  });
11113
11204
  }
11114
11205
  });
11115
- var existingPostCreativeSchema = z9.object({
11116
- creativeType: z9.literal("existing_post"),
11206
+ var existingPostCreativeSchema = z10.object({
11207
+ creativeType: z10.literal("existing_post"),
11117
11208
  name: creativeSharedFields.name,
11118
11209
  /** "<page_id>_<post_id>" object story id of the post to promote. */
11119
- object_story_id: z9.string().regex(/^\d+_\d+$/, 'expected "<page_id>_<post_id>"'),
11210
+ object_story_id: z10.string().regex(/^\d+_\d+$/, 'expected "<page_id>_<post_id>"'),
11120
11211
  instagram_user_id: creativeSharedFields.instagram_user_id,
11121
11212
  url_tags: creativeSharedFields.url_tags,
11122
11213
  enhancements: creativeSharedFields.enhancements
11123
11214
  });
11124
- var creativeContentSchema2 = z9.discriminatedUnion("creativeType", [
11215
+ var creativeContentSchema2 = z10.discriminatedUnion("creativeType", [
11125
11216
  singleCreativeSchema,
11126
11217
  carouselCreativeSchema2,
11127
11218
  dynamicCreativeSchema,
11128
11219
  existingPostCreativeSchema
11129
11220
  ]);
11130
11221
  var adCreativeCreateSchema = creativeContentSchema2;
11131
- var adCreativeUpdateSchema = z9.object({
11132
- name: z9.string().max(META_LIMITS.creative.nameMax).optional(),
11222
+ var adCreativeUpdateSchema = z10.object({
11223
+ name: z10.string().max(META_LIMITS.creative.nameMax).optional(),
11133
11224
  status: updateStatusSchema.optional(),
11134
11225
  /** Content patch — only honored when the target is a staged meta_temp_* creative. */
11135
- content: z9.record(z9.string(), z9.unknown()).optional()
11226
+ content: z10.record(z10.string(), z10.unknown()).optional()
11136
11227
  }).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
11137
- var adCreateSchema2 = z9.object({
11138
- name: z9.string().min(1).max(META_LIMITS.ad.nameMax),
11228
+ var adCreateSchema2 = z10.object({
11229
+ name: z10.string().min(1).max(META_LIMITS.ad.nameMax),
11139
11230
  adset_id: parentRefSchema2,
11140
11231
  status: stageableStatusSchema3.default("PAUSED"),
11141
- creative: z9.object({ creative_id: parentRefSchema2 }),
11232
+ creative: z10.object({ creative_id: parentRefSchema2 }),
11142
11233
  /** Conversion pixel / offline event set / view tags — structural passthrough. */
11143
- tracking_specs: z9.array(z9.record(z9.string(), z9.unknown())).optional()
11234
+ tracking_specs: z10.array(z10.record(z10.string(), z10.unknown())).optional()
11144
11235
  });
11145
- var adUpdateSchema2 = z9.object({
11146
- name: z9.string().min(1).max(META_LIMITS.ad.nameMax).optional(),
11236
+ var adUpdateSchema2 = z10.object({
11237
+ name: z10.string().min(1).max(META_LIMITS.ad.nameMax).optional(),
11147
11238
  status: updateStatusSchema.optional(),
11148
11239
  /** Swapping the creative is the Meta way to "edit" an ad's creative. */
11149
- creative: z9.object({ creative_id: parentRefSchema2 }).optional(),
11150
- tracking_specs: z9.array(z9.record(z9.string(), z9.unknown())).optional()
11240
+ creative: z10.object({ creative_id: parentRefSchema2 }).optional(),
11241
+ tracking_specs: z10.array(z10.record(z10.string(), z10.unknown())).optional()
11151
11242
  }).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
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(),
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(),
11163
11254
  lookalike_spec: lookalikeSpecSchema.optional(),
11164
11255
  /** Website/engagement rule — structural passthrough validated by Meta. */
11165
- rule: z9.record(z9.string(), z9.unknown()).optional()
11256
+ rule: z10.record(z10.string(), z10.unknown()).optional()
11166
11257
  }).superRefine((p, ctx) => {
11167
11258
  if (p.subtype === "LOOKALIKE" && !p.lookalike_spec) {
11168
11259
  ctx.addIssue({ code: "custom", path: ["lookalike_spec"], message: "LOOKALIKE audiences need a lookalike_spec" });
@@ -11171,16 +11262,16 @@ var customAudienceCreateSchema = z9.object({
11171
11262
  ctx.addIssue({ code: "custom", path: ["rule"], message: `${p.subtype} audiences need a rule (use --file)` });
11172
11263
  }
11173
11264
  });
11174
- var customAudienceUpdateSchema = z9.object({
11175
- name: z9.string().min(1).max(META_LIMITS.audience.nameMax).optional(),
11176
- description: z9.string().max(500).optional()
11265
+ var customAudienceUpdateSchema = z10.object({
11266
+ name: z10.string().min(1).max(META_LIMITS.audience.nameMax).optional(),
11267
+ description: z10.string().max(500).optional()
11177
11268
  }).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
11178
- var mediaUploadSchema = z9.object({
11179
- kind: z9.enum(MEDIA_KINDS),
11269
+ var mediaUploadSchema = z10.object({
11270
+ kind: z10.enum(MEDIA_KINDS),
11180
11271
  bakerImageId: bakerMediaIdSchema2.optional(),
11181
11272
  bakerVideoId: bakerMediaIdSchema2.optional(),
11182
11273
  /** Optional display name / filename hint. */
11183
- name: z9.string().max(255).optional()
11274
+ name: z10.string().max(255).optional()
11184
11275
  }).superRefine((p, ctx) => {
11185
11276
  if (p.kind === "image" && !p.bakerImageId) {
11186
11277
  ctx.addIssue({ code: "custom", path: ["bakerImageId"], message: "image uploads need a bakerImageId" });
@@ -11202,16 +11293,16 @@ var META_DRAFT_OP_KINDS = [
11202
11293
  "customAudience.update",
11203
11294
  "media.upload"
11204
11295
  ];
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]);
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]);
11208
11299
  function createOp3(kind, payload) {
11209
- return z9.object({ kind: z9.literal(kind), accountId: accountIdSchema2, payload });
11300
+ return z10.object({ kind: z10.literal(kind), accountId: accountIdSchema2, payload });
11210
11301
  }
11211
11302
  function updateOp3(kind, payload) {
11212
- return z9.object({ kind: z9.literal(kind), accountId: accountIdSchema2, target: updateTargetSchema2, payload });
11303
+ return z10.object({ kind: z10.literal(kind), accountId: accountIdSchema2, target: updateTargetSchema2, payload });
11213
11304
  }
11214
- var metaDraftOpInputSchema = z9.discriminatedUnion("kind", [
11305
+ var metaDraftOpInputSchema = z10.discriminatedUnion("kind", [
11215
11306
  createOp3("campaign.create", campaignCreateSchema3),
11216
11307
  updateOp3("campaign.update", campaignUpdateSchema3),
11217
11308
  createOp3("adSet.create", adSetCreateSchema),
@@ -11226,89 +11317,89 @@ var metaDraftOpInputSchema = z9.discriminatedUnion("kind", [
11226
11317
  ]);
11227
11318
 
11228
11319
  // ../api/src/ads-meta/wire.ts
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"]),
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"]),
11233
11324
  /** The resulting Meta node id (campaign/adset/creative/ad/audience) or simulated id. */
11234
- id: z10.string().optional(),
11325
+ id: z11.string().optional(),
11235
11326
  /** For media.upload ops: the resulting image hash. */
11236
- hash: z10.string().optional(),
11237
- error: z10.string().optional(),
11238
- skippedBecause: z10.string().optional(),
11239
- executedAt: z10.number().optional()
11327
+ hash: z11.string().optional(),
11328
+ error: z11.string().optional(),
11329
+ skippedBecause: z11.string().optional(),
11330
+ executedAt: z11.number().optional()
11240
11331
  });
11241
- var metaDraftStageRequestSchema = z10.object({
11242
- chatId: z10.string(),
11332
+ var metaDraftStageRequestSchema = z11.object({
11333
+ chatId: z11.string(),
11243
11334
  op: metaDraftOpInputSchema
11244
11335
  });
11245
- var metaDraftStageResponseSchema = z10.object({
11246
- staged: z10.literal(true),
11247
- ref: z10.string(),
11336
+ var metaDraftStageResponseSchema = z11.object({
11337
+ staged: z11.literal(true),
11338
+ ref: z11.string(),
11248
11339
  kind: metaDraftOpKindSchema,
11249
11340
  mode: metaWriteModeSchema,
11250
- dependsOn: z10.array(z10.string()),
11251
- summary: z10.string(),
11252
- warnings: z10.array(z10.string()),
11341
+ dependsOn: z11.array(z11.string()),
11342
+ summary: z11.string(),
11343
+ warnings: z11.array(z11.string()),
11253
11344
  /** True when the op amended an already-staged op in place instead of appending a new one. */
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(),
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(),
11262
11353
  /** Pause the original after the copy publishes. */
11263
- replace: z10.boolean().optional()
11354
+ replace: z11.boolean().optional()
11264
11355
  });
11265
- var metaDraftOpViewSchema = z10.object({
11266
- ref: z10.string(),
11356
+ var metaDraftOpViewSchema = z11.object({
11357
+ ref: z11.string(),
11267
11358
  kind: metaDraftOpKindSchema,
11268
- accountId: z10.string(),
11269
- target: z10.string().optional(),
11270
- dependsOn: z10.array(z10.string()),
11271
- summary: z10.string(),
11272
- stagedAt: z10.number(),
11359
+ accountId: z11.string(),
11360
+ target: z11.string().optional(),
11361
+ dependsOn: z11.array(z11.string()),
11362
+ summary: z11.string(),
11363
+ stagedAt: z11.number(),
11273
11364
  result: metaDraftOpResultSchema.optional()
11274
11365
  });
11275
- var metaDraftListRequestSchema = z10.object({
11276
- chatId: z10.string()
11366
+ var metaDraftListRequestSchema = z11.object({
11367
+ chatId: z11.string()
11277
11368
  });
11278
- var metaDraftAdvisorySchema = z10.object({
11279
- ref: z10.string(),
11280
- message: z10.string()
11369
+ var metaDraftAdvisorySchema = z11.object({
11370
+ ref: z11.string(),
11371
+ message: z11.string()
11281
11372
  });
11282
- var metaDraftListResponseSchema = z10.object({
11283
- status: z10.enum(["active", "publishing", "applied", "discarded", "none"]),
11373
+ var metaDraftListResponseSchema = z11.object({
11374
+ status: z11.enum(["active", "publishing", "applied", "discarded", "none"]),
11284
11375
  mode: metaWriteModeSchema,
11285
- count: z10.number(),
11286
- ops: z10.array(metaDraftOpViewSchema),
11376
+ count: z11.number(),
11377
+ ops: z11.array(metaDraftOpViewSchema),
11287
11378
  /** Non-blocking cross-op quality advisories — "good campaign, not just valid". */
11288
- advisories: z10.array(metaDraftAdvisorySchema)
11379
+ advisories: z11.array(metaDraftAdvisorySchema)
11289
11380
  });
11290
- var metaDraftRemoveRequestSchema = z10.object({
11291
- chatId: z10.string(),
11292
- ref: z10.string()
11381
+ var metaDraftRemoveRequestSchema = z11.object({
11382
+ chatId: z11.string(),
11383
+ ref: z11.string()
11293
11384
  });
11294
- var metaDraftRemoveResponseSchema = z10.object({
11385
+ var metaDraftRemoveResponseSchema = z11.object({
11295
11386
  /** The requested ref plus any dependents removed by cascade. */
11296
- removed: z10.array(z10.string())
11387
+ removed: z11.array(z11.string())
11297
11388
  });
11298
- var metaDraftClearRequestSchema = z10.object({
11299
- chatId: z10.string()
11389
+ var metaDraftClearRequestSchema = z11.object({
11390
+ chatId: z11.string()
11300
11391
  });
11301
- var metaDraftClearResponseSchema = z10.object({
11302
- cleared: z10.number()
11392
+ var metaDraftClearResponseSchema = z11.object({
11393
+ cleared: z11.number()
11303
11394
  });
11304
- var metaFieldErrorSchema = z10.object({
11305
- path: z10.string(),
11306
- message: z10.string()
11395
+ var metaFieldErrorSchema = z11.object({
11396
+ path: z11.string(),
11397
+ message: z11.string()
11307
11398
  });
11308
- var metaDraftErrorResponseSchema = z10.object({
11309
- code: z10.string(),
11310
- error: z10.string(),
11311
- fields: z10.array(metaFieldErrorSchema).optional()
11399
+ var metaDraftErrorResponseSchema = z11.object({
11400
+ code: z11.string(),
11401
+ error: z11.string(),
11402
+ fields: z11.array(metaFieldErrorSchema).optional()
11312
11403
  });
11313
11404
 
11314
11405
  // src/commands/ads/meta/write-shared.ts
@@ -11319,19 +11410,19 @@ function failWriteValidation3(message) {
11319
11410
  writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
11320
11411
  process.exit(1);
11321
11412
  }
11322
- function loadJsonFileArg3(path14) {
11323
- if (typeof path14 !== "string" || path14.length === 0) {
11413
+ function loadJsonFileArg3(path12) {
11414
+ if (typeof path12 !== "string" || path12.length === 0) {
11324
11415
  return {};
11325
11416
  }
11326
11417
  try {
11327
- const parsed = JSON.parse(readFileSync8(path14, "utf8"));
11418
+ const parsed = JSON.parse(readFileSync8(path12, "utf8"));
11328
11419
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
11329
- failWriteValidation3(`${path14} must contain a JSON object`);
11420
+ failWriteValidation3(`${path12} must contain a JSON object`);
11330
11421
  }
11331
11422
  return parsed;
11332
11423
  } catch (err) {
11333
11424
  if (err instanceof SyntaxError) {
11334
- failWriteValidation3(`${path14} is not valid JSON: ${err.message}`);
11425
+ failWriteValidation3(`${path12} is not valid JSON: ${err.message}`);
11335
11426
  }
11336
11427
  throw err;
11337
11428
  }
@@ -14394,7 +14485,7 @@ async function probeDuration(filePath) {
14394
14485
 
14395
14486
  // src/commands/canvas/run.ts
14396
14487
  import { readFile as readFile2 } from "fs/promises";
14397
- import path5 from "path";
14488
+ import path4 from "path";
14398
14489
  import { defineCommand as defineCommand88 } from "citty";
14399
14490
 
14400
14491
  // src/commands/canvas/placeholders.ts
@@ -14438,102 +14529,9 @@ function isResolvableRelative(value) {
14438
14529
  return typeof value === "string" && value.length > 0 && !value.includes("[TODO") && !path2.isAbsolute(value);
14439
14530
  }
14440
14531
 
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_CREATIVE_SLUG_LENGTH = 100;
14447
- function creativeSlugFromCanvasPath(filePath) {
14448
- const normalized = filePath.split(path3.sep).join("/");
14449
- const match = normalized.match(/(?:^|\/)src\/creatives\/([a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\//);
14450
- const slug = match?.[1] ?? null;
14451
- return slug && slug.length <= MAX_CREATIVE_SLUG_LENGTH ? slug : null;
14452
- }
14453
- var OUTPUT_KINDS = /* @__PURE__ */ new Set(["image", "video", "audio", "json", "text", "font"]);
14454
- function toRecordOutput(slot, value) {
14455
- const refs = collectAssetRefLikes(value);
14456
- const ref = refs.length === 1 ? refs[0] : null;
14457
- if (!ref || !isPersistedAssetRef(ref)) return null;
14458
- const kind = typeof ref.kind === "string" && OUTPUT_KINDS.has(ref.kind) ? ref.kind : null;
14459
- if (!kind) return null;
14460
- return {
14461
- slot,
14462
- kind,
14463
- sha256: ref.sha256,
14464
- url: ref.url,
14465
- mime: ref.mime,
14466
- width: typeof ref.width === "number" ? ref.width : void 0,
14467
- height: typeof ref.height === "number" ? ref.height : void 0,
14468
- durationMs: typeof ref.duration_ms === "number" ? ref.duration_ms : void 0
14469
- };
14470
- }
14471
- function nodeOutputsToRecord(nodeOutputs) {
14472
- const out = [];
14473
- for (const [slot, value] of Object.entries(nodeOutputs)) {
14474
- if (Array.isArray(value)) {
14475
- value.forEach((item, i) => {
14476
- const rec = toRecordOutput(`${slot}#${i}`, item);
14477
- if (rec) out.push(rec);
14478
- });
14479
- } else {
14480
- const rec = toRecordOutput(slot, value);
14481
- if (rec) out.push(rec);
14482
- }
14483
- }
14484
- return out.slice(0, MAX_OUTPUTS_PER_NODE);
14485
- }
14486
- function finalOutputsToRecord(output) {
14487
- if (Array.isArray(output)) {
14488
- return output.map((item, i) => toRecordOutput(`final#${i}`, item)).filter((rec2) => rec2 !== null).slice(0, MAX_FINAL_OUTPUTS);
14489
- }
14490
- const rec = toRecordOutput("final", output);
14491
- return rec ? [rec] : [];
14492
- }
14493
- function buildRunRecord(result, meta) {
14494
- const nodes = result.node_runs.slice(0, MAX_RUN_NODES).map((run) => ({
14495
- nodeId: run.node_id,
14496
- nodeType: run.node_type,
14497
- cached: run.cached,
14498
- credits: run.credits,
14499
- durationMs: run.duration_ms,
14500
- outputs: nodeOutputsToRecord(result.outputs_by_node[run.node_id] ?? {})
14501
- }));
14502
- const finalOutputs = finalOutputsToRecord(result.output);
14503
- return {
14504
- runId: result.run_id,
14505
- creativeSlug: meta.creativeSlug,
14506
- canvasPath: meta.canvasPath,
14507
- canvasSha: meta.canvasSha,
14508
- chatId: meta.chatId,
14509
- status: "completed",
14510
- stats: {
14511
- totalNodes: result.stats.total_nodes,
14512
- cachedNodes: result.stats.cached_nodes,
14513
- totalCredits: result.stats.total_credits,
14514
- durationMs: result.stats.duration_ms
14515
- },
14516
- nodes,
14517
- finalOutputs: finalOutputs.length > 0 ? finalOutputs : void 0
14518
- };
14519
- }
14520
- function buildFailedRunRecord(runId, errorMessage, meta) {
14521
- return {
14522
- runId,
14523
- creativeSlug: meta.creativeSlug,
14524
- canvasPath: meta.canvasPath,
14525
- canvasSha: meta.canvasSha,
14526
- chatId: meta.chatId,
14527
- status: "failed",
14528
- errorMessage: errorMessage.slice(0, 2e3),
14529
- stats: { totalNodes: 0, cachedNodes: 0, totalCredits: 0, durationMs: 0 },
14530
- nodes: []
14531
- };
14532
- }
14533
-
14534
14532
  // src/commands/canvas/run-retention.ts
14535
14533
  import { rm } from "fs/promises";
14536
- import path4 from "path";
14534
+ import path3 from "path";
14537
14535
  function runDirsToPrune(entries, keep, currentRunId) {
14538
14536
  const runs = entries.filter((e) => /^r_[0-9A-Za-z]+$/.test(e) && e !== currentRunId).sort();
14539
14537
  if (keep <= 0) return runs;
@@ -14550,7 +14548,7 @@ async function pruneOldRuns(outputsDir, keep, currentRunId, log) {
14550
14548
  const toPrune = runDirsToPrune(entries, keep, currentRunId);
14551
14549
  if (toPrune.length === 0) return;
14552
14550
  for (const dir of toPrune) {
14553
- await rm(path4.join(outputsDir, dir), { recursive: true, force: true }).catch(
14551
+ await rm(path3.join(outputsDir, dir), { recursive: true, force: true }).catch(
14554
14552
  (e) => log(`[prune ] could not remove ${dir}: ${e.message}`)
14555
14553
  );
14556
14554
  }
@@ -14577,22 +14575,10 @@ var runCommand = defineCommand88({
14577
14575
  "keep-runs": {
14578
14576
  type: "string",
14579
14577
  description: "After the run, prune old r_* run dirs, keeping the N newest (off by default)"
14580
- },
14581
- "remote-cache": {
14582
- type: "string",
14583
- description: "on | off \u2014 company-scoped remote cache + durable asset persistence (default on; env BAKER_CANVAS_REMOTE_CACHE)"
14584
- },
14585
- // citty consumes any `--no-<flag>` as a negation of `<flag>`, so the
14586
- // opt-out spelling `--no-record` requires the flag to be named `record`
14587
- // (a literal "no-record" arg would never receive a value).
14588
- record: {
14589
- type: "boolean",
14590
- default: true,
14591
- description: "Post the durable run-history record to Baker (disable with --no-record)"
14592
14578
  }
14593
14579
  },
14594
14580
  async run({ args }) {
14595
- const filePath = path5.resolve(String(args.file));
14581
+ const filePath = path4.resolve(String(args.file));
14596
14582
  const raw = await readFile2(filePath, "utf8");
14597
14583
  let parsed;
14598
14584
  try {
@@ -14603,7 +14589,7 @@ var runCommand = defineCommand88({
14603
14589
  `);
14604
14590
  process.exit(2);
14605
14591
  }
14606
- parsed = resolveRelativeCanvasPaths(parsed, path5.dirname(filePath));
14592
+ parsed = resolveRelativeCanvasPaths(parsed, path4.dirname(filePath));
14607
14593
  const pending = unsuppliedPlaceholderAssets(parsed);
14608
14594
  if (pending.length > 0) {
14609
14595
  process.stderr.write(
@@ -14623,26 +14609,16 @@ var runCommand = defineCommand88({
14623
14609
  );
14624
14610
  process.exit(2);
14625
14611
  }
14626
- const remoteCache = args["remote-cache"] !== void 0 ? String(args["remote-cache"]) !== "off" : void 0;
14627
14612
  const engine = createEngineFromEnv({
14628
14613
  cacheDir: args["cache-dir"] ? String(args["cache-dir"]) : void 0,
14629
14614
  outputsDir: args["outputs-dir"] ? String(args["outputs-dir"]) : void 0,
14630
14615
  log: (line) => process.stdout.write(`${line}
14631
- `),
14632
- remoteCache
14616
+ `)
14633
14617
  });
14634
- const runId = args["run-id"] ? String(args["run-id"]) : `r_${ulid()}`;
14635
- const recordMeta = {
14636
- creativeSlug: creativeSlugFromCanvasPath(filePath) ?? void 0,
14637
- canvasPath: path5.relative(process.cwd(), filePath) || void 0,
14638
- canvasSha: sha256Hex(Buffer.from(raw)),
14639
- chatId: getEnv().BAKER_CHAT_ID || void 0
14640
- };
14641
- const record = args.record === false ? null : buildRecorder();
14642
14618
  try {
14643
14619
  const policy = args["cache-policy"] ?? "read_write";
14644
14620
  const result = await engine.run(parsed, {
14645
- run_id: runId,
14621
+ run_id: args["run-id"] ? String(args["run-id"]) : void 0,
14646
14622
  cache_policy: policy,
14647
14623
  concurrency: resolveConcurrency(
14648
14624
  // --concurrency wins; --parallel is the discoverable alias for the same bound.
@@ -14650,10 +14626,9 @@ var runCommand = defineCommand88({
14650
14626
  process.env.BAKER_CANVAS_CONCURRENCY
14651
14627
  )
14652
14628
  });
14653
- if (record) await record(buildRunRecord(result, recordMeta));
14654
14629
  const keepRuns = args["keep-runs"] !== void 0 ? Number(args["keep-runs"]) : void 0;
14655
14630
  if (keepRuns !== void 0 && Number.isFinite(keepRuns)) {
14656
- const outputsDir = args["outputs-dir"] ? path5.resolve(String(args["outputs-dir"])) : path5.resolve("canvas");
14631
+ const outputsDir = args["outputs-dir"] ? path4.resolve(String(args["outputs-dir"])) : path4.resolve("canvas");
14657
14632
  await pruneOldRuns(outputsDir, keepRuns, result.run_id, (line) => process.stdout.write(`${line}
14658
14633
  `));
14659
14634
  }
@@ -14681,7 +14656,6 @@ var runCommand = defineCommand88({
14681
14656
  }
14682
14657
  if (e instanceof LayerExecutionError) {
14683
14658
  const failures = e.failures.map((f) => ({ node_id: f.nodeId, message: describeFailureReason(f.reason) }));
14684
- if (record) await record(buildFailedRunRecord(runId, e.message, recordMeta));
14685
14659
  process.stderr.write(
14686
14660
  `${JSON.stringify({ ok: false, error: { code: "runtime", message: e.message, failures } }, null, 2)}
14687
14661
  `
@@ -14689,54 +14663,40 @@ var runCommand = defineCommand88({
14689
14663
  process.exit(1);
14690
14664
  }
14691
14665
  const msg = e instanceof Error ? e.message : String(e);
14692
- if (record) await record(buildFailedRunRecord(runId, msg, recordMeta));
14693
14666
  process.stderr.write(`${JSON.stringify({ ok: false, error: { code: "runtime", message: msg } }, null, 2)}
14694
14667
  `);
14695
14668
  process.exit(1);
14696
14669
  }
14697
14670
  }
14698
14671
  });
14699
- function buildRecorder() {
14700
- return async (payload) => {
14701
- try {
14702
- const creds = requireCredentialsFromEnv();
14703
- const client = new BackendClient({ baseUrl: creds.url, apiKey: creds.apiKey });
14704
- await client.recordRun(payload);
14705
- } catch (e) {
14706
- const msg = e instanceof Error ? e.message : String(e);
14707
- process.stderr.write(`[warn] run record not persisted (${msg})
14708
- `);
14709
- }
14710
- };
14711
- }
14712
14672
 
14713
14673
  // src/commands/canvas/scaffold-static-ad.ts
14714
- import { access, cp, mkdir, readFile as readFile3, writeFile } from "fs/promises";
14715
- import path8 from "path";
14674
+ import { readFile as readFile3, writeFile } from "fs/promises";
14675
+ import path6 from "path";
14716
14676
  import { defineCommand as defineCommand89 } from "citty";
14717
14677
 
14718
14678
  // src/engine/scaffold/staticAd.ts
14719
- import { z as z11 } from "zod";
14679
+ import { z as z12 } from "zod";
14720
14680
  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"]);
14721
14681
  var DEFAULT_ASPECT_RATIO = "9:16";
14722
- var Blueprint = z11.object({
14723
- meta: z11.object({ estimated_aspect_ratio: z11.string().optional() }).loose().optional(),
14724
- text_content: z11.array(z11.object({ text: z11.string().optional() }).loose()).optional()
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()
14725
14685
  }).loose();
14726
- var ElementLocator = z11.object({
14727
- collection: z11.enum(["subjects", "people", "brands_logos"]),
14728
- index: z11.number().int().nonnegative()
14686
+ var ElementLocator = z12.object({
14687
+ collection: z12.enum(["subjects", "people", "brands_logos"]),
14688
+ index: z12.number().int().nonnegative()
14729
14689
  }).loose();
14730
- var MainElement = z11.object({
14690
+ var MainElement = z12.object({
14731
14691
  // logo | product | person | animal | badge | other
14732
- type: z11.string(),
14733
- label: z11.string().optional(),
14734
- description: z11.string().optional(),
14735
- expression: z11.string().nullable().optional(),
14736
- reason: z11.string().optional(),
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(),
14737
14697
  locator: ElementLocator.optional()
14738
14698
  }).loose();
14739
- var MainElements = z11.array(MainElement);
14699
+ var MainElements = z12.array(MainElement);
14740
14700
  function sanitizeId(raw, fallback) {
14741
14701
  const id = raw.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
14742
14702
  return /^[a-z]/.test(id) ? id : `${fallback}_${id}`.replace(/_+$/g, "") || fallback;
@@ -14898,106 +14858,18 @@ function staticAdReport(input, elementsInput, opts) {
14898
14858
  };
14899
14859
  }
14900
14860
 
14901
- // src/commands/canvas/creative-definition.ts
14902
- import path6 from "path";
14903
- var PLATFORM_VALUES = ["meta", "google", "linkedin", "tiktok", "youtube", "x", "other"];
14904
- var FORMAT_VALUES = ["1:1", "4:5", "9:16", "16:9", "1.91:1"];
14905
- function titleFromSlug(slug) {
14906
- const title = slug.split("-").filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
14907
- return title || slug;
14908
- }
14909
- function resolvePlatform(platform) {
14910
- const value = platform?.trim();
14911
- return value && PLATFORM_VALUES.includes(value) ? value : "meta";
14912
- }
14913
- function resolveFormats(aspect) {
14914
- const value = aspect?.trim();
14915
- return value && FORMAT_VALUES.includes(value) ? [value] : ["4:5"];
14916
- }
14917
- function referenceRelativePath(kind, ext) {
14918
- const name = kind === "video" ? "source" : "original";
14919
- return `references/${name}${ext}`;
14920
- }
14921
- function sourceExtension(source, isUrl, kind) {
14922
- const raw = isUrl ? urlPathname(source) : source;
14923
- const ext = path6.extname(raw).toLowerCase();
14924
- if (/^\.[a-z0-9]{1,5}$/.test(ext)) return ext;
14925
- return kind === "video" ? ".mp4" : ".jpg";
14926
- }
14927
- function urlPathname(source) {
14928
- try {
14929
- return new URL(source).pathname;
14930
- } catch {
14931
- return source;
14932
- }
14933
- }
14934
- function describeBlueprintIntent(blueprint) {
14935
- const intent = blueprint?.ad_intent;
14936
- if (typeof intent === "string" && intent.trim()) return intent.trim();
14937
- if (intent && typeof intent === "object") {
14938
- const summary = intent.summary ?? intent.feeling;
14939
- if (typeof summary === "string" && summary.trim()) return summary.trim();
14940
- }
14941
- return void 0;
14942
- }
14943
- function yamlScalar(value) {
14944
- return JSON.stringify(value);
14945
- }
14946
- function buildCreativeDefinition(input) {
14947
- const lines = ["---", `title: ${yamlScalar(input.title)}`, `kind: ${input.kind}`, `platform: ${input.platform}`];
14948
- lines.push(`formats: [${input.formats.map(yamlScalar).join(", ")}]`);
14949
- lines.push(`status: ${input.status ?? "draft"}`);
14950
- if (input.sourceReferenceUrl) lines.push(`sourceReferenceUrl: ${yamlScalar(input.sourceReferenceUrl)}`);
14951
- if (input.sourceAdvertiser) lines.push(`sourceAdvertiser: ${yamlScalar(input.sourceAdvertiser)}`);
14952
- if (input.sourceKind) lines.push(`sourceKind: ${input.sourceKind}`);
14953
- if (input.sourcePath) lines.push(`sourcePath: ${yamlScalar(input.sourcePath)}`);
14954
- lines.push("---", "");
14955
- lines.push(input.description?.trim() || `${input.title} \u2014 canvas-built ${input.kind} ad for ${input.platform}.`);
14956
- lines.push("");
14957
- return lines.join("\n");
14958
- }
14959
-
14960
14861
  // src/commands/canvas/scaffold-static-ad-paths.ts
14961
- import path7 from "path";
14962
- function resolveScaffoldStaticAdPaths(rawFile, out, cwd = process.cwd(), slug) {
14862
+ import path5 from "path";
14863
+ function resolveScaffoldStaticAdPaths(rawFile, out, cwd = process.cwd()) {
14963
14864
  const file = rawFile.trim();
14964
14865
  const imageIsUrl = /^https?:\/\//i.test(file);
14965
- const imageSource = imageIsUrl ? file : path7.resolve(cwd, file);
14966
- 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");
14967
- const blueprintPath = path7.join(path7.dirname(outPath), "prompt.json");
14968
- const creativeDir = slug ? path7.dirname(outPath) : null;
14969
- const definitionPath = creativeDir ? path7.join(creativeDir, "_definition.md") : null;
14970
- const referencesDir = creativeDir ? path7.join(creativeDir, "references") : null;
14971
- return { imageIsUrl, imageSource, outPath, blueprintPath, creativeDir, definitionPath, referencesDir };
14972
- }
14973
- var SCAFFOLD_SLUG_PATTERN = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
14974
- var SCAFFOLD_SLUG_MAX_LENGTH = 100;
14975
- function isValidScaffoldSlug(slug) {
14976
- return slug.length <= SCAFFOLD_SLUG_MAX_LENGTH && SCAFFOLD_SLUG_PATTERN.test(slug);
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 };
14977
14870
  }
14978
14871
 
14979
14872
  // src/commands/canvas/scaffold-static-ad.ts
14980
- async function fileExists(target) {
14981
- try {
14982
- await access(target);
14983
- return true;
14984
- } catch {
14985
- return false;
14986
- }
14987
- }
14988
- async function copySourceIntoReferences(source, isUrl, referencesDir) {
14989
- await mkdir(referencesDir, { recursive: true });
14990
- const relPath = referenceRelativePath("image", sourceExtension(source, isUrl, "image"));
14991
- const dest = path8.join(referencesDir, path8.basename(relPath));
14992
- if (isUrl) {
14993
- const res = await fetch(source);
14994
- if (!res.ok) throw new Error(`failed to download source image (${res.status})`);
14995
- await writeFile(dest, Buffer.from(await res.arrayBuffer()));
14996
- } else {
14997
- await cp(source, dest);
14998
- }
14999
- return relPath;
15000
- }
15001
14873
  function resolveModel(kind, preferred) {
15002
14874
  const ids = Object.keys(MODEL_REGISTRY[kind]);
15003
14875
  return ids.includes(preferred) ? preferred : ids[0] ?? preferred;
@@ -15157,16 +15029,6 @@ var scaffoldStaticAdCommand = defineCommand89({
15157
15029
  file: { type: "positional", required: true, description: "Path or http(s) URL to the source/inspiration image" },
15158
15030
  context: { type: "string", description: "Known provenance (advertiser, category, market) to ground the describe" },
15159
15031
  out: { type: "string", description: "Output canvas path (default <image-dir>/static-ad.canvas.json)" },
15160
- slug: {
15161
- type: "string",
15162
- description: "Creative slug \u2014 writes the canvas to src/creatives/<slug>/<slug>.canvas.json (repo convention)"
15163
- },
15164
- title: { type: "string", description: "Creative title for _definition.md (default: title-cased slug)" },
15165
- platform: {
15166
- type: "string",
15167
- description: "Ad platform for _definition.md (meta|google|linkedin|tiktok|youtube|x|other; default meta)"
15168
- },
15169
- advertiser: { type: "string", description: "Source advertiser recorded in _definition.md" },
15170
15032
  "describe-model": { type: "string", description: "Override the image_describe model id" },
15171
15033
  "select-model": { type: "string", description: "Override the text_generate model id for element selection" },
15172
15034
  "layout-model": { type: "string", description: "Override the text_generate model id for the layout pass" },
@@ -15175,21 +15037,10 @@ var scaffoldStaticAdCommand = defineCommand89({
15175
15037
  "skip-font": { type: "boolean", description: "Skip the brand-font \u2192 type-specimen slot" }
15176
15038
  },
15177
15039
  async run({ args }) {
15178
- const slug = args.slug ? String(args.slug) : void 0;
15179
- if (slug && !isValidScaffoldSlug(slug)) {
15180
- process.stderr.write(
15181
- `${JSON.stringify({ ok: false, error: { code: "invalid_slug", message: "--slug must be lowercase kebab (a-z, 0-9, hyphens), max 100 chars" } }, null, 2)}
15182
- `
15183
- );
15184
- process.exit(2);
15185
- }
15186
- const { imageIsUrl, imageSource, outPath, blueprintPath, definitionPath, referencesDir } = resolveScaffoldStaticAdPaths(
15040
+ const { imageIsUrl, imageSource, outPath, blueprintPath } = resolveScaffoldStaticAdPaths(
15187
15041
  String(args.file),
15188
- args.out ? String(args.out) : void 0,
15189
- process.cwd(),
15190
- slug
15042
+ args.out ? String(args.out) : void 0
15191
15043
  );
15192
- await mkdir(path8.dirname(outPath), { recursive: true });
15193
15044
  const { describeModel, selectModel, layoutModel, genModel } = resolveModels(args);
15194
15045
  const describeCanvas = buildDescribeCanvas(
15195
15046
  imageSource,
@@ -15206,21 +15057,11 @@ var scaffoldStaticAdCommand = defineCommand89({
15206
15057
  }
15207
15058
  await writeFile(blueprintPath, `${JSON.stringify(annotated, null, 2)}
15208
15059
  `, "utf8");
15209
- let canvasImagePath = imageSource;
15210
- let canvasImageIsUrl = imageIsUrl;
15211
- let canvasBlueprintPath = blueprintPath;
15212
- let sourceRelPath;
15213
- if (referencesDir) {
15214
- sourceRelPath = await copySourceIntoReferences(imageSource, imageIsUrl, referencesDir);
15215
- canvasImagePath = sourceRelPath;
15216
- canvasImageIsUrl = false;
15217
- canvasBlueprintPath = "./prompt.json";
15218
- }
15219
15060
  const opts = {
15220
15061
  genModel,
15221
- imagePath: canvasImagePath,
15222
- imageIsUrl: canvasImageIsUrl,
15223
- blueprintPath: canvasBlueprintPath,
15062
+ imagePath: imageSource,
15063
+ imageIsUrl,
15064
+ blueprintPath,
15224
15065
  aspectRatio: args.aspect ? String(args.aspect) : void 0,
15225
15066
  includeFont: !args["skip-font"]
15226
15067
  };
@@ -15242,31 +15083,12 @@ var scaffoldStaticAdCommand = defineCommand89({
15242
15083
  }
15243
15084
  await writeFile(outPath, `${JSON.stringify(canvas, null, 2)}
15244
15085
  `, "utf8");
15245
- if (definitionPath && !await fileExists(definitionPath)) {
15246
- await writeFile(
15247
- definitionPath,
15248
- buildCreativeDefinition({
15249
- title: args.title ? String(args.title) : titleFromSlug(slug ?? ""),
15250
- kind: "static",
15251
- platform: resolvePlatform(args.platform ? String(args.platform) : void 0),
15252
- formats: resolveFormats(args.aspect ? String(args.aspect) : report.aspect_ratio),
15253
- sourceReferenceUrl: imageIsUrl ? imageSource : void 0,
15254
- sourceAdvertiser: args.advertiser ? String(args.advertiser) : args.context ? String(args.context) : void 0,
15255
- sourceKind: "image",
15256
- sourcePath: sourceRelPath,
15257
- description: describeBlueprintIntent(blueprint)
15258
- }),
15259
- "utf8"
15260
- );
15261
- }
15262
15086
  process.stdout.write(
15263
15087
  `${JSON.stringify(
15264
15088
  {
15265
15089
  ok: true,
15266
15090
  canvas_path: outPath,
15267
15091
  prompt_path: blueprintPath,
15268
- definition_path: definitionPath ?? void 0,
15269
- source_reference: sourceRelPath ?? void 0,
15270
15092
  output: canvas.output,
15271
15093
  models: { describe: describeModel, select: selectModel, layout: layoutModel, gen: opts.genModel },
15272
15094
  aspect_ratio: report.aspect_ratio,
@@ -15277,7 +15099,7 @@ var scaffoldStaticAdCommand = defineCommand89({
15277
15099
  run_estimated_credits: validation.estimatedCredits
15278
15100
  },
15279
15101
  checklist: {
15280
- 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.`,
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.`,
15281
15103
  assets_to_supply: report.elements,
15282
15104
  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)",
15283
15105
  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."
@@ -15292,8 +15114,8 @@ var scaffoldStaticAdCommand = defineCommand89({
15292
15114
  });
15293
15115
 
15294
15116
  // src/commands/canvas/scaffold-video.ts
15295
- import { cp as cp2, mkdir as mkdir2, readFile as readFile6, writeFile as writeFile2 } from "fs/promises";
15296
- import path11 from "path";
15117
+ import { cp, mkdir, readFile as readFile6, writeFile as writeFile2 } from "fs/promises";
15118
+ import path9 from "path";
15297
15119
  import { defineCommand as defineCommand90 } from "citty";
15298
15120
 
15299
15121
  // src/engine/nodes/local/lib/sceneDetect.ts
@@ -15410,7 +15232,7 @@ import { toCardinal as nwKo } from "n2words/ko-KR";
15410
15232
  import { toCardinal as nwNl } from "n2words/nl-NL";
15411
15233
  import { toCardinal as nwPl } from "n2words/pl-PL";
15412
15234
  import { toCardinal as nwPt } from "n2words/pt-PT";
15413
- import { z as z12 } from "zod";
15235
+ import { z as z13 } from "zod";
15414
15236
 
15415
15237
  // src/engine/scaffold/lib/shoot-modes.ts
15416
15238
  var SHOOT_MODES = [
@@ -15723,71 +15545,71 @@ function trimArgs(durationS, offsetS = 0, dims) {
15723
15545
  "{{out.video}}"
15724
15546
  ];
15725
15547
  }
15726
- var FrameAsset = z12.object({ url: z12.string().optional() }).loose().optional();
15727
- var DialogueLine = z12.object({
15728
- speaker: z12.string().optional(),
15729
- line: z12.string().optional(),
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(),
15730
15552
  // Absolute seconds on the source timeline (the deconstruct emits both).
15731
- start_s: z12.number().optional(),
15732
- end_s: z12.number().optional(),
15733
- delivery: z12.string().optional(),
15734
- voice_description: z12.string().optional(),
15553
+ start_s: z13.number().optional(),
15554
+ end_s: z13.number().optional(),
15555
+ delivery: z13.string().optional(),
15556
+ voice_description: z13.string().optional(),
15735
15557
  // DECON-supplied: is this speaker's FACE visibly speaking in THIS scene? Element
15736
15558
  // presence alone can't answer that — a founder pictured in a polaroid close-up is
15737
15559
  // "present" yet the line is voiceover, and treating it as on-camera produced a
15738
15560
  // native Seedance lip-sync clip of a still photograph. `false` pins the line to
15739
15561
  // the VO path; absent keeps the presence-based decision (old blueprints).
15740
- on_camera: z12.boolean().optional()
15562
+ on_camera: z13.boolean().optional()
15741
15563
  }).loose();
15742
- var Sfx = z12.object({
15743
- at_s: z12.number().optional(),
15744
- duration_s: z12.number().optional(),
15745
- sound_effect_prompt: z12.string().optional(),
15746
- description: z12.string().optional()
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()
15747
15569
  }).loose();
15748
- var CompositionRegion = z12.object({
15570
+ var CompositionRegion = z13.object({
15749
15571
  // full | top | bottom | left | right | inset
15750
- panel: z12.string().optional(),
15572
+ panel: z13.string().optional(),
15751
15573
  // 9-grid anchor for an `inset` presenter box.
15752
- position: z12.string().optional(),
15753
- is_presenter: z12.boolean().optional(),
15574
+ position: z13.string().optional(),
15575
+ is_presenter: z13.boolean().optional(),
15754
15576
  // The cast id shown/speaking in this region (routes lip-sync + element refs).
15755
- cast_ref: z12.string().optional(),
15577
+ cast_ref: z13.string().optional(),
15756
15578
  // What the region's content IS: camera | screen_capture | static_graphic |
15757
15579
  // generated. Authoritative for routing when present (regex-over-prose fallback
15758
15580
  // otherwise): screen_capture/static_graphic are rebuilt from REAL surfaces on the
15759
15581
  // overlay layer, never AI-generated.
15760
- kind: z12.string().optional(),
15582
+ kind: z13.string().optional(),
15761
15583
  // Opaque id naming the SPECIFIC on-screen document/note/app-state this
15762
15584
  // screen_capture region shows. Two scenes share it only when they show the SAME
15763
15585
  // recording continuing (scrolling/typing/waiting within it) — a genuinely
15764
15586
  // DIFFERENT document/note/recording (a source video splicing two screen captures)
15765
15587
  // gets a different id. Breaks a persistent-layout run into separate surface stubs
15766
15588
  // instead of asking the operator for one screenshot that can't cover both.
15767
- surface_id: z12.string().optional(),
15589
+ surface_id: z13.string().optional(),
15768
15590
  // Camera bubble(s)/inset(s) embedded INSIDE this region's surface (a Loom-style
15769
15591
  // presenter bubble inside a screen recording) — video-in-video the reproduction
15770
15592
  // must re-composite, not paint into the surface.
15771
- nested: z12.array(z12.object({}).loose()).optional(),
15772
- summary: z12.string().optional(),
15773
- frame_prompt: z12.string().optional(),
15774
- motion_prompt: z12.string().optional()
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()
15775
15597
  }).loose();
15776
- var SceneComposition = z12.object({
15598
+ var SceneComposition = z13.object({
15777
15599
  // full_frame (default) | split_screen | pip | keyed_overlay
15778
- layout: z12.string().optional(),
15600
+ layout: z13.string().optional(),
15779
15601
  // split_screen only: vertical (top/bottom) | horizontal (left/right).
15780
- split_axis: z12.string().optional(),
15781
- regions: z12.array(CompositionRegion).optional()
15602
+ split_axis: z13.string().optional(),
15603
+ regions: z13.array(CompositionRegion).optional()
15782
15604
  }).loose();
15783
- var CameraMotion = z12.object({ movement: z12.string().optional(), detail: z12.string().optional() }).loose();
15784
- var TranscriptWord = z12.object({ text: z12.string().optional() }).loose();
15785
- var Scene = z12.object({
15786
- start_s: z12.number().optional(),
15787
- end_s: z12.number().optional(),
15788
- duration_s: z12.number().optional(),
15789
- summary: z12.string().optional(),
15790
- action_detail: z12.string().optional(),
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(),
15791
15613
  // The scene's spatial layout. Absent/full_frame ⇒ one uncut shot (default path).
15792
15614
  // A layered layout (split_screen/pip/keyed_overlay) with regions ⇒ the scaffold
15793
15615
  // builds one clip per region and stacks/overlays them into the scene picture.
@@ -15795,82 +15617,82 @@ var Scene = z12.object({
15795
15617
  // The capture "look" for this scene — selected from the ad-native shoot-mode
15796
15618
  // grammar (see lib/shoot-modes.ts). When absent the scaffold auto-derives a
15797
15619
  // UGC/product mode; a human can override per scene by setting this.
15798
- shoot_mode: z12.string().optional(),
15620
+ shoot_mode: z13.string().optional(),
15799
15621
  // Diegetic ambient the clip's native audio should carry (no music). When
15800
15622
  // absent the scene falls back to its shoot mode's default ambience.
15801
- ambient: z12.string().optional(),
15623
+ ambient: z13.string().optional(),
15802
15624
  camera_motion: CameraMotion.optional(),
15803
- start_frame_prompt: z12.string().optional(),
15804
- end_frame_prompt: z12.string().optional(),
15805
- motion_prompt: z12.string().optional(),
15625
+ start_frame_prompt: z13.string().optional(),
15626
+ end_frame_prompt: z13.string().optional(),
15627
+ motion_prompt: z13.string().optional(),
15806
15628
  // The scene's role in the ad's persuasion arc (DECON-supplied); drives the
15807
15629
  // script re-craft checklist. Inferred from position when absent.
15808
- narrative_role: z12.string().optional(),
15630
+ narrative_role: z13.string().optional(),
15809
15631
  // DECON-supplied on the HOOK scene: the engineered physical/emotional state that
15810
15632
  // makes the first frame stop the scroll (sweaty/breathless/urgent …). Injected
15811
15633
  // into the hook's start-frame description so the generator renders that state,
15812
15634
  // not a calm influencer (CCA-11).
15813
- hook_mechanic: z12.object({ mechanic: z12.string().optional(), why_it_stops_scroll: z12.string().optional() }).loose().optional(),
15635
+ hook_mechanic: z13.object({ mechanic: z13.string().optional(), why_it_stops_scroll: z13.string().optional() }).loose().optional(),
15814
15636
  // DECON-supplied per-scene location (so a gym hook isn't flattened to "home").
15815
- scene_setting: z12.string().optional(),
15637
+ scene_setting: z13.string().optional(),
15816
15638
  // How this scene cuts to the next (DECON-supplied). A recognized non-cut type
15817
15639
  // (fade/whip/zoom/dissolve/swipe) is reproduced as an ffmpeg xfade at the
15818
15640
  // boundary; cut/match_cut/none/other stay hard cuts. The last scene's value is
15819
15641
  // ignored (nothing follows it).
15820
- transition_out: z12.object({ type: z12.string().optional(), description: z12.string().optional() }).loose().optional(),
15821
- dialogue: z12.array(DialogueLine).optional(),
15822
- sfx: z12.array(Sfx).optional(),
15823
- overlays: z12.array(z12.unknown()).optional(),
15824
- floating_elements: z12.array(z12.unknown()).optional(),
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(),
15825
15647
  // DECON-supplied: how much the picture itself moves within the shot. Gates the
15826
15648
  // flash-hold optimization — a sub-2s b-roll flash with REAL subject motion
15827
15649
  // (pouring, spreading, hands working) must stay a real clip; freezing it turns
15828
15650
  // a montage into a slideshow. Absent (old blueprints) keeps the cheap still.
15829
- motion_level: z12.enum(["static", "subtle", "dynamic"]).optional(),
15830
- transcript_slice: z12.array(TranscriptWord).optional(),
15651
+ motion_level: z13.enum(["static", "subtle", "dynamic"]).optional(),
15652
+ transcript_slice: z13.array(TranscriptWord).optional(),
15831
15653
  start_frame_asset: FrameAsset,
15832
15654
  end_frame_asset: FrameAsset,
15833
15655
  // DECON-supplied: true when this scene is a length-split CONTINUATION of the
15834
15656
  // previous one (the SAME physical shot, broken up only because it exceeded the
15835
15657
  // clip ceiling). The scaffold then shares the splice keyframe — this scene's
15836
15658
  // start frame IS the previous scene's end frame — so the join is seamless.
15837
- continues_previous: z12.boolean().optional()
15659
+ continues_previous: z13.boolean().optional()
15838
15660
  }).loose();
15839
- var VideoBlueprint = z12.object({
15840
- source: z12.object({ aspect_ratio: z12.string().optional(), duration_s: z12.number().optional() }).loose().optional(),
15841
- global: z12.object({
15842
- music: z12.object({
15843
- present: z12.boolean().optional(),
15844
- music_prompt: z12.string().optional(),
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(),
15845
15667
  // Absolute second the music enters in the reference (the bed often
15846
15668
  // kicks in mid-ad, after the hook). We start the regenerated track here
15847
15669
  // instead of at 0 so the timing matches.
15848
- starts_at_s: z12.number().optional(),
15670
+ starts_at_s: z13.number().optional(),
15849
15671
  // Populated by the deconstruct when AudD (Shazam-style) recognizes the
15850
15672
  // reference track. We never reuse it — only style the regenerated bed.
15851
- identified_track: z12.object({ title: z12.string().optional(), artist: z12.string().optional() }).loose().nullish()
15673
+ identified_track: z13.object({ title: z13.string().optional(), artist: z13.string().optional() }).loose().nullish()
15852
15674
  }).loose().optional(),
15853
- cast: z12.array(
15854
- z12.object({
15855
- id: z12.string().optional(),
15856
- description: z12.string().optional(),
15675
+ cast: z13.array(
15676
+ z13.object({
15677
+ id: z13.string().optional(),
15678
+ description: z13.string().optional(),
15857
15679
  // The deconstruct's note on the target-market localization (e.g. "native
15858
15680
  // French speaker") — read to derive the spoken-track language code.
15859
- market_localization_note: z12.string().optional()
15681
+ market_localization_note: z13.string().optional()
15860
15682
  }).loose()
15861
15683
  ).optional(),
15862
- voiceover: z12.object({
15684
+ voiceover: z13.object({
15863
15685
  // on_camera | mixed → mouths are on screen (lip-sync candidates);
15864
15686
  // voiceover | none → narration over the picture (no lip-sync).
15865
- mode: z12.string().optional(),
15866
- voice_description: z12.string().optional(),
15867
- persona: z12.string().optional()
15687
+ mode: z13.string().optional(),
15688
+ voice_description: z13.string().optional(),
15689
+ persona: z13.string().optional()
15868
15690
  }).loose().optional(),
15869
15691
  // Visual palette — read only to colour a clean brand-card/CTA plate (the
15870
15692
  // first hex is the dominant brand colour); never to drive frame generation.
15871
- style: z12.object({ palette: z12.array(z12.object({ hex: z12.string().optional() }).loose()).optional() }).loose().optional()
15693
+ style: z13.object({ palette: z13.array(z13.object({ hex: z13.string().optional() }).loose()).optional() }).loose().optional()
15872
15694
  }).loose().optional(),
15873
- scenes: z12.array(Scene).min(1)
15695
+ scenes: z13.array(Scene).min(1)
15874
15696
  }).loose();
15875
15697
  function injectHookPhysicality(blueprint) {
15876
15698
  for (const scene of blueprint.scenes) {
@@ -15880,26 +15702,26 @@ function injectHookPhysicality(blueprint) {
15880
15702
  scene.start_frame_prompt = `${prompt} The subject's physical state IS the scroll-stopper \u2014 render it explicitly, not a calm pose: ${why}.`;
15881
15703
  }
15882
15704
  }
15883
- var AppearsItem = z12.union([z12.number(), z12.object({ scene: z12.number(), edge: z12.string().optional() }).loose()]);
15884
- var RecurringElement = z12.object({
15705
+ var AppearsItem = z13.union([z13.number(), z13.object({ scene: z13.number(), edge: z13.string().optional() }).loose()]);
15706
+ var RecurringElement = z13.object({
15885
15707
  // person | animal | product | logo | badge | other
15886
- type: z12.string(),
15887
- label: z12.string().optional(),
15888
- description: z12.string().optional(),
15889
- expression: z12.string().nullable().optional(),
15708
+ type: z13.string(),
15709
+ label: z13.string().optional(),
15710
+ description: z13.string().optional(),
15711
+ expression: z13.string().nullable().optional(),
15890
15712
  // When the element maps to a global cast entry, its stable id (for annotation).
15891
- cast_id: z12.string().nullable().optional(),
15713
+ cast_id: z13.string().nullable().optional(),
15892
15714
  // The label of another element that is the SAME individual as this one, shown
15893
15715
  // in a DIFFERENT wardrobe/persona/state (e.g. one creator playing skeptic in a
15894
15716
  // pink shirt and believer in a white shirt). Each look gets its own reference
15895
15717
  // slot, but the face/identity must stay identical across them.
15896
- same_as: z12.string().nullable().optional(),
15718
+ same_as: z13.string().nullable().optional(),
15897
15719
  // Scenes the element appears in. Either a bare list of scene indices (both
15898
15720
  // edges) or per-{scene,edge} entries. Both forms are accepted and merged.
15899
- scenes: z12.array(z12.number()).optional(),
15900
- appears_in: z12.array(AppearsItem).optional()
15721
+ scenes: z13.array(z13.number()).optional(),
15722
+ appears_in: z13.array(AppearsItem).optional()
15901
15723
  }).loose();
15902
- var RecurringElements = z12.array(RecurringElement);
15724
+ var RecurringElements = z13.array(RecurringElement);
15903
15725
  function sanitizeId2(raw, fallback) {
15904
15726
  const id = raw.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
15905
15727
  return /^[a-z]/.test(id) ? id : `${fallback}_${id}`.replace(/_+$/g, "") || fallback;
@@ -16317,7 +16139,7 @@ function scrubFloatSentences(text, floatDescs) {
16317
16139
  return kept;
16318
16140
  }
16319
16141
  function sceneFloatDescs(scene) {
16320
- const floats = z12.array(FloatingElement).safeParse(scene.floating_elements ?? []);
16142
+ const floats = z13.array(FloatingElement).safeParse(scene.floating_elements ?? []);
16321
16143
  if (!floats.success) return [];
16322
16144
  return floats.data.map((f) => f.description?.trim() ?? "").filter(Boolean);
16323
16145
  }
@@ -17657,25 +17479,25 @@ function buildSfxMusic(blueprint, nodes) {
17657
17479
  }
17658
17480
  return tracks;
17659
17481
  }
17660
- var OverlayStyle = z12.object({ color_hex: z12.string().optional(), background: z12.string().optional(), size: z12.string().optional() }).loose();
17661
- var Overlay = z12.object({
17662
- text: z12.string().optional(),
17663
- appears_at_s: z12.number().optional(),
17664
- duration_s: z12.number().optional(),
17665
- position: z12.string().optional(),
17666
- role: z12.string().optional(),
17667
- animation: z12.string().optional(),
17668
- animation_detail: z12.string().optional(),
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(),
17669
17491
  style: OverlayStyle.optional()
17670
17492
  }).loose();
17671
- var FloatingElement = z12.object({
17672
- kind: z12.string().optional(),
17673
- description: z12.string().optional(),
17674
- brand_name: z12.string().nullish(),
17675
- what_it_represents: z12.string().optional(),
17676
- appears_at_s: z12.number().optional(),
17677
- duration_s: z12.number().optional(),
17678
- position: z12.string().optional()
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()
17679
17501
  }).loose();
17680
17502
  function escapeHtml(s) {
17681
17503
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
@@ -17707,7 +17529,7 @@ function positionClass(position) {
17707
17529
  function collectCaptions(blueprint) {
17708
17530
  return blueprint.scenes.flatMap((scene) => {
17709
17531
  const sceneStart = scene.start_s ?? 0;
17710
- const overlays = z12.array(Overlay).safeParse(scene.overlays ?? []);
17532
+ const overlays = z13.array(Overlay).safeParse(scene.overlays ?? []);
17711
17533
  return overlays.success ? overlays.data.filter((ov) => Boolean(ov.text?.trim())).map((ov) => {
17712
17534
  const at = ov.appears_at_s ?? sceneStart;
17713
17535
  return { text: ov.text.trim(), at, end: at + (ov.duration_s ?? 2.5), ov };
@@ -17787,7 +17609,7 @@ function collectFloatWindows(blueprint, uiRouted) {
17787
17609
  const windows = /* @__PURE__ */ new Map();
17788
17610
  blueprint.scenes.forEach((scene, i) => {
17789
17611
  const sceneStart = scene.start_s ?? 0;
17790
- const floats = z12.array(FloatingElement).safeParse(scene.floating_elements ?? []);
17612
+ const floats = z13.array(FloatingElement).safeParse(scene.floating_elements ?? []);
17791
17613
  if (!floats.success) return;
17792
17614
  for (const fe of floats.data) {
17793
17615
  const at = fe.appears_at_s ?? sceneStart;
@@ -18173,8 +17995,8 @@ function buildMotionBoard(blueprint) {
18173
17995
  const end_s = scene.end_s ?? start_s + sceneDurationS(scene);
18174
17996
  cursor = end_s;
18175
17997
  const spoken = sceneSpokenText(scene);
18176
- const overlays = z12.array(Overlay).safeParse(scene.overlays ?? []);
18177
- const floats = z12.array(FloatingElement).safeParse(scene.floating_elements ?? []);
17998
+ const overlays = z13.array(Overlay).safeParse(scene.overlays ?? []);
17999
+ const floats = z13.array(FloatingElement).safeParse(scene.floating_elements ?? []);
18178
18000
  const graphics = [
18179
18001
  ...(overlays.success ? overlays.data : []).filter((ov) => ov.text?.trim()).map((ov) => ({
18180
18002
  kind: "text",
@@ -18401,23 +18223,23 @@ function videoReport(input, elementsInput) {
18401
18223
 
18402
18224
  // src/commands/canvas/composition-path.ts
18403
18225
  import { existsSync as existsSync3 } from "fs";
18404
- import path9 from "path";
18226
+ import path7 from "path";
18405
18227
  function resolveShippedCanvasDir(name, startDir, exists = existsSync3, maxDepth = 8) {
18406
- const rel = path9.join("canvas", name);
18228
+ const rel = path7.join("canvas", name);
18407
18229
  let dir = startDir;
18408
18230
  for (let i = 0; i < maxDepth; i++) {
18409
- const candidate = path9.join(dir, rel);
18410
- if (exists(path9.join(candidate, "meta.json"))) return candidate;
18411
- const parent = path9.dirname(dir);
18231
+ const candidate = path7.join(dir, rel);
18232
+ if (exists(path7.join(candidate, "meta.json"))) return candidate;
18233
+ const parent = path7.dirname(dir);
18412
18234
  if (parent === dir) break;
18413
18235
  dir = parent;
18414
18236
  }
18415
- return path9.resolve(startDir, "../../../", rel);
18237
+ return path7.resolve(startDir, "../../../", rel);
18416
18238
  }
18417
18239
 
18418
18240
  // src/commands/canvas/gitignore.ts
18419
18241
  import { appendFile, readFile as readFile5 } from "fs/promises";
18420
- import path10 from "path";
18242
+ import path8 from "path";
18421
18243
  function missingGitignoreEntries(existing, entries) {
18422
18244
  const present = new Set(
18423
18245
  existing.split("\n").map((l) => l.trim().replace(/\/+$/, "")).filter((l) => l.length > 0 && !l.startsWith("#"))
@@ -18425,7 +18247,7 @@ function missingGitignoreEntries(existing, entries) {
18425
18247
  return entries.filter((e) => !present.has(e.trim().replace(/\/+$/, "")));
18426
18248
  }
18427
18249
  async function ensureGitignore(dir, entries) {
18428
- const file = path10.join(dir, ".gitignore");
18250
+ const file = path8.join(dir, ".gitignore");
18429
18251
  let existing;
18430
18252
  try {
18431
18253
  existing = await readFile5(file, "utf8");
@@ -18486,8 +18308,8 @@ async function loadTranscriptBestEffort(ref) {
18486
18308
  async function stageCaptions(outDir, transcript) {
18487
18309
  const text = transcript?.trim();
18488
18310
  if (!text || text === "[]") return {};
18489
- const compositionPath = path11.join(outDir, "tiktok-captions-composition");
18490
- await cp2(SHIPPED_CAPTIONS_DIR, compositionPath, { recursive: true });
18311
+ const compositionPath = path9.join(outDir, "tiktok-captions-composition");
18312
+ await cp(SHIPPED_CAPTIONS_DIR, compositionPath, { recursive: true });
18491
18313
  return { compositionPath };
18492
18314
  }
18493
18315
  function patchCompositionMeta(metaJson, dims) {
@@ -18504,10 +18326,10 @@ function patchCompositionHtml(html, dims) {
18504
18326
  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`);
18505
18327
  }
18506
18328
  async function stampCompositionDims(compositionDir, dims) {
18507
- const metaPath = path11.join(compositionDir, "meta.json");
18329
+ const metaPath = path9.join(compositionDir, "meta.json");
18508
18330
  const rawMeta = await readFile6(metaPath, "utf8");
18509
18331
  await writeFile2(metaPath, patchCompositionMeta(rawMeta, dims), "utf8");
18510
- const htmlPath = path11.join(compositionDir, "index.html");
18332
+ const htmlPath = path9.join(compositionDir, "index.html");
18511
18333
  const rawHtml = await readFile6(htmlPath, "utf8");
18512
18334
  await writeFile2(htmlPath, patchCompositionHtml(rawHtml, dims), "utf8");
18513
18335
  }
@@ -18647,10 +18469,6 @@ var scaffoldVideoCommand = defineCommand90({
18647
18469
  args: {
18648
18470
  file: { type: "positional", required: true, description: "Path to the reference video" },
18649
18471
  out: { type: "string", description: "Output canvas path (default <video-dir>/<name>.video.canvas.json)" },
18650
- slug: {
18651
- type: "string",
18652
- description: "Creative slug \u2014 writes the canvas to src/creatives/<slug>/<slug>.canvas.json (repo convention)"
18653
- },
18654
18472
  frames: { type: "string", description: '"generate" (default, anchored regen) or "reuse" (wire real frames in)' },
18655
18473
  ambient: {
18656
18474
  type: "boolean",
@@ -18677,19 +18495,11 @@ var scaffoldVideoCommand = defineCommand90({
18677
18495
  }
18678
18496
  },
18679
18497
  async run({ args }) {
18680
- const videoPath = path11.resolve(String(args.file));
18681
- const base = path11.basename(videoPath, path11.extname(videoPath));
18682
- const slug = args.slug ? String(args.slug) : void 0;
18683
- if (slug && !isValidScaffoldSlug(slug)) {
18684
- process.stderr.write(
18685
- `${JSON.stringify({ ok: false, error: { code: "invalid_slug", message: "--slug must be lowercase kebab (a-z, 0-9, hyphens), max 100 chars" } }, null, 2)}
18686
- `
18687
- );
18688
- process.exit(2);
18689
- }
18690
- 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`);
18691
- const outDir = path11.dirname(outPath);
18692
- const blueprintPath = path11.join(outDir, "prompt.json");
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");
18693
18503
  const frames = args.frames === "reuse" ? "reuse" : "generate";
18694
18504
  const maxScenes = args["max-scenes"] ? Number(args["max-scenes"]) : void 0;
18695
18505
  if (Number.isFinite(maxScenes)) {
@@ -18708,7 +18518,7 @@ var scaffoldVideoCommand = defineCommand90({
18708
18518
  shotCuts
18709
18519
  });
18710
18520
  const { blueprint, elements, transcript, creditsSpent } = await runAnalysisPasses(deconstructCanvas, selectModel);
18711
- await mkdir2(outDir, { recursive: true });
18521
+ await mkdir(outDir, { recursive: true });
18712
18522
  const annotated = annotateBlueprintWithElements(blueprint, elements);
18713
18523
  await writeFile2(blueprintPath, `${JSON.stringify(annotated, null, 2)}
18714
18524
  `, "utf8");
@@ -18729,10 +18539,10 @@ var scaffoldVideoCommand = defineCommand90({
18729
18539
  `
18730
18540
  );
18731
18541
  }
18732
- const compositionDest = path11.join(outDir, "video-overlay-composition");
18733
- await cp2(SHIPPED_COMPOSITION_DIR, compositionDest, { recursive: true });
18542
+ const compositionDest = path9.join(outDir, "video-overlay-composition");
18543
+ await cp(SHIPPED_COMPOSITION_DIR, compositionDest, { recursive: true });
18734
18544
  await stampCompositionDims(compositionDest, outDims);
18735
- const indexPath = path11.join(compositionDest, "index.html");
18545
+ const indexPath = path9.join(compositionDest, "index.html");
18736
18546
  const overlayHtml = buildOverlayHtml(blueprint, { captionsActive: Boolean(transcript) });
18737
18547
  const indexHtml = await readFile6(indexPath, "utf8");
18738
18548
  const injected = indexHtml.replace("<!--OVERLAYS-->", () => overlayHtml);
@@ -18748,9 +18558,9 @@ var scaffoldVideoCommand = defineCommand90({
18748
18558
  const opts = {
18749
18559
  imageModel,
18750
18560
  videoModel,
18751
- overlayCompositionPath: path11.relative(outDir, compositionDest),
18752
- captionsCompositionPath: captions.compositionPath ? path11.relative(outDir, captions.compositionPath) : void 0,
18753
- blueprintPath: path11.relative(outDir, blueprintPath),
18561
+ overlayCompositionPath: path9.relative(outDir, compositionDest),
18562
+ captionsCompositionPath: captions.compositionPath ? path9.relative(outDir, captions.compositionPath) : void 0,
18563
+ blueprintPath: path9.relative(outDir, blueprintPath),
18754
18564
  frames,
18755
18565
  ambient: Boolean(args.ambient),
18756
18566
  ...args.aspect ? { aspect: String(args.aspect) } : {},
@@ -18808,7 +18618,7 @@ var scaffoldVideoCommand = defineCommand90({
18808
18618
  run_estimated_credits: validation.estimatedCredits
18809
18619
  },
18810
18620
  checklist: {
18811
- 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.`,
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.`,
18812
18622
  recurring_elements_to_supply: report.elements,
18813
18623
  voices_to_confirm: report.dialogue.map((d) => ({
18814
18624
  scene: d.scene,
@@ -18835,7 +18645,7 @@ var scaffoldVideoCommand = defineCommand90({
18835
18645
 
18836
18646
  // src/commands/canvas/set-prompt.ts
18837
18647
  import { readFile as readFile7, writeFile as writeFile3 } from "fs/promises";
18838
- import path12 from "path";
18648
+ import path10 from "path";
18839
18649
  import { defineCommand as defineCommand91 } from "citty";
18840
18650
  function setNodePrompt(canvas, nodeId, text) {
18841
18651
  const nodes = canvas?.nodes;
@@ -18863,7 +18673,7 @@ var setPromptCommand = defineCommand91({
18863
18673
  "text-file": { type: "string", description: "Read the new prompt from a UTF-8 file (preserves accents/newlines)" }
18864
18674
  },
18865
18675
  async run({ args }) {
18866
- const filePath = path12.resolve(String(args.file));
18676
+ const filePath = path10.resolve(String(args.file));
18867
18677
  let canvas;
18868
18678
  try {
18869
18679
  canvas = JSON.parse(await readFile7(filePath, "utf8"));
@@ -18873,7 +18683,7 @@ var setPromptCommand = defineCommand91({
18873
18683
  process.exit(2);
18874
18684
  }
18875
18685
  let text;
18876
- if (args["text-file"]) text = await readFile7(path12.resolve(String(args["text-file"])), "utf8");
18686
+ if (args["text-file"]) text = await readFile7(path10.resolve(String(args["text-file"])), "utf8");
18877
18687
  else if (args.text !== void 0) text = String(args.text);
18878
18688
  else {
18879
18689
  process.stderr.write(
@@ -18894,7 +18704,7 @@ var setPromptCommand = defineCommand91({
18894
18704
  process.exit(2);
18895
18705
  return;
18896
18706
  }
18897
- const validation = await validateCanvasDeep(resolveRelativeCanvasPaths(updated, path12.dirname(filePath)), defaultRegistry());
18707
+ const validation = await validateCanvasDeep(resolveRelativeCanvasPaths(updated, path10.dirname(filePath)), defaultRegistry());
18898
18708
  if (!validation.ok) {
18899
18709
  process.stderr.write(`${JSON.stringify({ ok: false, error: { code: "validation", issues: validation.issues } }, null, 2)}
18900
18710
  `);
@@ -18910,7 +18720,7 @@ var setPromptCommand = defineCommand91({
18910
18720
 
18911
18721
  // src/commands/canvas/validate.ts
18912
18722
  import { readFile as readFile8 } from "fs/promises";
18913
- import path13 from "path";
18723
+ import path11 from "path";
18914
18724
  import { defineCommand as defineCommand92 } from "citty";
18915
18725
  var validateCommand = defineCommand92({
18916
18726
  meta: {
@@ -18919,7 +18729,7 @@ var validateCommand = defineCommand92({
18919
18729
  },
18920
18730
  args: { file: { type: "positional", required: true, description: "Path to canvas JSON" } },
18921
18731
  async run({ args }) {
18922
- const filePath = path13.resolve(String(args.file));
18732
+ const filePath = path11.resolve(String(args.file));
18923
18733
  const raw = await readFile8(filePath, "utf8");
18924
18734
  let parsed;
18925
18735
  try {
@@ -18930,7 +18740,7 @@ var validateCommand = defineCommand92({
18930
18740
  `);
18931
18741
  process.exit(2);
18932
18742
  }
18933
- parsed = resolveRelativeCanvasPaths(parsed, path13.dirname(filePath));
18743
+ parsed = resolveRelativeCanvasPaths(parsed, path11.dirname(filePath));
18934
18744
  const result = await validateCanvasDeep(parsed, defaultRegistry());
18935
18745
  if (!result.ok) {
18936
18746
  process.stderr.write(`${JSON.stringify({ ok: false, issues: result.issues }, null, 2)}
@@ -19067,16 +18877,6 @@ registerSchema({
19067
18877
  type: "string",
19068
18878
  description: "Optional URL of the original reference ad",
19069
18879
  required: false
19070
- },
19071
- slug: {
19072
- type: "string",
19073
- description: "Creative slug (src/creatives/<slug>/) \u2014 attaches the image to that creative's row",
19074
- required: false
19075
- },
19076
- runId: {
19077
- type: "string",
19078
- description: "Canvas run id (r_\u2026) of the approved generation to pin as published",
19079
- required: false
19080
18880
  }
19081
18881
  }
19082
18882
  });
@@ -19086,13 +18886,6 @@ function detectCreativeContentType(filePath) {
19086
18886
  unsupportedMessage: "Unsupported creative image extension. Use PNG, JPG, or WebP."
19087
18887
  });
19088
18888
  }
19089
- function chatIdFromEnv() {
19090
- try {
19091
- return getEnv().BAKER_CHAT_ID || void 0;
19092
- } catch {
19093
- return void 0;
19094
- }
19095
- }
19096
18889
  function parseOptionalUrl(value) {
19097
18890
  if (value === void 0 || value.trim() === "") {
19098
18891
  return void 0;
@@ -19123,11 +18916,7 @@ async function publishCreative(args, deps = defaultImageApiDeps) {
19123
18916
  return publishImageAsCreative(deps, {
19124
18917
  imageId: upload.imageId,
19125
18918
  title,
19126
- sourceReferenceUrl,
19127
- slug: args.slug,
19128
- runId: args.runId,
19129
- // Attribute the publish to the driving chat (injected by the bridge).
19130
- chatId: chatIdFromEnv()
18919
+ sourceReferenceUrl
19131
18920
  });
19132
18921
  }
19133
18922
  var publishCommand = defineCommand94({
@@ -19143,16 +18932,6 @@ var publishCommand = defineCommand94({
19143
18932
  type: "string",
19144
18933
  description: "Optional URL of the original reference ad",
19145
18934
  required: false
19146
- },
19147
- slug: {
19148
- type: "string",
19149
- description: "Creative slug (src/creatives/<slug>/) \u2014 attaches the image to that creative's row",
19150
- required: false
19151
- },
19152
- runId: {
19153
- type: "string",
19154
- description: "Canvas run id (r_\u2026) of the approved generation to pin as published",
19155
- required: false
19156
18935
  }
19157
18936
  },
19158
18937
  run: async ({ args }) => {
@@ -19171,9 +18950,7 @@ var publishCommand = defineCommand94({
19171
18950
  file,
19172
18951
  title,
19173
18952
  context: args.context,
19174
- sourceReferenceUrl: args.sourceReferenceUrl,
19175
- slug: args.slug,
19176
- runId: args.runId
18953
+ sourceReferenceUrl: args.sourceReferenceUrl
19177
18954
  });
19178
18955
  writeJson({ ok: true, data });
19179
18956
  } catch (err) {
@@ -20071,9 +19848,9 @@ async function readImageBuffer(pathOrUrl) {
20071
19848
  }
20072
19849
  return readFile10(pathOrUrl);
20073
19850
  }
20074
- async function isDirectory(path14) {
19851
+ async function isDirectory(path12) {
20075
19852
  try {
20076
- const s = await stat2(path14);
19853
+ const s = await stat2(path12);
20077
19854
  return s.isDirectory();
20078
19855
  } catch {
20079
19856
  return false;
@@ -24135,11 +23912,121 @@ var schemaCommand = defineCommand147({
24135
23912
  }
24136
23913
  });
24137
23914
 
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
+
24138
24025
  // src/commands/testimonials/index.ts
24139
- import { defineCommand as defineCommand151 } from "citty";
24026
+ import { defineCommand as defineCommand152 } from "citty";
24140
24027
 
24141
24028
  // src/commands/testimonials/get.ts
24142
- import { defineCommand as defineCommand148 } from "citty";
24029
+ import { defineCommand as defineCommand149 } from "citty";
24143
24030
  registerSchema({
24144
24031
  command: "testimonials.get",
24145
24032
  description: "Get a single testimonial by ID",
@@ -24147,7 +24034,7 @@ registerSchema({
24147
24034
  id: { type: "string", description: "Testimonial ID", required: true }
24148
24035
  }
24149
24036
  });
24150
- var getCommand4 = defineCommand148({
24037
+ var getCommand4 = defineCommand149({
24151
24038
  meta: { name: "get", description: "Get a single testimonial by ID. Example: baker testimonials get j571abc123" },
24152
24039
  args: {
24153
24040
  id: { type: "positional", description: "Testimonial ID", required: false },
@@ -24184,7 +24071,7 @@ var getCommand4 = defineCommand148({
24184
24071
  });
24185
24072
 
24186
24073
  // src/commands/testimonials/list.ts
24187
- import { defineCommand as defineCommand149 } from "citty";
24074
+ import { defineCommand as defineCommand150 } from "citty";
24188
24075
  registerSchema({
24189
24076
  command: "testimonials.list",
24190
24077
  description: "List testimonials with optional filters.",
@@ -24214,7 +24101,7 @@ registerSchema({
24214
24101
  limit: { type: "number", description: "Max results (default 50)", required: false, default: 50 }
24215
24102
  }
24216
24103
  });
24217
- var listCommand7 = defineCommand149({
24104
+ var listCommand8 = defineCommand150({
24218
24105
  meta: {
24219
24106
  name: "list",
24220
24107
  description: "List testimonials with optional filters. Example: baker testimonials list --source google --sentiment positive"
@@ -24263,7 +24150,7 @@ var listCommand7 = defineCommand149({
24263
24150
  });
24264
24151
 
24265
24152
  // src/commands/testimonials/search.ts
24266
- import { defineCommand as defineCommand150 } from "citty";
24153
+ import { defineCommand as defineCommand151 } from "citty";
24267
24154
  registerSchema({
24268
24155
  command: "testimonials.search",
24269
24156
  description: "Search testimonials by text query. Uses hybrid BM25 + vector + reranking.",
@@ -24294,7 +24181,7 @@ registerSchema({
24294
24181
  tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
24295
24182
  }
24296
24183
  });
24297
- var searchCommand2 = defineCommand150({
24184
+ var searchCommand2 = defineCommand151({
24298
24185
  meta: {
24299
24186
  name: "search",
24300
24187
  description: "Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4"
@@ -24365,10 +24252,10 @@ var searchCommand2 = defineCommand150({
24365
24252
  });
24366
24253
 
24367
24254
  // src/commands/testimonials/tags.ts
24368
- var tagsCommand3 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
24255
+ var tagsCommand4 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
24369
24256
 
24370
24257
  // src/commands/testimonials/index.ts
24371
- var testimonialsCommand = defineCommand151({
24258
+ var testimonialsCommand = defineCommand152({
24372
24259
  meta: {
24373
24260
  name: "testimonials",
24374
24261
  description: `Find and browse testimonials in Baker. Subcommands: search, get, list, tags.
@@ -24383,16 +24270,16 @@ Examples:
24383
24270
  subCommands: {
24384
24271
  get: getCommand4,
24385
24272
  search: searchCommand2,
24386
- list: listCommand7,
24387
- tags: tagsCommand3
24273
+ list: listCommand8,
24274
+ tags: tagsCommand4
24388
24275
  }
24389
24276
  });
24390
24277
 
24391
24278
  // src/commands/videos/index.ts
24392
- import { defineCommand as defineCommand156 } from "citty";
24279
+ import { defineCommand as defineCommand157 } from "citty";
24393
24280
 
24394
24281
  // src/commands/videos/delete.ts
24395
- import { defineCommand as defineCommand152 } from "citty";
24282
+ import { defineCommand as defineCommand153 } from "citty";
24396
24283
  registerSchema({
24397
24284
  command: "videos.delete",
24398
24285
  description: "Delete a video by ID",
@@ -24406,7 +24293,7 @@ registerSchema({
24406
24293
  }
24407
24294
  }
24408
24295
  });
24409
- var deleteCommand3 = defineCommand152({
24296
+ var deleteCommand3 = defineCommand153({
24410
24297
  meta: {
24411
24298
  name: "delete",
24412
24299
  description: "Delete a video by ID. Use --dry-run to preview. Example: baker videos delete j571abc123 --dry-run"
@@ -24447,7 +24334,7 @@ var deleteCommand3 = defineCommand152({
24447
24334
  });
24448
24335
 
24449
24336
  // src/commands/videos/get.ts
24450
- import { defineCommand as defineCommand153 } from "citty";
24337
+ import { defineCommand as defineCommand154 } from "citty";
24451
24338
  registerSchema({
24452
24339
  command: "videos.get",
24453
24340
  description: "Get a single video by ID",
@@ -24455,7 +24342,7 @@ registerSchema({
24455
24342
  id: { type: "string", description: "Video ID", required: true }
24456
24343
  }
24457
24344
  });
24458
- var getCommand5 = defineCommand153({
24345
+ var getCommand5 = defineCommand154({
24459
24346
  meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
24460
24347
  args: {
24461
24348
  id: { type: "positional", description: "Video ID", required: false },
@@ -24492,7 +24379,7 @@ var getCommand5 = defineCommand153({
24492
24379
  });
24493
24380
 
24494
24381
  // src/commands/videos/search.ts
24495
- import { defineCommand as defineCommand154 } from "citty";
24382
+ import { defineCommand as defineCommand155 } from "citty";
24496
24383
  registerSchema({
24497
24384
  command: "videos.search",
24498
24385
  description: "Search videos by text query. Only returns ready videos.",
@@ -24502,7 +24389,7 @@ registerSchema({
24502
24389
  tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
24503
24390
  }
24504
24391
  });
24505
- var searchCommand3 = defineCommand154({
24392
+ var searchCommand3 = defineCommand155({
24506
24393
  meta: {
24507
24394
  name: "search",
24508
24395
  description: "Semantic search videos by text query. Uses hybrid BM25 + vector + reranking. Example: baker videos search 'product demo' --tags tutorial"
@@ -24549,12 +24436,12 @@ var searchCommand3 = defineCommand154({
24549
24436
  });
24550
24437
 
24551
24438
  // src/commands/videos/tags.ts
24552
- var tagsCommand4 = makeTagsCommand("videos", "video", "/api/videos/tags");
24439
+ var tagsCommand5 = makeTagsCommand("videos", "video", "/api/videos/tags");
24553
24440
 
24554
24441
  // src/commands/videos/upload.ts
24555
24442
  import { readFile as readFile12, stat as stat3 } from "fs/promises";
24556
24443
  import { extname as extname3 } from "path";
24557
- import { defineCommand as defineCommand155 } from "citty";
24444
+ import { defineCommand as defineCommand156 } from "citty";
24558
24445
  var MIME_MAP = {
24559
24446
  ".mp4": "video/mp4",
24560
24447
  ".mov": "video/quicktime",
@@ -24588,7 +24475,7 @@ function detectContentType(filePath) {
24588
24475
  }
24589
24476
  return mime;
24590
24477
  }
24591
- var uploadCommand2 = defineCommand155({
24478
+ var uploadCommand2 = defineCommand156({
24592
24479
  meta: {
24593
24480
  name: "upload",
24594
24481
  description: "Upload a video file to Baker via Mux direct upload. Auto-detects content type. Example: baker videos upload ./demo.mp4"
@@ -24642,7 +24529,7 @@ var uploadCommand2 = defineCommand155({
24642
24529
  });
24643
24530
 
24644
24531
  // src/commands/videos/index.ts
24645
- var videosCommand = defineCommand156({
24532
+ var videosCommand = defineCommand157({
24646
24533
  meta: {
24647
24534
  name: "videos",
24648
24535
  description: `Find and manage videos in Baker. Subcommands: search, get, upload, delete, tags.
@@ -24660,15 +24547,15 @@ Examples:
24660
24547
  search: searchCommand3,
24661
24548
  upload: uploadCommand2,
24662
24549
  delete: deleteCommand3,
24663
- tags: tagsCommand4
24550
+ tags: tagsCommand5
24664
24551
  }
24665
24552
  });
24666
24553
 
24667
24554
  // src/commands/winning-ads/index.ts
24668
- import { defineCommand as defineCommand159 } from "citty";
24555
+ import { defineCommand as defineCommand160 } from "citty";
24669
24556
 
24670
24557
  // src/commands/winning-ads/advertisers.ts
24671
- import { defineCommand as defineCommand157 } from "citty";
24558
+ import { defineCommand as defineCommand158 } from "citty";
24672
24559
  registerSchema({
24673
24560
  command: "winning-ads.advertisers",
24674
24561
  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).",
@@ -24681,7 +24568,7 @@ registerSchema({
24681
24568
  function identity(record) {
24682
24569
  return record;
24683
24570
  }
24684
- var advertisersCommand2 = defineCommand157({
24571
+ var advertisersCommand2 = defineCommand158({
24685
24572
  meta: {
24686
24573
  name: "advertisers",
24687
24574
  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'
@@ -24732,7 +24619,7 @@ var advertisersCommand2 = defineCommand157({
24732
24619
  });
24733
24620
 
24734
24621
  // src/commands/winning-ads/search.ts
24735
- import { defineCommand as defineCommand158 } from "citty";
24622
+ import { defineCommand as defineCommand159 } from "citty";
24736
24623
  registerSchema({
24737
24624
  command: "winning-ads.search",
24738
24625
  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.",
@@ -24840,7 +24727,7 @@ function buildSearchBody(args) {
24840
24727
  }
24841
24728
  return body;
24842
24729
  }
24843
- var searchCommand4 = defineCommand158({
24730
+ var searchCommand4 = defineCommand159({
24844
24731
  meta: {
24845
24732
  name: "search",
24846
24733
  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"
@@ -24952,7 +24839,7 @@ var searchCommand4 = defineCommand158({
24952
24839
  });
24953
24840
 
24954
24841
  // src/commands/winning-ads/index.ts
24955
- var winningAdsCommand = defineCommand159({
24842
+ var winningAdsCommand = defineCommand160({
24956
24843
  meta: {
24957
24844
  name: "winning-ads",
24958
24845
  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.
@@ -24992,11 +24879,11 @@ function getCliVersion() {
24992
24879
  }
24993
24880
 
24994
24881
  // src/cli.ts
24995
- var main = defineCommand160({
24882
+ var main = defineCommand161({
24996
24883
  meta: {
24997
24884
  name: "baker",
24998
24885
  version: getCliVersion(),
24999
- description: `AI-agent CLI for finding and managing images, videos, testimonials, action items, scheduled actions, and ad platform data in Baker.
24886
+ description: `AI-agent CLI for finding and managing images, videos, testimonials, action items, scheduled actions, marketing tags, and ad platform data in Baker.
25000
24887
 
25001
24888
  Auth: Set BAKER_API_KEY (starts with bk_) and BAKER_API_URL environment variables.
25002
24889
  Chat: Set BAKER_CHAT_ID for action and scheduled-action commands that stage changes against a chat.
@@ -25016,6 +24903,7 @@ Introspection: Run 'baker schema <command>' to inspect argument schemas.`
25016
24903
  videos: videosCommand,
25017
24904
  testimonials: testimonialsCommand,
25018
24905
  canvas: canvasCommand,
24906
+ tags: tagsCommand3,
25019
24907
  "winning-ads": winningAdsCommand,
25020
24908
  mcp: mcpCommand,
25021
24909
  schema: schemaCommand