@productmaker/mcp 11.1.0 → 11.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/http.js +1835 -929
  2. package/dist/stdio.js +1824 -918
  3. package/package.json +1 -1
package/dist/stdio.js CHANGED
@@ -1457,6 +1457,7 @@ function requireKieImageId(ids, index, label) {
1457
1457
  }
1458
1458
  __name(requireKieImageId, "requireKieImageId");
1459
1459
  var KIE_FLARE_IMAGE_TO_IMAGE_MODEL = requireKieImageId(GPT_IMAGE_2_5.kie.imageToImage, 1, "flare-imageToImage");
1460
+ var KIE_FLARE_TEXT_TO_IMAGE_MODEL = requireKieImageId(GPT_IMAGE_2_5.kie.textToImage, 1, "flare-textToImage");
1460
1461
  function canonicalImageModelInput(raw) {
1461
1462
  if (raw === void 0) return void 0;
1462
1463
  const token = resolveImageToken(raw);
@@ -6339,6 +6340,7 @@ var BillingRecordInput = z31.object({
6339
6340
  taskId: z31.string().uuid().optional(),
6340
6341
  mixTaskId: z31.string().uuid().optional(),
6341
6342
  productResearchRunId: z31.string().uuid().optional(),
6343
+ servicePageId: z31.string().uuid().optional(),
6342
6344
  provider: BillingProvider,
6343
6345
  label: z31.string().optional(),
6344
6346
  units: z31.number().int().nonnegative().optional(),
@@ -6349,7 +6351,8 @@ var BillingRecordInput = z31.object({
6349
6351
  const scopedIds = [
6350
6352
  value.taskId,
6351
6353
  value.mixTaskId,
6352
- value.productResearchRunId
6354
+ value.productResearchRunId,
6355
+ value.servicePageId
6353
6356
  ].filter(Boolean);
6354
6357
  if (scopedIds.length > 1) {
6355
6358
  ctx.addIssue({
@@ -19751,137 +19754,1040 @@ var StoredLandingDirectorSchema = z89.object({
19751
19754
  }))
19752
19755
  });
19753
19756
 
19754
- // ../../packages/types/src/flight-recorder.ts
19757
+ // ../../packages/types/src/service-landing-artifact.ts
19758
+ import { z as z91 } from "zod";
19759
+
19760
+ // ../../packages/types/src/service-landing-primitives.ts
19755
19761
  import { z as z90 } from "zod";
19756
- var FlightRecorderGenerationTypeSchema = z90.enum([
19762
+ var OptionalTextSchema = z90.string().trim().min(1).max(500).optional();
19763
+ var AssetIdSchema = z90.string().uuid().transform((value) => value.toLowerCase());
19764
+ var ServiceLandingPrimaryCtaSchema = z90.object({
19765
+ channelIndex: z90.number().int().nonnegative(),
19766
+ label: z90.string().trim().min(1).max(80)
19767
+ }).strict();
19768
+
19769
+ // ../../packages/types/src/service-landing-artifact.ts
19770
+ var SERVICE_LANDING_SCHEMA_VERSION = 1;
19771
+ var SERVICE_LANDING_CATALOG_VERSION = 1;
19772
+ var SERVICE_LANDING_LAYOUTS = [
19773
+ "editorial",
19774
+ "studio",
19775
+ "professional"
19776
+ ];
19777
+ var SERVICE_LANDING_PALETTES = [
19778
+ "light",
19779
+ "dark",
19780
+ "sand",
19781
+ "sage",
19782
+ "ocean"
19783
+ ];
19784
+ var SERVICE_LANDING_MOTION = [
19785
+ "none",
19786
+ "fade"
19787
+ ];
19788
+ var SERVICE_LANDING_SECTION_VARIANTS = {
19789
+ hero: [
19790
+ "centered",
19791
+ "split"
19792
+ ],
19793
+ services: [
19794
+ "cards",
19795
+ "list"
19796
+ ],
19797
+ about: [
19798
+ "plain",
19799
+ "split"
19800
+ ],
19801
+ faq: [
19802
+ "accordion",
19803
+ "list"
19804
+ ],
19805
+ contact: [
19806
+ "card",
19807
+ "banner"
19808
+ ]
19809
+ };
19810
+ var SafeTextSchema = z91.string().trim().min(1).max(500);
19811
+ var GlobalPhoneSchema = z91.string().trim().regex(/^\+?[1-9][0-9 ()-]*$/).refine((value) => {
19812
+ const digits = value.replace(/\D/g, "");
19813
+ return digits.length >= 7 && digits.length <= 15;
19814
+ }, "phone must contain between 7 and 15 digits");
19815
+ function isSafePublicServiceLandingUrl(value) {
19816
+ try {
19817
+ const url = new URL(value);
19818
+ const hostname = url.hostname.toLowerCase().replace(/\.$/, "");
19819
+ if (url.protocol !== "https:" && url.protocol !== "http:" || !hostname.includes(".") || url.username || url.password || hostname === "localhost" || hostname.endsWith(".localhost") || hostname.endsWith(".local") || hostname.endsWith(".internal") || hostname.startsWith("[") || /^\d+(?:\.\d+){3}$/.test(hostname)) return false;
19820
+ return hostname.split(".").every((label) => label.length > 0 && label.length <= 63 && /^[a-z0-9-]+$/.test(label) && !label.startsWith("-") && !label.endsWith("-"));
19821
+ } catch {
19822
+ return false;
19823
+ }
19824
+ }
19825
+ __name(isSafePublicServiceLandingUrl, "isSafePublicServiceLandingUrl");
19826
+ var SupportedCurrencies = new Set(Intl.supportedValuesOf("currency"));
19827
+ var CurrencySchema2 = z91.string().regex(/^[A-Z]{3}$/).refine((value) => SupportedCurrencies.has(value), "currency must be a supported ISO 4217 code");
19828
+ var FixedPriceSchema = z91.object({
19829
+ kind: z91.enum([
19830
+ "fixed",
19831
+ "from"
19832
+ ]),
19833
+ amountMinor: z91.number().int().nonnegative().safe(),
19834
+ currency: CurrencySchema2
19835
+ }).strict();
19836
+ var RangePriceSchema = z91.object({
19837
+ kind: z91.literal("range"),
19838
+ minMinor: z91.number().int().nonnegative().safe(),
19839
+ maxMinor: z91.number().int().nonnegative().safe(),
19840
+ currency: CurrencySchema2
19841
+ }).strict().superRefine((value, context) => {
19842
+ if (value.minMinor > value.maxMinor) {
19843
+ context.addIssue({
19844
+ code: z91.ZodIssueCode.custom,
19845
+ path: [
19846
+ "maxMinor"
19847
+ ],
19848
+ message: "maxMinor must be at least minMinor"
19849
+ });
19850
+ }
19851
+ });
19852
+ var NonAmountPriceSchema = z91.object({
19853
+ kind: z91.enum([
19854
+ "quote",
19855
+ "hidden"
19856
+ ])
19857
+ }).strict();
19858
+ var LabelPriceSchema = z91.object({
19859
+ kind: z91.literal("label"),
19860
+ label: z91.string().trim().min(1).max(180)
19861
+ }).strict();
19862
+ var ServiceLandingPriceSchema = z91.union([
19863
+ FixedPriceSchema,
19864
+ RangePriceSchema,
19865
+ NonAmountPriceSchema,
19866
+ LabelPriceSchema
19867
+ ]);
19868
+ var WhatsAppChannelSchema = z91.object({
19869
+ kind: z91.literal("whatsapp"),
19870
+ value: GlobalPhoneSchema,
19871
+ label: OptionalTextSchema
19872
+ }).strict();
19873
+ var PhoneChannelSchema = z91.object({
19874
+ kind: z91.literal("phone"),
19875
+ value: GlobalPhoneSchema,
19876
+ label: OptionalTextSchema
19877
+ }).strict();
19878
+ var EmailChannelSchema = z91.object({
19879
+ kind: z91.literal("email"),
19880
+ value: z91.string().trim().email().max(254),
19881
+ label: OptionalTextSchema
19882
+ }).strict();
19883
+ var BookingUrlChannelSchema = z91.object({
19884
+ kind: z91.literal("booking_url"),
19885
+ value: z91.string().trim().url().max(2048).refine((value) => {
19886
+ return isSafePublicServiceLandingUrl(value);
19887
+ }, "booking URL must use a safe public http or https origin"),
19888
+ label: OptionalTextSchema
19889
+ }).strict();
19890
+ var ServiceLandingContactChannelSchema = z91.discriminatedUnion("kind", [
19891
+ WhatsAppChannelSchema,
19892
+ PhoneChannelSchema,
19893
+ EmailChannelSchema,
19894
+ BookingUrlChannelSchema
19895
+ ]);
19896
+ var ServiceLandingServiceSchema = z91.object({
19897
+ id: z91.string().uuid(),
19898
+ name: z91.string().trim().min(1).max(120),
19899
+ description: OptionalTextSchema,
19900
+ inclusions: z91.array(z91.string().trim().min(1).max(160)).max(12),
19901
+ price: ServiceLandingPriceSchema
19902
+ }).strict();
19903
+ var HeroSectionSchema = z91.object({
19904
+ type: z91.literal("hero"),
19905
+ variant: z91.enum(SERVICE_LANDING_SECTION_VARIANTS.hero),
19906
+ heading: OptionalTextSchema,
19907
+ summary: OptionalTextSchema,
19908
+ mediaAssetId: AssetIdSchema.optional()
19909
+ }).strict();
19910
+ var ServicesSectionSchema = z91.object({
19911
+ type: z91.literal("services"),
19912
+ variant: z91.enum(SERVICE_LANDING_SECTION_VARIANTS.services),
19913
+ heading: OptionalTextSchema,
19914
+ serviceIds: z91.array(AssetIdSchema).min(1).max(12)
19915
+ }).strict();
19916
+ var AboutSectionSchema = z91.object({
19917
+ type: z91.literal("about"),
19918
+ variant: z91.enum(SERVICE_LANDING_SECTION_VARIANTS.about),
19919
+ heading: OptionalTextSchema,
19920
+ body: SafeTextSchema
19921
+ }).strict();
19922
+ var FaqSectionSchema = z91.object({
19923
+ type: z91.literal("faq"),
19924
+ variant: z91.enum(SERVICE_LANDING_SECTION_VARIANTS.faq),
19925
+ heading: OptionalTextSchema,
19926
+ items: z91.array(z91.object({
19927
+ question: z91.string().trim().min(1).max(180),
19928
+ answer: z91.string().trim().min(1).max(500)
19929
+ }).strict()).min(1).max(8)
19930
+ }).strict();
19931
+ var ContactSectionSchema = z91.object({
19932
+ type: z91.literal("contact"),
19933
+ variant: z91.enum(SERVICE_LANDING_SECTION_VARIANTS.contact),
19934
+ heading: OptionalTextSchema
19935
+ }).strict();
19936
+ var ServiceLandingSectionSchema = z91.discriminatedUnion("type", [
19937
+ HeroSectionSchema,
19938
+ ServicesSectionSchema,
19939
+ AboutSectionSchema,
19940
+ FaqSectionSchema,
19941
+ ContactSectionSchema
19942
+ ]);
19943
+ var ServiceLandingThemeSchema = z91.object({
19944
+ layout: z91.enum(SERVICE_LANDING_LAYOUTS),
19945
+ palette: z91.enum(SERVICE_LANDING_PALETTES),
19946
+ motion: z91.enum(SERVICE_LANDING_MOTION),
19947
+ colors: z91.object({
19948
+ primaryColor: z91.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),
19949
+ secondaryColor: z91.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),
19950
+ backgroundColor: z91.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),
19951
+ accentColor: z91.string().regex(/^#[0-9a-fA-F]{6}$/).optional()
19952
+ }).strict().optional()
19953
+ }).strict();
19954
+ var ServiceLandingContactSchema = z91.object({
19955
+ channels: z91.array(ServiceLandingContactChannelSchema).max(4),
19956
+ primaryCta: ServiceLandingPrimaryCtaSchema.optional()
19957
+ }).strict();
19958
+ var ServiceLandingCodeSchema = z91.object({
19959
+ html: z91.string().trim().min(1).max(18e4),
19960
+ css: z91.string().trim().max(1e5).default(""),
19961
+ assetIds: z91.array(AssetIdSchema).max(24)
19962
+ }).strict();
19963
+ function isRecord2(value) {
19964
+ return value !== null && typeof value === "object" && !Array.isArray(value);
19965
+ }
19966
+ __name(isRecord2, "isRecord");
19967
+ var CODE_ARTIFACT_DEFAULT_THEME = {
19968
+ layout: "studio",
19969
+ palette: "light",
19970
+ motion: "none"
19971
+ };
19972
+ function applyCodeArtifactDefaults(value) {
19973
+ if (!isRecord2(value) || value.code === void 0) return value;
19974
+ const business = isRecord2(value.business) ? value.business : {};
19975
+ const contact = isRecord2(value.contact) ? {
19976
+ ...value.contact,
19977
+ ...value.contact.channels === void 0 ? {
19978
+ channels: []
19979
+ } : {}
19980
+ } : value.contact === void 0 ? {
19981
+ channels: []
19982
+ } : value.contact;
19983
+ const name = business.name;
19984
+ return {
19985
+ ...value,
19986
+ business: {
19987
+ ...business,
19988
+ ...name === void 0 || typeof name === "string" && name.trim().length === 0 ? {
19989
+ name: "Tu marca"
19990
+ } : {}
19991
+ },
19992
+ theme: value.theme === void 0 ? CODE_ARTIFACT_DEFAULT_THEME : value.theme,
19993
+ services: value.services === void 0 ? [] : value.services,
19994
+ contact,
19995
+ sections: value.sections === void 0 ? [] : value.sections
19996
+ };
19997
+ }
19998
+ __name(applyCodeArtifactDefaults, "applyCodeArtifactDefaults");
19999
+ var ServiceLandingArtifactSchema = z91.preprocess(applyCodeArtifactDefaults, z91.object({
20000
+ schemaVersion: z91.literal(SERVICE_LANDING_SCHEMA_VERSION),
20001
+ catalogVersion: z91.literal(SERVICE_LANDING_CATALOG_VERSION),
20002
+ business: z91.object({
20003
+ name: z91.string().trim().min(1).max(120),
20004
+ description: OptionalTextSchema,
20005
+ /** Server-owned asset id; the renderer resolves it through the page owner. */
20006
+ logoAssetId: AssetIdSchema.optional()
20007
+ }).strict(),
20008
+ theme: ServiceLandingThemeSchema,
20009
+ services: z91.array(ServiceLandingServiceSchema).max(12),
20010
+ contact: ServiceLandingContactSchema,
20011
+ sections: z91.array(ServiceLandingSectionSchema).max(5),
20012
+ /** Complete model-authored body and stylesheet; the public renderer sanitizes both. */
20013
+ code: ServiceLandingCodeSchema.optional()
20014
+ }).strict().superRefine((artifact, context) => {
20015
+ if (artifact.code) {
20016
+ if (artifact.sections.length || new Set(artifact.code.assetIds).size !== artifact.code.assetIds.length) {
20017
+ context.addIssue({
20018
+ code: z91.ZodIssueCode.custom,
20019
+ path: [
20020
+ "code"
20021
+ ],
20022
+ message: "Code drafts cannot mix catalog sections or duplicate asset references"
20023
+ });
20024
+ }
20025
+ const ids = artifact.services.map((service) => service.id);
20026
+ if (new Set(ids).size !== ids.length) {
20027
+ context.addIssue({
20028
+ code: z91.ZodIssueCode.custom,
20029
+ path: [
20030
+ "services"
20031
+ ],
20032
+ message: "service ids must be unique"
20033
+ });
20034
+ }
20035
+ return;
20036
+ }
20037
+ if (artifact.services.length === 0) {
20038
+ context.addIssue({
20039
+ code: z91.ZodIssueCode.custom,
20040
+ path: [
20041
+ "services"
20042
+ ],
20043
+ message: "catalog artifacts require at least one service"
20044
+ });
20045
+ }
20046
+ if (!artifact.contact.primaryCta) {
20047
+ context.addIssue({
20048
+ code: z91.ZodIssueCode.custom,
20049
+ path: [
20050
+ "contact",
20051
+ "primaryCta"
20052
+ ],
20053
+ message: "catalog artifacts require a primary CTA"
20054
+ });
20055
+ } else if (artifact.contact.primaryCta.channelIndex >= artifact.contact.channels.length) {
20056
+ context.addIssue({
20057
+ code: z91.ZodIssueCode.custom,
20058
+ path: [
20059
+ "contact",
20060
+ "primaryCta",
20061
+ "channelIndex"
20062
+ ],
20063
+ message: "CTA channel does not exist"
20064
+ });
20065
+ }
20066
+ const sectionTypes = artifact.sections.map((section) => section.type);
20067
+ if (new Set(sectionTypes).size !== sectionTypes.length) {
20068
+ context.addIssue({
20069
+ code: z91.ZodIssueCode.custom,
20070
+ path: [
20071
+ "sections"
20072
+ ],
20073
+ message: "section types must be unique"
20074
+ });
20075
+ }
20076
+ if (sectionTypes[0] !== "hero") {
20077
+ context.addIssue({
20078
+ code: z91.ZodIssueCode.custom,
20079
+ path: [
20080
+ "sections",
20081
+ 0
20082
+ ],
20083
+ message: "hero must be the first section"
20084
+ });
20085
+ }
20086
+ if (!sectionTypes.includes("services") || !sectionTypes.includes("contact")) {
20087
+ context.addIssue({
20088
+ code: z91.ZodIssueCode.custom,
20089
+ path: [
20090
+ "sections"
20091
+ ],
20092
+ message: "services and contact sections are required"
20093
+ });
20094
+ }
20095
+ const serviceIds = new Set(artifact.services.map((service) => service.id));
20096
+ if (serviceIds.size !== artifact.services.length) {
20097
+ context.addIssue({
20098
+ code: z91.ZodIssueCode.custom,
20099
+ path: [
20100
+ "services"
20101
+ ],
20102
+ message: "service ids must be unique"
20103
+ });
20104
+ }
20105
+ for (const [index, section] of artifact.sections.entries()) {
20106
+ if (section.type !== "services") continue;
20107
+ const ids = new Set(section.serviceIds);
20108
+ if (ids.size !== section.serviceIds.length || section.serviceIds.some((id) => !serviceIds.has(id))) {
20109
+ context.addIssue({
20110
+ code: z91.ZodIssueCode.custom,
20111
+ path: [
20112
+ "sections",
20113
+ index,
20114
+ "serviceIds"
20115
+ ],
20116
+ message: "service section references must be unique and belong to the artifact"
20117
+ });
20118
+ }
20119
+ }
20120
+ }));
20121
+
20122
+ // ../../packages/types/src/service-landing-facts-brand.ts
20123
+ import { z as z92 } from "zod";
20124
+ var ServiceLandingServiceFactsSchema = z92.object({
20125
+ id: z92.string().uuid(),
20126
+ name: z92.string().trim().min(1).max(120).optional(),
20127
+ description: OptionalTextSchema,
20128
+ inclusions: z92.array(z92.string().trim().min(1).max(160)).max(12).default([]),
20129
+ price: ServiceLandingPriceSchema.optional()
20130
+ }).strict();
20131
+ var ServicePageFactsSchema = z92.object({
20132
+ business: z92.object({
20133
+ name: z92.string().trim().min(1).max(120).optional(),
20134
+ description: OptionalTextSchema,
20135
+ audience: OptionalTextSchema,
20136
+ deliveryMode: z92.enum([
20137
+ "in_person",
20138
+ "remote",
20139
+ "hybrid"
20140
+ ]).optional(),
20141
+ coverage: OptionalTextSchema
20142
+ }).strict(),
20143
+ services: z92.array(ServiceLandingServiceFactsSchema).max(12).default([]),
20144
+ contact: z92.object({
20145
+ channels: z92.array(ServiceLandingContactChannelSchema).max(4).default([]),
20146
+ primaryCta: ServiceLandingPrimaryCtaSchema.optional()
20147
+ }).strict(),
20148
+ credentials: z92.array(z92.string().trim().min(1).max(180)).max(12).default([])
20149
+ }).strict();
20150
+ var ServicePageBrandCatalogPriceSchema = ServiceLandingPriceSchema.refine((price) => price.kind === "fixed", "Brand catalog prices must be fixed prices");
20151
+ var ServicePageBrandContextSchema = z92.object({
20152
+ identity: z92.object({
20153
+ name: z92.string().trim().min(1).max(120),
20154
+ oneLiner: z92.string().trim().min(1).max(500).optional(),
20155
+ overview: z92.string().trim().min(1).max(2e3).optional(),
20156
+ aboutParagraph: z92.string().trim().min(1).max(2e3).optional()
20157
+ }).strict(),
20158
+ verbal: z92.object({
20159
+ toneAdjectives: z92.array(z92.string().trim().min(1).max(60)).max(12),
20160
+ coreValues: z92.array(z92.string().trim().min(1).max(120)).max(12),
20161
+ doWords: z92.array(z92.string().trim().min(1).max(40)).max(20),
20162
+ dontWords: z92.array(z92.string().trim().min(1).max(40)).max(20),
20163
+ keyMessages: z92.array(z92.string().trim().min(1).max(200)).max(5)
20164
+ }).strict(),
20165
+ catalog: z92.array(z92.object({
20166
+ name: z92.string().trim().min(1).max(120),
20167
+ price: ServicePageBrandCatalogPriceSchema.optional()
20168
+ }).strict()).max(12).optional(),
20169
+ visual: z92.object({
20170
+ primaryColor: z92.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),
20171
+ secondaryColor: z92.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),
20172
+ tertiaryColor: z92.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),
20173
+ neutralColor: z92.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),
20174
+ accentColors: z92.array(z92.string().regex(/^#[0-9a-fA-F]{6}$/)).max(8),
20175
+ designDirection: z92.enum([
20176
+ "editorial_minimal",
20177
+ "playful_bold",
20178
+ "luxury_serif",
20179
+ "tech_clean",
20180
+ "earthy_organic",
20181
+ "heritage_classic",
20182
+ "neon_futurist",
20183
+ "hand_crafted",
20184
+ "corporate_modern",
20185
+ "streetwear_drop"
20186
+ ]).optional(),
20187
+ buttonStyle: z92.enum([
20188
+ "solid_sharp",
20189
+ "solid_rounded",
20190
+ "pill",
20191
+ "outline",
20192
+ "ghost",
20193
+ "underline_only"
20194
+ ]).optional(),
20195
+ radiusScale: z92.enum([
20196
+ "none",
20197
+ "subtle",
20198
+ "medium",
20199
+ "large",
20200
+ "pill"
20201
+ ]).optional(),
20202
+ photographyStyle: z92.enum([
20203
+ "studio_product",
20204
+ "lifestyle_human",
20205
+ "ugc_raw",
20206
+ "editorial_fashion",
20207
+ "flat_illustration",
20208
+ "mixed"
20209
+ ]).optional(),
20210
+ visualAesthetics: z92.array(z92.string().trim().min(1).max(60)).max(20)
20211
+ }).strict()
20212
+ }).strict();
20213
+ var ServicePageStatusSchema = z92.enum([
20214
+ "draft",
20215
+ "published",
20216
+ "unpublished"
20217
+ ]);
20218
+ var ServicePageSourceKindSchema = z92.enum([
20219
+ "manual_text",
20220
+ "document",
20221
+ "brand",
20222
+ "instagram",
20223
+ "logo"
20224
+ ]);
20225
+ var ServicePageSourceStatusSchema = z92.enum([
20226
+ "received",
20227
+ "reading",
20228
+ "ready",
20229
+ "needs_manual_review",
20230
+ "failed"
20231
+ ]);
20232
+ var ServicePageParserMetadataSchema = z92.object({
20233
+ truncated: z92.boolean(),
20234
+ status: z92.enum([
20235
+ "ready",
20236
+ "needs_manual_review"
20237
+ ]),
20238
+ locations: z92.array(z92.object({
20239
+ source: z92.string().trim().min(1).max(255),
20240
+ locator: z92.string().trim().min(1).max(120),
20241
+ text: z92.string().max(2e3),
20242
+ line: z92.number().int().positive().optional(),
20243
+ page: z92.number().int().positive().optional(),
20244
+ sheet: z92.string().trim().min(1).max(255).optional(),
20245
+ cell: z92.string().trim().min(1).max(64).optional()
20246
+ }).strict()).max(1e3).optional(),
20247
+ pages: z92.array(z92.object({
20248
+ source: z92.string().trim().min(1).max(255),
20249
+ page: z92.number().int().positive(),
20250
+ locator: z92.string().trim().min(1).max(120)
20251
+ }).strict()).max(50).optional(),
20252
+ sheets: z92.array(z92.object({
20253
+ name: z92.string().trim().min(1).max(255),
20254
+ selected: z92.boolean(),
20255
+ nonEmptyCells: z92.number().int().nonnegative().nullable(),
20256
+ summary: z92.string().max(2e3)
20257
+ }).strict()).max(100).optional(),
20258
+ warnings: z92.array(z92.object({
20259
+ code: z92.enum([
20260
+ "text_truncated",
20261
+ "pdf_scanned",
20262
+ "formula_without_cached_value",
20263
+ "cell_limit_reached",
20264
+ "sheet_selection_applied",
20265
+ "no_sheets_selected",
20266
+ "no_extractable_text",
20267
+ "text_locators_truncated"
20268
+ ]),
20269
+ message: z92.string().max(500),
20270
+ source: z92.string().trim().min(1).max(255),
20271
+ page: z92.number().int().positive().optional(),
20272
+ sheet: z92.string().trim().min(1).max(255).optional(),
20273
+ cell: z92.string().trim().min(1).max(64).optional()
20274
+ }).strict()).max(100).optional()
20275
+ }).strict();
20276
+ var ServicePageSourceSchema = z92.object({
20277
+ id: z92.string().uuid(),
20278
+ kind: ServicePageSourceKindSchema,
20279
+ status: ServicePageSourceStatusSchema,
20280
+ displayName: z92.string().trim().min(1).max(180).optional(),
20281
+ extractedCharacterCount: z92.number().int().nonnegative().max(3e4).optional(),
20282
+ errorCode: z92.string().regex(/^[A-Z0-9_]{1,64}$/).optional(),
20283
+ parserMetadata: ServicePageParserMetadataSchema.optional()
20284
+ }).strict();
20285
+ var ServicePageFactConflictSchema = z92.object({
20286
+ fieldPath: z92.string().trim().min(1).max(180),
20287
+ candidates: z92.array(z92.object({
20288
+ id: z92.string().uuid(),
20289
+ value: z92.string().trim().min(1).max(500),
20290
+ sourceIds: z92.array(z92.string().uuid()).min(1).max(10)
20291
+ }).strict()).min(2).max(8)
20292
+ }).strict();
20293
+ var ServicePageFactProvenanceSchema = z92.object({
20294
+ fieldPath: z92.string().trim().min(1).max(180),
20295
+ sourceIds: z92.array(z92.string().uuid()).min(1).max(10),
20296
+ evidence: z92.string().trim().max(1e3).optional()
20297
+ }).strict();
20298
+ var ServicePageFactsReviewSchema = z92.object({
20299
+ facts: ServicePageFactsSchema,
20300
+ sources: z92.array(ServicePageSourceSchema).max(50),
20301
+ provenance: z92.array(ServicePageFactProvenanceSchema).max(100),
20302
+ missingFields: z92.array(z92.string().trim().min(1).max(180)).max(30),
20303
+ conflicts: z92.array(ServicePageFactConflictSchema).max(30),
20304
+ confirmed: z92.boolean(),
20305
+ confirmedAt: z92.string().datetime().optional()
20306
+ }).strict();
20307
+
20308
+ // ../../packages/types/src/service-landing-api.ts
20309
+ import { z as z93 } from "zod";
20310
+ var ServicePageCreateRequestSchema = z93.object({
20311
+ brandId: z93.string().uuid(),
20312
+ includeBrandLogo: z93.boolean().optional(),
20313
+ idempotencyKey: z93.string().uuid().optional()
20314
+ }).strict();
20315
+ var ServicePageFactsUpdateRequestSchema = z93.object({
20316
+ expectedRevision: z93.number().int().nonnegative(),
20317
+ idempotencyKey: z93.string().uuid(),
20318
+ facts: ServicePageFactsSchema
20319
+ }).strict();
20320
+ var ServicePageFactsConfirmRequestSchema = z93.object({
20321
+ expectedRevision: z93.number().int().nonnegative(),
20322
+ idempotencyKey: z93.string().uuid(),
20323
+ resolutions: z93.array(z93.object({
20324
+ fieldPath: z93.string().trim().min(1).max(180),
20325
+ candidateId: z93.string().uuid()
20326
+ }).strict()).max(30)
20327
+ }).strict();
20328
+ var ServicePageIntakeRequestSchema = z93.object({
20329
+ expectedRevision: z93.number().int().nonnegative(),
20330
+ idempotencyKey: z93.string().uuid(),
20331
+ text: z93.string().trim().max(3e4).optional(),
20332
+ profileUrl: z93.string().trim().url().max(2048).refine((value) => {
20333
+ try {
20334
+ const url = new URL(value);
20335
+ const host = url.hostname.toLowerCase().replace(/^www\./, "");
20336
+ return url.protocol === "https:" && [
20337
+ "instagram.com",
20338
+ "instagr.am"
20339
+ ].includes(host) && /^\/[A-Za-z0-9._]+\/?$/.test(url.pathname);
20340
+ } catch {
20341
+ return false;
20342
+ }
20343
+ }, "profileUrl must be an HTTPS Instagram profile URL").optional()
20344
+ }).strict();
20345
+ var ServicePageQuotePurposeSchema = z93.enum([
20346
+ "fact_extraction",
20347
+ "generation"
20348
+ ]);
20349
+ var ServicePageQuoteRequestSchema = z93.object({
20350
+ expectedRevision: z93.number().int().nonnegative()
20351
+ }).strict();
20352
+ var SERVICE_PAGE_EDIT_INSTRUCTION_MAX_CHARS = 2e3;
20353
+ var SERVICE_PAGE_EDIT_MAX_ATTEMPTS = 4;
20354
+ var SERVICE_PAGE_EDIT_WINDOW_MS = SERVICE_PAGE_EDIT_MAX_ATTEMPTS * 3e5;
20355
+ var SERVICE_PAGE_CHAT_ATTACHMENT_MAX_SELECTION = 4;
20356
+ var ServicePageAttachmentRefSchema = z93.object({
20357
+ kind: z93.enum([
20358
+ "source",
20359
+ "asset"
20360
+ ]),
20361
+ id: z93.string().uuid().transform((id) => id.toLowerCase())
20362
+ }).strict();
20363
+ var ServicePageAttachmentRefsSchema = z93.array(ServicePageAttachmentRefSchema).max(SERVICE_PAGE_CHAT_ATTACHMENT_MAX_SELECTION).superRefine((refs, ctx) => {
20364
+ const seen = /* @__PURE__ */ new Set();
20365
+ refs.forEach((ref, index) => {
20366
+ const key = `${ref.kind}:${ref.id}`;
20367
+ if (seen.has(key)) {
20368
+ ctx.addIssue({
20369
+ code: z93.ZodIssueCode.custom,
20370
+ path: [
20371
+ index
20372
+ ],
20373
+ message: "Attachment references must be unique."
20374
+ });
20375
+ }
20376
+ seen.add(key);
20377
+ });
20378
+ });
20379
+ var ServicePageChatAttachmentStatusSchema = z93.enum([
20380
+ "ready",
20381
+ "needs_manual_review"
20382
+ ]);
20383
+ var ServicePageChatAttachmentSchema = z93.object({
20384
+ ref: ServicePageAttachmentRefSchema,
20385
+ displayName: z93.string().trim().min(1).max(180),
20386
+ mediaType: z93.string().trim().min(1).max(127),
20387
+ status: ServicePageChatAttachmentStatusSchema
20388
+ }).strict();
20389
+ var ServicePageChatAttachmentUploadResponseSchema = z93.object({
20390
+ attachments: z93.array(ServicePageChatAttachmentSchema).min(1).max(10)
20391
+ }).strict();
20392
+ var ServicePageChatAttachmentUploadRequestSchema = z93.object({
20393
+ expectedRevision: z93.number().int().nonnegative(),
20394
+ idempotencyKey: z93.string().uuid(),
20395
+ profileUrl: z93.string().url().max(2048).optional()
20396
+ }).strict();
20397
+ var ServicePageEditInstructionSchema = z93.string().trim().min(3).max(SERVICE_PAGE_EDIT_INSTRUCTION_MAX_CHARS);
20398
+ var ServicePageEditEstimateRequestSchema = z93.object({
20399
+ expectedRevision: z93.number().int().nonnegative(),
20400
+ baseCandidateOperationId: z93.string().uuid().transform((id) => id.toLowerCase()).optional(),
20401
+ instruction: ServicePageEditInstructionSchema.optional(),
20402
+ attachmentRefs: ServicePageAttachmentRefsSchema.optional()
20403
+ }).strict();
20404
+ var ServicePageEditEstimateResponseSchema = z93.object({
20405
+ estimatedMinCostCredits: z93.number().int().nonnegative(),
20406
+ estimatedMaxCostCredits: z93.number().int().nonnegative(),
20407
+ maximumAuthorizedCostCredits: z93.number().int().nonnegative(),
20408
+ maximumMediaCostCredits: z93.number().int().nonnegative()
20409
+ }).strict();
20410
+ var ServicePageGenerationQuoteRequestSchema = z93.object({
20411
+ expectedRevision: z93.number().int().nonnegative(),
20412
+ baseCandidateOperationId: z93.string().uuid().transform((id) => id.toLowerCase()).optional(),
20413
+ instruction: ServicePageEditInstructionSchema.optional(),
20414
+ attachmentRefs: ServicePageAttachmentRefsSchema.optional()
20415
+ }).strict();
20416
+ var ServicePageQuoteResponseSchema = z93.object({
20417
+ quoteId: z93.string().uuid(),
20418
+ purpose: ServicePageQuotePurposeSchema,
20419
+ expectedRevision: z93.number().int().nonnegative(),
20420
+ requestHash: z93.string().regex(/^[a-f0-9]{64}$/),
20421
+ estimatedCostCents: z93.number().int().nonnegative(),
20422
+ credits: z93.number().int().nonnegative(),
20423
+ estimatedMinCostCredits: z93.number().int().nonnegative().optional(),
20424
+ estimatedMaxCostCredits: z93.number().int().nonnegative().optional(),
20425
+ maximumMediaCostCredits: z93.number().int().nonnegative().optional(),
20426
+ currency: z93.literal("USD"),
20427
+ expiresAt: z93.string().datetime(),
20428
+ requiresConfirmation: z93.literal(true)
20429
+ }).strict();
20430
+ var ServicePageGenerateRequestSchema = z93.object({
20431
+ quoteId: z93.string().uuid(),
20432
+ idempotencyKey: z93.string().uuid(),
20433
+ expectedRevision: z93.number().int().nonnegative(),
20434
+ baseCandidateOperationId: z93.string().uuid().transform((id) => id.toLowerCase()).optional(),
20435
+ instruction: ServicePageEditInstructionSchema.optional(),
20436
+ attachmentRefs: ServicePageAttachmentRefsSchema.optional()
20437
+ }).strict();
20438
+ var ServicePageFactExtractionRequestSchema = ServicePageGenerateRequestSchema.omit({
20439
+ instruction: true
20440
+ });
20441
+ var ServicePageOperationStatusSchema = z93.enum([
20442
+ "queued",
20443
+ "running",
20444
+ "succeeded",
20445
+ "failed",
20446
+ "conflict",
20447
+ "requires_reconciliation"
20448
+ ]);
20449
+ var ServicePageOperationResponseSchema = z93.object({
20450
+ opId: z93.string().uuid(),
20451
+ servicePageId: z93.string().uuid(),
20452
+ kind: z93.enum([
20453
+ "fact_extraction",
20454
+ "generation"
20455
+ ]),
20456
+ status: ServicePageOperationStatusSchema,
20457
+ expectedRevision: z93.number().int().nonnegative().optional(),
20458
+ revision: z93.number().int().nonnegative().optional(),
20459
+ candidateCode: ServiceLandingCodeSchema.optional(),
20460
+ candidateFacts: ServicePageFactsSchema.optional(),
20461
+ candidateArtifact: ServiceLandingArtifactSchema.optional(),
20462
+ errorCode: z93.string().regex(/^[A-Z0-9_]{1,64}$/).optional(),
20463
+ recoverable: z93.boolean()
20464
+ }).strict();
20465
+ var ServicePageEditHistoryItemSchema = z93.object({
20466
+ opId: z93.string().uuid(),
20467
+ instruction: ServicePageEditInstructionSchema,
20468
+ status: ServicePageOperationStatusSchema,
20469
+ expectedRevision: z93.number().int().nonnegative(),
20470
+ resultRevision: z93.number().int().nonnegative().nullable(),
20471
+ createdAt: z93.string().datetime(),
20472
+ completedAt: z93.string().datetime().nullable(),
20473
+ errorCode: z93.string().regex(/^[A-Z0-9_]{1,64}$/).nullable(),
20474
+ attachments: z93.array(z93.object({
20475
+ ref: ServicePageAttachmentRefSchema,
20476
+ displayName: z93.string().trim().min(1).max(180)
20477
+ }).strict()).max(4)
20478
+ }).strict();
20479
+ var ServicePageEditHistorySchema = z93.array(ServicePageEditHistoryItemSchema).max(50).default([]);
20480
+ var ServicePageOperationJobSchema = z93.object({
20481
+ operationId: z93.string().uuid(),
20482
+ servicePageId: z93.string().uuid(),
20483
+ userId: z93.string().min(1).max(256),
20484
+ kind: z93.enum([
20485
+ "fact_extraction",
20486
+ "generation"
20487
+ ])
20488
+ }).strict();
20489
+ var ServicePageDraftUpdateRequestSchema = z93.object({
20490
+ expectedRevision: z93.number().int().nonnegative(),
20491
+ idempotencyKey: z93.string().uuid(),
20492
+ candidateOperationId: z93.string().uuid().transform((id) => id.toLowerCase()).optional(),
20493
+ artifact: ServiceLandingArtifactSchema
20494
+ }).strict();
20495
+ var ServicePagePublishRequestSchema = z93.object({
20496
+ expectedRevision: z93.number().int().nonnegative(),
20497
+ slug: z93.string().trim().toLowerCase().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).max(64),
20498
+ idempotencyKey: z93.string().uuid()
20499
+ }).strict();
20500
+ var ServicePageUnpublishRequestSchema = z93.object({
20501
+ publishedRevision: z93.number().int().positive(),
20502
+ idempotencyKey: z93.string().uuid()
20503
+ }).strict();
20504
+ var ServicePageSummarySchema = z93.object({
20505
+ id: z93.string().uuid(),
20506
+ brandId: z93.string().uuid().nullable(),
20507
+ businessName: z93.string().trim().min(1).max(120).nullable(),
20508
+ status: ServicePageStatusSchema,
20509
+ draftRevision: z93.number().int().nonnegative(),
20510
+ publishedRevision: z93.number().int().nonnegative().nullable(),
20511
+ slug: z93.string().nullable(),
20512
+ publicUrl: z93.string().url().nullable(),
20513
+ updatedAt: z93.string().datetime()
20514
+ }).strict();
20515
+ var ServicePagePublicAssetSchema = z93.object({
20516
+ url: z93.string().max(2048).regex(/^\/v1\/service-pages\/(?:public\/[a-z0-9-]+|[0-9a-f-]{36})\/assets\/[0-9a-f-]{36}$/i),
20517
+ mimeType: z93.enum([
20518
+ "image/jpeg",
20519
+ "image/png",
20520
+ "image/webp",
20521
+ "video/mp4"
20522
+ ]).optional(),
20523
+ width: z93.number().int().positive().max(12e3),
20524
+ height: z93.number().int().positive().max(12e3),
20525
+ alt: z93.string().trim().min(1).max(180),
20526
+ variants: z93.array(z93.object({
20527
+ url: z93.string().max(2048).regex(/^\/v1\/service-pages\/(?:public\/[a-z0-9-]+|[0-9a-f-]{36})\/assets\/[0-9a-f-]{36}$/i),
20528
+ width: z93.number().int().positive().max(12e3),
20529
+ height: z93.number().int().positive().max(12e3)
20530
+ }).strict()).max(3).optional()
20531
+ }).strict();
20532
+ var ServicePageDetailSchema = ServicePageSummarySchema.extend({
20533
+ facts: ServicePageFactsSchema,
20534
+ sources: z93.array(ServicePageSourceSchema).max(50),
20535
+ provenance: z93.array(ServicePageFactProvenanceSchema).max(100),
20536
+ missingFields: z93.array(z93.string().trim().min(1).max(180)).max(30),
20537
+ conflicts: z93.array(ServicePageFactConflictSchema).max(30),
20538
+ factsConfirmed: z93.boolean(),
20539
+ factsConfirmedAt: z93.string().datetime().nullable(),
20540
+ /** True only after a confirmed source-backed extraction result was persisted. */
20541
+ factExtractionCompleted: z93.boolean(),
20542
+ artifact: ServiceLandingArtifactSchema.nullable(),
20543
+ assetsById: z93.record(AssetIdSchema, ServicePagePublicAssetSchema),
20544
+ editHistory: ServicePageEditHistorySchema
20545
+ }).strict();
20546
+ var ServicePageListResponseSchema = z93.object({
20547
+ pages: z93.array(ServicePageSummarySchema)
20548
+ }).strict();
20549
+ var ServicePageIntakeResponseSchema = z93.object({
20550
+ servicePageId: z93.string().uuid(),
20551
+ draftRevision: z93.number().int().nonnegative(),
20552
+ sources: z93.array(ServicePageSourceSchema).max(50),
20553
+ facts: ServicePageFactsSchema,
20554
+ missingFields: z93.array(z93.string().trim().min(1).max(180)).max(30),
20555
+ conflicts: z93.array(ServicePageFactConflictSchema).max(30),
20556
+ assetsById: z93.record(AssetIdSchema, ServicePagePublicAssetSchema)
20557
+ }).strict();
20558
+ var ServicePagePreviewResponseSchema = z93.object({
20559
+ servicePageId: z93.string().uuid(),
20560
+ revision: z93.number().int().nonnegative(),
20561
+ artifact: ServiceLandingArtifactSchema,
20562
+ assetsById: z93.record(AssetIdSchema, ServicePagePublicAssetSchema)
20563
+ }).strict();
20564
+ var ServicePagePreviewRequestSchema = z93.object({
20565
+ expectedRevision: z93.number().int().nonnegative(),
20566
+ candidateOperationId: z93.string().uuid().optional(),
20567
+ artifact: ServiceLandingArtifactSchema.optional()
20568
+ }).strict().superRefine((request, context) => {
20569
+ if (!request.artifact && !request.candidateOperationId) {
20570
+ context.addIssue({
20571
+ code: z93.ZodIssueCode.custom,
20572
+ message: "Preview requires an artifact or a candidate operation"
20573
+ });
20574
+ }
20575
+ });
20576
+ var ServicePagePublicReadSchema = z93.object({
20577
+ slug: z93.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).max(64),
20578
+ publicUrl: z93.string().url(),
20579
+ canonicalUrl: z93.string().url(),
20580
+ title: z93.string().trim().min(1).max(160),
20581
+ description: z93.string().trim().min(1).max(300),
20582
+ ogImageAssetId: AssetIdSchema.optional(),
20583
+ publishedRevision: z93.number().int().positive(),
20584
+ artifact: ServiceLandingArtifactSchema,
20585
+ assetsById: z93.record(AssetIdSchema, ServicePagePublicAssetSchema)
20586
+ }).strict();
20587
+
20588
+ // ../../packages/types/src/service-landing-analytics.ts
20589
+ import { z as z94 } from "zod";
20590
+ var DimensionsSchema = z94.object({
20591
+ action: z94.enum([
20592
+ "open",
20593
+ "create",
20594
+ "delete",
20595
+ "intake",
20596
+ "extract",
20597
+ "confirm_facts",
20598
+ "generate",
20599
+ "recover",
20600
+ "save",
20601
+ "publish",
20602
+ "unpublish",
20603
+ "preview",
20604
+ "change_design",
20605
+ "contact_click"
20606
+ ]),
20607
+ stage: z94.enum([
20608
+ "intake",
20609
+ "review",
20610
+ "generation",
20611
+ "editor",
20612
+ "publication",
20613
+ "public"
20614
+ ]),
20615
+ brandPresence: z94.enum([
20616
+ "none",
20617
+ "selected"
20618
+ ]),
20619
+ sourceKind: z94.enum([
20620
+ "none",
20621
+ "manual",
20622
+ "brand",
20623
+ "documents",
20624
+ "photos",
20625
+ "instagram",
20626
+ "mixed"
20627
+ ]),
20628
+ // Closed tool choice only; prompts, provider IDs and business inputs stay private.
20629
+ mediaKind: z94.enum([
20630
+ "none",
20631
+ "images",
20632
+ "videos",
20633
+ "mixed"
20634
+ ]).optional()
20635
+ });
20636
+ var ReasonSchema = z94.enum([
20637
+ "validation",
20638
+ "not_found",
20639
+ "conflict",
20640
+ "quote_expired",
20641
+ "credits",
20642
+ "provider",
20643
+ "network",
20644
+ "unknown"
20645
+ ]);
20646
+ var SignalSchema = z94.discriminatedUnion("kind", [
20647
+ DimensionsSchema.extend({
20648
+ kind: z94.enum([
20649
+ "started",
20650
+ "completed",
20651
+ "variant"
20652
+ ])
20653
+ }),
20654
+ DimensionsSchema.extend({
20655
+ kind: z94.literal("failed"),
20656
+ reason: ReasonSchema
20657
+ })
20658
+ ]);
20659
+
20660
+ // ../../packages/types/src/flight-recorder.ts
20661
+ import { z as z95 } from "zod";
20662
+ var FlightRecorderGenerationTypeSchema = z95.enum([
19757
20663
  "initial",
19758
20664
  "regeneration",
19759
20665
  "edit",
19760
20666
  "retry"
19761
20667
  ]);
19762
- var FlightRecorderProviderSchema = z90.enum([
20668
+ var FlightRecorderProviderSchema = z95.enum([
19763
20669
  "kie",
19764
20670
  "fal"
19765
20671
  ]);
19766
- var FlightRecorderElementSchema = z90.object({
19767
- name: z90.string().optional(),
19768
- description: z90.string().optional(),
19769
- frontalImageUrl: z90.string().optional(),
19770
- referenceImageUrls: z90.array(z90.string()).optional(),
19771
- videoUrl: z90.string().optional()
19772
- });
19773
- var FlightRecorderDistillationSchema = z90.object({
19774
- actorGender: CreativeGenderPin.or(z90.string()).optional(),
19775
- voiceId: z90.string().optional(),
19776
- cameraMotion: z90.string().optional()
19777
- }).catchall(z90.unknown());
19778
- var FlightRecorderEntrySchema = z90.object({
19779
- schemaVersion: z90.literal(1).optional(),
19780
- id: z90.string().min(1),
19781
- taskId: z90.string().min(1),
19782
- runId: z90.string().min(1),
19783
- sequence: z90.number().int().nonnegative(),
19784
- timestamp: z90.string().min(1),
19785
- provider: FlightRecorderProviderSchema.or(z90.string()),
19786
- model: z90.string().min(1),
19787
- prompt: z90.string(),
19788
- durationSeconds: z90.number().nonnegative(),
19789
- aspectRatio: z90.string().optional(),
19790
- resolution: z90.string().optional(),
19791
- startImageUrl: z90.string().optional(),
19792
- endImageUrl: z90.string().optional(),
19793
- generateAudio: z90.boolean().optional(),
20672
+ var FlightRecorderElementSchema = z95.object({
20673
+ name: z95.string().optional(),
20674
+ description: z95.string().optional(),
20675
+ frontalImageUrl: z95.string().optional(),
20676
+ referenceImageUrls: z95.array(z95.string()).optional(),
20677
+ videoUrl: z95.string().optional()
20678
+ });
20679
+ var FlightRecorderDistillationSchema = z95.object({
20680
+ actorGender: CreativeGenderPin.or(z95.string()).optional(),
20681
+ voiceId: z95.string().optional(),
20682
+ cameraMotion: z95.string().optional()
20683
+ }).catchall(z95.unknown());
20684
+ var FlightRecorderEntrySchema = z95.object({
20685
+ schemaVersion: z95.literal(1).optional(),
20686
+ id: z95.string().min(1),
20687
+ taskId: z95.string().min(1),
20688
+ runId: z95.string().min(1),
20689
+ sequence: z95.number().int().nonnegative(),
20690
+ timestamp: z95.string().min(1),
20691
+ provider: FlightRecorderProviderSchema.or(z95.string()),
20692
+ model: z95.string().min(1),
20693
+ prompt: z95.string(),
20694
+ durationSeconds: z95.number().nonnegative(),
20695
+ aspectRatio: z95.string().optional(),
20696
+ resolution: z95.string().optional(),
20697
+ startImageUrl: z95.string().optional(),
20698
+ endImageUrl: z95.string().optional(),
20699
+ generateAudio: z95.boolean().optional(),
19794
20700
  // Correlation & pipeline metadata
19795
- angleKey: z90.string().optional(),
19796
- sceneIndex: z90.number().int().nonnegative().optional(),
20701
+ angleKey: z95.string().optional(),
20702
+ sceneIndex: z95.number().int().nonnegative().optional(),
19797
20703
  generationType: FlightRecorderGenerationTypeSchema,
19798
- operationId: z90.string().min(1).optional(),
19799
- revisionId: z90.string().min(1).optional(),
19800
- attemptNumber: z90.number().int().nonnegative().default(1),
20704
+ operationId: z95.string().min(1).optional(),
20705
+ revisionId: z95.string().min(1).optional(),
20706
+ attemptNumber: z95.number().int().nonnegative().default(1),
19801
20707
  // Elements & Distillation
19802
- elements: z90.array(FlightRecorderElementSchema).optional(),
20708
+ elements: z95.array(FlightRecorderElementSchema).optional(),
19803
20709
  distillation: FlightRecorderDistillationSchema.optional(),
19804
20710
  // Raw payload (sanitized of secrets)
19805
- rawPayload: z90.record(z90.unknown())
20711
+ rawPayload: z95.record(z95.unknown())
19806
20712
  });
19807
- var FlightRecorderQuerySchema = z90.object({
19808
- taskId: z90.string().min(1),
19809
- runId: z90.string().optional(),
19810
- sceneIndex: z90.number().int().nonnegative().optional(),
19811
- angleKey: z90.string().optional(),
20713
+ var FlightRecorderQuerySchema = z95.object({
20714
+ taskId: z95.string().min(1),
20715
+ runId: z95.string().optional(),
20716
+ sceneIndex: z95.number().int().nonnegative().optional(),
20717
+ angleKey: z95.string().optional(),
19812
20718
  generationType: FlightRecorderGenerationTypeSchema.optional(),
19813
- cursor: z90.number().int().nonnegative().optional(),
19814
- limit: z90.number().int().positive().optional()
20719
+ cursor: z95.number().int().nonnegative().optional(),
20720
+ limit: z95.number().int().positive().optional()
19815
20721
  });
19816
- var FlightRecorderResponseSchema = z90.object({
19817
- taskId: z90.string().min(1),
19818
- runId: z90.string().min(1),
19819
- entries: z90.array(FlightRecorderEntrySchema),
20722
+ var FlightRecorderResponseSchema = z95.object({
20723
+ taskId: z95.string().min(1),
20724
+ runId: z95.string().min(1),
20725
+ entries: z95.array(FlightRecorderEntrySchema),
19820
20726
  lastCall: FlightRecorderEntrySchema.nullable(),
19821
- count: z90.number().int().nonnegative(),
19822
- nextCursor: z90.number().int().nonnegative().nullable()
20727
+ count: z95.number().int().nonnegative(),
20728
+ nextCursor: z95.number().int().nonnegative().nullable()
19823
20729
  });
19824
20730
 
19825
20731
  // ../../packages/types/src/video-script-requests.ts
19826
- import { z as z91 } from "zod";
19827
- var ApproveVideoScriptSceneEdit = z91.object({
19828
- index: z91.number().int().nonnegative().describe("\xCDndice de la escena (0-based, mismo que devuelve get_video_script)."),
19829
- dialogue: z91.string().trim().max(VIDEO_SCRIPT_APPROVAL_MAX_DIALOGUE_CHARS).describe('Di\xE1logo final de la escena. Puede ser el original sin cambios o la edici\xF3n del usuario. Vac\xEDo ("") s\xF3lo es v\xE1lido en escenas silenciosas por dise\xF1o (productOnly o \xE1ngulos winner-copy); en una escena hablada el backend lo rechaza con 400.')
20732
+ import { z as z96 } from "zod";
20733
+ var ApproveVideoScriptSceneEdit = z96.object({
20734
+ index: z96.number().int().nonnegative().describe("\xCDndice de la escena (0-based, mismo que devuelve get_video_script)."),
20735
+ dialogue: z96.string().trim().max(VIDEO_SCRIPT_APPROVAL_MAX_DIALOGUE_CHARS).describe('Di\xE1logo final de la escena. Puede ser el original sin cambios o la edici\xF3n del usuario. Vac\xEDo ("") s\xF3lo es v\xE1lido en escenas silenciosas por dise\xF1o (productOnly o \xE1ngulos winner-copy); en una escena hablada el backend lo rechaza con 400.')
19830
20736
  }).strict();
19831
- var ApproveVideoScriptCapabilityRequest = z91.object({
19832
- taskId: z91.string().min(1).describe("ID de la tarea."),
19833
- angleKey: z91.string().trim().min(1).max(120).optional().describe('Mismo angleKey usado en get_video_script. REQUERIDO en multi-angle (si se omite el backend resuelve a "angle_0" literal). En single-angle puede omitirse.'),
19834
- scenes: z91.array(ApproveVideoScriptSceneEdit).min(1).max(VIDEO_SCRIPT_APPROVAL_MAX_SCENES).describe("Escenas con los di\xE1logos finales. El backend mergea por `index` \u2014 las escenas NO incluidas conservan el di\xE1logo original. Debe haber entre 1 y 50 entradas. Para cada entrada que mandes con un dialogue distinto del original, el backend valida minWords \u2264 words \u2264 maxWords y rechaza con 400 si te sales del rango.")
20737
+ var ApproveVideoScriptCapabilityRequest = z96.object({
20738
+ taskId: z96.string().min(1).describe("ID de la tarea."),
20739
+ angleKey: z96.string().trim().min(1).max(120).optional().describe('Mismo angleKey usado en get_video_script. REQUERIDO en multi-angle (si se omite el backend resuelve a "angle_0" literal). En single-angle puede omitirse.'),
20740
+ scenes: z96.array(ApproveVideoScriptSceneEdit).min(1).max(VIDEO_SCRIPT_APPROVAL_MAX_SCENES).describe("Escenas con los di\xE1logos finales. El backend mergea por `index` \u2014 las escenas NO incluidas conservan el di\xE1logo original. Debe haber entre 1 y 50 entradas. Para cada entrada que mandes con un dialogue distinto del original, el backend valida minWords \u2264 words \u2264 maxWords y rechaza con 400 si te sales del rango.")
19835
20741
  }).strict();
19836
20742
  var REGENERATE_VIDEO_SCRIPT_NARRATIVE_STYLE_DESCRIPTION = 'Narrativa para el nuevo guion. Incluye valores hist\xF3ricos porque esta herramienta tambi\xE9n regenera tareas antiguas. REQUERIDO \u2014 el backend NO acepta "mantener la actual"; siempre tienes que elegir una. Si el usuario quiere re-rolear con la misma narrativa, pasa la que ya tiene el \xE1ngulo (la ves en get_video_script o en get_task_status).';
19837
- var RegenerateVideoScriptCapabilityRequest = z91.object({
19838
- taskId: z91.string().min(1).describe("ID de la tarea."),
19839
- angleKey: z91.string().min(1).describe('Clave del \xE1ngulo a regenerar. Single-angle: pasa "angle_0". Multi-angle: el mismo que devuelve get_video_script. NO se puede omitir \u2014 el backend lo exige siempre.'),
20743
+ var RegenerateVideoScriptCapabilityRequest = z96.object({
20744
+ taskId: z96.string().min(1).describe("ID de la tarea."),
20745
+ angleKey: z96.string().min(1).describe('Clave del \xE1ngulo a regenerar. Single-angle: pasa "angle_0". Multi-angle: el mismo que devuelve get_video_script. NO se puede omitir \u2014 el backend lo exige siempre.'),
19840
20746
  narrativeStyle: NarrativeStyle.describe(REGENERATE_VIDEO_SCRIPT_NARRATIVE_STYLE_DESCRIPTION),
19841
- narrativeSelection: z91.enum([
20747
+ narrativeSelection: z96.enum([
19842
20748
  "market",
19843
20749
  "guided"
19844
20750
  ]).optional().describe("Elecci\xF3n expl\xEDcita del usuario: market usa el estudio de mercado disponible; guided usa la narrativa elegida. Omitir conserva el comportamiento existente.")
19845
20751
  }).strict();
19846
20752
 
19847
20753
  // ../../packages/types/src/classic-landing-delivery.ts
19848
- import { z as z92 } from "zod";
19849
- var Url = z92.string().url().refine((value) => {
20754
+ import { z as z97 } from "zod";
20755
+ var Url = z97.string().url().refine((value) => {
19850
20756
  const url = new URL(value);
19851
20757
  return [
19852
20758
  "https:",
19853
20759
  "http:"
19854
20760
  ].includes(url.protocol) && !url.username && !url.password;
19855
20761
  }, "Invalid owned asset URL");
19856
- var ClassicLandingAssetBlockSchema = z92.discriminatedUnion("kind", [
19857
- z92.object({
19858
- kind: z92.literal("image"),
19859
- ownerTaskId: z92.string().uuid(),
19860
- sourceIndex: z92.number().int().positive(),
19861
- variantIndex: z92.number().int().nonnegative(),
20762
+ var ClassicLandingAssetBlockSchema = z97.discriminatedUnion("kind", [
20763
+ z97.object({
20764
+ kind: z97.literal("image"),
20765
+ ownerTaskId: z97.string().uuid(),
20766
+ sourceIndex: z97.number().int().positive(),
20767
+ variantIndex: z97.number().int().nonnegative(),
19862
20768
  url: Url,
19863
- role: z92.string(),
19864
- width: z92.number().positive().optional(),
19865
- height: z92.number().positive().optional()
20769
+ role: z97.string(),
20770
+ width: z97.number().positive().optional(),
20771
+ height: z97.number().positive().optional()
19866
20772
  }).strict(),
19867
- z92.object({
19868
- kind: z92.literal("gif"),
19869
- ownerTaskId: z92.string().uuid(),
19870
- gifId: z92.string().uuid(),
19871
- gifRevision: z92.number().int().nonnegative(),
20773
+ z97.object({
20774
+ kind: z97.literal("gif"),
20775
+ ownerTaskId: z97.string().uuid(),
20776
+ gifId: z97.string().uuid(),
20777
+ gifRevision: z97.number().int().nonnegative(),
19872
20778
  demo: LandingGifReadableSchema,
19873
- historicalDelivery: z92.literal(true).optional()
20779
+ historicalDelivery: z97.literal(true).optional()
19874
20780
  }).strict()
19875
20781
  ]);
19876
- var PublishedClassicLandingSchema = z92.object({
19877
- version: z92.literal(1),
19878
- ownerTaskId: z92.string().uuid(),
19879
- documentRevision: z92.number().int().nonnegative(),
19880
- ownerRevisions: z92.array(z92.object({
19881
- ownerTaskId: z92.string().uuid(),
19882
- landingRevision: z92.number().int().nonnegative()
20782
+ var PublishedClassicLandingSchema = z97.object({
20783
+ version: z97.literal(1),
20784
+ ownerTaskId: z97.string().uuid(),
20785
+ documentRevision: z97.number().int().nonnegative(),
20786
+ ownerRevisions: z97.array(z97.object({
20787
+ ownerTaskId: z97.string().uuid(),
20788
+ landingRevision: z97.number().int().nonnegative()
19883
20789
  }).strict()).max(100),
19884
- blocks: z92.array(ClassicLandingAssetBlockSchema).max(100)
20790
+ blocks: z97.array(ClassicLandingAssetBlockSchema).max(100)
19885
20791
  }).strict().superRefine((snapshot, ctx) => {
19886
20792
  const expectedOwners = /* @__PURE__ */ new Set([
19887
20793
  snapshot.ownerTaskId,
@@ -19889,14 +20795,14 @@ var PublishedClassicLandingSchema = z92.object({
19889
20795
  ]);
19890
20796
  const owners = snapshot.ownerRevisions.map((owner) => owner.ownerTaskId);
19891
20797
  if (new Set(owners).size !== owners.length || owners.length !== expectedOwners.size || owners.some((owner) => !expectedOwners.has(owner))) ctx.addIssue({
19892
- code: z92.ZodIssueCode.custom,
20798
+ code: z97.ZodIssueCode.custom,
19893
20799
  path: [
19894
20800
  "ownerRevisions"
19895
20801
  ],
19896
20802
  message: "Every published owner requires one revision fence"
19897
20803
  });
19898
20804
  if (snapshot.blocks.filter((block) => block.kind === "image").length > 20) ctx.addIssue({
19899
- code: z92.ZodIssueCode.custom,
20805
+ code: z97.ZodIssueCode.custom,
19900
20806
  path: [
19901
20807
  "blocks"
19902
20808
  ],
@@ -19906,7 +20812,7 @@ var PublishedClassicLandingSchema = z92.object({
19906
20812
  for (const block of snapshot.blocks) {
19907
20813
  const id = block.kind === "gif" ? `gif:${block.gifId}` : `image:${block.ownerTaskId}:${block.sourceIndex}`;
19908
20814
  if (ids.has(id)) ctx.addIssue({
19909
- code: z92.ZodIssueCode.custom,
20815
+ code: z97.ZodIssueCode.custom,
19910
20816
  message: "Duplicate published block"
19911
20817
  });
19912
20818
  ids.add(id);
@@ -19914,86 +20820,86 @@ var PublishedClassicLandingSchema = z92.object({
19914
20820
  ...block,
19915
20821
  state: "ready"
19916
20822
  }))) ctx.addIssue({
19917
- code: z92.ZodIssueCode.custom,
20823
+ code: z97.ZodIssueCode.custom,
19918
20824
  message: "Invalid published GIF"
19919
20825
  });
19920
20826
  }
19921
20827
  });
19922
20828
 
19923
20829
  // ../../packages/types/src/dropi-financial.ts
19924
- import { z as z93 } from "zod";
19925
- var DropiCountrySchema = z93.enum(DROPI_COUNTRY_CODES);
19926
- var DropiCountryQuerySchema = z93.object({
20830
+ import { z as z98 } from "zod";
20831
+ var DropiCountrySchema = z98.enum(DROPI_COUNTRY_CODES);
20832
+ var DropiCountryQuerySchema = z98.object({
19927
20833
  countryCode: DropiCountrySchema.default("CO")
19928
20834
  }).strict();
19929
- var ConnectDropiFinancialSchema = z93.object({
20835
+ var ConnectDropiFinancialSchema = z98.object({
19930
20836
  countryCode: DropiCountrySchema.default("CO"),
19931
- integrationKey: z93.string().trim().min(1).max(4096).regex(/^[\x21-\x7e]+$/)
20837
+ integrationKey: z98.string().trim().min(1).max(4096).regex(/^[\x21-\x7e]+$/)
19932
20838
  }).strict();
19933
- var SyncDropiFinancialSchema = z93.object({
20839
+ var SyncDropiFinancialSchema = z98.object({
19934
20840
  countryCode: DropiCountrySchema.optional(),
19935
- operationId: z93.string().uuid().optional(),
19936
- since: z93.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(),
19937
- until: z93.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional()
20841
+ operationId: z98.string().uuid().optional(),
20842
+ since: z98.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional(),
20843
+ until: z98.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional()
19938
20844
  }).strict();
19939
- var connectionCountries = z93.array(DropiCountrySchema).max(DROPI_COUNTRY_CODES.length).refine((countries) => new Set(countries).size === countries.length);
19940
- var DropiFinancialConnectionsSchema = z93.object({
20845
+ var connectionCountries = z98.array(DropiCountrySchema).max(DROPI_COUNTRY_CODES.length).refine((countries) => new Set(countries).size === countries.length);
20846
+ var DropiFinancialConnectionsSchema = z98.object({
19941
20847
  connectedCountries: connectionCountries,
19942
20848
  /** Effective connect availability after flags, proxy and scoped-identity readiness. */
19943
20849
  enabledCountries: connectionCountries
19944
20850
  }).strict();
19945
- var DropiFinancialStatusSchema = z93.object({
19946
- enabled: z93.boolean(),
19947
- connected: z93.boolean(),
20851
+ var DropiFinancialStatusSchema = z98.object({
20852
+ enabled: z98.boolean(),
20853
+ connected: z98.boolean(),
19948
20854
  countryCode: DropiCountrySchema,
19949
20855
  /** Configured environment allowlist; selected-country availability is `enabled`. */
19950
- enabledCountries: z93.array(DropiCountrySchema).optional(),
19951
- environment: z93.enum([
20856
+ enabledCountries: z98.array(DropiCountrySchema).optional(),
20857
+ environment: z98.enum([
19952
20858
  "sandbox",
19953
20859
  "production"
19954
20860
  ]),
19955
- lastSyncAt: z93.string().nullable(),
19956
- lastError: z93.string().nullable(),
19957
- historyNext: z93.string().nullable(),
19958
- historyUntil: z93.string().nullable(),
19959
- changesThrough: z93.string().nullable(),
19960
- manualNext: z93.string().nullable(),
19961
- manual: z93.object({
19962
- since: z93.string(),
19963
- until: z93.string(),
19964
- next: z93.string().nullable()
20861
+ lastSyncAt: z98.string().nullable(),
20862
+ lastError: z98.string().nullable(),
20863
+ historyNext: z98.string().nullable(),
20864
+ historyUntil: z98.string().nullable(),
20865
+ changesThrough: z98.string().nullable(),
20866
+ manualNext: z98.string().nullable(),
20867
+ manual: z98.object({
20868
+ since: z98.string(),
20869
+ until: z98.string(),
20870
+ next: z98.string().nullable()
19965
20871
  }).nullable(),
19966
- retentionSince: z93.string()
19967
- });
19968
- var DropiFinancialSyncResultSchema = z93.object({
19969
- orders: z93.number().int().nonnegative(),
19970
- written: z93.number().int().nonnegative(),
19971
- updated: z93.number().int().nonnegative(),
19972
- pending: z93.boolean(),
19973
- next: z93.string().nullable(),
19974
- historyNext: z93.string().nullable(),
19975
- changesThrough: z93.string().nullable(),
19976
- since: z93.string(),
19977
- until: z93.string(),
19978
- unmatched: z93.array(z93.object({
19979
- externalProductId: z93.string(),
19980
- orders: z93.number().int().nonnegative()
20872
+ retentionSince: z98.string()
20873
+ });
20874
+ var DropiFinancialSyncResultSchema = z98.object({
20875
+ orders: z98.number().int().nonnegative(),
20876
+ written: z98.number().int().nonnegative(),
20877
+ updated: z98.number().int().nonnegative(),
20878
+ pending: z98.boolean(),
20879
+ next: z98.string().nullable(),
20880
+ historyNext: z98.string().nullable(),
20881
+ changesThrough: z98.string().nullable(),
20882
+ since: z98.string(),
20883
+ until: z98.string(),
20884
+ unmatched: z98.array(z98.object({
20885
+ externalProductId: z98.string(),
20886
+ orders: z98.number().int().nonnegative()
19981
20887
  }))
19982
20888
  });
19983
20889
 
19984
20890
  // ../../packages/types/src/service-website-capture.ts
19985
- import { z as z94 } from "zod";
20891
+ import { z as z99 } from "zod";
19986
20892
  var WEBSITE_CAPTURE_MAX_RESEARCH_BYTES = 1024 * 1024;
19987
20893
  var WEBSITE_CAPTURE_MAX_FILES = 100;
19988
20894
  var WEBSITE_CAPTURE_MAX_FILE_BYTES = 8 * 1024 * 1024;
19989
20895
  var WEBSITE_CAPTURE_MAX_BUNDLE_BYTES = 30 * 1024 * 1024;
19990
- var WebsiteCaptureCauseSchema = z94.enum([
20896
+ var WebsiteCaptureCauseSchema = z99.enum([
19991
20897
  "site_blocked",
19992
20898
  "site_unreachable",
19993
20899
  "not_enough_content",
19994
20900
  "internal"
19995
20901
  ]);
19996
- var WebsiteCaptureStatusSchema = z94.enum([
20902
+ var WebsiteCaptureStatusSchema = z99.enum([
19997
20903
  "queued",
19998
20904
  "capturing",
19999
20905
  "ready",
@@ -20015,128 +20921,128 @@ function normalizeWebsiteCaptureUrl(value) {
20015
20921
  }
20016
20922
  }
20017
20923
  __name(normalizeWebsiteCaptureUrl, "normalizeWebsiteCaptureUrl");
20018
- var WebsiteCaptureRequestSchema = z94.object({
20019
- url: z94.string().trim().max(2048).url().refine((value) => normalizeWebsiteCaptureUrl(value) !== null, "Use an HTTP(S) URL without credentials").transform((value) => normalizeWebsiteCaptureUrl(value)),
20924
+ var WebsiteCaptureRequestSchema = z99.object({
20925
+ url: z99.string().trim().max(2048).url().refine((value) => normalizeWebsiteCaptureUrl(value) !== null, "Use an HTTP(S) URL without credentials").transform((value) => normalizeWebsiteCaptureUrl(value)),
20020
20926
  language: MotionGraphicsLanguageSchema
20021
20927
  }).strict();
20022
- var WebsiteCaptureResponseSchema = z94.object({
20023
- captureId: z94.string().uuid(),
20928
+ var WebsiteCaptureResponseSchema = z99.object({
20929
+ captureId: z99.string().uuid(),
20024
20930
  status: WebsiteCaptureStatusSchema,
20025
- expiresAt: z94.string().datetime(),
20026
- previewUrl: z94.string().url().optional(),
20931
+ expiresAt: z99.string().datetime(),
20932
+ previewUrl: z99.string().url().optional(),
20027
20933
  cause: WebsiteCaptureCauseSchema.optional()
20028
20934
  });
20029
20935
  var WebsiteCaptureJobSchema = WebsiteCaptureRequestSchema.extend({
20030
- captureId: z94.string().uuid(),
20031
- attempt: z94.number().int().positive(),
20032
- leaseUntil: z94.string().datetime()
20936
+ captureId: z99.string().uuid(),
20937
+ attempt: z99.number().int().positive(),
20938
+ leaseUntil: z99.string().datetime()
20033
20939
  });
20034
- var WebsiteCaptureClaimResponseSchema = z94.object({
20940
+ var WebsiteCaptureClaimResponseSchema = z99.object({
20035
20941
  capture: WebsiteCaptureJobSchema.nullable()
20036
20942
  });
20037
20943
  var attempt = {
20038
- attempt: z94.number().int().positive()
20944
+ attempt: z99.number().int().positive()
20039
20945
  };
20040
- var digest = z94.string().regex(/^[a-f0-9]{64}$/);
20041
- var WebsiteCaptureUploadRequestSchema = z94.object({
20946
+ var digest = z99.string().regex(/^[a-f0-9]{64}$/);
20947
+ var WebsiteCaptureUploadRequestSchema = z99.object({
20042
20948
  ...attempt,
20043
- contentLength: z94.number().int().positive().max(WEBSITE_CAPTURE_MAX_BUNDLE_BYTES),
20949
+ contentLength: z99.number().int().positive().max(WEBSITE_CAPTURE_MAX_BUNDLE_BYTES),
20044
20950
  sha256: digest
20045
20951
  }).strict();
20046
- var WebsiteCaptureDoneRequestSchema = z94.object({
20952
+ var WebsiteCaptureDoneRequestSchema = z99.object({
20047
20953
  ...attempt,
20048
20954
  sha256: digest
20049
20955
  }).strict();
20050
- var WebsiteCaptureFailedRequestSchema = z94.object({
20956
+ var WebsiteCaptureFailedRequestSchema = z99.object({
20051
20957
  ...attempt,
20052
20958
  cause: WebsiteCaptureCauseSchema
20053
20959
  }).strict();
20054
- var WebsiteCaptureBundleSchema = z94.object({
20055
- version: z94.literal(1),
20056
- files: z94.array(z94.object({
20057
- path: z94.string().max(140).regex(/^research\/(?:page\.json|(?:desktop|mobile)-[1-9]\d*\.jpg|logo\.(?:png|svg)|image-[1-9]\d*\.(?:png|jpg|jpeg|webp|svg|avif)|font-[1-9]\d*\.(?:woff2?|ttf|otf))$/),
20058
- base64: z94.string().max(Math.ceil(WEBSITE_CAPTURE_MAX_FILE_BYTES / 3) * 4).regex(/^[A-Za-z0-9+/]*={0,2}$/).refine((value) => value.length % 4 === 0),
20960
+ var WebsiteCaptureBundleSchema = z99.object({
20961
+ version: z99.literal(1),
20962
+ files: z99.array(z99.object({
20963
+ path: z99.string().max(140).regex(/^research\/(?:page\.json|(?:desktop|mobile)-[1-9]\d*\.jpg|logo\.(?:png|svg)|image-[1-9]\d*\.(?:png|jpg|jpeg|webp|svg|avif)|font-[1-9]\d*\.(?:woff2?|ttf|otf))$/),
20964
+ base64: z99.string().max(Math.ceil(WEBSITE_CAPTURE_MAX_FILE_BYTES / 3) * 4).regex(/^[A-Za-z0-9+/]*={0,2}$/).refine((value) => value.length % 4 === 0),
20059
20965
  sha256: digest
20060
20966
  }).strict()).min(1).max(WEBSITE_CAPTURE_MAX_FILES)
20061
20967
  }).strict().refine((bundle) => new Set(bundle.files.map((file) => file.path)).size === bundle.files.length, "Duplicate capture file");
20062
- var WebsiteCaptureScreenshotSchema = z94.object({
20063
- file: z94.string(),
20064
- scrollTop: z94.number()
20065
- });
20066
- var WebsiteCaptureAccessSchema = z94.object({
20067
- publicContentText: z94.string().max(8e3),
20068
- passwordGate: z94.boolean(),
20069
- challengeGate: z94.boolean(),
20070
- blockingOverlay: z94.boolean()
20071
- });
20072
- var WebsiteCaptureResearchSchema = z94.object({
20073
- requestedUrl: z94.string().url(),
20074
- capturedAt: z94.string().datetime(),
20075
- locale: z94.string(),
20076
- bodyTextTruncated: z94.boolean(),
20077
- finalUrl: z94.string().url(),
20078
- lang: z94.string().nullable(),
20079
- title: z94.string(),
20080
- description: z94.string(),
20081
- openGraph: z94.object({
20082
- title: z94.string(),
20083
- description: z94.string(),
20084
- image: z94.string(),
20085
- siteName: z94.string()
20968
+ var WebsiteCaptureScreenshotSchema = z99.object({
20969
+ file: z99.string(),
20970
+ scrollTop: z99.number()
20971
+ });
20972
+ var WebsiteCaptureAccessSchema = z99.object({
20973
+ publicContentText: z99.string().max(8e3),
20974
+ passwordGate: z99.boolean(),
20975
+ challengeGate: z99.boolean(),
20976
+ blockingOverlay: z99.boolean()
20977
+ });
20978
+ var WebsiteCaptureResearchSchema = z99.object({
20979
+ requestedUrl: z99.string().url(),
20980
+ capturedAt: z99.string().datetime(),
20981
+ locale: z99.string(),
20982
+ bodyTextTruncated: z99.boolean(),
20983
+ finalUrl: z99.string().url(),
20984
+ lang: z99.string().nullable(),
20985
+ title: z99.string(),
20986
+ description: z99.string(),
20987
+ openGraph: z99.object({
20988
+ title: z99.string(),
20989
+ description: z99.string(),
20990
+ image: z99.string(),
20991
+ siteName: z99.string()
20086
20992
  }),
20087
- themeColor: z94.string(),
20088
- headings: z94.object({
20089
- h1: z94.array(z94.string()),
20090
- h2: z94.array(z94.string()),
20091
- h3: z94.array(z94.string())
20993
+ themeColor: z99.string(),
20994
+ headings: z99.object({
20995
+ h1: z99.array(z99.string()),
20996
+ h2: z99.array(z99.string()),
20997
+ h3: z99.array(z99.string())
20092
20998
  }),
20093
- callsToAction: z94.array(z94.string()),
20094
- listItems: z94.array(z94.string()),
20095
- bodyText: z94.string(),
20999
+ callsToAction: z99.array(z99.string()),
21000
+ listItems: z99.array(z99.string()),
21001
+ bodyText: z99.string(),
20096
21002
  access: WebsiteCaptureAccessSchema.optional(),
20097
- consent: z94.object({
20098
- pressed: z94.string().nullable(),
20099
- removed: z94.number().nonnegative()
21003
+ consent: z99.object({
21004
+ pressed: z99.string().nullable(),
21005
+ removed: z99.number().nonnegative()
20100
21006
  }).optional(),
20101
- overlaysDismissed: z94.number().int().nonnegative().optional(),
20102
- style: z94.object({
20103
- bodyBackground: z94.string(),
20104
- bodyColor: z94.string(),
20105
- bodyFont: z94.string(),
20106
- headingFont: z94.string().nullable(),
20107
- headingColor: z94.string().nullable(),
20108
- actionColors: z94.array(z94.object({
20109
- color: z94.string(),
20110
- uses: z94.number()
21007
+ overlaysDismissed: z99.number().int().nonnegative().optional(),
21008
+ style: z99.object({
21009
+ bodyBackground: z99.string(),
21010
+ bodyColor: z99.string(),
21011
+ bodyFont: z99.string(),
21012
+ headingFont: z99.string().nullable(),
21013
+ headingColor: z99.string().nullable(),
21014
+ actionColors: z99.array(z99.object({
21015
+ color: z99.string(),
21016
+ uses: z99.number()
20111
21017
  }))
20112
21018
  }),
20113
- images: z94.array(z94.object({
20114
- file: z94.string(),
20115
- src: z94.string(),
20116
- alt: z94.string(),
20117
- width: z94.number().nullable(),
20118
- height: z94.number().nullable(),
20119
- isOpenGraph: z94.boolean()
21019
+ images: z99.array(z99.object({
21020
+ file: z99.string(),
21021
+ src: z99.string(),
21022
+ alt: z99.string(),
21023
+ width: z99.number().nullable(),
21024
+ height: z99.number().nullable(),
21025
+ isOpenGraph: z99.boolean()
20120
21026
  })),
20121
- logo: z94.object({
20122
- file: z94.literal("logo.png"),
20123
- svg: z94.literal("logo.svg").optional(),
20124
- width: z94.number(),
20125
- height: z94.number()
21027
+ logo: z99.object({
21028
+ file: z99.literal("logo.png"),
21029
+ svg: z99.literal("logo.svg").optional(),
21030
+ width: z99.number(),
21031
+ height: z99.number()
20126
21032
  }).nullable(),
20127
- fonts: z94.array(z94.object({
20128
- family: z94.string(),
20129
- weight: z94.string(),
20130
- style: z94.string(),
20131
- unicodeRange: z94.string().nullable(),
20132
- file: z94.string().optional()
21033
+ fonts: z99.array(z99.object({
21034
+ family: z99.string(),
21035
+ weight: z99.string(),
21036
+ style: z99.string(),
21037
+ unicodeRange: z99.string().nullable(),
21038
+ file: z99.string().optional()
20133
21039
  }).transform((font) => ({
20134
21040
  ...font,
20135
21041
  file: font.file
20136
21042
  }))),
20137
- screenshots: z94.object({
20138
- desktop: z94.array(WebsiteCaptureScreenshotSchema),
20139
- mobile: z94.array(WebsiteCaptureScreenshotSchema)
21043
+ screenshots: z99.object({
21044
+ desktop: z99.array(WebsiteCaptureScreenshotSchema),
21045
+ mobile: z99.array(WebsiteCaptureScreenshotSchema)
20140
21046
  })
20141
21047
  });
20142
21048
 
@@ -20382,7 +21288,7 @@ var ApiClient = class {
20382
21288
  };
20383
21289
 
20384
21290
  // src/index.ts
20385
- var MCP_VERSION = "11.1.0";
21291
+ var MCP_VERSION = "11.1.1";
20386
21292
 
20387
21293
  // src/meta-upload-app.ts
20388
21294
  import { readFileSync } from "fs";
@@ -20454,7 +21360,7 @@ function registerMediaUploadAppResource(server, resolveEndpoint) {
20454
21360
  __name(registerMediaUploadAppResource, "registerMediaUploadAppResource");
20455
21361
 
20456
21362
  // src/tools/tasks.ts
20457
- import { z as z99 } from "zod";
21363
+ import { z as z104 } from "zod";
20458
21364
 
20459
21365
  // src/resolve-image.ts
20460
21366
  import { lookup as dnsLookup } from "dns/promises";
@@ -21015,9 +21921,9 @@ async function resolveMediaRef(ref, opts) {
21015
21921
  __name(resolveMediaRef, "resolveMediaRef");
21016
21922
 
21017
21923
  // src/tools/shared.ts
21018
- import { z as z95 } from "zod";
21019
- var Lang = z95.string().regex(/^[a-z]{2}(?:[-_][a-zA-Z]{2})?$/, "Usa un c\xF3digo de idioma BCP-47, por ejemplo es, en-US o pt-BR").max(10);
21020
- var Country = z95.string().min(2).max(3);
21924
+ import { z as z100 } from "zod";
21925
+ var Lang = z100.string().regex(/^[a-z]{2}(?:[-_][a-zA-Z]{2})?$/, "Usa un c\xF3digo de idioma BCP-47, por ejemplo es, en-US o pt-BR").max(10);
21926
+ var Country = z100.string().min(2).max(3);
21021
21927
  var LandingStrategyEnum = LandingStrategySchema;
21022
21928
  var LandingImageFormatEnum = LandingImageFormatSchema;
21023
21929
  var VideoPresetEnum = VideoPreset.extract([
@@ -21121,7 +22027,7 @@ function animationStyleApplies(videoPreset, angleNarratives) {
21121
22027
  return ANIMATED_VIDEO_PRESETS.has(videoPreset ?? "") || (angleNarratives ?? []).some((n) => ANIMATED_NARRATIVE_STYLES.has(n));
21122
22028
  }
21123
22029
  __name(animationStyleApplies, "animationStyleApplies");
21124
- var VideoTierEnum = z95.enum([
22030
+ var VideoTierEnum = z100.enum([
21125
22031
  "basic"
21126
22032
  ]);
21127
22033
  function resolveVideoTier(_tier) {
@@ -21179,10 +22085,10 @@ var ImageCreativeStyleEnum = ImageCreativeStyle;
21179
22085
  var ImageCreativeArchetypeEnum = ImageCreativeArchetype;
21180
22086
  var ImageCreativeVisualTreatmentEnum = ImageCreativeVisualTreatment;
21181
22087
  var ImageCreativeAspectRatioEnum = ImageCreativeAspectRatio;
21182
- var ImageRefSchema = z95.object({
21183
- url: z95.string().url().optional().describe('URL p\xFAblica HTTPS de la foto. Ej: una URL de Shopify CDN, Cloudinary, Imgur. \xDAsala cuando el usuario te diga "est\xE1 en X.com/foto.jpg" o cuando la foto ya est\xE9 hospedada.'),
21184
- path: z95.string().min(1).optional().describe('Ruta del archivo en el computador del usuario. Ej: "/Users/maria/Desktop/foto.jpg", "~/Pictures/camiseta.png", "C:\\Users\\Maria\\Desktop\\foto.jpg". El MCP local la lee del disco y la sube. SOLO funciona cuando el MCP corre local (stdio). NO funciona en mcp.productmaker.app (HTTP) \u2014 ah\xED usa `url`.'),
21185
- assetId: z95.string().uuid().optional().describe("ID opaco devuelto por check_media_upload. \xDAsalo para una imagen subida desde el MCP App; ProductMaker adopta el archivo directamente y el MCP nunca descarga sus bytes.")
22088
+ var ImageRefSchema = z100.object({
22089
+ url: z100.string().url().optional().describe('URL p\xFAblica HTTPS de la foto. Ej: una URL de Shopify CDN, Cloudinary, Imgur. \xDAsala cuando el usuario te diga "est\xE1 en X.com/foto.jpg" o cuando la foto ya est\xE9 hospedada.'),
22090
+ path: z100.string().min(1).optional().describe('Ruta del archivo en el computador del usuario. Ej: "/Users/maria/Desktop/foto.jpg", "~/Pictures/camiseta.png", "C:\\Users\\Maria\\Desktop\\foto.jpg". El MCP local la lee del disco y la sube. SOLO funciona cuando el MCP corre local (stdio). NO funciona en mcp.productmaker.app (HTTP) \u2014 ah\xED usa `url`.'),
22091
+ assetId: z100.string().uuid().optional().describe("ID opaco devuelto por check_media_upload. \xDAsalo para una imagen subida desde el MCP App; ProductMaker adopta el archivo directamente y el MCP nunca descarga sus bytes.")
21186
22092
  }).refine((v) => [
21187
22093
  v.url,
21188
22094
  v.path,
@@ -21190,11 +22096,11 @@ var ImageRefSchema = z95.object({
21190
22096
  ].filter(Boolean).length === 1, {
21191
22097
  message: "each image entry must have exactly one of `url`, `path`, or `assetId`"
21192
22098
  });
21193
- var ImagesInput = z95.array(ImageRefSchema).min(1).max(5).superRefine((images, ctx) => {
22099
+ var ImagesInput = z100.array(ImageRefSchema).min(1).max(5).superRefine((images, ctx) => {
21194
22100
  const assetCount = images.filter((image) => Boolean(image.assetId)).length;
21195
22101
  if (assetCount > 0 && assetCount !== images.length) {
21196
22102
  ctx.addIssue({
21197
- code: z95.ZodIssueCode.custom,
22103
+ code: z100.ZodIssueCode.custom,
21198
22104
  message: "all image entries must use assetId, or all must use URL/path sources"
21199
22105
  });
21200
22106
  }
@@ -21215,10 +22121,10 @@ function asText(value) {
21215
22121
  };
21216
22122
  }
21217
22123
  __name(asText, "asText");
21218
- function isRecord2(v) {
22124
+ function isRecord3(v) {
21219
22125
  return typeof v === "object" && v !== null && !Array.isArray(v);
21220
22126
  }
21221
- __name(isRecord2, "isRecord");
22127
+ __name(isRecord3, "isRecord");
21222
22128
  function escapeMdLabel(s) {
21223
22129
  return s.replace(/[[\](){}\x60<>\r\n\\*_]/g, " ").replace(/\s+/g, " ").trim();
21224
22130
  }
@@ -21267,14 +22173,14 @@ async function submitCreative(api, opts) {
21267
22173
  });
21268
22174
  }
21269
22175
  __name(submitCreative, "submitCreative");
21270
- var ResearchTargetCountryEnum = z95.enum([
22176
+ var ResearchTargetCountryEnum = z100.enum([
21271
22177
  "CO",
21272
22178
  "MX",
21273
22179
  "PE",
21274
22180
  "EC",
21275
22181
  "CL"
21276
22182
  ]);
21277
- var ResearchCategoryEnum = z95.enum([
22183
+ var ResearchCategoryEnum = z100.enum([
21278
22184
  "auto",
21279
22185
  "automotive",
21280
22186
  "kitchen",
@@ -21892,7 +22798,7 @@ function translateError(err) {
21892
22798
  return mcp(code, err.message);
21893
22799
  }
21894
22800
  if (err instanceof ApiHttpError) {
21895
- const body = isRecord2(err.body) ? err.body : {};
22801
+ const body = isRecord3(err.body) ? err.body : {};
21896
22802
  if (body.code === McpErrorCode.SHOPIFY_PUBLISH_INPUT_REQUIRED || body.code === McpErrorCode.SHOPIFY_PUBLISH_CONTEXT_CHANGED || body.code === McpErrorCode.SHOPIFY_PUBLISH_CORRECTION_REQUIRES_EDITOR || body.code === McpErrorCode.SHOPIFY_PUBLISH_CORRECTION_NOT_CONVERGED || body.code === McpErrorCode.SHOPIFY_PUBLISH_VERIFICATION_FAILED || body.code === McpErrorCode.SHOPIFY_PUBLISH_TARGET_INCOMPATIBLE || body.code === McpErrorCode.SHOPIFY_THEME_SETUP_REQUIRED || body.code === McpErrorCode.SHOPIFY_PUBLISH_FAILED) {
21897
22803
  const parsed = ShopifyPublishErrorResponse.safeParse(body);
21898
22804
  if (!parsed.success) return mcp(McpErrorCode.INTERNAL, resolveMessage(McpErrorCode.INTERNAL, void 0));
@@ -22639,29 +23545,29 @@ ${parsed.data.error ? `${escapeMarkdownText(parsed.data.error)}
22639
23545
  __name(renderVideoScriptMarkdown, "renderVideoScriptMarkdown");
22640
23546
 
22641
23547
  // src/tools/media-presentation.ts
22642
- import { z as z96 } from "zod";
22643
- var HttpsPresentationUrlSchema = z96.string().url().max(2048).refine((value) => new URL(value).protocol === "https:");
23548
+ import { z as z101 } from "zod";
23549
+ var HttpsPresentationUrlSchema = z101.string().url().max(2048).refine((value) => new URL(value).protocol === "https:");
22644
23550
  var ProductMakerPreviewUrlSchema = HttpsPresentationUrlSchema.refine((value) => {
22645
23551
  const hostname = new URL(value).hostname.toLowerCase();
22646
23552
  return hostname === "productmaker.app" || hostname.endsWith(".productmaker.app");
22647
23553
  }, "preview URL must be owned by ProductMaker");
22648
- var positiveIntAtMost = /* @__PURE__ */ __name((maximum) => z96.number().int().positive().max(maximum), "positiveIntAtMost");
22649
- var PresentationImageSchema = z96.object({
22650
- kind: z96.literal("image"),
23554
+ var positiveIntAtMost = /* @__PURE__ */ __name((maximum) => z101.number().int().positive().max(maximum), "positiveIntAtMost");
23555
+ var PresentationImageSchema = z101.object({
23556
+ kind: z101.literal("image"),
22651
23557
  url: HttpsPresentationUrlSchema,
22652
- mimeType: z96.enum([
23558
+ mimeType: z101.enum([
22653
23559
  "image/jpeg",
22654
23560
  "image/png"
22655
23561
  ]),
22656
23562
  byteSize: positiveIntAtMost(5 * 1024 * 1024),
22657
23563
  width: positiveIntAtMost(16384),
22658
23564
  height: positiveIntAtMost(16384),
22659
- alt: z96.string().trim().min(1).max(240)
23565
+ alt: z101.string().trim().min(1).max(240)
22660
23566
  }).strict();
22661
23567
  var McpMediaPresentationSchema = PresentationImageSchema;
22662
- var GalleryImageSchema = z96.object({
23568
+ var GalleryImageSchema = z101.object({
22663
23569
  url: ProductMakerPreviewUrlSchema,
22664
- alt: z96.string().trim().min(1).max(240)
23570
+ alt: z101.string().trim().min(1).max(240)
22665
23571
  });
22666
23572
  var MCP_GALLERY_IMAGE_MAX_BYTES = 10 * 1024 * 1024;
22667
23573
  async function imageBlocks(image, transport) {
@@ -22718,12 +23624,12 @@ async function buildMcpMediaPresentationContent(rawPresentation, transport = "ht
22718
23624
  ];
22719
23625
  }
22720
23626
  __name(buildMcpMediaPresentationContent, "buildMcpMediaPresentationContent");
22721
- var OwnedImagePreviewSchema = z96.object({
23627
+ var OwnedImagePreviewSchema = z101.object({
22722
23628
  url: HttpsPresentationUrlSchema.refine((value) => {
22723
23629
  const url = new URL(value);
22724
23630
  return !url.username && !url.password && !isPrivateHost(url.hostname);
22725
23631
  }, "Preview URL must be public HTTPS without credentials"),
22726
- alt: z96.string().trim().min(1).max(240)
23632
+ alt: z101.string().trim().min(1).max(240)
22727
23633
  });
22728
23634
  async function buildMcpImagePreviewContent(rawPreview, transport = "http") {
22729
23635
  const preview2 = OwnedImagePreviewSchema.safeParse(rawPreview);
@@ -22806,7 +23712,7 @@ async function buildMcpImageGalleryContent(rawItems, transport = "http") {
22806
23712
  __name(buildMcpImageGalleryContent, "buildMcpImageGalleryContent");
22807
23713
 
22808
23714
  // src/tools/animated-video.ts
22809
- import { z as z97 } from "zod";
23715
+ import { z as z102 } from "zod";
22810
23716
 
22811
23717
  // src/tools/paid-confirmation.ts
22812
23718
  function describeMarketStudyChoice(enabled) {
@@ -22919,17 +23825,17 @@ function sortCanonical(items) {
22919
23825
  });
22920
23826
  }
22921
23827
  __name(sortCanonical, "sortCanonical");
22922
- function isRecord3(value) {
23828
+ function isRecord4(value) {
22923
23829
  return typeof value === "object" && value !== null && !Array.isArray(value);
22924
23830
  }
22925
- __name(isRecord3, "isRecord");
23831
+ __name(isRecord4, "isRecord");
22926
23832
  function collectLanguageCodes(value, out) {
22927
23833
  if (Array.isArray(value)) {
22928
23834
  const items = value;
22929
23835
  for (const item of items) collectLanguageCodes(item, out);
22930
23836
  return out;
22931
23837
  }
22932
- if (!isRecord3(value)) return out;
23838
+ if (!isRecord4(value)) return out;
22933
23839
  for (const [key, entry] of Object.entries(value)) {
22934
23840
  if (LANGUAGE_FIELDS.has(key) && typeof entry === "string") {
22935
23841
  const base = entry.trim().split(/[-_]/)[0]?.toLowerCase();
@@ -22975,7 +23881,7 @@ function normalizeForKey(value, languages) {
22975
23881
  const items = value;
22976
23882
  return items.map((item) => normalizeForKey(item, languages));
22977
23883
  }
22978
- if (!isRecord3(value)) return value;
23884
+ if (!isRecord4(value)) return value;
22979
23885
  const out = {};
22980
23886
  for (const [key, entry] of Object.entries(value)) {
22981
23887
  if (PARAPHRASE_PRONE_FIELDS.has(key)) {
@@ -23047,25 +23953,25 @@ function animatedVideoMaxPriceText(durationSec) {
23047
23953
  return `m\xE1ximo ${animatedVideoCredits(durationSec)} cr\xE9ditos (se devuelve lo que no use)`;
23048
23954
  }
23049
23955
  __name(animatedVideoMaxPriceText, "animatedVideoMaxPriceText");
23050
- var DurationInput = z97.union(MOTION_GRAPHICS_DURATIONS.map((d) => z97.literal(d)));
23051
- var CreateAnimatedVideoInput = z97.object({
23052
- action: z97.enum([
23956
+ var DurationInput = z102.union(MOTION_GRAPHICS_DURATIONS.map((d) => z102.literal(d)));
23957
+ var CreateAnimatedVideoInput = z102.object({
23958
+ action: z102.enum([
23053
23959
  "prepare",
23054
23960
  "status",
23055
23961
  "cancel",
23056
23962
  "generate"
23057
23963
  ]).default("prepare").describe("prepare inicia una captura gratuita; status consulta websiteCaptureId; cancel la cancela; generate requiere captura ready y confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrar vista previa y precio."),
23058
- websiteCaptureId: z97.string().uuid().optional().describe("ID de la captura preparada. Obligatorio para status/cancel/generate; no inventarlo."),
23059
- generationRequestId: z97.string().uuid().optional().describe("Identidad opcional de una generaci\xF3n confirmada. Repite el mismo UUID al recuperar una respuesta perdida; usa otro \xFAnicamente cuando el usuario pida y confirme otro video, nunca por un error de transporte."),
23060
- confirmed: z97.boolean().optional().describe("Solo true despu\xE9s de que el usuario confirme esta captura, formato, duraci\xF3n, idioma y precio. Obligatorio para generate; preparar no genera ni cobra."),
23964
+ websiteCaptureId: z102.string().uuid().optional().describe("ID de la captura preparada. Obligatorio para status/cancel/generate; no inventarlo."),
23965
+ generationRequestId: z102.string().uuid().optional().describe("Identidad opcional de una generaci\xF3n confirmada. Repite el mismo UUID al recuperar una respuesta perdida; usa otro \xFAnicamente cuando el usuario pida y confirme otro video, nunca por un error de transporte."),
23966
+ confirmed: z102.boolean().optional().describe("Solo true despu\xE9s de que el usuario confirme esta captura, formato, duraci\xF3n, idioma y precio. Obligatorio para generate; preparar no genera ni cobra."),
23061
23967
  // Plain text, not `.url()`: users type «cal.com», and the web accepts it.
23062
23968
  // normalizeWebAddress (shared with the web) adds https:// and refuses
23063
23969
  // anything that is not a public http(s) address.
23064
- landingUrl: z97.string().trim().min(1).optional().describe("Enlace p\xFAblico de la p\xE1gina del servicio, como lo dio el usuario (\xABcal.com\xBB o \xABhttps://cal.com\xBB). El video sale de lo que muestra esa p\xE1gina: su marca, colores y mensajes."),
23970
+ landingUrl: z102.string().trim().min(1).optional().describe("Enlace p\xFAblico de la p\xE1gina del servicio, como lo dio el usuario (\xABcal.com\xBB o \xABhttps://cal.com\xBB). El video sale de lo que muestra esa p\xE1gina: su marca, colores y mensajes."),
23065
23971
  format: MotionGraphicsFormatSchema.optional().describe('Formato: "vertical" (9:16, Reels/TikTok), "square" (1:1, feed) u "horizontal" (16:9, YouTube/web). Si el usuario no lo dijo, PREG\xDANTALE.'),
23066
23972
  durationSec: DurationInput.optional().describe(`Duraci\xF3n en segundos: ${MOTION_GRAPHICS_DURATIONS.join(", ")}. Fija el precio (ver la descripci\xF3n de la herramienta). Si el usuario no la dijo, PREG\xDANTALE.`),
23067
23973
  language: MotionGraphicsLanguageSchema.optional().describe('Idioma de los textos del video: "es", "en" o "pt".'),
23068
- notes: z97.string().trim().max(MOTION_GRAPHICS_NOTES_MAX_CHARS).optional().describe("Opcional. Indicaciones para el video en lenguaje natural (ej. enf\xF3cate en los precios, tono m\xE1s formal, menciona la prueba gratis).")
23974
+ notes: z102.string().trim().max(MOTION_GRAPHICS_NOTES_MAX_CHARS).optional().describe("Opcional. Indicaciones para el video en lenguaje natural (ej. enf\xF3cate en los precios, tono m\xE1s formal, menciona la prueba gratis).")
23069
23975
  }).strict();
23070
23976
  function captureNextAction(capture) {
23071
23977
  if (capture.status === "ready") return "Muestra la vista previa al usuario y confirma formato, duraci\xF3n, idioma y precio. Solo despu\xE9s llama create_animated_video con action=generate, este websiteCaptureId y confirmed=true.";
@@ -23098,35 +24004,35 @@ var FORMAT_LABELS = {
23098
24004
  square: "cuadrado 1:1",
23099
24005
  horizontal: "horizontal 16:9"
23100
24006
  };
23101
- var AnimatedVideoResultSchema = z97.object({
23102
- status: z97.enum([
24007
+ var AnimatedVideoResultSchema = z102.object({
24008
+ status: z102.enum([
23103
24009
  "pending",
23104
24010
  "done",
23105
24011
  "error"
23106
24012
  ]),
23107
- serviceMode: z97.literal("motion_graphics"),
23108
- finalMp4Url: z97.string().optional(),
23109
- error: z97.string().optional(),
23110
- motionGraphics: z97.object({
24013
+ serviceMode: z102.literal("motion_graphics"),
24014
+ finalMp4Url: z102.string().optional(),
24015
+ error: z102.string().optional(),
24016
+ motionGraphics: z102.object({
23111
24017
  stage: MotionGraphicsStageSchema,
23112
24018
  format: MotionGraphicsFormatSchema,
23113
- durationSec: z97.number(),
23114
- width: z97.number().optional(),
23115
- height: z97.number().optional(),
24019
+ durationSec: z102.number(),
24020
+ width: z102.number().optional(),
24021
+ height: z102.number().optional(),
23116
24022
  language: MotionGraphicsLanguageSchema.optional(),
23117
- queuedAt: z97.string().optional(),
23118
- jobsAhead: z97.number().int().nonnegative().optional(),
23119
- stageStartedAt: z97.string().optional(),
23120
- renderProgress: z97.number().optional(),
24023
+ queuedAt: z102.string().optional(),
24024
+ jobsAhead: z102.number().int().nonnegative().optional(),
24025
+ stageStartedAt: z102.string().optional(),
24026
+ renderProgress: z102.number().optional(),
23121
24027
  // AI clip fields (absent on a video paid before clips, or from an API
23122
24028
  // that predates them). Lenient: an unreadable value is dropped
23123
24029
  // instead of hiding the status.
23124
- clipCount: z97.number().int().nonnegative().optional().catch(void 0),
23125
- clipsUsed: z97.number().int().nonnegative().optional().catch(void 0),
23126
- clipPriceCents: z97.number().finite().nonnegative().optional().catch(void 0),
23127
- clipsRefunded: z97.number().int().nonnegative().optional().catch(void 0),
23128
- activity: z97.array(MotionGraphicsActivitySchema).optional().catch(void 0),
23129
- previewUrl: z97.string().optional()
24030
+ clipCount: z102.number().int().nonnegative().optional().catch(void 0),
24031
+ clipsUsed: z102.number().int().nonnegative().optional().catch(void 0),
24032
+ clipPriceCents: z102.number().finite().nonnegative().optional().catch(void 0),
24033
+ clipsRefunded: z102.number().int().nonnegative().optional().catch(void 0),
24034
+ activity: z102.array(MotionGraphicsActivitySchema).optional().catch(void 0),
24035
+ previewUrl: z102.string().optional()
23130
24036
  }).passthrough()
23131
24037
  }).passthrough();
23132
24038
  function parseAnimatedVideoResult(value) {
@@ -23342,10 +24248,10 @@ function registerAnimatedVideoTools(server, api) {
23342
24248
  __name(registerAnimatedVideoTools, "registerAnimatedVideoTools");
23343
24249
 
23344
24250
  // src/tools/winning-product-image.ts
23345
- import { z as z98 } from "zod";
23346
- var WinnerReferenceInput = z98.object({
23347
- runId: z98.string().uuid(),
23348
- candidateSourceId: z98.string().trim().min(1).max(160)
24251
+ import { z as z103 } from "zod";
24252
+ var WinnerReferenceInput = z103.object({
24253
+ runId: z103.string().uuid(),
24254
+ candidateSourceId: z103.string().trim().min(1).max(160)
23349
24255
  }).strict().describe("Referencia opaca de un producto devuelto por find_winning_products/get_product_research_run.");
23350
24256
  async function resolveWinnerImages(api, winnerReference, images) {
23351
24257
  if (!winnerReference) return images;
@@ -23382,62 +24288,62 @@ var createProductTaskSingleOutputDescription = renderCreateProductTaskAvoidWhenF
23382
24288
  var CREATE_SERVICE_VIDEO_ON_MCP = PRODUCTMAKER_MCP_CAPABILITY_NAMES.includes("create_service_video");
23383
24289
  var listTasksGuidance = getProductMakerCapabilityModelGuidance("list_tasks");
23384
24290
  var editTaskDraftGuidance = getProductMakerCapabilityModelGuidance("edit_task_draft");
23385
- var CreateProductTaskInput = z99.object({
24291
+ var CreateProductTaskInput = z104.object({
23386
24292
  images: ImagesInput.optional().describe("1\u20135 fotos del mismo producto. Omitir \xFAnicamente cuando projectId apunta a un proyecto propio con imagen guardada."),
23387
24293
  winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
23388
- projectId: z99.string().uuid().optional().describe("Opcional. Proyecto guiado propio. Permite continuar sin volver a subir la imagen guardada; nunca evita cr\xE9ditos, cuotas ni confirmaciones."),
23389
- productUrl: z99.string().url().optional().describe("Opcional. URL de la p\xE1gina del producto (Shopify, AliExpress, Amazon, etc.) para enriquecer el contexto. Si se omite, la IA infiere todo desde la imagen."),
24294
+ projectId: z104.string().uuid().optional().describe("Opcional. Proyecto guiado propio. Permite continuar sin volver a subir la imagen guardada; nunca evita cr\xE9ditos, cuotas ni confirmaciones."),
24295
+ productUrl: z104.string().url().optional().describe("Opcional. URL de la p\xE1gina del producto (Shopify, AliExpress, Amazon, etc.) para enriquecer el contexto. Si se omite, la IA infiere todo desde la imagen."),
23390
24296
  language: Lang.describe('C\xF3digo de idioma para el contenido generado. Ejemplos: "es", "en", "pt". REQUERIDO \u2014 si el usuario no lo especific\xF3, PREG\xDANTALE antes de invocar. NUNCA infieras desde el contexto del chat ni asumas "es" por default.'),
23391
24297
  country: Country.describe('C\xF3digo ISO del pa\xEDs objetivo. Ejemplos: "CO", "MX", "US", "AR". Define moneda, m\xE9todos de pago locales y tono. REQUERIDO \u2014 si el usuario no lo especific\xF3, PREG\xDANTALE antes de invocar. NUNCA infieras desde el contexto del chat.'),
23392
- price: z99.string().min(1).max(120).optional().describe('Precio que se mostrar\xE1 en la landing y video. Formato libre \u2014 ej. "$89.900", "USD 29.99", "MXN 599". Opcional pero MUY IMPACTANTE: si el usuario no lo mencion\xF3, PREG\xDANTALE antes de invocar. Si te dice "t\xFA elige", om\xEDtelo y el backend sugiere uno.'),
23393
- compareAtPrice: z99.string().min(1).max(120).optional().describe('Opcional. Precio anterior para comunicar un descuento real en landing e im\xE1genes. Ej. "$129.000" cuando price="$89.900".'),
23394
- offer: z99.string().min(1).max(240).optional().describe('Oferta o promoci\xF3n a destacar. Ej. "2x1", "Env\xEDo gratis hoy", "50% OFF". Opcional pero MUY IMPACTANTE: si el usuario no lo mencion\xF3, PREG\xDANTALE antes de invocar (es v\xE1lido que diga "sin oferta"). Si te dice "t\xFA elige", om\xEDtelo.'),
23395
- paymentMethods: z99.string().min(1).max(240).optional().describe('Opcional. M\xE9todos de pago que puede mostrar la landing. Ej. "Tarjeta, PSE, Nequi, Contraentrega". Si se omite, la landing no muestra m\xE9todos de pago.'),
23396
- productContext: z99.string().max(PRODUCT_CONTEXT_MAX_CHARS).optional().describe("Opcional. Informacion adicional del producto que la IA debe usar como contexto prioritario: uso real, comprador, restricciones, diferenciadores o direccion creativa. No reemplaza la investigacion de competencia; si hay competencia, guia el primer angulo y los outputs no deben contradecirlo."),
23397
- productLabel: z99.string().trim().max(80).optional().describe('Opcional. Qu\xE9 es el producto, en pocas palabras (ej. "quita pelusas para ropa"). Es AUTORITATIVO: si lo env\xEDas, la IA usa esta identidad y no la reemplaza por otra categor\xEDa. Si lo omites, la IA detecta el producto desde la imagen.'),
24298
+ price: z104.string().min(1).max(120).optional().describe('Precio que se mostrar\xE1 en la landing y video. Formato libre \u2014 ej. "$89.900", "USD 29.99", "MXN 599". Opcional pero MUY IMPACTANTE: si el usuario no lo mencion\xF3, PREG\xDANTALE antes de invocar. Si te dice "t\xFA elige", om\xEDtelo y el backend sugiere uno.'),
24299
+ compareAtPrice: z104.string().min(1).max(120).optional().describe('Opcional. Precio anterior para comunicar un descuento real en landing e im\xE1genes. Ej. "$129.000" cuando price="$89.900".'),
24300
+ offer: z104.string().min(1).max(240).optional().describe('Oferta o promoci\xF3n a destacar. Ej. "2x1", "Env\xEDo gratis hoy", "50% OFF". Opcional pero MUY IMPACTANTE: si el usuario no lo mencion\xF3, PREG\xDANTALE antes de invocar (es v\xE1lido que diga "sin oferta"). Si te dice "t\xFA elige", om\xEDtelo.'),
24301
+ paymentMethods: z104.string().min(1).max(240).optional().describe('Opcional. M\xE9todos de pago que puede mostrar la landing. Ej. "Tarjeta, PSE, Nequi, Contraentrega". Si se omite, la landing no muestra m\xE9todos de pago.'),
24302
+ productContext: z104.string().max(PRODUCT_CONTEXT_MAX_CHARS).optional().describe("Opcional. Informacion adicional del producto que la IA debe usar como contexto prioritario: uso real, comprador, restricciones, diferenciadores o direccion creativa. No reemplaza la investigacion de competencia; si hay competencia, guia el primer angulo y los outputs no deben contradecirlo."),
24303
+ productLabel: z104.string().trim().max(80).optional().describe('Opcional. Qu\xE9 es el producto, en pocas palabras (ej. "quita pelusas para ropa"). Es AUTORITATIVO: si lo env\xEDas, la IA usa esta identidad y no la reemplaza por otra categor\xEDa. Si lo omites, la IA detecta el producto desde la imagen.'),
23398
24304
  videoPreset: VideoPresetEnum.default("auto").describe('Opcional. Tipo/narrativa del video \u2014 \xFAnico campo de "estilo" que el usuario controla. Default "auto" (la IA escoge tras analizar el producto). Todos los presets funcionan a 15s (single_call) y 30s (Multiescena); "problem_solution" en single_call abre sin el producto y el producto entra por referencia en su beat de soluci\xF3n. Opciones: "auto", "ugc_dynamic" (review con experiencia y prueba), "ugc_how_to" (tutorial con pasos y resultado visible), "ugc_unboxing_chaos" (apertura y primera prueba), "problem_solution" (problema concreto, producto como soluci\xF3n y CTA), "product_showcase" (producto ejecutando una funci\xF3n real), "wearable_showcase" (prenda o accesorio modelado), "cinematic" (TV spot con receta cinematogr\xE1fica), "wild_card" (idea imposible: un truco visual que en la vida real no podr\xEDa pasar, y al cierre la invitaci\xF3n a comprar), "pixar_problem" (problema animado 3D), "pixar_sassy" (producto que habla). Si el usuario pide algo fuera de esta lista, p\xEDdele una opci\xF3n v\xE1lida.'),
23399
24305
  animationStyle: AnimationStyleEnum.optional().describe('Opcional. Estilo visual SOLO para presets animados ("pixar_problem" o "pixar_sassy") \u2014 la API lo rechaza con cualquier otro preset. Opciones: "pixar_3d" (default, look 3D de pel\xEDcula animada), "claymation" (plastilina stop-motion artesanal), "wes_anderson" (tableau sim\xE9trico pastel), "sci_fi" (futurista con HUDs y ne\xF3n), "realista" (fotorrealista, fiel al producto). Si el usuario pide un look animado sin nombrar el estilo, omite el campo.'),
23400
- durationSeconds: z99.union([
23401
- z99.literal(15),
23402
- z99.literal(30)
24306
+ durationSeconds: z104.union([
24307
+ z104.literal(15),
24308
+ z104.literal(30)
23403
24309
  ]).default(15).describe("Opcional. Duraci\xF3n objetivo del video: 15s (single_call, default) o 30s (Multiescena, aproximadamente 30s y facturado por escena)."),
23404
- pauseForAngleReview: z99.boolean().optional().describe("Compatibilidad heredada. MCP deriva esta pausa de aiDecidesAll: manual siempre pausa y autom\xE1tico siempre la omite. No uses este campo para saltar reviews."),
23405
- aiDecidesAll: z99.boolean().optional().describe("Mapea el toggle web \u201CDejar que la IA decida todo\u201D. Si true, ProductMaker omite reviews. Act\xEDvalo \xFAnicamente cuando el usuario lo pida expl\xEDcitamente. Omitido/false = reviews conversacionales."),
24310
+ pauseForAngleReview: z104.boolean().optional().describe("Compatibilidad heredada. MCP deriva esta pausa de aiDecidesAll: manual siempre pausa y autom\xE1tico siempre la omite. No uses este campo para saltar reviews."),
24311
+ aiDecidesAll: z104.boolean().optional().describe("Mapea el toggle web \u201CDejar que la IA decida todo\u201D. Si true, ProductMaker omite reviews. Act\xEDvalo \xFAnicamente cuando el usuario lo pida expl\xEDcitamente. Omitido/false = reviews conversacionales."),
23406
24312
  videoTier: VideoTierEnum.optional().describe('Opcional. Estilo del video. "basic" = "Realista" para 15s; al pedir durationSeconds=30 el sistema selecciona internamente Multiescena. No se expone el tier interno directamente.'),
23407
24313
  videoStructure: VideoStructureEnum.default("single_take").describe('Opcional. Formato: "single_take" = Un solo clip (generado completo; puede incluir cambios de plano) o "multi_scene" = Multiescena. Default: single_take.'),
23408
24314
  videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
23409
24315
  videoResolution: VideoResolutionEnum.optional().describe('Opcional. Resoluci\xF3n del render. En la web se pregunta "\xBFResoluci\xF3n del video?". "480p" = excelente calidad y m\xE1s econ\xF3mico (RECOMENDADO, default si se omite); "720p" = m\xE1xima nitidez, entre 3% y 15% m\xE1s caro seg\xFAn formato y tier. Si el usuario no menciona resoluci\xF3n, OMITE este campo (el backend usa 480p).'),
23410
- videoAngleCount: z99.number().int().min(1).max(3).optional().describe("Cantidad de videos a renderizar: 1, 2 o 3. REQUERIDO cuando outputs incluye video (o se omite outputs, cuyo default incluye video); om\xEDtelo s\xF3lo cuando no se generar\xE1 video. Preg\xFAntalo incluso con aiDecidesAll=true porque cambia el costo."),
24316
+ videoAngleCount: z104.number().int().min(1).max(3).optional().describe("Cantidad de videos a renderizar: 1, 2 o 3. REQUERIDO cuando outputs incluye video (o se omite outputs, cuyo default incluye video); om\xEDtelo s\xF3lo cuando no se generar\xE1 video. Preg\xFAntalo incluso con aiDecidesAll=true porque cambia el costo."),
23411
24317
  angleNarratives: PublicNarrativeStyleEnum.array().max(3).optional().describe('Opcional. Narrativa POR \xC1NGULO (posicional). Valores actuales: "review", "ugc_how_to", "ugc_unboxing_chaos", "problem_product_cta" (problema concreto, producto como soluci\xF3n y CTA), "product_showcase", "wearable_showcase", "cinematic", "wild_card", "animated_problem_pixar", "sassy_product_pixar", "market" (narrativa an\xE1lisis de mercado: adapta el video a los patrones ganadores estudiados de la competencia; requiere competitorScanEnabled: true). angleNarratives[i] fuerza la narrativa del \xE1ngulo i; las posiciones restantes las elige la IA. La lista no puede superar videoAngleCount.'),
23412
- outputs: z99.array(z99.enum([
24318
+ outputs: z104.array(z104.enum([
23413
24319
  "landing",
23414
24320
  "video",
23415
24321
  "image"
23416
24322
  ])).min(1).max(3).optional().describe(`Opcional. Qu\xE9 outputs generar. Default: todos ["landing","video","image"]. Para 2 outputs: ["landing","image"] (sin video), ["video","image"] (sin landing), ["landing","video"] (sin imagen). ${createProductTaskSingleOutputDescription}`),
23417
- includeInitialLandingGif: z99.boolean().optional().describe("Opcional. En nuevas landings cl\xE1sicas habilitadas, omitirlo incluye el primer GIF del producto y su coste en el total. Env\xEDa false si el usuario lo excluye: no se genera ni se reserva su coste. Conserva la elecci\xF3n al confirmar y al reintentar."),
23418
- competitorScanEnabled: z99.boolean().optional().describe("Opcional. Default false: omitirlo significa SIN estudio de mercado. Antes de crear, llama estimate_market_study_cost con kind=product_task, muestra al usuario el costo con y sin estudio y preg\xFAntale si lo quiere; env\xEDa true solo si lo acepta (o si solicita la narrativa an\xE1lisis de mercado). Si la tarea incluye video, true analiza anuncios de la competencia y desbloquea la narrativa an\xE1lisis de mercado; si el estudio no encuentra datos suficientes, degrada al planner cl\xE1sico."),
24323
+ includeInitialLandingGif: z104.boolean().optional().describe("Opcional. En nuevas landings cl\xE1sicas habilitadas, omitirlo incluye el primer GIF del producto y su coste en el total. Env\xEDa false si el usuario lo excluye: no se genera ni se reserva su coste. Conserva la elecci\xF3n al confirmar y al reintentar."),
24324
+ competitorScanEnabled: z104.boolean().optional().describe("Opcional. Default false: omitirlo significa SIN estudio de mercado. Antes de crear, llama estimate_market_study_cost con kind=product_task, muestra al usuario el costo con y sin estudio y preg\xFAntale si lo quiere; env\xEDa true solo si lo acepta (o si solicita la narrativa an\xE1lisis de mercado). Si la tarea incluye video, true analiza anuncios de la competencia y desbloquea la narrativa an\xE1lisis de mercado; si el estudio no encuentra datos suficientes, degrada al planner cl\xE1sico."),
23419
24325
  generateAiEdit: AiEditRequestSchema.optional().describe('Opcional. Pide la Edici\xF3n con IA: una pasada que a\xF1ade texto, efectos y m\xFAsica sobre cada video entregado (variante with_ai_edit; se cobra al entregar, por video). Nivel: "economy" (Econ\xF3mica, Sonnet 5.5, m\xE1s barata) o "pro" (Opus 5.5, mejor calidad, ~10 min). true equivale a "pro"; false/omitido = sin edici\xF3n.'),
23420
- replicateWinnerWhenFound: z99.boolean().optional().describe("Conserva la preferencia de copiar un ganador si existe. false estudia el mercado sin reemplazar un \xE1ngulo por el anuncio ganador. No a\xF1ade una pregunta obligatoria."),
23421
- brandId: z99.string().uuid().optional().describe("Opcional. ID de una marca del usuario; si se env\xEDa, el sistema usa su voz, colores y persona para enriquecer los outputs generados."),
23422
- actorId: z99.string().trim().min(1).max(120).optional().describe("Opcional. ID de un personaje guardado (usa list_actors para verlos). Si lo env\xEDas, su foto y su voz mandan sobre la descripci\xF3n de texto."),
24326
+ replicateWinnerWhenFound: z104.boolean().optional().describe("Conserva la preferencia de copiar un ganador si existe. false estudia el mercado sin reemplazar un \xE1ngulo por el anuncio ganador. No a\xF1ade una pregunta obligatoria."),
24327
+ brandId: z104.string().uuid().optional().describe("Opcional. ID de una marca del usuario; si se env\xEDa, el sistema usa su voz, colores y persona para enriquecer los outputs generados."),
24328
+ actorId: z104.string().trim().min(1).max(120).optional().describe("Opcional. ID de un personaje guardado (usa list_actors para verlos). Si lo env\xEDas, su foto y su voz mandan sobre la descripci\xF3n de texto."),
23423
24329
  creativeGender: CreativeGenderEnum.optional().describe('Opcional. QUI\xC9N APARECE EN PANTALLA en todos los creativos de la task: el presentador del video, las personas fotografiadas en la landing y la persona del anuncio. NO es la voz. M\xE1ndalo en cuanto el usuario lo diga en cualquier momento de la conversaci\xF3n y con cualquier redacci\xF3n ("quiero una mujer", "que salga un hombre", "esto es para hombres"): si no lo mandas, el g\xE9nero lo inventa la IA y el usuario recibe lo contrario de lo que pidi\xF3 sin ning\xFAn aviso. "mixed" solo cuando pida expl\xEDcitamente ambos. Si adem\xE1s mandas actorId, el personaje guardado manda sobre este campo.'),
23424
- creativeDirection: z99.string().max(500).optional().describe('Opcional. Direcci\xF3n creativa en texto libre (colores, mood, estilo) que aplica a los outputs de IMAGEN y LANDING (no al video \u2014 el estilo/ambiente del video se dirige con scriptNotes). M\xC1XIMA PRIORIDAD: anula marca, colores y estilo por defecto. Ej. "amarillo y azul, minimalista". M\xE1x 500 caracteres.'),
23425
- headline: z99.string().max(120).optional().describe("Opcional. Titular EXACTO a renderizar. Se imprime tal cual: la IA no lo reescribe, no lo acorta y no lo traduce. Se aplica a las IM\xC1GENES y a la portada de la landing de esta task (el video no lo usa; para el video usa scriptNotes). \xDAsalo cuando el copy es de marca y no es negociable. M\xE1x 120 caracteres. Si lo omites, la IA escribe el titular."),
23426
- subheadline: z99.string().max(160).optional().describe("Opcional. Subt\xEDtulo EXACTO a renderizar, misma regla que headline. Independiente: puedes fijar solo el subt\xEDtulo. M\xE1x 160 caracteres."),
24330
+ creativeDirection: z104.string().max(500).optional().describe('Opcional. Direcci\xF3n creativa en texto libre (colores, mood, estilo) que aplica a los outputs de IMAGEN y LANDING (no al video \u2014 el estilo/ambiente del video se dirige con scriptNotes). M\xC1XIMA PRIORIDAD: anula marca, colores y estilo por defecto. Ej. "amarillo y azul, minimalista". M\xE1x 500 caracteres.'),
24331
+ headline: z104.string().max(120).optional().describe("Opcional. Titular EXACTO a renderizar. Se imprime tal cual: la IA no lo reescribe, no lo acorta y no lo traduce. Se aplica a las IM\xC1GENES y a la portada de la landing de esta task (el video no lo usa; para el video usa scriptNotes). \xDAsalo cuando el copy es de marca y no es negociable. M\xE1x 120 caracteres. Si lo omites, la IA escribe el titular."),
24332
+ subheadline: z104.string().max(160).optional().describe("Opcional. Subt\xEDtulo EXACTO a renderizar, misma regla que headline. Independiente: puedes fijar solo el subt\xEDtulo. M\xE1x 160 caracteres."),
23427
24333
  landingStrategy: LandingStrategyEnum.optional().describe('Opcional. Estructura de la landing cl\xE1sica cuando landing est\xE1 entre outputs: "classic" (estructura original probada y recomendada; default del primer rollout), "auto" (la IA decide; experimental), "pain_solution", "social_proof" (Landing Viral: UGC, WhatsApp, Instagram y evidencia social), "benefits_clarity", "offer_value" o "lifestyle_identity". Default "classic".'),
23428
24334
  landingImageFormat: LandingImageFormatEnum.default("9:16").describe('Opcional. Formato/relaci\xF3n de aspecto de las im\xE1genes de la landing cl\xE1sica cuando landing est\xE1 entre outputs: "9:16" (vertical, por defecto), "4:5" (vertical compacto para feed) o "1:1" (cuadrado). Default "9:16".')
23429
24335
  }).strict();
23430
- var CreateServiceVideoInput = z99.object({
23431
- landingUrl: z99.string().url().describe("URL p\xFAblica de la landing del servicio. Es suficiente para generar el video; los medios son opcionales en la web."),
23432
- additionalContext: z99.string().max(3e3).optional().describe('Instrucci\xF3n natural prioritaria. Ej.: "adapta el ritmo de estos competidores", "enfatiza reservas de demos" o restricciones de claims.'),
24336
+ var CreateServiceVideoInput = z104.object({
24337
+ landingUrl: z104.string().url().describe("URL p\xFAblica de la landing del servicio. Es suficiente para generar el video; los medios son opcionales en la web."),
24338
+ additionalContext: z104.string().max(3e3).optional().describe('Instrucci\xF3n natural prioritaria. Ej.: "adapta el ritmo de estos competidores", "enfatiza reservas de demos" o restricciones de claims.'),
23433
24339
  language: Lang.describe("Idioma del video: es, en o pt."),
23434
- voiceId: z99.string().trim().min(1).pipe(VoiceId).optional().describe('Opcional. Voz para toda la narraci\xF3n. Usa "auto" para que la IA la alinee con el presentador. Las voces del banco compartido fueron retiradas.'),
23435
- brandId: z99.string().uuid().optional().describe("Marca guardada del usuario. Aplica voz, mensajes, paleta y persona predeterminada."),
23436
- reviewMode: z99.enum([
24340
+ voiceId: z104.string().trim().min(1).pipe(VoiceId).optional().describe('Opcional. Voz para toda la narraci\xF3n. Usa "auto" para que la IA la alinee con el presentador. Las voces del banco compartido fueron retiradas.'),
24341
+ brandId: z104.string().uuid().optional().describe("Marca guardada del usuario. Aplica voz, mensajes, paleta y persona predeterminada."),
24342
+ reviewMode: z104.enum([
23437
24343
  "automatic",
23438
24344
  "guided"
23439
24345
  ]).default("automatic").describe("automatic = la IA elige concepto y guion sin pausas; guided = el usuario aprueba concepto y storyboard."),
23440
- videoPreset: z99.enum([
24346
+ videoPreset: z104.enum([
23441
24347
  "auto",
23442
24348
  "ugc_dynamic",
23443
24349
  "ugc_how_to",
@@ -23447,128 +24353,128 @@ var CreateServiceVideoInput = z99.object({
23447
24353
  videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El proveedor se elige internamente. Default: economy.'),
23448
24354
  videoResolution: VideoResolutionEnum.default("480p").describe('Opcional. Resoluci\xF3n: "480p" o "720p". 720p cuesta m\xE1s por segundo y solo est\xE1 disponible en "economy" y "pro" (Medio = 768P). Default: 480p.')
23449
24355
  }).strict();
23450
- var GetTaskStatusInput = z99.object({
23451
- taskId: z99.string().min(1),
23452
- waitSeconds: z99.number().int().min(0).max(120).optional()
24356
+ var GetTaskStatusInput = z104.object({
24357
+ taskId: z104.string().min(1),
24358
+ waitSeconds: z104.number().int().min(0).max(120).optional()
23453
24359
  });
23454
- var ListTasksInput = z99.object({
23455
- limit: z99.number().int().min(1).max(50).optional(),
23456
- offset: z99.number().int().min(0).optional(),
23457
- search: z99.string().optional()
24360
+ var ListTasksInput = z104.object({
24361
+ limit: z104.number().int().min(1).max(50).optional(),
24362
+ offset: z104.number().int().min(0).optional(),
24363
+ search: z104.string().optional()
23458
24364
  });
23459
24365
  var MCP_REVIEW_LIST_FIELD_MAX = IMAGE_WIZARD_LIST_FIELD_MAX;
23460
24366
  var MCP_REVIEW_FEATURE_ITEM_MAX = IMAGE_FEATURE_ITEM_MAX;
23461
- var EditTaskDraftInput = z99.object({
23462
- taskId: z99.string().min(1),
23463
- angleIndex: z99.number().int().min(0),
23464
- angle: z99.object({
23465
- angle: z99.string().min(1).max(480),
23466
- buyerPersona: z99.string().min(1).max(360),
23467
- actor: z99.string().min(1).max(360).optional(),
23468
- actorId: z99.string().trim().min(1).optional().describe("Opcional. ID de un personaje guardado (usa list_actors para verlos). Si lo env\xEDas, su foto y su voz mandan sobre la descripci\xF3n de texto."),
23469
- gender: z99.enum([
24367
+ var EditTaskDraftInput = z104.object({
24368
+ taskId: z104.string().min(1),
24369
+ angleIndex: z104.number().int().min(0),
24370
+ angle: z104.object({
24371
+ angle: z104.string().min(1).max(480),
24372
+ buyerPersona: z104.string().min(1).max(360),
24373
+ actor: z104.string().min(1).max(360).optional(),
24374
+ actorId: z104.string().trim().min(1).optional().describe("Opcional. ID de un personaje guardado (usa list_actors para verlos). Si lo env\xEDas, su foto y su voz mandan sobre la descripci\xF3n de texto."),
24375
+ gender: z104.enum([
23470
24376
  "female",
23471
24377
  "male"
23472
24378
  ]).optional(),
23473
- scriptNotes: z99.string().max(2e3).optional()
24379
+ scriptNotes: z104.string().max(2e3).optional()
23474
24380
  })
23475
24381
  });
23476
- var PendingActionPayload = z99.discriminatedUnion("kind", [
23477
- z99.object({
23478
- kind: z99.literal("product_reference_set_approval"),
24382
+ var PendingActionPayload = z104.discriminatedUnion("kind", [
24383
+ z104.object({
24384
+ kind: z104.literal("product_reference_set_approval"),
23479
24385
  scope: ProductReferenceScopeEnum.optional(),
23480
- scopeKey: z99.string().min(1).max(120).optional(),
23481
- scopeSnapshotId: z99.string().uuid().optional(),
23482
- expectedScopeHash: z99.string().min(1).max(128).optional(),
24386
+ scopeKey: z104.string().min(1).max(120).optional(),
24387
+ scopeSnapshotId: z104.string().uuid().optional(),
24388
+ expectedScopeHash: z104.string().min(1).max(128).optional(),
23483
24389
  decision: ProductReferenceResolutionDecisionEnum,
23484
24390
  reason: ProductReferenceRejectionReasonEnum.optional(),
23485
- affectedRefKeys: z99.array(z99.string().min(1).max(200)).min(1).optional(),
23486
- affectedPhotoNumbers: z99.array(z99.number().int().positive()).min(1).optional(),
23487
- recoveryAction: z99.enum([
24391
+ affectedRefKeys: z104.array(z104.string().min(1).max(200)).min(1).optional(),
24392
+ affectedPhotoNumbers: z104.array(z104.number().int().positive()).min(1).optional(),
24393
+ recoveryAction: z104.enum([
23488
24394
  "remove",
23489
24395
  "replace",
23490
24396
  "upload",
23491
24397
  "return_to_selection"
23492
24398
  ]).optional()
23493
24399
  }),
23494
- z99.object({
23495
- kind: z99.literal("product_reference_confirmation"),
23496
- selectedPhotoNumbers: z99.array(z99.number().int().positive().max(5)).min(1).max(5).optional().describe("Opcional. N\xFAmeros visibles de las fotos que el usuario quiere conservar; las dem\xE1s se deseleccionan. Debe quedar al menos una."),
24400
+ z104.object({
24401
+ kind: z104.literal("product_reference_confirmation"),
24402
+ selectedPhotoNumbers: z104.array(z104.number().int().positive().max(5)).min(1).max(5).optional().describe("Opcional. N\xFAmeros visibles de las fotos que el usuario quiere conservar; las dem\xE1s se deseleccionan. Debe quedar al menos una."),
23497
24403
  userChoice: ProductReferenceUserChoiceEnum.optional(),
23498
- confirmedProductNames: z99.array(z99.string().min(1).max(120)).min(2).max(8).optional(),
24404
+ confirmedProductNames: z104.array(z104.string().min(1).max(120)).min(2).max(8).optional(),
23499
24405
  videoStructure: VideoStructureEnum.optional().describe("Opcional. Formato para reanudar el video: single_take (Un solo clip, generado completo; puede incluir cambios de plano) o multi_scene (Multiescena). El backend vuelve a validar que sea compatible con el agrupamiento confirmado."),
23500
24406
  videoQuality: VideoQualityEnum.optional().describe("Opcional. Calidad para reanudar el video: economy (Econ\xF3mico), medium (Medio) o pro. El proveedor se elige internamente y el backend vuelve a cotizar la ruta."),
23501
- useMultiSceneShowcase: z99.boolean().optional().describe("Compatibilidad con confirmaciones antiguas: si es true junto con userChoice=variants, conserva el showcase multiescena.")
24407
+ useMultiSceneShowcase: z104.boolean().optional().describe("Compatibilidad con confirmaciones antiguas: si es true junto con userChoice=variants, conserva el showcase multiescena.")
23502
24408
  }),
23503
- z99.object({
23504
- kind: z99.literal("angle_review_approval"),
24409
+ z104.object({
24410
+ kind: z104.literal("angle_review_approval"),
23505
24411
  // All edits are optional — empty action body just approves the
23506
24412
  // backend-generated draft as-is. Field shapes mirror the angle-review
23507
24413
  // request contracts in @packages/types/wizard.ts; the handler routes to
23508
24414
  // the dedicated video/image/autopilot endpoint based on StatusResponse.kind.
23509
- customAngle: z99.string().min(1).max(480).optional(),
24415
+ customAngle: z104.string().min(1).max(480).optional(),
23510
24416
  // Keep the shared MCP action within the strictest downstream contract:
23511
24417
  // autopilot/image resume endpoints cap these fields at 1500 characters.
23512
- painPoints: z99.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
23513
- benefits: z99.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
24418
+ painPoints: z104.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
24419
+ benefits: z104.string().max(MCP_REVIEW_LIST_FIELD_MAX).optional(),
23514
24420
  // Same policy as the two fields above: the strictest downstream contract
23515
24421
  // wins. The image endpoint caps each feature at 240 while landing/video
23516
24422
  // accept 300, and this single action routes to whichever the task is — so
23517
24423
  // accepting 300 here turns a 250-character feature on an image task into
23518
24424
  // an opaque HTTP 400 after the model already believed it had been saved.
23519
- features: z99.array(z99.string().min(1).max(MCP_REVIEW_FEATURE_ITEM_MAX)).max(10).optional(),
23520
- buyerPersona: z99.string().min(1).max(360).optional(),
24425
+ features: z104.array(z104.string().min(1).max(MCP_REVIEW_FEATURE_ITEM_MAX)).max(10).optional(),
24426
+ buyerPersona: z104.string().min(1).max(360).optional(),
23521
24427
  narrativeStyle: PublicNarrativeStyleEnum.optional().describe('Narrativa del video. "problem_product_cta" (Problema y Soluci\xF3n) funciona en ambos formatos \u2014 en Un solo clip abre sin producto y el producto entra por referencia en su beat. La familia storyteller ("animated_storyteller", "animated_inner_journey", "animated_object_soul", "animated_timeline") no est\xE1 disponible por ahora.'),
23522
- actor: z99.string().min(1).max(360).optional().describe("Nueva descripci\xF3n del presentador. Al enviarla sin actorId, se elimina autom\xE1ticamente cualquier actor guardado previo de esos \xE1ngulos."),
23523
- actorId: z99.string().max(120).nullable().optional(),
23524
- creativeDirection: z99.string().max(2e3).optional(),
23525
- selectedAngleNumbers: z99.array(z99.number().int().positive()).min(1).max(3).optional().describe("N\xFAmeros visibles (1-based) de los \xE1ngulos que el usuario quiere renderizar. Deben ser \xFAnicos, existir en la review y no superar el videoAngleCount autorizado."),
23526
- angleEdits: z99.array(z99.object({
23527
- angleNumber: z99.number().int().positive(),
23528
- narrativeSelection: z99.enum([
24428
+ actor: z104.string().min(1).max(360).optional().describe("Nueva descripci\xF3n del presentador. Al enviarla sin actorId, se elimina autom\xE1ticamente cualquier actor guardado previo de esos \xE1ngulos."),
24429
+ actorId: z104.string().max(120).nullable().optional(),
24430
+ creativeDirection: z104.string().max(2e3).optional(),
24431
+ selectedAngleNumbers: z104.array(z104.number().int().positive()).min(1).max(3).optional().describe("N\xFAmeros visibles (1-based) de los \xE1ngulos que el usuario quiere renderizar. Deben ser \xFAnicos, existir en la review y no superar el videoAngleCount autorizado."),
24432
+ angleEdits: z104.array(z104.object({
24433
+ angleNumber: z104.number().int().positive(),
24434
+ narrativeSelection: z104.enum([
23529
24435
  "market",
23530
24436
  "guided"
23531
24437
  ]).optional().describe("Elecci\xF3n expl\xEDcita: market usa el estudio disponible; guided usa la narrativa elegida para este \xE1ngulo."),
23532
- angle: z99.string().min(1).max(480).optional(),
23533
- buyerPersona: z99.string().min(1).max(360).optional(),
24438
+ angle: z104.string().min(1).max(480).optional(),
24439
+ buyerPersona: z104.string().min(1).max(360).optional(),
23534
24440
  narrativeStyle: PublicNarrativeStyleEnum.optional().describe('Narrativa del video. "problem_product_cta" (Problema y Soluci\xF3n) funciona en ambos formatos \u2014 en Un solo clip abre sin producto y el producto entra por referencia en su beat. La familia storyteller ("animated_storyteller", "animated_inner_journey", "animated_object_soul", "animated_timeline") no est\xE1 disponible por ahora.'),
23535
- actor: z99.string().min(1).max(360).optional(),
23536
- actorId: z99.string().max(120).nullable().optional(),
23537
- creativeDirection: z99.string().max(2e3).optional()
24441
+ actor: z104.string().min(1).max(360).optional(),
24442
+ actorId: z104.string().max(120).nullable().optional(),
24443
+ creativeDirection: z104.string().max(2e3).optional()
23538
24444
  }).strict()).max(3).optional().describe("Ediciones independientes por n\xFAmero visible de \xE1ngulo. S\xF3lo se aceptan para \xE1ngulos incluidos en selectedAngleNumbers (o en la selecci\xF3n por defecto)."),
23539
- gapDurationSeconds: z99.union([
23540
- z99.literal(15),
23541
- z99.literal(30)
24445
+ gapDurationSeconds: z104.union([
24446
+ z104.literal(15),
24447
+ z104.literal(30)
23542
24448
  ]).optional().describe("Opcional. Solo para aceptar expl\xEDcitamente la recomendaci\xF3n gapDurationChoice del status. 30 env\xEDa el override double_30s para el \xE1ngulo recomendado; 15 u omitido conserva la duraci\xF3n cotizada.")
23543
24449
  }),
23544
- z99.object({
23545
- kind: z99.literal("service_angle_approval"),
23546
- angleId: z99.string().uuid().optional(),
23547
- angleNumber: z99.number().int().positive().optional(),
23548
- content: z99.string().min(1).max(480).optional(),
23549
- creativeDirection: z99.string().min(1).max(1500).optional(),
23550
- actor: z99.string().min(1).max(360).optional()
24450
+ z104.object({
24451
+ kind: z104.literal("service_angle_approval"),
24452
+ angleId: z104.string().uuid().optional(),
24453
+ angleNumber: z104.number().int().positive().optional(),
24454
+ content: z104.string().min(1).max(480).optional(),
24455
+ creativeDirection: z104.string().min(1).max(1500).optional(),
24456
+ actor: z104.string().min(1).max(360).optional()
23551
24457
  }),
23552
- z99.object({
23553
- kind: z99.literal("service_script_approval"),
23554
- voiceovers: z99.record(z99.string(), z99.string().min(1).max(600)).optional(),
23555
- visualDirections: z99.record(z99.string(), z99.string().min(1).max(1200)).optional(),
23556
- voiceoversByScene: z99.record(z99.string(), z99.string().min(1).max(600)).optional(),
23557
- visualDirectionsByScene: z99.record(z99.string(), z99.string().min(1).max(1200)).optional()
24458
+ z104.object({
24459
+ kind: z104.literal("service_script_approval"),
24460
+ voiceovers: z104.record(z104.string(), z104.string().min(1).max(600)).optional(),
24461
+ visualDirections: z104.record(z104.string(), z104.string().min(1).max(1200)).optional(),
24462
+ voiceoversByScene: z104.record(z104.string(), z104.string().min(1).max(600)).optional(),
24463
+ visualDirectionsByScene: z104.record(z104.string(), z104.string().min(1).max(1200)).optional()
23558
24464
  })
23559
24465
  ]);
23560
- var ResolvePendingActionInput = z99.object({
23561
- taskId: z99.string().min(1),
24466
+ var ResolvePendingActionInput = z104.object({
24467
+ taskId: z104.string().min(1),
23562
24468
  action: PendingActionPayload
23563
24469
  }).strict();
23564
24470
  function resolveVariantConfirmVideoTier(action) {
23565
24471
  return action.useMultiSceneShowcase && action.userChoice === "variants" ? "standard" : void 0;
23566
24472
  }
23567
24473
  __name(resolveVariantConfirmVideoTier, "resolveVariantConfirmVideoTier");
23568
- var StatusForResolveSchema = z99.object({
24474
+ var StatusForResolveSchema = z104.object({
23569
24475
  // Metadata used to select the backend resume contract. Older API responses
23570
24476
  // may omit these fields, so the resolver keeps the generic fallback.
23571
- kind: z99.enum([
24477
+ kind: z104.enum([
23572
24478
  "autopilot",
23573
24479
  "video",
23574
24480
  "image",
@@ -23576,18 +24482,18 @@ var StatusForResolveSchema = z99.object({
23576
24482
  "mix",
23577
24483
  "service"
23578
24484
  ]).optional(),
23579
- selectedOutputs: z99.array(z99.enum([
24485
+ selectedOutputs: z104.array(z104.enum([
23580
24486
  "landing",
23581
24487
  "video",
23582
24488
  "image"
23583
24489
  ])).optional(),
23584
- videoAngleCount: z99.number().int().min(1).max(3).optional(),
23585
- ugcFormat: z99.enum([
24490
+ videoAngleCount: z104.number().int().min(1).max(3).optional(),
24491
+ ugcFormat: z104.enum([
23586
24492
  "single_8s",
23587
24493
  "single_15s",
23588
24494
  "double_30s"
23589
24495
  ]).optional(),
23590
- videoStyle: z99.enum([
24496
+ videoStyle: z104.enum([
23591
24497
  "ugc",
23592
24498
  "cartoon_3d",
23593
24499
  "product_only",
@@ -23597,13 +24503,13 @@ var StatusForResolveSchema = z99.object({
23597
24503
  videoQuality: VideoQualityEnum.optional(),
23598
24504
  videoRouteId: VideoRouteIdEnum.optional(),
23599
24505
  videoModel: TaskVideoModelEnum.optional(),
23600
- videoTier: z99.enum([
24506
+ videoTier: z104.enum([
23601
24507
  "legacy",
23602
24508
  "standard",
23603
24509
  "pro",
23604
24510
  "single_call"
23605
24511
  ]).optional(),
23606
- videoResolution: z99.enum([
24512
+ videoResolution: z104.enum([
23607
24513
  "480p",
23608
24514
  "720p"
23609
24515
  ]).optional(),
@@ -23611,60 +24517,60 @@ var StatusForResolveSchema = z99.object({
23611
24517
  // A task created before a narrative was blocked/hidden must still parse,
23612
24518
  // or resolve_pending_action could never approve it.
23613
24519
  narrativeStyle: NarrativeStyle.optional(),
23614
- pauseForVideoScriptReview: z99.boolean().optional(),
23615
- pendingUserAction: z99.object({
23616
- kind: z99.string(),
23617
- candidateGrouping: z99.string().optional(),
23618
- selectedImageUrls: z99.array(z99.string()).optional(),
23619
- proposedProductNames: z99.array(z99.string()).optional(),
24520
+ pauseForVideoScriptReview: z104.boolean().optional(),
24521
+ pendingUserAction: z104.object({
24522
+ kind: z104.string(),
24523
+ candidateGrouping: z104.string().optional(),
24524
+ selectedImageUrls: z104.array(z104.string()).optional(),
24525
+ proposedProductNames: z104.array(z104.string()).optional(),
23620
24526
  // Adaptive reference questions are server-owned. Echo only the evidence
23621
24527
  // identity and the choices shown by the current snapshot; never accept a
23622
24528
  // client-supplied reference set as authorization.
23623
- options: z99.array(ProductReferenceUserChoiceEnum).max(4).optional(),
23624
- mode: z99.enum([
24529
+ options: z104.array(ProductReferenceUserChoiceEnum).max(4).optional(),
24530
+ mode: z104.enum([
23625
24531
  "question",
23626
24532
  "visual_recovery"
23627
24533
  ]).optional(),
23628
24534
  /** Hand-mirrored from packages/types result.ts — see CLAUDE.md § MCP Server Sync. */
23629
- canKeepSelection: z99.boolean().optional(),
23630
- decisionKey: z99.string().optional(),
23631
- questionOrdinal: z99.number().int().min(1).max(5).optional(),
23632
- questionCeiling: z99.union([
23633
- z99.literal(3),
23634
- z99.literal(5)
24535
+ canKeepSelection: z104.boolean().optional(),
24536
+ decisionKey: z104.string().optional(),
24537
+ questionOrdinal: z104.number().int().min(1).max(5).optional(),
24538
+ questionCeiling: z104.union([
24539
+ z104.literal(3),
24540
+ z104.literal(5)
23635
24541
  ]).optional(),
23636
- referenceEvidenceVersion: z99.number().int().positive().optional(),
23637
- expectedEvidenceHash: z99.string().optional(),
23638
- question: z99.object({
23639
- prompt: z99.string().min(1).max(240),
23640
- helpText: z99.string().min(1).max(300).optional(),
23641
- options: z99.array(z99.object({
24542
+ referenceEvidenceVersion: z104.number().int().positive().optional(),
24543
+ expectedEvidenceHash: z104.string().optional(),
24544
+ question: z104.object({
24545
+ prompt: z104.string().min(1).max(240),
24546
+ helpText: z104.string().min(1).max(300).optional(),
24547
+ options: z104.array(z104.object({
23642
24548
  value: ProductReferenceUserChoiceEnum,
23643
- label: z99.string().min(1).max(120),
23644
- description: z99.string().min(1).max(240).optional()
24549
+ label: z104.string().min(1).max(120),
24550
+ description: z104.string().min(1).max(240).optional()
23645
24551
  })).min(2).max(4)
23646
24552
  }).optional(),
23647
24553
  scope: ProductReferenceScopeEnum.optional(),
23648
- scopeKey: z99.string().optional(),
23649
- scopeSnapshotId: z99.string().uuid().optional(),
23650
- scopeHash: z99.string().optional(),
23651
- baseReferenceSetHash: z99.string().optional(),
23652
- phase: z99.enum([
24554
+ scopeKey: z104.string().optional(),
24555
+ scopeSnapshotId: z104.string().uuid().optional(),
24556
+ scopeHash: z104.string().optional(),
24557
+ baseReferenceSetHash: z104.string().optional(),
24558
+ phase: z104.enum([
23653
24559
  "preparation",
23654
24560
  "final"
23655
24561
  ]).optional(),
23656
- selectedRefKeys: z99.array(z99.string().min(1).max(200)).optional(),
23657
- allowedDecisions: z99.array(ProductReferenceResolutionDecisionEnum).optional(),
23658
- previews: z99.array(z99.object({
23659
- refKey: z99.string().min(1).max(200)
24562
+ selectedRefKeys: z104.array(z104.string().min(1).max(200)).optional(),
24563
+ allowedDecisions: z104.array(ProductReferenceResolutionDecisionEnum).optional(),
24564
+ previews: z104.array(z104.object({
24565
+ refKey: z104.string().min(1).max(200)
23660
24566
  }).passthrough()).optional(),
23661
- customAngleDraft: z99.string().optional(),
23662
- painPointsDraft: z99.string().optional(),
23663
- benefitsDraft: z99.string().optional(),
23664
- featuresDraft: z99.array(z99.string()).optional(),
23665
- angleOptions: z99.array(z99.object({
23666
- index: z99.number().int().nonnegative(),
23667
- angle: z99.string().min(1)
24567
+ customAngleDraft: z104.string().optional(),
24568
+ painPointsDraft: z104.string().optional(),
24569
+ benefitsDraft: z104.string().optional(),
24570
+ featuresDraft: z104.array(z104.string()).optional(),
24571
+ angleOptions: z104.array(z104.object({
24572
+ index: z104.number().int().nonnegative(),
24573
+ angle: z104.string().min(1)
23668
24574
  }).passthrough()).min(1).max(5).optional(),
23669
24575
  // Recommendation consumed only when the caller explicitly sends
23670
24576
  // gapDurationSeconds: 30 in the angle approval action.
@@ -23674,17 +24580,17 @@ var StatusForResolveSchema = z99.object({
23674
24580
  // keys. `actorId` (the saved custom actor the picker stored) was silently
23675
24581
  // dropped here, so the approval handler below could not echo it back on the
23676
24582
  // PATCH — the selection looked accepted and reached no render.
23677
- angles: z99.array(z99.object({
23678
- id: z99.string().uuid(),
23679
- content: z99.string(),
23680
- creativeDirection: z99.string(),
23681
- actor: z99.string(),
23682
- actorId: z99.string().nullable().optional()
24583
+ angles: z104.array(z104.object({
24584
+ id: z104.string().uuid(),
24585
+ content: z104.string(),
24586
+ creativeDirection: z104.string(),
24587
+ actor: z104.string(),
24588
+ actorId: z104.string().nullable().optional()
23683
24589
  }).passthrough()).optional(),
23684
- panels: z99.array(z99.object({
23685
- beatId: z99.string(),
23686
- voiceover: z99.string(),
23687
- visualDirection: z99.string()
24590
+ panels: z104.array(z104.object({
24591
+ beatId: z104.string(),
24592
+ voiceover: z104.string(),
24593
+ visualDirection: z104.string()
23688
24594
  }).passthrough()).optional()
23689
24595
  }).optional()
23690
24596
  }).passthrough();
@@ -24036,8 +24942,8 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
24036
24942
  server.registerTool("verify_landing_commerce", {
24037
24943
  description: getProductMakerCapabilityModelGuidance("verify_landing_commerce").summary + " Verifica una correcci\xF3n manual de precios, tachados o packs de una landing editable existente. Solo relee Shopify y los recibos externos; no cambia precios, inventario, SKU ni compra una edici\xF3n. Pasa taskId y editId de la edici\xF3n ya conocida; nunca inventes IDs ni pidas repetir el cambio. Devuelve el estado can\xF3nico por proveedor: conserva el aviso pendiente hasta confirmar los valores reales. Solo despu\xE9s de confirmar todos los valores, el servidor puede volver a habilitar la compra. Web guardada no demuestra publicaci\xF3n p\xFAblica ni checkout; muestra las correcciones y enlaces pendientes sin c\xF3digos t\xE9cnicos. La disponibilidad del editor conserva sus permisos actuales.",
24038
24944
  inputSchema: {
24039
- taskId: z99.string().uuid(),
24040
- editId: z99.string().uuid()
24945
+ taskId: z104.string().uuid(),
24946
+ editId: z104.string().uuid()
24041
24947
  },
24042
24948
  annotations: OVERWRITES_EXTERNAL
24043
24949
  }, async (input) => {
@@ -24677,7 +25583,7 @@ ANTES de invocar, resume outputs, cantidad de videos y datos comerciales, explic
24677
25583
  __name(registerTaskTools, "registerTaskTools");
24678
25584
 
24679
25585
  // src/tools/creatives.ts
24680
- import { z as z100 } from "zod";
25586
+ import { z as z105 } from "zod";
24681
25587
  var generateFreeVideoGuidance = getProductMakerCapabilityModelGuidance("generate_free_video");
24682
25588
  var generateVideoCreativeGuidance = getProductMakerCapabilityModelGuidance("generate_video_creative");
24683
25589
  var generateImageCreativesGuidance = getProductMakerCapabilityModelGuidance("generate_image_creatives");
@@ -24688,72 +25594,72 @@ var CreativeRefs = {
24688
25594
  images: ImagesInput,
24689
25595
  language: Lang.describe('Idioma del contenido. Ej. "es", "en", "pt". REQUERIDO \u2014 si el usuario no lo dijo, PREG\xDANTALE antes de invocar. NUNCA infieras desde el contexto del chat ni asumas un default.'),
24690
25596
  country: Country.describe('Pa\xEDs objetivo ISO. Ej. "CO", "MX", "US", "AR". Define moneda, m\xE9todos de pago y tono. REQUERIDO \u2014 si el usuario no lo dijo, PREG\xDANTALE antes de invocar. NUNCA infieras desde el contexto del chat ni asumas un default.'),
24691
- price: z100.string().min(1).max(120).optional().describe('Precio en formato libre \u2014 ej. "$89.900", "USD 29.99". Opcional pero MUY IMPACTANTE para conversi\xF3n: si el usuario no lo mencion\xF3, PREG\xDANTALE antes de invocar. Si el usuario te dice "t\xFA elige", omite el campo y la IA del backend sugiere uno.'),
24692
- offer: z100.string().min(1).max(240).optional().describe('Oferta a destacar \u2014 ej. "2x1", "Env\xEDo gratis", "50% OFF". Opcional pero MUY IMPACTANTE: si el usuario no lo mencion\xF3, PREG\xDANTALE antes de invocar (es v\xE1lido que diga "sin oferta"). Si el usuario te dice "t\xFA elige", omite el campo.'),
24693
- compareAtPrice: z100.string().min(1).max(120).optional().describe('Opcional. Precio anterior o de referencia para mostrar descuento. Ej. "$129.000" cuando price="$89.900".'),
24694
- productContext: z100.string().max(3e3).optional().describe("Opcional. Informacion adicional del producto que la IA debe usar como contexto prioritario: uso real, comprador, restricciones, diferenciadores o direccion creativa. No reemplaza la investigacion de competencia; si hay competencia, guia el primer angulo y los outputs no deben contradecirlo."),
24695
- productLabel: z100.string().trim().max(80).optional().describe('Opcional. Nombre o tipo del producto en pocas palabras (ej. "collar de oro", "quita pelusas para ropa"). Es AUTORITATIVO: la IA usa esta identidad y no la reemplaza por otra categor\xEDa. Si lo omites, la IA lo detecta desde la imagen. NO salta la extracci\xF3n.'),
24696
- buyerPersona: z100.string().optional().describe('Opcional. Descripci\xF3n del comprador objetivo. Ej. "Mujeres 35-50, profesionales urbanas". Si se omite, la IA infiere desde el \xE1ngulo y producto.'),
24697
- isCombo: z100.boolean().optional().describe("Opcional. Si true, el creativo presenta el producto como combo/pack. Default false."),
24698
- competitorScanEnabled: z100.boolean().optional().describe("Opcional. Default false: omitirlo significa SIN estudio de mercado. Antes de crear, llama estimate_market_study_cost, muestra al usuario el costo con y sin estudio y preg\xFAntale si lo quiere; env\xEDa true solo si lo acepta (o si solicita la narrativa an\xE1lisis de mercado). En video, true analiza anuncios de la competencia y desbloquea la narrativa an\xE1lisis de mercado; si el estudio no encuentra datos suficientes, degrada al planner cl\xE1sico."),
24699
- brandId: z100.string().uuid().optional().describe("Opcional. ID de una marca del usuario; si se env\xEDa, el sistema usa su voz, colores y persona para enriquecer el creativo.")
25597
+ price: z105.string().min(1).max(120).optional().describe('Precio en formato libre \u2014 ej. "$89.900", "USD 29.99". Opcional pero MUY IMPACTANTE para conversi\xF3n: si el usuario no lo mencion\xF3, PREG\xDANTALE antes de invocar. Si el usuario te dice "t\xFA elige", omite el campo y la IA del backend sugiere uno.'),
25598
+ offer: z105.string().min(1).max(240).optional().describe('Oferta a destacar \u2014 ej. "2x1", "Env\xEDo gratis", "50% OFF". Opcional pero MUY IMPACTANTE: si el usuario no lo mencion\xF3, PREG\xDANTALE antes de invocar (es v\xE1lido que diga "sin oferta"). Si el usuario te dice "t\xFA elige", omite el campo.'),
25599
+ compareAtPrice: z105.string().min(1).max(120).optional().describe('Opcional. Precio anterior o de referencia para mostrar descuento. Ej. "$129.000" cuando price="$89.900".'),
25600
+ productContext: z105.string().max(3e3).optional().describe("Opcional. Informacion adicional del producto que la IA debe usar como contexto prioritario: uso real, comprador, restricciones, diferenciadores o direccion creativa. No reemplaza la investigacion de competencia; si hay competencia, guia el primer angulo y los outputs no deben contradecirlo."),
25601
+ productLabel: z105.string().trim().max(80).optional().describe('Opcional. Nombre o tipo del producto en pocas palabras (ej. "collar de oro", "quita pelusas para ropa"). Es AUTORITATIVO: la IA usa esta identidad y no la reemplaza por otra categor\xEDa. Si lo omites, la IA lo detecta desde la imagen. NO salta la extracci\xF3n.'),
25602
+ buyerPersona: z105.string().optional().describe('Opcional. Descripci\xF3n del comprador objetivo. Ej. "Mujeres 35-50, profesionales urbanas". Si se omite, la IA infiere desde el \xE1ngulo y producto.'),
25603
+ isCombo: z105.boolean().optional().describe("Opcional. Si true, el creativo presenta el producto como combo/pack. Default false."),
25604
+ competitorScanEnabled: z105.boolean().optional().describe("Opcional. Default false: omitirlo significa SIN estudio de mercado. Antes de crear, llama estimate_market_study_cost, muestra al usuario el costo con y sin estudio y preg\xFAntale si lo quiere; env\xEDa true solo si lo acepta (o si solicita la narrativa an\xE1lisis de mercado). En video, true analiza anuncios de la competencia y desbloquea la narrativa an\xE1lisis de mercado; si el estudio no encuentra datos suficientes, degrada al planner cl\xE1sico."),
25605
+ brandId: z105.string().uuid().optional().describe("Opcional. ID de una marca del usuario; si se env\xEDa, el sistema usa su voz, colores y persona para enriquecer el creativo.")
24700
25606
  };
24701
- var VideoPresenter = z100.discriminatedUnion("mode", [
24702
- z100.object({
24703
- mode: z100.literal("none")
25607
+ var VideoPresenter = z105.discriminatedUnion("mode", [
25608
+ z105.object({
25609
+ mode: z105.literal("none")
24704
25610
  }).strict(),
24705
- z100.object({
24706
- mode: z100.literal("saved_actor"),
24707
- actorId: z100.string().trim().min(1).max(120).describe("ID devuelto por list_actors para un actor guardado del usuario.")
25611
+ z105.object({
25612
+ mode: z105.literal("saved_actor"),
25613
+ actorId: z105.string().trim().min(1).max(120).describe("ID devuelto por list_actors para un actor guardado del usuario.")
24708
25614
  }).strict(),
24709
- z100.object({
24710
- mode: z100.literal("described"),
24711
- description: z100.string().trim().min(1).max(500).describe("Descripci\xF3n concreta de la persona que presenta el producto.")
25615
+ z105.object({
25616
+ mode: z105.literal("described"),
25617
+ description: z105.string().trim().min(1).max(500).describe("Descripci\xF3n concreta de la persona que presenta el producto.")
24712
25618
  }).strict()
24713
25619
  ]);
24714
- var VideoCreativeSetup = z100.discriminatedUnion("mode", [
24715
- z100.object({
24716
- mode: z100.literal("automatic").describe('S\xF3lo cuando el usuario pidi\xF3 expl\xEDcitamente "decide todo".')
25620
+ var VideoCreativeSetup = z105.discriminatedUnion("mode", [
25621
+ z105.object({
25622
+ mode: z105.literal("automatic").describe('S\xF3lo cuando el usuario pidi\xF3 expl\xEDcitamente "decide todo".')
24717
25623
  }).strict(),
24718
- z100.object({
24719
- mode: z100.literal("guided"),
25624
+ z105.object({
25625
+ mode: z105.literal("guided"),
24720
25626
  videoPreset: VideoPresetEnum.default("auto").describe('Narrativa opcional. Con estudio de mercado no la preguntes: se usa "auto" y el estudio define la estructura. Sin estudio conserva la elecci\xF3n del usuario. Todas las narrativas funcionan en Un solo clip y Multiescena.'),
24721
- buyerPersona: z100.string().trim().min(1).max(360),
25627
+ buyerPersona: z105.string().trim().min(1).max(360),
24722
25628
  animationStyle: AnimationStyleEnum.optional().describe('Opcional. Estilo visual SOLO para presets animados ("pixar_problem" o "pixar_sassy") \u2014 la API lo rechaza con cualquier otro preset. Opciones: "pixar_3d" (default, look 3D de pel\xEDcula animada), "claymation" (plastilina stop-motion artesanal), "wes_anderson" (tableau sim\xE9trico pastel), "sci_fi" (futurista con HUDs y ne\xF3n), "realista" (fotorrealista, fiel al producto). Si el usuario pide un look animado sin nombrar el estilo, omite el campo.'),
24723
25629
  presenter: VideoPresenter,
24724
- creativeDirection: z100.string().trim().min(1).max(500).nullable().describe("Direcci\xF3n visual elegida. null significa que el usuario deleg\xF3 expl\xEDcitamente esta decisi\xF3n.")
25630
+ creativeDirection: z105.string().trim().min(1).max(500).nullable().describe("Direcci\xF3n visual elegida. null significa que el usuario deleg\xF3 expl\xEDcitamente esta decisi\xF3n.")
24725
25631
  }).strict()
24726
25632
  ]);
24727
- var VideoInput = z100.object({
25633
+ var VideoInput = z105.object({
24728
25634
  images: CreativeRefs.images.optional(),
24729
25635
  winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
24730
- title: z100.string().min(1).describe('T\xEDtulo corto del producto. Aparece en la primera vista del video. Ej. "Crema Anti-Edad Premium".'),
24731
- primaryAngle: z100.string().min(1).describe('\xC1ngulo de venta principal (frase del beneficio). Ej. "Reduce arrugas en 14 d\xEDas" o "Para quienes odian las cremas grasosas".'),
25636
+ title: z105.string().min(1).describe('T\xEDtulo corto del producto. Aparece en la primera vista del video. Ej. "Crema Anti-Edad Premium".'),
25637
+ primaryAngle: z105.string().min(1).describe('\xC1ngulo de venta principal (frase del beneficio). Ej. "Reduce arrugas en 14 d\xEDas" o "Para quienes odian las cremas grasosas".'),
24732
25638
  language: CreativeRefs.language,
24733
25639
  country: CreativeRefs.country,
24734
- aspectRatio: z100.enum([
25640
+ aspectRatio: z105.enum([
24735
25641
  "9:16",
24736
25642
  "16:9",
24737
25643
  "Auto"
24738
25644
  ]).describe('Relaci\xF3n de aspecto. "9:16" = vertical (TikTok/Reels \u2014 default recomendado para ads). "16:9" = horizontal (YouTube). "Auto" = decide la IA.'),
24739
25645
  generateAiEdit: AiEditRequestSchema.optional().describe('Opcional. Pide la Edici\xF3n con IA: una pasada que a\xF1ade texto, efectos y m\xFAsica sobre cada video entregado (variante with_ai_edit; se cobra al entregar, por video). Nivel: "economy" (Econ\xF3mica, Sonnet 5.5, m\xE1s barata) o "pro" (Opus 5.5, mejor calidad, ~10 min). true equivale a "pro"; false/omitido = sin edici\xF3n.'),
24740
- durationSeconds: z100.number().int().min(4).max(30).default(15).describe("Opcional. Duraci\xF3n objetivo: Un solo clip Econ\xF3mico o Medio usa 15s; Un solo clip Pro usa 15s o 30s; Multiescena usa 15s o 30s totales. La combinaci\xF3n de formato y calidad determina la ruta y el costo."),
24741
- videoAngleCount: z100.number().int().min(1).max(3).describe("Cantidad de videos a renderizar: 1, 2 o 3. Es una decisi\xF3n de costo obligatoria: preg\xFAntala incluso cuando creativeSetup.mode=automatic."),
25646
+ durationSeconds: z105.number().int().min(4).max(30).default(15).describe("Opcional. Duraci\xF3n objetivo: Un solo clip Econ\xF3mico o Medio usa 15s; Un solo clip Pro usa 15s o 30s; Multiescena usa 15s o 30s totales. La combinaci\xF3n de formato y calidad determina la ruta y el costo."),
25647
+ videoAngleCount: z105.number().int().min(1).max(3).describe("Cantidad de videos a renderizar: 1, 2 o 3. Es una decisi\xF3n de costo obligatoria: preg\xFAntala incluso cuando creativeSetup.mode=automatic."),
24742
25648
  angleNarratives: PublicNarrativeStyleEnum.array().max(3).optional().describe('Opcional. Narrativa POR \xC1NGULO (posicional). Valores actuales: "review", "ugc_how_to", "ugc_unboxing_chaos", "problem_product_cta" (problema concreto, producto como soluci\xF3n y CTA), "product_showcase", "wearable_showcase", "cinematic", "wild_card", "animated_problem_pixar", "sassy_product_pixar", "market" (narrativa an\xE1lisis de mercado: adapta el video a los patrones ganadores estudiados de la competencia; requiere competitorScanEnabled: true). angleNarratives[i] fuerza la narrativa del \xE1ngulo i; las posiciones restantes las elige la IA. La lista no puede superar videoAngleCount.'),
24743
25649
  creativeSetup: VideoCreativeSetup.describe("Configuraci\xF3n creativa obligatoria. En guided pregunta narrativa, p\xFAblico, presentador y direcci\xF3n antes de confirmar. Usa automatic s\xF3lo si el usuario deleg\xF3 todo expl\xEDcitamente."),
24744
25650
  videoStructure: VideoStructureEnum.default("single_take").describe('Opcional. Formato: "single_take" = Un solo clip (generado completo; puede incluir cambios de plano) o "multi_scene" = Multiescena (varias tomas concatenadas). Default: single_take.'),
24745
25651
  videoQuality: VideoQualityEnum.default("economy").describe('Opcional. Calidad: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro. El sistema elige el proveedor internamente. Default: economy.'),
24746
25652
  videoResolution: VideoResolutionEnum.optional().describe('Opcional. Resoluci\xF3n del render: "480p" o "720p". Si se omite, se usa 480p; elige 720p expl\xEDcitamente si necesitas m\xE1s nitidez.'),
24747
- features: z100.array(z100.string()).optional().describe('Opcional. Lista de features/beneficios clave a mencionar. Ej. ["resistente al agua", "bater\xEDa 24h", "carga inal\xE1mbrica"].'),
25653
+ features: z105.array(z105.string()).optional().describe('Opcional. Lista de features/beneficios clave a mencionar. Ej. ["resistente al agua", "bater\xEDa 24h", "carga inal\xE1mbrica"].'),
24748
25654
  price: CreativeRefs.price,
24749
25655
  offer: CreativeRefs.offer,
24750
25656
  productContext: CreativeRefs.productContext,
24751
25657
  productLabel: CreativeRefs.productLabel,
24752
- cta: z100.string().optional().describe('Opcional. Call-to-action final del video. Ej. "Compra ahora", "Pide el tuyo hoy", "Link en bio". Si se omite, la IA escribe uno.'),
24753
- scriptNotes: z100.string().optional().describe('Opcional. Notas/restricciones para el guion (la IA las usa al redactar). Ej. "No mencionar la marca X", "Tono divertido, no cl\xEDnico", "Mencionar 2x1". NO es el guion literal: creativeSetup.mode=guided activa siempre la revisi\xF3n palabra-por-palabra con get_video_script / approve_video_script.'),
25658
+ cta: z105.string().optional().describe('Opcional. Call-to-action final del video. Ej. "Compra ahora", "Pide el tuyo hoy", "Link en bio". Si se omite, la IA escribe uno.'),
25659
+ scriptNotes: z105.string().optional().describe('Opcional. Notas/restricciones para el guion (la IA las usa al redactar). Ej. "No mencionar la marca X", "Tono divertido, no cl\xEDnico", "Mencionar 2x1". NO es el guion literal: creativeSetup.mode=guided activa siempre la revisi\xF3n palabra-por-palabra con get_video_script / approve_video_script.'),
24754
25660
  creativeGender: CreativeGenderEnum.optional().describe('Opcional. QUI\xC9N APARECE EN PANTALLA en el video: mujer ("female"), hombre ("male") o ambos ("mixed"). NO es la voz; cuando se fija, la voz se alinea sola con el personaje. M\xE1ndalo en cuanto el usuario diga qui\xE9n debe SALIR en el video, con cualquier redacci\xF3n ("quiero una mujer", "que salga un hombre", "protagonista femenina"): si no lo mandas, el g\xE9nero lo inventa la IA y el usuario puede recibir lo contrario de lo que pidi\xF3 sin ning\xFAn aviso. NO lo mandes cuando hable del P\xDABLICO COMPRADOR ("esto es para hombres", "mi p\xFAblico son mujeres", "va dirigido a mam\xE1s"): eso es a qui\xE9n se le vende, no qui\xE9n act\xFAa, y fijarlo ah\xED pinea un protagonista que nadie pidi\xF3. "mixed" solo cuando pida expl\xEDcitamente ambos, y ten en cuenta que no garantiza una mezcla: no fija ning\xFAn g\xE9nero y cada creativo elige su protagonista. No lo preguntes como paso obligatorio. Si creativeSetup.presenter.mode="saved_actor", el personaje guardado manda sobre este campo.'),
24755
25661
  competitorScanEnabled: CreativeRefs.competitorScanEnabled,
24756
- replicateWinnerWhenFound: z100.boolean().optional().describe("Conserva la preferencia de copiar un ganador si existe. false permite estudiar el mercado sin reemplazar un \xE1ngulo por el anuncio ganador. No a\xF1adas una pregunta obligatoria para este campo."),
25662
+ replicateWinnerWhenFound: z105.boolean().optional().describe("Conserva la preferencia de copiar un ganador si existe. false permite estudiar el mercado sin reemplazar un \xE1ngulo por el anuncio ganador. No a\xF1adas una pregunta obligatoria para este campo."),
24757
25663
  brandId: CreativeRefs.brandId
24758
25664
  }).strict();
24759
25665
  var FreeVideoQualityEnum = VideoQualityEnum;
@@ -24771,7 +25677,7 @@ var FREE_VIDEO_DURATIONS_BY_QUALITY = {
24771
25677
  length: 29
24772
25678
  }, (_, index) => index + 2)
24773
25679
  };
24774
- var FreeVideoModelIdEnum = z100.enum([
25680
+ var FreeVideoModelIdEnum = z105.enum([
24775
25681
  "grok-imagine-video-1-5-preview",
24776
25682
  "minimax-h3/reference-to-video",
24777
25683
  "wan/3-0-video",
@@ -24782,66 +25688,66 @@ var FREE_SELECTABLE_MODEL_IDS = [
24782
25688
  "minimax-h3/reference-to-video",
24783
25689
  "wan/3-0-video"
24784
25690
  ];
24785
- var FreeVideoInput = z100.object({
25691
+ var FreeVideoInput = z105.object({
24786
25692
  images: ImagesInput.optional().describe("Opcional. 1-5 fotos del producto. Om\xEDtelo para generar desde texto puro."),
24787
- rawPrompt: z100.string().trim().min(1).max(2e3).describe("Prompt o guion exacto del video. Si activas subt\xEDtulos, este mismo texto se usa como guion de subt\xEDtulos."),
25693
+ rawPrompt: z105.string().trim().min(1).max(2e3).describe("Prompt o guion exacto del video. Si activas subt\xEDtulos, este mismo texto se usa como guion de subt\xEDtulos."),
24788
25694
  language: CreativeRefs.language,
24789
25695
  quality: FreeVideoQualityEnum.describe('Calidad del video: "economy" = Econ\xF3mico, "medium" = Medio o "pro" = Pro (Wan).'),
24790
25696
  // Retired in MCP 7.0.0 (Task 11): kept in the schema, accepted, and
24791
25697
  // parsed ONLY so the handler can reject it with a message naming its
24792
25698
  // replacement — dropping it silently would turn a caller's explicit
24793
25699
  // Pro++ pick into a quiet fallback to Wan.
24794
- freeProModel: z100.enum([
25700
+ freeProModel: z105.enum([
24795
25701
  "wan",
24796
25702
  "seedance"
24797
25703
  ]).optional().describe("ELIMINADO en MCP 7.0.0 \u2014 usa `modelId`. Enviar este campo produce un error."),
24798
25704
  modelId: FreeVideoModelIdEnum.optional().describe('Opcional. Elige expl\xEDcitamente el modelo del registro en vez del default de la calidad: "grok-imagine-video-1-5-preview" (Grok 1.5), "minimax-h3/reference-to-video" (H3 Max) o "wan/3-0-video" (Wan 3.0). Om\xEDtelo para usar el modelo por defecto de la calidad elegida. El modelo determina la duraci\xF3n permitida (Grok 6/8/10/15s, H3 Max 4-15s, Wan 2-30s) y el precio. "bytedance/seedance-2-5" est\xE1 inactivo y se rechaza con un error claro, nunca un 500.'),
24799
- durationSeconds: z100.number().int().min(2).max(30).describe("Duraci\xF3n exacta. Econ\xF3mico: 6, 8, 10 o 15s; Medio: enteros de 4 a 15s; Pro Wan: 2 a 30s; Pro++ Seedance: 4 a 30s."),
25705
+ durationSeconds: z105.number().int().min(2).max(30).describe("Duraci\xF3n exacta. Econ\xF3mico: 6, 8, 10 o 15s; Medio: enteros de 4 a 15s; Pro Wan: 2 a 30s; Pro++ Seedance: 4 a 30s."),
24800
25706
  videoResolution: VideoResolutionEnum.describe("Resoluci\xF3n del video: 480p o 720p."),
24801
- generateAiMusic: z100.boolean().default(false).describe('Opcional. Agrega m\xFAsica instrumental IA debajo del audio nativo. Default false. Equivale a generateAiEdit (nivel "pro"): la Edici\xF3n con IA trae su propia m\xFAsica.'),
25707
+ generateAiMusic: z105.boolean().default(false).describe('Opcional. Agrega m\xFAsica instrumental IA debajo del audio nativo. Default false. Equivale a generateAiEdit (nivel "pro"): la Edici\xF3n con IA trae su propia m\xFAsica.'),
24802
25708
  generateAiEdit: AiEditRequestSchema.optional().describe('Opcional. Pide la Edici\xF3n con IA: una pasada que a\xF1ade texto, gr\xE1ficos y m\xFAsica sobre el video ya entregado (variante with_ai_edit; se cobra al entregar). Nivel: "economy" (Econ\xF3mica, Sonnet 5.5, m\xE1s barata) o "pro" (Opus 5.5, mejor calidad, ~10 min). true equivale a "pro". Default sin edici\xF3n.'),
24803
- addSubtitles: z100.boolean().default(false).describe("Opcional. Quema subt\xEDtulos usando el rawPrompt exacto. Default false."),
24804
- idempotencyKey: z100.string().uuid().optional().describe("Opcional. Se acepta por compatibilidad pero se ignora: la identidad del reintento se deriva autom\xE1ticamente de los argumentos sem\xE1nticos, as\xED que un retry con los mismos argumentos ya es idempotente sin este campo.")
25709
+ addSubtitles: z105.boolean().default(false).describe("Opcional. Quema subt\xEDtulos usando el rawPrompt exacto. Default false."),
25710
+ idempotencyKey: z105.string().uuid().optional().describe("Opcional. Se acepta por compatibilidad pero se ignora: la identidad del reintento se deriva autom\xE1ticamente de los argumentos sem\xE1nticos, as\xED que un retry con los mismos argumentos ya es idempotente sin este campo.")
24805
25711
  }).strict();
24806
25712
  var imageStyleList = ImageCreativeStyleEnum.options.join(" | ");
24807
- var ImageCreativeSetup = z100.discriminatedUnion("mode", [
24808
- z100.object({
24809
- mode: z100.literal("automatic")
25713
+ var ImageCreativeSetup = z105.discriminatedUnion("mode", [
25714
+ z105.object({
25715
+ mode: z105.literal("automatic")
24810
25716
  }).strict(),
24811
- z100.object({
24812
- mode: z100.literal("guided"),
24813
- creativeArchetype: z100.union([
25717
+ z105.object({
25718
+ mode: z105.literal("guided"),
25719
+ creativeArchetype: z105.union([
24814
25720
  ImageCreativeArchetypeEnum,
24815
- z100.literal("ai_decides")
25721
+ z105.literal("ai_decides")
24816
25722
  ]),
24817
- visualTreatment: z100.union([
25723
+ visualTreatment: z105.union([
24818
25724
  ImageCreativeVisualTreatmentEnum,
24819
- z100.literal("ai_decides")
25725
+ z105.literal("ai_decides")
24820
25726
  ]),
24821
25727
  aspectRatio: ImageCreativeAspectRatioEnum,
24822
- nVariants: z100.union([
24823
- z100.literal(1),
24824
- z100.literal(2),
24825
- z100.literal(3),
24826
- z100.literal(4),
24827
- z100.literal(6)
25728
+ nVariants: z105.union([
25729
+ z105.literal(1),
25730
+ z105.literal(2),
25731
+ z105.literal(3),
25732
+ z105.literal(4),
25733
+ z105.literal(6)
24828
25734
  ]),
24829
- imageModel: z100.enum(PUBLIC_IMAGE_QUALITY_INPUTS).describe('Calidad: "image:1k" (Est\xE1ndar) o "image:2k" (Premium). Los tokens gpt-image-2-5:{1k,2k} y gpt-image-2:{1k,2k} se siguen aceptando.'),
24830
- styleMix: z100.boolean().nullable().describe("Decisi\xF3n s\xF3lo para 2\u20134 variantes. Usa null para 1 o 6, cuando la UI no hace esta pregunta."),
24831
- generateAdCopy: z100.boolean(),
24832
- competitorScanEnabled: z100.boolean(),
24833
- productContext: z100.string().trim().min(1).max(3e3).nullable(),
24834
- creativeDirection: z100.string().trim().min(1).max(500).nullable(),
24835
- brandColors: z100.string().trim().min(1).max(240).nullable().describe('Colores en lenguaje natural, igual que en el chat web. Ej. "Azul y Dorado". null significa sin colores espec\xEDficos.'),
24836
- headline: z100.string().trim().min(1).max(120).nullable(),
24837
- subheadline: z100.string().trim().min(1).max(160).nullable()
25735
+ imageModel: z105.enum(PUBLIC_IMAGE_QUALITY_INPUTS).describe('Calidad: "image:1k" (Est\xE1ndar) o "image:2k" (Premium). Los tokens gpt-image-2-5:{1k,2k} y gpt-image-2:{1k,2k} se siguen aceptando.'),
25736
+ styleMix: z105.boolean().nullable().describe("Decisi\xF3n s\xF3lo para 2\u20134 variantes. Usa null para 1 o 6, cuando la UI no hace esta pregunta."),
25737
+ generateAdCopy: z105.boolean(),
25738
+ competitorScanEnabled: z105.boolean(),
25739
+ productContext: z105.string().trim().min(1).max(3e3).nullable(),
25740
+ creativeDirection: z105.string().trim().min(1).max(500).nullable(),
25741
+ brandColors: z105.string().trim().min(1).max(240).nullable().describe('Colores en lenguaje natural, igual que en el chat web. Ej. "Azul y Dorado". null significa sin colores espec\xEDficos.'),
25742
+ headline: z105.string().trim().min(1).max(120).nullable(),
25743
+ subheadline: z105.string().trim().min(1).max(160).nullable()
24838
25744
  }).strict()
24839
25745
  ]).superRefine((setup, context) => {
24840
25746
  if (setup.mode !== "guided") return;
24841
25747
  const needsStyleMix = setup.nVariants >= 2 && setup.nVariants <= 4;
24842
25748
  if (needsStyleMix && setup.styleMix === null) {
24843
25749
  context.addIssue({
24844
- code: z100.ZodIssueCode.custom,
25750
+ code: z105.ZodIssueCode.custom,
24845
25751
  path: [
24846
25752
  "styleMix"
24847
25753
  ],
@@ -24850,7 +25756,7 @@ var ImageCreativeSetup = z100.discriminatedUnion("mode", [
24850
25756
  }
24851
25757
  if (!needsStyleMix && setup.styleMix !== null) {
24852
25758
  context.addIssue({
24853
- code: z100.ZodIssueCode.custom,
25759
+ code: z105.ZodIssueCode.custom,
24854
25760
  path: [
24855
25761
  "styleMix"
24856
25762
  ],
@@ -24859,7 +25765,7 @@ var ImageCreativeSetup = z100.discriminatedUnion("mode", [
24859
25765
  }
24860
25766
  if (imageResolutionOf(setup.imageModel) === "2k" && setup.aspectRatio === "4:5") {
24861
25767
  context.addIssue({
24862
- code: z100.ZodIssueCode.custom,
25768
+ code: z105.ZodIssueCode.custom,
24863
25769
  path: [
24864
25770
  "aspectRatio"
24865
25771
  ],
@@ -24867,55 +25773,55 @@ var ImageCreativeSetup = z100.discriminatedUnion("mode", [
24867
25773
  });
24868
25774
  }
24869
25775
  });
24870
- var LandingCreativeSetup = z100.discriminatedUnion("mode", [
24871
- z100.object({
24872
- mode: z100.literal("automatic")
25776
+ var LandingCreativeSetup = z105.discriminatedUnion("mode", [
25777
+ z105.object({
25778
+ mode: z105.literal("automatic")
24873
25779
  }).strict(),
24874
- z100.object({
24875
- mode: z100.literal("guided"),
25780
+ z105.object({
25781
+ mode: z105.literal("guided"),
24876
25782
  landingStrategy: LandingStrategyEnum,
24877
25783
  landingImageFormat: LandingImageFormatEnum,
24878
- competitorScanEnabled: z100.boolean(),
24879
- paymentMethods: z100.string().trim().min(1).max(240).nullable(),
24880
- productContext: z100.string().trim().min(1).max(3e3).nullable(),
24881
- creativeDirection: z100.string().trim().min(1).max(500).nullable(),
24882
- headline: z100.string().trim().min(1).max(120).nullable(),
24883
- subheadline: z100.string().trim().min(1).max(160).nullable()
25784
+ competitorScanEnabled: z105.boolean(),
25785
+ paymentMethods: z105.string().trim().min(1).max(240).nullable(),
25786
+ productContext: z105.string().trim().min(1).max(3e3).nullable(),
25787
+ creativeDirection: z105.string().trim().min(1).max(500).nullable(),
25788
+ headline: z105.string().trim().min(1).max(120).nullable(),
25789
+ subheadline: z105.string().trim().min(1).max(160).nullable()
24884
25790
  }).strict()
24885
25791
  ]);
24886
- var ImageInput = z100.object({
25792
+ var ImageInput = z105.object({
24887
25793
  images: CreativeRefs.images.optional(),
24888
25794
  winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
24889
- productTitle: z100.string().min(1).describe('Nombre del producto. Ej. "Crema Anti-Edad Premium".'),
24890
- primaryAngle: z100.string().min(1).optional().describe('Opcional. \xC1ngulo de venta principal. Si se omite, ProductMaker lo genera y creativeSetup.mode="guided" lo muestra para revisi\xF3n antes de crear las im\xE1genes.'),
25795
+ productTitle: z105.string().min(1).describe('Nombre del producto. Ej. "Crema Anti-Edad Premium".'),
25796
+ primaryAngle: z105.string().min(1).optional().describe('Opcional. \xC1ngulo de venta principal. Si se omite, ProductMaker lo genera y creativeSetup.mode="guided" lo muestra para revisi\xF3n antes de crear las im\xE1genes.'),
24891
25797
  buyerPersona: CreativeRefs.buyerPersona,
24892
25798
  language: CreativeRefs.language,
24893
25799
  country: CreativeRefs.country,
24894
25800
  creativeSetup: ImageCreativeSetup.describe("Configuraci\xF3n obligatoria equivalente al wizard web. Usa guided salvo que el usuario delegue expl\xEDcitamente todo; presenta las decisiones guiadas en un \xFAnico checklist compacto."),
24895
25801
  imageStyle: ImageCreativeStyleEnum.optional().describe(`Opcional. Estilo del shot del producto. Valores: ${imageStyleList}. Si se omite, la IA escoge seg\xFAn el archetype.`),
24896
- features: z100.array(z100.string()).optional().describe('Opcional. Features/beneficios a destacar visualmente. Ej. ["resistente al agua", "ultra liviano"].'),
25802
+ features: z105.array(z105.string()).optional().describe('Opcional. Features/beneficios a destacar visualmente. Ej. ["resistente al agua", "ultra liviano"].'),
24897
25803
  price: CreativeRefs.price,
24898
- omitPrice: z100.boolean().optional().describe("Pon true \xFAnicamente cuando el usuario pida expl\xEDcitamente una imagen sin precio. Evita que el backend reutilice un precio extra\xEDdo del producto. No lo combines con price ni compareAtPrice."),
25804
+ omitPrice: z105.boolean().optional().describe("Pon true \xFAnicamente cuando el usuario pida expl\xEDcitamente una imagen sin precio. Evita que el backend reutilice un precio extra\xEDdo del producto. No lo combines con price ni compareAtPrice."),
24899
25805
  compareAtPrice: CreativeRefs.compareAtPrice,
24900
25806
  offer: CreativeRefs.offer,
24901
25807
  productLabel: CreativeRefs.productLabel,
24902
25808
  isCombo: CreativeRefs.isCombo,
24903
25809
  brandId: CreativeRefs.brandId
24904
25810
  });
24905
- var EditImageCreativeInput = z100.object({
24906
- taskId: z100.string().uuid().describe("ID de la tarea de imagen ya finalizada."),
24907
- variantIndex: z100.number().int().min(0).max(10).describe("\xCDndice de la variante a corregir (0 = primera imagen)."),
24908
- clientRequestId: z100.string().min(1).max(160).optional().describe("Identidad estable de esta correcci\xF3n; reutil\xEDzala al reconciliar una respuesta perdida, no para otra instrucci\xF3n."),
24909
- instruction: z100.string().min(1).max(1e3).describe('Qu\xE9 cambiar en esa imagen. Ej. "quita el badge de env\xEDo gratis", "cambia el fondo a blanco".')
25811
+ var EditImageCreativeInput = z105.object({
25812
+ taskId: z105.string().uuid().describe("ID de la tarea de imagen ya finalizada."),
25813
+ variantIndex: z105.number().int().min(0).max(10).describe("\xCDndice de la variante a corregir (0 = primera imagen)."),
25814
+ clientRequestId: z105.string().min(1).max(160).optional().describe("Identidad estable de esta correcci\xF3n; reutil\xEDzala al reconciliar una respuesta perdida, no para otra instrucci\xF3n."),
25815
+ instruction: z105.string().min(1).max(1e3).describe('Qu\xE9 cambiar en esa imagen. Ej. "quita el badge de env\xEDo gratis", "cambia el fondo a blanco".')
24910
25816
  });
24911
- var LandingInput = z100.object({
24912
- includeInitialLandingGif: z100.boolean().optional().describe("Opcional. En nuevas landings cl\xE1sicas habilitadas, omitirlo incluye el primer GIF del producto y su coste en el total. Env\xEDa false si el usuario lo excluye: no se genera ni se reserva su coste. Conserva la elecci\xF3n al confirmar y al reintentar."),
25817
+ var LandingInput = z105.object({
25818
+ includeInitialLandingGif: z105.boolean().optional().describe("Opcional. En nuevas landings cl\xE1sicas habilitadas, omitirlo incluye el primer GIF del producto y su coste en el total. Env\xEDa false si el usuario lo excluye: no se genera ni se reserva su coste. Conserva la elecci\xF3n al confirmar y al reintentar."),
24913
25819
  images: CreativeRefs.images.optional(),
24914
25820
  winnerReference: WinnerReferenceInput.optional().describe(WINNER_IMAGE_CHOICE_GUIDANCE),
24915
25821
  language: CreativeRefs.language,
24916
25822
  country: CreativeRefs.country,
24917
25823
  creativeSetup: LandingCreativeSetup.describe("Configuraci\xF3n obligatoria de landing cl\xE1sica equivalente al wizard web. No expone landing editable/code mientras siga siendo admin-only."),
24918
- salesAngle: z100.string().optional().describe('Opcional. \xC1ngulo de venta principal. Ej. "Reduce arrugas en 14 d\xEDas". Si se omite, la IA lo deduce de la imagen.'),
25824
+ salesAngle: z105.string().optional().describe('Opcional. \xC1ngulo de venta principal. Ej. "Reduce arrugas en 14 d\xEDas". Si se omite, la IA lo deduce de la imagen.'),
24919
25825
  buyerPersona: CreativeRefs.buyerPersona,
24920
25826
  price: CreativeRefs.price,
24921
25827
  compareAtPrice: CreativeRefs.compareAtPrice,
@@ -25197,8 +26103,8 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
25197
26103
  server.registerTool("get_image_edit_status", {
25198
26104
  description: imageEditStatusGuidance.summary,
25199
26105
  inputSchema: {
25200
- taskId: z100.string().uuid(),
25201
- operationId: z100.string().uuid()
26106
+ taskId: z105.string().uuid(),
26107
+ operationId: z105.string().uuid()
25202
26108
  },
25203
26109
  annotations: READS_INTERNAL
25204
26110
  }, async (input) => {
@@ -25255,10 +26161,10 @@ function registerCreativeTools(server, api, { transport = "http" } = {}) {
25255
26161
  __name(registerCreativeTools, "registerCreativeTools");
25256
26162
 
25257
26163
  // src/tools/creative-variants.ts
25258
- import { z as z101 } from "zod";
26164
+ import { z as z106 } from "zod";
25259
26165
  var estimateCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("estimate_creative_variant");
25260
26166
  var createCreativeVariantGuidance = getProductMakerCapabilityModelGuidance("create_creative_variant");
25261
- var LandingSectionKeyEnum = z101.enum([
26167
+ var LandingSectionKeyEnum = z106.enum([
25262
26168
  "problem_hook",
25263
26169
  "problem_cost",
25264
26170
  "solution_mechanism",
@@ -25298,24 +26204,24 @@ var LandingSectionKeyEnum = z101.enum([
25298
26204
  "lifestyle_fit",
25299
26205
  "join_lifestyle"
25300
26206
  ]);
25301
- var CreativeVariantKindEnum = z101.enum([
26207
+ var CreativeVariantKindEnum = z106.enum([
25302
26208
  "video",
25303
26209
  "image",
25304
26210
  "landing"
25305
26211
  ]);
25306
- var EstimateCreativeVariantInputBase = z101.object({
25307
- sourceTaskId: z101.string().uuid().describe("ID de la tarea original completada."),
26212
+ var EstimateCreativeVariantInputBase = z106.object({
26213
+ sourceTaskId: z106.string().uuid().describe("ID de la tarea original completada."),
25308
26214
  kind: CreativeVariantKindEnum,
25309
26215
  videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Solo cambia el preset p\xFAblico; el servidor conserva el modelo/tier del task origen."),
25310
26216
  videoResolution: VideoResolutionEnum.optional().describe("Opcional para video. Resoluci\xF3n del nuevo render."),
25311
- nVariants: z101.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
26217
+ nVariants: z106.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
25312
26218
  sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si ya conoces la secci\xF3n, evita cotizar la clasificaci\xF3n con IA."),
25313
- instructions: z101.string().trim().min(1).max(2e3).optional().describe("Opcional para landing. Si se env\xEDa sin sectionKey, el estimado suma la clasificaci\xF3n pagada con IA.")
26219
+ instructions: z106.string().trim().min(1).max(2e3).optional().describe("Opcional para landing. Si se env\xEDa sin sectionKey, el estimado suma la clasificaci\xF3n pagada con IA.")
25314
26220
  }).strict();
25315
26221
  var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine((input, ctx) => {
25316
26222
  if (input.kind === "video" && input.nVariants !== void 0) {
25317
26223
  ctx.addIssue({
25318
- code: z101.ZodIssueCode.custom,
26224
+ code: z106.ZodIssueCode.custom,
25319
26225
  path: [
25320
26226
  "nVariants"
25321
26227
  ],
@@ -25325,7 +26231,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
25325
26231
  if (input.kind !== "video") {
25326
26232
  if (input.videoPreset !== void 0) {
25327
26233
  ctx.addIssue({
25328
- code: z101.ZodIssueCode.custom,
26234
+ code: z106.ZodIssueCode.custom,
25329
26235
  path: [
25330
26236
  "videoPreset"
25331
26237
  ],
@@ -25334,7 +26240,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
25334
26240
  }
25335
26241
  if (input.videoResolution !== void 0) {
25336
26242
  ctx.addIssue({
25337
- code: z101.ZodIssueCode.custom,
26243
+ code: z106.ZodIssueCode.custom,
25338
26244
  path: [
25339
26245
  "videoResolution"
25340
26246
  ],
@@ -25344,7 +26250,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
25344
26250
  }
25345
26251
  if (input.kind !== "image" && input.nVariants !== void 0) {
25346
26252
  ctx.addIssue({
25347
- code: z101.ZodIssueCode.custom,
26253
+ code: z106.ZodIssueCode.custom,
25348
26254
  path: [
25349
26255
  "nVariants"
25350
26256
  ],
@@ -25354,7 +26260,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
25354
26260
  if (input.kind !== "landing") {
25355
26261
  if (input.sectionKey !== void 0) {
25356
26262
  ctx.addIssue({
25357
- code: z101.ZodIssueCode.custom,
26263
+ code: z106.ZodIssueCode.custom,
25358
26264
  path: [
25359
26265
  "sectionKey"
25360
26266
  ],
@@ -25363,7 +26269,7 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
25363
26269
  }
25364
26270
  if (input.instructions !== void 0) {
25365
26271
  ctx.addIssue({
25366
- code: z101.ZodIssueCode.custom,
26272
+ code: z106.ZodIssueCode.custom,
25367
26273
  path: [
25368
26274
  "instructions"
25369
26275
  ],
@@ -25372,31 +26278,31 @@ var EstimateCreativeVariantInput = EstimateCreativeVariantInputBase.superRefine(
25372
26278
  }
25373
26279
  }
25374
26280
  });
25375
- var CreateCreativeVariantInputBase = z101.object({
25376
- sourceTaskId: z101.string().uuid().describe("ID de la tarea original completada."),
26281
+ var CreateCreativeVariantInputBase = z106.object({
26282
+ sourceTaskId: z106.string().uuid().describe("ID de la tarea original completada."),
25377
26283
  kind: CreativeVariantKindEnum,
25378
- confirm: z101.literal(true).describe("Confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrarle el estimado de cr\xE9ditos."),
25379
- clientRequestId: z101.string().uuid().describe("UUID estable para esta intenci\xF3n (obligatorio por compatibilidad de contrato; el servidor deriva la identidad real del request desde los argumentos sem\xE1nticos, as\xED que un UUID nuevo en un retry NO crea una variante duplicada). Si la API devuelve status=error, una nueva generaci\xF3n exige otra confirmaci\xF3n."),
25380
- angle: z101.string().trim().min(1).max(500).optional().describe("\xC1ngulo nuevo para video o imagen."),
25381
- buyerPersona: z101.string().trim().min(1).max(360).optional().describe("Buyer persona coherente con el \xE1ngulo."),
25382
- scriptNotes: z101.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n breve del guion para una variante de video."),
25383
- creativeDirection: z101.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n creativa para una variante de imagen."),
26284
+ confirm: z106.literal(true).describe("Confirmaci\xF3n expl\xEDcita del usuario despu\xE9s de mostrarle el estimado de cr\xE9ditos."),
26285
+ clientRequestId: z106.string().uuid().describe("UUID estable para esta intenci\xF3n (obligatorio por compatibilidad de contrato; el servidor deriva la identidad real del request desde los argumentos sem\xE1nticos, as\xED que un UUID nuevo en un retry NO crea una variante duplicada). Si la API devuelve status=error, una nueva generaci\xF3n exige otra confirmaci\xF3n."),
26286
+ angle: z106.string().trim().min(1).max(500).optional().describe("\xC1ngulo nuevo para video o imagen."),
26287
+ buyerPersona: z106.string().trim().min(1).max(360).optional().describe("Buyer persona coherente con el \xE1ngulo."),
26288
+ scriptNotes: z106.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n breve del guion para una variante de video."),
26289
+ creativeDirection: z106.string().trim().min(1).max(2e3).optional().describe("Direcci\xF3n creativa para una variante de imagen."),
25384
26290
  videoPreset: TaskCreativeVariantVideoPresetEnum.optional().describe("Opcional para video. Preset p\xFAblico; el servidor resuelve modelo/tier desde el task origen."),
25385
26291
  videoResolution: VideoResolutionEnum.optional().describe("Opcional para video."),
25386
- generateAiMusic: z101.boolean().optional().describe("Opcional para video."),
25387
- nVariants: z101.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
26292
+ generateAiMusic: z106.boolean().optional().describe("Opcional para video."),
26293
+ nVariants: z106.number().int().min(1).max(3).optional().describe("Opcional para imagen. N\xFAmero de im\xE1genes adicionales (1-3)."),
25388
26294
  imageStyle: ImageCreativeStyleEnum.optional().describe("Opcional para imagen."),
25389
26295
  creativeArchetype: ImageCreativeArchetypeEnum.optional().describe("Opcional para imagen."),
25390
26296
  visualTreatment: ImageCreativeVisualTreatmentEnum.optional().describe("Opcional para imagen."),
25391
26297
  aspectRatio: ImageCreativeAspectRatioEnum.optional().describe("Opcional para imagen."),
25392
- styleMix: z101.boolean().optional().describe("Opcional para imagen."),
26298
+ styleMix: z106.boolean().optional().describe("Opcional para imagen."),
25393
26299
  sectionKey: LandingSectionKeyEnum.optional().describe("Opcional para landing. Si se omite, se clasifica con IA a partir de instructions."),
25394
- instructions: z101.string().trim().min(1).max(2e3).optional().describe("Solicitud libre para una nueva secci\xF3n de landing. La IA la clasifica si no env\xEDas sectionKey.")
26300
+ instructions: z106.string().trim().min(1).max(2e3).optional().describe("Solicitud libre para una nueva secci\xF3n de landing. La IA la clasifica si no env\xEDas sectionKey.")
25395
26301
  }).strict();
25396
26302
  var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((input, ctx) => {
25397
26303
  if ((input.kind === "video" || input.kind === "image") && !input.angle) {
25398
26304
  ctx.addIssue({
25399
- code: z101.ZodIssueCode.custom,
26305
+ code: z106.ZodIssueCode.custom,
25400
26306
  path: [
25401
26307
  "angle"
25402
26308
  ],
@@ -25405,7 +26311,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
25405
26311
  }
25406
26312
  if (input.kind === "landing" && !input.sectionKey && !input.instructions) {
25407
26313
  ctx.addIssue({
25408
- code: z101.ZodIssueCode.custom,
26314
+ code: z106.ZodIssueCode.custom,
25409
26315
  path: [
25410
26316
  "instructions"
25411
26317
  ],
@@ -25451,7 +26357,7 @@ var CreateCreativeVariantInput = CreateCreativeVariantInputBase.superRefine((inp
25451
26357
  for (const field of fieldsByKind[input.kind]) {
25452
26358
  if (input[field] !== void 0) {
25453
26359
  ctx.addIssue({
25454
- code: z101.ZodIssueCode.custom,
26360
+ code: z106.ZodIssueCode.custom,
25455
26361
  path: [
25456
26362
  field
25457
26363
  ],
@@ -25584,13 +26490,13 @@ function registerCreativeVariantTools(server, api) {
25584
26490
  __name(registerCreativeVariantTools, "registerCreativeVariantTools");
25585
26491
 
25586
26492
  // src/tools/script-review.ts
25587
- import { z as z102 } from "zod";
26493
+ import { z as z107 } from "zod";
25588
26494
  var getVideoScriptGuidance = getProductMakerCapabilityModelGuidance("get_video_script");
25589
26495
  var regenerateVideoScriptGuidance = getProductMakerCapabilityModelGuidance("regenerate_video_script");
25590
26496
  var approveVideoScriptGuidance = getProductMakerCapabilityModelGuidance("approve_video_script");
25591
- var GetVideoScriptInput = z102.object({
25592
- taskId: z102.string().min(1).describe("ID de la tarea (la misma que devolvi\xF3 create_product_task / generate_video_creative)."),
25593
- angleKey: z102.string().min(1).optional().describe('Clave del \xE1ngulo cuyo guion se quiere leer (formato "angle_0", "angle_1", ...). REQUERIDO para tareas multi-angle: si se omite, el backend resuelve a "angle_0" LITERAL (no "el primer pendiente"), as\xED que en multi-angle donde angle_0 ya est\xE9 aprobado/saltado obtendr\xEDas status="approved" y nunca alcanzar\xEDas el \xE1ngulo realmente pendiente. Para single-angle puede omitirse.')
26497
+ var GetVideoScriptInput = z107.object({
26498
+ taskId: z107.string().min(1).describe("ID de la tarea (la misma que devolvi\xF3 create_product_task / generate_video_creative)."),
26499
+ angleKey: z107.string().min(1).optional().describe('Clave del \xE1ngulo cuyo guion se quiere leer (formato "angle_0", "angle_1", ...). REQUERIDO para tareas multi-angle: si se omite, el backend resuelve a "angle_0" LITERAL (no "el primer pendiente"), as\xED que en multi-angle donde angle_0 ya est\xE9 aprobado/saltado obtendr\xEDas status="approved" y nunca alcanzar\xEDas el \xE1ngulo realmente pendiente. Para single-angle puede omitirse.')
25594
26500
  }).strict();
25595
26501
  var ApproveVideoScriptInput = ApproveVideoScriptCapabilityRequest;
25596
26502
  var RegenerateVideoScriptInput = RegenerateVideoScriptCapabilityRequest.extend({
@@ -25673,7 +26579,7 @@ function registerScriptReviewTools(server, api) {
25673
26579
  __name(registerScriptReviewTools, "registerScriptReviewTools");
25674
26580
 
25675
26581
  // src/tools/connections.ts
25676
- import { z as z103 } from "zod";
26582
+ import { z as z108 } from "zod";
25677
26583
  var listShopifyShopsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_shops");
25678
26584
  var listShopifyProductsGuidance = getProductMakerCapabilityModelGuidance("list_shopify_products");
25679
26585
  var listMetaAdAccountsGuidance = getProductMakerCapabilityModelGuidance("list_meta_ad_accounts");
@@ -25682,7 +26588,7 @@ var listTikTokAdvertisersGuidance = getProductMakerCapabilityModelGuidance("list
25682
26588
  function registerConnectionTools(server, api) {
25683
26589
  server.registerTool("list_shopify_shops", {
25684
26590
  description: listShopifyShopsGuidance.summary + " Si la lista est\xE1 vac\xEDa, dile al usuario que conecte una tienda en productmaker.app/integrations antes de intentar publicar.",
25685
- inputSchema: z103.object({}).shape,
26591
+ inputSchema: z108.object({}).shape,
25686
26592
  annotations: READS_INTERNAL
25687
26593
  }, async () => {
25688
26594
  try {
@@ -25694,10 +26600,10 @@ function registerConnectionTools(server, api) {
25694
26600
  });
25695
26601
  server.registerTool("list_shopify_products", {
25696
26602
  description: listShopifyProductsGuidance.summary + ' Usa el `id` devuelto junto con `publicationMode="existing"` en `publish_to_shopify`. Si `taskId` se proporciona, la respuesta tambi\xE9n indica el producto publicado actualmente para esa tarea y tienda. No modifica Shopify.',
25697
- inputSchema: z103.object({
25698
- shopDomain: z103.string().min(3).max(120),
25699
- query: z103.string().trim().max(120).optional(),
25700
- taskId: z103.string().uuid().optional()
26603
+ inputSchema: z108.object({
26604
+ shopDomain: z108.string().min(3).max(120),
26605
+ query: z108.string().trim().max(120).optional(),
26606
+ taskId: z108.string().uuid().optional()
25701
26607
  }).shape,
25702
26608
  annotations: READS_EXTERNAL
25703
26609
  }, async ({ shopDomain, query, taskId }) => {
@@ -25715,7 +26621,7 @@ function registerConnectionTools(server, api) {
25715
26621
  });
25716
26622
  server.registerTool("list_meta_ad_accounts", {
25717
26623
  description: listMetaAdAccountsGuidance.summary + " Para publicar, prefiere `list_meta_destinations`, que tambi\xE9n devuelve el portfolio y las p\xE1ginas disponibles. Si est\xE1 vac\xEDa, ind\xEDcale al usuario conectar Meta en productmaker.app/integrations.",
25718
- inputSchema: z103.object({}).shape,
26624
+ inputSchema: z108.object({}).shape,
25719
26625
  annotations: READS_EXTERNAL
25720
26626
  }, async () => {
25721
26627
  try {
@@ -25727,7 +26633,7 @@ function registerConnectionTools(server, api) {
25727
26633
  });
25728
26634
  server.registerTool("list_meta_destinations", {
25729
26635
  description: listMetaDestinationsGuidance.summary + " Es obligatorio llamar esta herramienta antes de publicar, mostrar las opciones y enviar al publicador el `portfolioId`, `adAccountId` y `pageId` elegidos; nunca elijas silenciosamente la primera p\xE1gina o cuenta. No modifica Meta.",
25730
- inputSchema: z103.object({}).shape,
26636
+ inputSchema: z108.object({}).shape,
25731
26637
  annotations: READS_EXTERNAL,
25732
26638
  _meta: {
25733
26639
  "openai/widgetAccessible": true
@@ -25742,7 +26648,7 @@ function registerConnectionTools(server, api) {
25742
26648
  });
25743
26649
  server.registerTool("list_tiktok_advertisers", {
25744
26650
  description: listTikTokAdvertisersGuidance.summary + " Si est\xE1 vac\xEDa, ind\xEDcale al usuario conectar TikTok en productmaker.app/integrations.",
25745
- inputSchema: z103.object({}).shape,
26651
+ inputSchema: z108.object({}).shape,
25746
26652
  annotations: READS_EXTERNAL
25747
26653
  }, async () => {
25748
26654
  try {
@@ -25756,7 +26662,7 @@ function registerConnectionTools(server, api) {
25756
26662
  __name(registerConnectionTools, "registerConnectionTools");
25757
26663
 
25758
26664
  // src/tools/actors.ts
25759
- import { z as z104 } from "zod";
26665
+ import { z as z109 } from "zod";
25760
26666
  var listActorsGuidance = getProductMakerCapabilityModelGuidance("list_actors");
25761
26667
  var actorVoiceGuidance = {
25762
26668
  capabilities: getProductMakerCapabilityModelGuidance("get_actor_voice_capabilities"),
@@ -25796,7 +26702,7 @@ function sanitizeVoiceResult(value) {
25796
26702
  __name(sanitizeVoiceResult, "sanitizeVoiceResult");
25797
26703
  function registerActorTools(server, api) {
25798
26704
  const actor = {
25799
- actorId: z104.string().min(1).max(64)
26705
+ actorId: z109.string().min(1).max(64)
25800
26706
  };
25801
26707
  const safe = /* @__PURE__ */ __name(async (request) => {
25802
26708
  try {
@@ -25825,8 +26731,8 @@ function registerActorTools(server, api) {
25825
26731
  inputSchema: {
25826
26732
  ...actor,
25827
26733
  draft: ActorVoiceDraftSchema,
25828
- requestKey: z104.string().trim().min(1).max(128),
25829
- acceptedQuoteId: z104.string().trim().min(1).max(128)
26734
+ requestKey: z109.string().trim().min(1).max(128),
26735
+ acceptedQuoteId: z109.string().trim().min(1).max(128)
25830
26736
  },
25831
26737
  annotations: CREATES_PAID
25832
26738
  }, async ({ actorId, ...body }) => safe(api.postJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/previews`, body)));
@@ -25834,7 +26740,7 @@ function registerActorTools(server, api) {
25834
26740
  description: actorVoiceGuidance.get.summary,
25835
26741
  inputSchema: {
25836
26742
  ...actor,
25837
- candidateId: z104.string().min(1).max(64)
26743
+ candidateId: z109.string().min(1).max(64)
25838
26744
  },
25839
26745
  annotations: READS_INTERNAL
25840
26746
  }, async ({ actorId, candidateId }) => safe(api.getJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/previews/${encodeURIComponent(candidateId)}`)));
@@ -25842,15 +26748,15 @@ function registerActorTools(server, api) {
25842
26748
  description: actorVoiceGuidance.approve.summary,
25843
26749
  inputSchema: {
25844
26750
  ...actor,
25845
- candidateId: z104.string().min(1).max(64),
25846
- expectedRevision: z104.number().int().positive(),
25847
- expectedApprovedRevision: z104.number().int().positive().nullable().optional()
26751
+ candidateId: z109.string().min(1).max(64),
26752
+ expectedRevision: z109.number().int().positive(),
26753
+ expectedApprovedRevision: z109.number().int().positive().nullable().optional()
25848
26754
  },
25849
26755
  annotations: CREATES_INTERNAL
25850
26756
  }, async ({ actorId, ...body }) => safe(api.postJson(`/v1/actors/${encodeURIComponent(actorId)}/voice/approve`, body)));
25851
26757
  server.registerTool("list_actors", {
25852
26758
  description: listActorsGuidance.summary + " Devuelve id, nombre, descripci\xF3n, g\xE9nero y voz privada del personaje. Cuando el personaje tiene una voz personalizada, `voice.identityId` y `voice.revision` identifican la versi\xF3n aprobada \u2014 conserva la revisi\xF3n al llamar `approve_actor_voice` (expectedApprovedRevision) para reemplazarla. Los IDs de proveedor nunca se exponen por MCP. Usa el `id` como `actorId` al crear o editar una tarea. Solo aparecen los personajes listos para usar; si la lista est\xE1 vac\xEDa, dile al usuario que cree uno en productmaker.app antes de intentar asignarlo. No modifica nada.",
25853
- inputSchema: z104.object({}).shape,
26759
+ inputSchema: z109.object({}).shape,
25854
26760
  annotations: READS_INTERNAL
25855
26761
  }, async () => {
25856
26762
  try {
@@ -25883,7 +26789,7 @@ function registerActorTools(server, api) {
25883
26789
  __name(registerActorTools, "registerActorTools");
25884
26790
 
25885
26791
  // src/tools/publish.ts
25886
- import { z as z105 } from "zod";
26792
+ import { z as z110 } from "zod";
25887
26793
 
25888
26794
  // src/tools/meta-publish-attempt-id.ts
25889
26795
  var META_PUBLISH_NAMESPACE = "7b19c9ac-b4eb-4db1-970e-c2f24ce30b98";
@@ -25922,40 +26828,40 @@ var publishToShopifyGuidance = getProductMakerCapabilityModelGuidance("publish_t
25922
26828
  var publishToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_to_meta");
25923
26829
  var publishCreativesToMetaGuidance = getProductMakerCapabilityModelGuidance("publish_creatives_to_meta");
25924
26830
  var publishToTikTokGuidance = getProductMakerCapabilityModelGuidance("publish_to_tiktok");
25925
- var ShopifyInput = z105.object({
25926
- taskId: z105.string().min(1),
25927
- shopDomain: z105.string().min(1),
26831
+ var ShopifyInput = z110.object({
26832
+ taskId: z110.string().min(1),
26833
+ shopDomain: z110.string().min(1),
25928
26834
  /** Override: number of landing images to include. Default = ALL images the
25929
26835
  * task generated (the MCP fetches /v1/results first to count). Bounded
25930
26836
  * generously here; the backend validates each index against
25931
26837
  * landing.images.length and rejects out-of-range. */
25932
- numLandingImages: z105.number().int().min(1).max(20).optional(),
25933
- variantIndex: z105.number().int().min(0).optional(),
26838
+ numLandingImages: z110.number().int().min(1).max(20).optional(),
26839
+ variantIndex: z110.number().int().min(0).optional(),
25934
26840
  /** ASK THE USER before setting: "¿Tu producto tiene variantes (talla, color, etc.)?".
25935
26841
  * When true, the landing renders variant-picker pills; when false, it ships
25936
26842
  * a single-option product page. Defaults to false. */
25937
- showVariantPicker: z105.boolean().optional(),
26843
+ showVariantPicker: z110.boolean().optional(),
25938
26844
  /** Default `auto` updates the product previously published for this task and
25939
26845
  * shop. Use `existing` with targetProductId to choose another product, or
25940
26846
  * `new` only when the user explicitly wants a duplicate/new listing. */
25941
- publicationMode: z105.enum([
26847
+ publicationMode: z110.enum([
25942
26848
  "auto",
25943
26849
  "existing",
25944
26850
  "new"
25945
26851
  ]).optional(),
25946
26852
  /** Shopify product GID, numeric id, or admin product URL. Required when
25947
26853
  * publicationMode is `existing`. */
25948
- targetProductId: z105.string().trim().min(1).max(300).optional(),
26854
+ targetProductId: z110.string().trim().min(1).max(300).optional(),
25949
26855
  /** Add an announcement bar text above add-to-cart (optional). */
25950
- announcementBarEnabled: z105.boolean().optional(),
25951
- announcementBarText: z105.string().trim().min(1).max(SHOPIFY_ANNOUNCEMENT_BAR_MAX_LENGTH).optional(),
26856
+ announcementBarEnabled: z110.boolean().optional(),
26857
+ announcementBarText: z110.string().trim().min(1).max(SHOPIFY_ANNOUNCEMENT_BAR_MAX_LENGTH).optional(),
25952
26858
  commerceCorrection: PublishCommerceCorrectionSchema.optional().describe("Complete seller-confirmed commerce values, with the revision and fingerprint returned in recovery. Never invent missing prices or convert currency."),
25953
- confirmed: z105.boolean().optional().describe("Required as true only when submitting commerceCorrection, after showing its values and obtaining explicit seller confirmation.")
26859
+ confirmed: z110.boolean().optional().describe("Required as true only when submitting commerceCorrection, after showing its values and obtaining explicit seller confirmation.")
25954
26860
  });
25955
26861
  var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value, ctx) => {
25956
26862
  if (value.commerceCorrection && value.confirmed !== true) {
25957
26863
  ctx.addIssue({
25958
- code: z105.ZodIssueCode.custom,
26864
+ code: z110.ZodIssueCode.custom,
25959
26865
  path: [
25960
26866
  "confirmed"
25961
26867
  ],
@@ -25964,7 +26870,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
25964
26870
  }
25965
26871
  if (value.announcementBarEnabled && !value.announcementBarText) {
25966
26872
  ctx.addIssue({
25967
- code: z105.ZodIssueCode.custom,
26873
+ code: z110.ZodIssueCode.custom,
25968
26874
  path: [
25969
26875
  "announcementBarText"
25970
26876
  ],
@@ -25973,7 +26879,7 @@ var ShopifyInputWithAnnouncementBarValidation = ShopifyInput.superRefine((value,
25973
26879
  }
25974
26880
  if (!value.announcementBarEnabled && value.announcementBarText) {
25975
26881
  ctx.addIssue({
25976
- code: z105.ZodIssueCode.custom,
26882
+ code: z110.ZodIssueCode.custom,
25977
26883
  path: [
25978
26884
  "announcementBarText"
25979
26885
  ],
@@ -25987,91 +26893,91 @@ function parseShopifyInput(rawInput) {
25987
26893
  return parsed.data;
25988
26894
  }
25989
26895
  __name(parseShopifyInput, "parseShopifyInput");
25990
- var McpCampaignConfig = z105.object({
26896
+ var McpCampaignConfig = z110.object({
25991
26897
  /** ALWAYS in US dollars, whatever the ad account's currency is. ProductMaker
25992
26898
  * converts to the account currency server-side. Do NOT pre-convert: on a COP
25993
26899
  * account the user's "60.000 al día" is `dailyBudgetUsd: 15`, not 60000. */
25994
- dailyBudgetUsd: z105.number().positive().optional(),
26900
+ dailyBudgetUsd: z110.number().positive().optional(),
25995
26901
  /** ISO-3166-1 alpha-2 country codes or resolvable names (CountryIso2Schema
25996
26902
  * normalizes at validation). Meta accepts max 1 (single-country ad set).
25997
26903
  * TikTok takes only the first entry. */
25998
- targetCountries: z105.array(CountryIso2Schema).max(1).optional(),
25999
- campaignName: z105.string().trim().min(1).max(100).optional()
26904
+ targetCountries: z110.array(CountryIso2Schema).max(1).optional(),
26905
+ campaignName: z110.string().trim().min(1).max(100).optional()
26000
26906
  });
26001
26907
  var McpAdAccountId = MetaAdAccountId.describe('Meta ad account id. Accepts "act_1234567890" or the bare numeric id "1234567890".');
26002
- var MetaInput = z105.object({
26003
- taskId: z105.string().min(1),
26908
+ var MetaInput = z110.object({
26909
+ taskId: z110.string().min(1),
26004
26910
  /** Exact Meta Business portfolio selected from `list_meta_destinations`. */
26005
- portfolioId: z105.string().trim().min(1),
26911
+ portfolioId: z110.string().trim().min(1),
26006
26912
  /** Exact Facebook Page selected from `list_meta_destinations`. */
26007
- pageId: z105.string().trim().min(1),
26913
+ pageId: z110.string().trim().min(1),
26008
26914
  adAccountId: McpAdAccountId,
26009
- pixelId: z105.string().min(1).optional(),
26010
- landingUrl: z105.string().url().optional(),
26915
+ pixelId: z110.string().min(1).optional(),
26916
+ landingUrl: z110.string().url().optional(),
26011
26917
  /** Select which angles to publish by 0-based index. Omit to publish all
26012
26918
  * successful angles. Example: a task with 3 angles → `[0,2]` publishes #0 + #2. */
26013
- angleIndexes: z105.array(z105.number().int().nonnegative()).optional(),
26919
+ angleIndexes: z110.array(z110.number().int().nonnegative()).optional(),
26014
26920
  campaignConfig: McpCampaignConfig.optional(),
26015
26921
  /** Override the ad's primary text (body copy). If omitted, ProductMaker
26016
26922
  * uses the auto-generated copy attached to the task. Capped at 500 chars
26017
26923
  * (Meta's primary-text limit). */
26018
- primaryText: z105.string().trim().min(1).max(500).optional(),
26924
+ primaryText: z110.string().trim().min(1).max(500).optional(),
26019
26925
  /** Optional WhatsApp number. When set, the ad button opens a WhatsApp chat
26020
26926
  * (wa.me) instead of a landing page. */
26021
- phoneNumber: z105.string().min(8).max(32).optional()
26927
+ phoneNumber: z110.string().min(8).max(32).optional()
26022
26928
  });
26023
- var GroupedTaskSource = z105.object({
26024
- type: z105.literal("task"),
26025
- taskId: z105.string().min(1),
26026
- angleIndex: z105.number().int().min(0).optional(),
26027
- videoVariant: z105.enum([
26929
+ var GroupedTaskSource = z110.object({
26930
+ type: z110.literal("task"),
26931
+ taskId: z110.string().min(1),
26932
+ angleIndex: z110.number().int().min(0).optional(),
26933
+ videoVariant: z110.enum([
26028
26934
  "with_subtitles",
26029
26935
  "without_subtitles"
26030
26936
  ]).optional(),
26031
- imageVariantIndex: z105.number().int().min(0).optional()
26032
- });
26033
- var GroupedMediaSource = z105.object({
26034
- type: z105.literal("media"),
26035
- url: z105.string().url().optional().describe("Public HTTPS media URL. For a file on the user laptop, use request_media_upload on the hosted MCP instead."),
26036
- path: z105.string().min(1).optional().describe('Local file path only when this MCP runs over stdio. On the hosted MCP, call request_media_upload and then use source.type="asset".'),
26037
- thumbnailUrl: z105.string().url().optional(),
26038
- thumbnailPath: z105.string().min(1).optional()
26937
+ imageVariantIndex: z110.number().int().min(0).optional()
26938
+ });
26939
+ var GroupedMediaSource = z110.object({
26940
+ type: z110.literal("media"),
26941
+ url: z110.string().url().optional().describe("Public HTTPS media URL. For a file on the user laptop, use request_media_upload on the hosted MCP instead."),
26942
+ path: z110.string().min(1).optional().describe('Local file path only when this MCP runs over stdio. On the hosted MCP, call request_media_upload and then use source.type="asset".'),
26943
+ thumbnailUrl: z110.string().url().optional(),
26944
+ thumbnailPath: z110.string().min(1).optional()
26039
26945
  }).refine((value) => Boolean(value.url) !== Boolean(value.path), {
26040
26946
  message: "media source needs exactly one of `url` or `path`"
26041
26947
  }).refine((value) => !(value.thumbnailUrl && value.thumbnailPath), {
26042
26948
  message: "media source needs at most one of `thumbnailUrl` or `thumbnailPath`"
26043
26949
  });
26044
- var GroupedUploadedAssetSource = z105.object({
26045
- type: z105.literal("asset"),
26950
+ var GroupedUploadedAssetSource = z110.object({
26951
+ type: z110.literal("asset"),
26046
26952
  /** Returned by check_media_upload. ProductMaker resolves ownership server-side. */
26047
- assetId: z105.string().uuid(),
26048
- thumbnailAssetId: z105.string().uuid().optional()
26953
+ assetId: z110.string().uuid(),
26954
+ thumbnailAssetId: z110.string().uuid().optional()
26049
26955
  });
26050
- var GroupedCreative = z105.object({
26051
- type: z105.enum([
26956
+ var GroupedCreative = z110.object({
26957
+ type: z110.enum([
26052
26958
  "image",
26053
26959
  "video"
26054
26960
  ]),
26055
- source: z105.union([
26961
+ source: z110.union([
26056
26962
  GroupedTaskSource,
26057
26963
  GroupedMediaSource,
26058
26964
  GroupedUploadedAssetSource
26059
26965
  ]),
26060
- title: z105.string().max(120).optional(),
26061
- description: z105.string().max(500).optional(),
26966
+ title: z110.string().max(120).optional(),
26967
+ description: z110.string().max(500).optional(),
26062
26968
  cta: MetaCtaType.optional(),
26063
- creativeId: z105.string().min(1).optional()
26969
+ creativeId: z110.string().min(1).optional()
26064
26970
  });
26065
- var GroupedCampaignConfigBase = z105.object({
26971
+ var GroupedCampaignConfigBase = z110.object({
26066
26972
  campaignType: MetaCampaignType.default("sales"),
26067
26973
  optimizationMode: MetaOptimizationMode.default("advantage_plus"),
26068
26974
  budgetMode: MetaBudgetMode.optional(),
26069
- campaignDailyBudget: z105.number().int().positive().optional(),
26070
- adSets: z105.array(z105.object({
26071
- tempId: z105.string().min(1).max(80),
26072
- name: z105.string().min(1).max(100),
26073
- dailyBudget: z105.number().int().positive().optional(),
26074
- creativeIds: z105.array(z105.string().min(1)).min(1)
26975
+ campaignDailyBudget: z110.number().int().positive().optional(),
26976
+ adSets: z110.array(z110.object({
26977
+ tempId: z110.string().min(1).max(80),
26978
+ name: z110.string().min(1).max(100),
26979
+ dailyBudget: z110.number().int().positive().optional(),
26980
+ creativeIds: z110.array(z110.string().min(1)).min(1)
26075
26981
  })).min(1).max(CAMPAIGN_LIMITS.MAX_AD_SETS),
26076
26982
  /**
26077
26983
  * Valid values are 'landing' and 'whatsapp' — there is no 'website'. This
@@ -26079,17 +26985,17 @@ var GroupedCampaignConfigBase = z105.object({
26079
26985
  * opaque `invalid_literal` and made the WhatsApp destination — supported by
26080
26986
  * the API since #849 — unreachable from this tool.
26081
26987
  */
26082
- destination: z105.discriminatedUnion("type", [
26083
- z105.object({
26084
- type: z105.literal("landing"),
26085
- landingUrl: z105.string().url()
26988
+ destination: z110.discriminatedUnion("type", [
26989
+ z110.object({
26990
+ type: z110.literal("landing"),
26991
+ landingUrl: z110.string().url()
26086
26992
  }),
26087
- z105.object({
26088
- type: z105.literal("whatsapp"),
26089
- phoneNumber: z105.string().min(8).max(32)
26993
+ z110.object({
26994
+ type: z110.literal("whatsapp"),
26995
+ phoneNumber: z110.string().min(8).max(32)
26090
26996
  })
26091
26997
  ]),
26092
- saveAsDefault: z105.boolean().default(false),
26998
+ saveAsDefault: z110.boolean().default(false),
26093
26999
  budgetPolicy: MetaBudgetPolicy.optional()
26094
27000
  });
26095
27001
  function resolveBudgetMode(value) {
@@ -26103,7 +27009,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
26103
27009
  const budgetMode = resolveBudgetMode(value);
26104
27010
  if (budgetMode === "campaign" && value.campaignDailyBudget === void 0) {
26105
27011
  ctx.addIssue({
26106
- code: z105.ZodIssueCode.custom,
27012
+ code: z110.ZodIssueCode.custom,
26107
27013
  path: [
26108
27014
  "campaignDailyBudget"
26109
27015
  ],
@@ -26114,7 +27020,7 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
26114
27020
  value.adSets.forEach((adSet, index) => {
26115
27021
  if (adSet.dailyBudget === void 0) {
26116
27022
  ctx.addIssue({
26117
- code: z105.ZodIssueCode.custom,
27023
+ code: z110.ZodIssueCode.custom,
26118
27024
  path: [
26119
27025
  "adSets",
26120
27026
  index,
@@ -26129,28 +27035,28 @@ var GroupedCampaignConfig = GroupedCampaignConfigBase.superRefine((value, ctx) =
26129
27035
  ...value,
26130
27036
  budgetMode: resolveBudgetMode(value)
26131
27037
  }));
26132
- var PublishCreativesToMetaInputBase = z105.object({
26133
- creatives: z105.array(GroupedCreative).min(1).max(CAMPAIGN_LIMITS.MAX_CREATIVES),
27038
+ var PublishCreativesToMetaInputBase = z110.object({
27039
+ creatives: z110.array(GroupedCreative).min(1).max(CAMPAIGN_LIMITS.MAX_CREATIVES),
26134
27040
  /** Exact Meta Business portfolio selected from `list_meta_destinations`. */
26135
- portfolioId: z105.string().trim().min(1),
27041
+ portfolioId: z110.string().trim().min(1),
26136
27042
  /** Exact Facebook Page selected from `list_meta_destinations`. */
26137
- pageId: z105.string().trim().min(1),
27043
+ pageId: z110.string().trim().min(1),
26138
27044
  adAccountId: McpAdAccountId,
26139
- pixelId: z105.string().min(1).optional(),
27045
+ pixelId: z110.string().min(1).optional(),
26140
27046
  /** Required unless `campaignConfig.destination` is whatsapp — see the
26141
27047
  * superRefine below. Mirrors the API's `FacebookCreateCampaignFromTasksBodySchema`. */
26142
- landingUrl: z105.string().url().optional(),
27048
+ landingUrl: z110.string().url().optional(),
26143
27049
  /** ISO-2 code or resolvable country name — mirrors the API contract
26144
27050
  * (CountryIso2Schema), which normalizes names to alpha-2 at validation. */
26145
27051
  targetCountry: CountryIso2Schema,
26146
- campaignName: z105.string().trim().min(1).max(100),
27052
+ campaignName: z110.string().trim().min(1).max(100),
26147
27053
  campaignConfig: GroupedCampaignConfig.optional()
26148
27054
  });
26149
27055
  var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((value, ctx) => {
26150
27056
  const destination = value.campaignConfig?.destination;
26151
27057
  if (destination?.type !== "whatsapp" && destination?.type !== "landing" && !value.landingUrl) {
26152
27058
  ctx.addIssue({
26153
- code: z105.ZodIssueCode.custom,
27059
+ code: z110.ZodIssueCode.custom,
26154
27060
  path: [
26155
27061
  "landingUrl"
26156
27062
  ],
@@ -26159,7 +27065,7 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
26159
27065
  }
26160
27066
  if (destination?.type === "landing" && value.landingUrl && destination.landingUrl !== value.landingUrl) {
26161
27067
  ctx.addIssue({
26162
- code: z105.ZodIssueCode.custom,
27068
+ code: z110.ZodIssueCode.custom,
26163
27069
  path: [
26164
27070
  "campaignConfig",
26165
27071
  "destination",
@@ -26178,16 +27084,16 @@ var PublishCreativesToMetaInput = PublishCreativesToMetaInputBase.superRefine((v
26178
27084
  }
26179
27085
  return value;
26180
27086
  });
26181
- var PresignUploadResponseSchema = z105.object({
26182
- uploadUrl: z105.string().url().refine((value) => {
27087
+ var PresignUploadResponseSchema = z110.object({
27088
+ uploadUrl: z110.string().url().refine((value) => {
26183
27089
  const url = new URL(value);
26184
27090
  return !url.username && !url.password && url.protocol === "https:";
26185
27091
  }, "presigned upload URL must be HTTPS without embedded credentials"),
26186
- publicUrl: z105.string().url().refine((value) => {
27092
+ publicUrl: z110.string().url().refine((value) => {
26187
27093
  const url = new URL(value);
26188
27094
  return !url.username && !url.password;
26189
27095
  }, "public media URL must not contain embedded credentials"),
26190
- stagingAssetId: z105.string().uuid()
27096
+ stagingAssetId: z110.string().uuid()
26191
27097
  });
26192
27098
  async function uploadResolvedMedia(api, media, assetRole) {
26193
27099
  if (!media.buffer) throw new ResolveMediaError("INVALID_INPUT", "resolved media has no bytes");
@@ -26212,16 +27118,16 @@ async function resolveAndUploadMedia(api, ref, expectedKind, assetRole, transpor
26212
27118
  return uploadResolvedMedia(api, media, assetRole);
26213
27119
  }
26214
27120
  __name(resolveAndUploadMedia, "resolveAndUploadMedia");
26215
- var TikTokInput = z105.object({
26216
- taskId: z105.string().min(1),
26217
- advertiserId: z105.string().min(1),
26218
- pixelId: z105.string().min(1).optional(),
26219
- landingUrl: z105.string().url().optional(),
26220
- angleIndexes: z105.array(z105.number().int().nonnegative()).optional(),
27121
+ var TikTokInput = z110.object({
27122
+ taskId: z110.string().min(1),
27123
+ advertiserId: z110.string().min(1),
27124
+ pixelId: z110.string().min(1).optional(),
27125
+ landingUrl: z110.string().url().optional(),
27126
+ angleIndexes: z110.array(z110.number().int().nonnegative()).optional(),
26221
27127
  campaignConfig: McpCampaignConfig.optional(),
26222
27128
  /** Override the ad's description (TikTok's body copy). If omitted,
26223
27129
  * ProductMaker uses the auto-generated copy attached to the task. */
26224
- primaryText: z105.string().trim().min(1).max(500).optional()
27130
+ primaryText: z110.string().trim().min(1).max(500).optional()
26225
27131
  });
26226
27132
  function registerPublishTools(server, api, opts = {}) {
26227
27133
  const transport = opts.transport ?? "http";
@@ -26273,7 +27179,7 @@ function registerPublishTools(server, api, opts = {}) {
26273
27179
  return renderShopifyPublishMarkdown(r);
26274
27180
  } catch (e) {
26275
27181
  const error = translateError(e);
26276
- if (isRecord2(error.data) && [
27182
+ if (isRecord3(error.data) && [
26277
27183
  "SHOPIFY_PUBLISH_INPUT_REQUIRED",
26278
27184
  "SHOPIFY_PUBLISH_CONTEXT_CHANGED",
26279
27185
  "SHOPIFY_PUBLISH_CORRECTION_REQUIRES_EDITOR",
@@ -26323,7 +27229,7 @@ function registerPublishTools(server, api, opts = {}) {
26323
27229
  body.campaignOverrides = toMetaCampaignOverrides(campaignConfig);
26324
27230
  }
26325
27231
  if (phoneNumber) {
26326
- const overrides = isRecord2(body.campaignOverrides) ? body.campaignOverrides : {};
27232
+ const overrides = isRecord3(body.campaignOverrides) ? body.campaignOverrides : {};
26327
27233
  body.campaignOverrides = {
26328
27234
  ...overrides,
26329
27235
  destination: {
@@ -26544,9 +27450,9 @@ __name(renderBundleMappingMarkdown, "renderBundleMappingMarkdown");
26544
27450
  async function fetchLandingImageCount(api, taskId) {
26545
27451
  try {
26546
27452
  const r = await api.getJson(`/v1/results/${encodeURIComponent(taskId)}`);
26547
- if (!isRecord2(r)) return 0;
27453
+ if (!isRecord3(r)) return 0;
26548
27454
  const landing = r.landing;
26549
- if (!isRecord2(landing)) return 0;
27455
+ if (!isRecord3(landing)) return 0;
26550
27456
  const images = landing.images;
26551
27457
  return Array.isArray(images) ? images.length : 0;
26552
27458
  } catch {
@@ -26573,39 +27479,39 @@ __name(toTikTokCampaignConfig, "toTikTokCampaignConfig");
26573
27479
 
26574
27480
  // src/tools/meta-upload.ts
26575
27481
  import { registerAppTool } from "@modelcontextprotocol/ext-apps/server";
26576
- import { z as z106 } from "zod";
27482
+ import { z as z111 } from "zod";
26577
27483
  var requestMediaUploadGuidance = getProductMakerCapabilityModelGuidance("request_media_upload");
26578
- var UploadSessionInputBase = z106.object({
26579
- mediaKind: z106.enum([
27484
+ var UploadSessionInputBase = z111.object({
27485
+ mediaKind: z111.enum([
26580
27486
  "image",
26581
27487
  "video",
26582
27488
  "mixed"
26583
27489
  ]).default("mixed").describe("The kind of file the user will select. Use image for product references and landing pages, video for a single video, and mixed only when the consumer supports both."),
26584
- assetRole: z106.enum([
27490
+ assetRole: z111.enum([
26585
27491
  "media",
26586
27492
  "thumbnail"
26587
27493
  ]).default("media").describe("Use media for the creative itself; thumbnail only for an image thumbnail."),
26588
- uploadPurpose: z106.enum([
27494
+ uploadPurpose: z111.enum([
26589
27495
  "product_reference",
26590
27496
  "creative",
26591
27497
  "generic"
26592
27498
  ]).default("generic").describe("The user's purpose for these files. Use product_reference for a product photo used by tasks or landings, creative for media that will become an ad or creative, and generic only when neither applies."),
26593
- maxFiles: z106.number().int().min(1).max(10).optional().describe("Optional batch limit: image accepts 1-5, video exactly 1, and mixed 1-10.")
27499
+ maxFiles: z111.number().int().min(1).max(10).optional().describe("Optional batch limit: image accepts 1-5, video exactly 1, and mixed 1-10.")
26594
27500
  });
26595
- var OpenAiFileReference = z106.object({
26596
- download_url: z106.string().url().describe("Required by ChatGPT's openai/fileParams schema. The App prefers getFileDownloadUrl(file_id) for a fresh URL, and the server never fetches this value."),
26597
- file_id: z106.string().min(1),
26598
- mime_type: z106.string().min(1).optional(),
26599
- file_name: z106.string().min(1).optional()
27501
+ var OpenAiFileReference = z111.object({
27502
+ download_url: z111.string().url().describe("Required by ChatGPT's openai/fileParams schema. The App prefers getFileDownloadUrl(file_id) for a fresh URL, and the server never fetches this value."),
27503
+ file_id: z111.string().min(1),
27504
+ mime_type: z111.string().min(1).optional(),
27505
+ file_name: z111.string().min(1).optional()
26600
27506
  });
26601
27507
  var UploadSessionToolInputShape = {
26602
27508
  ...UploadSessionInputBase.shape,
26603
- files: z106.array(OpenAiFileReference).max(10).optional().describe("Optional OpenAI-hosted file references provided by ChatGPT. They are only metadata for the UI bridge and are never forwarded to ProductMaker.")
27509
+ files: z111.array(OpenAiFileReference).max(10).optional().describe("Optional OpenAI-hosted file references provided by ChatGPT. They are only metadata for the UI bridge and are never forwarded to ProductMaker.")
26604
27510
  };
26605
- var UploadSessionToolInput = z106.object(UploadSessionToolInputShape).superRefine((value, ctx) => {
27511
+ var UploadSessionToolInput = z111.object(UploadSessionToolInputShape).superRefine((value, ctx) => {
26606
27512
  if (value.assetRole === "thumbnail" && value.mediaKind !== "image") {
26607
27513
  ctx.addIssue({
26608
- code: z106.ZodIssueCode.custom,
27514
+ code: z111.ZodIssueCode.custom,
26609
27515
  path: [
26610
27516
  "mediaKind"
26611
27517
  ],
@@ -26614,7 +27520,7 @@ var UploadSessionToolInput = z106.object(UploadSessionToolInputShape).superRefin
26614
27520
  }
26615
27521
  if (value.mediaKind === "video" && value.maxFiles !== void 0 && value.maxFiles !== 1) {
26616
27522
  ctx.addIssue({
26617
- code: z106.ZodIssueCode.custom,
27523
+ code: z111.ZodIssueCode.custom,
26618
27524
  path: [
26619
27525
  "maxFiles"
26620
27526
  ],
@@ -26623,7 +27529,7 @@ var UploadSessionToolInput = z106.object(UploadSessionToolInputShape).superRefin
26623
27529
  }
26624
27530
  if (value.mediaKind === "image" && (value.maxFiles ?? 1) > 5) {
26625
27531
  ctx.addIssue({
26626
- code: z106.ZodIssueCode.custom,
27532
+ code: z111.ZodIssueCode.custom,
26627
27533
  path: [
26628
27534
  "maxFiles"
26629
27535
  ],
@@ -26631,38 +27537,38 @@ var UploadSessionToolInput = z106.object(UploadSessionToolInputShape).superRefin
26631
27537
  });
26632
27538
  }
26633
27539
  });
26634
- var UploadSessionResponse = z106.object({
26635
- sessionId: z106.string().uuid(),
26636
- uploadPageUrl: z106.string().url(),
26637
- mediaKind: z106.enum([
27540
+ var UploadSessionResponse = z111.object({
27541
+ sessionId: z111.string().uuid(),
27542
+ uploadPageUrl: z111.string().url(),
27543
+ mediaKind: z111.enum([
26638
27544
  "image",
26639
27545
  "video",
26640
27546
  "mixed"
26641
27547
  ]),
26642
- assetRole: z106.enum([
27548
+ assetRole: z111.enum([
26643
27549
  "media",
26644
27550
  "thumbnail"
26645
27551
  ]),
26646
- maxFiles: z106.number().int().positive(),
26647
- expiresAt: z106.string().datetime()
27552
+ maxFiles: z111.number().int().positive(),
27553
+ expiresAt: z111.string().datetime()
26648
27554
  });
26649
- var UploadStatusInput = z106.object({
26650
- sessionId: z106.string().uuid().describe("The sessionId returned by request_media_upload.")
27555
+ var UploadStatusInput = z111.object({
27556
+ sessionId: z111.string().uuid().describe("The sessionId returned by request_media_upload.")
26651
27557
  });
26652
- var UniversalUploadStatusResponse = z106.discriminatedUnion("status", [
26653
- z106.object({
26654
- status: z106.literal("pending"),
26655
- assets: z106.array(z106.never()).length(0)
27558
+ var UniversalUploadStatusResponse = z111.discriminatedUnion("status", [
27559
+ z111.object({
27560
+ status: z111.literal("pending"),
27561
+ assets: z111.array(z111.never()).length(0)
26656
27562
  }),
26657
- z106.object({
26658
- status: z106.literal("uploaded"),
26659
- assets: z106.array(z106.object({
26660
- assetId: z106.string().uuid(),
26661
- mediaKind: z106.enum([
27563
+ z111.object({
27564
+ status: z111.literal("uploaded"),
27565
+ assets: z111.array(z111.object({
27566
+ assetId: z111.string().uuid(),
27567
+ mediaKind: z111.enum([
26662
27568
  "image",
26663
27569
  "video"
26664
27570
  ]),
26665
- assetRole: z106.enum([
27571
+ assetRole: z111.enum([
26666
27572
  "media",
26667
27573
  "thumbnail"
26668
27574
  ])
@@ -26670,13 +27576,13 @@ var UniversalUploadStatusResponse = z106.discriminatedUnion("status", [
26670
27576
  })
26671
27577
  ]);
26672
27578
  var UniversalUploadStructuredResponse = UploadSessionResponse.extend({
26673
- uploadPurpose: z106.enum([
27579
+ uploadPurpose: z111.enum([
26674
27580
  "product_reference",
26675
27581
  "creative",
26676
27582
  "generic"
26677
27583
  ]),
26678
- checkToolName: z106.literal("check_media_upload"),
26679
- resolveEndpoint: z106.string().url()
27584
+ checkToolName: z111.literal("check_media_upload"),
27585
+ resolveEndpoint: z111.string().url()
26680
27586
  });
26681
27587
  function contextualizeUploadPageUrl(uploadPageUrl, uploadPurpose) {
26682
27588
  const url = new URL(uploadPageUrl);
@@ -26767,15 +27673,15 @@ function registerMediaUploadTools(server, api) {
26767
27673
  __name(registerMediaUploadTools, "registerMediaUploadTools");
26768
27674
 
26769
27675
  // src/tools/campaigns.ts
26770
- import { z as z107 } from "zod";
27676
+ import { z as z112 } from "zod";
26771
27677
  var getMetaCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_meta_campaign_status");
26772
27678
  var getTikTokCampaignStatusGuidance = getProductMakerCapabilityModelGuidance("get_tiktok_campaign_status");
26773
- var MetaStatusInput = z107.object({
26774
- campaignId: z107.string().min(1).describe("Meta campaign ID returned by publish_to_meta.")
27679
+ var MetaStatusInput = z112.object({
27680
+ campaignId: z112.string().min(1).describe("Meta campaign ID returned by publish_to_meta.")
26775
27681
  });
26776
- var TikTokStatusInput = z107.object({
26777
- campaignId: z107.string().min(1).describe("TikTok campaign ID returned by publish_to_tiktok."),
26778
- advertiserId: z107.string().min(1).describe("The same advertiserId used to publish the campaign.")
27682
+ var TikTokStatusInput = z112.object({
27683
+ campaignId: z112.string().min(1).describe("TikTok campaign ID returned by publish_to_tiktok."),
27684
+ advertiserId: z112.string().min(1).describe("The same advertiserId used to publish the campaign.")
26779
27685
  });
26780
27686
  function registerCampaignTools(server, api) {
26781
27687
  server.registerTool("get_meta_campaign_status", {
@@ -26880,10 +27786,10 @@ function renderTikTokStatusMarkdown(r) {
26880
27786
  __name(renderTikTokStatusMarkdown, "renderTikTokStatusMarkdown");
26881
27787
 
26882
27788
  // ../../packages/product-economics/src/product-costing.ts
26883
- import { z as z109 } from "zod";
27789
+ import { z as z114 } from "zod";
26884
27790
 
26885
27791
  // ../../packages/product-economics/src/product-costing-countries.ts
26886
- import { z as z108 } from "zod";
27792
+ import { z as z113 } from "zod";
26887
27793
 
26888
27794
  // ../../packages/product-economics/src/product-costing-shipping-references.json
26889
27795
  var product_costing_shipping_references_default = {
@@ -26947,21 +27853,21 @@ var product_costing_shipping_references_default = {
26947
27853
  };
26948
27854
 
26949
27855
  // ../../packages/product-economics/src/product-costing-countries.ts
26950
- var ShippingReferenceSchema = z108.object({
26951
- reference: z108.number().positive(),
26952
- min: z108.number().nonnegative(),
26953
- max: z108.number().positive(),
26954
- updatedAt: z108.string().date(),
26955
- confidence: z108.enum([
27856
+ var ShippingReferenceSchema = z113.object({
27857
+ reference: z113.number().positive(),
27858
+ min: z113.number().nonnegative(),
27859
+ max: z113.number().positive(),
27860
+ updatedAt: z113.string().date(),
27861
+ confidence: z113.enum([
26956
27862
  "high",
26957
27863
  "medium",
26958
27864
  "medium-low"
26959
27865
  ]),
26960
- sources: z108.array(z108.string().url().startsWith("https://")).min(1).max(3)
27866
+ sources: z113.array(z113.string().url().startsWith("https://")).min(1).max(3)
26961
27867
  }).superRefine(({ reference, min, max }, context) => {
26962
27868
  if (min > reference || reference > max) {
26963
27869
  context.addIssue({
26964
- code: z108.ZodIssueCode.custom,
27870
+ code: z113.ZodIssueCode.custom,
26965
27871
  message: "shipping_reference_outside_range",
26966
27872
  path: [
26967
27873
  "reference"
@@ -26969,7 +27875,7 @@ var ShippingReferenceSchema = z108.object({
26969
27875
  });
26970
27876
  }
26971
27877
  });
26972
- var SHIPPING_REFERENCES = z108.record(ShippingReferenceSchema).parse(product_costing_shipping_references_default);
27878
+ var SHIPPING_REFERENCES = z113.record(ShippingReferenceSchema).parse(product_costing_shipping_references_default);
26973
27879
  var PRODUCT_COSTING_COUNTRY_CODES = Object.freeze(Object.keys(SHIPPING_REFERENCES));
26974
27880
  var SPANISH_LOCALE_COUNTRIES = /* @__PURE__ */ new Set([
26975
27881
  "MX",
@@ -27151,18 +28057,18 @@ function getProductCostingCountryName(country) {
27151
28057
  __name(getProductCostingCountryName, "getProductCostingCountryName");
27152
28058
 
27153
28059
  // ../../packages/product-economics/src/product-costing.ts
27154
- var ProductCostingInputSchema = z109.object({
27155
- country: z109.string().refine(isProductCostingCountryCode, "unsupported_country"),
27156
- supplierCost: z109.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").positive("supplier_cost_positive"),
27157
- shippingCost: z109.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("shipping_cost_nonnegative"),
27158
- returnRate: z109.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
27159
- cancellationRate: z109.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
27160
- adsManagerCpa: z109.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("cpa_nonnegative"),
27161
- desiredMargin: z109.number().finite().min(0, "margin_nonnegative").lt(1, "margin_below_one")
28060
+ var ProductCostingInputSchema = z114.object({
28061
+ country: z114.string().refine(isProductCostingCountryCode, "unsupported_country"),
28062
+ supplierCost: z114.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").positive("supplier_cost_positive"),
28063
+ shippingCost: z114.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("shipping_cost_nonnegative"),
28064
+ returnRate: z114.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
28065
+ cancellationRate: z114.number().finite().min(0, "rate_nonnegative").lt(1, "rate_below_one"),
28066
+ adsManagerCpa: z114.number().finite().max(Number.MAX_SAFE_INTEGER, "amount_too_large").nonnegative("cpa_nonnegative"),
28067
+ desiredMargin: z114.number().finite().min(0, "margin_nonnegative").lt(1, "margin_below_one")
27162
28068
  }).superRefine(({ returnRate, cancellationRate }, context) => {
27163
28069
  if (returnRate + cancellationRate >= 1) {
27164
28070
  context.addIssue({
27165
- code: z109.ZodIssueCode.custom,
28071
+ code: z114.ZodIssueCode.custom,
27166
28072
  message: "delivery_rate_positive",
27167
28073
  path: [
27168
28074
  "cancellationRate"
@@ -27259,15 +28165,15 @@ function calculateProductCosting(rawInput) {
27259
28165
  __name(calculateProductCosting, "calculateProductCosting");
27260
28166
 
27261
28167
  // src/tools/product-costing.ts
27262
- import { z as z110 } from "zod";
28168
+ import { z as z115 } from "zod";
27263
28169
  var costProductGuidance = getProductMakerCapabilityModelGuidance("cost_product");
27264
- var optionalAmount = /* @__PURE__ */ __name((description) => z110.number().finite().max(Number.MAX_SAFE_INTEGER).nonnegative().optional().describe(description), "optionalAmount");
27265
- var optionalPercent = /* @__PURE__ */ __name((description) => z110.number().finite().min(0).lt(100).optional().describe(description), "optionalPercent");
27266
- var ProductCostingToolInput = z110.object({
27267
- country: z110.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
28170
+ var optionalAmount = /* @__PURE__ */ __name((description) => z115.number().finite().max(Number.MAX_SAFE_INTEGER).nonnegative().optional().describe(description), "optionalAmount");
28171
+ var optionalPercent = /* @__PURE__ */ __name((description) => z115.number().finite().min(0).lt(100).optional().describe(description), "optionalPercent");
28172
+ var ProductCostingToolInput = z115.object({
28173
+ country: z115.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
27268
28174
  message: "Pa\xEDs no soportado por ProductMaker."
27269
28175
  }).optional().describe("C\xF3digo ISO-2 de cualquiera de los pa\xEDses disponibles en ProductMaker. Omite para Colombia."),
27270
- supplierCost: z110.number().finite().max(Number.MAX_SAFE_INTEGER).positive().optional().describe("Costo real de una unidad con el proveedor, en la moneda del pa\xEDs. Requerido salvo que uses supplierCostCop para Colombia."),
28176
+ supplierCost: z115.number().finite().max(Number.MAX_SAFE_INTEGER).positive().optional().describe("Costo real de una unidad con el proveedor, en la moneda del pa\xEDs. Requerido salvo que uses supplierCostCop para Colombia."),
27271
28177
  supplierCostCop: optionalAmount("Alias anterior para costo del proveedor en Colombia. Prefiere supplierCost."),
27272
28178
  shippingCost: optionalAmount("Costo de un env\xEDo en la moneda del pa\xEDs. Omite para usar el valor gu\xEDa vigente."),
27273
28179
  shippingCostCop: optionalAmount("Alias anterior para flete en Colombia. Prefiere shippingCost."),
@@ -27430,7 +28336,7 @@ function formatPercent(value) {
27430
28336
  __name(formatPercent, "formatPercent");
27431
28337
 
27432
28338
  // src/tools/product-research.ts
27433
- import { z as z111 } from "zod";
28339
+ import { z as z116 } from "zod";
27434
28340
 
27435
28341
  // src/tools/product-research-idempotency.ts
27436
28342
  var RESEARCH_IDEMPOTENCY_WINDOW_MS = 2 * 60 * 60 * 1e3;
@@ -27801,17 +28707,17 @@ var TERMINAL2 = /* @__PURE__ */ new Set([
27801
28707
  ]);
27802
28708
  var POLL_INTERVAL_MS = 5e3;
27803
28709
  var MAX_WAIT_SECONDS = 120;
27804
- var FindInput = z111.object({
28710
+ var FindInput = z116.object({
27805
28711
  targetCountry: ResearchTargetCountryEnum.describe("Pa\xEDs objetivo. S\xF3lo CO, MX, PE, EC y CL tienen cobertura de investigaci\xF3n."),
27806
28712
  categoryKey: ResearchCategoryEnum.default("auto").describe('Categor\xEDa a investigar. Usa "auto" para que la IA elija seg\xFAn el mercado.'),
27807
- confirmed: z111.boolean().describe(`Ponlo en true SOLO despu\xE9s de que el usuario haya aceptado el cargo de ${PRICE_CREDITS} cr\xE9ditos. No lo asumas.`),
27808
- waitSeconds: z111.number().int().min(0).max(MAX_WAIT_SECONDS).optional().describe("Segundos a esperar el reporte antes de devolver el runId. M\xE1ximo 120.")
28713
+ confirmed: z116.boolean().describe(`Ponlo en true SOLO despu\xE9s de que el usuario haya aceptado el cargo de ${PRICE_CREDITS} cr\xE9ditos. No lo asumas.`),
28714
+ waitSeconds: z116.number().int().min(0).max(MAX_WAIT_SECONDS).optional().describe("Segundos a esperar el reporte antes de devolver el runId. M\xE1ximo 120.")
27809
28715
  });
27810
- var GetInput = z111.object({
27811
- runId: z111.string().uuid().describe("ID del run devuelto por find_winning_products.")
28716
+ var GetInput = z116.object({
28717
+ runId: z116.string().uuid().describe("ID del run devuelto por find_winning_products.")
27812
28718
  });
27813
- var ListInput = z111.object({
27814
- limit: z111.number().int().min(1).max(20).default(10)
28719
+ var ListInput = z116.object({
28720
+ limit: z116.number().int().min(1).max(20).default(10)
27815
28721
  });
27816
28722
  function textResult(text2) {
27817
28723
  return {
@@ -27950,17 +28856,17 @@ _Esta llamada no cobr\xF3 cr\xE9ditos: se reutiliz\xF3 una investigaci\xF3n reci
27950
28856
  __name(registerProductResearchTools, "registerProductResearchTools");
27951
28857
 
27952
28858
  // src/tools/dropshipping-projects.ts
27953
- import { z as z112 } from "zod";
28859
+ import { z as z117 } from "zod";
27954
28860
  var startDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("start_dropshipping_project");
27955
28861
  var costDropshippingProjectGuidance = getProductMakerCapabilityModelGuidance("cost_dropshipping_project");
27956
28862
  var guideDropshippingLaunchGuidance = getProductMakerCapabilityModelGuidance("guide_dropshipping_launch");
27957
- var ProjectId = z112.string().uuid();
27958
- var DropshippingProjectStatus = z112.enum([
28863
+ var ProjectId = z117.string().uuid();
28864
+ var DropshippingProjectStatus = z117.enum([
27959
28865
  "active",
27960
28866
  "completed",
27961
28867
  "archived"
27962
28868
  ]);
27963
- var DropshippingProjectPhase = z112.enum([
28869
+ var DropshippingProjectPhase = z117.enum([
27964
28870
  "research",
27965
28871
  "costing",
27966
28872
  "media",
@@ -27969,21 +28875,21 @@ var DropshippingProjectPhase = z112.enum([
27969
28875
  "advertising",
27970
28876
  "complete"
27971
28877
  ]);
27972
- var DropshippingRewardMilestone = z112.enum([
28878
+ var DropshippingRewardMilestone = z117.enum([
27973
28879
  "product_selected",
27974
28880
  "costing_saved",
27975
28881
  "product_media_ready",
27976
28882
  "creatives_completed",
27977
28883
  "campaign_created"
27978
28884
  ]);
27979
- var TargetCountry = z112.enum([
28885
+ var TargetCountry = z117.enum([
27980
28886
  "CO",
27981
28887
  "MX",
27982
28888
  "PE",
27983
28889
  "EC",
27984
28890
  "CL"
27985
28891
  ]);
27986
- var ResearchCategory = z112.enum([
28892
+ var ResearchCategory = z117.enum([
27987
28893
  "auto",
27988
28894
  "automotive",
27989
28895
  "kitchen",
@@ -27998,7 +28904,7 @@ var ResearchCategory = z112.enum([
27998
28904
  "garden",
27999
28905
  "cleaning"
28000
28906
  ]);
28001
- var HttpUrl3 = z112.string().url().max(2e3).refine((value) => {
28907
+ var HttpUrl3 = z117.string().url().max(2e3).refine((value) => {
28002
28908
  try {
28003
28909
  return [
28004
28910
  "http:",
@@ -28008,45 +28914,45 @@ var HttpUrl3 = z112.string().url().max(2e3).refine((value) => {
28008
28914
  return false;
28009
28915
  }
28010
28916
  }, "URL must use HTTP(S)");
28011
- var ResearchCandidateOrigin = z112.object({
28012
- type: z112.literal("research_candidate"),
28917
+ var ResearchCandidateOrigin = z117.object({
28918
+ type: z117.literal("research_candidate"),
28013
28919
  runId: ProjectId,
28014
- candidateSourceId: z112.string().min(1).max(160)
28920
+ candidateSourceId: z117.string().min(1).max(160)
28015
28921
  });
28016
- var TaskOrigin = z112.object({
28017
- type: z112.literal("task"),
28922
+ var TaskOrigin = z117.object({
28923
+ type: z117.literal("task"),
28018
28924
  taskId: ProjectId
28019
28925
  });
28020
- var ManualOrigin = z112.object({
28021
- type: z112.literal("manual"),
28926
+ var ManualOrigin = z117.object({
28927
+ type: z117.literal("manual"),
28022
28928
  clientRequestId: ProjectId,
28023
- country: z112.string().min(2).max(3).optional()
28929
+ country: z117.string().min(2).max(3).optional()
28024
28930
  });
28025
- var StartProjectInput = z112.object({
28026
- origin: z112.discriminatedUnion("type", [
28931
+ var StartProjectInput = z117.object({
28932
+ origin: z117.discriminatedUnion("type", [
28027
28933
  ResearchCandidateOrigin,
28028
28934
  TaskOrigin,
28029
28935
  ManualOrigin
28030
28936
  ]),
28031
- productName: z112.string().trim().min(1).max(240).optional(),
28937
+ productName: z117.string().trim().min(1).max(240).optional(),
28032
28938
  productUrl: HttpUrl3.optional(),
28033
- country: z112.string().min(2).max(3).optional(),
28034
- languageCode: z112.string().min(2).max(16).optional()
28939
+ country: z117.string().min(2).max(3).optional(),
28940
+ languageCode: z117.string().min(2).max(16).optional()
28035
28941
  }).strict();
28036
- var CostProjectInput = z112.object({
28942
+ var CostProjectInput = z117.object({
28037
28943
  projectId: ProjectId,
28038
- version: z112.number().int().positive().describe("Version le\xEDda del proyecto. Copia la \xFAltima que viste; no se la pidas al usuario."),
28039
- country: z112.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
28944
+ version: z117.number().int().positive().describe("Version le\xEDda del proyecto. Copia la \xFAltima que viste; no se la pidas al usuario."),
28945
+ country: z117.string().trim().toUpperCase().refine(isProductCostingCountryCode, {
28040
28946
  message: "Pa\xEDs no soportado por ProductMaker."
28041
28947
  }).describe("C\xF3digo ISO-2 del pa\xEDs del proyecto. Usa el `targetCountry` que devuelve el proyecto."),
28042
- supplierCost: z112.number().finite().positive().describe("Costo real de una unidad con el proveedor, en la moneda del pa\xEDs. \xDANICO dato que debes pedirle al usuario: nunca lo inventes."),
28043
- shippingCost: z112.number().finite().nonnegative().optional().describe("Costo de un env\xEDo. Omite para usar el valor gu\xEDa del pa\xEDs en vez de inventarlo."),
28044
- returnRate: z112.number().finite().min(0).lt(1).optional().describe("Fracci\xF3n de pedidos devueltos (0.25 = 25%). Omite para usar el valor gu\xEDa del pa\xEDs."),
28045
- cancellationRate: z112.number().finite().min(0).lt(1).optional().describe("Fracci\xF3n de pedidos cancelados (0.15 = 15%). Omite para usar el valor gu\xEDa del pa\xEDs."),
28046
- adsManagerCpa: z112.number().finite().nonnegative().optional().describe("Costo por compra de Ads Manager. Omite para usar el valor gu\xEDa del pa\xEDs."),
28047
- desiredMargin: z112.number().finite().min(0).lt(1).optional().describe("Margen deseado (0.1 = 10%). Omite para usar el valor gu\xEDa del pa\xEDs.")
28048
- });
28049
- var GuideInput = z112.object({
28948
+ supplierCost: z117.number().finite().positive().describe("Costo real de una unidad con el proveedor, en la moneda del pa\xEDs. \xDANICO dato que debes pedirle al usuario: nunca lo inventes."),
28949
+ shippingCost: z117.number().finite().nonnegative().optional().describe("Costo de un env\xEDo. Omite para usar el valor gu\xEDa del pa\xEDs en vez de inventarlo."),
28950
+ returnRate: z117.number().finite().min(0).lt(1).optional().describe("Fracci\xF3n de pedidos devueltos (0.25 = 25%). Omite para usar el valor gu\xEDa del pa\xEDs."),
28951
+ cancellationRate: z117.number().finite().min(0).lt(1).optional().describe("Fracci\xF3n de pedidos cancelados (0.15 = 15%). Omite para usar el valor gu\xEDa del pa\xEDs."),
28952
+ adsManagerCpa: z117.number().finite().nonnegative().optional().describe("Costo por compra de Ads Manager. Omite para usar el valor gu\xEDa del pa\xEDs."),
28953
+ desiredMargin: z117.number().finite().min(0).lt(1).optional().describe("Margen deseado (0.1 = 10%). Omite para usar el valor gu\xEDa del pa\xEDs.")
28954
+ });
28955
+ var GuideInput = z117.object({
28050
28956
  projectId: ProjectId.optional()
28051
28957
  }).strict();
28052
28958
  var NEXT_ACTION_KINDS = [
@@ -28064,29 +28970,29 @@ var NEXT_ACTION_KINDS = [
28064
28970
  "repair_meta_campaign",
28065
28971
  "review_paused_campaign"
28066
28972
  ];
28067
- var DropshippingProjectNextAction = z112.discriminatedUnion("kind", NEXT_ACTION_KINDS.map((kind) => z112.object({
28068
- kind: z112.literal(kind),
28069
- href: z112.string().min(1)
28973
+ var DropshippingProjectNextAction = z117.discriminatedUnion("kind", NEXT_ACTION_KINDS.map((kind) => z117.object({
28974
+ kind: z117.literal(kind),
28975
+ href: z117.string().min(1)
28070
28976
  })));
28071
- var CostingInputSchema = z112.object({
28072
- country: z112.string().min(2).max(3),
28073
- supplierCost: z112.number().finite().positive(),
28074
- shippingCost: z112.number().finite().nonnegative(),
28075
- returnRate: z112.number().finite().min(0).lt(1),
28076
- cancellationRate: z112.number().finite().min(0).lt(1),
28077
- adsManagerCpa: z112.number().finite().nonnegative(),
28078
- desiredMargin: z112.number().finite().min(0).lt(1)
28977
+ var CostingInputSchema = z117.object({
28978
+ country: z117.string().min(2).max(3),
28979
+ supplierCost: z117.number().finite().positive(),
28980
+ shippingCost: z117.number().finite().nonnegative(),
28981
+ returnRate: z117.number().finite().min(0).lt(1),
28982
+ cancellationRate: z117.number().finite().min(0).lt(1),
28983
+ adsManagerCpa: z117.number().finite().nonnegative(),
28984
+ desiredMargin: z117.number().finite().min(0).lt(1)
28079
28985
  }).superRefine(({ returnRate, cancellationRate }, context) => {
28080
28986
  if (returnRate + cancellationRate >= 1) context.addIssue({
28081
- code: z112.ZodIssueCode.custom,
28987
+ code: z117.ZodIssueCode.custom,
28082
28988
  path: [
28083
28989
  "cancellationRate"
28084
28990
  ]
28085
28991
  });
28086
28992
  });
28087
- var FiniteCostingNumber = z112.number().finite();
28088
- var CostingResultSchema = z112.object({
28089
- country: z112.string().min(2).max(3),
28993
+ var FiniteCostingNumber = z117.number().finite();
28994
+ var CostingResultSchema = z117.object({
28995
+ country: z117.string().min(2).max(3),
28090
28996
  deliveryRate: FiniteCostingNumber,
28091
28997
  adjustedShippingCost: FiniteCostingNumber,
28092
28998
  adjustedCpa: FiniteCostingNumber,
@@ -28099,45 +29005,45 @@ var CostingResultSchema = z112.object({
28099
29005
  estimatedProfit: FiniteCostingNumber,
28100
29006
  actualMargin: FiniteCostingNumber,
28101
29007
  breakEvenAdsManagerCpa: FiniteCostingNumber,
28102
- wasPriceAutoAdjusted: z112.boolean(),
28103
- profitabilityStatus: z112.literal("healthy")
28104
- });
28105
- var RewardProgressSchema = z112.object({
28106
- campaignKey: z112.literal("dropshipping-launch-v1"),
28107
- totalCredits: z112.number().int().positive(),
28108
- earnedCredits: z112.number().int().nonnegative(),
28109
- milestones: z112.array(z112.object({
29008
+ wasPriceAutoAdjusted: z117.boolean(),
29009
+ profitabilityStatus: z117.literal("healthy")
29010
+ });
29011
+ var RewardProgressSchema = z117.object({
29012
+ campaignKey: z117.literal("dropshipping-launch-v1"),
29013
+ totalCredits: z117.number().int().positive(),
29014
+ earnedCredits: z117.number().int().nonnegative(),
29015
+ milestones: z117.array(z117.object({
28110
29016
  milestone: DropshippingRewardMilestone,
28111
- credits: z112.number().int().positive(),
28112
- available: z112.boolean().optional(),
28113
- earned: z112.boolean(),
29017
+ credits: z117.number().int().positive(),
29018
+ available: z117.boolean().optional(),
29019
+ earned: z117.boolean(),
28114
29020
  grantId: ProjectId.nullable(),
28115
- grantedAt: z112.string().datetime().nullable()
29021
+ grantedAt: z117.string().datetime().nullable()
28116
29022
  })).length(DropshippingRewardMilestone.options.length)
28117
29023
  });
28118
- var ProjectResponseSchema = z112.object({
29024
+ var ProjectResponseSchema = z117.object({
28119
29025
  id: ProjectId,
28120
29026
  taskId: ProjectId.nullable(),
28121
29027
  status: DropshippingProjectStatus,
28122
- originKey: z112.string().min(1),
29028
+ originKey: z117.string().min(1),
28123
29029
  researchRunId: ProjectId.nullable(),
28124
- candidateSourceId: z112.string().nullable(),
28125
- productName: z112.string().nullable(),
29030
+ candidateSourceId: z117.string().nullable(),
29031
+ productName: z117.string().nullable(),
28126
29032
  productUrl: HttpUrl3.nullable(),
28127
29033
  referenceImageUrl: HttpUrl3.nullable(),
28128
- targetCountry: z112.string().nullable(),
28129
- languageCode: z112.string().nullable(),
28130
- hasReferenceImage: z112.boolean(),
28131
- hasWinnerReferenceImage: z112.boolean(),
29034
+ targetCountry: z117.string().nullable(),
29035
+ languageCode: z117.string().nullable(),
29036
+ hasReferenceImage: z117.boolean(),
29037
+ hasWinnerReferenceImage: z117.boolean(),
28132
29038
  costingInput: CostingInputSchema.nullable(),
28133
29039
  costingResult: CostingResultSchema.nullable(),
28134
- costingVersion: z112.number().int().positive().nullable(),
28135
- version: z112.number().int().positive(),
29040
+ costingVersion: z117.number().int().positive().nullable(),
29041
+ version: z117.number().int().positive(),
28136
29042
  phase: DropshippingProjectPhase,
28137
29043
  nextAction: DropshippingProjectNextAction.nullable(),
28138
29044
  rewards: RewardProgressSchema,
28139
- createdAt: z112.string().datetime(),
28140
- updatedAt: z112.string().datetime()
29045
+ createdAt: z117.string().datetime(),
29046
+ updatedAt: z117.string().datetime()
28141
29047
  }).passthrough();
28142
29048
  var NEXT_ACTION_GUIDANCE = {
28143
29049
  cost_product: "Llama `cost_dropshipping_project` con el costo real del proveedor. Nunca lo inventes: p\xEDdeselo al usuario. Es el \xDANICO dato que debes pedirle: omite env\xEDo, devoluciones, cancelaciones, CPA y margen para que ProductMaker use los valores gu\xEDa del pa\xEDs, y luego dile al usuario cu\xE1les us\xF3 por si quiere corregirlos.",
@@ -28257,58 +29163,58 @@ function registerDropshippingProjectTools(server, api) {
28257
29163
  __name(registerDropshippingProjectTools, "registerDropshippingProjectTools");
28258
29164
 
28259
29165
  // src/tools/daily-control.ts
28260
- import { z as z113 } from "zod";
29166
+ import { z as z118 } from "zod";
28261
29167
  var getDailyControlGuidance = getProductMakerCapabilityModelGuidance("get_daily_control");
28262
29168
  var linkCampaignToProjectGuidance = getProductMakerCapabilityModelGuidance("link_campaign_to_project");
28263
29169
  var reportDailyReturnsGuidance = getProductMakerCapabilityModelGuidance("report_daily_returns");
28264
- var ProviderCampaignIdentifier = z113.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/);
28265
- var DateOnly = z113.string().regex(/^\d{4}-\d{2}-\d{2}$/);
28266
- var DailyControlInput = z113.object({
29170
+ var ProviderCampaignIdentifier = z118.string().min(1).max(64).regex(/^[A-Za-z0-9_-]+$/);
29171
+ var DateOnly = z118.string().regex(/^\d{4}-\d{2}-\d{2}$/);
29172
+ var DailyControlInput = z118.object({
28267
29173
  date: DateOnly.optional().describe("D\xEDa final de la ventana (YYYY-MM-DD). Si se omite, la ventana termina AYER en UTC \u2014 nunca hoy, porque el d\xEDa en curso est\xE1 incompleto \u2014 y el servidor puede correrla un d\xEDa m\xE1s atr\xE1s si en la zona horaria de la tienda ese d\xEDa todav\xEDa no ha cerrado."),
28268
- days: z113.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
28269
- projectId: z113.string().uuid().optional().describe("Opcional: limita el reporte a un solo proyecto en vez de todos los productos activos.")
29174
+ days: z118.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
29175
+ projectId: z118.string().uuid().optional().describe("Opcional: limita el reporte a un solo proyecto en vez de todos los productos activos.")
28270
29176
  }).strict();
28271
- var LinkCampaignInput = z113.object({
28272
- projectId: z113.string().uuid(),
28273
- provider: z113.enum([
29177
+ var LinkCampaignInput = z118.object({
29178
+ projectId: z118.string().uuid(),
29179
+ provider: z118.enum([
28274
29180
  "meta",
28275
29181
  "tiktok"
28276
29182
  ]),
28277
29183
  accountId: ProviderCampaignIdentifier.describe("Cuenta publicitaria del proveedor. Para Meta el servidor la IGNORA y deriva la cuenta real de la campa\xF1a \u2014 se sigue pidiendo aqu\xED solo porque TikTok s\xED la necesita para resolver la campa\xF1a."),
28278
29184
  campaignId: ProviderCampaignIdentifier
28279
29185
  }).strict();
28280
- var ReportReturnsInput = z113.object({
28281
- projectId: z113.string().uuid(),
29186
+ var ReportReturnsInput = z118.object({
29187
+ projectId: z118.string().uuid(),
28282
29188
  date: DateOnly,
28283
- returnedOrders: z113.number().int().min(0).max(1e5),
28284
- note: z113.string().trim().max(280).optional()
29189
+ returnedOrders: z118.number().int().min(0).max(1e5),
29190
+ note: z118.string().trim().max(280).optional()
28285
29191
  }).strict();
28286
- var DailyControlStatusMirror = DailyControlStatusEnum.or(z113.string());
28287
- var DailyControlLightMirror = DailyControlLightEnum.or(z113.string());
28288
- var DailyControlSourceMirror = DailyControlSourceEnum.or(z113.string());
28289
- var DailyControlVerdictMirror = DailyControlVerdictEnum.or(z113.string());
28290
- var DailyControlDayMirror = z113.object({
28291
- date: z113.string(),
28292
- returnedOrders: z113.number(),
29192
+ var DailyControlStatusMirror = DailyControlStatusEnum.or(z118.string());
29193
+ var DailyControlLightMirror = DailyControlLightEnum.or(z118.string());
29194
+ var DailyControlSourceMirror = DailyControlSourceEnum.or(z118.string());
29195
+ var DailyControlVerdictMirror = DailyControlVerdictEnum.or(z118.string());
29196
+ var DailyControlDayMirror = z118.object({
29197
+ date: z118.string(),
29198
+ returnedOrders: z118.number(),
28293
29199
  returnedSource: DailyControlSourceMirror,
28294
29200
  cancelledSource: DailyControlSourceMirror,
28295
- hasEstimates: z113.boolean(),
29201
+ hasEstimates: z118.boolean(),
28296
29202
  light: DailyControlLightMirror
28297
29203
  }).passthrough();
28298
- var DailyControlProductMirror = z113.object({
28299
- projectId: z113.string().uuid(),
28300
- productName: z113.string().nullable(),
29204
+ var DailyControlProductMirror = z118.object({
29205
+ projectId: z118.string().uuid(),
29206
+ productName: z118.string().nullable(),
28301
29207
  status: DailyControlStatusMirror,
28302
- statusMessage: z113.string().nullable(),
28303
- days: z113.array(DailyControlDayMirror),
29208
+ statusMessage: z118.string().nullable(),
29209
+ days: z118.array(DailyControlDayMirror),
28304
29210
  verdict: DailyControlVerdictMirror.nullable(),
28305
- rationale: z113.string().nullable()
29211
+ rationale: z118.string().nullable()
28306
29212
  }).passthrough();
28307
- var DailyControlResponseMirror = z113.object({
28308
- since: z113.string(),
28309
- until: z113.string(),
28310
- products: z113.array(DailyControlProductMirror),
28311
- archivedProjectSpend: z113.array(z113.unknown())
29213
+ var DailyControlResponseMirror = z118.object({
29214
+ since: z118.string(),
29215
+ until: z118.string(),
29216
+ products: z118.array(DailyControlProductMirror),
29217
+ archivedProjectSpend: z118.array(z118.unknown())
28312
29218
  }).passthrough();
28313
29219
  var MCP_WARNINGS_KEY = "_mcpDailyControlWarnings";
28314
29220
  function withWarnings(response) {
@@ -28383,7 +29289,7 @@ __name(registerDailyControlTools, "registerDailyControlTools");
28383
29289
  // src/tools/product-control.ts
28384
29290
  import { readFile, stat } from "fs/promises";
28385
29291
  import { basename as basename2, isAbsolute, resolve as resolve3 } from "path";
28386
- import { z as z114 } from "zod";
29292
+ import { z as z119 } from "zod";
28387
29293
  var getProductControlGuidance = getProductMakerCapabilityModelGuidance("get_product_control");
28388
29294
  var listImportableProductsGuidance = getProductMakerCapabilityModelGuidance("list_importable_products");
28389
29295
  var importProductControlsGuidance = getProductMakerCapabilityModelGuidance("import_product_controls");
@@ -28396,36 +29302,36 @@ var createOperationGuidance = getProductMakerCapabilityModelGuidance("create_ope
28396
29302
  var mergeProductsGuidance = getProductMakerCapabilityModelGuidance("merge_products");
28397
29303
  var syncShopifyOrdersGuidance = getProductMakerCapabilityModelGuidance("sync_shopify_orders");
28398
29304
  var importOrdersFileGuidance = getProductMakerCapabilityModelGuidance("import_orders_file");
28399
- var DateOnly2 = z114.string().regex(/^\d{4}-\d{2}-\d{2}$/);
29305
+ var DateOnly2 = z119.string().regex(/^\d{4}-\d{2}-\d{2}$/);
28400
29306
  var IMPORT_BATCH_MAX2 = 50;
28401
- var ProductControlListInput = z114.object({
28402
- days: z114.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
29307
+ var ProductControlListInput = z119.object({
29308
+ days: z119.number().int().min(1).max(14).default(3).describe("Tama\xF1o de la ventana, 1 a 14 d\xEDas."),
28403
29309
  date: DateOnly2.optional().describe("D\xEDa final de la ventana (YYYY-MM-DD). Si se omite, termina en el \xFAltimo d\xEDa cerrado \u2014 nunca hoy, que est\xE1 incompleto."),
28404
- shopDomain: z114.string().min(1).optional().describe("Tienda, si tiene m\xE1s de una conectada.")
29310
+ shopDomain: z119.string().min(1).optional().describe("Tienda, si tiene m\xE1s de una conectada.")
28405
29311
  }).strict();
28406
- var ImportableProductsInput = z114.object({
28407
- q: z114.string().trim().max(120).optional().describe("B\xFAsqueda por t\xEDtulo. Sin esto un cat\xE1logo grande es inrecorrible."),
28408
- after: z114.string().max(512).optional().describe("Cursor de la p\xE1gina anterior, tal como vino en la respuesta."),
28409
- shopDomain: z114.string().min(1).optional()
29312
+ var ImportableProductsInput = z119.object({
29313
+ q: z119.string().trim().max(120).optional().describe("B\xFAsqueda por t\xEDtulo. Sin esto un cat\xE1logo grande es inrecorrible."),
29314
+ after: z119.string().max(512).optional().describe("Cursor de la p\xE1gina anterior, tal como vino en la respuesta."),
29315
+ shopDomain: z119.string().min(1).optional()
28410
29316
  }).strict();
28411
- var ImportProductControlsInput = z114.object({
28412
- shopifyProductIds: z114.array(z114.string().min(1).max(64)).min(1).max(IMPORT_BATCH_MAX2).describe("Identificadores tal como vinieron de list_importable_products. NO los inventes ni los deduzcas del t\xEDtulo."),
29317
+ var ImportProductControlsInput = z119.object({
29318
+ shopifyProductIds: z119.array(z119.string().min(1).max(64)).min(1).max(IMPORT_BATCH_MAX2).describe("Identificadores tal como vinieron de list_importable_products. NO los inventes ni los deduzcas del t\xEDtulo."),
28413
29319
  // Obligatorio, como en el endpoint: con dos tiendas conectadas, importar
28414
29320
  // sin decir a cuál archivaría el producto bajo la tienda equivocada.
28415
- shopDomain: z114.string().min(1)
29321
+ shopDomain: z119.string().min(1)
28416
29322
  }).strict();
28417
- var SetProductCostingInput = z114.object({
28418
- shopDomain: z114.string().min(1),
28419
- shopifyProductId: z114.string().min(1).max(64),
28420
- targetCountry: z114.string().length(2).describe("Pa\xEDs de venta en ISO-2, que fija moneda y referencia de flete."),
28421
- supplierCost: z114.number().finite().positive().describe("Lo que le cuesta el producto al proveedor. Nunca cero."),
28422
- shippingCost: z114.number().finite().nonnegative(),
28423
- returnRate: z114.number().finite().min(0).lt(1).describe("Proporci\xF3n 0\u20131, no porcentaje: 0.15 es quince por ciento."),
28424
- cancellationRate: z114.number().finite().min(0).lt(1)
29323
+ var SetProductCostingInput = z119.object({
29324
+ shopDomain: z119.string().min(1),
29325
+ shopifyProductId: z119.string().min(1).max(64),
29326
+ targetCountry: z119.string().length(2).describe("Pa\xEDs de venta en ISO-2, que fija moneda y referencia de flete."),
29327
+ supplierCost: z119.number().finite().positive().describe("Lo que le cuesta el producto al proveedor. Nunca cero."),
29328
+ shippingCost: z119.number().finite().nonnegative(),
29329
+ returnRate: z119.number().finite().min(0).lt(1).describe("Proporci\xF3n 0\u20131, no porcentaje: 0.15 es quince por ciento."),
29330
+ cancellationRate: z119.number().finite().min(0).lt(1)
28425
29331
  }).strict();
28426
- var Count = z114.number().int().min(0).max(1e5).nullable().optional();
28427
- var ReportProductCountsInput = z114.object({
28428
- productControlId: z114.string().uuid().describe("El identificador que devuelve get_product_control."),
29332
+ var Count = z119.number().int().min(0).max(1e5).nullable().optional();
29333
+ var ReportProductCountsInput = z119.object({
29334
+ productControlId: z119.string().uuid().describe("El identificador que devuelve get_product_control."),
28429
29335
  date: DateOnly2,
28430
29336
  orders: Count.describe("Pedidos que entraron ese d\xEDa."),
28431
29337
  cancelledOrders: Count,
@@ -28435,36 +29341,36 @@ var ReportProductCountsInput = z114.object({
28435
29341
  }).strict();
28436
29342
  var MAX_ORDERS_FILE_BYTES = 8 * 1024 * 1024;
28437
29343
  var SyncShopifyOrdersInput = SyncShopifyOrdersSchema;
28438
- var ImportOrdersFileInput = z114.object({
29344
+ var ImportOrdersFileInput = z119.object({
28439
29345
  /** Ruta ABSOLUTA en la máquina de quien usa el MCP. */
28440
- path: z114.string().min(1),
28441
- operationId: z114.string().uuid().optional(),
29346
+ path: z119.string().min(1),
29347
+ operationId: z119.string().uuid().optional(),
28442
29348
  /** Solo mirar: devuelve el resumen y no escribe nada. */
28443
- dryRun: z114.boolean().optional()
29349
+ dryRun: z119.boolean().optional()
28444
29350
  }).strict();
28445
- var CreateOperationInput = z114.object({
28446
- countryCode: z114.string().length(2),
28447
- label: z114.string().trim().min(1).max(60).optional()
29351
+ var CreateOperationInput = z119.object({
29352
+ countryCode: z119.string().length(2),
29353
+ label: z119.string().trim().min(1).max(60).optional()
28448
29354
  }).strict();
28449
- var MergeProductsInput = z114.object({
28450
- sourceId: z114.string().uuid(),
28451
- targetId: z114.string().uuid()
29355
+ var MergeProductsInput = z119.object({
29356
+ sourceId: z119.string().uuid(),
29357
+ targetId: z119.string().uuid()
28452
29358
  }).strict();
28453
- var SetMonthlyExpenseInput = z114.object({
28454
- month: z114.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
29359
+ var SetMonthlyExpenseInput = z119.object({
29360
+ month: z119.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
28455
29361
  label: SaveMonthlyExpenseSchema.shape.label,
28456
- amount: z114.number().finite().min(0),
28457
- operationId: z114.string().uuid().optional()
29362
+ amount: z119.number().finite().min(0),
29363
+ operationId: z119.string().uuid().optional()
28458
29364
  }).strict();
28459
- var SetAdSpendInput = z114.object({
28460
- month: z114.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
28461
- operationId: z114.string().uuid().optional(),
29365
+ var SetAdSpendInput = z119.object({
29366
+ month: z119.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional(),
29367
+ operationId: z119.string().uuid().optional(),
28462
29368
  /** null RETIRA la corrección; cero afirma que no pautó. */
28463
- amount: z114.number().finite().min(0).nullable()
29369
+ amount: z119.number().finite().min(0).nullable()
28464
29370
  }).strict();
28465
- var GetFinancesInput = z114.object({
28466
- month: z114.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional().describe("Mes en YYYY-MM. Si se omite, el mes en curso. Solo mes calendario."),
28467
- operationId: z114.string().uuid().optional().describe("El negocio, si tiene mas de uno. Con uno solo no hace falta decirlo.")
29371
+ var GetFinancesInput = z119.object({
29372
+ month: z119.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional().describe("Mes en YYYY-MM. Si se omite, el mes en curso. Solo mes calendario."),
29373
+ operationId: z119.string().uuid().optional().describe("El negocio, si tiene mas de uno. Con uno solo no hace falta decirlo.")
28468
29374
  }).strict();
28469
29375
  function registerProductControlTools(server, api, { transport = "http" } = {}) {
28470
29376
  server.registerTool("get_product_control", {
@@ -28654,28 +29560,28 @@ function registerProductControlTools(server, api, { transport = "http" } = {}) {
28654
29560
  __name(registerProductControlTools, "registerProductControlTools");
28655
29561
 
28656
29562
  // src/tools/market-study-estimate.ts
28657
- import { z as z115 } from "zod";
29563
+ import { z as z120 } from "zod";
28658
29564
  var estimateMarketStudyGuidance = getProductMakerCapabilityModelGuidance("estimate_market_study_cost");
28659
- var ProductTaskOutputEnum = z115.enum([
29565
+ var ProductTaskOutputEnum = z120.enum([
28660
29566
  "landing",
28661
29567
  "video",
28662
29568
  "image"
28663
29569
  ]);
28664
- var EstimateMarketStudyInput = z115.object({
28665
- kind: z115.enum([
29570
+ var EstimateMarketStudyInput = z120.object({
29571
+ kind: z120.enum([
28666
29572
  "video",
28667
29573
  "product_task"
28668
29574
  ]).describe('"video" para generate_video_creative; "product_task" para create_product_task.'),
28669
- videoAngleCount: z115.number().int().min(1).max(3).describe("Los mismos 1, 2 o 3 videos que vas a pedir al crear."),
28670
- durationSeconds: z115.number().int().min(4).max(30).default(15).describe("La misma duraci\xF3n que enviar\xE1s al crear."),
29575
+ videoAngleCount: z120.number().int().min(1).max(3).describe("Los mismos 1, 2 o 3 videos que vas a pedir al crear."),
29576
+ durationSeconds: z120.number().int().min(4).max(30).default(15).describe("La misma duraci\xF3n que enviar\xE1s al crear."),
28671
29577
  videoStructure: VideoStructureEnum.default("single_take"),
28672
29578
  videoQuality: VideoQualityEnum.default("economy"),
28673
29579
  videoResolution: VideoResolutionEnum.default("480p"),
28674
- productImageCount: z115.number().int().min(1).max(5).optional().describe("Cantidad de fotos del producto que adjuntar\xE1s (1-5)."),
29580
+ productImageCount: z120.number().int().min(1).max(5).optional().describe("Cantidad de fotos del producto que adjuntar\xE1s (1-5)."),
28675
29581
  outputs: ProductTaskOutputEnum.array().min(1).max(3).optional().describe('Solo para kind="product_task": los mismos outputs de create_product_task. Default: todos.'),
28676
- generateAiMusic: z115.boolean().optional(),
29582
+ generateAiMusic: z120.boolean().optional(),
28677
29583
  generateAiEdit: AiEditRequestSchema.optional(),
28678
- replicateWinnerWhenFound: z115.boolean().optional().describe("La misma preferencia que enviar\xE1s al crear. false excluye la reserva de r\xE9plica del ganador de la cotizaci\xF3n con estudio.")
29584
+ replicateWinnerWhenFound: z120.boolean().optional().describe("La misma preferencia que enviar\xE1s al crear. false excluye la reserva de r\xE9plica del ganador de la cotizaci\xF3n con estudio.")
28679
29585
  }).strict();
28680
29586
  function buildMarketStudyEstimateRequests(input) {
28681
29587
  const quotesVideo = input.kind === "video" || (input.outputs ?? [