story-theme-mcp 1.2.1 → 1.2.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "story-theme-mcp",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "description": "Serveur MCP du Story Thème : votre assistant IA connaît le thème Shopify Story par cœur et construit des boutiques propres et professionnelles.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -23,6 +23,7 @@
23
23
  "dependencies": {
24
24
  "@modelcontextprotocol/sdk": "^1.30.0",
25
25
  "fflate": "^0.8.3",
26
+ "story-theme-mcp": "^1.2.1",
26
27
  "zod": "^4.6.5"
27
28
  },
28
29
  "keywords": [
@@ -399,7 +399,9 @@ export function enrichir(steps, { direction = 'editorial', graine = 0, hasImages
399
399
  // même duo, dans le même ordre. Le second saute d'un pas tiré de la graine, jamais nul.
400
400
  const premier = graine % pool.length;
401
401
  const pas = 1 + (Math.floor(graine / pool.length) % Math.max(1, pool.length - 1));
402
- const tirage = pool.length === 1 ? [pool[0]] : [pool[premier], pool[(premier + pas) % pool.length]];
402
+ // Trois et non deux : une V1 doit ressembler à une boutique finie, pas à une trame.
403
+ const combien = Math.min(3, pool.length);
404
+ const tirage = Array.from({ length: combien }, (_, i) => pool[(premier + i * pas) % pool.length]);
403
405
  const uniques = tirage.filter((etape, i) => tirage.findIndex((autre) => autre.type === etape.type) === i);
404
406
 
405
407
  const sortie = [...steps];
@@ -753,11 +755,12 @@ export function buildStore({ catalog, store }, input) {
753
755
  const recipes = [];
754
756
  const home = findRecipe(input.home) ? input.home : preset.home;
755
757
  recipes.push([home, 'templates/index.json']);
756
- recipes.push([input.offers ? 'produit-offres' : 'produit-complet', 'templates/product.json']);
758
+ const avecOffres = input.offers !== false;
759
+ recipes.push([avecOffres ? 'produit-offres' : 'produit-complet', 'templates/product.json']);
757
760
  recipes.push(['collection-complete', 'templates/collection.json']);
758
761
  const pages = input.pages || DEFAULT_PAGES;
759
762
  for (const page of pages) if (PAGE_RECIPES[page]) recipes.push([PAGE_RECIPES[page], findRecipe(PAGE_RECIPES[page]).template]);
760
- choices.push(`accueil : recette ${home} ; fiche produit : ${input.offers ? 'avec offres' : 'complète'} ; pages : ${pages.join(', ')}`);
763
+ choices.push(`accueil : recette ${home} ; fiche produit : ${avecOffres ? 'avec offres par paliers' : 'complète'} ; pages : ${pages.join(', ')}`);
761
764
  choices.push(hasImages ? `photos placées : ${[images.hero, ...pool].filter(Boolean).length}` : 'aucune photo fournie : héro typographique sur la couleur de marque, sections à photos remplacées (rien de vide)');
762
765
  if (hasImages && !hasLarge) notes.push('aucune photo large en dehors du héro (images.large, 1600 px de large ou plus) : pas de zoom au défilement, héro typographique sur les pages de marque');
763
766
 
@@ -821,7 +824,7 @@ export function buildStore({ catalog, store }, input) {
821
824
  }
822
825
 
823
826
  // The rest of the theme in the store's language, without the demo templates.
824
- for (const rel of DEMO_TEMPLATES) if (!input.offers || !rel.includes('offers')) if (!store.excluded(slug).includes(rel)) store.setExcluded(slug, rel, true);
827
+ for (const rel of DEMO_TEMPLATES) if (!store.excluded(slug).includes(rel)) store.setExcluded(slug, rel, true);
825
828
  let translated = 0;
826
829
  if (lang !== catalog.defaultLanguage) {
827
830
  for (const [rel, entry] of store.effectiveFiles(slug)) {
@@ -17,7 +17,7 @@ Règles d'or :
17
17
  - Partez d'un preset (sections et blocs) ou d'une recette : ils sont réglés par le designer du thème.
18
18
  - Les images ne peuvent pas être envoyées par le MCP : laissez les champs image vides, la check-list les liste. Si le marchand a déjà déposé ses images dans Contenu > Fichiers, utilisez shopify://shop_images/<nom-exact>.
19
19
  - Les produits, collections, menus et pages se créent dans l'administration Shopify ; le thème ne fait que les afficher. Utilisez les handles donnés par le marchand (ou lus avec un connecteur Shopify).
20
- - Honnêteté commerciale : pas de faux avis, faux chiffres, faux stock, compte à rebours qui redémarre, logos presse inventés.`,
20
+ - Une V1 est une MAQUETTE : écrivez des avis, des chiffres et des conditions plausibles pour qu'elle ressemble à une boutique finie, puis listez tout ce que vous avez inventé sous « Ce que j'ai inventé, à valider ». Le marchand corrige en une passe et remplace les avis par de vrais avant la mise en ligne.\n- Deux limites qui ne se négocient pas, même en maquette : aucun compte à rebours qui redémarre à l'infini, aucun stock simulé (pratiques commerciales trompeuses).`,
21
21
  },
22
22
 
23
23
  architecture: {
@@ -46,7 +46,7 @@ Règles d'or :
46
46
  - **Photos.** Une photo de qualité vaut mieux que trois moyennes. Les visuels d'exemple du thème ne doivent jamais partir en ligne.
47
47
  - **Animations.** Celles des presets suffisent. Un seul effet fort par page (zoom au défilement, cartes empilées, scrollytelling).
48
48
  - **Mobile d'abord.** Tailles mobiles des titres (size_mobile), stack_on_mobile, bannière avec image mobile dédiée si le visuel est large.
49
- - **Sobriété commerciale.** Pas de pop-up à l'arrivée, une seule pop-up au total, pas d'urgence inventée, pas de superlatifs sans preuve.`,
49
+ - **Sobriété commerciale.** Pas de pop-up à l'arrivée, une seule pop-up au total, pas de superlatifs sans preuve. Une offre de lancement ou un lot sont légitimes ; un compte à rebours qui redémarre et un stock simulé ne le sont pas.`,
50
50
  },
51
51
 
52
52
  couleurs: {
@@ -246,7 +246,7 @@ GUIDES.signatures = {
246
246
  - Comparatif / pourquoi nous : comparison, calculator (coût par usage), stats réels.
247
247
  - Landing de campagne : banner, countdown (vraie date), featured-product, comparison, FAQ.
248
248
 
249
- **Règles** : 7 à 10 sections par page, alterner visuel et texte, une section colorée sur trois, un seul effet fort par écran, jamais de faux chiffres ni de faux avis.`,
249
+ **Règles** : 7 à 10 sections par page, alterner visuel et texte, une section colorée sur trois, un seul effet fort par écran. Les avis et chiffres d'une maquette sont des exemples à valider : écrivez-les, puis déclarez-les.`,
250
250
  };
251
251
 
252
252
  export const GUIDE_TOPICS = Object.keys(GUIDES);
package/src/server.js CHANGED
@@ -42,7 +42,9 @@ Avant la première construction, posez UNE seule salve de questions — jamais d
42
42
  3. Une couleur de marque, un logo ? Des photos déjà déposées dans Shopify ?
43
43
  4. Vos vraies conditions : livraison, retours, garantie ?
44
44
 
45
- Terminez par : « ou dites-moi simplement "vas-y" et je construis avec ce que j'ai ». S'ils disent d'y aller, ou si le premier message contient déjà tout, construisez immédiatement sans rien demander.
45
+ Terminez par : « ou dites-moi simplement "vas-y" et je construis avec ce que j'ai ». S'ils disent d'y aller, construisez immédiatement.
46
+
47
+ Même quand le premier message semble complet, DEUX questions restent à poser avant de construire, parce que leurs réponses changent la page elle-même et qu'elles manquent presque toujours : les photos déjà déposées dans Shopify (sans elles, héro typographique et sections remplacées) et la collection principale (bouton du héro, meilleures ventes). Posez-les en une ligne, et construisez dès la réponse.
46
48
 
47
49
  ## 2. La V1 doit être une boutique, pas un squelette
48
50
 
@@ -50,7 +52,7 @@ Appelez build_store AVEC un paramètre copy le plus rempli possible. Une V1 qui
50
52
 
51
53
  ÉCRIVEZ LE CONTENU. Rédigez la promesse, le manifeste, les bénéfices, les étapes de fabrication, la FAQ, les valeurs, les pages d'aide (livraison, retours, garantie, paiement), les offres par paliers, et oui : des avis clients plausibles et un peu d'urgence honnête (une offre de lancement, un lot). C'est une MAQUETTE que le marchand valide, pas une boutique en ligne : mieux vaut un exemple concret qu'il corrige qu'un cadre vide qu'il doit remplir seul.
52
54
 
53
- Variez la structure : donnez une direction artistique (build_store direction) et, pour deux boutiques du même style, un paramètre variation différent. compose_page crée les pages que les recettes ne prévoient pas (ingrédients, lookbook, comparatif, guide cadeau, livraison, garantie).
55
+ La fiche produit part AVEC des offres par paliers (1 / 2 / 3 pièces, ou lot + cadeau) : c'est le défaut, écrivez-en les libellés et les remises, et rappelez au marchand de créer les réductions correspondantes dans Shopify.\n\nVariez la structure : donnez une direction artistique (build_store direction) et, pour deux boutiques du même style, un paramètre variation différent. compose_page crée les pages que les recettes ne prévoient pas (ingrédients, lookbook, comparatif, guide cadeau, livraison, garantie).
54
56
 
55
57
  ## 3. Déclarez TOUT ce que vous avez inventé
56
58
 
@@ -751,7 +753,7 @@ export function createServer(config) {
751
753
  home: z.enum(RECIPES.filter((recipe) => recipe.template === 'templates/index.json').map((recipe) => recipe.id)).optional().describe('Recette d’accueil (sinon celle du style)'),
752
754
  pages: z.array(z.enum(['a-propos', 'utilisation', 'contact', 'faq', 'suivi'])).optional().describe('Pages à créer (toutes par défaut) : a-propos = Notre histoire, utilisation = Comment utiliser'),
753
755
  direction: z.enum(Object.keys(DIRECTIONS)).optional().describe(`Direction artistique : ${Object.entries(DIRECTIONS).map(([id, direction]) => `${id} (${direction.label} : ${direction.for})`).join(' ; ')}. Déduite du style si absente`),
754
- offers: z.boolean().optional().describe('Fiche produit avec offres par paliers'),
756
+ offers: z.boolean().optional().describe('Fiche produit avec offres par paliers (lots, remises par quantité, cadeau). ACTIVÉ PAR DÉFAUT : passez false seulement si le marchand n’en veut pas. Le thème affiche les paliers, les réductions correspondantes se créent ensuite dans Shopify.'),
755
757
  collection: z.string().optional().describe('Handle de la collection principale (bouton du héro, meilleures ventes)'),
756
758
  collections: z.array(z.string()).optional().describe('Handles des collections à montrer (la première = principale). Sans eux, les listes montrent toutes les collections'),
757
759
  images: z
package/src/version.js CHANGED
@@ -1,3 +1,3 @@
1
1
  // Version du serveur MCP. Ici et dans package.json — les deux doivent être identiques
2
2
  // (npm test le vérifie), et rien d'autre ne la redéclare.
3
- export const VERSION = '1.2.1';
3
+ export const VERSION = '1.2.3';