@productmaker/mcp 6.8.2 → 6.9.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.
- package/dist/http.js +131 -5
- package/dist/stdio.js +131 -5
- package/package.json +1 -1
package/dist/http.js
CHANGED
|
@@ -2677,6 +2677,7 @@ function getCurrencyForCountry(country) {
|
|
|
2677
2677
|
}
|
|
2678
2678
|
__name(getCurrencyForCountry, "getCurrencyForCountry");
|
|
2679
2679
|
var MAX_PLAUSIBLE_AMOUNT = 1e10;
|
|
2680
|
+
var KNOWN_CURRENCY_CODES = new Set(Object.values(CURRENCY_BY_COUNTRY).map((c) => c.code));
|
|
2680
2681
|
|
|
2681
2682
|
// ../../packages/types/src/shopify-publish-recovery.ts
|
|
2682
2683
|
var MAX_MONEY_LENGTH = 40;
|
|
@@ -5083,6 +5084,52 @@ var ShopifyPublishErrorResponse = z27.discriminatedUnion("code", [
|
|
|
5083
5084
|
code: z27.literal("SHOPIFY_PUBLISH_CORRECTION_REQUIRES_EDITOR"),
|
|
5084
5085
|
action: z27.literal("open_editor"),
|
|
5085
5086
|
message: z27.string().optional()
|
|
5087
|
+
}),
|
|
5088
|
+
z27.object({
|
|
5089
|
+
/**
|
|
5090
|
+
* The chosen existing product cannot express the confirmed offer's
|
|
5091
|
+
* quantity/price options. `message` carries the merchant-facing reason;
|
|
5092
|
+
* the client offers a one-click "create a new product and retry" path.
|
|
5093
|
+
*/
|
|
5094
|
+
code: z27.literal("SHOPIFY_PUBLISH_TARGET_INCOMPATIBLE"),
|
|
5095
|
+
message: z27.string().optional(),
|
|
5096
|
+
commerceCorrectionSaved: z27.literal(true).optional()
|
|
5097
|
+
}),
|
|
5098
|
+
z27.object({
|
|
5099
|
+
/**
|
|
5100
|
+
* Code-landing publish refused BEFORE any product mutation: the shared
|
|
5101
|
+
* cl-landing template exists but the merchant has not saved the
|
|
5102
|
+
* code-landing-renderer app block, so the product page would render blank.
|
|
5103
|
+
* `themeEditorDeepLink` is the one-click fix — mandatory because without it
|
|
5104
|
+
* the client has nothing actionable to show.
|
|
5105
|
+
*/
|
|
5106
|
+
code: z27.literal("SHOPIFY_THEME_SETUP_REQUIRED"),
|
|
5107
|
+
message: z27.string().optional(),
|
|
5108
|
+
shopDomain: z27.string().optional(),
|
|
5109
|
+
themeEditorDeepLink: z27.string().url(),
|
|
5110
|
+
/**
|
|
5111
|
+
* Present when the request also carried a commerceCorrection that was
|
|
5112
|
+
* committed before the gate refused — the client must drop the stale
|
|
5113
|
+
* correction before retrying or it dies on CONTEXT_CHANGED.
|
|
5114
|
+
*/
|
|
5115
|
+
commerceCorrectionSaved: z27.literal(true).optional()
|
|
5116
|
+
})
|
|
5117
|
+
]);
|
|
5118
|
+
var CodeLandingThemeSetupResponse = z27.discriminatedUnion("status", [
|
|
5119
|
+
z27.object({
|
|
5120
|
+
/** The app block is saved (ready) or still missing (setup_required). */
|
|
5121
|
+
status: z27.enum([
|
|
5122
|
+
"ready",
|
|
5123
|
+
"setup_required"
|
|
5124
|
+
]),
|
|
5125
|
+
/** One-click theme-editor link that pre-adds the Code Landing block. */
|
|
5126
|
+
themeEditorDeepLink: z27.string().url(),
|
|
5127
|
+
shopDomain: z27.string()
|
|
5128
|
+
}),
|
|
5129
|
+
z27.object({
|
|
5130
|
+
/** Not a code-landing task — the gate does not apply. */
|
|
5131
|
+
status: z27.literal("not_applicable"),
|
|
5132
|
+
shopDomain: z27.string().optional()
|
|
5086
5133
|
})
|
|
5087
5134
|
]);
|
|
5088
5135
|
var ShopifyAuthUrlResponse = z27.object({
|
|
@@ -6292,7 +6339,7 @@ var SharedOutputEstimationFields = {
|
|
|
6292
6339
|
* The lightweight competitor scan must never imply this add-on. */
|
|
6293
6340
|
competitorCommercialStudyRequested: z33.boolean().optional(),
|
|
6294
6341
|
/** Declining the winner replica makes `gap_replication` unreachable, so its
|
|
6295
|
-
*
|
|
6342
|
+
* tier-matched replication ceiling must not be quoted. See
|
|
6296
6343
|
* `.agent/specs/winner-replication-consent.spec.test.ts`. */
|
|
6297
6344
|
replicateWinnerWhenFound: z33.boolean().optional()
|
|
6298
6345
|
};
|
|
@@ -13047,6 +13094,8 @@ var PRODUCTMAKER_CAPABILITY_REGISTRY = deepFreeze([
|
|
|
13047
13094
|
], [
|
|
13048
13095
|
"product_reference"
|
|
13049
13096
|
], [
|
|
13097
|
+
"task",
|
|
13098
|
+
"product",
|
|
13050
13099
|
"landing"
|
|
13051
13100
|
], SHARED_CHANNEL_EXPOSURE, [
|
|
13052
13101
|
{
|
|
@@ -13144,6 +13193,8 @@ var PRODUCTMAKER_CAPABILITY_REGISTRY = deepFreeze([
|
|
|
13144
13193
|
], [
|
|
13145
13194
|
"product_reference"
|
|
13146
13195
|
], [
|
|
13196
|
+
"task",
|
|
13197
|
+
"creative",
|
|
13147
13198
|
"video"
|
|
13148
13199
|
], SHARED_CHANNEL_EXPOSURE, [
|
|
13149
13200
|
{
|
|
@@ -14198,6 +14249,60 @@ import { z as z65 } from "zod";
|
|
|
14198
14249
|
|
|
14199
14250
|
// ../../packages/types/src/whatsapp-presentation-finalizer.ts
|
|
14200
14251
|
import { z as z64 } from "zod";
|
|
14252
|
+
var WhatsAppQuoteRecoveryChoiceSchema = z64.enum([
|
|
14253
|
+
"without_winner",
|
|
14254
|
+
"retry",
|
|
14255
|
+
"cancel"
|
|
14256
|
+
]);
|
|
14257
|
+
var recoveryBase = {
|
|
14258
|
+
version: z64.literal(1),
|
|
14259
|
+
requestHash: z64.string().min(1).max(256),
|
|
14260
|
+
issuedAt: z64.string().datetime(),
|
|
14261
|
+
expiresAt: z64.string().datetime(),
|
|
14262
|
+
offeredAlternative: z64.literal("without_winner").nullable()
|
|
14263
|
+
};
|
|
14264
|
+
var WhatsAppQuoteRecoveryReceiptSchema = z64.discriminatedUnion("state", [
|
|
14265
|
+
z64.object({
|
|
14266
|
+
...recoveryBase,
|
|
14267
|
+
state: z64.literal("open"),
|
|
14268
|
+
successorCommandId: z64.null(),
|
|
14269
|
+
choice: z64.null()
|
|
14270
|
+
}).strict(),
|
|
14271
|
+
z64.object({
|
|
14272
|
+
...recoveryBase,
|
|
14273
|
+
state: z64.literal("consumed"),
|
|
14274
|
+
successorCommandId: z64.string().uuid(),
|
|
14275
|
+
choice: z64.enum([
|
|
14276
|
+
"without_winner",
|
|
14277
|
+
"retry"
|
|
14278
|
+
])
|
|
14279
|
+
}).strict(),
|
|
14280
|
+
z64.object({
|
|
14281
|
+
...recoveryBase,
|
|
14282
|
+
state: z64.literal("awaiting_media"),
|
|
14283
|
+
successorCommandId: z64.null(),
|
|
14284
|
+
successorCollectionId: z64.string().uuid(),
|
|
14285
|
+
choice: z64.enum([
|
|
14286
|
+
"without_winner",
|
|
14287
|
+
"retry"
|
|
14288
|
+
])
|
|
14289
|
+
}).strict(),
|
|
14290
|
+
z64.object({
|
|
14291
|
+
...recoveryBase,
|
|
14292
|
+
state: z64.literal("cancelled"),
|
|
14293
|
+
successorCommandId: z64.null(),
|
|
14294
|
+
choice: z64.literal("cancel")
|
|
14295
|
+
}).strict()
|
|
14296
|
+
]).refine((receipt) => {
|
|
14297
|
+
const duration = Date.parse(receipt.expiresAt) - Date.parse(receipt.issuedAt);
|
|
14298
|
+
return duration > 0 && duration <= 24 * 60 * 60 * 1e3;
|
|
14299
|
+
}, "Recovery must expire within twenty-four hours");
|
|
14300
|
+
var WhatsAppQuoteBudgetResultSchema = z64.object({
|
|
14301
|
+
estimatedMinCredits: z64.number().finite().nonnegative(),
|
|
14302
|
+
estimatedMaxCredits: z64.number().finite().positive(),
|
|
14303
|
+
balanceCredits: z64.number().finite(),
|
|
14304
|
+
budgetRecovery: WhatsAppQuoteRecoveryReceiptSchema.optional()
|
|
14305
|
+
}).strict().refine((result) => result.estimatedMinCredits <= result.estimatedMaxCredits, "Minimum budget cannot exceed maximum");
|
|
14201
14306
|
var json = z64.lazy(() => z64.union([
|
|
14202
14307
|
z64.null(),
|
|
14203
14308
|
z64.boolean(),
|
|
@@ -14228,6 +14333,12 @@ function sameJson(a, b) {
|
|
|
14228
14333
|
__name(sameJson, "sameJson");
|
|
14229
14334
|
var WhatsAppPresentationFinalizerSchema = z64.object({
|
|
14230
14335
|
command: z64.discriminatedUnion("kind", [
|
|
14336
|
+
z64.object({
|
|
14337
|
+
...proposedSnapshot,
|
|
14338
|
+
kind: z64.literal("reject_quote"),
|
|
14339
|
+
errorCode: z64.literal("insufficient_balance"),
|
|
14340
|
+
result: WhatsAppQuoteBudgetResultSchema
|
|
14341
|
+
}).strict(),
|
|
14231
14342
|
z64.object({
|
|
14232
14343
|
...proposedSnapshot,
|
|
14233
14344
|
kind: z64.literal("reject_command"),
|
|
@@ -14287,7 +14398,7 @@ var WhatsAppPresentationFinalizerSchema = z64.object({
|
|
|
14287
14398
|
expiresAt: z64.string().datetime()
|
|
14288
14399
|
}).strict().optional()
|
|
14289
14400
|
}).strict().superRefine((value, ctx) => {
|
|
14290
|
-
if (value.command?.kind === "reject_command" || value.command?.kind === "complete_cancel") {
|
|
14401
|
+
if (value.command?.kind === "reject_command" || value.command?.kind === "reject_quote" || value.command?.kind === "complete_cancel") {
|
|
14291
14402
|
if (value.plan || value.collection) ctx.addIssue({
|
|
14292
14403
|
code: z64.ZodIssueCode.custom,
|
|
14293
14404
|
message: "Proposed command finalizers cannot bind plans or collections"
|
|
@@ -14296,6 +14407,13 @@ var WhatsAppPresentationFinalizerSchema = z64.object({
|
|
|
14296
14407
|
code: z64.ZodIssueCode.custom,
|
|
14297
14408
|
message: "Rejection must preserve the original result"
|
|
14298
14409
|
});
|
|
14410
|
+
if (value.command.kind === "reject_quote") {
|
|
14411
|
+
const receipt = value.command.result.budgetRecovery;
|
|
14412
|
+
if (receipt && (receipt.requestHash !== value.command.requestHash || receipt.state !== "open")) ctx.addIssue({
|
|
14413
|
+
code: z64.ZodIssueCode.custom,
|
|
14414
|
+
message: "Budget recovery must be new and bound to the rejected request"
|
|
14415
|
+
});
|
|
14416
|
+
}
|
|
14299
14417
|
}
|
|
14300
14418
|
if (!value.command && !value.plan && !value.collection) ctx.addIssue({
|
|
14301
14419
|
code: z64.ZodIssueCode.custom,
|
|
@@ -16081,7 +16199,7 @@ var ApiClient = class {
|
|
|
16081
16199
|
};
|
|
16082
16200
|
|
|
16083
16201
|
// src/index.ts
|
|
16084
|
-
var MCP_VERSION = "6.
|
|
16202
|
+
var MCP_VERSION = "6.9.1";
|
|
16085
16203
|
|
|
16086
16204
|
// src/meta-upload-app.ts
|
|
16087
16205
|
import { readFileSync } from "fs";
|
|
@@ -17199,6 +17317,8 @@ var McpErrorCode = {
|
|
|
17199
17317
|
SHOPIFY_PUBLISH_INPUT_REQUIRED: "SHOPIFY_PUBLISH_INPUT_REQUIRED",
|
|
17200
17318
|
SHOPIFY_PUBLISH_CONTEXT_CHANGED: "SHOPIFY_PUBLISH_CONTEXT_CHANGED",
|
|
17201
17319
|
SHOPIFY_PUBLISH_CORRECTION_REQUIRES_EDITOR: "SHOPIFY_PUBLISH_CORRECTION_REQUIRES_EDITOR",
|
|
17320
|
+
SHOPIFY_PUBLISH_TARGET_INCOMPATIBLE: "SHOPIFY_PUBLISH_TARGET_INCOMPATIBLE",
|
|
17321
|
+
SHOPIFY_THEME_SETUP_REQUIRED: "SHOPIFY_THEME_SETUP_REQUIRED",
|
|
17202
17322
|
// Meta / Facebook Ads
|
|
17203
17323
|
META_NO_FB_PAGE: "META_NO_FB_PAGE",
|
|
17204
17324
|
META_PORTFOLIO_MISMATCH: "META_PORTFOLIO_MISMATCH",
|
|
@@ -17269,6 +17389,8 @@ var CODE_MESSAGES = {
|
|
|
17269
17389
|
SHOPIFY_PUBLISH_INPUT_REQUIRED: "Review every recovery issue with the seller. Ask for missing prices and confirm the exact currency, unit price and pack totals before resending commerceCorrection with confirmed:true. Never invent amounts, convert currency or remove an offer.",
|
|
17270
17390
|
SHOPIFY_PUBLISH_CONTEXT_CHANGED: "The publication context changed. Reopen the task in ProductMaker, review the current store, product and landing revision, and obtain fresh confirmation. Do not reuse this correction.",
|
|
17271
17391
|
SHOPIFY_PUBLISH_CORRECTION_REQUIRES_EDITOR: "Open the landing editor in ProductMaker to reconcile the visible offer with checkout prices. The correction was not saved; do not retry it automatically or regenerate the landing without approval.",
|
|
17392
|
+
SHOPIFY_PUBLISH_TARGET_INCOMPATIBLE: "The selected Shopify product cannot carry the confirmed offer (missing quantity options/prices) or no longer exists. Read the error's message to the user, then retry with publicationMode:'new' to create a fresh product, or ask the user to pick a different existing product.",
|
|
17393
|
+
SHOPIFY_THEME_SETUP_REQUIRED: "The store's Shopify theme is missing the ProductMaker 'Code Landing' app block \u2014 publishing now would create a product whose page renders blank. Send the user the themeEditorDeepLink (in error data) to open the Shopify theme editor, have them confirm the Code Landing block is added and press Save, then retry publishing. This is a one-time step per store; nothing was published.",
|
|
17272
17394
|
SHOPIFY_NO_PUBLISHED_THEME: "The Shopify store has no published theme, so there is nowhere to place the landing. Ask the user to publish a theme (Online Store > Themes > Publish) and retry.",
|
|
17273
17395
|
SHOPIFY_THEME_STRUCTURE_UNSUPPORTED: "The active Shopify theme contains an HTML structure ProductMaker cannot process safely. Ask the user to restore a valid layout/theme.liquid or contact ProductMaker support to correct the theme, then retry.",
|
|
17274
17396
|
// Meta — high-frequency
|
|
@@ -17462,6 +17584,8 @@ var INVALID_PARAM_CODES = /* @__PURE__ */ new Set([
|
|
|
17462
17584
|
McpErrorCode.SHOPIFY_PUBLISH_INPUT_REQUIRED,
|
|
17463
17585
|
McpErrorCode.SHOPIFY_PUBLISH_CONTEXT_CHANGED,
|
|
17464
17586
|
McpErrorCode.SHOPIFY_PUBLISH_CORRECTION_REQUIRES_EDITOR,
|
|
17587
|
+
McpErrorCode.SHOPIFY_PUBLISH_TARGET_INCOMPATIBLE,
|
|
17588
|
+
McpErrorCode.SHOPIFY_THEME_SETUP_REQUIRED,
|
|
17465
17589
|
McpErrorCode.TIKTOK_NOT_CONNECTED,
|
|
17466
17590
|
McpErrorCode.NO_SHOPIFY_SHOPS,
|
|
17467
17591
|
McpErrorCode.NO_META_AD_ACCOUNTS
|
|
@@ -17487,6 +17611,7 @@ var PASSTHROUGH_CODES = /* @__PURE__ */ new Set([
|
|
|
17487
17611
|
McpErrorCode.SHOPIFY_PUBLISH_INPUT_REQUIRED,
|
|
17488
17612
|
McpErrorCode.SHOPIFY_PUBLISH_CONTEXT_CHANGED,
|
|
17489
17613
|
McpErrorCode.SHOPIFY_PUBLISH_CORRECTION_REQUIRES_EDITOR,
|
|
17614
|
+
McpErrorCode.SHOPIFY_PUBLISH_TARGET_INCOMPATIBLE,
|
|
17490
17615
|
McpErrorCode.SHOPIFY_NOT_CONNECTED,
|
|
17491
17616
|
McpErrorCode.SHOPIFY_TOKEN_EXPIRED,
|
|
17492
17617
|
McpErrorCode.SHOPIFY_SCOPE_UPGRADE_REQUIRED,
|
|
@@ -17609,13 +17734,14 @@ function translateError(err) {
|
|
|
17609
17734
|
}
|
|
17610
17735
|
if (err instanceof ApiHttpError) {
|
|
17611
17736
|
const body = isRecord2(err.body) ? err.body : {};
|
|
17612
|
-
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_FAILED) {
|
|
17737
|
+
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_THEME_SETUP_REQUIRED || body.code === McpErrorCode.SHOPIFY_PUBLISH_FAILED) {
|
|
17613
17738
|
const parsed = ShopifyPublishErrorResponse.safeParse(body);
|
|
17614
17739
|
if (!parsed.success) return mcp(McpErrorCode.INTERNAL, resolveMessage(McpErrorCode.INTERNAL, void 0));
|
|
17615
17740
|
const details = parsed.data;
|
|
17616
17741
|
const extra = {};
|
|
17617
17742
|
if (details.code === "SHOPIFY_PUBLISH_INPUT_REQUIRED") extra.recovery = details.recovery;
|
|
17618
17743
|
if (details.code === "SHOPIFY_PUBLISH_CORRECTION_REQUIRES_EDITOR") extra.action = details.action;
|
|
17744
|
+
if (details.code === "SHOPIFY_THEME_SETUP_REQUIRED") extra.themeEditorDeepLink = details.themeEditorDeepLink;
|
|
17619
17745
|
const saved = "commerceCorrectionSaved" in details && details.commerceCorrectionSaved === true;
|
|
17620
17746
|
if (saved) extra.commerceCorrectionSaved = true;
|
|
17621
17747
|
const message = resolveMessage(body.code, void 0);
|
|
@@ -20889,7 +21015,7 @@ var TikTokInput = z76.object({
|
|
|
20889
21015
|
});
|
|
20890
21016
|
function registerPublishTools(server, api, opts = {}) {
|
|
20891
21017
|
const transport = opts.transport ?? "http";
|
|
20892
|
-
server.tool("publish_to_shopify", publishToShopifyGuidance.summary + " Precondici\xF3n: la tarea debe estar en status='complete' \u2014 usa `get_task_status` antes. Por defecto `publicationMode=auto`: si esta tarea ya fue publicada en esa tienda, actualiza ESE MISMO producto y conserva URL, precio, variantes, inventario y SKU; si no, crea uno. Usa `existing` + `targetProductId` cuando el usuario elija otro producto y `new` s\xF3lo si pide crear uno nuevo. ANTES de llamar preg\xFAntale \"\xBFTu producto tiene variantes (talla, color, etc.)?\" y pasa `showVariantPicker: true` si responde que s\xED. Por defecto publica TODAS las im\xE1genes generadas; pasa `numLandingImages` s\xF3lo si el usuario pide menos. En code landings con una oferta expl\xEDcita de packs, ProductMaker s\xF3lo publica el selector si variantes reales de Shopify cobran los totales exactos; la respuesta explica si las cre\xF3, verific\xF3 o descart\xF3 por no existir ahorro. Si devuelve SHOPIFY_PUBLISH_INPUT_REQUIRED, muestra todos los problemas de recovery y solicita los importes faltantes. Solo env\xEDa commerceCorrection con su revisi\xF3n/huella y confirmed:true despu\xE9s de confirmar los valores exactos; nunca inventes importes, conviertas moneda ni elimines ofertas. Un contexto obsoleto requiere volver a revisar; open_editor requiere el editor de ProductMaker. Ante resultado incierto, verifica la tarea/tienda antes de volver a publicar, especialmente con new; commerceCorrectionSaved no prueba publicaci\xF3n. La respuesta es markdown con el link a la landing y al producto.", ShopifyInput.shape, OVERWRITES_EXTERNAL, async (input, extra) => {
|
|
21018
|
+
server.tool("publish_to_shopify", publishToShopifyGuidance.summary + " Precondici\xF3n: la tarea debe estar en status='complete' \u2014 usa `get_task_status` antes. Por defecto `publicationMode=auto`: si esta tarea ya fue publicada en esa tienda, actualiza ESE MISMO producto y conserva URL, precio, variantes, inventario y SKU; si no, crea uno. Usa `existing` + `targetProductId` cuando el usuario elija otro producto y `new` s\xF3lo si pide crear uno nuevo. ANTES de llamar preg\xFAntale \"\xBFTu producto tiene variantes (talla, color, etc.)?\" y pasa `showVariantPicker: true` si responde que s\xED. Por defecto publica TODAS las im\xE1genes generadas; pasa `numLandingImages` s\xF3lo si el usuario pide menos. En code landings con una oferta expl\xEDcita de packs, ProductMaker s\xF3lo publica el selector si variantes reales de Shopify cobran los totales exactos; la respuesta explica si las cre\xF3, verific\xF3 o descart\xF3 por no existir ahorro. Si devuelve SHOPIFY_PUBLISH_INPUT_REQUIRED, muestra todos los problemas de recovery y solicita los importes faltantes. Solo env\xEDa commerceCorrection con su revisi\xF3n/huella y confirmed:true despu\xE9s de confirmar los valores exactos; nunca inventes importes, conviertas moneda ni elimines ofertas. Un contexto obsoleto requiere volver a revisar; open_editor requiere el editor de ProductMaker. Si devuelve SHOPIFY_THEME_SETUP_REQUIRED, el tema de la tienda no tiene el bloque Code Landing y nada se public\xF3: env\xEDa al usuario el themeEditorDeepLink del error para abrir el editor del tema de Shopify, p\xEDdele que agregue el bloque y pulse Guardar (una sola vez por tienda), y reintenta s\xF3lo despu\xE9s. Ante resultado incierto, verifica la tarea/tienda antes de volver a publicar, especialmente con new; commerceCorrectionSaved no prueba publicaci\xF3n. La respuesta es markdown con el link a la landing y al producto.", ShopifyInput.shape, OVERWRITES_EXTERNAL, async (input, extra) => {
|
|
20893
21019
|
try {
|
|
20894
21020
|
const parsed = parseShopifyInput(input);
|
|
20895
21021
|
if (parsed.publicationMode === "existing" && !parsed.targetProductId) {
|
package/dist/stdio.js
CHANGED
|
@@ -2699,6 +2699,7 @@ function getCurrencyForCountry(country) {
|
|
|
2699
2699
|
}
|
|
2700
2700
|
__name(getCurrencyForCountry, "getCurrencyForCountry");
|
|
2701
2701
|
var MAX_PLAUSIBLE_AMOUNT = 1e10;
|
|
2702
|
+
var KNOWN_CURRENCY_CODES = new Set(Object.values(CURRENCY_BY_COUNTRY).map((c) => c.code));
|
|
2702
2703
|
|
|
2703
2704
|
// ../../packages/types/src/shopify-publish-recovery.ts
|
|
2704
2705
|
var MAX_MONEY_LENGTH = 40;
|
|
@@ -5105,6 +5106,52 @@ var ShopifyPublishErrorResponse = z27.discriminatedUnion("code", [
|
|
|
5105
5106
|
code: z27.literal("SHOPIFY_PUBLISH_CORRECTION_REQUIRES_EDITOR"),
|
|
5106
5107
|
action: z27.literal("open_editor"),
|
|
5107
5108
|
message: z27.string().optional()
|
|
5109
|
+
}),
|
|
5110
|
+
z27.object({
|
|
5111
|
+
/**
|
|
5112
|
+
* The chosen existing product cannot express the confirmed offer's
|
|
5113
|
+
* quantity/price options. `message` carries the merchant-facing reason;
|
|
5114
|
+
* the client offers a one-click "create a new product and retry" path.
|
|
5115
|
+
*/
|
|
5116
|
+
code: z27.literal("SHOPIFY_PUBLISH_TARGET_INCOMPATIBLE"),
|
|
5117
|
+
message: z27.string().optional(),
|
|
5118
|
+
commerceCorrectionSaved: z27.literal(true).optional()
|
|
5119
|
+
}),
|
|
5120
|
+
z27.object({
|
|
5121
|
+
/**
|
|
5122
|
+
* Code-landing publish refused BEFORE any product mutation: the shared
|
|
5123
|
+
* cl-landing template exists but the merchant has not saved the
|
|
5124
|
+
* code-landing-renderer app block, so the product page would render blank.
|
|
5125
|
+
* `themeEditorDeepLink` is the one-click fix — mandatory because without it
|
|
5126
|
+
* the client has nothing actionable to show.
|
|
5127
|
+
*/
|
|
5128
|
+
code: z27.literal("SHOPIFY_THEME_SETUP_REQUIRED"),
|
|
5129
|
+
message: z27.string().optional(),
|
|
5130
|
+
shopDomain: z27.string().optional(),
|
|
5131
|
+
themeEditorDeepLink: z27.string().url(),
|
|
5132
|
+
/**
|
|
5133
|
+
* Present when the request also carried a commerceCorrection that was
|
|
5134
|
+
* committed before the gate refused — the client must drop the stale
|
|
5135
|
+
* correction before retrying or it dies on CONTEXT_CHANGED.
|
|
5136
|
+
*/
|
|
5137
|
+
commerceCorrectionSaved: z27.literal(true).optional()
|
|
5138
|
+
})
|
|
5139
|
+
]);
|
|
5140
|
+
var CodeLandingThemeSetupResponse = z27.discriminatedUnion("status", [
|
|
5141
|
+
z27.object({
|
|
5142
|
+
/** The app block is saved (ready) or still missing (setup_required). */
|
|
5143
|
+
status: z27.enum([
|
|
5144
|
+
"ready",
|
|
5145
|
+
"setup_required"
|
|
5146
|
+
]),
|
|
5147
|
+
/** One-click theme-editor link that pre-adds the Code Landing block. */
|
|
5148
|
+
themeEditorDeepLink: z27.string().url(),
|
|
5149
|
+
shopDomain: z27.string()
|
|
5150
|
+
}),
|
|
5151
|
+
z27.object({
|
|
5152
|
+
/** Not a code-landing task — the gate does not apply. */
|
|
5153
|
+
status: z27.literal("not_applicable"),
|
|
5154
|
+
shopDomain: z27.string().optional()
|
|
5108
5155
|
})
|
|
5109
5156
|
]);
|
|
5110
5157
|
var ShopifyAuthUrlResponse = z27.object({
|
|
@@ -6314,7 +6361,7 @@ var SharedOutputEstimationFields = {
|
|
|
6314
6361
|
* The lightweight competitor scan must never imply this add-on. */
|
|
6315
6362
|
competitorCommercialStudyRequested: z33.boolean().optional(),
|
|
6316
6363
|
/** Declining the winner replica makes `gap_replication` unreachable, so its
|
|
6317
|
-
*
|
|
6364
|
+
* tier-matched replication ceiling must not be quoted. See
|
|
6318
6365
|
* `.agent/specs/winner-replication-consent.spec.test.ts`. */
|
|
6319
6366
|
replicateWinnerWhenFound: z33.boolean().optional()
|
|
6320
6367
|
};
|
|
@@ -13069,6 +13116,8 @@ var PRODUCTMAKER_CAPABILITY_REGISTRY = deepFreeze([
|
|
|
13069
13116
|
], [
|
|
13070
13117
|
"product_reference"
|
|
13071
13118
|
], [
|
|
13119
|
+
"task",
|
|
13120
|
+
"product",
|
|
13072
13121
|
"landing"
|
|
13073
13122
|
], SHARED_CHANNEL_EXPOSURE, [
|
|
13074
13123
|
{
|
|
@@ -13166,6 +13215,8 @@ var PRODUCTMAKER_CAPABILITY_REGISTRY = deepFreeze([
|
|
|
13166
13215
|
], [
|
|
13167
13216
|
"product_reference"
|
|
13168
13217
|
], [
|
|
13218
|
+
"task",
|
|
13219
|
+
"creative",
|
|
13169
13220
|
"video"
|
|
13170
13221
|
], SHARED_CHANNEL_EXPOSURE, [
|
|
13171
13222
|
{
|
|
@@ -13966,6 +14017,60 @@ import { z as z65 } from "zod";
|
|
|
13966
14017
|
|
|
13967
14018
|
// ../../packages/types/src/whatsapp-presentation-finalizer.ts
|
|
13968
14019
|
import { z as z64 } from "zod";
|
|
14020
|
+
var WhatsAppQuoteRecoveryChoiceSchema = z64.enum([
|
|
14021
|
+
"without_winner",
|
|
14022
|
+
"retry",
|
|
14023
|
+
"cancel"
|
|
14024
|
+
]);
|
|
14025
|
+
var recoveryBase = {
|
|
14026
|
+
version: z64.literal(1),
|
|
14027
|
+
requestHash: z64.string().min(1).max(256),
|
|
14028
|
+
issuedAt: z64.string().datetime(),
|
|
14029
|
+
expiresAt: z64.string().datetime(),
|
|
14030
|
+
offeredAlternative: z64.literal("without_winner").nullable()
|
|
14031
|
+
};
|
|
14032
|
+
var WhatsAppQuoteRecoveryReceiptSchema = z64.discriminatedUnion("state", [
|
|
14033
|
+
z64.object({
|
|
14034
|
+
...recoveryBase,
|
|
14035
|
+
state: z64.literal("open"),
|
|
14036
|
+
successorCommandId: z64.null(),
|
|
14037
|
+
choice: z64.null()
|
|
14038
|
+
}).strict(),
|
|
14039
|
+
z64.object({
|
|
14040
|
+
...recoveryBase,
|
|
14041
|
+
state: z64.literal("consumed"),
|
|
14042
|
+
successorCommandId: z64.string().uuid(),
|
|
14043
|
+
choice: z64.enum([
|
|
14044
|
+
"without_winner",
|
|
14045
|
+
"retry"
|
|
14046
|
+
])
|
|
14047
|
+
}).strict(),
|
|
14048
|
+
z64.object({
|
|
14049
|
+
...recoveryBase,
|
|
14050
|
+
state: z64.literal("awaiting_media"),
|
|
14051
|
+
successorCommandId: z64.null(),
|
|
14052
|
+
successorCollectionId: z64.string().uuid(),
|
|
14053
|
+
choice: z64.enum([
|
|
14054
|
+
"without_winner",
|
|
14055
|
+
"retry"
|
|
14056
|
+
])
|
|
14057
|
+
}).strict(),
|
|
14058
|
+
z64.object({
|
|
14059
|
+
...recoveryBase,
|
|
14060
|
+
state: z64.literal("cancelled"),
|
|
14061
|
+
successorCommandId: z64.null(),
|
|
14062
|
+
choice: z64.literal("cancel")
|
|
14063
|
+
}).strict()
|
|
14064
|
+
]).refine((receipt) => {
|
|
14065
|
+
const duration = Date.parse(receipt.expiresAt) - Date.parse(receipt.issuedAt);
|
|
14066
|
+
return duration > 0 && duration <= 24 * 60 * 60 * 1e3;
|
|
14067
|
+
}, "Recovery must expire within twenty-four hours");
|
|
14068
|
+
var WhatsAppQuoteBudgetResultSchema = z64.object({
|
|
14069
|
+
estimatedMinCredits: z64.number().finite().nonnegative(),
|
|
14070
|
+
estimatedMaxCredits: z64.number().finite().positive(),
|
|
14071
|
+
balanceCredits: z64.number().finite(),
|
|
14072
|
+
budgetRecovery: WhatsAppQuoteRecoveryReceiptSchema.optional()
|
|
14073
|
+
}).strict().refine((result) => result.estimatedMinCredits <= result.estimatedMaxCredits, "Minimum budget cannot exceed maximum");
|
|
13969
14074
|
var json = z64.lazy(() => z64.union([
|
|
13970
14075
|
z64.null(),
|
|
13971
14076
|
z64.boolean(),
|
|
@@ -13996,6 +14101,12 @@ function sameJson(a, b) {
|
|
|
13996
14101
|
__name(sameJson, "sameJson");
|
|
13997
14102
|
var WhatsAppPresentationFinalizerSchema = z64.object({
|
|
13998
14103
|
command: z64.discriminatedUnion("kind", [
|
|
14104
|
+
z64.object({
|
|
14105
|
+
...proposedSnapshot,
|
|
14106
|
+
kind: z64.literal("reject_quote"),
|
|
14107
|
+
errorCode: z64.literal("insufficient_balance"),
|
|
14108
|
+
result: WhatsAppQuoteBudgetResultSchema
|
|
14109
|
+
}).strict(),
|
|
13999
14110
|
z64.object({
|
|
14000
14111
|
...proposedSnapshot,
|
|
14001
14112
|
kind: z64.literal("reject_command"),
|
|
@@ -14055,7 +14166,7 @@ var WhatsAppPresentationFinalizerSchema = z64.object({
|
|
|
14055
14166
|
expiresAt: z64.string().datetime()
|
|
14056
14167
|
}).strict().optional()
|
|
14057
14168
|
}).strict().superRefine((value, ctx) => {
|
|
14058
|
-
if (value.command?.kind === "reject_command" || value.command?.kind === "complete_cancel") {
|
|
14169
|
+
if (value.command?.kind === "reject_command" || value.command?.kind === "reject_quote" || value.command?.kind === "complete_cancel") {
|
|
14059
14170
|
if (value.plan || value.collection) ctx.addIssue({
|
|
14060
14171
|
code: z64.ZodIssueCode.custom,
|
|
14061
14172
|
message: "Proposed command finalizers cannot bind plans or collections"
|
|
@@ -14064,6 +14175,13 @@ var WhatsAppPresentationFinalizerSchema = z64.object({
|
|
|
14064
14175
|
code: z64.ZodIssueCode.custom,
|
|
14065
14176
|
message: "Rejection must preserve the original result"
|
|
14066
14177
|
});
|
|
14178
|
+
if (value.command.kind === "reject_quote") {
|
|
14179
|
+
const receipt = value.command.result.budgetRecovery;
|
|
14180
|
+
if (receipt && (receipt.requestHash !== value.command.requestHash || receipt.state !== "open")) ctx.addIssue({
|
|
14181
|
+
code: z64.ZodIssueCode.custom,
|
|
14182
|
+
message: "Budget recovery must be new and bound to the rejected request"
|
|
14183
|
+
});
|
|
14184
|
+
}
|
|
14067
14185
|
}
|
|
14068
14186
|
if (!value.command && !value.plan && !value.collection) ctx.addIssue({
|
|
14069
14187
|
code: z64.ZodIssueCode.custom,
|
|
@@ -14460,7 +14578,7 @@ var ApiClient = class {
|
|
|
14460
14578
|
};
|
|
14461
14579
|
|
|
14462
14580
|
// src/index.ts
|
|
14463
|
-
var MCP_VERSION = "6.
|
|
14581
|
+
var MCP_VERSION = "6.9.1";
|
|
14464
14582
|
|
|
14465
14583
|
// src/meta-upload-app.ts
|
|
14466
14584
|
import { readFileSync } from "fs";
|
|
@@ -15578,6 +15696,8 @@ var McpErrorCode = {
|
|
|
15578
15696
|
SHOPIFY_PUBLISH_INPUT_REQUIRED: "SHOPIFY_PUBLISH_INPUT_REQUIRED",
|
|
15579
15697
|
SHOPIFY_PUBLISH_CONTEXT_CHANGED: "SHOPIFY_PUBLISH_CONTEXT_CHANGED",
|
|
15580
15698
|
SHOPIFY_PUBLISH_CORRECTION_REQUIRES_EDITOR: "SHOPIFY_PUBLISH_CORRECTION_REQUIRES_EDITOR",
|
|
15699
|
+
SHOPIFY_PUBLISH_TARGET_INCOMPATIBLE: "SHOPIFY_PUBLISH_TARGET_INCOMPATIBLE",
|
|
15700
|
+
SHOPIFY_THEME_SETUP_REQUIRED: "SHOPIFY_THEME_SETUP_REQUIRED",
|
|
15581
15701
|
// Meta / Facebook Ads
|
|
15582
15702
|
META_NO_FB_PAGE: "META_NO_FB_PAGE",
|
|
15583
15703
|
META_PORTFOLIO_MISMATCH: "META_PORTFOLIO_MISMATCH",
|
|
@@ -15648,6 +15768,8 @@ var CODE_MESSAGES = {
|
|
|
15648
15768
|
SHOPIFY_PUBLISH_INPUT_REQUIRED: "Review every recovery issue with the seller. Ask for missing prices and confirm the exact currency, unit price and pack totals before resending commerceCorrection with confirmed:true. Never invent amounts, convert currency or remove an offer.",
|
|
15649
15769
|
SHOPIFY_PUBLISH_CONTEXT_CHANGED: "The publication context changed. Reopen the task in ProductMaker, review the current store, product and landing revision, and obtain fresh confirmation. Do not reuse this correction.",
|
|
15650
15770
|
SHOPIFY_PUBLISH_CORRECTION_REQUIRES_EDITOR: "Open the landing editor in ProductMaker to reconcile the visible offer with checkout prices. The correction was not saved; do not retry it automatically or regenerate the landing without approval.",
|
|
15771
|
+
SHOPIFY_PUBLISH_TARGET_INCOMPATIBLE: "The selected Shopify product cannot carry the confirmed offer (missing quantity options/prices) or no longer exists. Read the error's message to the user, then retry with publicationMode:'new' to create a fresh product, or ask the user to pick a different existing product.",
|
|
15772
|
+
SHOPIFY_THEME_SETUP_REQUIRED: "The store's Shopify theme is missing the ProductMaker 'Code Landing' app block \u2014 publishing now would create a product whose page renders blank. Send the user the themeEditorDeepLink (in error data) to open the Shopify theme editor, have them confirm the Code Landing block is added and press Save, then retry publishing. This is a one-time step per store; nothing was published.",
|
|
15651
15773
|
SHOPIFY_NO_PUBLISHED_THEME: "The Shopify store has no published theme, so there is nowhere to place the landing. Ask the user to publish a theme (Online Store > Themes > Publish) and retry.",
|
|
15652
15774
|
SHOPIFY_THEME_STRUCTURE_UNSUPPORTED: "The active Shopify theme contains an HTML structure ProductMaker cannot process safely. Ask the user to restore a valid layout/theme.liquid or contact ProductMaker support to correct the theme, then retry.",
|
|
15653
15775
|
// Meta — high-frequency
|
|
@@ -15841,6 +15963,8 @@ var INVALID_PARAM_CODES = /* @__PURE__ */ new Set([
|
|
|
15841
15963
|
McpErrorCode.SHOPIFY_PUBLISH_INPUT_REQUIRED,
|
|
15842
15964
|
McpErrorCode.SHOPIFY_PUBLISH_CONTEXT_CHANGED,
|
|
15843
15965
|
McpErrorCode.SHOPIFY_PUBLISH_CORRECTION_REQUIRES_EDITOR,
|
|
15966
|
+
McpErrorCode.SHOPIFY_PUBLISH_TARGET_INCOMPATIBLE,
|
|
15967
|
+
McpErrorCode.SHOPIFY_THEME_SETUP_REQUIRED,
|
|
15844
15968
|
McpErrorCode.TIKTOK_NOT_CONNECTED,
|
|
15845
15969
|
McpErrorCode.NO_SHOPIFY_SHOPS,
|
|
15846
15970
|
McpErrorCode.NO_META_AD_ACCOUNTS
|
|
@@ -15866,6 +15990,7 @@ var PASSTHROUGH_CODES = /* @__PURE__ */ new Set([
|
|
|
15866
15990
|
McpErrorCode.SHOPIFY_PUBLISH_INPUT_REQUIRED,
|
|
15867
15991
|
McpErrorCode.SHOPIFY_PUBLISH_CONTEXT_CHANGED,
|
|
15868
15992
|
McpErrorCode.SHOPIFY_PUBLISH_CORRECTION_REQUIRES_EDITOR,
|
|
15993
|
+
McpErrorCode.SHOPIFY_PUBLISH_TARGET_INCOMPATIBLE,
|
|
15869
15994
|
McpErrorCode.SHOPIFY_NOT_CONNECTED,
|
|
15870
15995
|
McpErrorCode.SHOPIFY_TOKEN_EXPIRED,
|
|
15871
15996
|
McpErrorCode.SHOPIFY_SCOPE_UPGRADE_REQUIRED,
|
|
@@ -15988,13 +16113,14 @@ function translateError(err) {
|
|
|
15988
16113
|
}
|
|
15989
16114
|
if (err instanceof ApiHttpError) {
|
|
15990
16115
|
const body = isRecord2(err.body) ? err.body : {};
|
|
15991
|
-
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_FAILED) {
|
|
16116
|
+
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_THEME_SETUP_REQUIRED || body.code === McpErrorCode.SHOPIFY_PUBLISH_FAILED) {
|
|
15992
16117
|
const parsed = ShopifyPublishErrorResponse.safeParse(body);
|
|
15993
16118
|
if (!parsed.success) return mcp(McpErrorCode.INTERNAL, resolveMessage(McpErrorCode.INTERNAL, void 0));
|
|
15994
16119
|
const details = parsed.data;
|
|
15995
16120
|
const extra = {};
|
|
15996
16121
|
if (details.code === "SHOPIFY_PUBLISH_INPUT_REQUIRED") extra.recovery = details.recovery;
|
|
15997
16122
|
if (details.code === "SHOPIFY_PUBLISH_CORRECTION_REQUIRES_EDITOR") extra.action = details.action;
|
|
16123
|
+
if (details.code === "SHOPIFY_THEME_SETUP_REQUIRED") extra.themeEditorDeepLink = details.themeEditorDeepLink;
|
|
15998
16124
|
const saved = "commerceCorrectionSaved" in details && details.commerceCorrectionSaved === true;
|
|
15999
16125
|
if (saved) extra.commerceCorrectionSaved = true;
|
|
16000
16126
|
const message = resolveMessage(body.code, void 0);
|
|
@@ -19321,7 +19447,7 @@ var TikTokInput = z75.object({
|
|
|
19321
19447
|
});
|
|
19322
19448
|
function registerPublishTools(server, api, opts = {}) {
|
|
19323
19449
|
const transport = opts.transport ?? "http";
|
|
19324
|
-
server.tool("publish_to_shopify", publishToShopifyGuidance.summary + " Precondici\xF3n: la tarea debe estar en status='complete' \u2014 usa `get_task_status` antes. Por defecto `publicationMode=auto`: si esta tarea ya fue publicada en esa tienda, actualiza ESE MISMO producto y conserva URL, precio, variantes, inventario y SKU; si no, crea uno. Usa `existing` + `targetProductId` cuando el usuario elija otro producto y `new` s\xF3lo si pide crear uno nuevo. ANTES de llamar preg\xFAntale \"\xBFTu producto tiene variantes (talla, color, etc.)?\" y pasa `showVariantPicker: true` si responde que s\xED. Por defecto publica TODAS las im\xE1genes generadas; pasa `numLandingImages` s\xF3lo si el usuario pide menos. En code landings con una oferta expl\xEDcita de packs, ProductMaker s\xF3lo publica el selector si variantes reales de Shopify cobran los totales exactos; la respuesta explica si las cre\xF3, verific\xF3 o descart\xF3 por no existir ahorro. Si devuelve SHOPIFY_PUBLISH_INPUT_REQUIRED, muestra todos los problemas de recovery y solicita los importes faltantes. Solo env\xEDa commerceCorrection con su revisi\xF3n/huella y confirmed:true despu\xE9s de confirmar los valores exactos; nunca inventes importes, conviertas moneda ni elimines ofertas. Un contexto obsoleto requiere volver a revisar; open_editor requiere el editor de ProductMaker. Ante resultado incierto, verifica la tarea/tienda antes de volver a publicar, especialmente con new; commerceCorrectionSaved no prueba publicaci\xF3n. La respuesta es markdown con el link a la landing y al producto.", ShopifyInput.shape, OVERWRITES_EXTERNAL, async (input, extra) => {
|
|
19450
|
+
server.tool("publish_to_shopify", publishToShopifyGuidance.summary + " Precondici\xF3n: la tarea debe estar en status='complete' \u2014 usa `get_task_status` antes. Por defecto `publicationMode=auto`: si esta tarea ya fue publicada en esa tienda, actualiza ESE MISMO producto y conserva URL, precio, variantes, inventario y SKU; si no, crea uno. Usa `existing` + `targetProductId` cuando el usuario elija otro producto y `new` s\xF3lo si pide crear uno nuevo. ANTES de llamar preg\xFAntale \"\xBFTu producto tiene variantes (talla, color, etc.)?\" y pasa `showVariantPicker: true` si responde que s\xED. Por defecto publica TODAS las im\xE1genes generadas; pasa `numLandingImages` s\xF3lo si el usuario pide menos. En code landings con una oferta expl\xEDcita de packs, ProductMaker s\xF3lo publica el selector si variantes reales de Shopify cobran los totales exactos; la respuesta explica si las cre\xF3, verific\xF3 o descart\xF3 por no existir ahorro. Si devuelve SHOPIFY_PUBLISH_INPUT_REQUIRED, muestra todos los problemas de recovery y solicita los importes faltantes. Solo env\xEDa commerceCorrection con su revisi\xF3n/huella y confirmed:true despu\xE9s de confirmar los valores exactos; nunca inventes importes, conviertas moneda ni elimines ofertas. Un contexto obsoleto requiere volver a revisar; open_editor requiere el editor de ProductMaker. Si devuelve SHOPIFY_THEME_SETUP_REQUIRED, el tema de la tienda no tiene el bloque Code Landing y nada se public\xF3: env\xEDa al usuario el themeEditorDeepLink del error para abrir el editor del tema de Shopify, p\xEDdele que agregue el bloque y pulse Guardar (una sola vez por tienda), y reintenta s\xF3lo despu\xE9s. Ante resultado incierto, verifica la tarea/tienda antes de volver a publicar, especialmente con new; commerceCorrectionSaved no prueba publicaci\xF3n. La respuesta es markdown con el link a la landing y al producto.", ShopifyInput.shape, OVERWRITES_EXTERNAL, async (input, extra) => {
|
|
19325
19451
|
try {
|
|
19326
19452
|
const parsed = parseShopifyInput(input);
|
|
19327
19453
|
if (parsed.publicationMode === "existing" && !parsed.targetProductId) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@productmaker/mcp",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.9.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "Product Maker MCP server — cost products, generate dropshipping landing pages, UGC videos, and ad creatives, and publish to Shopify and Meta Ads from Claude, ChatGPT, or Gemini.",
|