Créer et livrer une application omg.dev
Transformez la description du produit de l'utilisateur en un résultat fonctionnel et vérifié. Laissez le travail de configuration à l'agent. Ne posez que des questions sur les choix produits qui modifient sensiblement le résultat.
Posez une question par appel de question et mettez au plus une décision dedans. Une deuxième question dans le même appel n'est pas affichée à l'utilisateur sur tous les clients. Si l'utilisateur n'a pas dit ce que l'application doit faire, demandez-le en termes simples et attendez la réponse. Ne créez pas un produit factice à la place. Si une question expire, posez-la à nouveau une fois dans un message normal et terminez le tour.
Établir le projet
- Dans la Discussion Rapide, appelez
omg_create_projectune fois avec un nom court et descriptif. Définisseztemplatesurexpopour une application mobile Expo ou universelle. Le modèle Expo contient déjà un flux de tâches fonctionnel avec des données stockées sur le téléphone, Expo Router, Liquid Glass, les icônes Lucide, la prise en charge du web et la configuration EAS. Utilisez lerepo.cwdretourné pour chaque commande, édition, vérification et déploiement. Inspectezomg_list_reposavant de réessayer un appel de création incertain. - Dans une session Nouveau Projet, le répertoire courant est déjà le projet. Il contient Git, un README et ce skill. Ne créez pas un deuxième projet.
- Préservez
.git. N'écrasez pas un dossier existant et ne déplacez pas la Discussion Rapide actuelle dans le nouveau projet.
Choisir le chemin de livraison
-
Pour un site web, une application web ou une API, utilisez l'environnement d'exécution omg.dev pris en charge, sauf si l'utilisateur demande une autre plateforme. Dans un projet vierge, créez le modèle React omg.dev officiel avant d'écrire le code produit. Le répertoire courant contient déjà Git et les instructions omg.dev, alors générez dans un répertoire temporaire à l'intérieur, copiez la structure dans le projet et supprimez uniquement ce répertoire temporaire :
scaffold="$(mktemp -d .omg-web-scaffold-XXXXXX)" bunx --bun create-omg@latest "$scaffold" --template react-ts --no-install cp -a "$scaffold"/. . rm -rf "$scaffold" bun installCe modèle fournit
@omg-dev/vite-plugin,vibes-build, les fonctions serveur, la prise en charge de la base de données et l'analytique. Ne substituez pascreate-viteou une structure Vite écrite à la main. Lisezhttps://docs.omg.dev/llms.txtet uniquement les parties pertinentes dehttps://docs.omg.dev/llms-full.txtavant de choisir des packages supplémentaires ou des contrats API. -
Pour un jeu (course, arcade, puzzle, apprentissage pour enfants, mots, 3D), créez le projet avec
template: "web-game"et lisez.agents/skills/omg-web-game-builder/SKILL.mdau lieu de concevoir un moteur. Son étape 1 vient avant toute édition de code :bun run deven arrière-plan sur le port 5174, puisomg_expose_portavec le port 5174 et sansexpoGo, puis dites à l'utilisateur que l'aperçu est prêt dans la carte ci-dessous. Les étapes d'aperçu Expo de ce skill (port 8081,expoGo: true) ne s'appliquent pas à un jeu web. Utiliseztemplate: "expo-game"et.agents/skills/omg-game-builder/SKILL.mduniquement lorsque l'utilisateur demande un jeu à installer sur iPhone ou Android, ou nomme Expo ou une application native. -
Pour une application Expo, partez du modèle
expogéré et suivez "Application Expo : le chemin rapide" ci-dessous. Adaptez ses écrans et son magasin de données au lieu de reconstruire la configuration. Gardez les secrets dans les routes serveur hébergées. Une version native de production a besoin d'un serveur déployé à une origine sécurisée ; ne traitez pas un tunnel sandbox comme un hébergement de production. -
Utilisez un seul serveur Metro en direct pour Expo Web et Expo Go dans un Cloud Computer. Exposez son port via
omg_expose_port; ne partez pas du principe qu'Expo CLI global, Xcode, un simulateur ou des outils spécifiques à la machine existent. -
Lorsque l'application est compatible avec Expo Go,
omg_expose_portplace le lienexps://Expo Go sur une carte d'aperçu dans l'application omg.dev. Dites à l'utilisateur que l'aperçu est prêt et qu'il doit l'ouvrir à partir de la carte ci-dessous. Ne collez pas l'URLexps://brute dans votre réponse ; la carte l'affiche déjà. Ne la collez que là où l'utilisateur ne peut pas voir la carte, comme une réponse envoyée avecomg_send_to_originvers un canal de messagerie, ou lorsque l'utilisateur demande le lien. N'utilisez pas le tunnel Expo, l'exposition LAN,exp.directou ngrok. Si Expo Go ne peut pas charger un module natif requis, utilisez une version de développement lorsqu'elle est autorisée ou signalez cette limite clairement. -
TestFlight, la soumission à l'App Store, les services payants, les domaines et les comptes de production tiers sont des actions de livraison distinctes. Ne les effectuez que lorsque l'utilisateur les demande et que le compte requis est disponible. TestFlight nécessite le compte Expo de l'utilisateur et un compte Apple Developer payant, mais une version cloud EAS n'a pas besoin de Xcode ou d'un Mac dans le sandbox. Utilisez les flux de connexion pris en charge et ne demandez jamais de mots de passe ou de jetons dans le chat.
Application Expo : le chemin rapide
Un nouvel utilisateur attend. Le premier écran doit atteindre son téléphone en environ 3 minutes, avant tout travail de fonctionnalité. Suivez ces étapes dans l'ordre :
omg_create_projectavectemplate: "expo". Sinode_modulesmanque, exécutezbun installune fois.- Aperçu avant d'écrire du code. Appelez
omg_expose_portavec le port 8081 etexpoGo: true. Ensuite, exécutezbash scripts/start-expo-preview.sh <expoGo.proxyUrl> 8081depuis le répertoire du projet, avec un délai d'attente du shell de 240000 ms. Lorsqu'il afficheSandbox proxy answers: HTTP 200, présentez d'abord l'aperçu web : "Votre application est prête. La carte ci-dessous la montre en cours d'exécution, et elle fonctionne sur n'importe quel appareil." Mentionnez ensuite le téléphone en une phrase : "Pour l'essayer sur votre propre téléphone, appuyez sur Votre téléphone sur la carte." Lorsque le résultatomg_expose_portasimulatorAvailable: true, ajoutez une phrase de plus : "Vous pouvez aussi l'essayer sur un iPhone directement dans la carte : appuyez sur Simulateur." Ne promettez pas le simulateur lorsque ce champ est faux ou manquant. Ne collez pasexpoGo.url; la carte l'affiche. Metro recharge l'application à chaque sauvegarde, donc l'aperçu suit vos modifications à partir de maintenant. - Écrivez les écrans, en quelques modifications plus grandes plutôt qu'une petite modification par tour. Remplacez l'écran d'accueil du modèle dans
src/app/index.tsx; n'ajoutez pas une deuxième route d'index. - Exécutez
bun run typechecket corrigez ce qu'il signale. Il vérifie également les routes et échoue en cas de deuxième écran d'accueil ou de dossierapp/racine. Ensuite, exécutezbun run check:ui, ouvrez ses PNG, et corrigez ce qui ne va pas (voir l'étape 4 de la section Construction). N'écrivez pas de tests automatisés sauf si l'utilisateur le demande. - Déployez une fois avec
omg_deploy(voir ci-dessous). Les données restent sur le téléphone, il s'agit donc d'une version web statique. - Terminez avec
omg_ship.
Ne parcourez pas node_modules, ne récupérez pas de documentation et ne lisez pas le modèle fichier par fichier avant le premier aperçu : le résumé ci-dessous suffit. N'écrivez pas vos propres boucles de test de navigateur ou scripts de capture d'écran : bun run check:ui le fait. Si vous ne pouvez pas voir les images, lisez uniquement son rapport texte.
Le modèle :
src/app/index.tsx: l'écran d'accueil, et le seul fichier pour/. Remplacez son contenu par votre écran d'accueil. Gardez chaque écran danssrc/app/: Expo Router ignore un dossierapp/racine tant quesrc/appexiste. Pour les onglets, déplacez l'écran d'accueil verssrc/app/(tabs)/index.tsxet supprimezsrc/app/index.tsx, car les deux répondent à/et l'ancien gagne. Le fichier modèle a un en-tête, une entrée avec un bouton d'ajout, une liste avec bascule et suppression, une carte d'erreur et un bouton de rechargement. Les styles sont dans unStyleSheeten bas ; les constantes de thème sont en haut (INK,CORAL,BACKGROUND,SURFACE,SURFACE_BORDER).src/app/_layout.tsx: une pile Expo Router sans en-tête, à l'intérieur deKeyboardProvider. Un nouvel écran est un nouveau fichier danssrc/app/(stats.tsxest/stats). Naviguez avecrouter.push("/stats")ou<Link href="/stats">depuisexpo-router.src/lib/tasks.ts: les données, stockées sur le téléphone avec AsyncStorage (localStorage sur le web).tasksApi.list(),create(title),update(id, patch),remove(id). Gardez ce fichier. Pour chaque nouveau type d'élément, copiez sa forme avec sa propre clé de stockage.- Icônes :
lucide-react-native, par exemple<Plus color={CORAL} size={22} />. Surfaces en verre :GlassViewdepuisexpo-glass-effect. - Couleurs : définissez chaque constante de thème à partir de la conception avant de styliser les écrans. Les cartes, les lignes et les feuilles utilisent la couleur de surface de la conception. Le
SURFACEblanc translucide du modèle ne convient qu'à son starter clair ; laissé sur une conception sombre ou colorée, chaque carte devient blanche. UtilisezGlassViewuniquement là où la conception montre du verre dépoli. Sur Android, il n'affiche pas de verre, donnez-lui donc une couleur d'arrière-plan. - Zones de sécurité : encapsulez chaque écran dans
SafeAreaViewdepuisreact-native-safe-area-contextavecedges={["top", "bottom"]}, ou utilisezuseSafeAreaInsets(). N'importez jamaisSafeAreaViewdepuisreact-native: il est exclusif à iOS, donc sur Android, l'en-tête passe sous la barre d'état et la barre d'onglets sous la barre de gestes. - Clavier : placez les écrans avec une entrée de texte dans
KeyboardAwareScrollViewdepuissrc/lib/keyboard(bottomOffset={24},keyboardShouldPersistTaps="handled"), comme le fait le modèle. Pour un champ épinglé en bas, utilisezKeyboardStickyViewdepuis le même fichier. Importez-les depuissrc/lib/keyboard, jamais depuisreact-native-keyboard-controllerdirectement : son jumeau.web.tsxmaintient l'exportation web statique fonctionnelle. N'utilisez pasKeyboardAvoidingViewde React Native : sur iOS, l'écran bouge après le clavier, lentement.
Données : stockez-les sur le téléphone par défaut, avec le modèle tasks.ts. Utilisez des données hébergées uniquement lorsque l'utilisateur demande des comptes ou des données partagées entre personnes. Ajoutez ensuite la connexion avec @omg-dev/sdk et les collections .scoped("user") dans schema.ts. N'appelez jamais /api/... avec un fetch brut : une collection hébergée répond à un téléphone anonyme avec 401 Authentication required.
Pour les données hébergées, installez la dernière version de @omg-dev/sdk et déployez le backend avant de tester ses données partagées dans Metro. Gardez .omg/project.json dans le répertoire du projet. L'aperçu web hébergé utilise cette identité d'application enregistrée et connecte son propriétaire via le SDK. Utilisez <VibesAuthProvider> et les requêtes SDK. N'ajoutez pas de connexion d'aperçu séparée, ne transmettez pas de cookies de tableau de bord et ne remplacez pas les autorisations de l'application de l'utilisateur. Un téléphone physique a toujours besoin de la connexion normale de l'application et de l'origine du backend déployé.
Règles Metro : utilisez uniquement les ports 8081 à 8099, car les liens Expo Go fonctionnent uniquement dans cette plage. Démarrez Metro uniquement avec le script ; npx et ss ne sont pas installés sur chaque Ordinateur.
Blocs de construction (Expo)
Le modèle fournit des assistants testés dans src/kit/. Importez-les ; ne les réécrivez pas. Ils fonctionnent sur iOS, Android et le web. Chaque fichier commence par un commentaire qui montre son utilisation.
overlay.tsx:useConfirm()etuseSheet().<OverlayProvider>est déjà dans_layout.tsx. Utilisezif (await confirm({ title, destructive: true }))pour chaque suppression ou confirmation.Alert.alertavec des boutons ne fait rien sur le web. UtilisezuseSheet().open(node)pour les feuilles et les formulaires. N'empilez pas les composantsModal: le deuxième se dessine derrière le premier sur le web.ActionRow.tsx: une ligne pressable avec une action de suppression ou autre à côté. Un bouton imbriqué à l'intérieur d'une ligne pressable déclenche également la ligne sur le web.image.ts:await toPersistentImage(pickerAsset). Appelez le sélecteur avecbase64: true, quality: 0.5et stockez la chaîne retournée. Un URI de sélecteur sur le web est une URLblob:qui disparaît après un rechargement.use-timer.ts:usePersistedTimer(key, durationMs)avecstart,pause,resume,resetetformatClock. Il stocke l'heure de fin, donc un rechargement ne le réinitialise pas. Utilisez-le pour chaque minuteur ou compte à rebours.use-viewport.ts:useViewport()etuseIsWide(). Dans l'exportation web statique,useWindowDimensions()peut donner une largeur de 0 au premier rendu. PréférezflexetmaxWidth; n'utilisez le hook que lorsque vous avez besoin d'un nombre.
Données partagées entre personnes (une liste partagée, un échange, un groupe) : utilisez le chemin @omg-dev/sdk hébergé dans "Données" ci-dessus. N'écrivez pas de serveur local. Si un serveur local est inévitable, répondez OPTIONS et envoyez ces en-têtes sur chaque réponse : Access-Control-Allow-Origin avec l'Origin de la requête (ou *), Access-Control-Allow-Methods: GET,POST,PUT,PATCH,DELETE,OPTIONS, et Access-Control-Allow-Headers: content-type,authorization. Un PUT ou DELETE manquant échoue uniquement dans le navigateur.
Construction
- Convertissez la requête en une petite condition de réalisation observable. Faites des choix visuels et techniques raisonnables lorsque l'utilisateur ne les a pas spécifiés.
- Échafaudez à l'intérieur du répertoire du projet. Pour un modèle Expo géré, installez ses dépendances épinglées et préservez
.omg/template.json; ne le remplacez pas par un autre starter. Pour un projet vierge, installez les dépendances et la configuration documentées actuelles. N'installez pas une CLI omg.dev retirée et ne demandez pas à l'utilisateur des jetons d'infrastructure ; les outils d'exécution fournissent l'identifiant Cloud. - Implémentez le chemin réel. Si le produit a besoin de données partagées, d'authentification, de téléchargements ou de travail serveur, utilisez les API hébergées documentées et vérifiez la persistance et le contrôle d'accès. Ne remplacez pas le comportement partagé demandé par des données factices ou un stockage uniquement dans le navigateur.
- N'écrivez pas de tests automatisés sauf si l'utilisateur le demande. Vérifiez plutôt avec l'auto-vérification : exécutez
bun run typecheck, puisbun run check:ui. La vérification construit l'exportation web, démarre le scriptserveroubackendde l'application s'il y en a un, ouvre chaque route à 390x844 et enregistre un PNG par route dans.omg/ui-check/. Il signale les pages blanches, les limites d'erreur, les erreurs de console, les requêtes échouées, un serveur planté et les boutons ou liens qu'un autre élément recouvre (par exemple un bouton "Ajouter" sous une barre d'onglets). Ouvrez ensuite chaque PNG avec la visionneuse d'images et comparez-le avec la requête et toute référence de conception. Corrigez ce qui ne va pas et relancez la vérification jusqu'à ce que le rapport soit propre. Indiquez quelle surface vous avez vérifiée ; une exécution web n'est pas une preuve du comportement natif. - Mettez à jour le README avec l'objectif du produit, la commande d'exécution locale, l'architecture et les notes de livraison. Validez le code source fini localement afin que les sessions omg.dev ultérieures partent d'une base complète.
Connexion pour une application web hébergée
omg.dev possède la connexion pour les applications à <slug>.omgs.app. Ne construisez jamais de formulaire de connexion, de champ de mot de passe ou de votre propre magasin de session.
- Privé (par défaut) : chaque visiteur se connecte à omg.dev avant que l'application ne s'ouvre. L'application n'a besoin d'aucune interface utilisateur de connexion.
- Public avec connexion : utilisez ceci lorsque l'utilisateur souhaite une page d'accueil pour les visiteurs. Définissez l'application sur
publicavec...