oliverswitzer/lens — Objectif Produit

Créez et maintenez un objectif produit — un graphe JSON versionné avec git qui capture l'objectif, le cœur de boucle, les personas, les entretiens, les preuves, les hypothèses et les décisions, le tout compilé en un index.html autonome et annotable avec une vue des différences.

Qu'est-ce que lens — Objectif Produit ?

Le skill Lens permet de modéliser et suivre l'état d’un produit sous forme d’un graphe JSON versionné via git. Il structure les informations en nœuds (objectif, boucle principale, personas, entretiens, hypothèses, surfaces, concurrents, piliers de contenu, décisions) et en revendications (observées, avis de l’owner, hypothèses) avec un niveau de confiance calculé automatiquement. Le build produit un index.html que toute l’équipe peut ouvrir et annoter, et une vue des différences permet de visualiser ce qui a changé entre deux commits. Compatible avec tout assistant codant (Claude Code, Cursor, etc.) à condition d’avoir Node 20+ et git, sans dépendances supplémentaires. Idéal pour les équipes produit qui veulent centraliser la connaissance produit, suivre les preuves et prendre des décisions éclairées.

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/oliverswitzer/product-lens/tree/main/skills/lens

Installed? Explore more Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Objectif Produit (Lens)

Un objectif produit est un graphe JSON, <lens>/model.json, transformé en un <lens>/index.html autonome que chacun peut ouvrir et annoter. <lens> est le dossier dans lequel il est généré (par défaut docs/lens). <lens>/README.md documente les types de nœuds, les relations, la forme des revendications et les règles d'intégrité. La construction refuse un modèle qui enfreint une règle, donc une construction réussie est la première vérification.

Ce skill contient template/ (ce qui est copié dans un dépôt), scripts/ (aides pour les concurrents) et competitors.md. Il se trouve dans .claude/skills/lens/ du dépôt, ou ~/.claude/skills/lens/ en installation globale ; ci-dessous, $SKILL désigne ce dossier.

Prérequis : Node 20+ et git. Pas de package.json, pas de dépendances.

Mettre en place un nouvel objectif

  1. Choisir le dossier. Demandez à l'utilisateur où placer l'objectif ; par défaut docs/lens. Refusez d'écraser un model.json existant.

  2. Copier le modèle (tout sauf un index.html construit) :

    mkdir -p docs/lens && cp -R "$SKILL/template/." docs/lens/ && rm -f docs/lens/index.html
    echo '[]' > docs/lens/ids.lock.json      # les identifiants de départ ne sont pas les vôtres ; commencez le verrou vide
    
  3. Interviewez l'utilisateur, puis remplacez le modèle de départ. model.json contient un exemple fictif "Acme Notes" qui montre tous les types courants. Conservez sa structure, remplacez son contenu. Posez les questions un sujet à la fois, et donnez un brouillon concret à corriger plutôt qu'une question ouverte :

    • le nom du produit (title) et le nom du propriétaire (le nœud owner, id p-owner sauf s'il en préfère un autre ; son title s'affiche comme "Vue de " sur chaque revendication) ;
    • l'objectif en une phrase (purpose, une revendication view citant la source du propriétaire) ;
    • le cœur de boucle, 2 à 5 loop-step ordonnés ;
    • à qui il s'adresse (avatars, avec une carte de persona), et ce qui fait mal (problems) ;
    • les entretiens ou autres preuves déjà existants (source + nœuds person ; n'inventez jamais de citations ou d'horodatages — s'il n'y a pas de transcription, enregistrez-le comme le rapport du propriétaire) ;
    • ce qui a été livré (surface, shipped: true, avec une capture d'écran réelle) et ce qui n'est qu'une idée (shipped: false) ;
    • ce que les gens utilisent à la place (alternatives) ;
    • jusqu'à trois paris à prouver maintenant (nœuds hypothesis avec focus: 1|2|3). Tout ce que l'utilisateur dit sans preuve est une view (la sienne) ou une hypothesis ; rien n'est observed sans source ni at. Utilisez des noms génériques ("Personne A") sauf si l'utilisateur souhaite des noms réels dans un fichier pouvant être public.
  4. Nettoyer l'exemple. Supprimez assets/example.png une fois qu'aucun nœud ne le référence, et pointez les captures d'écran vers assets/surfaces/<surface-id>/<slug>.png. Les chemins code et adrs des surfaces sont relatifs à la racine du dépôt et doivent exister (pointez adrs vers l'endroit où le dépôt conserve les décisions, par ex. docs/adr/).

  5. Construire et tester :

    node docs/lens/build.mjs && node --test docs/lens/tests/*.test.mjs
    
  6. Visualiser. Les annotations sont stockées dans le navigateur par origine, servez donc le fichier plutôt que de l'ouvrir directement :

    python3 -m http.server 8767 --bind 127.0.0.1    # depuis la racine du dépôt
    open "http://127.0.0.1:8767/docs/lens/index.html"
    
  7. Suggérez une ligne .gitignore pour docs/lens/assets/ads/**/*.mp4 s'ils vont suivre les publicités des concurrents. Commitez model.json, ids.lock.json, index.html, assets/ et le reste du dossier, en suivant les règles de commit du dépôt.

Préparer le terrain

Lisez les nœuds pertinents, leurs revendications et leurs sources avant de demander quoi que ce soit au propriétaire. Donnez-lui une synthèse concrète à corriger. Pour une surface, vérifiez le code qu'elle nomme (code, adrs) lorsque son comportement est important ; un enregistrement de décision dit ce qui a été décidé, pas ce que le code fait aujourd'hui.

Ajouter des preuves

Chaque affirmation est une revendication avec kind, evidence et éventuellement next :

  • observed (Entendu / vu) : ce que quelqu'un a dit ou fait. Citez la source avec at (un horodatage de transcription, ou une section pour un document). Paraphrasez ou citez de près ; n'améliorez jamais une hésitation ("pourrait être utile").
  • view (Vue du propriétaire) : l'interprétation du propriétaire. Elle doit citer une source dont les people incluent le owner du modèle.
  • hypothesis (Non testé) : tout ce qui n'est pas testé, y compris les suggestions d'agent et les idées d'implémentation.
  • Une hypothèse est aussi un type de nœud : enregistrez chaque élément de preuve avec stance (supports ou contradicts) et at. Ne définissez jamais de confiance ; le compteur sur les hypothèses focus est calculé à partir de ces preuves lors de la prochaine construction (personnes interrogées distinctes qui la soutiennent ; un cran de moins si quelqu'un la contredit ; l'avis du propriétaire ne l'augmente jamais). Enregistrez les preuves contradictoires aussi facilement que les preuves favorables.
  • Donnez à chaque revendication faible un next : une question suffisamment spécifique à poser lors d'un appel. Elle apparaît dans Prochaine conversation.
  • Gardez qui a dit quoi : une idée que le propriétaire a soulevée et à laquelle quelqu'un a acquiescé n'est pas leur besoin.
  • Un nouvel entretien est une source avec date, people, locator et un court takeaways, cité par les revendications qu'il soutient. Laissez de côté les détails personnels sans rapport avec le produit. Archivez les transcriptions dans <lens>/sources/ uniquement si le dépôt est privé et que la personne interrogée a accepté.

Mettre à jour une surface (après l'avoir modifiée)

Lorsqu'une modification change l'apparence ou le comportement d'une surface, dans la même branche :

  1. Capturez le(s) état(s) modifié(s) depuis le produit en cours d'exécution dans <lens>/assets/surfaces/<surface-id>/<slug>.png (remplacez les anciens, conservez-en 1 à 4).
  2. Mettez à jour les entrées screenshots de la surface : caption, capturedAt (aujourd'hui), origin: "app", version. La page signale toute capture antérieure au dernier commit du code de la surface.
  3. Mettez à jour unique / situations si le comportement a changé, et code / adrs si les fichiers ont bougé.

Une toute nouvelle surface livrée est un nouveau nœud surface avec shipped: true, au moins une capture d'écran, des arêtes serves vers les problèmes qu'elle résout et des arêtes implements vers les étapes de la boucle.

Ajouter une idée (issue d'un brainstorming)

Une surface qui a été discutée mais pas construite est une surface avec shipped: false ; elle apparaît sous Idées, visuellement distincte. Donnez-lui unique (en tant que revendications hypothesis), situations, heard (ce que les gens ont dit, avec preuves), et des maquettes en tant que screenshots avec origin: "design". Quand elle est livrée, passez shipped à true et remplacez les maquettes par des captures réelles.

Ajouter un pilier de contenu ou une idée

Un thème marketing est un pillar ; un article concret, une vidéo ou un événement est un content-idea sous celui-ci, avec un format. Liez les piliers ou idées speaks-to aux avatars, les idées features les surfaces qu'elles montrent et like les concurrents qui utilisent déjà un angle similaire. Les idées et piliers sont Non testés jusqu'à ce que le contenu ait atteint les gens ; enregistrez ce qui s'est passé comme preuve sur une hypothèse about l'idée.

Ajouter un insight marché

Une tendance issue de recherches externes est un insight dans l'onglet Informations marché. Enregistrez l'article comme source Market research (éventuellement un instantané sous sources/), énoncez ses faits comme des findings observés, et gardez ce que cela signifie pour un avatar comme une vue ou une hypothèse, incluant une constatation sur les limites de la source. Liez-le bears-on à tout ce qu'il affecte.

Ajouter ou actualiser un concurrent

Suivez $SKILL/competitors.md : recherchez (vérifications de publicités dans un vrai navigateur, sans jamais contourner un mur), scripts/add-product.py, capture de publicités intermédiaire, scripts/apply-staged-ads.py (vérifie tout, puis applique en une étape), scripts/smoke-ads.mjs, puis commitez sans les .mp4. Comparez avec le produit à partir de l'objectif et des hypothèses ciblées, jamais de sa page marketing, et étiquetez cette comparaison Non testée.

Les résultats d'utilisabilité ne font pas partie du contenu de l'objectif

Les problèmes d'interaction (un bouton que personne ne trouve, un état de focus manquant) appartiennent au suivi des problèmes de l'équipe. Enregistrez-les là-bas et mentionnez uniquement leur signification produit, si elle existe, dans l'objectif.

Renommer ou supprimer

ids.lock.json enregistre chaque identifiant annotable issu de la dernière construction. Un identifiant qui disparaît doit être mappé dans les renamed de model.json ("old-id": "new-id", ou null s'il est supprimé intentionnellement), sinon la construction échoue. C'est ce qui permet de conserver les annotations existantes.

Modifier l'objectif lui-même

Toute modification sous components/ (ce qu'une vue affiche, le routage, la validation, la diff) commence par un test échouant dans <lens>/tests/ (node:test ; fixture partagée dans tests/fixture.mjs, noms fictifs uniquement). Gardez la logique dans des modules purs ; seul components/app.js touche au DOM. Exécutez ensuite les tests, puis vérifiez le même scénario dans un navigateur.

Visualiser la différence

Lorsque le propriétaire demande à voir, revoir ou visualiser ce qui a changé :

node docs/lens/diff.mjs [rev]          # HEAD par défaut ; affiche la liste des modifications
python3 -m http.server 8767 --bind 127.0.0.1
open "http://127.0.0.1:8767/docs/lens/index.html"

Les contours verts sont les éléments ajoutés et les jaunes sont les éléments modifiés ; les éléments supprimés sont listés en rouge dans la bannière. Chaque ligne ajoutée ou modifiée est liée à son élément. Les modifications sont appariées par identifiant, donc une seule revendication s'allume sans sa carte entière. Avant de commiter, effacez toujours et vérifiez :

node docs/lens/build.mjs
grep -c LENS-V2-DIFF docs/lens/index.html   # doit afficher 0

Reconstruire et vérifier

node docs/lens/build.mjs && node --test docs/lens/tests/*.test.mjs

Examinez ensuite les vues concernées dans le navigateur. Les annotations sont locales au navigateur pour l'origine ; exportez-les avant de changer. Terminez par le lien de l'objectif, ce qui a changé, les preuves et les limites.

Skills associés