@productmaker/mcp 0.8.0 → 0.9.0

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 CHANGED
@@ -966,6 +966,17 @@ var PendingActionPayload = z2.discriminatedUnion("kind", [
966
966
  z2.object({
967
967
  kind: z2.literal("product_reference_confirmation"),
968
968
  userChoice: ProductReferenceUserChoiceEnum
969
+ }),
970
+ z2.object({
971
+ kind: z2.literal("angle_review_approval"),
972
+ // All edits are optional — empty action body just approves the
973
+ // backend-generated draft as-is. Field shapes mirror ApproveAnglesRequest
974
+ // in @packages/types/wizard.ts (the only path-of-resolution endpoint is
975
+ // POST /v1/tasks/:taskId/approve-angles).
976
+ customAngle: z2.string().min(1).max(480).optional(),
977
+ painPoints: z2.string().max(3e3).optional(),
978
+ benefits: z2.string().max(3e3).optional(),
979
+ features: z2.array(z2.string().min(1).max(300)).max(10).optional()
969
980
  })
970
981
  ]);
971
982
  var ResolvePendingActionInput = z2.object({
@@ -976,7 +987,11 @@ var StatusForResolveSchema = z2.object({
976
987
  pendingUserAction: z2.object({
977
988
  kind: z2.string(),
978
989
  candidateGrouping: z2.string().optional(),
979
- selectedImageUrls: z2.array(z2.string()).optional()
990
+ selectedImageUrls: z2.array(z2.string()).optional(),
991
+ customAngleDraft: z2.string().optional(),
992
+ painPointsDraft: z2.string().optional(),
993
+ benefitsDraft: z2.string().optional(),
994
+ featuresDraft: z2.array(z2.string()).optional()
980
995
  }).optional()
981
996
  }).passthrough();
982
997
  function registerTaskTools(server, api, { proxyBaseUrl = null, transport = "http" } = {}) {
@@ -1074,7 +1089,7 @@ function registerTaskTools(server, api, { proxyBaseUrl = null, transport = "http
1074
1089
  throw translateError(e);
1075
1090
  }
1076
1091
  });
1077
- server.tool("resolve_pending_action", 'Resuelve una acci\xF3n que el pipeline est\xE1 esperando del usuario. La llamas cuando `get_task_status` devuelve `pendingUserAction` (sin esto la tarea NUNCA avanza por m\xE1s que esperes). El `action.kind` que mandas DEBE coincidir con el `pendingUserAction.kind` que viste en el status \u2014 es el contrato de simetr\xEDa que mantiene este tool como \xFAnica superficie de resoluci\xF3n de gates.\n\nKINDS soportados hoy:\n\n\u2022 `product_reference_confirmation` \u2014 el clasificador no est\xE1 seguro si las fotos son variantes del mismo producto o productos distintos. Payload: `userChoice` \u2208 { "same_product" (mismo producto, fotos son s\xF3lo \xE1ngulos distintos), "variants" (mismo producto, distintos colores/tallas/sabores), "combo_distinct" (son 2 productos distintos vendidos juntos como combo \u2014 marca la tarea como combo), "different_products" (productos distintos y el usuario quiere generar s\xF3lo uno \u2014 el backend bloquea hasta que selecciones im\xE1genes de un solo producto; normalmente NO es la respuesta correcta para destrabar) }. PREG\xDANTALE al usuario antes de invocar \u2014 `pendingUserAction.targetProductLabel` y `reason` te dan contexto para formularle la pregunta en lenguaje natural. Usa SOLO valores presentes en `pendingUserAction.options`.\n\nFuturos kinds (no implementados a\xFAn) se agregar\xE1n como nuevas variantes del `action` discriminated union \u2014 el flujo "lee kind del status \u2192 manda mismo kind aqu\xED" sigue igual.', ResolvePendingActionInput.shape, async (input) => {
1092
+ server.tool("resolve_pending_action", 'Resuelve una acci\xF3n que el pipeline est\xE1 esperando del usuario. La llamas cuando `get_task_status` devuelve `pendingUserAction` (sin esto la tarea NUNCA avanza por m\xE1s que esperes). El `action.kind` que mandas DEBE coincidir con el `pendingUserAction.kind` que viste en el status \u2014 es el contrato de simetr\xEDa que mantiene este tool como \xFAnica superficie de resoluci\xF3n de gates.\n\nKINDS soportados hoy:\n\n\u2022 `product_reference_confirmation` \u2014 el clasificador no est\xE1 seguro si las fotos son variantes del mismo producto o productos distintos. Payload: `userChoice` \u2208 { "same_product" (mismo producto, fotos son s\xF3lo \xE1ngulos distintos), "variants" (mismo producto, distintos colores/tallas/sabores), "combo_distinct" (son 2 productos distintos vendidos juntos como combo \u2014 marca la tarea como combo), "different_products" (productos distintos y el usuario quiere generar s\xF3lo uno \u2014 el backend bloquea hasta que selecciones im\xE1genes de un solo producto; normalmente NO es la respuesta correcta para destrabar) }. PREG\xDANTALE al usuario antes de invocar \u2014 `pendingUserAction.targetProductLabel` y `reason` te dan contexto para formularle la pregunta en lenguaje natural. Usa SOLO valores presentes en `pendingUserAction.options`.\n\n\u2022 `angle_review_approval` \u2014 el usuario opto por `pauseForAngleReview: true` al crear el creativo (en `generate_image_creatives`, `generate_video_creative` o `generate_landing`). La IA ya gener\xF3 el \xE1ngulo + pain points + benefits + features y la tarea est\xE1 pausada esperando que el usuario apruebe o edite antes de renderizar. Lee `customAngleDraft`, `painPointsDraft`, `benefitsDraft`, `featuresDraft` del `pendingUserAction` para mostr\xE1rselos al usuario en lenguaje natural ("la IA propuso este \xE1ngulo: ... \xBFlo apruebas o cambias algo?"). Payload (TODOS opcionales \u2014 sin nada = aprobar tal cual; con campos = aprobar con ediciones): `customAngle` (override del \xE1ngulo), `painPoints`, `benefits`, `features` (array de 1-10 bullets). Llamar sin ning\xFAn campo es v\xE1lido y aprueba el draft sin cambios.\n\nFuturos kinds (no implementados a\xFAn) se agregar\xE1n como nuevas variantes del `action` discriminated union \u2014 el flujo "lee kind del status \u2192 manda mismo kind aqu\xED" sigue igual.', ResolvePendingActionInput.shape, async (input) => {
1078
1093
  try {
1079
1094
  const raw = await api.getJson(`/v1/status/${encodeURIComponent(input.taskId)}`);
1080
1095
  const status = StatusForResolveSchema.parse(raw);
@@ -1104,9 +1119,26 @@ function registerTaskTools(server, api, { proxyBaseUrl = null, transport = "http
1104
1119
  });
1105
1120
  return asText(r);
1106
1121
  }
1122
+ case "angle_review_approval": {
1123
+ const body = {};
1124
+ if (pending.customAngleDraft && pending.customAngleDraft.length > 0) {
1125
+ body.customAngle = pending.customAngleDraft;
1126
+ }
1127
+ if (pending.painPointsDraft != null) body.painPoints = pending.painPointsDraft;
1128
+ if (pending.benefitsDraft != null) body.benefits = pending.benefitsDraft;
1129
+ if (pending.featuresDraft != null) body.features = [
1130
+ ...pending.featuresDraft
1131
+ ];
1132
+ if (input.action.customAngle != null) body.customAngle = input.action.customAngle;
1133
+ if (input.action.painPoints != null) body.painPoints = input.action.painPoints;
1134
+ if (input.action.benefits != null) body.benefits = input.action.benefits;
1135
+ if (input.action.features != null) body.features = input.action.features;
1136
+ const r = await api.postJson(`/v1/tasks/${encodeURIComponent(input.taskId)}/approve-angles`, body);
1137
+ return asText(r);
1138
+ }
1107
1139
  default: {
1108
- const _exhaustive = input.action.kind;
1109
- throw new Error(`Unsupported pending action kind: ${String(_exhaustive)}`);
1140
+ const _exhaustive = input.action;
1141
+ throw new Error(`Unsupported pending action kind: ${String(_exhaustive.kind)}`);
1110
1142
  }
1111
1143
  }
1112
1144
  } catch (e) {
package/dist/stdio.js CHANGED
@@ -922,6 +922,17 @@ var PendingActionPayload = z2.discriminatedUnion("kind", [
922
922
  z2.object({
923
923
  kind: z2.literal("product_reference_confirmation"),
924
924
  userChoice: ProductReferenceUserChoiceEnum
925
+ }),
926
+ z2.object({
927
+ kind: z2.literal("angle_review_approval"),
928
+ // All edits are optional — empty action body just approves the
929
+ // backend-generated draft as-is. Field shapes mirror ApproveAnglesRequest
930
+ // in @packages/types/wizard.ts (the only path-of-resolution endpoint is
931
+ // POST /v1/tasks/:taskId/approve-angles).
932
+ customAngle: z2.string().min(1).max(480).optional(),
933
+ painPoints: z2.string().max(3e3).optional(),
934
+ benefits: z2.string().max(3e3).optional(),
935
+ features: z2.array(z2.string().min(1).max(300)).max(10).optional()
925
936
  })
926
937
  ]);
927
938
  var ResolvePendingActionInput = z2.object({
@@ -932,7 +943,11 @@ var StatusForResolveSchema = z2.object({
932
943
  pendingUserAction: z2.object({
933
944
  kind: z2.string(),
934
945
  candidateGrouping: z2.string().optional(),
935
- selectedImageUrls: z2.array(z2.string()).optional()
946
+ selectedImageUrls: z2.array(z2.string()).optional(),
947
+ customAngleDraft: z2.string().optional(),
948
+ painPointsDraft: z2.string().optional(),
949
+ benefitsDraft: z2.string().optional(),
950
+ featuresDraft: z2.array(z2.string()).optional()
936
951
  }).optional()
937
952
  }).passthrough();
938
953
  function registerTaskTools(server, api, { proxyBaseUrl = null, transport = "http" } = {}) {
@@ -1030,7 +1045,7 @@ function registerTaskTools(server, api, { proxyBaseUrl = null, transport = "http
1030
1045
  throw translateError(e);
1031
1046
  }
1032
1047
  });
1033
- server.tool("resolve_pending_action", 'Resuelve una acci\xF3n que el pipeline est\xE1 esperando del usuario. La llamas cuando `get_task_status` devuelve `pendingUserAction` (sin esto la tarea NUNCA avanza por m\xE1s que esperes). El `action.kind` que mandas DEBE coincidir con el `pendingUserAction.kind` que viste en el status \u2014 es el contrato de simetr\xEDa que mantiene este tool como \xFAnica superficie de resoluci\xF3n de gates.\n\nKINDS soportados hoy:\n\n\u2022 `product_reference_confirmation` \u2014 el clasificador no est\xE1 seguro si las fotos son variantes del mismo producto o productos distintos. Payload: `userChoice` \u2208 { "same_product" (mismo producto, fotos son s\xF3lo \xE1ngulos distintos), "variants" (mismo producto, distintos colores/tallas/sabores), "combo_distinct" (son 2 productos distintos vendidos juntos como combo \u2014 marca la tarea como combo), "different_products" (productos distintos y el usuario quiere generar s\xF3lo uno \u2014 el backend bloquea hasta que selecciones im\xE1genes de un solo producto; normalmente NO es la respuesta correcta para destrabar) }. PREG\xDANTALE al usuario antes de invocar \u2014 `pendingUserAction.targetProductLabel` y `reason` te dan contexto para formularle la pregunta en lenguaje natural. Usa SOLO valores presentes en `pendingUserAction.options`.\n\nFuturos kinds (no implementados a\xFAn) se agregar\xE1n como nuevas variantes del `action` discriminated union \u2014 el flujo "lee kind del status \u2192 manda mismo kind aqu\xED" sigue igual.', ResolvePendingActionInput.shape, async (input) => {
1048
+ server.tool("resolve_pending_action", 'Resuelve una acci\xF3n que el pipeline est\xE1 esperando del usuario. La llamas cuando `get_task_status` devuelve `pendingUserAction` (sin esto la tarea NUNCA avanza por m\xE1s que esperes). El `action.kind` que mandas DEBE coincidir con el `pendingUserAction.kind` que viste en el status \u2014 es el contrato de simetr\xEDa que mantiene este tool como \xFAnica superficie de resoluci\xF3n de gates.\n\nKINDS soportados hoy:\n\n\u2022 `product_reference_confirmation` \u2014 el clasificador no est\xE1 seguro si las fotos son variantes del mismo producto o productos distintos. Payload: `userChoice` \u2208 { "same_product" (mismo producto, fotos son s\xF3lo \xE1ngulos distintos), "variants" (mismo producto, distintos colores/tallas/sabores), "combo_distinct" (son 2 productos distintos vendidos juntos como combo \u2014 marca la tarea como combo), "different_products" (productos distintos y el usuario quiere generar s\xF3lo uno \u2014 el backend bloquea hasta que selecciones im\xE1genes de un solo producto; normalmente NO es la respuesta correcta para destrabar) }. PREG\xDANTALE al usuario antes de invocar \u2014 `pendingUserAction.targetProductLabel` y `reason` te dan contexto para formularle la pregunta en lenguaje natural. Usa SOLO valores presentes en `pendingUserAction.options`.\n\n\u2022 `angle_review_approval` \u2014 el usuario opto por `pauseForAngleReview: true` al crear el creativo (en `generate_image_creatives`, `generate_video_creative` o `generate_landing`). La IA ya gener\xF3 el \xE1ngulo + pain points + benefits + features y la tarea est\xE1 pausada esperando que el usuario apruebe o edite antes de renderizar. Lee `customAngleDraft`, `painPointsDraft`, `benefitsDraft`, `featuresDraft` del `pendingUserAction` para mostr\xE1rselos al usuario en lenguaje natural ("la IA propuso este \xE1ngulo: ... \xBFlo apruebas o cambias algo?"). Payload (TODOS opcionales \u2014 sin nada = aprobar tal cual; con campos = aprobar con ediciones): `customAngle` (override del \xE1ngulo), `painPoints`, `benefits`, `features` (array de 1-10 bullets). Llamar sin ning\xFAn campo es v\xE1lido y aprueba el draft sin cambios.\n\nFuturos kinds (no implementados a\xFAn) se agregar\xE1n como nuevas variantes del `action` discriminated union \u2014 el flujo "lee kind del status \u2192 manda mismo kind aqu\xED" sigue igual.', ResolvePendingActionInput.shape, async (input) => {
1034
1049
  try {
1035
1050
  const raw = await api.getJson(`/v1/status/${encodeURIComponent(input.taskId)}`);
1036
1051
  const status = StatusForResolveSchema.parse(raw);
@@ -1060,9 +1075,26 @@ function registerTaskTools(server, api, { proxyBaseUrl = null, transport = "http
1060
1075
  });
1061
1076
  return asText(r);
1062
1077
  }
1078
+ case "angle_review_approval": {
1079
+ const body = {};
1080
+ if (pending.customAngleDraft && pending.customAngleDraft.length > 0) {
1081
+ body.customAngle = pending.customAngleDraft;
1082
+ }
1083
+ if (pending.painPointsDraft != null) body.painPoints = pending.painPointsDraft;
1084
+ if (pending.benefitsDraft != null) body.benefits = pending.benefitsDraft;
1085
+ if (pending.featuresDraft != null) body.features = [
1086
+ ...pending.featuresDraft
1087
+ ];
1088
+ if (input.action.customAngle != null) body.customAngle = input.action.customAngle;
1089
+ if (input.action.painPoints != null) body.painPoints = input.action.painPoints;
1090
+ if (input.action.benefits != null) body.benefits = input.action.benefits;
1091
+ if (input.action.features != null) body.features = input.action.features;
1092
+ const r = await api.postJson(`/v1/tasks/${encodeURIComponent(input.taskId)}/approve-angles`, body);
1093
+ return asText(r);
1094
+ }
1063
1095
  default: {
1064
- const _exhaustive = input.action.kind;
1065
- throw new Error(`Unsupported pending action kind: ${String(_exhaustive)}`);
1096
+ const _exhaustive = input.action;
1097
+ throw new Error(`Unsupported pending action kind: ${String(_exhaustive.kind)}`);
1066
1098
  }
1067
1099
  }
1068
1100
  } catch (e) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@productmaker/mcp",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "description": "Product Maker MCP server — connect Claude Desktop, Claude Code, ChatGPT, or Gemini to Product Maker AI to generate dropshipping landing pages, UGC videos, and ad creatives, and publish to Shopify and Meta Ads from your AI assistant.",