Créer des canvases
Un canvas est une application navigateur côté client qui s'exécute dans une iframe en bac à sable à l'intérieur de PostHog.
Son code source réside dans PostHog — pas dans un repository — et tu le lis et l'écris via les
outils canvas-*. Ne sauvegarde jamais un canvas dans un fichier local ; publier via l'outil est ce qui
le sauvegarde.
Le travail sur canvas peut commencer par n'importe quelle tâche ordinaire. Un mode canvas dédié ou un canvas pré-créé n'est pas requis. Quand l'utilisateur demande un tableau, document, formulaire, visualisation, ou petite app qui doit vivre dans PostHog, traite cela comme une demande de canvas et suis cette skill.
Cette skill gère les canvases freeform (apps autonomes). Deux autres types de canvas existent : les canvases grid
(grilles de widgets, incluant le canvas home de l'utilisateur) et les canvases component (widgets réutilisables que les grilles placent). Quand la cible est une grille, un canvas home, un placement, ou un widget/composant réutilisable, charge composing-grid-canvases à la place — elle gère le ladder store search → configure → fork → build et la boucle de patch de layout. Créer le code source d'un composant utilise toujours les companions d'implémentation ci-dessous.
Résoudre le canvas cible
- Si la tâche nomme un id de canvas (les tâches initiées par canvas le font), c'est la cible. Ne crée pas une autre.
- Sinon, le canal cible est celui où la tâche a été créée — nommé dans le contexte de la tâche
(le bloc
channel_contextou les instructions de génération). Liste les canvases de ce canal aveccanvas-list(restreins avecchannel). Si l'un correspond clairement à ce que demande la requête — une itération antérieure du même tableau ou outil — construis dessus plutôt que de créer un quasi-doublon, et dis-le dans ta réponse pour que l'utilisateur sache où le résultat a atterri. - Uniquement quand rien d'existant ne correspond, crée un avec
canvas-createdans ce même canal, nommé avec un court titre descriptif tiré de la requête — jamais "Untitled canvas". - N'arpente jamais les canaux pour choisir une cible toi-même : utilise
channel-listuniquement pour résoudre un canal nommé par L'UTILISATEUR vers son id. Son listing place le canal personnel #me en premier, et #me n'est jamais une valeur par défaut — un canvas classé là est invisible pour tous les autres. Si la tâche ne nomme ni canvas ni canal, demande quel canal utiliser au lieu de deviner.
Charger les skills companions pour l'implémentation
Cette skill gère la sélection du canvas et le cycle de vie de l'authoring. Les skills companions contiennent les contrats d'implémentation. Charge chaque companion applicable avant d'écrire le code source :
building-react-quill-canvasespour les dashboards, boards de données, formulaires, outils, état de type application, ou tout ce qui doit avoir l'air natif à PostHog. Elle gère les imports autorisés, la composition Quill, le theming, les graphiques, les états de chargement et d'erreur, et le date picker.building-html-canvasespour les documents, articles, expériences ciblées, graphiques générés,<canvas>, ou WebGL où les composants d'application n'ajoutent aucune structure utile. Elle gère le markup sémantique, les APIs navigateur direct, le nettoyage d'animations, et le theming non-Quill.querying-canvas-datachaque fois que le canvas lit les données PostHog, capture des events, ou navigue. Elle gère le SDKph, la préférence saved-insight, les formes de résultat, les variables, les plages de dates, le chargement progressif par requête, et les déclarations de capacités de données. Charge-la aux côtés de l'une ou l'autre skill d'implémentation quand les données interviennent.validating-and-publishing-canvasespour chaque canvas. Elle gère la forme du projet, les déclarations de capacités, les diagnostics de validation, les publications sécurisées, les brouillons, les builds, et la récupération de conflits.
Mixe les approches d'implémentation quand approprié : React peut gérer le chrome d'application tandis que le code de graphiques navigateur gère un élément canvas, ou une page largement statique peut monter une île interactive.
C'est un jugement, pas un mode persiste — demande à l'utilisateur uniquement quand le choix change une exigence visible par l'utilisateur que tu ne peux pas déduire.
Images
Utilise les URLs de la bibliothèque médias publiques pour les images dans un canvas. Appelle posthog:media-images-list avec
purpose="canvas" d'abord et réutilise une image convenable quand l'une existe déjà.
Pour ajouter une image locale :
- Appelle
posthog:media-image-upload-startavec le nom du fichier etpurpose="canvas". - Depuis un shell, POST le fichier vers l'
upload_urlretourné comme donnée multipart form. Inclus chaque entréeform_fieldsretournée et place la partie fichier en dernier. - Appelle
posthog:media-image-upload-completeavec l'id retourné et utilise sonurlpermanent comme imagesrc. - Ajoute l'origine exacte de l'URL à
project.capabilities.network.origins. La validation du canvas vérifie cette déclaration, et l'artifact publié l'utilise dans sa Content Security Policy.
Les URLs de média du canvas sont publiques et ne nécessitent pas d'authentification. Ne charge jamais de secrets, credentials, données client, ou screenshots sensibles. Les images doivent être sous 4 MB et décoder en PNG, JPEG, GIF, WebP, AVIF, ou BMP. Ne base64-encode jamais les bytes d'image dans un appel d'outil.
Patterns de requête courants
Utilise ceux-ci comme exemples de routage, pas des templates fixes :
- Dashboard produit, board d'analytics web, ou explorateur de métriques : React + Quill plus querying de données.
- Checklist, formulaire, ou workflow léger : React + Quill, plus querying de données pour les lectures PostHog,
la capture d'events, ou la navigation. Pour une checklist ou runbook spécifiquement, commence par l'exemple travaillé
dans
building-react-quill-canvases(references/checklist-example.md) — progrès partagé d'équipe via les clésph.statepar étape. N'implique pas de persistance que les APIs disponibles ne fournissent pas. - Document ou rapport narratif : HTML pour une expérience de lecture largement statique ; React + Quill plus querying de données quand cela a besoin de données PostHog en direct, de filtres, ou d'interactions de type application.
- Graphique généré ou animation : HTML et APIs de graphiques navigateur. Ajoute React uniquement quand cela simplifie matériellement l'état d'application ou le chrome.
Quand la tâche porte un pattern demandé hérité comme dashboard ou web-analytics, applique la
forme correspondante ci-dessus. Le pattern est un indice ; la vraie requête de l'utilisateur reste autoritaire.
La boucle d'itération
- Lis le code source actuel et le pointeur de version avec
canvas-source-retrieve. Retienscurrent_version_id— ta publication doit être gardée par celui-ci. - Édite les fichiers du projet en utilisant les companions d'implémentation sélectionnés ci-dessus. Pour toute donnée PostHog
que le canvas affiche, suis
querying-canvas-data(saved insights chargées via le SDKph— ne fetch jamais ou ton propre client PostHog), rends chaque figure vérifiable — une métrique soutenue par insight lie son insight sauvegardé dans PostHog, une requête ad-hoc affiche la requête exacte qui a tourné, selon la section "Verifiability" de cette skill — et déclare chaque appelphdansproject.capabilities(ids courts d'insight danscapabilities.posthog.insights, events capturés danscaptureEvents,inlineQueries: truepour les requêtes ad-hoc, etagentRequests: truepourph.agent.request) — l'hôte renforce ceux-ci à l'exécution et la validation rejette les appels non déclarés. - Suis
validating-and-publishing-canvases: valide aveccanvas-validate-createaussi souvent que nécessaire et corrige chaque diagnostic de sévérité erreur. - Sauvegarde le projet — quel outil dépend de si le canvas est déjà en direct :
- Première version (
current_version_idest null) : publie le projet complet aveccanvas-publish-create, en passantexpected_current_version_id: null. - Déjà en direct (
current_version_idest défini) : étape le projet complet comme brouillon aveccanvas-draft-create— l'utilisateur prévisualise le brouillon et le promeut en direct. Publie ou promeut toi-même uniquement quand l'utilisateur a explicitement demandé de rendre le changement en direct. Suis la skillvalidating-and-publishing-canvasespour les diagnostics et la récupération de conflits.
- Première version (
- Attends le build — les brouillons et les publications mettent une file d'attente. Sonde
canvas-builds-retrieve(tous les quelques secondes, jusqu'à ~2 minutes) jusqu'à ce que ton build soitreadyoufailed. Surfailed, lis les diagnostics d'erreur du build, corrige le projet, et sauvegarde à nouveau — ne termine pas la tâche avec un build échoué.
Sauvegarde une fois par changement demandé, quand le canvas est prêt — pas après chaque micro-edit. Quand tu
as étapé un brouillon, termine ta réponse en disant qu'un brouillon est prêt à prévisualiser et à promouvoir ; la
skill validating-and-publishing-canvases couvre le flux brouillon → build → prévisualisation → promotion.
Termine ta réponse en nommant le canal dans lequel le canvas se trouve et en le liant avec le champ url que
les outils canvas retournent (canvas-create, canvas-list, et les réponses publish/source le portent).
Ce champ est le seul lien valide vers un canvas — ne le construis jamais toi-même ; les URLs devinées
(pages de projet, routes web) ne se résolvent pas.
Mémoire d'exécution et actions
-
ph.state— mémoire clé-valeur durable :ph.state.get(key, { scope }),ph.state.set(key, value, { scope })(une valeur null supprime la clé),ph.state.list({ scope }). La portée"user"(la valeur par défaut) est privée à chaque viewer ;"shared"est une valeur par canvas, visible à toute l'équipe. Déclare les portées que tu utilises danscapabilities.posthog.state. Les valeurs sont JSON, limitées à 64 KB sérialisés et 256 clés par portée — stocke les big data dans PostHog (insights, le warehouse) et référence-les. Ne mets jamais de secrets ou de PII de viewer dans state. -
ph.actions.invoke(verb, payload)— écris dans PostHog en tant que viewer. Déclare chaque verb danscapabilities.posthog.actions; les verbs non déclarés ou non enregistrés échouent la validation et l'hôte les refuse à l'exécution. Câble les actions aux gestes utilisateur explicites (un bouton que le viewer clique), jamais au chargement ou au rendu. Le registry est la source de vérité : liste-le avec l'outilcanvases-actions-retrieveet suis l'usagede chaque verb (forme payload/résultat, comportement, et la copie de confirmation qu'il justifie) avant de le câbler. -
ph.agent.request(prompt)— demande au agent d'authoring du canvas un changement, avec l'approbation du viewer. DéclareagentRequests: truedanscapabilities.posthog. Appelle-le uniquement à partir d'un clic direct ou d'une soumission de formulaire — l'hôte affiche le prompt exact et demande au viewer d'accepter avant de dépenser du calcul, et rejette les appels faits pendant le rendu, le montage, ou le polling. L'agent étape le changement comme brouillon pour que le créateur du canvas l'examine ; la requête d'un non-créateur est classée dans le fil de la tâche d'authoring au lieu de lancer un run.
Forme du projet source
- Garde
index.htmlcomme shell d'entrée retourné par l'outil source. src/canvas.tsxreste le composant d'entrée React conventionnel, mais peut importer TypeScript, TSX, JavaScript, JSON, SVG, CSS supplémentaires et des fichiers assets admis depuis le projet.- Les module workers autonomes peuvent être importés avec
./worker.ts?worker. Un worker ne doit pas importer un autre module local. - Utilise le flux de bibliothèque médias publiques ci-dessus pour les images. Les autres assets binaires appartiennent à la map
assetsdu projet en tant que contenu base64 avec un type content admis. WOFF/WOFF2, WebAssembly, et les assets octet-stream génériques sont supportés. - Garde la map de dépendance de plateforme exactement comme retournée. N'ajoute pas de packages npm ; les imports relatifs locaux sont des fichiers du projet, tandis que les imports nus restent limités à l'ensemble pinné par la plateforme.