Stack technique 2026+
Archive de conception. Cette page raconte ce qui etait vise le jour ou elle a ete ecrite, pas l'etat du code aujourd'hui. Ce qui a ete livre depuis est recense dans le README.
Archive de conception. Cette page raconte ce qui etait vise le jour ou elle a ete ecrite, pas l'etat du code aujourd'hui. Ce qui a ete livre depuis est recense dans le README.
← retour au README
4. Stack technique 2026+
Bloc 1 — Pattern de versionnage (v0.dev)
Technique : modèle « chat-as-branch » (une conversation = une branche) : chaque conversation crée une branche de thème, chaque message qui modifie des fichiers crée un snapshot (à la manière d'un commit).
Modèle de données : Conversation (1) → Message (n) →
ThemeVersion (n optionnels) ; chaque ThemeVersion porte
parentVersionId, themeFilesDiff (jsonpatch), metadata.
API V1 :
POST /api/branches/[id]/restore: remet les fichiers dans l'état du snapshot NPOST /api/branches/[id]/fork: nouvelle conversation depuis le snapshot NPOST /api/branches/[id]/publish: push vers le draft Shopify connecté
Stockage : V1 = snapshot complet en base (JSON Postgres), V2 = diffs jsonpatch avec compaction toutes les N versions (sinon 50 snapshots × 200 fichiers ≈ 10 MB).
Pièges : la restauration est destructive → snapshot automatique du travail
en cours avant. Calqué sur un git stash automatique.
Sources :
- v0 Docs FAQ
- Changelog v0, janvier 2026 : panneau Git intégré
- Cursor Background Agents
Bloc 2 — Boucle d'agent du Vercel AI SDK + Workflow DevKit
Technique : ToolLoopAgent (AI SDK v6) + Workflow DevKit (durabilité,
GA fin 2025).
Pattern :
TaskPrisma persisté ({id, conversationId, status, agentRunId, plan})POST /api/tasks/[id]/run→ encapsuleToolLoopAgentdans une fonction Workflow DevKit, renvoieagentRunIdimmédiatement- Streaming via
getWritable()(flux durable) → SSE consommé par l'UI ; une reconnexion reprend à partir de l'offset - Reprise après crash : rejeu déterministe offert par Workflow DevKit
(toute E/S passe par
step()outool()) stopWhen: [stepCountIs(40), hasToolCall("requestUserApproval")]pour l'humain dans la boucle (HITL)
Pièges : Workflow DevKit est en GA depuis peu (oct. 2025), surveiller les changements cassants sur les flux durables. Convention stricte : toute E/S externalisée.
Sources :
Bloc 3 — Éditeur Monaco
Technique : @monaco-editor/react (référence en 2026, 88 extraits Context7).
Bundle de 5–10 MB → chargement différé obligatoire via next/dynamic({ssr: false}).
Pattern :
const Editor = dynamic(() => import("@monaco-editor/react"), {
ssr: false,
})
// Multi-tab via prop `path` + saveViewState=true (cursor/scroll par fichier)
// Custom theme via useMonaco + monaco.editor.defineTheme (OKLch BoostEcom)
LSP Liquid : @shopify/theme-language-server-node (officiel),
exécuté dans une Vercel Function exposée en WebSocket (WebSocket pris en charge
par Vercel en 2025), connecté via monaco-languageclient (Typefox).
Pièges : bundle de 5–10 MB → découpage en chunks agressif, chargement
uniquement quand l'utilisateur ouvre le Workspace. Repli si les retours disent
« trop lourd » : CodeMirror 6 (300 KB) + @codemirror/lang-liquid.
Sources :
Bloc 3.5 — Serveurs MCP natifs de Shopify (découverte de la recherche)
Shopify a publié en open source 3 serveurs MCP officiels en 2026 (github.com/ Shopify/Shopify-AI-Toolkit, MIT). Aucun ne couvre notre besoin
(opérations marchand de niveau production), notre MCP maison reste donc
légitime, mais on peut composer :
| MCP officiel | Périmètre | Notre usage |
|---|---|---|
Dev MCP (shopify-dev-mcp) | Documentation + introspection du schéma GraphQL | ✅ Intégrer côté agents de développement BoostEcom (Cursor / Claude Code) : accélère notre productivité interne |
| Storefront MCP | Acheteur (search_catalog, lookup_catalog, get_product, cart, checkout) | 🔍 V2/Phase 2 (AI Operator côté acheteur) : fork comme base d'un assistant d'achat dans la boutique |
| Admin MCP (Winter '26) | Développeur (scaffolding d'app, opérations GraphQL, génération de code Admin/UI/Liquid/Hydrogen) | 🔍 Surveiller : Shopify pourrait l'étendre aux opérations marchand, on sera prêts à pivoter |
Notre MCP (src/app/api/mcp/[storeId]/register-tools.ts) couvre le manque
d'opérations marchand en production : opérer une boutique avec une auth
multi-tenant pour le CRUD pages/blogs/menus/clients/réductions. À garder
jusqu'à preuve du contraire côté Shopify.
Risque : Shopify pourrait publier plus tard un MCP standardisé d'opérations marchand (Winter '26+). Parade : l'encapsuler derrière notre interface d'outil, et s'aligner progressivement sur sa forme si elle émerge.
Bloc 4 — API Theme de Shopify
Technique : GraphQL Admin API 2025-10. REST est legacy depuis 2024-10, les nouvelles apps sont GraphQL uniquement depuis avril 2025.
Mutations clés :
themeCreate(name, source): clone Live ou DawnthemeFilesUpsert(themeId, files: [...]): lot de 50 maximum, job asynchronethemeFilesDelete,themeRename,themeDeletethemePublish(id): bascule atomique du live ← clic explicite
Requêtes : themes, theme(id), themeFiles(themeId).
Sandbox : thème draft = role: UNPUBLISHED. URL de preview =
https://{shop}.myshopify.com/?preview_theme_id={id} + cookie
_shopify_tm.
Scopes minimum : read_themes, write_themes,
unauthenticated_read_content.
Pièges :
- Limite de débit GraphQL en seau percé (1000 points de coût, recharge de 50/s) : file + backoff sur 429
- Limite de 20 thèmes par boutique → nettoyage automatique des drafts inactifs depuis plus de 30 jours ; pool de drafts pour paralléliser
- Demande d'exception requise pour
write_themessur une app publique (pas bloquant pour une custom app)
Sources :
- themeFilesUpsert
- Changelog de la gestion des thèmes et fichiers
- Migration REST → GraphQL obligatoire
Bloc 5 — Proxy de preview live
Technique : iframe directe avec ?preview_theme_id={id}. Shopify
n'envoie PAS de frame-ancestors sur le storefront public (seulement
sur l'admin).
Hot reload : utiliser @shopify/theme-hot-reload (npm, MIT,
officiel Shopify), sans réinventer le mécanisme. La lib gère :
- l'équivalent d'une surveillance du système de fichiers côté serveur (notre push
themeFilesUpsert) - l'injection d'un script basé sur SSE dans le draft
- un rechargement intelligent par section (seule la section est rendue à nouveau, pas toute la page) = une UX bien supérieure au rechargement complet
- le remplacement à chaud du CSS, instantané, sans recharger la page
Pattern :
- Importer
@shopify/theme-hot-reloaddans la Vercel Function proxy/api/preview/[storeId]/* - Encapsuler leur endpoint SSE dans notre flux
- Sur
themeFilesUpsertcôté workspace → diffusion d'un événement → la lib pousse la bonne mise à jour à l'iframe
Verrouiller la version exacte (lib en 0.0.x, API instable). Scope
unauthenticated_read_content requis (déjà présent dans nos custom apps
habituelles).
Pièges :
- Page de mot de passe des boutiques de développement → casse l'iframe.
Contournement : réécriture par proxy Next.js
/preview/:shop/:path*qui propage les cookies en same-origin - Cookie tiers
_shopify_tm: peut expirer ; même parade
Sources :
- Protection iframe de Shopify : admin seulement, pas le storefront
- Rechargement à chaud de
shopify theme dev(Shopify CLI) : confirme l'usage de SSE
Bloc 6 — UX de la file de tâches (Linear + Cursor)
Technique : modèle Agent Session de Linear combiné au **background agent
- git worktree** de Cursor. Persistance Prisma. Exécution = Workflow DevKit (cf. Bloc 2).
États : pending → in_progress → waiting_review → done | failed | cancelled (calqué sur Linear).
Schéma Prisma :
model Task {
id String @id @default(cuid())
storeId String
conversationId String?
title String
description String?
status TaskStatus
priority Int @default(0)
assigneeAgent String? // "atlas" | "maya" | "marco" | …
parentTaskId String?
dependsOnTaskIds String[]
plan Json? // AgentPlan steps
output Json? // run result
agentRunId String? // Workflow DevKit run ID
createdBy String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
completedAt DateTime?
}
enum TaskStatus {
PENDING IN_PROGRESS WAITING_REVIEW DONE FAILED CANCELLED
}
model TaskActivity {
id String @id @default(cuid())
taskId String
type String // "comment" | "tool_call" | "status_change"
payload Json
ts DateTime @default(now())
}
UI : panneau gauche du workspace, priorité par glisser-déposer, filtre par statut/agent, badge live « in_progress » avec indicateur de streaming.
Parallélisation : chaque tâche = un run Workflow isolé. État partagé via la base (pas en mémoire de processus).
Pièges : limite de 20 thèmes Shopify → au plus ~10 tâches parallèles avec isolation par draft. V1 = exécution séquentielle, V2 = parallèle avec un pool de drafts recyclés.
Sources :
Bloc 7 — Terminal dans le navigateur
Technique V1 : console en lecture seule (SSE des sorties des appels d'outils des agents, zéro infra, zéro coût).
Technique V2 : Vercel Sandbox (microVM Firecracker, $0.128 par heure CPU
en Pro). POST /api/sandbox/exec → lancement éphémère, exécution de la commande
(shopify theme check, shopify theme push --json), stdout/stderr diffusés
en SSE, arrêt forcé à 60 s.
Pas de WebContainers (StackBlitz) : licence opaque, dépendance externe, bundle client lourd, pas de système de fichiers partagé avec le backend Prisma.
Replis documentés :
- E2B (2e choix) : communauté plus large, adopté par des entreprises du Fortune 500, Firecracker aussi, sessions de 24 h (contre 5 h chez Vercel). Bascule si les quotas Vercel deviennent contraignants.
- Daytona (voie d'évolution V3) : seul à prendre en charge Computer Use en natif, démarrage à froid de 90 ms (contre 150 ms chez Vercel), sessions illimitées. Pour la V3, si on veut intégrer Computer Use dans le workspace (preview multi-segment réaliste, test du checkout de bout en bout).
Écartés : Modal (orienté Python, pas pertinent), le SDK CodeSandbox (tarification par sandbox inadaptée), Northflank/Beam auto-hébergés (charge d'exploitation disproportionnée).
Pièges : plafond d'heures CPU par organisation, chaque sandbox étiquetée
avec orgId pour le suivi de facturation. Un démarrage à froid Firecracker de
~1-2 s convient à un usage ponctuel, pas à l'interactif (V3 = Daytona ou
Fly.io Sprites si besoin).
Sources :
Suivant : data-model.md