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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,19 +1,26 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
+ BackendClient,
3
4
  ELEVENLABS_MAX_MUSIC_LENGTH_MS,
4
5
  IMAGE_GENERATE_MODELS,
5
6
  LayerExecutionError,
6
7
  MODEL_REGISTRY,
7
8
  SEEDANCE_DURATIONS,
8
9
  ValidationError,
10
+ collectAssetRefLikes,
9
11
  createEngineFromEnv,
10
12
  defaultRegistry,
11
13
  describeFailureReason,
12
14
  elementMentionKeywords,
13
15
  generateCatalog,
16
+ isPersistedAssetRef,
17
+ requireCredentialsFromEnv,
14
18
  resolveConcurrency,
19
+ sha256Hex,
20
+ toModelSafeImage,
21
+ ulid,
15
22
  validateCanvasDeep
16
- } from "./chunk-IWPAXJC3.js";
23
+ } from "./chunk-T6HBTZOO.js";
17
24
  import {
18
25
  csvOrJson,
19
26
  daysAgoIso,
@@ -49,7 +56,7 @@ import {
49
56
  import "./chunk-5WRI5ZAA.js";
50
57
 
51
58
  // src/cli.ts
52
- import { defineCommand as defineCommand161, runMain } from "citty";
59
+ import { defineCommand as defineCommand160, runMain } from "citty";
53
60
 
54
61
  // src/commands/actions/index.ts
55
62
  import { defineCommand as defineCommand18 } from "citty";
@@ -848,6 +855,7 @@ var LINKEDIN_LIMITS = {
848
855
  choiceOptionsMax: 30,
849
856
  choiceOptionTextMax: 100,
850
857
  thankYouMessageMax: 300,
858
+ privacyPolicyTextMax: 2e3,
851
859
  legalDisclaimerMax: 2e3,
852
860
  consentsMax: 5,
853
861
  // Campaign Manager caps disclosure checkboxes at 5
@@ -1442,6 +1450,7 @@ var leadFormFields = {
1442
1450
  /** Form language, e.g. { country: "US", language: "en" }. Defaults to the account locale on LinkedIn. */
1443
1451
  locale: z2.object({ country: z2.string().length(2), language: z2.string().length(2) }).optional(),
1444
1452
  privacyPolicyUrl: httpsUrlSchema,
1453
+ privacyPolicyText: z2.string().max(LEAD.privacyPolicyTextMax).optional(),
1445
1454
  questions: z2.array(leadFormQuestionSchema).min(1).max(LEAD.questionsMax),
1446
1455
  consents: z2.array(leadFormConsentSchema).max(LEAD.consentsMax).optional(),
1447
1456
  hiddenFields: z2.array(leadFormHiddenFieldSchema).max(LEAD.hiddenFieldsMax).optional(),
@@ -1916,261 +1925,142 @@ var imagesIngestResponseSchema = z4.object({
1916
1925
  contentHash: z4.string()
1917
1926
  });
1918
1927
 
1919
- // ../api/src/tags.ts
1920
- import { z as z5 } from "zod";
1921
- var TAG_TYPES = [
1922
- "meta",
1923
- "amplitude",
1924
- "googleAds",
1925
- "tiktok",
1926
- "vwo",
1927
- "hotjar",
1928
- "clarity",
1929
- "pinterest",
1930
- "code",
1931
- "googleAnalytics",
1932
- "googleTagManager",
1933
- "hubspot",
1934
- "linkedinInsightTag",
1935
- "onetrust",
1936
- "posthog",
1937
- "datafast",
1938
- "recaptcha",
1939
- "twitterAds"
1940
- ];
1941
- var tagTypeSchema = z5.enum(TAG_TYPES);
1942
- var TAG_IDENTIFYING_FIELD = {
1943
- meta: "pixelId",
1944
- googleAds: "conversionID",
1945
- tiktok: "pixelCode",
1946
- pinterest: "tagId",
1947
- linkedinInsightTag: "partnerId",
1948
- googleAnalytics: "measurementId",
1949
- googleTagManager: "containerID",
1950
- amplitude: "apiKey",
1951
- hotjar: "siteID",
1952
- clarity: "projectId",
1953
- hubspot: "hubID",
1954
- vwo: "accountId",
1955
- code: null,
1956
- onetrust: "domainId",
1957
- posthog: "projectToken",
1958
- datafast: "websiteId",
1959
- recaptcha: "siteKey",
1960
- twitterAds: "pixelId"
1961
- };
1962
- var tagDraftOpKindSchema = z5.enum(["create", "update", "delete"]);
1963
- var tagDraftOpViewSchema = z5.object({
1964
- /** `tag_temp_*` for staged creates; the real tag id for update/delete ops. */
1965
- ref: z5.string(),
1966
- kind: tagDraftOpKindSchema,
1967
- type: tagTypeSchema,
1968
- /** Present on update/delete ops — the real tag this op targets. */
1969
- tagId: z5.string().optional(),
1970
- /** Non-secret config (create: full; update: the staged patch). Secrets are structurally absent. */
1971
- config: z5.record(z5.string(), z5.string()),
1972
- /** Update only — fields the op explicitly clears. */
1973
- clearFields: z5.array(z5.string()).optional(),
1974
- /** Names of secret fields already provided via the dashboard secure form. Never values. */
1975
- secretsSet: z5.array(z5.string()),
1976
- /** Names of secret fields still awaiting user input. */
1977
- secretsPending: z5.array(z5.string()),
1978
- summary: z5.string(),
1979
- stagedAt: z5.number()
1980
- });
1981
- var tagsEffectiveEntrySchema = z5.object({
1982
- /** Real tag id, or `tag_temp_*` for staged creates. Use as flow side-effect `tagIds` value. */
1983
- ref: z5.string(),
1984
- tagId: z5.string().optional(),
1985
- type: tagTypeSchema,
1986
- /** Value of the type's identifying field, when set. */
1987
- identifier: z5.string().optional(),
1988
- /** Redacted config; for staged updates, production config with the patch merged. */
1989
- config: z5.record(z5.string(), z5.string()),
1990
- /** Absent = live production tag with no staged changes in this chat. */
1991
- staged: tagDraftOpKindSchema.optional(),
1992
- secretsSet: z5.array(z5.string()),
1993
- secretsPending: z5.array(z5.string())
1994
- });
1995
- var tagsListRequestSchema = z5.object({ chatId: z5.string() });
1996
- var tagsListResponseSchema = z5.object({ tags: z5.array(tagsEffectiveEntrySchema) });
1997
- var tagsDraftListRequestSchema = z5.object({ chatId: z5.string() });
1998
- var tagsDraftListResponseSchema = z5.object({
1999
- status: z5.enum(["active", "publishing", "applied", "discarded", "none"]),
2000
- ops: z5.array(tagDraftOpViewSchema)
2001
- });
2002
- var tagInputRequestSchema = z5.object({
2003
- // Every tag change is a tab in the approval form: create/edit show the full
2004
- // body; delete shows a confirm. No tag change bypasses this approval.
2005
- mode: z5.enum(["create", "edit", "delete"]),
2006
- tagType: tagTypeSchema,
2007
- /** Edit/delete mode — the real tag id or `tag_temp_*` ref being changed. */
2008
- ref: z5.string().optional(),
2009
- /** Non-secret values the agent proposes to prefill. Secret keys are stripped at every boundary. */
2010
- prefilledConfig: z5.record(z5.string(), z5.string()).optional(),
2011
- /** Secret field names the agent asks the user to provide. */
2012
- requestedSecretFields: z5.array(z5.string()).optional(),
2013
- /** Short message shown above the form explaining why the input is needed. */
2014
- message: z5.string().optional()
2015
- });
2016
- var tagChangeToolInputSchema = z5.object({
2017
- changes: z5.array(tagInputRequestSchema).min(1).max(8)
2018
- });
2019
- var tagInputResultSchema = z5.discriminatedUnion("status", [
2020
- z5.object({
2021
- status: z5.literal("submitted"),
2022
- ref: z5.string(),
2023
- type: tagTypeSchema,
2024
- /** Identifying field name → value (non-secret), when the type has one. */
2025
- identifier: z5.record(z5.string(), z5.string()).optional(),
2026
- secretFieldsSet: z5.array(z5.string()),
2027
- note: z5.string().optional()
2028
- }),
2029
- z5.object({
2030
- status: z5.literal("declined"),
2031
- reason: z5.string().optional()
2032
- })
2033
- ]);
2034
- var tagChangeToolResultSchema = z5.object({
2035
- results: z5.array(tagInputResultSchema)
2036
- });
2037
-
2038
1928
  // ../api/src/testimonials.ts
2039
- import { z as z6 } from "zod";
2040
- var testimonialSourceTypeSchema = z6.enum(["google", "trustpilot"]);
2041
- var testimonialStatusSchema = z6.enum(["pending", "processing", "ready", "error"]);
2042
- var testimonialSentimentSchema = z6.enum(["positive", "neutral", "negative"]);
2043
- var testimonialDocSchema = z6.object({
2044
- _id: z6.string(),
2045
- _creationTime: z6.number(),
2046
- companyId: z6.string(),
2047
- sourceId: z6.string(),
1929
+ import { z as z5 } from "zod";
1930
+ var testimonialSourceTypeSchema = z5.enum(["google", "trustpilot"]);
1931
+ var testimonialStatusSchema = z5.enum(["pending", "processing", "ready", "error"]);
1932
+ var testimonialSentimentSchema = z5.enum(["positive", "neutral", "negative"]);
1933
+ var testimonialDocSchema = z5.object({
1934
+ _id: z5.string(),
1935
+ _creationTime: z5.number(),
1936
+ companyId: z5.string(),
1937
+ sourceId: z5.string(),
2048
1938
  sourceType: testimonialSourceTypeSchema,
2049
- reviewText: z6.string(),
2050
- reviewTitle: z6.string().optional(),
2051
- searchText: z6.string().optional(),
2052
- reviewerName: z6.string().optional(),
2053
- reviewerImageUrl: z6.string().optional(),
2054
- reviewerImageId: z6.string().optional(),
2055
- reviewerLocation: z6.string().optional(),
2056
- rating: z6.number().optional(),
2057
- reviewDate: z6.number().optional(),
2058
- ownerAnswer: z6.string().optional(),
2059
- mediaUrls: z6.array(z6.string()).optional(),
2060
- imageIds: z6.array(z6.string()).optional(),
2061
- videoIds: z6.array(z6.string()).optional(),
2062
- sourceUrl: z6.string().optional(),
2063
- rawData: z6.unknown().optional(),
2064
- tags: z6.array(z6.string()),
2065
- highlight: z6.string().optional(),
2066
- language: z6.string().optional(),
2067
- summary: z6.string().optional(),
1939
+ reviewText: z5.string(),
1940
+ reviewTitle: z5.string().optional(),
1941
+ searchText: z5.string().optional(),
1942
+ reviewerName: z5.string().optional(),
1943
+ reviewerImageUrl: z5.string().optional(),
1944
+ reviewerImageId: z5.string().optional(),
1945
+ reviewerLocation: z5.string().optional(),
1946
+ rating: z5.number().optional(),
1947
+ reviewDate: z5.number().optional(),
1948
+ ownerAnswer: z5.string().optional(),
1949
+ mediaUrls: z5.array(z5.string()).optional(),
1950
+ imageIds: z5.array(z5.string()).optional(),
1951
+ videoIds: z5.array(z5.string()).optional(),
1952
+ sourceUrl: z5.string().optional(),
1953
+ rawData: z5.unknown().optional(),
1954
+ tags: z5.array(z5.string()),
1955
+ highlight: z5.string().optional(),
1956
+ language: z5.string().optional(),
1957
+ summary: z5.string().optional(),
2068
1958
  sentiment: testimonialSentimentSchema.optional(),
2069
- textEmbedding: z6.array(z6.number()).optional(),
2070
- externalId: z6.string().optional(),
2071
- contentHash: z6.string().optional(),
1959
+ textEmbedding: z5.array(z5.number()).optional(),
1960
+ externalId: z5.string().optional(),
1961
+ contentHash: z5.string().optional(),
2072
1962
  status: testimonialStatusSchema,
2073
- errorMessage: z6.string().optional(),
2074
- createdAt: z6.number(),
2075
- updatedAt: z6.number()
1963
+ errorMessage: z5.string().optional(),
1964
+ createdAt: z5.number(),
1965
+ updatedAt: z5.number()
2076
1966
  });
2077
- var testimonialsListRequestSchema = z6.object({
1967
+ var testimonialsListRequestSchema = z5.object({
2078
1968
  source: testimonialSourceTypeSchema.optional(),
2079
- rating_min: z6.coerce.number().int().min(1).max(5).optional(),
2080
- rating_max: z6.coerce.number().int().min(1).max(5).optional(),
2081
- tags: z6.string().transform((s) => s.split(",").filter(Boolean)).optional(),
1969
+ rating_min: z5.coerce.number().int().min(1).max(5).optional(),
1970
+ rating_max: z5.coerce.number().int().min(1).max(5).optional(),
1971
+ tags: z5.string().transform((s) => s.split(",").filter(Boolean)).optional(),
2082
1972
  status: testimonialStatusSchema.optional(),
2083
1973
  sentiment: testimonialSentimentSchema.optional(),
2084
- language: z6.string().min(2).max(5).optional(),
2085
- limit: z6.coerce.number().int().positive().max(200).optional()
2086
- });
2087
- var testimonialsListResponseSchema = z6.array(testimonialDocSchema);
2088
- var testimonialsGetRequestSchema = z6.object({ id: z6.string().min(1, "Missing id parameter") });
2089
- var testimonialsSearchRequestSchema = z6.object({
2090
- query: z6.string().min(1),
2091
- limit: z6.coerce.number().int().positive().max(100).optional(),
1974
+ language: z5.string().min(2).max(5).optional(),
1975
+ limit: z5.coerce.number().int().positive().max(200).optional()
1976
+ });
1977
+ var testimonialsListResponseSchema = z5.array(testimonialDocSchema);
1978
+ var testimonialsGetRequestSchema = z5.object({ id: z5.string().min(1, "Missing id parameter") });
1979
+ var testimonialsSearchRequestSchema = z5.object({
1980
+ query: z5.string().min(1),
1981
+ limit: z5.coerce.number().int().positive().max(100).optional(),
2092
1982
  source: testimonialSourceTypeSchema.optional(),
2093
- rating_min: z6.coerce.number().int().min(1).max(5).optional(),
2094
- rating_max: z6.coerce.number().int().min(1).max(5).optional(),
2095
- tags: z6.array(z6.string()).optional(),
1983
+ rating_min: z5.coerce.number().int().min(1).max(5).optional(),
1984
+ rating_max: z5.coerce.number().int().min(1).max(5).optional(),
1985
+ tags: z5.array(z5.string()).optional(),
2096
1986
  status: testimonialStatusSchema.optional(),
2097
1987
  sentiment: testimonialSentimentSchema.optional(),
2098
- language: z6.string().min(2).max(5).optional()
1988
+ language: z5.string().min(2).max(5).optional()
2099
1989
  }).refine(
2100
1990
  (data) => data.rating_min === void 0 || data.rating_max === void 0 || data.rating_min <= data.rating_max,
2101
1991
  { message: "rating_min must be less than or equal to rating_max" }
2102
1992
  );
2103
- var testimonialsSearchResponseSchema = z6.array(testimonialDocSchema);
2104
- var testimonialsOutscraperWebhookResponseSchema = z6.object({
2105
- ok: z6.literal(true),
2106
- note: z6.string().optional()
1993
+ var testimonialsSearchResponseSchema = z5.array(testimonialDocSchema);
1994
+ var testimonialsOutscraperWebhookResponseSchema = z5.object({
1995
+ ok: z5.literal(true),
1996
+ note: z5.string().optional()
2107
1997
  });
2108
1998
 
2109
1999
  // ../api/src/videos.ts
2110
- import { z as z7 } from "zod";
2111
- var videoStatusSchema = z7.enum(["uploading", "uploaded", "processing", "ready", "error"]);
2112
- var videoTranscriptSegmentSchema = z7.object({
2113
- text: z7.string(),
2114
- startSecond: z7.number(),
2115
- endSecond: z7.number()
2116
- });
2117
- var videoSceneSchema = z7.object({
2118
- title: z7.string(),
2119
- description: z7.string(),
2120
- startSecond: z7.number(),
2121
- endSecond: z7.number(),
2122
- thumbnailTime: z7.number()
2123
- });
2124
- var videoDocSchema = z7.object({
2125
- _id: z7.string(),
2126
- _creationTime: z7.number(),
2127
- companyId: z7.string(),
2128
- muxAssetId: z7.string(),
2129
- muxPlaybackId: z7.string(),
2130
- muxUploadId: z7.string(),
2131
- name: z7.string(),
2132
- description: z7.string(),
2133
- tags: z7.array(z7.string()),
2134
- source: z7.string(),
2135
- externalId: z7.string().optional(),
2136
- sourceId: z7.string().optional(),
2137
- width: z7.number().optional(),
2138
- height: z7.number().optional(),
2139
- aspectRatio: z7.number().optional(),
2140
- duration: z7.number().optional(),
2141
- transcript: z7.string().optional(),
2142
- transcriptSegments: z7.array(videoTranscriptSegmentSchema).optional(),
2143
- scenes: z7.array(videoSceneSchema).optional(),
2144
- descriptionEmbedding: z7.array(z7.number()).optional(),
2145
- searchText: z7.string().optional(),
2000
+ import { z as z6 } from "zod";
2001
+ var videoStatusSchema = z6.enum(["uploading", "uploaded", "processing", "ready", "error"]);
2002
+ var videoTranscriptSegmentSchema = z6.object({
2003
+ text: z6.string(),
2004
+ startSecond: z6.number(),
2005
+ endSecond: z6.number()
2006
+ });
2007
+ var videoSceneSchema = z6.object({
2008
+ title: z6.string(),
2009
+ description: z6.string(),
2010
+ startSecond: z6.number(),
2011
+ endSecond: z6.number(),
2012
+ thumbnailTime: z6.number()
2013
+ });
2014
+ var videoDocSchema = z6.object({
2015
+ _id: z6.string(),
2016
+ _creationTime: z6.number(),
2017
+ companyId: z6.string(),
2018
+ muxAssetId: z6.string(),
2019
+ muxPlaybackId: z6.string(),
2020
+ muxUploadId: z6.string(),
2021
+ name: z6.string(),
2022
+ description: z6.string(),
2023
+ tags: z6.array(z6.string()),
2024
+ source: z6.string(),
2025
+ externalId: z6.string().optional(),
2026
+ sourceId: z6.string().optional(),
2027
+ width: z6.number().optional(),
2028
+ height: z6.number().optional(),
2029
+ aspectRatio: z6.number().optional(),
2030
+ duration: z6.number().optional(),
2031
+ transcript: z6.string().optional(),
2032
+ transcriptSegments: z6.array(videoTranscriptSegmentSchema).optional(),
2033
+ scenes: z6.array(videoSceneSchema).optional(),
2034
+ descriptionEmbedding: z6.array(z6.number()).optional(),
2035
+ searchText: z6.string().optional(),
2146
2036
  status: videoStatusSchema,
2147
- errorMessage: z7.string().optional(),
2148
- createdAt: z7.number(),
2149
- updatedAt: z7.number(),
2150
- thumbnailUrl: z7.string()
2151
- });
2152
- var videosWebhookResponseSchema = z7.object({ ok: z7.literal(true) });
2153
- var videosGetRequestSchema = z7.object({ id: z7.string().min(1, "Missing id parameter") });
2154
- var videosSearchRequestSchema = z7.object({
2155
- query: z7.string().min(1),
2156
- limit: z7.coerce.number().int().positive().max(100).optional(),
2157
- tags: z7.array(z7.string()).optional()
2158
- });
2159
- var videoSearchResultSchema = z7.object({
2160
- _id: z7.string(),
2161
- thumbnailUrl: z7.string(),
2162
- name: z7.string(),
2163
- description: z7.string(),
2164
- tags: z7.array(z7.string()),
2165
- status: z7.string(),
2166
- duration: z7.number().optional(),
2167
- muxPlaybackId: z7.string(),
2168
- createdAt: z7.number()
2169
- });
2170
- var videosSearchResponseSchema = z7.array(videoSearchResultSchema);
2171
- var videosUploadResponseSchema = z7.object({ uploadUrl: z7.string(), videoId: z7.string() });
2172
- var videosDeleteRequestSchema = z7.object({ id: z7.string().min(1, "Missing video ID") });
2173
- var videosDeleteResponseSchema = z7.object({ ok: z7.literal(true) });
2037
+ errorMessage: z6.string().optional(),
2038
+ createdAt: z6.number(),
2039
+ updatedAt: z6.number(),
2040
+ thumbnailUrl: z6.string()
2041
+ });
2042
+ var videosWebhookResponseSchema = z6.object({ ok: z6.literal(true) });
2043
+ var videosGetRequestSchema = z6.object({ id: z6.string().min(1, "Missing id parameter") });
2044
+ var videosSearchRequestSchema = z6.object({
2045
+ query: z6.string().min(1),
2046
+ limit: z6.coerce.number().int().positive().max(100).optional(),
2047
+ tags: z6.array(z6.string()).optional()
2048
+ });
2049
+ var videoSearchResultSchema = z6.object({
2050
+ _id: z6.string(),
2051
+ thumbnailUrl: z6.string(),
2052
+ name: z6.string(),
2053
+ description: z6.string(),
2054
+ tags: z6.array(z6.string()),
2055
+ status: z6.string(),
2056
+ duration: z6.number().optional(),
2057
+ muxPlaybackId: z6.string(),
2058
+ createdAt: z6.number()
2059
+ });
2060
+ var videosSearchResponseSchema = z6.array(videoSearchResultSchema);
2061
+ var videosUploadResponseSchema = z6.object({ uploadUrl: z6.string(), videoId: z6.string() });
2062
+ var videosDeleteRequestSchema = z6.object({ id: z6.string().min(1, "Missing video ID") });
2063
+ var videosDeleteResponseSchema = z6.object({ ok: z6.literal(true) });
2174
2064
 
2175
2065
  // src/commands/actions/complete.ts
2176
2066
  import { defineCommand as defineCommand2 } from "citty";
@@ -3983,37 +3873,37 @@ var GEO_TARGET_CONSTANT_REGEX = /^geoTargetConstants\/\d+$/;
3983
3873
  var LANGUAGE_CONSTANT_REGEX = /^languageConstants\/\d+$/;
3984
3874
 
3985
3875
  // ../api/src/ads-google/ops.ts
3986
- import { z as z8 } from "zod";
3987
- var tempRefSchema2 = z8.string().regex(TEMP_REF_REGEX2, "expected a g_temp_* reference");
3988
- var refSchema = z8.union([
3989
- z8.string().regex(RESOURCE_NAME_REGEX, "expected a customers/\u2026/\u2026/\u2026 resource name"),
3990
- z8.string().regex(NUMERIC_ID_REGEX2, "expected a numeric id"),
3876
+ import { z as z7 } from "zod";
3877
+ var tempRefSchema2 = z7.string().regex(TEMP_REF_REGEX2, "expected a g_temp_* reference");
3878
+ var refSchema = z7.union([
3879
+ z7.string().regex(RESOURCE_NAME_REGEX, "expected a customers/\u2026/\u2026/\u2026 resource name"),
3880
+ z7.string().regex(NUMERIC_ID_REGEX2, "expected a numeric id"),
3991
3881
  tempRefSchema2
3992
3882
  ]);
3993
3883
  var targetRefSchema = refSchema;
3994
- var microsSchema = z8.number().int().positive("expected a positive micros amount");
3995
- var httpsUrlSchema2 = z8.string().url().refine((u) => u.startsWith("https://"), "final URLs must be https");
3996
- var customerIdSchema = z8.string().regex(NUMERIC_ID_REGEX2, "customerId must be the bare numeric customer id");
3997
- var stageableStatusSchema2 = z8.enum(STAGEABLE_CREATE_STATUSES2);
3998
- var matchTypeSchema = z8.enum(KEYWORD_MATCH_TYPES);
3999
- 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");
4000
- var budgetCreateSchema = z8.object({
4001
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.budget.nameMax),
3884
+ var microsSchema = z7.number().int().positive("expected a positive micros amount");
3885
+ var httpsUrlSchema2 = z7.string().url().refine((u) => u.startsWith("https://"), "final URLs must be https");
3886
+ var customerIdSchema = z7.string().regex(NUMERIC_ID_REGEX2, "customerId must be the bare numeric customer id");
3887
+ var stageableStatusSchema2 = z7.enum(STAGEABLE_CREATE_STATUSES2);
3888
+ var matchTypeSchema = z7.enum(KEYWORD_MATCH_TYPES);
3889
+ 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");
3890
+ var budgetCreateSchema = z7.object({
3891
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.budget.nameMax),
4002
3892
  amountMicros: microsSchema,
4003
- deliveryMethod: z8.enum(BUDGET_DELIVERY_METHODS).default("STANDARD"),
4004
- explicitlyShared: z8.boolean().default(false)
3893
+ deliveryMethod: z7.enum(BUDGET_DELIVERY_METHODS).default("STANDARD"),
3894
+ explicitlyShared: z7.boolean().default(false)
4005
3895
  });
4006
- var budgetUpdateSchema = z8.object({
4007
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.budget.nameMax).optional(),
3896
+ var budgetUpdateSchema = z7.object({
3897
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.budget.nameMax).optional(),
4008
3898
  amountMicros: microsSchema.optional(),
4009
- deliveryMethod: z8.enum(BUDGET_DELIVERY_METHODS).optional()
3899
+ deliveryMethod: z7.enum(BUDGET_DELIVERY_METHODS).optional()
4010
3900
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
4011
- var biddingConfigSchema = z8.object({
4012
- type: z8.enum(BIDDING_STRATEGY_TYPES),
3901
+ var biddingConfigSchema = z7.object({
3902
+ type: z7.enum(BIDDING_STRATEGY_TYPES),
4013
3903
  targetCpaMicros: microsSchema.optional(),
4014
- targetRoas: z8.number().positive().optional(),
3904
+ targetRoas: z7.number().positive().optional(),
4015
3905
  cpcBidCeilingMicros: microsSchema.optional(),
4016
- enhancedCpcEnabled: z8.boolean().optional()
3906
+ enhancedCpcEnabled: z7.boolean().optional()
4017
3907
  }).superRefine((p, ctx) => {
4018
3908
  if (p.type === "TARGET_CPA" && p.targetCpaMicros === void 0) {
4019
3909
  ctx.addIssue({ code: "custom", path: ["targetCpaMicros"], message: "TARGET_CPA needs targetCpaMicros" });
@@ -4022,17 +3912,17 @@ var biddingConfigSchema = z8.object({
4022
3912
  ctx.addIssue({ code: "custom", path: ["targetRoas"], message: "TARGET_ROAS needs targetRoas" });
4023
3913
  }
4024
3914
  });
4025
- var networkSettingsSchema = z8.object({
4026
- targetGoogleSearch: z8.boolean().optional(),
4027
- targetSearchNetwork: z8.boolean().optional(),
4028
- targetContentNetwork: z8.boolean().optional(),
4029
- targetPartnerSearchNetwork: z8.boolean().optional()
3915
+ var networkSettingsSchema = z7.object({
3916
+ targetGoogleSearch: z7.boolean().optional(),
3917
+ targetSearchNetwork: z7.boolean().optional(),
3918
+ targetContentNetwork: z7.boolean().optional(),
3919
+ targetPartnerSearchNetwork: z7.boolean().optional()
4030
3920
  });
4031
- var dateSchema = z8.string().regex(/^\d{4}-\d{2}-\d{2}$/, "expected a YYYY-MM-DD date");
4032
- var campaignCreateSchema2 = z8.object({
4033
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.campaign.nameMax),
4034
- channelType: z8.enum(ADVERTISING_CHANNEL_TYPES),
4035
- channelSubType: z8.enum(ADVERTISING_CHANNEL_SUB_TYPES).optional(),
3921
+ var dateSchema = z7.string().regex(/^\d{4}-\d{2}-\d{2}$/, "expected a YYYY-MM-DD date");
3922
+ var campaignCreateSchema2 = z7.object({
3923
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.campaign.nameMax),
3924
+ channelType: z7.enum(ADVERTISING_CHANNEL_TYPES),
3925
+ channelSubType: z7.enum(ADVERTISING_CHANNEL_SUB_TYPES).optional(),
4036
3926
  budget: refSchema,
4037
3927
  /** Inline standard bidding, or a portfolio strategy ref via biddingStrategy. */
4038
3928
  bidding: biddingConfigSchema.optional(),
@@ -4041,7 +3931,7 @@ var campaignCreateSchema2 = z8.object({
4041
3931
  startDate: dateSchema.optional(),
4042
3932
  endDate: dateSchema.optional(),
4043
3933
  /** Advisory Google Ads UI objective — drives warnings, not sent to the API. */
4044
- objective: z8.enum(CAMPAIGN_OBJECTIVES).optional(),
3934
+ objective: z7.enum(CAMPAIGN_OBJECTIVES).optional(),
4045
3935
  status: stageableStatusSchema2.default("PAUSED")
4046
3936
  }).superRefine((p, ctx) => {
4047
3937
  if (!p.bidding && !p.biddingStrategy) {
@@ -4065,129 +3955,129 @@ var campaignCreateSchema2 = z8.object({
4065
3955
  ctx.addIssue({ code: "custom", path: ["endDate"], message: "endDate must be after startDate" });
4066
3956
  }
4067
3957
  });
4068
- var campaignUpdateSchema2 = z8.object({
4069
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.campaign.nameMax).optional(),
3958
+ var campaignUpdateSchema2 = z7.object({
3959
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.campaign.nameMax).optional(),
4070
3960
  budget: refSchema.optional(),
4071
3961
  bidding: biddingConfigSchema.optional(),
4072
3962
  networkSettings: networkSettingsSchema.optional(),
4073
3963
  startDate: dateSchema.optional(),
4074
3964
  endDate: dateSchema.optional(),
4075
- status: z8.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
3965
+ status: z7.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
4076
3966
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
4077
- var adGroupCreateSchema = z8.object({
4078
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.adGroup.nameMax),
3967
+ var adGroupCreateSchema = z7.object({
3968
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.adGroup.nameMax),
4079
3969
  campaign: refSchema,
4080
- type: z8.enum(AD_GROUP_TYPES).default("SEARCH_STANDARD"),
3970
+ type: z7.enum(AD_GROUP_TYPES).default("SEARCH_STANDARD"),
4081
3971
  cpcBidMicros: microsSchema.optional(),
4082
3972
  status: stageableStatusSchema2.default("PAUSED")
4083
3973
  });
4084
- var adGroupUpdateSchema = z8.object({
4085
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.adGroup.nameMax).optional(),
3974
+ var adGroupUpdateSchema = z7.object({
3975
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.adGroup.nameMax).optional(),
4086
3976
  cpcBidMicros: microsSchema.optional(),
4087
- status: z8.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
3977
+ status: z7.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
4088
3978
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
4089
- var keywordAddSchema = z8.object({
3979
+ var keywordAddSchema = z7.object({
4090
3980
  adGroup: refSchema,
4091
3981
  text: keywordTextSchema,
4092
3982
  matchType: matchTypeSchema,
4093
3983
  cpcBidMicros: microsSchema.optional(),
4094
- finalUrls: z8.array(httpsUrlSchema2).optional(),
3984
+ finalUrls: z7.array(httpsUrlSchema2).optional(),
4095
3985
  status: stageableStatusSchema2.default("ENABLED")
4096
3986
  });
4097
- var keywordUpdateSchema = z8.object({
3987
+ var keywordUpdateSchema = z7.object({
4098
3988
  cpcBidMicros: microsSchema.optional(),
4099
- finalUrls: z8.array(httpsUrlSchema2).optional(),
4100
- status: z8.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
3989
+ finalUrls: z7.array(httpsUrlSchema2).optional(),
3990
+ status: z7.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
4101
3991
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
4102
- var negativeKeywordAddSchema = z8.object({
4103
- level: z8.enum(["adGroup", "campaign"]),
3992
+ var negativeKeywordAddSchema = z7.object({
3993
+ level: z7.enum(["adGroup", "campaign"]),
4104
3994
  parent: refSchema,
4105
3995
  text: keywordTextSchema,
4106
3996
  matchType: matchTypeSchema
4107
3997
  });
4108
- var sharedSetCreateSchema = z8.object({
4109
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.sharedSet.nameMax),
4110
- type: z8.enum(SHARED_SET_TYPES).default("NEGATIVE_KEYWORDS")
3998
+ var sharedSetCreateSchema = z7.object({
3999
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.sharedSet.nameMax),
4000
+ type: z7.enum(SHARED_SET_TYPES).default("NEGATIVE_KEYWORDS")
4111
4001
  });
4112
- var sharedSetMemberAddSchema = z8.object({
4002
+ var sharedSetMemberAddSchema = z7.object({
4113
4003
  sharedSet: refSchema,
4114
4004
  text: keywordTextSchema,
4115
4005
  matchType: matchTypeSchema
4116
4006
  });
4117
- var campaignSharedSetAttachSchema = z8.object({
4007
+ var campaignSharedSetAttachSchema = z7.object({
4118
4008
  campaign: refSchema,
4119
4009
  sharedSet: refSchema
4120
4010
  });
4121
- var adTextAssetSchema = z8.object({
4122
- text: z8.string().min(1),
4123
- pinnedField: z8.enum(PINNED_FIELDS).optional()
4011
+ var adTextAssetSchema = z7.object({
4012
+ text: z7.string().min(1),
4013
+ pinnedField: z7.enum(PINNED_FIELDS).optional()
4124
4014
  });
4125
- var responsiveSearchAdSchema = z8.object({
4126
- format: z8.literal("responsiveSearch"),
4127
- headlines: z8.array(
4015
+ var responsiveSearchAdSchema = z7.object({
4016
+ format: z7.literal("responsiveSearch"),
4017
+ headlines: z7.array(
4128
4018
  adTextAssetSchema.refine(
4129
4019
  (a) => a.text.length <= GOOGLE_ADS_LIMITS.responsiveSearchAd.headlineTextMax,
4130
4020
  "headline exceeds 30 chars"
4131
4021
  )
4132
4022
  ).min(GOOGLE_ADS_LIMITS.responsiveSearchAd.headlinesMin).max(GOOGLE_ADS_LIMITS.responsiveSearchAd.headlinesMax),
4133
- descriptions: z8.array(
4023
+ descriptions: z7.array(
4134
4024
  adTextAssetSchema.refine(
4135
4025
  (a) => a.text.length <= GOOGLE_ADS_LIMITS.responsiveSearchAd.descriptionTextMax,
4136
4026
  "description exceeds 90 chars"
4137
4027
  )
4138
4028
  ).min(GOOGLE_ADS_LIMITS.responsiveSearchAd.descriptionsMin).max(GOOGLE_ADS_LIMITS.responsiveSearchAd.descriptionsMax),
4139
- path1: z8.string().max(GOOGLE_ADS_LIMITS.responsiveSearchAd.pathMax).optional(),
4140
- path2: z8.string().max(GOOGLE_ADS_LIMITS.responsiveSearchAd.pathMax).optional(),
4141
- finalUrls: z8.array(httpsUrlSchema2).min(1)
4142
- });
4143
- var responsiveDisplayAdSchema = z8.object({
4144
- format: z8.literal("responsiveDisplay"),
4145
- headlines: z8.array(z8.object({ text: z8.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.headlineTextMax) })).min(1).max(5),
4146
- longHeadline: z8.object({ text: z8.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.longHeadlineTextMax) }),
4147
- descriptions: z8.array(z8.object({ text: z8.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.descriptionTextMax) })).min(1).max(5),
4148
- businessName: z8.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.businessNameMax),
4029
+ path1: z7.string().max(GOOGLE_ADS_LIMITS.responsiveSearchAd.pathMax).optional(),
4030
+ path2: z7.string().max(GOOGLE_ADS_LIMITS.responsiveSearchAd.pathMax).optional(),
4031
+ finalUrls: z7.array(httpsUrlSchema2).min(1)
4032
+ });
4033
+ var responsiveDisplayAdSchema = z7.object({
4034
+ format: z7.literal("responsiveDisplay"),
4035
+ headlines: z7.array(z7.object({ text: z7.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.headlineTextMax) })).min(1).max(5),
4036
+ longHeadline: z7.object({ text: z7.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.longHeadlineTextMax) }),
4037
+ descriptions: z7.array(z7.object({ text: z7.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.descriptionTextMax) })).min(1).max(5),
4038
+ businessName: z7.string().min(1).max(GOOGLE_ADS_LIMITS.responsiveDisplayAd.businessNameMax),
4149
4039
  // A Responsive Display Ad's images are fields on the ad's own content (never campaign-level
4150
4040
  // asset links). Google requires ≥1 landscape marketing image (1.91:1) AND ≥1 square marketing
4151
4041
  // image (1:1) to serve; the logo images are optional.
4152
- marketingImageAssets: z8.array(refSchema).optional(),
4153
- squareMarketingImageAssets: z8.array(refSchema).optional(),
4154
- logoImageAssets: z8.array(refSchema).optional(),
4155
- finalUrls: z8.array(httpsUrlSchema2).min(1)
4156
- });
4157
- var callAdSchema = z8.object({
4158
- format: z8.literal("call"),
4159
- countryCode: z8.string().length(2),
4160
- phoneNumber: z8.string().min(3),
4161
- headline1: z8.string().min(1).max(30),
4162
- headline2: z8.string().min(1).max(30),
4163
- description1: z8.string().min(1).max(90),
4164
- description2: z8.string().min(1).max(90),
4165
- businessName: z8.string().min(1).max(25),
4166
- finalUrls: z8.array(httpsUrlSchema2).min(1)
4167
- });
4168
- var appAdSchema = z8.object({
4169
- format: z8.literal("app"),
4170
- headlines: z8.array(z8.object({ text: z8.string().min(1).max(30) })).min(1),
4171
- descriptions: z8.array(z8.object({ text: z8.string().min(1).max(90) })).min(1)
4172
- });
4173
- var videoAdSchema = z8.object({
4174
- format: z8.literal("video"),
4042
+ marketingImageAssets: z7.array(refSchema).optional(),
4043
+ squareMarketingImageAssets: z7.array(refSchema).optional(),
4044
+ logoImageAssets: z7.array(refSchema).optional(),
4045
+ finalUrls: z7.array(httpsUrlSchema2).min(1)
4046
+ });
4047
+ var callAdSchema = z7.object({
4048
+ format: z7.literal("call"),
4049
+ countryCode: z7.string().length(2),
4050
+ phoneNumber: z7.string().min(3),
4051
+ headline1: z7.string().min(1).max(30),
4052
+ headline2: z7.string().min(1).max(30),
4053
+ description1: z7.string().min(1).max(90),
4054
+ description2: z7.string().min(1).max(90),
4055
+ businessName: z7.string().min(1).max(25),
4056
+ finalUrls: z7.array(httpsUrlSchema2).min(1)
4057
+ });
4058
+ var appAdSchema = z7.object({
4059
+ format: z7.literal("app"),
4060
+ headlines: z7.array(z7.object({ text: z7.string().min(1).max(30) })).min(1),
4061
+ descriptions: z7.array(z7.object({ text: z7.string().min(1).max(90) })).min(1)
4062
+ });
4063
+ var videoAdSchema = z7.object({
4064
+ format: z7.literal("video"),
4175
4065
  // A raw YouTube id is not a publishable Google Ads reference — the video must be staged as
4176
4066
  // its own `google.asset.create` (type: youtubeVideo) first, then referenced here by asset ref.
4177
- videoAssets: z8.array(refSchema).min(1),
4178
- finalUrls: z8.array(httpsUrlSchema2).min(1)
4179
- });
4180
- var demandGenAdSchema = z8.object({
4181
- format: z8.literal("demandGen"),
4182
- headlines: z8.array(z8.object({ text: z8.string().min(1).max(40) })).min(1).max(5),
4183
- descriptions: z8.array(z8.object({ text: z8.string().min(1).max(90) })).min(1).max(5),
4184
- businessName: z8.string().min(1).max(25),
4185
- finalUrls: z8.array(httpsUrlSchema2).min(1),
4186
- imageAssets: z8.array(refSchema).optional(),
4187
- squareImageAssets: z8.array(refSchema).optional(),
4188
- logoImageAssets: z8.array(refSchema).optional()
4189
- });
4190
- var adContentSchema = z8.discriminatedUnion("format", [
4067
+ videoAssets: z7.array(refSchema).min(1),
4068
+ finalUrls: z7.array(httpsUrlSchema2).min(1)
4069
+ });
4070
+ var demandGenAdSchema = z7.object({
4071
+ format: z7.literal("demandGen"),
4072
+ headlines: z7.array(z7.object({ text: z7.string().min(1).max(40) })).min(1).max(5),
4073
+ descriptions: z7.array(z7.object({ text: z7.string().min(1).max(90) })).min(1).max(5),
4074
+ businessName: z7.string().min(1).max(25),
4075
+ finalUrls: z7.array(httpsUrlSchema2).min(1),
4076
+ imageAssets: z7.array(refSchema).optional(),
4077
+ squareImageAssets: z7.array(refSchema).optional(),
4078
+ logoImageAssets: z7.array(refSchema).optional()
4079
+ });
4080
+ var adContentSchema = z7.discriminatedUnion("format", [
4191
4081
  responsiveSearchAdSchema,
4192
4082
  responsiveDisplayAdSchema,
4193
4083
  callAdSchema,
@@ -4195,45 +4085,45 @@ var adContentSchema = z8.discriminatedUnion("format", [
4195
4085
  videoAdSchema,
4196
4086
  demandGenAdSchema
4197
4087
  ]);
4198
- var adCreateSchema = z8.object({
4088
+ var adCreateSchema = z7.object({
4199
4089
  adGroup: refSchema,
4200
4090
  status: stageableStatusSchema2.default("PAUSED"),
4201
4091
  content: adContentSchema
4202
4092
  });
4203
- var adUpdateSchema = z8.object({
4204
- status: z8.enum(["ENABLED", "PAUSED", "REMOVED"]).optional(),
4093
+ var adUpdateSchema = z7.object({
4094
+ status: z7.enum(["ENABLED", "PAUSED", "REMOVED"]).optional(),
4205
4095
  /** Whole-content replacement for RSA-like formats; re-validated against adContentSchema. */
4206
- content: z8.record(z8.string(), z8.unknown()).optional()
4096
+ content: z7.record(z7.string(), z7.unknown()).optional()
4207
4097
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
4208
- var textAssetSchema = z8.object({ type: z8.literal("text"), text: z8.string().min(1) });
4209
- var imageAssetSchema = z8.object({
4210
- type: z8.literal("image"),
4211
- imageId: z8.string().min(1),
4212
- name: z8.string().optional()
4213
- });
4214
- var youtubeVideoAssetSchema = z8.object({
4215
- type: z8.literal("youtubeVideo"),
4216
- youtubeVideoId: z8.string().min(1),
4217
- name: z8.string().optional()
4218
- });
4219
- var sitelinkAssetSchema = z8.object({
4220
- type: z8.literal("sitelink"),
4221
- linkText: z8.string().min(1).max(GOOGLE_ADS_LIMITS.asset.sitelinkLinkTextMax),
4222
- description1: z8.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
4223
- description2: z8.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
4224
- finalUrls: z8.array(httpsUrlSchema2).min(1)
4225
- });
4226
- var calloutAssetSchema = z8.object({
4227
- type: z8.literal("callout"),
4228
- calloutText: z8.string().min(1).max(GOOGLE_ADS_LIMITS.asset.calloutTextMax)
4229
- });
4230
- var structuredSnippetAssetSchema = z8.object({
4231
- type: z8.literal("structuredSnippet"),
4232
- header: z8.string().min(1).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetHeaderMax),
4233
- values: z8.array(z8.string().min(1)).min(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMin).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMax)
4234
- });
4235
- var callToActionAssetSchema = z8.object({ type: z8.literal("callToAction"), callToAction: z8.string().min(1) });
4236
- var assetCreateSchema = z8.discriminatedUnion("type", [
4098
+ var textAssetSchema = z7.object({ type: z7.literal("text"), text: z7.string().min(1) });
4099
+ var imageAssetSchema = z7.object({
4100
+ type: z7.literal("image"),
4101
+ imageId: z7.string().min(1),
4102
+ name: z7.string().optional()
4103
+ });
4104
+ var youtubeVideoAssetSchema = z7.object({
4105
+ type: z7.literal("youtubeVideo"),
4106
+ youtubeVideoId: z7.string().min(1),
4107
+ name: z7.string().optional()
4108
+ });
4109
+ var sitelinkAssetSchema = z7.object({
4110
+ type: z7.literal("sitelink"),
4111
+ linkText: z7.string().min(1).max(GOOGLE_ADS_LIMITS.asset.sitelinkLinkTextMax),
4112
+ description1: z7.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
4113
+ description2: z7.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
4114
+ finalUrls: z7.array(httpsUrlSchema2).min(1)
4115
+ });
4116
+ var calloutAssetSchema = z7.object({
4117
+ type: z7.literal("callout"),
4118
+ calloutText: z7.string().min(1).max(GOOGLE_ADS_LIMITS.asset.calloutTextMax)
4119
+ });
4120
+ var structuredSnippetAssetSchema = z7.object({
4121
+ type: z7.literal("structuredSnippet"),
4122
+ header: z7.string().min(1).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetHeaderMax),
4123
+ values: z7.array(z7.string().min(1)).min(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMin).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMax)
4124
+ });
4125
+ var callToActionAssetSchema = z7.object({ type: z7.literal("callToAction"), callToAction: z7.string().min(1) });
4126
+ var assetCreateSchema = z7.discriminatedUnion("type", [
4237
4127
  textAssetSchema,
4238
4128
  imageAssetSchema,
4239
4129
  youtubeVideoAssetSchema,
@@ -4242,136 +4132,136 @@ var assetCreateSchema = z8.discriminatedUnion("type", [
4242
4132
  structuredSnippetAssetSchema,
4243
4133
  callToActionAssetSchema
4244
4134
  ]);
4245
- var assetUpdateSchema = z8.object({
4246
- name: z8.string().min(1).optional(),
4247
- linkText: z8.string().min(1).max(GOOGLE_ADS_LIMITS.asset.sitelinkLinkTextMax).optional(),
4248
- description1: z8.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
4249
- description2: z8.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
4250
- finalUrls: z8.array(httpsUrlSchema2).min(1).optional(),
4251
- calloutText: z8.string().min(1).max(GOOGLE_ADS_LIMITS.asset.calloutTextMax).optional(),
4252
- header: z8.string().min(1).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetHeaderMax).optional(),
4253
- values: z8.array(z8.string().min(1)).min(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMin).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMax).optional(),
4254
- callToAction: z8.string().min(1).optional(),
4255
- text: z8.string().min(1).optional()
4135
+ var assetUpdateSchema = z7.object({
4136
+ name: z7.string().min(1).optional(),
4137
+ linkText: z7.string().min(1).max(GOOGLE_ADS_LIMITS.asset.sitelinkLinkTextMax).optional(),
4138
+ description1: z7.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
4139
+ description2: z7.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
4140
+ finalUrls: z7.array(httpsUrlSchema2).min(1).optional(),
4141
+ calloutText: z7.string().min(1).max(GOOGLE_ADS_LIMITS.asset.calloutTextMax).optional(),
4142
+ header: z7.string().min(1).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetHeaderMax).optional(),
4143
+ values: z7.array(z7.string().min(1)).min(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMin).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMax).optional(),
4144
+ callToAction: z7.string().min(1).optional(),
4145
+ text: z7.string().min(1).optional()
4256
4146
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
4257
- var assetLinkAttachSchema = z8.object({
4258
- level: z8.enum(["campaign", "adGroup", "customer"]),
4147
+ var assetLinkAttachSchema = z7.object({
4148
+ level: z7.enum(["campaign", "adGroup", "customer"]),
4259
4149
  parent: refSchema.optional(),
4260
4150
  asset: refSchema,
4261
- fieldType: z8.enum(ASSET_FIELD_TYPES)
4151
+ fieldType: z7.enum(ASSET_FIELD_TYPES)
4262
4152
  }).superRefine((value, ctx) => {
4263
4153
  if (value.level !== "customer" && !value.parent) {
4264
4154
  ctx.addIssue({
4265
- code: z8.ZodIssueCode.custom,
4155
+ code: z7.ZodIssueCode.custom,
4266
4156
  path: ["parent"],
4267
4157
  message: `parent is required for a ${value.level}-level asset link (--parent-ref)`
4268
4158
  });
4269
4159
  }
4270
4160
  });
4271
- var assetGroupCreateSchema = z8.object({
4161
+ var assetGroupCreateSchema = z7.object({
4272
4162
  campaign: refSchema,
4273
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.nameMax),
4274
- finalUrls: z8.array(httpsUrlSchema2).min(1),
4275
- 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),
4276
- 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),
4277
- 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),
4278
- businessName: z8.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.businessNameMax),
4279
- imageAssets: z8.array(refSchema).optional(),
4280
- squareImageAssets: z8.array(refSchema).optional(),
4281
- logoAssets: z8.array(refSchema).optional(),
4282
- status: z8.enum(["ENABLED", "PAUSED"]).default("PAUSED")
4283
- });
4284
- var assetGroupUpdateSchema = z8.object({
4285
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.nameMax).optional(),
4286
- finalUrls: z8.array(httpsUrlSchema2).min(1).optional(),
4287
- status: z8.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
4163
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.nameMax),
4164
+ finalUrls: z7.array(httpsUrlSchema2).min(1),
4165
+ 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),
4166
+ 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),
4167
+ 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),
4168
+ businessName: z7.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.businessNameMax),
4169
+ imageAssets: z7.array(refSchema).optional(),
4170
+ squareImageAssets: z7.array(refSchema).optional(),
4171
+ logoAssets: z7.array(refSchema).optional(),
4172
+ status: z7.enum(["ENABLED", "PAUSED"]).default("PAUSED")
4173
+ });
4174
+ var assetGroupUpdateSchema = z7.object({
4175
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.assetGroup.nameMax).optional(),
4176
+ finalUrls: z7.array(httpsUrlSchema2).min(1).optional(),
4177
+ status: z7.enum(["ENABLED", "PAUSED", "REMOVED"]).optional()
4288
4178
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
4289
- var audienceCreateSchema2 = z8.object({
4290
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.audience.nameMax),
4291
- type: z8.enum(USER_LIST_TYPES).default("BASIC"),
4292
- description: z8.string().optional(),
4179
+ var audienceCreateSchema2 = z7.object({
4180
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.audience.nameMax),
4181
+ type: z7.enum(USER_LIST_TYPES).default("BASIC"),
4182
+ description: z7.string().optional(),
4293
4183
  /** Customer-match members (crm-based) — file-first for large lists. */
4294
- members: z8.array(z8.record(z8.string(), z8.string())).optional(),
4295
- sourceFileRef: z8.string().optional()
4184
+ members: z7.array(z7.record(z7.string(), z7.string())).optional(),
4185
+ sourceFileRef: z7.string().optional()
4296
4186
  });
4297
- var audienceCriterionAttachSchema = z8.object({
4298
- level: z8.enum(["campaign", "adGroup"]),
4187
+ var audienceCriterionAttachSchema = z7.object({
4188
+ level: z7.enum(["campaign", "adGroup"]),
4299
4189
  parent: refSchema,
4300
4190
  userList: refSchema,
4301
- negative: z8.boolean().default(false)
4191
+ negative: z7.boolean().default(false)
4302
4192
  });
4303
- var conversionActionCreateSchema = z8.object({
4304
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.conversionAction.nameMax),
4305
- type: z8.enum(CONVERSION_ACTION_TYPES).default("WEBPAGE"),
4306
- category: z8.enum(CONVERSION_ACTION_CATEGORIES).default("DEFAULT"),
4307
- countingType: z8.enum(CONVERSION_COUNTING_TYPES).default("ONE_PER_CLICK"),
4193
+ var conversionActionCreateSchema = z7.object({
4194
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.conversionAction.nameMax),
4195
+ type: z7.enum(CONVERSION_ACTION_TYPES).default("WEBPAGE"),
4196
+ category: z7.enum(CONVERSION_ACTION_CATEGORIES).default("DEFAULT"),
4197
+ countingType: z7.enum(CONVERSION_COUNTING_TYPES).default("ONE_PER_CLICK"),
4308
4198
  defaultValueMicros: microsSchema.optional(),
4309
- defaultCurrencyCode: z8.string().length(3).optional(),
4310
- clickThroughLookbackWindowDays: z8.number().int().positive().optional(),
4311
- viewThroughLookbackWindowDays: z8.number().int().positive().optional(),
4312
- status: z8.enum(["ENABLED", "PAUSED"]).default("ENABLED")
4313
- });
4314
- var conversionActionUpdateSchema = z8.object({
4315
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.conversionAction.nameMax).optional(),
4316
- category: z8.enum(CONVERSION_ACTION_CATEGORIES).optional(),
4317
- countingType: z8.enum(CONVERSION_COUNTING_TYPES).optional(),
4199
+ defaultCurrencyCode: z7.string().length(3).optional(),
4200
+ clickThroughLookbackWindowDays: z7.number().int().positive().optional(),
4201
+ viewThroughLookbackWindowDays: z7.number().int().positive().optional(),
4202
+ status: z7.enum(["ENABLED", "PAUSED"]).default("ENABLED")
4203
+ });
4204
+ var conversionActionUpdateSchema = z7.object({
4205
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.conversionAction.nameMax).optional(),
4206
+ category: z7.enum(CONVERSION_ACTION_CATEGORIES).optional(),
4207
+ countingType: z7.enum(CONVERSION_COUNTING_TYPES).optional(),
4318
4208
  defaultValueMicros: microsSchema.optional(),
4319
- defaultCurrencyCode: z8.string().length(3).optional(),
4320
- clickThroughLookbackWindowDays: z8.number().int().positive().optional(),
4321
- viewThroughLookbackWindowDays: z8.number().int().positive().optional(),
4322
- status: z8.enum(["ENABLED", "REMOVED", "HIDDEN"]).optional()
4209
+ defaultCurrencyCode: z7.string().length(3).optional(),
4210
+ clickThroughLookbackWindowDays: z7.number().int().positive().optional(),
4211
+ viewThroughLookbackWindowDays: z7.number().int().positive().optional(),
4212
+ status: z7.enum(["ENABLED", "REMOVED", "HIDDEN"]).optional()
4323
4213
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
4324
- var biddingStrategyCreateSchema = z8.object({
4325
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.biddingStrategy.nameMax),
4214
+ var biddingStrategyCreateSchema = z7.object({
4215
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.biddingStrategy.nameMax),
4326
4216
  config: biddingConfigSchema
4327
4217
  }).superRefine((p, ctx) => {
4328
4218
  if (p.config.type === "MANUAL_CPC") {
4329
4219
  ctx.addIssue({ code: "custom", path: ["config", "type"], message: "portfolio strategies cannot be Manual CPC" });
4330
4220
  }
4331
4221
  });
4332
- var biddingStrategyUpdateSchema = z8.object({
4333
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.biddingStrategy.nameMax).optional(),
4222
+ var biddingStrategyUpdateSchema = z7.object({
4223
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.biddingStrategy.nameMax).optional(),
4334
4224
  config: biddingConfigSchema.optional()
4335
4225
  }).refine((p) => Object.values(p).some((v) => v !== void 0), "update needs at least one field");
4336
- var labelCreateSchema = z8.object({
4337
- name: z8.string().min(1).max(GOOGLE_ADS_LIMITS.label.nameMax),
4338
- backgroundColor: z8.string().regex(/^#[0-9A-Fa-f]{6}$/).optional(),
4339
- description: z8.string().optional()
4226
+ var labelCreateSchema = z7.object({
4227
+ name: z7.string().min(1).max(GOOGLE_ADS_LIMITS.label.nameMax),
4228
+ backgroundColor: z7.string().regex(/^#[0-9A-Fa-f]{6}$/).optional(),
4229
+ description: z7.string().optional()
4340
4230
  });
4341
- var labelAttachSchema = z8.object({
4342
- level: z8.enum(["campaign", "adGroup", "ad"]),
4231
+ var labelAttachSchema = z7.object({
4232
+ level: z7.enum(["campaign", "adGroup", "ad"]),
4343
4233
  parent: refSchema,
4344
4234
  label: refSchema
4345
4235
  });
4346
- var locationCriterionSchema = z8.object({
4347
- criterionType: z8.literal("location"),
4348
- geoTargetConstant: z8.union([z8.string().regex(GEO_TARGET_CONSTANT_REGEX), z8.string().regex(NUMERIC_ID_REGEX2)])
4349
- });
4350
- var languageCriterionSchema = z8.object({
4351
- criterionType: z8.literal("language"),
4352
- languageConstant: z8.union([z8.string().regex(LANGUAGE_CONSTANT_REGEX), z8.string().regex(NUMERIC_ID_REGEX2)])
4353
- });
4354
- var adScheduleCriterionSchema = z8.object({
4355
- criterionType: z8.literal("adSchedule"),
4356
- dayOfWeek: z8.enum(DAYS_OF_WEEK),
4357
- startHour: z8.number().int().min(0).max(23),
4358
- startMinute: z8.enum(["ZERO", "FIFTEEN", "THIRTY", "FORTY_FIVE"]).default("ZERO"),
4359
- endHour: z8.number().int().min(0).max(24),
4360
- endMinute: z8.enum(["ZERO", "FIFTEEN", "THIRTY", "FORTY_FIVE"]).default("ZERO")
4361
- });
4362
- var deviceCriterionSchema = z8.object({
4363
- criterionType: z8.literal("device"),
4364
- device: z8.enum(DEVICE_TYPES),
4236
+ var locationCriterionSchema = z7.object({
4237
+ criterionType: z7.literal("location"),
4238
+ geoTargetConstant: z7.union([z7.string().regex(GEO_TARGET_CONSTANT_REGEX), z7.string().regex(NUMERIC_ID_REGEX2)])
4239
+ });
4240
+ var languageCriterionSchema = z7.object({
4241
+ criterionType: z7.literal("language"),
4242
+ languageConstant: z7.union([z7.string().regex(LANGUAGE_CONSTANT_REGEX), z7.string().regex(NUMERIC_ID_REGEX2)])
4243
+ });
4244
+ var adScheduleCriterionSchema = z7.object({
4245
+ criterionType: z7.literal("adSchedule"),
4246
+ dayOfWeek: z7.enum(DAYS_OF_WEEK),
4247
+ startHour: z7.number().int().min(0).max(23),
4248
+ startMinute: z7.enum(["ZERO", "FIFTEEN", "THIRTY", "FORTY_FIVE"]).default("ZERO"),
4249
+ endHour: z7.number().int().min(0).max(24),
4250
+ endMinute: z7.enum(["ZERO", "FIFTEEN", "THIRTY", "FORTY_FIVE"]).default("ZERO")
4251
+ });
4252
+ var deviceCriterionSchema = z7.object({
4253
+ criterionType: z7.literal("device"),
4254
+ device: z7.enum(DEVICE_TYPES),
4365
4255
  // Google's `CampaignCriterion.bid_modifier`: "The modifier must be in the range 0.1 - 10.0. Use 0
4366
4256
  // 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.
4367
- bidModifier: z8.number().min(0).max(10).optional().refine((v) => v === void 0 || v === 0 || v >= 0.1, {
4257
+ bidModifier: z7.number().min(0).max(10).optional().refine((v) => v === void 0 || v === 0 || v >= 0.1, {
4368
4258
  message: "bid modifier must be 0 (exclude the device) or between 0.1 and 10.0"
4369
4259
  })
4370
4260
  });
4371
- var campaignCriterionAddSchema = z8.object({
4261
+ var campaignCriterionAddSchema = z7.object({
4372
4262
  campaign: refSchema,
4373
- negative: z8.boolean().default(false),
4374
- criterion: z8.discriminatedUnion("criterionType", [
4263
+ negative: z7.boolean().default(false),
4264
+ criterion: z7.discriminatedUnion("criterionType", [
4375
4265
  locationCriterionSchema,
4376
4266
  languageCriterionSchema,
4377
4267
  adScheduleCriterionSchema,
@@ -4381,7 +4271,7 @@ var campaignCriterionAddSchema = z8.object({
4381
4271
  const c = val.criterion;
4382
4272
  if (c.criterionType === "adSchedule" && c.endHour === 24 && c.endMinute !== "ZERO") {
4383
4273
  ctx.addIssue({
4384
- code: z8.ZodIssueCode.custom,
4274
+ code: z7.ZodIssueCode.custom,
4385
4275
  message: "endHour 24 (midnight) cannot have a non-zero endMinute",
4386
4276
  path: ["criterion", "endMinute"]
4387
4277
  });
@@ -4433,17 +4323,17 @@ var GOOGLE_DRAFT_OP_KINDS = [
4433
4323
  "google.campaignCriterion.add",
4434
4324
  "google.campaignCriterion.remove"
4435
4325
  ];
4436
- var googleDraftOpKindSchema = z8.enum(GOOGLE_DRAFT_OP_KINDS);
4326
+ var googleDraftOpKindSchema = z7.enum(GOOGLE_DRAFT_OP_KINDS);
4437
4327
  function createOp2(kind, payload) {
4438
- return z8.object({ kind: z8.literal(kind), customerId: customerIdSchema, payload });
4328
+ return z7.object({ kind: z7.literal(kind), customerId: customerIdSchema, payload });
4439
4329
  }
4440
4330
  function updateOp2(kind, payload) {
4441
- return z8.object({ kind: z8.literal(kind), customerId: customerIdSchema, target: targetRefSchema, payload });
4331
+ return z7.object({ kind: z7.literal(kind), customerId: customerIdSchema, target: targetRefSchema, payload });
4442
4332
  }
4443
4333
  function targetOp(kind) {
4444
- return z8.object({ kind: z8.literal(kind), customerId: customerIdSchema, target: targetRefSchema });
4334
+ return z7.object({ kind: z7.literal(kind), customerId: customerIdSchema, target: targetRefSchema });
4445
4335
  }
4446
- var googleDraftOpInputSchema = z8.discriminatedUnion("kind", [
4336
+ var googleDraftOpInputSchema = z7.discriminatedUnion("kind", [
4447
4337
  createOp2("google.budget.create", budgetCreateSchema),
4448
4338
  updateOp2("google.budget.update", budgetUpdateSchema),
4449
4339
  createOp2("google.campaign.create", campaignCreateSchema2),
@@ -4491,132 +4381,132 @@ var googleDraftOpInputSchema = z8.discriminatedUnion("kind", [
4491
4381
  ]);
4492
4382
 
4493
4383
  // ../api/src/ads-google/wire.ts
4494
- import { z as z9 } from "zod";
4495
- var googleWriteModeSchema = z9.enum(["live", "simulated"]);
4496
- var googleDraftOpResultSchema = z9.object({
4497
- status: z9.enum(["applied", "simulated", "failed", "skipped"]),
4498
- resourceName: z9.string().optional(),
4499
- error: z9.string().optional(),
4500
- skippedBecause: z9.string().optional(),
4501
- executedAt: z9.number().optional()
4502
- });
4503
- var googleDraftStageRequestSchema = z9.object({
4504
- chatId: z9.string(),
4384
+ import { z as z8 } from "zod";
4385
+ var googleWriteModeSchema = z8.enum(["live", "simulated"]);
4386
+ var googleDraftOpResultSchema = z8.object({
4387
+ status: z8.enum(["applied", "simulated", "failed", "skipped"]),
4388
+ resourceName: z8.string().optional(),
4389
+ error: z8.string().optional(),
4390
+ skippedBecause: z8.string().optional(),
4391
+ executedAt: z8.number().optional()
4392
+ });
4393
+ var googleDraftStageRequestSchema = z8.object({
4394
+ chatId: z8.string(),
4505
4395
  op: googleDraftOpInputSchema
4506
4396
  });
4507
- var googleDraftStageResponseSchema = z9.object({
4508
- staged: z9.literal(true),
4509
- ref: z9.string(),
4397
+ var googleDraftStageResponseSchema = z8.object({
4398
+ staged: z8.literal(true),
4399
+ ref: z8.string(),
4510
4400
  kind: googleDraftOpKindSchema,
4511
4401
  mode: googleWriteModeSchema,
4512
- dependsOn: z9.array(z9.string()),
4513
- summary: z9.string(),
4514
- warnings: z9.array(z9.string()),
4402
+ dependsOn: z8.array(z8.string()),
4403
+ summary: z8.string(),
4404
+ warnings: z8.array(z8.string()),
4515
4405
  /** True when the op amended an already-staged op in place instead of appending a new one. */
4516
- amended: z9.boolean().optional()
4406
+ amended: z8.boolean().optional()
4517
4407
  });
4518
- var googleDraftAmendRequestSchema = z9.object({
4519
- chatId: z9.string(),
4520
- ref: z9.string(),
4521
- patch: z9.record(z9.string(), z9.unknown())
4408
+ var googleDraftAmendRequestSchema = z8.object({
4409
+ chatId: z8.string(),
4410
+ ref: z8.string(),
4411
+ patch: z8.record(z8.string(), z8.unknown())
4522
4412
  });
4523
- var googleDraftShowRequestSchema = z9.object({
4524
- chatId: z9.string(),
4525
- ref: z9.string()
4413
+ var googleDraftShowRequestSchema = z8.object({
4414
+ chatId: z8.string(),
4415
+ ref: z8.string()
4526
4416
  });
4527
4417
  var GOOGLE_DRAFT_BATCH_MAX = 500;
4528
- var googleDraftStageBatchRequestSchema = z9.object({
4529
- chatId: z9.string(),
4530
- ops: z9.array(googleDraftOpInputSchema).min(1).max(GOOGLE_DRAFT_BATCH_MAX)
4418
+ var googleDraftStageBatchRequestSchema = z8.object({
4419
+ chatId: z8.string(),
4420
+ ops: z8.array(googleDraftOpInputSchema).min(1).max(GOOGLE_DRAFT_BATCH_MAX)
4531
4421
  });
4532
- var googleDraftStageBatchResponseSchema = z9.object({
4533
- staged: z9.literal(true),
4422
+ var googleDraftStageBatchResponseSchema = z8.object({
4423
+ staged: z8.literal(true),
4534
4424
  mode: googleWriteModeSchema,
4535
- count: z9.number(),
4536
- ops: z9.array(
4537
- z9.object({
4538
- ref: z9.string(),
4425
+ count: z8.number(),
4426
+ ops: z8.array(
4427
+ z8.object({
4428
+ ref: z8.string(),
4539
4429
  kind: googleDraftOpKindSchema,
4540
- dependsOn: z9.array(z9.string()),
4541
- summary: z9.string(),
4542
- warnings: z9.array(z9.string())
4430
+ dependsOn: z8.array(z8.string()),
4431
+ summary: z8.string(),
4432
+ warnings: z8.array(z8.string())
4543
4433
  })
4544
4434
  )
4545
4435
  });
4546
- var googleDraftOpViewSchema = z9.object({
4547
- ref: z9.string(),
4436
+ var googleDraftOpViewSchema = z8.object({
4437
+ ref: z8.string(),
4548
4438
  kind: googleDraftOpKindSchema,
4549
- customerId: z9.string(),
4550
- target: z9.string().optional(),
4551
- dependsOn: z9.array(z9.string()),
4552
- summary: z9.string(),
4553
- stagedAt: z9.number(),
4439
+ customerId: z8.string(),
4440
+ target: z8.string().optional(),
4441
+ dependsOn: z8.array(z8.string()),
4442
+ summary: z8.string(),
4443
+ stagedAt: z8.number(),
4554
4444
  result: googleDraftOpResultSchema.optional()
4555
4445
  });
4556
- var googleDraftShowResponseSchema = z9.object({
4446
+ var googleDraftShowResponseSchema = z8.object({
4557
4447
  op: googleDraftOpViewSchema.extend({
4558
- payload: z9.unknown().optional(),
4559
- warnings: z9.array(z9.string()).optional(),
4560
- annotations: z9.unknown().optional()
4448
+ payload: z8.unknown().optional(),
4449
+ warnings: z8.array(z8.string()).optional(),
4450
+ annotations: z8.unknown().optional()
4561
4451
  })
4562
4452
  });
4563
- var googleDraftListRequestSchema = z9.object({
4564
- chatId: z9.string()
4453
+ var googleDraftListRequestSchema = z8.object({
4454
+ chatId: z8.string()
4565
4455
  });
4566
- var googleDraftAdvisorySchema = z9.object({
4567
- scope: z9.enum(["campaign", "adGroup"]),
4568
- message: z9.string()
4456
+ var googleDraftAdvisorySchema = z8.object({
4457
+ scope: z8.enum(["campaign", "adGroup"]),
4458
+ message: z8.string()
4569
4459
  });
4570
- var googleDraftStatusCollectionSchema = z9.object({
4571
- label: z9.string(),
4572
- added: z9.number(),
4573
- removed: z9.number(),
4574
- existing: z9.number()
4460
+ var googleDraftStatusCollectionSchema = z8.object({
4461
+ label: z8.string(),
4462
+ added: z8.number(),
4463
+ removed: z8.number(),
4464
+ existing: z8.number()
4575
4465
  });
4576
- var googleDraftChangeOperationSchema = z9.enum(["create", "update", "pause", "resume", "remove"]);
4577
- var googleDraftStatusNodeSchema = z9.lazy(
4578
- () => z9.object({
4579
- entity: z9.string(),
4580
- name: z9.string(),
4466
+ var googleDraftChangeOperationSchema = z8.enum(["create", "update", "pause", "resume", "remove"]);
4467
+ var googleDraftStatusNodeSchema = z8.lazy(
4468
+ () => z8.object({
4469
+ entity: z8.string(),
4470
+ name: z8.string(),
4581
4471
  operation: googleDraftChangeOperationSchema.optional(),
4582
- existing: z9.boolean(),
4583
- collections: z9.array(googleDraftStatusCollectionSchema),
4584
- children: z9.array(googleDraftStatusNodeSchema),
4585
- warnings: z9.array(z9.string()).optional()
4472
+ existing: z8.boolean(),
4473
+ collections: z8.array(googleDraftStatusCollectionSchema),
4474
+ children: z8.array(googleDraftStatusNodeSchema),
4475
+ warnings: z8.array(z8.string()).optional()
4586
4476
  })
4587
4477
  );
4588
- var googleDraftListResponseSchema = z9.object({
4589
- status: z9.enum(["active", "publishing", "applied", "discarded", "none"]),
4478
+ var googleDraftListResponseSchema = z8.object({
4479
+ status: z8.enum(["active", "publishing", "applied", "discarded", "none"]),
4590
4480
  mode: googleWriteModeSchema,
4591
- count: z9.number(),
4592
- ops: z9.array(googleDraftOpViewSchema),
4481
+ count: z8.number(),
4482
+ ops: z8.array(googleDraftOpViewSchema),
4593
4483
  /** Grouped campaign ▸ ad group ▸ ad tree for the readable CLI status view. */
4594
- tree: z9.array(googleDraftStatusNodeSchema).optional(),
4484
+ tree: z8.array(googleDraftStatusNodeSchema).optional(),
4595
4485
  /** Non-blocking completeness advisories for the whole draft. */
4596
- advisories: z9.array(googleDraftAdvisorySchema).optional()
4486
+ advisories: z8.array(googleDraftAdvisorySchema).optional()
4597
4487
  });
4598
- var googleDraftRemoveRequestSchema = z9.object({
4599
- chatId: z9.string(),
4600
- ref: z9.string()
4488
+ var googleDraftRemoveRequestSchema = z8.object({
4489
+ chatId: z8.string(),
4490
+ ref: z8.string()
4601
4491
  });
4602
- var googleDraftRemoveResponseSchema = z9.object({
4492
+ var googleDraftRemoveResponseSchema = z8.object({
4603
4493
  /** The requested ref plus any dependents removed by cascade. */
4604
- removed: z9.array(z9.string())
4494
+ removed: z8.array(z8.string())
4605
4495
  });
4606
- var googleDraftClearRequestSchema = z9.object({
4607
- chatId: z9.string()
4496
+ var googleDraftClearRequestSchema = z8.object({
4497
+ chatId: z8.string()
4608
4498
  });
4609
- var googleDraftClearResponseSchema = z9.object({
4610
- cleared: z9.number()
4499
+ var googleDraftClearResponseSchema = z8.object({
4500
+ cleared: z8.number()
4611
4501
  });
4612
- var googleFieldErrorSchema = z9.object({
4613
- path: z9.string(),
4614
- message: z9.string()
4502
+ var googleFieldErrorSchema = z8.object({
4503
+ path: z8.string(),
4504
+ message: z8.string()
4615
4505
  });
4616
- var googleDraftErrorResponseSchema = z9.object({
4617
- code: z9.string(),
4618
- error: z9.string(),
4619
- fields: z9.array(googleFieldErrorSchema).optional()
4506
+ var googleDraftErrorResponseSchema = z8.object({
4507
+ code: z8.string(),
4508
+ error: z8.string(),
4509
+ fields: z8.array(googleFieldErrorSchema).optional()
4620
4510
  });
4621
4511
 
4622
4512
  // src/commands/ads/google/draft-status.ts
@@ -4781,11 +4671,11 @@ function rawTextEntries(value) {
4781
4671
  const values = Array.isArray(value) ? value : typeof value === "string" ? [value] : [];
4782
4672
  return values.filter((v) => typeof v === "string").flatMap((v) => v.split(",")).map((v) => v.trim()).filter(Boolean);
4783
4673
  }
4784
- function rawFileEntries(path12) {
4785
- if (typeof path12 !== "string" || path12.length === 0) {
4674
+ function rawFileEntries(path14) {
4675
+ if (typeof path14 !== "string" || path14.length === 0) {
4786
4676
  return [];
4787
4677
  }
4788
- return readFileSync2(path12, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
4678
+ return readFileSync2(path14, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#"));
4789
4679
  }
4790
4680
  function keywordEntries(args) {
4791
4681
  const defaultMatch = typeof args["match-type"] === "string" ? args["match-type"].toUpperCase() : void 0;
@@ -4808,19 +4698,19 @@ function keywordEntries(args) {
4808
4698
  }
4809
4699
  return entries;
4810
4700
  }
4811
- function loadJsonFileArg(path12) {
4812
- if (typeof path12 !== "string" || path12.length === 0) {
4701
+ function loadJsonFileArg(path14) {
4702
+ if (typeof path14 !== "string" || path14.length === 0) {
4813
4703
  return {};
4814
4704
  }
4815
4705
  try {
4816
- const parsed = JSON.parse(readFileSync2(path12, "utf8"));
4706
+ const parsed = JSON.parse(readFileSync2(path14, "utf8"));
4817
4707
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
4818
- failWriteValidation(`${path12} must contain a JSON object`);
4708
+ failWriteValidation(`${path14} must contain a JSON object`);
4819
4709
  }
4820
4710
  return parsed;
4821
4711
  } catch (err) {
4822
4712
  if (err instanceof SyntaxError) {
4823
- failWriteValidation(`${path12} is not valid JSON: ${err.message}`);
4713
+ failWriteValidation(`${path14} is not valid JSON: ${err.message}`);
4824
4714
  }
4825
4715
  throw err;
4826
4716
  }
@@ -4931,10 +4821,10 @@ async function stageUpdate(kind, customerId, target, payload) {
4931
4821
  async function stageTarget(kind, customerId, target) {
4932
4822
  await stageGoogleOp({ kind, customerId, target });
4933
4823
  }
4934
- async function draftAction(path12, body) {
4824
+ async function draftAction(path14, body) {
4935
4825
  try {
4936
4826
  const chatId = requireChatId();
4937
- const response = await apiPost(path12, { chatId, ...body });
4827
+ const response = await apiPost(path14, { chatId, ...body });
4938
4828
  writeJsonEnvelope(response);
4939
4829
  } catch (err) {
4940
4830
  handleGoogleError(err);
@@ -8689,19 +8579,19 @@ function failWriteValidation2(message) {
8689
8579
  writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
8690
8580
  process.exit(1);
8691
8581
  }
8692
- function loadJsonFileArg2(path12) {
8693
- if (typeof path12 !== "string" || path12.length === 0) {
8582
+ function loadJsonFileArg2(path14) {
8583
+ if (typeof path14 !== "string" || path14.length === 0) {
8694
8584
  return {};
8695
8585
  }
8696
8586
  try {
8697
- const parsed = JSON.parse(readFileSync6(path12, "utf8"));
8587
+ const parsed = JSON.parse(readFileSync6(path14, "utf8"));
8698
8588
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
8699
- failWriteValidation2(`${path12} must contain a JSON object`);
8589
+ failWriteValidation2(`${path14} must contain a JSON object`);
8700
8590
  }
8701
8591
  return parsed;
8702
8592
  } catch (err) {
8703
8593
  if (err instanceof SyntaxError) {
8704
- failWriteValidation2(`${path12} is not valid JSON: ${err.message}`);
8594
+ failWriteValidation2(`${path14} is not valid JSON: ${err.message}`);
8705
8595
  }
8706
8596
  throw err;
8707
8597
  }
@@ -8786,15 +8676,15 @@ function parseLocaleFlag(value) {
8786
8676
  }
8787
8677
  return { language: match[1], country: match[2].toUpperCase() };
8788
8678
  }
8789
- function loadTargetingFileArg(path12) {
8790
- if (typeof path12 !== "string" || path12.length === 0) {
8679
+ function loadTargetingFileArg(path14) {
8680
+ if (typeof path14 !== "string" || path14.length === 0) {
8791
8681
  return void 0;
8792
8682
  }
8793
- const parsed = loadJsonFileArg2(path12);
8683
+ const parsed = loadJsonFileArg2(path14);
8794
8684
  const criteria = parsed.targetingCriteria ?? parsed;
8795
8685
  if (!criteria.include) {
8796
8686
  failWriteValidation2(
8797
- `${path12} must contain targeting criteria with an "include" block (see baker schema ads.linkedin.campaigns.create)`
8687
+ `${path14} must contain targeting criteria with an "include" block (see baker schema ads.linkedin.campaigns.create)`
8798
8688
  );
8799
8689
  }
8800
8690
  return criteria;
@@ -8829,14 +8719,14 @@ function parseCsvLine(line) {
8829
8719
  cells.push(current);
8830
8720
  return cells.map((cell) => cell.trim());
8831
8721
  }
8832
- function parseListFileArg(path12, maxRows) {
8833
- if (typeof path12 !== "string" || path12.length === 0) {
8722
+ function parseListFileArg(path14, maxRows) {
8723
+ if (typeof path14 !== "string" || path14.length === 0) {
8834
8724
  return void 0;
8835
8725
  }
8836
- const raw = readFileSync6(path12, "utf8");
8726
+ const raw = readFileSync6(path14, "utf8");
8837
8727
  const lines = raw.split(/\r?\n/).filter((line) => line.trim().length > 0);
8838
8728
  if (lines.length < 2) {
8839
- failWriteValidation2(`${path12} needs a header row and at least one data row`);
8729
+ failWriteValidation2(`${path14} needs a header row and at least one data row`);
8840
8730
  }
8841
8731
  const columns = parseCsvLine(lines[0]).map((column) => column.trim());
8842
8732
  const rows = [];
@@ -8855,7 +8745,7 @@ function parseListFileArg(path12, maxRows) {
8855
8745
  }
8856
8746
  }
8857
8747
  if (rows.length > maxRows) {
8858
- failWriteValidation2(`${path12} has ${rows.length} rows \u2014 the inline limit is ${maxRows}. Split the list.`);
8748
+ failWriteValidation2(`${path14} has ${rows.length} rows \u2014 the inline limit is ${maxRows}. Split the list.`);
8859
8749
  }
8860
8750
  return { columns, rows };
8861
8751
  }
@@ -9500,7 +9390,7 @@ var leadFormsCreateCommand = defineCommand38({
9500
9390
  Required: name, headline (\u226460), privacyPolicyUrl, questions[] (\u226412; playbook: \u22644 for completion).
9501
9391
  Each question is a predefined profile field ({ name, predefinedField: "EMAIL" }) or a custom question ({ name, questionType: "MULTIPLE_CHOICE", options: [...] }; \u22643 custom).
9502
9392
  Best-practice fields the preview will nudge for if missing: 1-3 qualifying questions, consents[] (disclosure checkboxes), thankYou.message + thankYou.landingUrl|appointmentUrl.
9503
- Also supported: locale, formImageId|formImageUrn, hiddenFields[], legalDisclaimer, thankYou.cta. Example: baker ads linkedin lead-forms create --file form.json`
9393
+ Also supported: locale, formImageId|formImageUrn, privacyPolicyText, hiddenFields[], legalDisclaimer, thankYou.cta. Example: baker ads linkedin lead-forms create --file form.json`
9504
9394
  },
9505
9395
  args: {
9506
9396
  ...accountArgs,
@@ -10924,72 +10814,72 @@ var NUMERIC_ID_REGEX3 = /^\d+$/;
10924
10814
  var IMAGE_HASH_REGEX = /^[A-Fa-f0-9]{16,}$/;
10925
10815
 
10926
10816
  // ../api/src/ads-meta/ops.ts
10927
- import { z as z10 } from "zod";
10928
- var tempRefSchema3 = z10.string().regex(TEMP_REF_REGEX3, "expected a meta_temp_* reference");
10929
- var parentRefSchema2 = z10.union([z10.string().regex(NUMERIC_ID_REGEX3, "expected a numeric id"), tempRefSchema3]);
10930
- var moneySchema2 = z10.object({
10931
- 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"),
10932
- currencyCode: z10.string().length(3).optional()
10933
- });
10934
- var httpsUrlSchema3 = z10.string().url().refine((u) => u.startsWith("https://"), "destination URLs must be https");
10935
- var bakerMediaIdSchema2 = z10.string().min(1);
10936
- var stageableStatusSchema3 = z10.enum(STAGEABLE_CREATE_STATUSES3);
10937
- var updateStatusSchema = z10.enum(UPDATE_STATUSES);
10817
+ import { z as z9 } from "zod";
10818
+ var tempRefSchema3 = z9.string().regex(TEMP_REF_REGEX3, "expected a meta_temp_* reference");
10819
+ var parentRefSchema2 = z9.union([z9.string().regex(NUMERIC_ID_REGEX3, "expected a numeric id"), tempRefSchema3]);
10820
+ var moneySchema2 = z9.object({
10821
+ 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"),
10822
+ currencyCode: z9.string().length(3).optional()
10823
+ });
10824
+ var httpsUrlSchema3 = z9.string().url().refine((u) => u.startsWith("https://"), "destination URLs must be https");
10825
+ var bakerMediaIdSchema2 = z9.string().min(1);
10826
+ var stageableStatusSchema3 = z9.enum(STAGEABLE_CREATE_STATUSES3);
10827
+ var updateStatusSchema = z9.enum(UPDATE_STATUSES);
10938
10828
  function currencyMinimums2(currencyCode) {
10939
10829
  return CURRENCY_MINIMUMS2[currencyCode] ?? DEFAULT_CURRENCY_MINIMUM2;
10940
10830
  }
10941
- function validateDailyBudgetFloor(money, ctx, path12) {
10831
+ function validateDailyBudgetFloor(money, ctx, path14) {
10942
10832
  if (money?.currencyCode) {
10943
10833
  const min = currencyMinimums2(money.currencyCode).dailyBudgetMin;
10944
10834
  if (Number(money.amount) < min) {
10945
- ctx.addIssue({ code: "custom", path: path12, message: `below the ${min} ${money.currencyCode} daily minimum` });
10835
+ ctx.addIssue({ code: "custom", path: path14, message: `below the ${min} ${money.currencyCode} daily minimum` });
10946
10836
  }
10947
10837
  }
10948
10838
  }
10949
- var geoLocationsSchema = z10.object({
10950
- countries: z10.array(z10.string().length(2)).optional(),
10951
- regions: z10.array(z10.object({ key: z10.string() })).optional(),
10952
- cities: z10.array(z10.object({ key: z10.string(), radius: z10.number().optional(), distance_unit: z10.string().optional() })).optional(),
10953
- zips: z10.array(z10.object({ key: z10.string() })).optional(),
10954
- location_types: z10.array(z10.string()).optional()
10955
- }).catchall(z10.unknown());
10956
- var idNameSchema = z10.object({ id: z10.string(), name: z10.string().optional() });
10957
- var metaTargetingSchema = z10.object({
10839
+ var geoLocationsSchema = z9.object({
10840
+ countries: z9.array(z9.string().length(2)).optional(),
10841
+ regions: z9.array(z9.object({ key: z9.string() })).optional(),
10842
+ cities: z9.array(z9.object({ key: z9.string(), radius: z9.number().optional(), distance_unit: z9.string().optional() })).optional(),
10843
+ zips: z9.array(z9.object({ key: z9.string() })).optional(),
10844
+ location_types: z9.array(z9.string()).optional()
10845
+ }).catchall(z9.unknown());
10846
+ var idNameSchema = z9.object({ id: z9.string(), name: z9.string().optional() });
10847
+ var metaTargetingSchema = z9.object({
10958
10848
  geo_locations: geoLocationsSchema.optional(),
10959
10849
  excluded_geo_locations: geoLocationsSchema.optional(),
10960
- age_min: z10.number().int().min(13).max(65).optional(),
10961
- age_max: z10.number().int().min(13).max(65).optional(),
10962
- genders: z10.array(z10.union([z10.literal(1), z10.literal(2)])).optional(),
10963
- locales: z10.array(z10.number().int()).optional(),
10964
- interests: z10.array(idNameSchema).optional(),
10965
- behaviors: z10.array(idNameSchema).optional(),
10966
- custom_audiences: z10.array(z10.object({ id: parentRefSchema2 })).optional(),
10967
- excluded_custom_audiences: z10.array(z10.object({ id: parentRefSchema2 })).optional(),
10968
- flexible_spec: z10.array(z10.record(z10.string(), z10.unknown())).optional(),
10969
- exclusions: z10.record(z10.string(), z10.unknown()).optional(),
10970
- publisher_platforms: z10.array(z10.string()).optional(),
10971
- facebook_positions: z10.array(z10.string()).optional(),
10972
- instagram_positions: z10.array(z10.string()).optional(),
10973
- audience_network_positions: z10.array(z10.string()).optional(),
10974
- messenger_positions: z10.array(z10.string()).optional(),
10975
- device_platforms: z10.array(z10.string()).optional(),
10976
- targeting_automation: z10.object({ advantage_audience: z10.union([z10.literal(0), z10.literal(1)]) }).partial().optional()
10977
- }).catchall(z10.unknown());
10978
- var specialAdCategoriesSchema = z10.array(z10.enum(SPECIAL_AD_CATEGORIES)).default(["NONE"]);
10979
- var campaignCreateSchema3 = z10.object({
10980
- name: z10.string().min(1).max(META_LIMITS.campaign.nameMax),
10981
- objective: z10.enum(OBJECTIVES),
10850
+ age_min: z9.number().int().min(13).max(65).optional(),
10851
+ age_max: z9.number().int().min(13).max(65).optional(),
10852
+ genders: z9.array(z9.union([z9.literal(1), z9.literal(2)])).optional(),
10853
+ locales: z9.array(z9.number().int()).optional(),
10854
+ interests: z9.array(idNameSchema).optional(),
10855
+ behaviors: z9.array(idNameSchema).optional(),
10856
+ custom_audiences: z9.array(z9.object({ id: parentRefSchema2 })).optional(),
10857
+ excluded_custom_audiences: z9.array(z9.object({ id: parentRefSchema2 })).optional(),
10858
+ flexible_spec: z9.array(z9.record(z9.string(), z9.unknown())).optional(),
10859
+ exclusions: z9.record(z9.string(), z9.unknown()).optional(),
10860
+ publisher_platforms: z9.array(z9.string()).optional(),
10861
+ facebook_positions: z9.array(z9.string()).optional(),
10862
+ instagram_positions: z9.array(z9.string()).optional(),
10863
+ audience_network_positions: z9.array(z9.string()).optional(),
10864
+ messenger_positions: z9.array(z9.string()).optional(),
10865
+ device_platforms: z9.array(z9.string()).optional(),
10866
+ targeting_automation: z9.object({ advantage_audience: z9.union([z9.literal(0), z9.literal(1)]) }).partial().optional()
10867
+ }).catchall(z9.unknown());
10868
+ var specialAdCategoriesSchema = z9.array(z9.enum(SPECIAL_AD_CATEGORIES)).default(["NONE"]);
10869
+ var campaignCreateSchema3 = z9.object({
10870
+ name: z9.string().min(1).max(META_LIMITS.campaign.nameMax),
10871
+ objective: z9.enum(OBJECTIVES),
10982
10872
  status: stageableStatusSchema3.default("PAUSED"),
10983
10873
  special_ad_categories: specialAdCategoriesSchema,
10984
- special_ad_category_country: z10.array(z10.string().length(2)).optional(),
10985
- buying_type: z10.enum(BUYING_TYPES).default("AUCTION"),
10986
- bid_strategy: z10.enum(BID_STRATEGIES).optional(),
10874
+ special_ad_category_country: z9.array(z9.string().length(2)).optional(),
10875
+ buying_type: z9.enum(BUYING_TYPES).default("AUCTION"),
10876
+ bid_strategy: z9.enum(BID_STRATEGIES).optional(),
10987
10877
  /** Campaign Budget Optimization (Advantage campaign budget) — mutually exclusive with ad-set budgets. */
10988
10878
  dailyBudget: moneySchema2.optional(),
10989
10879
  lifetimeBudget: moneySchema2.optional(),
10990
10880
  spendCap: moneySchema2.optional(),
10991
- start_time: z10.number().int().positive().optional(),
10992
- stop_time: z10.number().int().positive().optional()
10881
+ start_time: z9.number().int().positive().optional(),
10882
+ stop_time: z9.number().int().positive().optional()
10993
10883
  }).superRefine((p, ctx) => {
10994
10884
  if (p.dailyBudget && p.lifetimeBudget) {
10995
10885
  ctx.addIssue({ code: "custom", path: ["dailyBudget"], message: "set only one of dailyBudget or lifetimeBudget" });
@@ -10999,15 +10889,15 @@ var campaignCreateSchema3 = z10.object({
10999
10889
  ctx.addIssue({ code: "custom", path: ["stop_time"], message: "stop_time must be after start_time" });
11000
10890
  }
11001
10891
  });
11002
- var campaignUpdateSchema3 = z10.object({
11003
- name: z10.string().min(1).max(META_LIMITS.campaign.nameMax).optional(),
10892
+ var campaignUpdateSchema3 = z9.object({
10893
+ name: z9.string().min(1).max(META_LIMITS.campaign.nameMax).optional(),
11004
10894
  status: updateStatusSchema.optional(),
11005
- bid_strategy: z10.enum(BID_STRATEGIES).optional(),
10895
+ bid_strategy: z9.enum(BID_STRATEGIES).optional(),
11006
10896
  dailyBudget: moneySchema2.optional(),
11007
10897
  lifetimeBudget: moneySchema2.optional(),
11008
10898
  spendCap: moneySchema2.optional(),
11009
- start_time: z10.number().int().positive().optional(),
11010
- stop_time: z10.number().int().positive().optional()
10899
+ start_time: z9.number().int().positive().optional(),
10900
+ stop_time: z9.number().int().positive().optional()
11011
10901
  }).superRefine((p, ctx) => {
11012
10902
  if (!Object.values(p).some((val) => val !== void 0)) {
11013
10903
  ctx.addIssue({ code: "custom", message: "update needs at least one field" });
@@ -11017,38 +10907,38 @@ var campaignUpdateSchema3 = z10.object({
11017
10907
  }
11018
10908
  validateDailyBudgetFloor(p.dailyBudget, ctx, ["dailyBudget", "amount"]);
11019
10909
  });
11020
- var promotedObjectSchema = z10.object({
10910
+ var promotedObjectSchema = z9.object({
11021
10911
  page_id: parentRefSchema2.optional(),
11022
- pixel_id: z10.string().regex(NUMERIC_ID_REGEX3).optional(),
11023
- custom_event_type: z10.enum(CUSTOM_EVENT_TYPES).optional(),
11024
- application_id: z10.string().regex(NUMERIC_ID_REGEX3).optional(),
11025
- object_store_url: z10.string().url().optional(),
11026
- product_catalog_id: z10.string().regex(NUMERIC_ID_REGEX3).optional(),
11027
- product_set_id: z10.string().regex(NUMERIC_ID_REGEX3).optional(),
11028
- whatsapp_phone_number: z10.string().optional(),
11029
- offline_conversion_data_set_id: z10.string().regex(NUMERIC_ID_REGEX3).optional()
10912
+ pixel_id: z9.string().regex(NUMERIC_ID_REGEX3).optional(),
10913
+ custom_event_type: z9.enum(CUSTOM_EVENT_TYPES).optional(),
10914
+ application_id: z9.string().regex(NUMERIC_ID_REGEX3).optional(),
10915
+ object_store_url: z9.string().url().optional(),
10916
+ product_catalog_id: z9.string().regex(NUMERIC_ID_REGEX3).optional(),
10917
+ product_set_id: z9.string().regex(NUMERIC_ID_REGEX3).optional(),
10918
+ whatsapp_phone_number: z9.string().optional(),
10919
+ offline_conversion_data_set_id: z9.string().regex(NUMERIC_ID_REGEX3).optional()
11030
10920
  }).partial();
11031
- var attributionSpecSchema = z10.array(
11032
- z10.object({
11033
- event_type: z10.enum(ATTRIBUTION_EVENT_TYPES),
11034
- window_days: z10.union([z10.literal(1), z10.literal(7), z10.literal(28)])
10921
+ var attributionSpecSchema = z9.array(
10922
+ z9.object({
10923
+ event_type: z9.enum(ATTRIBUTION_EVENT_TYPES),
10924
+ window_days: z9.union([z9.literal(1), z9.literal(7), z9.literal(28)])
11035
10925
  })
11036
10926
  );
11037
10927
  var adSetFields = {
11038
- name: z10.string().min(1).max(META_LIMITS.adSet.nameMax),
10928
+ name: z9.string().min(1).max(META_LIMITS.adSet.nameMax),
11039
10929
  campaign_id: parentRefSchema2,
11040
10930
  status: stageableStatusSchema3.default("PAUSED"),
11041
10931
  dailyBudget: moneySchema2.optional(),
11042
10932
  lifetimeBudget: moneySchema2.optional(),
11043
10933
  bidAmount: moneySchema2.optional(),
11044
- bid_strategy: z10.enum(BID_STRATEGIES).optional(),
11045
- billing_event: z10.enum(BILLING_EVENTS),
11046
- optimization_goal: z10.enum(OPTIMIZATION_GOALS),
11047
- destination_type: z10.enum(DESTINATION_TYPES).optional(),
10934
+ bid_strategy: z9.enum(BID_STRATEGIES).optional(),
10935
+ billing_event: z9.enum(BILLING_EVENTS),
10936
+ optimization_goal: z9.enum(OPTIMIZATION_GOALS),
10937
+ destination_type: z9.enum(DESTINATION_TYPES).optional(),
11048
10938
  promoted_object: promotedObjectSchema.optional(),
11049
10939
  attribution_spec: attributionSpecSchema.optional(),
11050
- start_time: z10.number().int().positive().optional(),
11051
- end_time: z10.number().int().positive().optional(),
10940
+ start_time: z9.number().int().positive().optional(),
10941
+ end_time: z9.number().int().positive().optional(),
11052
10942
  targeting: metaTargetingSchema
11053
10943
  };
11054
10944
  function validateAdSetBudgetAndBid(p, ctx) {
@@ -11066,22 +10956,22 @@ function validateAdSetBudgetAndBid(p, ctx) {
11066
10956
  ctx.addIssue({ code: "custom", path: ["end_time"], message: "end_time must be after start_time" });
11067
10957
  }
11068
10958
  }
11069
- var adSetCreateSchema = z10.object(adSetFields).superRefine((p, ctx) => {
10959
+ var adSetCreateSchema = z9.object(adSetFields).superRefine((p, ctx) => {
11070
10960
  validateAdSetBudgetAndBid(p, ctx);
11071
10961
  });
11072
- var adSetUpdateSchema = z10.object({
10962
+ var adSetUpdateSchema = z9.object({
11073
10963
  name: adSetFields.name.optional(),
11074
10964
  status: updateStatusSchema.optional(),
11075
10965
  dailyBudget: moneySchema2.optional(),
11076
10966
  lifetimeBudget: moneySchema2.optional(),
11077
10967
  bidAmount: moneySchema2.optional(),
11078
- bid_strategy: z10.enum(BID_STRATEGIES).optional(),
11079
- optimization_goal: z10.enum(OPTIMIZATION_GOALS).optional(),
11080
- destination_type: z10.enum(DESTINATION_TYPES).optional(),
10968
+ bid_strategy: z9.enum(BID_STRATEGIES).optional(),
10969
+ optimization_goal: z9.enum(OPTIMIZATION_GOALS).optional(),
10970
+ destination_type: z9.enum(DESTINATION_TYPES).optional(),
11081
10971
  promoted_object: promotedObjectSchema.optional(),
11082
10972
  attribution_spec: attributionSpecSchema.optional(),
11083
- start_time: z10.number().int().positive().optional(),
11084
- end_time: z10.number().int().positive().optional(),
10973
+ start_time: z9.number().int().positive().optional(),
10974
+ end_time: z9.number().int().positive().optional(),
11085
10975
  targeting: metaTargetingSchema.optional()
11086
10976
  }).superRefine((p, ctx) => {
11087
10977
  if (!Object.values(p).some((val) => val !== void 0)) {
@@ -11089,38 +10979,38 @@ var adSetUpdateSchema = z10.object({
11089
10979
  }
11090
10980
  validateAdSetBudgetAndBid(p, ctx);
11091
10981
  });
11092
- var messageSchema = z10.string().min(1).max(META_LIMITS.creative.messageHardMax);
11093
- var headlineSchema2 = z10.string().min(1).max(META_LIMITS.creative.headlineMax);
11094
- var descriptionSchema = z10.string().min(1).max(META_LIMITS.creative.descriptionMax);
11095
- var callToActionSchema = z10.object({
11096
- type: z10.enum(CTA_TYPES2),
10982
+ var messageSchema = z9.string().min(1).max(META_LIMITS.creative.messageHardMax);
10983
+ var headlineSchema2 = z9.string().min(1).max(META_LIMITS.creative.headlineMax);
10984
+ var descriptionSchema = z9.string().min(1).max(META_LIMITS.creative.descriptionMax);
10985
+ var callToActionSchema = z9.object({
10986
+ type: z9.enum(CTA_TYPES2),
11097
10987
  /** Overrides the base link for the CTA button; defaults to the ad's link. */
11098
10988
  link: httpsUrlSchema3.optional()
11099
10989
  });
11100
- var creativeEnhancementsSchema = z10.object({
11101
- standardEnhancements: z10.enum(ENROLL_STATUSES).optional(),
11102
- features: z10.record(z10.string(), z10.enum(ENROLL_STATUSES)).optional()
10990
+ var creativeEnhancementsSchema = z9.object({
10991
+ standardEnhancements: z9.enum(ENROLL_STATUSES).optional(),
10992
+ features: z9.record(z9.string(), z9.enum(ENROLL_STATUSES)).optional()
11103
10993
  });
11104
10994
  var creativeSharedFields = {
11105
- name: z10.string().max(META_LIMITS.creative.nameMax).optional(),
10995
+ name: z9.string().max(META_LIMITS.creative.nameMax).optional(),
11106
10996
  /** Facebook Page id backing the ad's identity. */
11107
10997
  page_id: parentRefSchema2,
11108
10998
  /** Instagram account id for IG placements (aka instagram_actor_id on read). */
11109
- instagram_user_id: z10.string().regex(NUMERIC_ID_REGEX3).optional(),
10999
+ instagram_user_id: z9.string().regex(NUMERIC_ID_REGEX3).optional(),
11110
11000
  /** URL tracking parameters appended to the destination, e.g. "utm_source=fb&utm_campaign=x". */
11111
- url_tags: z10.string().max(1e3).optional(),
11001
+ url_tags: z9.string().max(1e3).optional(),
11112
11002
  enhancements: creativeEnhancementsSchema.optional()
11113
11003
  };
11114
11004
  var imageMediaFields = {
11115
- imageHash: z10.string().regex(IMAGE_HASH_REGEX).optional(),
11005
+ imageHash: z9.string().regex(IMAGE_HASH_REGEX).optional(),
11116
11006
  imageRef: tempRefSchema3.optional()
11117
11007
  };
11118
11008
  var videoMediaFields = {
11119
- videoId: z10.string().regex(NUMERIC_ID_REGEX3).optional(),
11009
+ videoId: z9.string().regex(NUMERIC_ID_REGEX3).optional(),
11120
11010
  videoRef: tempRefSchema3.optional(),
11121
11011
  /** Thumbnail for a video creative — image hash, ref, or public url. */
11122
- thumbnailHash: z10.string().regex(IMAGE_HASH_REGEX).optional(),
11123
- imageUrl: z10.string().url().optional()
11012
+ thumbnailHash: z9.string().regex(IMAGE_HASH_REGEX).optional(),
11013
+ imageUrl: z9.string().url().optional()
11124
11014
  };
11125
11015
  function countImageRefs(p) {
11126
11016
  return [p.imageHash, p.imageRef].filter(Boolean).length;
@@ -11128,8 +11018,8 @@ function countImageRefs(p) {
11128
11018
  function countVideoRefs(p) {
11129
11019
  return [p.videoId, p.videoRef].filter(Boolean).length;
11130
11020
  }
11131
- var singleCreativeSchema = z10.object({
11132
- creativeType: z10.literal("single"),
11021
+ var singleCreativeSchema = z9.object({
11022
+ creativeType: z9.literal("single"),
11133
11023
  ...creativeSharedFields,
11134
11024
  /** Primary text. */
11135
11025
  message: messageSchema,
@@ -11138,7 +11028,7 @@ var singleCreativeSchema = z10.object({
11138
11028
  headline: headlineSchema2.optional(),
11139
11029
  description: descriptionSchema.optional(),
11140
11030
  /** Display URL / caption shown under the headline. */
11141
- caption: z10.string().max(255).optional(),
11031
+ caption: z9.string().max(255).optional(),
11142
11032
  call_to_action: callToActionSchema.optional(),
11143
11033
  ...imageMediaFields,
11144
11034
  ...videoMediaFields
@@ -11162,10 +11052,10 @@ var singleCreativeSchema = z10.object({
11162
11052
  });
11163
11053
  }
11164
11054
  });
11165
- var carouselCardSchema = z10.object({
11055
+ var carouselCardSchema = z9.object({
11166
11056
  link: httpsUrlSchema3,
11167
- headline: z10.string().max(META_LIMITS.creative.headlineMax).optional(),
11168
- description: z10.string().max(META_LIMITS.creative.descriptionMax).optional(),
11057
+ headline: z9.string().max(META_LIMITS.creative.headlineMax).optional(),
11058
+ description: z9.string().max(META_LIMITS.creative.descriptionMax).optional(),
11169
11059
  call_to_action: callToActionSchema.optional(),
11170
11060
  ...imageMediaFields,
11171
11061
  ...videoMediaFields
@@ -11185,35 +11075,35 @@ var carouselCardSchema = z10.object({
11185
11075
  ctx.addIssue({ code: "custom", path: ["videoId"], message: "each card is an image OR a video, not both" });
11186
11076
  }
11187
11077
  });
11188
- var carouselCreativeSchema2 = z10.object({
11189
- creativeType: z10.literal("carousel"),
11078
+ var carouselCreativeSchema2 = z9.object({
11079
+ creativeType: z9.literal("carousel"),
11190
11080
  ...creativeSharedFields,
11191
11081
  message: messageSchema,
11192
11082
  /** Optional "see more" card destination applied when a card has no own link. */
11193
11083
  link: httpsUrlSchema3.optional(),
11194
11084
  call_to_action: callToActionSchema.optional(),
11195
- cards: z10.array(carouselCardSchema).min(META_LIMITS.creative.carouselCardsMin).max(META_LIMITS.creative.carouselCardsMax)
11085
+ cards: z9.array(carouselCardSchema).min(META_LIMITS.creative.carouselCardsMin).max(META_LIMITS.creative.carouselCardsMax)
11196
11086
  });
11197
- var dynamicImageSchema = z10.object({ ...imageMediaFields }).refine((p) => countImageRefs(p) === 1, "each dynamic image needs exactly one reference");
11198
- var dynamicVideoSchema = z10.object({
11087
+ var dynamicImageSchema = z9.object({ ...imageMediaFields }).refine((p) => countImageRefs(p) === 1, "each dynamic image needs exactly one reference");
11088
+ var dynamicVideoSchema = z9.object({
11199
11089
  videoId: videoMediaFields.videoId,
11200
11090
  videoRef: videoMediaFields.videoRef,
11201
11091
  thumbnailHash: videoMediaFields.thumbnailHash
11202
11092
  }).refine((p) => countVideoRefs(p) === 1, "each dynamic video needs exactly one reference");
11203
11093
  var DYN = META_LIMITS.creative;
11204
- var dynamicCreativeSchema = z10.object({
11205
- creativeType: z10.literal("dynamic"),
11094
+ var dynamicCreativeSchema = z9.object({
11095
+ creativeType: z9.literal("dynamic"),
11206
11096
  ...creativeSharedFields,
11207
- bodies: z10.array(z10.object({ text: messageSchema })).min(DYN.dynamicTextsMin).max(DYN.dynamicTextsMax),
11208
- titles: z10.array(z10.object({ text: headlineSchema2 })).min(DYN.dynamicTextsMin).max(DYN.dynamicTextsMax),
11209
- descriptions: z10.array(z10.object({ text: descriptionSchema })).max(DYN.dynamicTextsMax).optional(),
11210
- images: z10.array(dynamicImageSchema).optional(),
11211
- videos: z10.array(dynamicVideoSchema).optional(),
11212
- ad_formats: z10.array(z10.enum(AD_FORMATS2)).min(1),
11213
- call_to_action_types: z10.array(z10.enum(CTA_TYPES2)).optional(),
11214
- link_urls: z10.array(z10.object({ website_url: httpsUrlSchema3, display_url: z10.string().optional() })).min(1),
11097
+ bodies: z9.array(z9.object({ text: messageSchema })).min(DYN.dynamicTextsMin).max(DYN.dynamicTextsMax),
11098
+ titles: z9.array(z9.object({ text: headlineSchema2 })).min(DYN.dynamicTextsMin).max(DYN.dynamicTextsMax),
11099
+ descriptions: z9.array(z9.object({ text: descriptionSchema })).max(DYN.dynamicTextsMax).optional(),
11100
+ images: z9.array(dynamicImageSchema).optional(),
11101
+ videos: z9.array(dynamicVideoSchema).optional(),
11102
+ ad_formats: z9.array(z9.enum(AD_FORMATS2)).min(1),
11103
+ call_to_action_types: z9.array(z9.enum(CTA_TYPES2)).optional(),
11104
+ link_urls: z9.array(z9.object({ website_url: httpsUrlSchema3, display_url: z9.string().optional() })).min(1),
11215
11105
  /** Multi-language / placement customization — structural passthrough for v1. */
11216
- asset_customization_rules: z10.array(z10.record(z10.string(), z10.unknown())).optional()
11106
+ asset_customization_rules: z9.array(z9.record(z9.string(), z9.unknown())).optional()
11217
11107
  }).superRefine((p, ctx) => {
11218
11108
  if (!(p.images?.length || p.videos?.length)) {
11219
11109
  ctx.addIssue({
@@ -11223,57 +11113,57 @@ var dynamicCreativeSchema = z10.object({
11223
11113
  });
11224
11114
  }
11225
11115
  });
11226
- var existingPostCreativeSchema = z10.object({
11227
- creativeType: z10.literal("existing_post"),
11116
+ var existingPostCreativeSchema = z9.object({
11117
+ creativeType: z9.literal("existing_post"),
11228
11118
  name: creativeSharedFields.name,
11229
11119
  /** "<page_id>_<post_id>" object story id of the post to promote. */
11230
- object_story_id: z10.string().regex(/^\d+_\d+$/, 'expected "<page_id>_<post_id>"'),
11120
+ object_story_id: z9.string().regex(/^\d+_\d+$/, 'expected "<page_id>_<post_id>"'),
11231
11121
  instagram_user_id: creativeSharedFields.instagram_user_id,
11232
11122
  url_tags: creativeSharedFields.url_tags,
11233
11123
  enhancements: creativeSharedFields.enhancements
11234
11124
  });
11235
- var creativeContentSchema2 = z10.discriminatedUnion("creativeType", [
11125
+ var creativeContentSchema2 = z9.discriminatedUnion("creativeType", [
11236
11126
  singleCreativeSchema,
11237
11127
  carouselCreativeSchema2,
11238
11128
  dynamicCreativeSchema,
11239
11129
  existingPostCreativeSchema
11240
11130
  ]);
11241
11131
  var adCreativeCreateSchema = creativeContentSchema2;
11242
- var adCreativeUpdateSchema = z10.object({
11243
- name: z10.string().max(META_LIMITS.creative.nameMax).optional(),
11132
+ var adCreativeUpdateSchema = z9.object({
11133
+ name: z9.string().max(META_LIMITS.creative.nameMax).optional(),
11244
11134
  status: updateStatusSchema.optional(),
11245
11135
  /** Content patch — only honored when the target is a staged meta_temp_* creative. */
11246
- content: z10.record(z10.string(), z10.unknown()).optional()
11136
+ content: z9.record(z9.string(), z9.unknown()).optional()
11247
11137
  }).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
11248
- var adCreateSchema2 = z10.object({
11249
- name: z10.string().min(1).max(META_LIMITS.ad.nameMax),
11138
+ var adCreateSchema2 = z9.object({
11139
+ name: z9.string().min(1).max(META_LIMITS.ad.nameMax),
11250
11140
  adset_id: parentRefSchema2,
11251
11141
  status: stageableStatusSchema3.default("PAUSED"),
11252
- creative: z10.object({ creative_id: parentRefSchema2 }),
11142
+ creative: z9.object({ creative_id: parentRefSchema2 }),
11253
11143
  /** Conversion pixel / offline event set / view tags — structural passthrough. */
11254
- tracking_specs: z10.array(z10.record(z10.string(), z10.unknown())).optional()
11144
+ tracking_specs: z9.array(z9.record(z9.string(), z9.unknown())).optional()
11255
11145
  });
11256
- var adUpdateSchema2 = z10.object({
11257
- name: z10.string().min(1).max(META_LIMITS.ad.nameMax).optional(),
11146
+ var adUpdateSchema2 = z9.object({
11147
+ name: z9.string().min(1).max(META_LIMITS.ad.nameMax).optional(),
11258
11148
  status: updateStatusSchema.optional(),
11259
11149
  /** Swapping the creative is the Meta way to "edit" an ad's creative. */
11260
- creative: z10.object({ creative_id: parentRefSchema2 }).optional(),
11261
- tracking_specs: z10.array(z10.record(z10.string(), z10.unknown())).optional()
11150
+ creative: z9.object({ creative_id: parentRefSchema2 }).optional(),
11151
+ tracking_specs: z9.array(z9.record(z9.string(), z9.unknown())).optional()
11262
11152
  }).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
11263
- var lookalikeSpecSchema = z10.object({
11264
- origin: z10.array(z10.object({ id: parentRefSchema2 })).min(1),
11265
- ratio: z10.number().min(0.01).max(0.2).optional(),
11266
- country: z10.string().length(2).optional()
11267
- });
11268
- var customAudienceCreateSchema = z10.object({
11269
- name: z10.string().min(1).max(META_LIMITS.audience.nameMax),
11270
- subtype: z10.enum(CUSTOM_AUDIENCE_SUBTYPES),
11271
- description: z10.string().max(500).optional(),
11272
- customer_file_source: z10.string().optional(),
11273
- retention_days: z10.number().int().min(1).max(META_LIMITS.audience.retentionDaysMax).optional(),
11153
+ var lookalikeSpecSchema = z9.object({
11154
+ origin: z9.array(z9.object({ id: parentRefSchema2 })).min(1),
11155
+ ratio: z9.number().min(0.01).max(0.2).optional(),
11156
+ country: z9.string().length(2).optional()
11157
+ });
11158
+ var customAudienceCreateSchema = z9.object({
11159
+ name: z9.string().min(1).max(META_LIMITS.audience.nameMax),
11160
+ subtype: z9.enum(CUSTOM_AUDIENCE_SUBTYPES),
11161
+ description: z9.string().max(500).optional(),
11162
+ customer_file_source: z9.string().optional(),
11163
+ retention_days: z9.number().int().min(1).max(META_LIMITS.audience.retentionDaysMax).optional(),
11274
11164
  lookalike_spec: lookalikeSpecSchema.optional(),
11275
11165
  /** Website/engagement rule — structural passthrough validated by Meta. */
11276
- rule: z10.record(z10.string(), z10.unknown()).optional()
11166
+ rule: z9.record(z9.string(), z9.unknown()).optional()
11277
11167
  }).superRefine((p, ctx) => {
11278
11168
  if (p.subtype === "LOOKALIKE" && !p.lookalike_spec) {
11279
11169
  ctx.addIssue({ code: "custom", path: ["lookalike_spec"], message: "LOOKALIKE audiences need a lookalike_spec" });
@@ -11282,16 +11172,16 @@ var customAudienceCreateSchema = z10.object({
11282
11172
  ctx.addIssue({ code: "custom", path: ["rule"], message: `${p.subtype} audiences need a rule (use --file)` });
11283
11173
  }
11284
11174
  });
11285
- var customAudienceUpdateSchema = z10.object({
11286
- name: z10.string().min(1).max(META_LIMITS.audience.nameMax).optional(),
11287
- description: z10.string().max(500).optional()
11175
+ var customAudienceUpdateSchema = z9.object({
11176
+ name: z9.string().min(1).max(META_LIMITS.audience.nameMax).optional(),
11177
+ description: z9.string().max(500).optional()
11288
11178
  }).refine((p) => Object.values(p).some((val) => val !== void 0), "update needs at least one field");
11289
- var mediaUploadSchema = z10.object({
11290
- kind: z10.enum(MEDIA_KINDS),
11179
+ var mediaUploadSchema = z9.object({
11180
+ kind: z9.enum(MEDIA_KINDS),
11291
11181
  bakerImageId: bakerMediaIdSchema2.optional(),
11292
11182
  bakerVideoId: bakerMediaIdSchema2.optional(),
11293
11183
  /** Optional display name / filename hint. */
11294
- name: z10.string().max(255).optional()
11184
+ name: z9.string().max(255).optional()
11295
11185
  }).superRefine((p, ctx) => {
11296
11186
  if (p.kind === "image" && !p.bakerImageId) {
11297
11187
  ctx.addIssue({ code: "custom", path: ["bakerImageId"], message: "image uploads need a bakerImageId" });
@@ -11313,16 +11203,16 @@ var META_DRAFT_OP_KINDS = [
11313
11203
  "customAudience.update",
11314
11204
  "media.upload"
11315
11205
  ];
11316
- var metaDraftOpKindSchema = z10.enum(META_DRAFT_OP_KINDS);
11317
- var accountIdSchema2 = z10.string().regex(NUMERIC_ID_REGEX3, "accountId must be the bare numeric ad account id");
11318
- var updateTargetSchema2 = z10.union([z10.string().regex(NUMERIC_ID_REGEX3), tempRefSchema3]);
11206
+ var metaDraftOpKindSchema = z9.enum(META_DRAFT_OP_KINDS);
11207
+ var accountIdSchema2 = z9.string().regex(NUMERIC_ID_REGEX3, "accountId must be the bare numeric ad account id");
11208
+ var updateTargetSchema2 = z9.union([z9.string().regex(NUMERIC_ID_REGEX3), tempRefSchema3]);
11319
11209
  function createOp3(kind, payload) {
11320
- return z10.object({ kind: z10.literal(kind), accountId: accountIdSchema2, payload });
11210
+ return z9.object({ kind: z9.literal(kind), accountId: accountIdSchema2, payload });
11321
11211
  }
11322
11212
  function updateOp3(kind, payload) {
11323
- return z10.object({ kind: z10.literal(kind), accountId: accountIdSchema2, target: updateTargetSchema2, payload });
11213
+ return z9.object({ kind: z9.literal(kind), accountId: accountIdSchema2, target: updateTargetSchema2, payload });
11324
11214
  }
11325
- var metaDraftOpInputSchema = z10.discriminatedUnion("kind", [
11215
+ var metaDraftOpInputSchema = z9.discriminatedUnion("kind", [
11326
11216
  createOp3("campaign.create", campaignCreateSchema3),
11327
11217
  updateOp3("campaign.update", campaignUpdateSchema3),
11328
11218
  createOp3("adSet.create", adSetCreateSchema),
@@ -11337,89 +11227,89 @@ var metaDraftOpInputSchema = z10.discriminatedUnion("kind", [
11337
11227
  ]);
11338
11228
 
11339
11229
  // ../api/src/ads-meta/wire.ts
11340
- import { z as z11 } from "zod";
11341
- var metaWriteModeSchema = z11.enum(["live", "simulated"]);
11342
- var metaDraftOpResultSchema = z11.object({
11343
- status: z11.enum(["applied", "simulated", "failed", "skipped"]),
11230
+ import { z as z10 } from "zod";
11231
+ var metaWriteModeSchema = z10.enum(["live", "simulated"]);
11232
+ var metaDraftOpResultSchema = z10.object({
11233
+ status: z10.enum(["applied", "simulated", "failed", "skipped"]),
11344
11234
  /** The resulting Meta node id (campaign/adset/creative/ad/audience) or simulated id. */
11345
- id: z11.string().optional(),
11235
+ id: z10.string().optional(),
11346
11236
  /** For media.upload ops: the resulting image hash. */
11347
- hash: z11.string().optional(),
11348
- error: z11.string().optional(),
11349
- skippedBecause: z11.string().optional(),
11350
- executedAt: z11.number().optional()
11237
+ hash: z10.string().optional(),
11238
+ error: z10.string().optional(),
11239
+ skippedBecause: z10.string().optional(),
11240
+ executedAt: z10.number().optional()
11351
11241
  });
11352
- var metaDraftStageRequestSchema = z11.object({
11353
- chatId: z11.string(),
11242
+ var metaDraftStageRequestSchema = z10.object({
11243
+ chatId: z10.string(),
11354
11244
  op: metaDraftOpInputSchema
11355
11245
  });
11356
- var metaDraftStageResponseSchema = z11.object({
11357
- staged: z11.literal(true),
11358
- ref: z11.string(),
11246
+ var metaDraftStageResponseSchema = z10.object({
11247
+ staged: z10.literal(true),
11248
+ ref: z10.string(),
11359
11249
  kind: metaDraftOpKindSchema,
11360
11250
  mode: metaWriteModeSchema,
11361
- dependsOn: z11.array(z11.string()),
11362
- summary: z11.string(),
11363
- warnings: z11.array(z11.string()),
11251
+ dependsOn: z10.array(z10.string()),
11252
+ summary: z10.string(),
11253
+ warnings: z10.array(z10.string()),
11364
11254
  /** True when the op amended an already-staged op in place instead of appending a new one. */
11365
- amended: z11.boolean().optional()
11366
- });
11367
- var metaDraftDuplicateRequestSchema = z11.object({
11368
- chatId: z11.string(),
11369
- accountId: z11.string(),
11370
- entity: z11.enum(["campaign", "adSet", "ad"]),
11371
- sourceId: z11.string(),
11372
- overrides: z11.record(z11.string(), z11.unknown()).optional(),
11255
+ amended: z10.boolean().optional()
11256
+ });
11257
+ var metaDraftDuplicateRequestSchema = z10.object({
11258
+ chatId: z10.string(),
11259
+ accountId: z10.string(),
11260
+ entity: z10.enum(["campaign", "adSet", "ad"]),
11261
+ sourceId: z10.string(),
11262
+ overrides: z10.record(z10.string(), z10.unknown()).optional(),
11373
11263
  /** Pause the original after the copy publishes. */
11374
- replace: z11.boolean().optional()
11264
+ replace: z10.boolean().optional()
11375
11265
  });
11376
- var metaDraftOpViewSchema = z11.object({
11377
- ref: z11.string(),
11266
+ var metaDraftOpViewSchema = z10.object({
11267
+ ref: z10.string(),
11378
11268
  kind: metaDraftOpKindSchema,
11379
- accountId: z11.string(),
11380
- target: z11.string().optional(),
11381
- dependsOn: z11.array(z11.string()),
11382
- summary: z11.string(),
11383
- stagedAt: z11.number(),
11269
+ accountId: z10.string(),
11270
+ target: z10.string().optional(),
11271
+ dependsOn: z10.array(z10.string()),
11272
+ summary: z10.string(),
11273
+ stagedAt: z10.number(),
11384
11274
  result: metaDraftOpResultSchema.optional()
11385
11275
  });
11386
- var metaDraftListRequestSchema = z11.object({
11387
- chatId: z11.string()
11276
+ var metaDraftListRequestSchema = z10.object({
11277
+ chatId: z10.string()
11388
11278
  });
11389
- var metaDraftAdvisorySchema = z11.object({
11390
- ref: z11.string(),
11391
- message: z11.string()
11279
+ var metaDraftAdvisorySchema = z10.object({
11280
+ ref: z10.string(),
11281
+ message: z10.string()
11392
11282
  });
11393
- var metaDraftListResponseSchema = z11.object({
11394
- status: z11.enum(["active", "publishing", "applied", "discarded", "none"]),
11283
+ var metaDraftListResponseSchema = z10.object({
11284
+ status: z10.enum(["active", "publishing", "applied", "discarded", "none"]),
11395
11285
  mode: metaWriteModeSchema,
11396
- count: z11.number(),
11397
- ops: z11.array(metaDraftOpViewSchema),
11286
+ count: z10.number(),
11287
+ ops: z10.array(metaDraftOpViewSchema),
11398
11288
  /** Non-blocking cross-op quality advisories — "good campaign, not just valid". */
11399
- advisories: z11.array(metaDraftAdvisorySchema)
11289
+ advisories: z10.array(metaDraftAdvisorySchema)
11400
11290
  });
11401
- var metaDraftRemoveRequestSchema = z11.object({
11402
- chatId: z11.string(),
11403
- ref: z11.string()
11291
+ var metaDraftRemoveRequestSchema = z10.object({
11292
+ chatId: z10.string(),
11293
+ ref: z10.string()
11404
11294
  });
11405
- var metaDraftRemoveResponseSchema = z11.object({
11295
+ var metaDraftRemoveResponseSchema = z10.object({
11406
11296
  /** The requested ref plus any dependents removed by cascade. */
11407
- removed: z11.array(z11.string())
11297
+ removed: z10.array(z10.string())
11408
11298
  });
11409
- var metaDraftClearRequestSchema = z11.object({
11410
- chatId: z11.string()
11299
+ var metaDraftClearRequestSchema = z10.object({
11300
+ chatId: z10.string()
11411
11301
  });
11412
- var metaDraftClearResponseSchema = z11.object({
11413
- cleared: z11.number()
11302
+ var metaDraftClearResponseSchema = z10.object({
11303
+ cleared: z10.number()
11414
11304
  });
11415
- var metaFieldErrorSchema = z11.object({
11416
- path: z11.string(),
11417
- message: z11.string()
11305
+ var metaFieldErrorSchema = z10.object({
11306
+ path: z10.string(),
11307
+ message: z10.string()
11418
11308
  });
11419
- var metaDraftErrorResponseSchema = z11.object({
11420
- code: z11.string(),
11421
- error: z11.string(),
11422
- fields: z11.array(metaFieldErrorSchema).optional()
11309
+ var metaDraftErrorResponseSchema = z10.object({
11310
+ code: z10.string(),
11311
+ error: z10.string(),
11312
+ fields: z10.array(metaFieldErrorSchema).optional()
11423
11313
  });
11424
11314
 
11425
11315
  // src/commands/ads/meta/write-shared.ts
@@ -11430,19 +11320,19 @@ function failWriteValidation3(message) {
11430
11320
  writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
11431
11321
  process.exit(1);
11432
11322
  }
11433
- function loadJsonFileArg3(path12) {
11434
- if (typeof path12 !== "string" || path12.length === 0) {
11323
+ function loadJsonFileArg3(path14) {
11324
+ if (typeof path14 !== "string" || path14.length === 0) {
11435
11325
  return {};
11436
11326
  }
11437
11327
  try {
11438
- const parsed = JSON.parse(readFileSync8(path12, "utf8"));
11328
+ const parsed = JSON.parse(readFileSync8(path14, "utf8"));
11439
11329
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
11440
- failWriteValidation3(`${path12} must contain a JSON object`);
11330
+ failWriteValidation3(`${path14} must contain a JSON object`);
11441
11331
  }
11442
11332
  return parsed;
11443
11333
  } catch (err) {
11444
11334
  if (err instanceof SyntaxError) {
11445
- failWriteValidation3(`${path12} is not valid JSON: ${err.message}`);
11335
+ failWriteValidation3(`${path14} is not valid JSON: ${err.message}`);
11446
11336
  }
11447
11337
  throw err;
11448
11338
  }
@@ -14505,7 +14395,7 @@ async function probeDuration(filePath) {
14505
14395
 
14506
14396
  // src/commands/canvas/run.ts
14507
14397
  import { readFile as readFile2 } from "fs/promises";
14508
- import path4 from "path";
14398
+ import path5 from "path";
14509
14399
  import { defineCommand as defineCommand88 } from "citty";
14510
14400
 
14511
14401
  // src/commands/canvas/placeholders.ts
@@ -14549,9 +14439,265 @@ function isResolvableRelative(value) {
14549
14439
  return typeof value === "string" && value.length > 0 && !value.includes("[TODO") && !path2.isAbsolute(value);
14550
14440
  }
14551
14441
 
14442
+ // src/commands/canvas/run-record.ts
14443
+ import path3 from "path";
14444
+ var MAX_RUN_NODES = 200;
14445
+ var MAX_OUTPUTS_PER_NODE = 10;
14446
+ var MAX_FINAL_OUTPUTS = 10;
14447
+ var MAX_PARAMS_PREVIEW_LENGTH = 4e3;
14448
+ function paramsPreviewFromParams(params) {
14449
+ if (params === void 0 || params === null) return void 0;
14450
+ const text = humanParamText(params, "prompt") ?? humanParamText(params, "source") ?? compactJson(params);
14451
+ if (!text) return void 0;
14452
+ return text.length > MAX_PARAMS_PREVIEW_LENGTH ? `${text.slice(0, MAX_PARAMS_PREVIEW_LENGTH - 1)}\u2026` : text;
14453
+ }
14454
+ function humanParamText(params, key) {
14455
+ const value = params[key];
14456
+ if (typeof value !== "string") return void 0;
14457
+ const trimmed = value.trim();
14458
+ return trimmed && !trimmed.startsWith("$ref:") ? trimmed : void 0;
14459
+ }
14460
+ function compactJson(params) {
14461
+ try {
14462
+ const json = JSON.stringify(params);
14463
+ return json && json !== "{}" ? json : void 0;
14464
+ } catch {
14465
+ return void 0;
14466
+ }
14467
+ }
14468
+ var MAX_CREATIVE_SLUG_LENGTH = 100;
14469
+ function creativeSlugFromCanvasPath(filePath) {
14470
+ const normalized = filePath.split(path3.sep).join("/");
14471
+ const match = normalized.match(/(?:^|\/)src\/creatives\/([a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\//);
14472
+ const slug = match?.[1] ?? null;
14473
+ return slug && slug.length <= MAX_CREATIVE_SLUG_LENGTH ? slug : null;
14474
+ }
14475
+ var OUTPUT_KINDS = /* @__PURE__ */ new Set(["image", "video", "audio", "json", "text", "font"]);
14476
+ function toRecordOutput(slot, value) {
14477
+ const refs = collectAssetRefLikes(value);
14478
+ const ref = refs.length === 1 ? refs[0] : null;
14479
+ if (!ref || !isPersistedAssetRef(ref)) return null;
14480
+ const kind = typeof ref.kind === "string" && OUTPUT_KINDS.has(ref.kind) ? ref.kind : null;
14481
+ if (!kind) return null;
14482
+ return {
14483
+ slot,
14484
+ kind,
14485
+ sha256: ref.sha256,
14486
+ url: ref.url,
14487
+ mime: ref.mime,
14488
+ width: typeof ref.width === "number" ? ref.width : void 0,
14489
+ height: typeof ref.height === "number" ? ref.height : void 0,
14490
+ durationMs: typeof ref.duration_ms === "number" ? ref.duration_ms : void 0
14491
+ };
14492
+ }
14493
+ function nodeOutputsToRecord(nodeOutputs) {
14494
+ const out = [];
14495
+ for (const [slot, value] of Object.entries(nodeOutputs)) {
14496
+ if (Array.isArray(value)) {
14497
+ value.forEach((item, i) => {
14498
+ const rec = toRecordOutput(`${slot}#${i}`, item);
14499
+ if (rec) out.push(rec);
14500
+ });
14501
+ } else {
14502
+ const rec = toRecordOutput(slot, value);
14503
+ if (rec) out.push(rec);
14504
+ }
14505
+ }
14506
+ return out.slice(0, MAX_OUTPUTS_PER_NODE);
14507
+ }
14508
+ function finalOutputsToRecord(output) {
14509
+ if (Array.isArray(output)) {
14510
+ return output.map((item, i) => toRecordOutput(`final#${i}`, item)).filter((rec2) => rec2 !== null).slice(0, MAX_FINAL_OUTPUTS);
14511
+ }
14512
+ const rec = toRecordOutput("final", output);
14513
+ return rec ? [rec] : [];
14514
+ }
14515
+ function buildRunRecord(result, meta, plan) {
14516
+ const nodes = result.node_runs.slice(0, MAX_RUN_NODES).map((run) => {
14517
+ const planned = plan?.get(run.node_id);
14518
+ return {
14519
+ nodeId: run.node_id,
14520
+ nodeType: run.node_type,
14521
+ cached: run.cached,
14522
+ credits: run.credits,
14523
+ durationMs: run.duration_ms,
14524
+ outputs: nodeOutputsToRecord(result.outputs_by_node[run.node_id] ?? {}),
14525
+ deps: planned?.deps,
14526
+ status: plan ? "completed" : void 0,
14527
+ paramsPreview: planned?.paramsPreview
14528
+ };
14529
+ });
14530
+ const finalOutputs = finalOutputsToRecord(result.output);
14531
+ return {
14532
+ runId: result.run_id,
14533
+ creativeSlug: meta.creativeSlug,
14534
+ canvasPath: meta.canvasPath,
14535
+ canvasSha: meta.canvasSha,
14536
+ chatId: meta.chatId,
14537
+ status: "completed",
14538
+ stats: {
14539
+ totalNodes: result.stats.total_nodes,
14540
+ cachedNodes: result.stats.cached_nodes,
14541
+ totalCredits: result.stats.total_credits,
14542
+ durationMs: result.stats.duration_ms
14543
+ },
14544
+ nodes,
14545
+ finalOutputs: finalOutputs.length > 0 ? finalOutputs : void 0
14546
+ };
14547
+ }
14548
+ function buildFailedRunRecord(runId, errorMessage, meta) {
14549
+ return {
14550
+ runId,
14551
+ creativeSlug: meta.creativeSlug,
14552
+ canvasPath: meta.canvasPath,
14553
+ canvasSha: meta.canvasSha,
14554
+ chatId: meta.chatId,
14555
+ status: "failed",
14556
+ errorMessage: errorMessage.slice(0, 2e3),
14557
+ stats: { totalNodes: 0, cachedNodes: 0, totalCredits: 0, durationMs: 0 },
14558
+ nodes: []
14559
+ };
14560
+ }
14561
+
14562
+ // src/commands/canvas/run-progress.ts
14563
+ var RunProgressTracker = class {
14564
+ runId;
14565
+ meta;
14566
+ startedAt;
14567
+ nodes = /* @__PURE__ */ new Map();
14568
+ planned = false;
14569
+ constructor(runId, meta) {
14570
+ this.runId = runId;
14571
+ this.meta = meta;
14572
+ this.startedAt = Date.now();
14573
+ }
14574
+ apply(event) {
14575
+ if (event.kind === "plan") {
14576
+ for (const node of event.nodes) {
14577
+ this.nodes.set(node.node_id, {
14578
+ nodeId: node.node_id,
14579
+ nodeType: node.node_type,
14580
+ cached: false,
14581
+ credits: 0,
14582
+ durationMs: 0,
14583
+ outputs: [],
14584
+ deps: node.deps,
14585
+ status: "pending",
14586
+ paramsPreview: paramsPreviewFromParams(node.params)
14587
+ });
14588
+ }
14589
+ this.planned = true;
14590
+ return;
14591
+ }
14592
+ if (event.kind === "node_start") {
14593
+ this.patchNode(event.node_id, { status: "running" });
14594
+ return;
14595
+ }
14596
+ if (event.kind === "node_settled") {
14597
+ this.patchNode(event.run.node_id, {
14598
+ status: "completed",
14599
+ cached: event.run.cached,
14600
+ credits: event.run.credits,
14601
+ durationMs: event.run.duration_ms,
14602
+ outputs: nodeOutputsToRecord(event.outputs)
14603
+ });
14604
+ return;
14605
+ }
14606
+ this.patchNode(event.node_id, { status: "failed" });
14607
+ }
14608
+ /** True once the plan event landed — before that there is nothing worth posting. */
14609
+ hasPlan() {
14610
+ return this.planned;
14611
+ }
14612
+ /** Plan facts (deps + params preview) for stamping the terminal record's nodes. */
14613
+ planInfo() {
14614
+ const info = /* @__PURE__ */ new Map();
14615
+ for (const node of this.nodes.values()) {
14616
+ info.set(node.nodeId, { deps: node.deps ?? [], paramsPreview: node.paramsPreview });
14617
+ }
14618
+ return info;
14619
+ }
14620
+ /** The current in-flight state as a postable full record. */
14621
+ snapshot() {
14622
+ const nodes = [...this.nodes.values()];
14623
+ return {
14624
+ runId: this.runId,
14625
+ ...this.meta,
14626
+ status: "running",
14627
+ stats: {
14628
+ totalNodes: nodes.length,
14629
+ cachedNodes: nodes.filter((n) => n.cached).length,
14630
+ totalCredits: nodes.reduce((sum, n) => sum + n.credits, 0),
14631
+ durationMs: Date.now() - this.startedAt
14632
+ },
14633
+ nodes
14634
+ };
14635
+ }
14636
+ /**
14637
+ * Terminal record for a failed run, preserving what each node got to —
14638
+ * completed nodes keep their outputs so the graph shows exactly where the
14639
+ * run died instead of an empty husk.
14640
+ */
14641
+ failedSnapshot(errorMessage) {
14642
+ const snapshot = this.snapshot();
14643
+ return {
14644
+ ...snapshot,
14645
+ status: "failed",
14646
+ errorMessage: errorMessage.slice(0, 2e3),
14647
+ stats: { ...snapshot.stats, durationMs: Date.now() - this.startedAt }
14648
+ };
14649
+ }
14650
+ patchNode(nodeId, patch) {
14651
+ const existing = this.nodes.get(nodeId);
14652
+ if (!existing) return;
14653
+ this.nodes.set(nodeId, { ...existing, ...patch, status: patch.status ?? existing.status });
14654
+ }
14655
+ };
14656
+ var RunRecordPoster = class {
14657
+ post;
14658
+ latest = null;
14659
+ inflight = null;
14660
+ warned = false;
14661
+ constructor(post) {
14662
+ this.post = post;
14663
+ }
14664
+ /** Queue a progress snapshot; returns immediately. */
14665
+ enqueue(payload) {
14666
+ this.latest = payload;
14667
+ if (!this.inflight) this.inflight = this.pump();
14668
+ }
14669
+ /**
14670
+ * Post the terminal record (awaited, errors surfaced to the caller). Any
14671
+ * queued progress snapshot is superseded — the terminal record is the full
14672
+ * state — but an in-flight POST is awaited first so it can't land after.
14673
+ */
14674
+ async flush(terminal) {
14675
+ this.latest = null;
14676
+ if (this.inflight) await this.inflight;
14677
+ await this.post(terminal);
14678
+ }
14679
+ async pump() {
14680
+ while (this.latest) {
14681
+ const payload = this.latest;
14682
+ this.latest = null;
14683
+ try {
14684
+ await this.post(payload);
14685
+ } catch (e) {
14686
+ if (!this.warned) {
14687
+ this.warned = true;
14688
+ const msg = e instanceof Error ? e.message : String(e);
14689
+ process.stderr.write(`[warn] live run progress not streaming (${msg})
14690
+ `);
14691
+ }
14692
+ }
14693
+ }
14694
+ this.inflight = null;
14695
+ }
14696
+ };
14697
+
14552
14698
  // src/commands/canvas/run-retention.ts
14553
14699
  import { rm } from "fs/promises";
14554
- import path3 from "path";
14700
+ import path4 from "path";
14555
14701
  function runDirsToPrune(entries, keep, currentRunId) {
14556
14702
  const runs = entries.filter((e) => /^r_[0-9A-Za-z]+$/.test(e) && e !== currentRunId).sort();
14557
14703
  if (keep <= 0) return runs;
@@ -14568,7 +14714,7 @@ async function pruneOldRuns(outputsDir, keep, currentRunId, log) {
14568
14714
  const toPrune = runDirsToPrune(entries, keep, currentRunId);
14569
14715
  if (toPrune.length === 0) return;
14570
14716
  for (const dir of toPrune) {
14571
- await rm(path3.join(outputsDir, dir), { recursive: true, force: true }).catch(
14717
+ await rm(path4.join(outputsDir, dir), { recursive: true, force: true }).catch(
14572
14718
  (e) => log(`[prune ] could not remove ${dir}: ${e.message}`)
14573
14719
  );
14574
14720
  }
@@ -14595,10 +14741,22 @@ var runCommand = defineCommand88({
14595
14741
  "keep-runs": {
14596
14742
  type: "string",
14597
14743
  description: "After the run, prune old r_* run dirs, keeping the N newest (off by default)"
14744
+ },
14745
+ "remote-cache": {
14746
+ type: "string",
14747
+ description: "on | off \u2014 company-scoped remote cache + durable asset persistence (default on; env BAKER_CANVAS_REMOTE_CACHE)"
14748
+ },
14749
+ // citty consumes any `--no-<flag>` as a negation of `<flag>`, so the
14750
+ // opt-out spelling `--no-record` requires the flag to be named `record`
14751
+ // (a literal "no-record" arg would never receive a value).
14752
+ record: {
14753
+ type: "boolean",
14754
+ default: true,
14755
+ description: "Post the durable run-history record to Baker (disable with --no-record)"
14598
14756
  }
14599
14757
  },
14600
14758
  async run({ args }) {
14601
- const filePath = path4.resolve(String(args.file));
14759
+ const filePath = path5.resolve(String(args.file));
14602
14760
  const raw = await readFile2(filePath, "utf8");
14603
14761
  let parsed;
14604
14762
  try {
@@ -14609,7 +14767,7 @@ var runCommand = defineCommand88({
14609
14767
  `);
14610
14768
  process.exit(2);
14611
14769
  }
14612
- parsed = resolveRelativeCanvasPaths(parsed, path4.dirname(filePath));
14770
+ parsed = resolveRelativeCanvasPaths(parsed, path5.dirname(filePath));
14613
14771
  const pending = unsuppliedPlaceholderAssets(parsed);
14614
14772
  if (pending.length > 0) {
14615
14773
  process.stderr.write(
@@ -14629,26 +14787,43 @@ var runCommand = defineCommand88({
14629
14787
  );
14630
14788
  process.exit(2);
14631
14789
  }
14790
+ const remoteCache = args["remote-cache"] !== void 0 ? String(args["remote-cache"]) !== "off" : void 0;
14632
14791
  const engine = createEngineFromEnv({
14633
14792
  cacheDir: args["cache-dir"] ? String(args["cache-dir"]) : void 0,
14634
14793
  outputsDir: args["outputs-dir"] ? String(args["outputs-dir"]) : void 0,
14635
14794
  log: (line) => process.stdout.write(`${line}
14636
- `)
14795
+ `),
14796
+ remoteCache
14637
14797
  });
14798
+ const runId = args["run-id"] ? String(args["run-id"]) : `r_${ulid()}`;
14799
+ const recordMeta = {
14800
+ creativeSlug: creativeSlugFromCanvasPath(filePath) ?? void 0,
14801
+ canvasPath: path5.relative(process.cwd(), filePath) || void 0,
14802
+ canvasSha: sha256Hex(Buffer.from(raw)),
14803
+ chatId: getEnv().BAKER_CHAT_ID || void 0
14804
+ };
14805
+ const record = args.record === false ? null : buildRecorder();
14806
+ const progress = record ? new RunProgressTracker(runId, recordMeta) : null;
14807
+ const poster = record ? new RunRecordPoster(record) : null;
14638
14808
  try {
14639
14809
  const policy = args["cache-policy"] ?? "read_write";
14640
14810
  const result = await engine.run(parsed, {
14641
- run_id: args["run-id"] ? String(args["run-id"]) : void 0,
14811
+ run_id: runId,
14642
14812
  cache_policy: policy,
14643
14813
  concurrency: resolveConcurrency(
14644
14814
  // --concurrency wins; --parallel is the discoverable alias for the same bound.
14645
14815
  (args.concurrency ?? args.parallel) !== void 0 ? String(args.concurrency ?? args.parallel) : void 0,
14646
14816
  process.env.BAKER_CANVAS_CONCURRENCY
14647
- )
14817
+ ),
14818
+ onProgress: progress && poster ? (event) => {
14819
+ progress.apply(event);
14820
+ if (progress.hasPlan()) poster.enqueue(progress.snapshot());
14821
+ } : void 0
14648
14822
  });
14823
+ if (poster) await poster.flush(buildRunRecord(result, recordMeta, progress?.planInfo()));
14649
14824
  const keepRuns = args["keep-runs"] !== void 0 ? Number(args["keep-runs"]) : void 0;
14650
14825
  if (keepRuns !== void 0 && Number.isFinite(keepRuns)) {
14651
- const outputsDir = args["outputs-dir"] ? path4.resolve(String(args["outputs-dir"])) : path4.resolve("canvas");
14826
+ const outputsDir = args["outputs-dir"] ? path5.resolve(String(args["outputs-dir"])) : path5.resolve("canvas");
14652
14827
  await pruneOldRuns(outputsDir, keepRuns, result.run_id, (line) => process.stdout.write(`${line}
14653
14828
  `));
14654
14829
  }
@@ -14674,8 +14849,10 @@ var runCommand = defineCommand88({
14674
14849
  );
14675
14850
  process.exit(2);
14676
14851
  }
14852
+ const failedPayload = (message) => progress?.hasPlan() ? progress.failedSnapshot(message) : buildFailedRunRecord(runId, message, recordMeta);
14677
14853
  if (e instanceof LayerExecutionError) {
14678
14854
  const failures = e.failures.map((f) => ({ node_id: f.nodeId, message: describeFailureReason(f.reason) }));
14855
+ if (poster) await poster.flush(failedPayload(e.message));
14679
14856
  process.stderr.write(
14680
14857
  `${JSON.stringify({ ok: false, error: { code: "runtime", message: e.message, failures } }, null, 2)}
14681
14858
  `
@@ -14683,40 +14860,54 @@ var runCommand = defineCommand88({
14683
14860
  process.exit(1);
14684
14861
  }
14685
14862
  const msg = e instanceof Error ? e.message : String(e);
14863
+ if (poster) await poster.flush(failedPayload(msg));
14686
14864
  process.stderr.write(`${JSON.stringify({ ok: false, error: { code: "runtime", message: msg } }, null, 2)}
14687
14865
  `);
14688
14866
  process.exit(1);
14689
14867
  }
14690
14868
  }
14691
14869
  });
14870
+ function buildRecorder() {
14871
+ return async (payload) => {
14872
+ try {
14873
+ const creds = requireCredentialsFromEnv();
14874
+ const client = new BackendClient({ baseUrl: creds.url, apiKey: creds.apiKey });
14875
+ await client.recordRun(payload);
14876
+ } catch (e) {
14877
+ const msg = e instanceof Error ? e.message : String(e);
14878
+ process.stderr.write(`[warn] run record not persisted (${msg})
14879
+ `);
14880
+ }
14881
+ };
14882
+ }
14692
14883
 
14693
14884
  // src/commands/canvas/scaffold-static-ad.ts
14694
- import { readFile as readFile3, writeFile } from "fs/promises";
14695
- import path6 from "path";
14885
+ import { access, mkdir, readFile as readFile3, writeFile } from "fs/promises";
14886
+ import path8 from "path";
14696
14887
  import { defineCommand as defineCommand89 } from "citty";
14697
14888
 
14698
14889
  // src/engine/scaffold/staticAd.ts
14699
- import { z as z12 } from "zod";
14890
+ import { z as z11 } from "zod";
14700
14891
  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"]);
14701
14892
  var DEFAULT_ASPECT_RATIO = "9:16";
14702
- var Blueprint = z12.object({
14703
- meta: z12.object({ estimated_aspect_ratio: z12.string().optional() }).loose().optional(),
14704
- text_content: z12.array(z12.object({ text: z12.string().optional() }).loose()).optional()
14893
+ var Blueprint = z11.object({
14894
+ meta: z11.object({ estimated_aspect_ratio: z11.string().optional() }).loose().optional(),
14895
+ text_content: z11.array(z11.object({ text: z11.string().optional() }).loose()).optional()
14705
14896
  }).loose();
14706
- var ElementLocator = z12.object({
14707
- collection: z12.enum(["subjects", "people", "brands_logos"]),
14708
- index: z12.number().int().nonnegative()
14897
+ var ElementLocator = z11.object({
14898
+ collection: z11.enum(["subjects", "people", "brands_logos"]),
14899
+ index: z11.number().int().nonnegative()
14709
14900
  }).loose();
14710
- var MainElement = z12.object({
14901
+ var MainElement = z11.object({
14711
14902
  // logo | product | person | animal | badge | other
14712
- type: z12.string(),
14713
- label: z12.string().optional(),
14714
- description: z12.string().optional(),
14715
- expression: z12.string().nullable().optional(),
14716
- reason: z12.string().optional(),
14903
+ type: z11.string(),
14904
+ label: z11.string().optional(),
14905
+ description: z11.string().optional(),
14906
+ expression: z11.string().nullable().optional(),
14907
+ reason: z11.string().optional(),
14717
14908
  locator: ElementLocator.optional()
14718
14909
  }).loose();
14719
- var MainElements = z12.array(MainElement);
14910
+ var MainElements = z11.array(MainElement);
14720
14911
  function sanitizeId(raw, fallback) {
14721
14912
  const id = raw.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
14722
14913
  return /^[a-z]/.test(id) ? id : `${fallback}_${id}`.replace(/_+$/g, "") || fallback;
@@ -14878,18 +15069,102 @@ function staticAdReport(input, elementsInput, opts) {
14878
15069
  };
14879
15070
  }
14880
15071
 
15072
+ // src/commands/canvas/creative-definition.ts
15073
+ import path6 from "path";
15074
+ var PLATFORM_VALUES = ["meta", "google", "linkedin", "tiktok", "youtube", "x", "other"];
15075
+ var FORMAT_VALUES = ["1:1", "4:5", "9:16", "16:9", "1.91:1"];
15076
+ function titleFromSlug(slug) {
15077
+ const title = slug.split("-").filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
15078
+ return title || slug;
15079
+ }
15080
+ function resolvePlatform(platform) {
15081
+ const value = platform?.trim();
15082
+ return value && PLATFORM_VALUES.includes(value) ? value : "meta";
15083
+ }
15084
+ function resolveFormats(aspect) {
15085
+ const value = aspect?.trim();
15086
+ return value && FORMAT_VALUES.includes(value) ? [value] : ["4:5"];
15087
+ }
15088
+ function referenceRelativePath(kind, ext) {
15089
+ const name = kind === "video" ? "source" : "original";
15090
+ return `references/${name}${ext}`;
15091
+ }
15092
+ function describeBlueprintIntent(blueprint) {
15093
+ const intent = blueprint?.ad_intent;
15094
+ if (typeof intent === "string" && intent.trim()) return intent.trim();
15095
+ if (intent && typeof intent === "object") {
15096
+ const summary = intent.summary ?? intent.feeling;
15097
+ if (typeof summary === "string" && summary.trim()) return summary.trim();
15098
+ }
15099
+ return void 0;
15100
+ }
15101
+ function yamlScalar(value) {
15102
+ return JSON.stringify(value);
15103
+ }
15104
+ function buildCreativeDefinition(input) {
15105
+ const lines = ["---", `title: ${yamlScalar(input.title)}`, `kind: ${input.kind}`, `platform: ${input.platform}`];
15106
+ lines.push(`formats: [${input.formats.map(yamlScalar).join(", ")}]`);
15107
+ lines.push(`status: ${input.status ?? "draft"}`);
15108
+ if (input.sourceReferenceUrl) lines.push(`sourceReferenceUrl: ${yamlScalar(input.sourceReferenceUrl)}`);
15109
+ if (input.sourceAdvertiser) lines.push(`sourceAdvertiser: ${yamlScalar(input.sourceAdvertiser)}`);
15110
+ if (input.sourceKind) lines.push(`sourceKind: ${input.sourceKind}`);
15111
+ if (input.sourcePath) lines.push(`sourcePath: ${yamlScalar(input.sourcePath)}`);
15112
+ lines.push("---", "");
15113
+ lines.push(input.description?.trim() || `${input.title} \u2014 canvas-built ${input.kind} ad for ${input.platform}.`);
15114
+ lines.push("");
15115
+ return lines.join("\n");
15116
+ }
15117
+
14881
15118
  // src/commands/canvas/scaffold-static-ad-paths.ts
14882
- import path5 from "path";
14883
- function resolveScaffoldStaticAdPaths(rawFile, out, cwd = process.cwd()) {
15119
+ import path7 from "path";
15120
+ function resolveScaffoldStaticAdPaths(rawFile, out, cwd = process.cwd(), slug) {
14884
15121
  const file = rawFile.trim();
14885
15122
  const imageIsUrl = /^https?:\/\//i.test(file);
14886
- const imageSource = imageIsUrl ? file : path5.resolve(cwd, file);
14887
- const outPath = out ? path5.resolve(cwd, out) : imageIsUrl ? path5.join(cwd, "static-ad.canvas.json") : path5.join(path5.dirname(imageSource), "static-ad.canvas.json");
14888
- const blueprintPath = path5.join(path5.dirname(outPath), "prompt.json");
14889
- return { imageIsUrl, imageSource, outPath, blueprintPath };
15123
+ const imageSource = imageIsUrl ? file : path7.resolve(cwd, file);
15124
+ 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");
15125
+ const blueprintPath = path7.join(path7.dirname(outPath), "prompt.json");
15126
+ const creativeDir = slug ? path7.dirname(outPath) : null;
15127
+ const definitionPath = creativeDir ? path7.join(creativeDir, "_definition.md") : null;
15128
+ const referencesDir = creativeDir ? path7.join(creativeDir, "references") : null;
15129
+ return { imageIsUrl, imageSource, outPath, blueprintPath, creativeDir, definitionPath, referencesDir };
15130
+ }
15131
+ var SCAFFOLD_SLUG_PATTERN = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
15132
+ var SCAFFOLD_SLUG_MAX_LENGTH = 100;
15133
+ function isValidScaffoldSlug(slug) {
15134
+ return slug.length <= SCAFFOLD_SLUG_MAX_LENGTH && SCAFFOLD_SLUG_PATTERN.test(slug);
14890
15135
  }
14891
15136
 
14892
15137
  // src/commands/canvas/scaffold-static-ad.ts
15138
+ async function fileExists(target) {
15139
+ try {
15140
+ await access(target);
15141
+ return true;
15142
+ } catch {
15143
+ return false;
15144
+ }
15145
+ }
15146
+ var MODEL_SAFE_EXT_BY_MIME = {
15147
+ "image/png": ".png",
15148
+ "image/jpeg": ".jpg",
15149
+ "image/gif": ".gif",
15150
+ "image/webp": ".webp"
15151
+ };
15152
+ async function copySourceIntoReferences(source, isUrl, referencesDir) {
15153
+ await mkdir(referencesDir, { recursive: true });
15154
+ let bytes;
15155
+ if (isUrl) {
15156
+ const res = await fetch(source);
15157
+ if (!res.ok) throw new Error(`failed to download source image (${res.status})`);
15158
+ bytes = Buffer.from(await res.arrayBuffer());
15159
+ } else {
15160
+ bytes = await readFile3(source);
15161
+ }
15162
+ const safe = await toModelSafeImage(bytes);
15163
+ const relPath = referenceRelativePath("image", MODEL_SAFE_EXT_BY_MIME[safe.mime] ?? ".png");
15164
+ const dest = path8.join(referencesDir, path8.basename(relPath));
15165
+ await writeFile(dest, safe.bytes);
15166
+ return relPath;
15167
+ }
14893
15168
  function resolveModel(kind, preferred) {
14894
15169
  const ids = Object.keys(MODEL_REGISTRY[kind]);
14895
15170
  return ids.includes(preferred) ? preferred : ids[0] ?? preferred;
@@ -15049,6 +15324,16 @@ var scaffoldStaticAdCommand = defineCommand89({
15049
15324
  file: { type: "positional", required: true, description: "Path or http(s) URL to the source/inspiration image" },
15050
15325
  context: { type: "string", description: "Known provenance (advertiser, category, market) to ground the describe" },
15051
15326
  out: { type: "string", description: "Output canvas path (default <image-dir>/static-ad.canvas.json)" },
15327
+ slug: {
15328
+ type: "string",
15329
+ description: "Creative slug \u2014 writes the canvas to src/creatives/<slug>/<slug>.canvas.json (repo convention)"
15330
+ },
15331
+ title: { type: "string", description: "Creative title for _definition.md (default: title-cased slug)" },
15332
+ platform: {
15333
+ type: "string",
15334
+ description: "Ad platform for _definition.md (meta|google|linkedin|tiktok|youtube|x|other; default meta)"
15335
+ },
15336
+ advertiser: { type: "string", description: "Source advertiser recorded in _definition.md" },
15052
15337
  "describe-model": { type: "string", description: "Override the image_describe model id" },
15053
15338
  "select-model": { type: "string", description: "Override the text_generate model id for element selection" },
15054
15339
  "layout-model": { type: "string", description: "Override the text_generate model id for the layout pass" },
@@ -15057,10 +15342,21 @@ var scaffoldStaticAdCommand = defineCommand89({
15057
15342
  "skip-font": { type: "boolean", description: "Skip the brand-font \u2192 type-specimen slot" }
15058
15343
  },
15059
15344
  async run({ args }) {
15060
- const { imageIsUrl, imageSource, outPath, blueprintPath } = resolveScaffoldStaticAdPaths(
15345
+ const slug = args.slug ? String(args.slug) : void 0;
15346
+ if (slug && !isValidScaffoldSlug(slug)) {
15347
+ process.stderr.write(
15348
+ `${JSON.stringify({ ok: false, error: { code: "invalid_slug", message: "--slug must be lowercase kebab (a-z, 0-9, hyphens), max 100 chars" } }, null, 2)}
15349
+ `
15350
+ );
15351
+ process.exit(2);
15352
+ }
15353
+ const { imageIsUrl, imageSource, outPath, blueprintPath, definitionPath, referencesDir } = resolveScaffoldStaticAdPaths(
15061
15354
  String(args.file),
15062
- args.out ? String(args.out) : void 0
15355
+ args.out ? String(args.out) : void 0,
15356
+ process.cwd(),
15357
+ slug
15063
15358
  );
15359
+ await mkdir(path8.dirname(outPath), { recursive: true });
15064
15360
  const { describeModel, selectModel, layoutModel, genModel } = resolveModels(args);
15065
15361
  const describeCanvas = buildDescribeCanvas(
15066
15362
  imageSource,
@@ -15077,11 +15373,21 @@ var scaffoldStaticAdCommand = defineCommand89({
15077
15373
  }
15078
15374
  await writeFile(blueprintPath, `${JSON.stringify(annotated, null, 2)}
15079
15375
  `, "utf8");
15376
+ let canvasImagePath = imageSource;
15377
+ let canvasImageIsUrl = imageIsUrl;
15378
+ let canvasBlueprintPath = blueprintPath;
15379
+ let sourceRelPath;
15380
+ if (referencesDir) {
15381
+ sourceRelPath = await copySourceIntoReferences(imageSource, imageIsUrl, referencesDir);
15382
+ canvasImagePath = sourceRelPath;
15383
+ canvasImageIsUrl = false;
15384
+ canvasBlueprintPath = "./prompt.json";
15385
+ }
15080
15386
  const opts = {
15081
15387
  genModel,
15082
- imagePath: imageSource,
15083
- imageIsUrl,
15084
- blueprintPath,
15388
+ imagePath: canvasImagePath,
15389
+ imageIsUrl: canvasImageIsUrl,
15390
+ blueprintPath: canvasBlueprintPath,
15085
15391
  aspectRatio: args.aspect ? String(args.aspect) : void 0,
15086
15392
  includeFont: !args["skip-font"]
15087
15393
  };
@@ -15103,12 +15409,31 @@ var scaffoldStaticAdCommand = defineCommand89({
15103
15409
  }
15104
15410
  await writeFile(outPath, `${JSON.stringify(canvas, null, 2)}
15105
15411
  `, "utf8");
15412
+ if (definitionPath && !await fileExists(definitionPath)) {
15413
+ await writeFile(
15414
+ definitionPath,
15415
+ buildCreativeDefinition({
15416
+ title: args.title ? String(args.title) : titleFromSlug(slug ?? ""),
15417
+ kind: "static",
15418
+ platform: resolvePlatform(args.platform ? String(args.platform) : void 0),
15419
+ formats: resolveFormats(args.aspect ? String(args.aspect) : report.aspect_ratio),
15420
+ sourceReferenceUrl: imageIsUrl ? imageSource : void 0,
15421
+ sourceAdvertiser: args.advertiser ? String(args.advertiser) : args.context ? String(args.context) : void 0,
15422
+ sourceKind: "image",
15423
+ sourcePath: sourceRelPath,
15424
+ description: describeBlueprintIntent(blueprint)
15425
+ }),
15426
+ "utf8"
15427
+ );
15428
+ }
15106
15429
  process.stdout.write(
15107
15430
  `${JSON.stringify(
15108
15431
  {
15109
15432
  ok: true,
15110
15433
  canvas_path: outPath,
15111
15434
  prompt_path: blueprintPath,
15435
+ definition_path: definitionPath ?? void 0,
15436
+ source_reference: sourceRelPath ?? void 0,
15112
15437
  output: canvas.output,
15113
15438
  models: { describe: describeModel, select: selectModel, layout: layoutModel, gen: opts.genModel },
15114
15439
  aspect_ratio: report.aspect_ratio,
@@ -15119,7 +15444,7 @@ var scaffoldStaticAdCommand = defineCommand89({
15119
15444
  run_estimated_credits: validation.estimatedCredits
15120
15445
  },
15121
15446
  checklist: {
15122
- 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.`,
15447
+ 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.`,
15123
15448
  assets_to_supply: report.elements,
15124
15449
  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)",
15125
15450
  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."
@@ -15134,8 +15459,8 @@ var scaffoldStaticAdCommand = defineCommand89({
15134
15459
  });
15135
15460
 
15136
15461
  // src/commands/canvas/scaffold-video.ts
15137
- import { cp, mkdir, readFile as readFile6, writeFile as writeFile2 } from "fs/promises";
15138
- import path9 from "path";
15462
+ import { cp, mkdir as mkdir2, readFile as readFile6, writeFile as writeFile2 } from "fs/promises";
15463
+ import path11 from "path";
15139
15464
  import { defineCommand as defineCommand90 } from "citty";
15140
15465
 
15141
15466
  // src/engine/nodes/local/lib/sceneDetect.ts
@@ -15252,7 +15577,7 @@ import { toCardinal as nwKo } from "n2words/ko-KR";
15252
15577
  import { toCardinal as nwNl } from "n2words/nl-NL";
15253
15578
  import { toCardinal as nwPl } from "n2words/pl-PL";
15254
15579
  import { toCardinal as nwPt } from "n2words/pt-PT";
15255
- import { z as z13 } from "zod";
15580
+ import { z as z12 } from "zod";
15256
15581
 
15257
15582
  // src/engine/scaffold/lib/shoot-modes.ts
15258
15583
  var SHOOT_MODES = [
@@ -15565,71 +15890,71 @@ function trimArgs(durationS, offsetS = 0, dims) {
15565
15890
  "{{out.video}}"
15566
15891
  ];
15567
15892
  }
15568
- var FrameAsset = z13.object({ url: z13.string().optional() }).loose().optional();
15569
- var DialogueLine = z13.object({
15570
- speaker: z13.string().optional(),
15571
- line: z13.string().optional(),
15893
+ var FrameAsset = z12.object({ url: z12.string().optional() }).loose().optional();
15894
+ var DialogueLine = z12.object({
15895
+ speaker: z12.string().optional(),
15896
+ line: z12.string().optional(),
15572
15897
  // Absolute seconds on the source timeline (the deconstruct emits both).
15573
- start_s: z13.number().optional(),
15574
- end_s: z13.number().optional(),
15575
- delivery: z13.string().optional(),
15576
- voice_description: z13.string().optional(),
15898
+ start_s: z12.number().optional(),
15899
+ end_s: z12.number().optional(),
15900
+ delivery: z12.string().optional(),
15901
+ voice_description: z12.string().optional(),
15577
15902
  // DECON-supplied: is this speaker's FACE visibly speaking in THIS scene? Element
15578
15903
  // presence alone can't answer that — a founder pictured in a polaroid close-up is
15579
15904
  // "present" yet the line is voiceover, and treating it as on-camera produced a
15580
15905
  // native Seedance lip-sync clip of a still photograph. `false` pins the line to
15581
15906
  // the VO path; absent keeps the presence-based decision (old blueprints).
15582
- on_camera: z13.boolean().optional()
15907
+ on_camera: z12.boolean().optional()
15583
15908
  }).loose();
15584
- var Sfx = z13.object({
15585
- at_s: z13.number().optional(),
15586
- duration_s: z13.number().optional(),
15587
- sound_effect_prompt: z13.string().optional(),
15588
- description: z13.string().optional()
15909
+ var Sfx = z12.object({
15910
+ at_s: z12.number().optional(),
15911
+ duration_s: z12.number().optional(),
15912
+ sound_effect_prompt: z12.string().optional(),
15913
+ description: z12.string().optional()
15589
15914
  }).loose();
15590
- var CompositionRegion = z13.object({
15915
+ var CompositionRegion = z12.object({
15591
15916
  // full | top | bottom | left | right | inset
15592
- panel: z13.string().optional(),
15917
+ panel: z12.string().optional(),
15593
15918
  // 9-grid anchor for an `inset` presenter box.
15594
- position: z13.string().optional(),
15595
- is_presenter: z13.boolean().optional(),
15919
+ position: z12.string().optional(),
15920
+ is_presenter: z12.boolean().optional(),
15596
15921
  // The cast id shown/speaking in this region (routes lip-sync + element refs).
15597
- cast_ref: z13.string().optional(),
15922
+ cast_ref: z12.string().optional(),
15598
15923
  // What the region's content IS: camera | screen_capture | static_graphic |
15599
15924
  // generated. Authoritative for routing when present (regex-over-prose fallback
15600
15925
  // otherwise): screen_capture/static_graphic are rebuilt from REAL surfaces on the
15601
15926
  // overlay layer, never AI-generated.
15602
- kind: z13.string().optional(),
15927
+ kind: z12.string().optional(),
15603
15928
  // Opaque id naming the SPECIFIC on-screen document/note/app-state this
15604
15929
  // screen_capture region shows. Two scenes share it only when they show the SAME
15605
15930
  // recording continuing (scrolling/typing/waiting within it) — a genuinely
15606
15931
  // DIFFERENT document/note/recording (a source video splicing two screen captures)
15607
15932
  // gets a different id. Breaks a persistent-layout run into separate surface stubs
15608
15933
  // instead of asking the operator for one screenshot that can't cover both.
15609
- surface_id: z13.string().optional(),
15934
+ surface_id: z12.string().optional(),
15610
15935
  // Camera bubble(s)/inset(s) embedded INSIDE this region's surface (a Loom-style
15611
15936
  // presenter bubble inside a screen recording) — video-in-video the reproduction
15612
15937
  // must re-composite, not paint into the surface.
15613
- nested: z13.array(z13.object({}).loose()).optional(),
15614
- summary: z13.string().optional(),
15615
- frame_prompt: z13.string().optional(),
15616
- motion_prompt: z13.string().optional()
15938
+ nested: z12.array(z12.object({}).loose()).optional(),
15939
+ summary: z12.string().optional(),
15940
+ frame_prompt: z12.string().optional(),
15941
+ motion_prompt: z12.string().optional()
15617
15942
  }).loose();
15618
- var SceneComposition = z13.object({
15943
+ var SceneComposition = z12.object({
15619
15944
  // full_frame (default) | split_screen | pip | keyed_overlay
15620
- layout: z13.string().optional(),
15945
+ layout: z12.string().optional(),
15621
15946
  // split_screen only: vertical (top/bottom) | horizontal (left/right).
15622
- split_axis: z13.string().optional(),
15623
- regions: z13.array(CompositionRegion).optional()
15947
+ split_axis: z12.string().optional(),
15948
+ regions: z12.array(CompositionRegion).optional()
15624
15949
  }).loose();
15625
- var CameraMotion = z13.object({ movement: z13.string().optional(), detail: z13.string().optional() }).loose();
15626
- var TranscriptWord = z13.object({ text: z13.string().optional() }).loose();
15627
- var Scene = z13.object({
15628
- start_s: z13.number().optional(),
15629
- end_s: z13.number().optional(),
15630
- duration_s: z13.number().optional(),
15631
- summary: z13.string().optional(),
15632
- action_detail: z13.string().optional(),
15950
+ var CameraMotion = z12.object({ movement: z12.string().optional(), detail: z12.string().optional() }).loose();
15951
+ var TranscriptWord = z12.object({ text: z12.string().optional() }).loose();
15952
+ var Scene = z12.object({
15953
+ start_s: z12.number().optional(),
15954
+ end_s: z12.number().optional(),
15955
+ duration_s: z12.number().optional(),
15956
+ summary: z12.string().optional(),
15957
+ action_detail: z12.string().optional(),
15633
15958
  // The scene's spatial layout. Absent/full_frame ⇒ one uncut shot (default path).
15634
15959
  // A layered layout (split_screen/pip/keyed_overlay) with regions ⇒ the scaffold
15635
15960
  // builds one clip per region and stacks/overlays them into the scene picture.
@@ -15637,82 +15962,82 @@ var Scene = z13.object({
15637
15962
  // The capture "look" for this scene — selected from the ad-native shoot-mode
15638
15963
  // grammar (see lib/shoot-modes.ts). When absent the scaffold auto-derives a
15639
15964
  // UGC/product mode; a human can override per scene by setting this.
15640
- shoot_mode: z13.string().optional(),
15965
+ shoot_mode: z12.string().optional(),
15641
15966
  // Diegetic ambient the clip's native audio should carry (no music). When
15642
15967
  // absent the scene falls back to its shoot mode's default ambience.
15643
- ambient: z13.string().optional(),
15968
+ ambient: z12.string().optional(),
15644
15969
  camera_motion: CameraMotion.optional(),
15645
- start_frame_prompt: z13.string().optional(),
15646
- end_frame_prompt: z13.string().optional(),
15647
- motion_prompt: z13.string().optional(),
15970
+ start_frame_prompt: z12.string().optional(),
15971
+ end_frame_prompt: z12.string().optional(),
15972
+ motion_prompt: z12.string().optional(),
15648
15973
  // The scene's role in the ad's persuasion arc (DECON-supplied); drives the
15649
15974
  // script re-craft checklist. Inferred from position when absent.
15650
- narrative_role: z13.string().optional(),
15975
+ narrative_role: z12.string().optional(),
15651
15976
  // DECON-supplied on the HOOK scene: the engineered physical/emotional state that
15652
15977
  // makes the first frame stop the scroll (sweaty/breathless/urgent …). Injected
15653
15978
  // into the hook's start-frame description so the generator renders that state,
15654
15979
  // not a calm influencer (CCA-11).
15655
- hook_mechanic: z13.object({ mechanic: z13.string().optional(), why_it_stops_scroll: z13.string().optional() }).loose().optional(),
15980
+ hook_mechanic: z12.object({ mechanic: z12.string().optional(), why_it_stops_scroll: z12.string().optional() }).loose().optional(),
15656
15981
  // DECON-supplied per-scene location (so a gym hook isn't flattened to "home").
15657
- scene_setting: z13.string().optional(),
15982
+ scene_setting: z12.string().optional(),
15658
15983
  // How this scene cuts to the next (DECON-supplied). A recognized non-cut type
15659
15984
  // (fade/whip/zoom/dissolve/swipe) is reproduced as an ffmpeg xfade at the
15660
15985
  // boundary; cut/match_cut/none/other stay hard cuts. The last scene's value is
15661
15986
  // ignored (nothing follows it).
15662
- transition_out: z13.object({ type: z13.string().optional(), description: z13.string().optional() }).loose().optional(),
15663
- dialogue: z13.array(DialogueLine).optional(),
15664
- sfx: z13.array(Sfx).optional(),
15665
- overlays: z13.array(z13.unknown()).optional(),
15666
- floating_elements: z13.array(z13.unknown()).optional(),
15987
+ transition_out: z12.object({ type: z12.string().optional(), description: z12.string().optional() }).loose().optional(),
15988
+ dialogue: z12.array(DialogueLine).optional(),
15989
+ sfx: z12.array(Sfx).optional(),
15990
+ overlays: z12.array(z12.unknown()).optional(),
15991
+ floating_elements: z12.array(z12.unknown()).optional(),
15667
15992
  // DECON-supplied: how much the picture itself moves within the shot. Gates the
15668
15993
  // flash-hold optimization — a sub-2s b-roll flash with REAL subject motion
15669
15994
  // (pouring, spreading, hands working) must stay a real clip; freezing it turns
15670
15995
  // a montage into a slideshow. Absent (old blueprints) keeps the cheap still.
15671
- motion_level: z13.enum(["static", "subtle", "dynamic"]).optional(),
15672
- transcript_slice: z13.array(TranscriptWord).optional(),
15996
+ motion_level: z12.enum(["static", "subtle", "dynamic"]).optional(),
15997
+ transcript_slice: z12.array(TranscriptWord).optional(),
15673
15998
  start_frame_asset: FrameAsset,
15674
15999
  end_frame_asset: FrameAsset,
15675
16000
  // DECON-supplied: true when this scene is a length-split CONTINUATION of the
15676
16001
  // previous one (the SAME physical shot, broken up only because it exceeded the
15677
16002
  // clip ceiling). The scaffold then shares the splice keyframe — this scene's
15678
16003
  // start frame IS the previous scene's end frame — so the join is seamless.
15679
- continues_previous: z13.boolean().optional()
16004
+ continues_previous: z12.boolean().optional()
15680
16005
  }).loose();
15681
- var VideoBlueprint = z13.object({
15682
- source: z13.object({ aspect_ratio: z13.string().optional(), duration_s: z13.number().optional() }).loose().optional(),
15683
- global: z13.object({
15684
- music: z13.object({
15685
- present: z13.boolean().optional(),
15686
- music_prompt: z13.string().optional(),
16006
+ var VideoBlueprint = z12.object({
16007
+ source: z12.object({ aspect_ratio: z12.string().optional(), duration_s: z12.number().optional() }).loose().optional(),
16008
+ global: z12.object({
16009
+ music: z12.object({
16010
+ present: z12.boolean().optional(),
16011
+ music_prompt: z12.string().optional(),
15687
16012
  // Absolute second the music enters in the reference (the bed often
15688
16013
  // kicks in mid-ad, after the hook). We start the regenerated track here
15689
16014
  // instead of at 0 so the timing matches.
15690
- starts_at_s: z13.number().optional(),
16015
+ starts_at_s: z12.number().optional(),
15691
16016
  // Populated by the deconstruct when AudD (Shazam-style) recognizes the
15692
16017
  // reference track. We never reuse it — only style the regenerated bed.
15693
- identified_track: z13.object({ title: z13.string().optional(), artist: z13.string().optional() }).loose().nullish()
16018
+ identified_track: z12.object({ title: z12.string().optional(), artist: z12.string().optional() }).loose().nullish()
15694
16019
  }).loose().optional(),
15695
- cast: z13.array(
15696
- z13.object({
15697
- id: z13.string().optional(),
15698
- description: z13.string().optional(),
16020
+ cast: z12.array(
16021
+ z12.object({
16022
+ id: z12.string().optional(),
16023
+ description: z12.string().optional(),
15699
16024
  // The deconstruct's note on the target-market localization (e.g. "native
15700
16025
  // French speaker") — read to derive the spoken-track language code.
15701
- market_localization_note: z13.string().optional()
16026
+ market_localization_note: z12.string().optional()
15702
16027
  }).loose()
15703
16028
  ).optional(),
15704
- voiceover: z13.object({
16029
+ voiceover: z12.object({
15705
16030
  // on_camera | mixed → mouths are on screen (lip-sync candidates);
15706
16031
  // voiceover | none → narration over the picture (no lip-sync).
15707
- mode: z13.string().optional(),
15708
- voice_description: z13.string().optional(),
15709
- persona: z13.string().optional()
16032
+ mode: z12.string().optional(),
16033
+ voice_description: z12.string().optional(),
16034
+ persona: z12.string().optional()
15710
16035
  }).loose().optional(),
15711
16036
  // Visual palette — read only to colour a clean brand-card/CTA plate (the
15712
16037
  // first hex is the dominant brand colour); never to drive frame generation.
15713
- style: z13.object({ palette: z13.array(z13.object({ hex: z13.string().optional() }).loose()).optional() }).loose().optional()
16038
+ style: z12.object({ palette: z12.array(z12.object({ hex: z12.string().optional() }).loose()).optional() }).loose().optional()
15714
16039
  }).loose().optional(),
15715
- scenes: z13.array(Scene).min(1)
16040
+ scenes: z12.array(Scene).min(1)
15716
16041
  }).loose();
15717
16042
  function injectHookPhysicality(blueprint) {
15718
16043
  for (const scene of blueprint.scenes) {
@@ -15722,26 +16047,26 @@ function injectHookPhysicality(blueprint) {
15722
16047
  scene.start_frame_prompt = `${prompt} The subject's physical state IS the scroll-stopper \u2014 render it explicitly, not a calm pose: ${why}.`;
15723
16048
  }
15724
16049
  }
15725
- var AppearsItem = z13.union([z13.number(), z13.object({ scene: z13.number(), edge: z13.string().optional() }).loose()]);
15726
- var RecurringElement = z13.object({
16050
+ var AppearsItem = z12.union([z12.number(), z12.object({ scene: z12.number(), edge: z12.string().optional() }).loose()]);
16051
+ var RecurringElement = z12.object({
15727
16052
  // person | animal | product | logo | badge | other
15728
- type: z13.string(),
15729
- label: z13.string().optional(),
15730
- description: z13.string().optional(),
15731
- expression: z13.string().nullable().optional(),
16053
+ type: z12.string(),
16054
+ label: z12.string().optional(),
16055
+ description: z12.string().optional(),
16056
+ expression: z12.string().nullable().optional(),
15732
16057
  // When the element maps to a global cast entry, its stable id (for annotation).
15733
- cast_id: z13.string().nullable().optional(),
16058
+ cast_id: z12.string().nullable().optional(),
15734
16059
  // The label of another element that is the SAME individual as this one, shown
15735
16060
  // in a DIFFERENT wardrobe/persona/state (e.g. one creator playing skeptic in a
15736
16061
  // pink shirt and believer in a white shirt). Each look gets its own reference
15737
16062
  // slot, but the face/identity must stay identical across them.
15738
- same_as: z13.string().nullable().optional(),
16063
+ same_as: z12.string().nullable().optional(),
15739
16064
  // Scenes the element appears in. Either a bare list of scene indices (both
15740
16065
  // edges) or per-{scene,edge} entries. Both forms are accepted and merged.
15741
- scenes: z13.array(z13.number()).optional(),
15742
- appears_in: z13.array(AppearsItem).optional()
16066
+ scenes: z12.array(z12.number()).optional(),
16067
+ appears_in: z12.array(AppearsItem).optional()
15743
16068
  }).loose();
15744
- var RecurringElements = z13.array(RecurringElement);
16069
+ var RecurringElements = z12.array(RecurringElement);
15745
16070
  function sanitizeId2(raw, fallback) {
15746
16071
  const id = raw.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
15747
16072
  return /^[a-z]/.test(id) ? id : `${fallback}_${id}`.replace(/_+$/g, "") || fallback;
@@ -16159,7 +16484,7 @@ function scrubFloatSentences(text, floatDescs) {
16159
16484
  return kept;
16160
16485
  }
16161
16486
  function sceneFloatDescs(scene) {
16162
- const floats = z13.array(FloatingElement).safeParse(scene.floating_elements ?? []);
16487
+ const floats = z12.array(FloatingElement).safeParse(scene.floating_elements ?? []);
16163
16488
  if (!floats.success) return [];
16164
16489
  return floats.data.map((f) => f.description?.trim() ?? "").filter(Boolean);
16165
16490
  }
@@ -17499,25 +17824,25 @@ function buildSfxMusic(blueprint, nodes) {
17499
17824
  }
17500
17825
  return tracks;
17501
17826
  }
17502
- var OverlayStyle = z13.object({ color_hex: z13.string().optional(), background: z13.string().optional(), size: z13.string().optional() }).loose();
17503
- var Overlay = z13.object({
17504
- text: z13.string().optional(),
17505
- appears_at_s: z13.number().optional(),
17506
- duration_s: z13.number().optional(),
17507
- position: z13.string().optional(),
17508
- role: z13.string().optional(),
17509
- animation: z13.string().optional(),
17510
- animation_detail: z13.string().optional(),
17827
+ var OverlayStyle = z12.object({ color_hex: z12.string().optional(), background: z12.string().optional(), size: z12.string().optional() }).loose();
17828
+ var Overlay = z12.object({
17829
+ text: z12.string().optional(),
17830
+ appears_at_s: z12.number().optional(),
17831
+ duration_s: z12.number().optional(),
17832
+ position: z12.string().optional(),
17833
+ role: z12.string().optional(),
17834
+ animation: z12.string().optional(),
17835
+ animation_detail: z12.string().optional(),
17511
17836
  style: OverlayStyle.optional()
17512
17837
  }).loose();
17513
- var FloatingElement = z13.object({
17514
- kind: z13.string().optional(),
17515
- description: z13.string().optional(),
17516
- brand_name: z13.string().nullish(),
17517
- what_it_represents: z13.string().optional(),
17518
- appears_at_s: z13.number().optional(),
17519
- duration_s: z13.number().optional(),
17520
- position: z13.string().optional()
17838
+ var FloatingElement = z12.object({
17839
+ kind: z12.string().optional(),
17840
+ description: z12.string().optional(),
17841
+ brand_name: z12.string().nullish(),
17842
+ what_it_represents: z12.string().optional(),
17843
+ appears_at_s: z12.number().optional(),
17844
+ duration_s: z12.number().optional(),
17845
+ position: z12.string().optional()
17521
17846
  }).loose();
17522
17847
  function escapeHtml(s) {
17523
17848
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
@@ -17549,7 +17874,7 @@ function positionClass(position) {
17549
17874
  function collectCaptions(blueprint) {
17550
17875
  return blueprint.scenes.flatMap((scene) => {
17551
17876
  const sceneStart = scene.start_s ?? 0;
17552
- const overlays = z13.array(Overlay).safeParse(scene.overlays ?? []);
17877
+ const overlays = z12.array(Overlay).safeParse(scene.overlays ?? []);
17553
17878
  return overlays.success ? overlays.data.filter((ov) => Boolean(ov.text?.trim())).map((ov) => {
17554
17879
  const at = ov.appears_at_s ?? sceneStart;
17555
17880
  return { text: ov.text.trim(), at, end: at + (ov.duration_s ?? 2.5), ov };
@@ -17629,7 +17954,7 @@ function collectFloatWindows(blueprint, uiRouted) {
17629
17954
  const windows = /* @__PURE__ */ new Map();
17630
17955
  blueprint.scenes.forEach((scene, i) => {
17631
17956
  const sceneStart = scene.start_s ?? 0;
17632
- const floats = z13.array(FloatingElement).safeParse(scene.floating_elements ?? []);
17957
+ const floats = z12.array(FloatingElement).safeParse(scene.floating_elements ?? []);
17633
17958
  if (!floats.success) return;
17634
17959
  for (const fe of floats.data) {
17635
17960
  const at = fe.appears_at_s ?? sceneStart;
@@ -18015,8 +18340,8 @@ function buildMotionBoard(blueprint) {
18015
18340
  const end_s = scene.end_s ?? start_s + sceneDurationS(scene);
18016
18341
  cursor = end_s;
18017
18342
  const spoken = sceneSpokenText(scene);
18018
- const overlays = z13.array(Overlay).safeParse(scene.overlays ?? []);
18019
- const floats = z13.array(FloatingElement).safeParse(scene.floating_elements ?? []);
18343
+ const overlays = z12.array(Overlay).safeParse(scene.overlays ?? []);
18344
+ const floats = z12.array(FloatingElement).safeParse(scene.floating_elements ?? []);
18020
18345
  const graphics = [
18021
18346
  ...(overlays.success ? overlays.data : []).filter((ov) => ov.text?.trim()).map((ov) => ({
18022
18347
  kind: "text",
@@ -18243,23 +18568,23 @@ function videoReport(input, elementsInput) {
18243
18568
 
18244
18569
  // src/commands/canvas/composition-path.ts
18245
18570
  import { existsSync as existsSync3 } from "fs";
18246
- import path7 from "path";
18571
+ import path9 from "path";
18247
18572
  function resolveShippedCanvasDir(name, startDir, exists = existsSync3, maxDepth = 8) {
18248
- const rel = path7.join("canvas", name);
18573
+ const rel = path9.join("canvas", name);
18249
18574
  let dir = startDir;
18250
18575
  for (let i = 0; i < maxDepth; i++) {
18251
- const candidate = path7.join(dir, rel);
18252
- if (exists(path7.join(candidate, "meta.json"))) return candidate;
18253
- const parent = path7.dirname(dir);
18576
+ const candidate = path9.join(dir, rel);
18577
+ if (exists(path9.join(candidate, "meta.json"))) return candidate;
18578
+ const parent = path9.dirname(dir);
18254
18579
  if (parent === dir) break;
18255
18580
  dir = parent;
18256
18581
  }
18257
- return path7.resolve(startDir, "../../../", rel);
18582
+ return path9.resolve(startDir, "../../../", rel);
18258
18583
  }
18259
18584
 
18260
18585
  // src/commands/canvas/gitignore.ts
18261
18586
  import { appendFile, readFile as readFile5 } from "fs/promises";
18262
- import path8 from "path";
18587
+ import path10 from "path";
18263
18588
  function missingGitignoreEntries(existing, entries) {
18264
18589
  const present = new Set(
18265
18590
  existing.split("\n").map((l) => l.trim().replace(/\/+$/, "")).filter((l) => l.length > 0 && !l.startsWith("#"))
@@ -18267,7 +18592,7 @@ function missingGitignoreEntries(existing, entries) {
18267
18592
  return entries.filter((e) => !present.has(e.trim().replace(/\/+$/, "")));
18268
18593
  }
18269
18594
  async function ensureGitignore(dir, entries) {
18270
- const file = path8.join(dir, ".gitignore");
18595
+ const file = path10.join(dir, ".gitignore");
18271
18596
  let existing;
18272
18597
  try {
18273
18598
  existing = await readFile5(file, "utf8");
@@ -18328,7 +18653,7 @@ async function loadTranscriptBestEffort(ref) {
18328
18653
  async function stageCaptions(outDir, transcript) {
18329
18654
  const text = transcript?.trim();
18330
18655
  if (!text || text === "[]") return {};
18331
- const compositionPath = path9.join(outDir, "tiktok-captions-composition");
18656
+ const compositionPath = path11.join(outDir, "tiktok-captions-composition");
18332
18657
  await cp(SHIPPED_CAPTIONS_DIR, compositionPath, { recursive: true });
18333
18658
  return { compositionPath };
18334
18659
  }
@@ -18346,10 +18671,10 @@ function patchCompositionHtml(html, dims) {
18346
18671
  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`);
18347
18672
  }
18348
18673
  async function stampCompositionDims(compositionDir, dims) {
18349
- const metaPath = path9.join(compositionDir, "meta.json");
18674
+ const metaPath = path11.join(compositionDir, "meta.json");
18350
18675
  const rawMeta = await readFile6(metaPath, "utf8");
18351
18676
  await writeFile2(metaPath, patchCompositionMeta(rawMeta, dims), "utf8");
18352
- const htmlPath = path9.join(compositionDir, "index.html");
18677
+ const htmlPath = path11.join(compositionDir, "index.html");
18353
18678
  const rawHtml = await readFile6(htmlPath, "utf8");
18354
18679
  await writeFile2(htmlPath, patchCompositionHtml(rawHtml, dims), "utf8");
18355
18680
  }
@@ -18489,6 +18814,10 @@ var scaffoldVideoCommand = defineCommand90({
18489
18814
  args: {
18490
18815
  file: { type: "positional", required: true, description: "Path to the reference video" },
18491
18816
  out: { type: "string", description: "Output canvas path (default <video-dir>/<name>.video.canvas.json)" },
18817
+ slug: {
18818
+ type: "string",
18819
+ description: "Creative slug \u2014 writes the canvas to src/creatives/<slug>/<slug>.canvas.json (repo convention)"
18820
+ },
18492
18821
  frames: { type: "string", description: '"generate" (default, anchored regen) or "reuse" (wire real frames in)' },
18493
18822
  ambient: {
18494
18823
  type: "boolean",
@@ -18515,11 +18844,19 @@ var scaffoldVideoCommand = defineCommand90({
18515
18844
  }
18516
18845
  },
18517
18846
  async run({ args }) {
18518
- const videoPath = path9.resolve(String(args.file));
18519
- const base = path9.basename(videoPath, path9.extname(videoPath));
18520
- const outPath = args.out ? path9.resolve(String(args.out)) : path9.join(path9.dirname(videoPath), `${base}.video.canvas.json`);
18521
- const outDir = path9.dirname(outPath);
18522
- const blueprintPath = path9.join(outDir, "prompt.json");
18847
+ const videoPath = path11.resolve(String(args.file));
18848
+ const base = path11.basename(videoPath, path11.extname(videoPath));
18849
+ const slug = args.slug ? String(args.slug) : void 0;
18850
+ if (slug && !isValidScaffoldSlug(slug)) {
18851
+ process.stderr.write(
18852
+ `${JSON.stringify({ ok: false, error: { code: "invalid_slug", message: "--slug must be lowercase kebab (a-z, 0-9, hyphens), max 100 chars" } }, null, 2)}
18853
+ `
18854
+ );
18855
+ process.exit(2);
18856
+ }
18857
+ 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`);
18858
+ const outDir = path11.dirname(outPath);
18859
+ const blueprintPath = path11.join(outDir, "prompt.json");
18523
18860
  const frames = args.frames === "reuse" ? "reuse" : "generate";
18524
18861
  const maxScenes = args["max-scenes"] ? Number(args["max-scenes"]) : void 0;
18525
18862
  if (Number.isFinite(maxScenes)) {
@@ -18538,7 +18875,7 @@ var scaffoldVideoCommand = defineCommand90({
18538
18875
  shotCuts
18539
18876
  });
18540
18877
  const { blueprint, elements, transcript, creditsSpent } = await runAnalysisPasses(deconstructCanvas, selectModel);
18541
- await mkdir(outDir, { recursive: true });
18878
+ await mkdir2(outDir, { recursive: true });
18542
18879
  const annotated = annotateBlueprintWithElements(blueprint, elements);
18543
18880
  await writeFile2(blueprintPath, `${JSON.stringify(annotated, null, 2)}
18544
18881
  `, "utf8");
@@ -18559,10 +18896,10 @@ var scaffoldVideoCommand = defineCommand90({
18559
18896
  `
18560
18897
  );
18561
18898
  }
18562
- const compositionDest = path9.join(outDir, "video-overlay-composition");
18899
+ const compositionDest = path11.join(outDir, "video-overlay-composition");
18563
18900
  await cp(SHIPPED_COMPOSITION_DIR, compositionDest, { recursive: true });
18564
18901
  await stampCompositionDims(compositionDest, outDims);
18565
- const indexPath = path9.join(compositionDest, "index.html");
18902
+ const indexPath = path11.join(compositionDest, "index.html");
18566
18903
  const overlayHtml = buildOverlayHtml(blueprint, { captionsActive: Boolean(transcript) });
18567
18904
  const indexHtml = await readFile6(indexPath, "utf8");
18568
18905
  const injected = indexHtml.replace("<!--OVERLAYS-->", () => overlayHtml);
@@ -18578,9 +18915,9 @@ var scaffoldVideoCommand = defineCommand90({
18578
18915
  const opts = {
18579
18916
  imageModel,
18580
18917
  videoModel,
18581
- overlayCompositionPath: path9.relative(outDir, compositionDest),
18582
- captionsCompositionPath: captions.compositionPath ? path9.relative(outDir, captions.compositionPath) : void 0,
18583
- blueprintPath: path9.relative(outDir, blueprintPath),
18918
+ overlayCompositionPath: path11.relative(outDir, compositionDest),
18919
+ captionsCompositionPath: captions.compositionPath ? path11.relative(outDir, captions.compositionPath) : void 0,
18920
+ blueprintPath: path11.relative(outDir, blueprintPath),
18584
18921
  frames,
18585
18922
  ambient: Boolean(args.ambient),
18586
18923
  ...args.aspect ? { aspect: String(args.aspect) } : {},
@@ -18638,7 +18975,7 @@ var scaffoldVideoCommand = defineCommand90({
18638
18975
  run_estimated_credits: validation.estimatedCredits
18639
18976
  },
18640
18977
  checklist: {
18641
- 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.`,
18978
+ 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.`,
18642
18979
  recurring_elements_to_supply: report.elements,
18643
18980
  voices_to_confirm: report.dialogue.map((d) => ({
18644
18981
  scene: d.scene,
@@ -18665,7 +19002,7 @@ var scaffoldVideoCommand = defineCommand90({
18665
19002
 
18666
19003
  // src/commands/canvas/set-prompt.ts
18667
19004
  import { readFile as readFile7, writeFile as writeFile3 } from "fs/promises";
18668
- import path10 from "path";
19005
+ import path12 from "path";
18669
19006
  import { defineCommand as defineCommand91 } from "citty";
18670
19007
  function setNodePrompt(canvas, nodeId, text) {
18671
19008
  const nodes = canvas?.nodes;
@@ -18693,7 +19030,7 @@ var setPromptCommand = defineCommand91({
18693
19030
  "text-file": { type: "string", description: "Read the new prompt from a UTF-8 file (preserves accents/newlines)" }
18694
19031
  },
18695
19032
  async run({ args }) {
18696
- const filePath = path10.resolve(String(args.file));
19033
+ const filePath = path12.resolve(String(args.file));
18697
19034
  let canvas;
18698
19035
  try {
18699
19036
  canvas = JSON.parse(await readFile7(filePath, "utf8"));
@@ -18703,7 +19040,7 @@ var setPromptCommand = defineCommand91({
18703
19040
  process.exit(2);
18704
19041
  }
18705
19042
  let text;
18706
- if (args["text-file"]) text = await readFile7(path10.resolve(String(args["text-file"])), "utf8");
19043
+ if (args["text-file"]) text = await readFile7(path12.resolve(String(args["text-file"])), "utf8");
18707
19044
  else if (args.text !== void 0) text = String(args.text);
18708
19045
  else {
18709
19046
  process.stderr.write(
@@ -18724,7 +19061,7 @@ var setPromptCommand = defineCommand91({
18724
19061
  process.exit(2);
18725
19062
  return;
18726
19063
  }
18727
- const validation = await validateCanvasDeep(resolveRelativeCanvasPaths(updated, path10.dirname(filePath)), defaultRegistry());
19064
+ const validation = await validateCanvasDeep(resolveRelativeCanvasPaths(updated, path12.dirname(filePath)), defaultRegistry());
18728
19065
  if (!validation.ok) {
18729
19066
  process.stderr.write(`${JSON.stringify({ ok: false, error: { code: "validation", issues: validation.issues } }, null, 2)}
18730
19067
  `);
@@ -18740,7 +19077,7 @@ var setPromptCommand = defineCommand91({
18740
19077
 
18741
19078
  // src/commands/canvas/validate.ts
18742
19079
  import { readFile as readFile8 } from "fs/promises";
18743
- import path11 from "path";
19080
+ import path13 from "path";
18744
19081
  import { defineCommand as defineCommand92 } from "citty";
18745
19082
  var validateCommand = defineCommand92({
18746
19083
  meta: {
@@ -18749,7 +19086,7 @@ var validateCommand = defineCommand92({
18749
19086
  },
18750
19087
  args: { file: { type: "positional", required: true, description: "Path to canvas JSON" } },
18751
19088
  async run({ args }) {
18752
- const filePath = path11.resolve(String(args.file));
19089
+ const filePath = path13.resolve(String(args.file));
18753
19090
  const raw = await readFile8(filePath, "utf8");
18754
19091
  let parsed;
18755
19092
  try {
@@ -18760,7 +19097,7 @@ var validateCommand = defineCommand92({
18760
19097
  `);
18761
19098
  process.exit(2);
18762
19099
  }
18763
- parsed = resolveRelativeCanvasPaths(parsed, path11.dirname(filePath));
19100
+ parsed = resolveRelativeCanvasPaths(parsed, path13.dirname(filePath));
18764
19101
  const result = await validateCanvasDeep(parsed, defaultRegistry());
18765
19102
  if (!result.ok) {
18766
19103
  process.stderr.write(`${JSON.stringify({ ok: false, issues: result.issues }, null, 2)}
@@ -18897,6 +19234,16 @@ registerSchema({
18897
19234
  type: "string",
18898
19235
  description: "Optional URL of the original reference ad",
18899
19236
  required: false
19237
+ },
19238
+ slug: {
19239
+ type: "string",
19240
+ description: "Creative slug (src/creatives/<slug>/) \u2014 attaches the image to that creative's row",
19241
+ required: false
19242
+ },
19243
+ runId: {
19244
+ type: "string",
19245
+ description: "Canvas run id (r_\u2026) of the approved generation to pin as published",
19246
+ required: false
18900
19247
  }
18901
19248
  }
18902
19249
  });
@@ -18906,6 +19253,13 @@ function detectCreativeContentType(filePath) {
18906
19253
  unsupportedMessage: "Unsupported creative image extension. Use PNG, JPG, or WebP."
18907
19254
  });
18908
19255
  }
19256
+ function chatIdFromEnv() {
19257
+ try {
19258
+ return getEnv().BAKER_CHAT_ID || void 0;
19259
+ } catch {
19260
+ return void 0;
19261
+ }
19262
+ }
18909
19263
  function parseOptionalUrl(value) {
18910
19264
  if (value === void 0 || value.trim() === "") {
18911
19265
  return void 0;
@@ -18936,7 +19290,11 @@ async function publishCreative(args, deps = defaultImageApiDeps) {
18936
19290
  return publishImageAsCreative(deps, {
18937
19291
  imageId: upload.imageId,
18938
19292
  title,
18939
- sourceReferenceUrl
19293
+ sourceReferenceUrl,
19294
+ slug: args.slug,
19295
+ runId: args.runId,
19296
+ // Attribute the publish to the driving chat (injected by the bridge).
19297
+ chatId: chatIdFromEnv()
18940
19298
  });
18941
19299
  }
18942
19300
  var publishCommand = defineCommand94({
@@ -18952,6 +19310,16 @@ var publishCommand = defineCommand94({
18952
19310
  type: "string",
18953
19311
  description: "Optional URL of the original reference ad",
18954
19312
  required: false
19313
+ },
19314
+ slug: {
19315
+ type: "string",
19316
+ description: "Creative slug (src/creatives/<slug>/) \u2014 attaches the image to that creative's row",
19317
+ required: false
19318
+ },
19319
+ runId: {
19320
+ type: "string",
19321
+ description: "Canvas run id (r_\u2026) of the approved generation to pin as published",
19322
+ required: false
18955
19323
  }
18956
19324
  },
18957
19325
  run: async ({ args }) => {
@@ -18970,7 +19338,9 @@ var publishCommand = defineCommand94({
18970
19338
  file,
18971
19339
  title,
18972
19340
  context: args.context,
18973
- sourceReferenceUrl: args.sourceReferenceUrl
19341
+ sourceReferenceUrl: args.sourceReferenceUrl,
19342
+ slug: args.slug,
19343
+ runId: args.runId
18974
19344
  });
18975
19345
  writeJson({ ok: true, data });
18976
19346
  } catch (err) {
@@ -19868,9 +20238,9 @@ async function readImageBuffer(pathOrUrl) {
19868
20238
  }
19869
20239
  return readFile10(pathOrUrl);
19870
20240
  }
19871
- async function isDirectory(path12) {
20241
+ async function isDirectory(path14) {
19872
20242
  try {
19873
- const s = await stat2(path12);
20243
+ const s = await stat2(path14);
19874
20244
  return s.isDirectory();
19875
20245
  } catch {
19876
20246
  return false;
@@ -23932,130 +24302,11 @@ var schemaCommand = defineCommand147({
23932
24302
  }
23933
24303
  });
23934
24304
 
23935
- // src/commands/tags/index.ts
23936
- import { defineCommand as defineCommand148 } from "citty";
23937
-
23938
- // src/commands/tags/shared.ts
23939
- function failApi3(err) {
23940
- if (err instanceof ApiError) {
23941
- writeJson({ ok: false, error: { code: err.code, message: err.message } });
23942
- process.exit(1);
23943
- }
23944
- if (err instanceof Error) {
23945
- writeJson({ ok: false, error: { code: "INTERNAL_ERROR", message: err.message } });
23946
- process.exit(1);
23947
- }
23948
- writeJson({ ok: false, error: { code: "INTERNAL_ERROR", message: "Unexpected error" } });
23949
- process.exit(1);
23950
- }
23951
- function renderConfigValue(value) {
23952
- return value.includes("\n") ? value.replace(/\n/g, "\n ") : value;
23953
- }
23954
- function renderEffectiveEntry(entry) {
23955
- const parts = [entry.ref, entry.type];
23956
- if (entry.identifier !== void 0) {
23957
- parts.push(entry.identifier);
23958
- }
23959
- if (entry.staged !== void 0) {
23960
- parts.push(`[staged: ${entry.staged}]`);
23961
- }
23962
- const secretBits = [
23963
- ...entry.secretsSet.map((field) => `${field} \u2713 set`),
23964
- ...entry.secretsPending.map((field) => `${field} \u23F3 pending`)
23965
- ];
23966
- if (secretBits.length > 0) {
23967
- parts.push(`[secrets: ${secretBits.join(", ")}]`);
23968
- }
23969
- const header = parts.join(" ");
23970
- const identifyingField = TAG_IDENTIFYING_FIELD[entry.type];
23971
- const configLines = Object.entries(entry.config).filter(([key]) => key !== identifyingField).map(([key, value]) => ` ${key}: ${renderConfigValue(value)}`);
23972
- return configLines.length > 0 ? `${header}
23973
- ${configLines.join("\n")}` : header;
23974
- }
23975
-
23976
- // src/commands/tags/index.ts
23977
- registerSchema({
23978
- command: "tags.list",
23979
- description: "Effective marketing tags for this chat: production tags overlaid with the changes staged in this chat. Prints each tag's readable config in full (secrets are never included) \u2014 e.g. the Clarity projectId, GA4 measurementId, or the entire custom `code` snippet \u2014 so reuse a stored value to pre-fill a follow-up change instead of asking the user for something we already have. 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.",
23980
- args: {
23981
- json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list", required: false }
23982
- }
23983
- });
23984
- async function listTags(json) {
23985
- try {
23986
- const chatId = requireChatId();
23987
- const response = await apiPost("/api/tags/list", { chatId });
23988
- if (json) {
23989
- writeJson({ ok: true, data: response });
23990
- return;
23991
- }
23992
- if (response.tags.length === 0) {
23993
- process.stdout.write("No tags configured. Propose one with the request_tag_input tool (baker_ui).\n");
23994
- return;
23995
- }
23996
- process.stdout.write(`${response.tags.map(renderEffectiveEntry).join("\n")}
23997
- `);
23998
- } catch (err) {
23999
- failApi3(err);
24000
- }
24001
- }
24002
- var listCommand7 = defineCommand148({
24003
- meta: {
24004
- name: "list",
24005
- description: "Effective tags for this chat (production + staged), with each tag's full readable config (secrets excluded) \u2014 reuse a stored value to pre-fill a change rather than asking the user. Refs printed here are what flow side-effect tagIds should use. Example: baker tags list"
24006
- },
24007
- args: { json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list" } },
24008
- run: async ({ args }) => {
24009
- await listTags(args.json === true);
24010
- }
24011
- });
24012
- async function listDraft3() {
24013
- try {
24014
- const chatId = requireChatId();
24015
- const response = await apiPost("/api/tags/draft", { chatId });
24016
- writeJson({ ok: true, data: response });
24017
- } catch (err) {
24018
- failApi3(err);
24019
- }
24020
- }
24021
- var draftCommand3 = defineCommand148({
24022
- meta: {
24023
- name: "draft",
24024
- 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)."
24025
- },
24026
- run: async () => {
24027
- await listDraft3();
24028
- }
24029
- });
24030
- var tagsCommand3 = defineCommand148({
24031
- meta: {
24032
- name: "tags",
24033
- 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.
24034
-
24035
- 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.
24036
-
24037
- 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.
24038
-
24039
- \`baker tags list\` prints each tag's readable config in full (secrets excluded) \u2014 the Clarity projectId, GA4 measurementId, the whole custom \`code\` snippet, etc. Reuse a stored value to pre-fill a follow-up change instead of asking the user for something already installed.
24040
-
24041
- Examples:
24042
- baker tags list # production + staged, full readable config + secret status
24043
- baker tags draft # review the staged changes awaiting publish`
24044
- },
24045
- subCommands: {
24046
- list: listCommand7,
24047
- draft: draftCommand3
24048
- },
24049
- run: async () => {
24050
- await listTags(false);
24051
- }
24052
- });
24053
-
24054
24305
  // src/commands/testimonials/index.ts
24055
- import { defineCommand as defineCommand152 } from "citty";
24306
+ import { defineCommand as defineCommand151 } from "citty";
24056
24307
 
24057
24308
  // src/commands/testimonials/get.ts
24058
- import { defineCommand as defineCommand149 } from "citty";
24309
+ import { defineCommand as defineCommand148 } from "citty";
24059
24310
  registerSchema({
24060
24311
  command: "testimonials.get",
24061
24312
  description: "Get a single testimonial by ID",
@@ -24063,7 +24314,7 @@ registerSchema({
24063
24314
  id: { type: "string", description: "Testimonial ID", required: true }
24064
24315
  }
24065
24316
  });
24066
- var getCommand4 = defineCommand149({
24317
+ var getCommand4 = defineCommand148({
24067
24318
  meta: { name: "get", description: "Get a single testimonial by ID. Example: baker testimonials get j571abc123" },
24068
24319
  args: {
24069
24320
  id: { type: "positional", description: "Testimonial ID", required: false },
@@ -24100,7 +24351,7 @@ var getCommand4 = defineCommand149({
24100
24351
  });
24101
24352
 
24102
24353
  // src/commands/testimonials/list.ts
24103
- import { defineCommand as defineCommand150 } from "citty";
24354
+ import { defineCommand as defineCommand149 } from "citty";
24104
24355
  registerSchema({
24105
24356
  command: "testimonials.list",
24106
24357
  description: "List testimonials with optional filters.",
@@ -24130,7 +24381,7 @@ registerSchema({
24130
24381
  limit: { type: "number", description: "Max results (default 50)", required: false, default: 50 }
24131
24382
  }
24132
24383
  });
24133
- var listCommand8 = defineCommand150({
24384
+ var listCommand7 = defineCommand149({
24134
24385
  meta: {
24135
24386
  name: "list",
24136
24387
  description: "List testimonials with optional filters. Example: baker testimonials list --source google --sentiment positive"
@@ -24179,7 +24430,7 @@ var listCommand8 = defineCommand150({
24179
24430
  });
24180
24431
 
24181
24432
  // src/commands/testimonials/search.ts
24182
- import { defineCommand as defineCommand151 } from "citty";
24433
+ import { defineCommand as defineCommand150 } from "citty";
24183
24434
  registerSchema({
24184
24435
  command: "testimonials.search",
24185
24436
  description: "Search testimonials by text query. Uses hybrid BM25 + vector + reranking.",
@@ -24210,7 +24461,7 @@ registerSchema({
24210
24461
  tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
24211
24462
  }
24212
24463
  });
24213
- var searchCommand2 = defineCommand151({
24464
+ var searchCommand2 = defineCommand150({
24214
24465
  meta: {
24215
24466
  name: "search",
24216
24467
  description: "Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4"
@@ -24281,10 +24532,10 @@ var searchCommand2 = defineCommand151({
24281
24532
  });
24282
24533
 
24283
24534
  // src/commands/testimonials/tags.ts
24284
- var tagsCommand4 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
24535
+ var tagsCommand3 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
24285
24536
 
24286
24537
  // src/commands/testimonials/index.ts
24287
- var testimonialsCommand = defineCommand152({
24538
+ var testimonialsCommand = defineCommand151({
24288
24539
  meta: {
24289
24540
  name: "testimonials",
24290
24541
  description: `Find and browse testimonials in Baker. Subcommands: search, get, list, tags.
@@ -24299,16 +24550,16 @@ Examples:
24299
24550
  subCommands: {
24300
24551
  get: getCommand4,
24301
24552
  search: searchCommand2,
24302
- list: listCommand8,
24303
- tags: tagsCommand4
24553
+ list: listCommand7,
24554
+ tags: tagsCommand3
24304
24555
  }
24305
24556
  });
24306
24557
 
24307
24558
  // src/commands/videos/index.ts
24308
- import { defineCommand as defineCommand157 } from "citty";
24559
+ import { defineCommand as defineCommand156 } from "citty";
24309
24560
 
24310
24561
  // src/commands/videos/delete.ts
24311
- import { defineCommand as defineCommand153 } from "citty";
24562
+ import { defineCommand as defineCommand152 } from "citty";
24312
24563
  registerSchema({
24313
24564
  command: "videos.delete",
24314
24565
  description: "Delete a video by ID",
@@ -24322,7 +24573,7 @@ registerSchema({
24322
24573
  }
24323
24574
  }
24324
24575
  });
24325
- var deleteCommand3 = defineCommand153({
24576
+ var deleteCommand3 = defineCommand152({
24326
24577
  meta: {
24327
24578
  name: "delete",
24328
24579
  description: "Delete a video by ID. Use --dry-run to preview. Example: baker videos delete j571abc123 --dry-run"
@@ -24363,7 +24614,7 @@ var deleteCommand3 = defineCommand153({
24363
24614
  });
24364
24615
 
24365
24616
  // src/commands/videos/get.ts
24366
- import { defineCommand as defineCommand154 } from "citty";
24617
+ import { defineCommand as defineCommand153 } from "citty";
24367
24618
  registerSchema({
24368
24619
  command: "videos.get",
24369
24620
  description: "Get a single video by ID",
@@ -24371,7 +24622,7 @@ registerSchema({
24371
24622
  id: { type: "string", description: "Video ID", required: true }
24372
24623
  }
24373
24624
  });
24374
- var getCommand5 = defineCommand154({
24625
+ var getCommand5 = defineCommand153({
24375
24626
  meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
24376
24627
  args: {
24377
24628
  id: { type: "positional", description: "Video ID", required: false },
@@ -24408,7 +24659,7 @@ var getCommand5 = defineCommand154({
24408
24659
  });
24409
24660
 
24410
24661
  // src/commands/videos/search.ts
24411
- import { defineCommand as defineCommand155 } from "citty";
24662
+ import { defineCommand as defineCommand154 } from "citty";
24412
24663
  registerSchema({
24413
24664
  command: "videos.search",
24414
24665
  description: "Search videos by text query. Only returns ready videos.",
@@ -24418,7 +24669,7 @@ registerSchema({
24418
24669
  tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
24419
24670
  }
24420
24671
  });
24421
- var searchCommand3 = defineCommand155({
24672
+ var searchCommand3 = defineCommand154({
24422
24673
  meta: {
24423
24674
  name: "search",
24424
24675
  description: "Semantic search videos by text query. Uses hybrid BM25 + vector + reranking. Example: baker videos search 'product demo' --tags tutorial"
@@ -24465,12 +24716,12 @@ var searchCommand3 = defineCommand155({
24465
24716
  });
24466
24717
 
24467
24718
  // src/commands/videos/tags.ts
24468
- var tagsCommand5 = makeTagsCommand("videos", "video", "/api/videos/tags");
24719
+ var tagsCommand4 = makeTagsCommand("videos", "video", "/api/videos/tags");
24469
24720
 
24470
24721
  // src/commands/videos/upload.ts
24471
24722
  import { readFile as readFile12, stat as stat3 } from "fs/promises";
24472
24723
  import { extname as extname3 } from "path";
24473
- import { defineCommand as defineCommand156 } from "citty";
24724
+ import { defineCommand as defineCommand155 } from "citty";
24474
24725
  var MIME_MAP = {
24475
24726
  ".mp4": "video/mp4",
24476
24727
  ".mov": "video/quicktime",
@@ -24504,7 +24755,7 @@ function detectContentType(filePath) {
24504
24755
  }
24505
24756
  return mime;
24506
24757
  }
24507
- var uploadCommand2 = defineCommand156({
24758
+ var uploadCommand2 = defineCommand155({
24508
24759
  meta: {
24509
24760
  name: "upload",
24510
24761
  description: "Upload a video file to Baker via Mux direct upload. Auto-detects content type. Example: baker videos upload ./demo.mp4"
@@ -24558,7 +24809,7 @@ var uploadCommand2 = defineCommand156({
24558
24809
  });
24559
24810
 
24560
24811
  // src/commands/videos/index.ts
24561
- var videosCommand = defineCommand157({
24812
+ var videosCommand = defineCommand156({
24562
24813
  meta: {
24563
24814
  name: "videos",
24564
24815
  description: `Find and manage videos in Baker. Subcommands: search, get, upload, delete, tags.
@@ -24576,15 +24827,15 @@ Examples:
24576
24827
  search: searchCommand3,
24577
24828
  upload: uploadCommand2,
24578
24829
  delete: deleteCommand3,
24579
- tags: tagsCommand5
24830
+ tags: tagsCommand4
24580
24831
  }
24581
24832
  });
24582
24833
 
24583
24834
  // src/commands/winning-ads/index.ts
24584
- import { defineCommand as defineCommand160 } from "citty";
24835
+ import { defineCommand as defineCommand159 } from "citty";
24585
24836
 
24586
24837
  // src/commands/winning-ads/advertisers.ts
24587
- import { defineCommand as defineCommand158 } from "citty";
24838
+ import { defineCommand as defineCommand157 } from "citty";
24588
24839
  registerSchema({
24589
24840
  command: "winning-ads.advertisers",
24590
24841
  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).",
@@ -24597,7 +24848,7 @@ registerSchema({
24597
24848
  function identity(record) {
24598
24849
  return record;
24599
24850
  }
24600
- var advertisersCommand2 = defineCommand158({
24851
+ var advertisersCommand2 = defineCommand157({
24601
24852
  meta: {
24602
24853
  name: "advertisers",
24603
24854
  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'
@@ -24648,7 +24899,7 @@ var advertisersCommand2 = defineCommand158({
24648
24899
  });
24649
24900
 
24650
24901
  // src/commands/winning-ads/search.ts
24651
- import { defineCommand as defineCommand159 } from "citty";
24902
+ import { defineCommand as defineCommand158 } from "citty";
24652
24903
  registerSchema({
24653
24904
  command: "winning-ads.search",
24654
24905
  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.",
@@ -24756,7 +25007,7 @@ function buildSearchBody(args) {
24756
25007
  }
24757
25008
  return body;
24758
25009
  }
24759
- var searchCommand4 = defineCommand159({
25010
+ var searchCommand4 = defineCommand158({
24760
25011
  meta: {
24761
25012
  name: "search",
24762
25013
  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"
@@ -24868,7 +25119,7 @@ var searchCommand4 = defineCommand159({
24868
25119
  });
24869
25120
 
24870
25121
  // src/commands/winning-ads/index.ts
24871
- var winningAdsCommand = defineCommand160({
25122
+ var winningAdsCommand = defineCommand159({
24872
25123
  meta: {
24873
25124
  name: "winning-ads",
24874
25125
  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.
@@ -24908,11 +25159,11 @@ function getCliVersion() {
24908
25159
  }
24909
25160
 
24910
25161
  // src/cli.ts
24911
- var main = defineCommand161({
25162
+ var main = defineCommand160({
24912
25163
  meta: {
24913
25164
  name: "baker",
24914
25165
  version: getCliVersion(),
24915
- description: `AI-agent CLI for finding and managing images, videos, testimonials, action items, scheduled actions, marketing tags, and ad platform data in Baker.
25166
+ description: `AI-agent CLI for finding and managing images, videos, testimonials, action items, scheduled actions, and ad platform data in Baker.
24916
25167
 
24917
25168
  Auth: Set BAKER_API_KEY (starts with bk_) and BAKER_API_URL environment variables.
24918
25169
  Chat: Set BAKER_CHAT_ID for action and scheduled-action commands that stage changes against a chat.
@@ -24932,7 +25183,6 @@ Introspection: Run 'baker schema <command>' to inspect argument schemas.`
24932
25183
  videos: videosCommand,
24933
25184
  testimonials: testimonialsCommand,
24934
25185
  canvas: canvasCommand,
24935
- tags: tagsCommand3,
24936
25186
  "winning-ads": winningAdsCommand,
24937
25187
  mcp: mcpCommand,
24938
25188
  schema: schemaCommand