[{"data":1,"prerenderedAt":1651},["ShallowReactive",2],{"docs-nav:fr":3,"docs:\u002Ffr\u002Fdocs\u002Fcli":189},[4],{"title":5,"path":6,"stem":7,"children":8,"page":52},"Fr","\u002Ffr","fr",[9],{"title":10,"path":11,"stem":12,"children":13},"Qu'est-ce que Fougere","\u002Ffr\u002Fdocs","fr\u002Fdocs\u002Findex",[14,15,19,23,27,31,53,78,123,148],{"title":10,"path":11,"stem":12},{"title":16,"path":17,"stem":18},"Démarrer","\u002Ffr\u002Fdocs\u002Fgetting-started","fr\u002Fdocs\u002F01.getting-started",{"title":20,"path":21,"stem":22},"Une app que vous avez déjà","\u002Ffr\u002Fdocs\u002Fexisting-app","fr\u002Fdocs\u002F02.existing-app",{"title":24,"path":25,"stem":26},"Apportez votre schéma","\u002Ffr\u002Fdocs\u002Fbring-your-schema","fr\u002Fdocs\u002F03.bring-your-schema",{"title":28,"path":29,"stem":30},"La CLI","\u002Ffr\u002Fdocs\u002Fcli","fr\u002Fdocs\u002F04.cli",{"title":32,"path":33,"stem":34,"children":35,"page":52},"Concepts","\u002Ffr\u002Fdocs\u002Fconcepts","fr\u002Fdocs\u002F2.concepts",[36,40,44,48],{"title":37,"path":38,"stem":39},"Philosophie","\u002Ffr\u002Fdocs\u002Fconcepts\u002Fphilosophy","fr\u002Fdocs\u002F2.concepts\u002F1.philosophy",{"title":41,"path":42,"stem":43},"La Frond","\u002Ffr\u002Fdocs\u002Fconcepts\u002Ffrond","fr\u002Fdocs\u002F2.concepts\u002F2.frond",{"title":45,"path":46,"stem":47},"Le chemin le plus court","\u002Ffr\u002Fdocs\u002Fconcepts\u002Fshortest-path","fr\u002Fdocs\u002F2.concepts\u002F3.shortest-path",{"title":49,"path":50,"stem":51},"Le socle","\u002Ffr\u002Fdocs\u002Fconcepts\u002Fthe-base","fr\u002Fdocs\u002F2.concepts\u002F4.the-base",false,{"title":54,"path":55,"stem":56,"children":57,"page":52},"Schéma","\u002Ffr\u002Fdocs\u002Fschema","fr\u002Fdocs\u002F3.schema",[58,62,66,70,74],{"title":59,"path":60,"stem":61},"Entités","\u002Ffr\u002Fdocs\u002Fschema\u002Fentities","fr\u002Fdocs\u002F3.schema\u002F1.entities",{"title":63,"path":64,"stem":65},"Vues","\u002Ffr\u002Fdocs\u002Fschema\u002Fviews","fr\u002Fdocs\u002F3.schema\u002F2.views",{"title":67,"path":68,"stem":69},"La carte d'identité","\u002Ffr\u002Fdocs\u002Fschema\u002Fcard","fr\u002Fdocs\u002F3.schema\u002F3.card",{"title":71,"path":72,"stem":73},"Standard Schema","\u002Ffr\u002Fdocs\u002Fschema\u002Fstandard-schema","fr\u002Fdocs\u002F3.schema\u002F4.standard-schema",{"title":75,"path":76,"stem":77},"Comment un schéma bouge","\u002Ffr\u002Fdocs\u002Fschema\u002Fevolution","fr\u002Fdocs\u002F3.schema\u002F5.evolution",{"title":79,"path":80,"stem":81,"children":82,"page":52},"Métier","\u002Ffr\u002Fdocs\u002Fbusiness","fr\u002Fdocs\u002F4.business",[83,87,91,95,99,103,107,111,115,119],{"title":84,"path":85,"stem":86},"Handlers","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fhandlers","fr\u002Fdocs\u002F4.business\u002F1.handlers",{"title":88,"path":89,"stem":90},"Les ports","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fports","fr\u002Fdocs\u002F4.business\u002F10.ports",{"title":92,"path":93,"stem":94},"Presenters","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fpresenters","fr\u002Fdocs\u002F4.business\u002F2.presenters",{"title":96,"path":97,"stem":98},"Collectors","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fcollectors","fr\u002Fdocs\u002F4.business\u002F3.collectors",{"title":100,"path":101,"stem":102},"Erreurs","\u002Ffr\u002Fdocs\u002Fbusiness\u002Ferrors","fr\u002Fdocs\u002F4.business\u002F4.errors",{"title":104,"path":105,"stem":106},"Seeds","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fseeds","fr\u002Fdocs\u002F4.business\u002F5.seeds",{"title":108,"path":109,"stem":110},"Les faits","\u002Ffr\u002Fdocs\u002Fbusiness\u002Ffacts","fr\u002Fdocs\u002F4.business\u002F6.facts",{"title":112,"path":113,"stem":114},"Le port Storage","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fstorage","fr\u002Fdocs\u002F4.business\u002F7.storage",{"title":116,"path":117,"stem":118},"Des écritures qui tiennent ou tombent ensemble","\u002Ffr\u002Fdocs\u002Fbusiness\u002Ftogether","fr\u002Fdocs\u002F4.business\u002F8.together",{"title":120,"path":121,"stem":122},"Les repositories","\u002Ffr\u002Fdocs\u002Fbusiness\u002Frepositories","fr\u002Fdocs\u002F4.business\u002F9.repositories",{"title":124,"path":125,"stem":126,"children":127,"page":52},"Client","\u002Ffr\u002Fdocs\u002Fclient","fr\u002Fdocs\u002F5.client",[128,132,136,140,144],{"title":129,"path":130,"stem":131},"Queries & commands","\u002Ffr\u002Fdocs\u002Fclient\u002Fqueries-commands","fr\u002Fdocs\u002F5.client\u002F1.queries-commands",{"title":133,"path":134,"stem":135},"Formulaires","\u002Ffr\u002Fdocs\u002Fclient\u002Fforms","fr\u002Fdocs\u002F5.client\u002F2.forms",{"title":137,"path":138,"stem":139},"Session","\u002Ffr\u002Fdocs\u002Fclient\u002Fsession","fr\u002Fdocs\u002F5.client\u002F3.session",{"title":141,"path":142,"stem":143},"invoke","\u002Ffr\u002Fdocs\u002Fclient\u002Finvoke","fr\u002Fdocs\u002F5.client\u002F4.invoke",{"title":145,"path":146,"stem":147},"Back-office","\u002Ffr\u002Fdocs\u002Fclient\u002Fadmin","fr\u002Fdocs\u002F5.client\u002F5.admin",{"title":149,"path":150,"stem":151,"children":152,"page":52},"Infrastructure","\u002Ffr\u002Fdocs\u002Finfra","fr\u002Fdocs\u002F6.infra",[153,157,161,165,169,173,177,181,185],{"title":154,"path":155,"stem":156},"Le gradient","\u002Ffr\u002Fdocs\u002Finfra\u002Fgradient","fr\u002Fdocs\u002F6.infra\u002F1.gradient",{"title":158,"path":159,"stem":160},"Surfaces — REST & GraphQL","\u002Ffr\u002Fdocs\u002Finfra\u002Fsurfaces","fr\u002Fdocs\u002F6.infra\u002F2.surfaces",{"title":162,"path":163,"stem":164},"Déploiement","\u002Ffr\u002Fdocs\u002Finfra\u002Fdeployment","fr\u002Fdocs\u002F6.infra\u002F3.deployment",{"title":166,"path":167,"stem":168},"Hôtes","\u002Ffr\u002Fdocs\u002Finfra\u002Fhosts","fr\u002Fdocs\u002F6.infra\u002F4.hosts",{"title":170,"path":171,"stem":172},"Les sources","\u002Ffr\u002Fdocs\u002Finfra\u002Fsources","fr\u002Fdocs\u002F6.infra\u002F5.sources",{"title":174,"path":175,"stem":176},"Le cycle de vie","\u002Ffr\u002Fdocs\u002Finfra\u002Flifecycle","fr\u002Fdocs\u002F6.infra\u002F6.lifecycle",{"title":178,"path":179,"stem":180},"L'identité entre Fronds","\u002Ffr\u002Fdocs\u002Finfra\u002Fidentity","fr\u002Fdocs\u002F6.infra\u002F7.identity",{"title":182,"path":183,"stem":184},"Observabilité","\u002Ffr\u002Fdocs\u002Finfra\u002Fobservability","fr\u002Fdocs\u002F6.infra\u002F8.observability",{"title":186,"path":187,"stem":188},"Tests","\u002Ffr\u002Fdocs\u002Finfra\u002Ftesting","fr\u002Fdocs\u002F6.infra\u002F9.testing",{"id":190,"title":28,"body":191,"description":1646,"extension":1647,"meta":1648,"navigation":526,"path":29,"seo":1649,"stem":30,"__hash__":1650},"docs_fr\u002Ffr\u002Fdocs\u002F04.cli.md",{"type":192,"value":193,"toc":1624},"minimark",[194,198,206,232,240,278,281,289,381,395,446,457,655,658,665,686,700,712,728,735,782,789,796,816,827,949,959,970,1079,1090,1109,1116,1123,1192,1203,1234,1239,1289,1303,1315,1322,1337,1344,1415,1426,1432,1444,1447,1453,1460,1467,1506,1530,1537,1544,1565,1573,1580,1595,1614,1620],[195,196,28],"h1",{"id":197},"la-cli",[199,200,201,205],"p",{},[202,203,204],"code",{},"@fougere\u002Fcli"," crée un workspace, héberge une Frond dans un processus séparé et appelle\nune opération depuis un shell. La CLI utilise elle-même des entités et des handlers ; ses\noptions sont donc validées à partir de leurs schémas.",[207,208,209],"blockquote",{},[199,210,211,215,216,219,220,223,224,227,228,231],{},[212,213,214],"strong",{},"Alpha."," Sur npm sous le tag ",[202,217,218],{},"alpha"," — ",[202,221,222],{},"npx fougere@alpha"," la lance sans installer,\n",[202,225,226],{},"npm create fougere"," l'entre directement sur ",[202,229,230],{},"new",". Les commandes et flags ci-dessous\nsont ce qui existe.",[233,234,236,239],"h2",{"id":235},"fougere-new-composer-un-workspace",[202,237,238],{},"fougere new"," — composer un workspace",[241,242,247],"pre",{"className":243,"code":244,"language":245,"meta":246,"style":246},"language-bash shiki shiki-themes material-theme-lighter github-light github-dark","fougere new shop --frond blog --app nuxt\n","bash","",[202,248,249],{"__ignoreMap":246},[250,251,254,258,262,265,269,272,275],"span",{"class":252,"line":253},"line",1,[250,255,257],{"class":256},"sbgvK","fougere",[250,259,261],{"class":260},"s_sjI"," new",[250,263,264],{"class":260}," shop",[250,266,268],{"class":267},"stzsN"," --frond",[250,270,271],{"class":260}," blog",[250,273,274],{"class":267}," --app",[250,276,277],{"class":260}," nuxt\n",[199,279,280],{},"La commande crée d'abord les Fronds, puis les apps qui les consomment. Elle produit un\nworkspace pnpm :",[241,282,287],{"className":283,"code":285,"language":286},[284],"language-text","shop\u002F\n  fougere.config.ts          ← db, auth, topologie\n  pnpm-workspace.yaml        ← packages: [fronds\u002F*, apps\u002F*]\n  fronds\u002Fblog\u002F               ← le domaine\n    entities\u002FPost.ts\n    handlers\u002FPostHandler.ts\n  apps\u002Fnuxt\u002F                 ← le consommateur\n    nuxt.config.ts\n    app\u002Fpages\u002Findex.vue\n","text",[202,288,285],{"__ignoreMap":246},[290,291,292,305],"table",{},[293,294,295],"thead",{},[296,297,298,302],"tr",{},[299,300,301],"th",{},"Flag",[299,303,304],{},"Ce qu'il fait",[306,307,308,323,333,343,357,371],"tbody",{},[296,309,310,316],{},[311,312,313],"td",{},[202,314,315],{},"--frond blog,api:catalog",[311,317,318,319,322],{},"les Fronds à ajouter — ",[202,320,321],{},"template:nom"," renomme ; le nom du template est le nom par défaut",[296,324,325,330],{},[311,326,327],{},[202,328,329],{},"--app nuxt:web",[311,331,332],{},"pareil, pour les apps",[296,334,335,340],{},[311,336,337],{},[202,338,339],{},"--bare",[311,341,342],{},"la coquille vide, rien de composé",[296,344,345,350],{},[311,346,347],{},[202,348,349],{},"--flat",[311,351,352,353,356],{},"un seul domaine : pas de ",[202,354,355],{},"fronds\u002F",", pas de workspace — la racine de l'app est la Frond",[296,358,359,364],{},[311,360,361],{},[202,362,363],{},"--local",[311,365,366,367,370],{},"lie ",[202,368,369],{},"@fougere\u002F*"," à un checkout local de Fougere (développement)",[296,372,373,378],{},[311,374,375],{},[202,376,377],{},"--force",[311,379,380],{},"écrase un dossier existant",[199,382,383,386,387,390,391,394],{},[212,384,385],{},"Arguments ou mode interactif."," Avec ",[202,388,389],{},"--frond"," et ",[202,392,393],{},"--app",", la commande n'affiche aucune\nquestion et peut être utilisée dans un script ou en CI. Sans ces options, elle demande les\ntemplates dans un TTY. Le mode interactif n'est pas disponible sans TTY.",[199,396,397,400,401,404,405,407,408,411,412,415,416,421,422,424,425,429,430,433,434,437,438,441,442,445],{},[212,398,399],{},"Structure à plat."," ",[202,402,403],{},"fougere new shop --flat --frond blog","\nécrit une app Nuxt dont la racine porte le domaine — pas de segment ",[202,406,355],{},", pas de\n",[202,409,410],{},"pnpm-workspace.yaml",", un seul ",[202,413,414],{},"pnpm install"," (",[417,418,420],"a",{"href":419},"\u002Ffr\u002Fdocs\u002Fgetting-started#un-seul-domaine-pas-de-fronds-du-tout","la forme à\nplat","). ",[202,423,393],{}," est refusé\navec lui : l'app ",[426,427,428],"em",{},"est"," la racine. Un deuxième domaine ira plus tard dans ",[202,431,432],{},"fronds\u002Fbilling\u002F","\net la Frond racine ne bouge pas. Le projet généré porte aussi un ",[202,435,436],{},"tsconfig.frond.json","\ndont le ",[202,439,440],{},"include"," nomme les dossiers de la convention. ",[202,443,444],{},"pnpm typecheck"," peut ainsi vérifier\nle domaine sans charger Nuxt.",[199,447,448,449,452,453,456],{},"La Frond générée contient une entité, deux vues dérivées (",[202,450,451],{},"NewPost"," pour l'entrée et\n",[202,454,455],{},"PostCard"," pour la liste) et une opération métier en plus du CRUD :",[241,458,462],{"className":459,"code":460,"language":461,"meta":246,"style":246},"language-ts shiki shiki-themes material-theme-lighter github-light github-dark","export class NewPost extends Post.pick('title', 'body') {}\n\nexport default class PostHandler extends Crud(Post) {\n  async create(input: NewPost): Promise\u003CPost> { … }\n\n  \u002F** La transition draft→published — une opération, pas une écriture de champ. *\u002F\n  async publish(id: string): Promise\u003CPost> { … }\n}\n","ts",[202,463,464,521,528,552,601,606,613,650],{"__ignoreMap":246},[250,465,466,470,474,477,480,484,488,492,495,499,502,504,507,510,513,515,518],{"class":252,"line":253},[250,467,469],{"class":468},"sVHd0","export",[250,471,473],{"class":472},"sbsja"," class",[250,475,476],{"class":256}," NewPost",[250,478,479],{"class":472}," extends",[250,481,483],{"class":482},"su5hD"," Post",[250,485,487],{"class":486},"sP7_E",".",[250,489,491],{"class":490},"sGLFI","pick",[250,493,494],{"class":482},"(",[250,496,498],{"class":497},"sjJ54","'",[250,500,501],{"class":260},"title",[250,503,498],{"class":497},[250,505,506],{"class":486},",",[250,508,509],{"class":497}," '",[250,511,512],{"class":260},"body",[250,514,498],{"class":497},[250,516,517],{"class":482},") ",[250,519,520],{"class":486},"{}\n",[250,522,524],{"class":252,"line":523},2,[250,525,527],{"emptyLinePlaceholder":526},true,"\n",[250,529,531,533,536,538,541,543,546,549],{"class":252,"line":530},3,[250,532,469],{"class":468},[250,534,535],{"class":468}," default",[250,537,473],{"class":472},[250,539,540],{"class":256}," PostHandler",[250,542,479],{"class":472},[250,544,545],{"class":490}," Crud",[250,547,548],{"class":482},"(Post) ",[250,550,551],{"class":486},"{\n",[250,553,555,558,562,564,568,572,574,577,579,582,585,588,591,594,598],{"class":252,"line":554},4,[250,556,557],{"class":472},"  async",[250,559,561],{"class":560},"sVXei"," create",[250,563,494],{"class":486},[250,565,567],{"class":566},"s99_P","input",[250,569,571],{"class":570},"smGrS",":",[250,573,476],{"class":256},[250,575,576],{"class":486},")",[250,578,571],{"class":570},[250,580,581],{"class":256}," Promise",[250,583,584],{"class":486},"\u003C",[250,586,587],{"class":256},"Post",[250,589,590],{"class":486},">",[250,592,593],{"class":486}," {",[250,595,597],{"class":596},"skxfh"," … ",[250,599,600],{"class":486},"}\n",[250,602,604],{"class":252,"line":603},5,[250,605,527],{"emptyLinePlaceholder":526},[250,607,609],{"class":252,"line":608},6,[250,610,612],{"class":611},"sutJx","  \u002F** La transition draft→published — une opération, pas une écriture de champ. *\u002F\n",[250,614,616,618,621,623,626,628,632,634,636,638,640,642,644,646,648],{"class":252,"line":615},7,[250,617,557],{"class":472},[250,619,620],{"class":560}," publish",[250,622,494],{"class":486},[250,624,625],{"class":566},"id",[250,627,571],{"class":570},[250,629,631],{"class":630},"sZMiF"," string",[250,633,576],{"class":486},[250,635,571],{"class":570},[250,637,581],{"class":256},[250,639,584],{"class":486},[250,641,587],{"class":256},[250,643,590],{"class":486},[250,645,593],{"class":486},[250,647,597],{"class":596},[250,649,600],{"class":486},[250,651,653],{"class":252,"line":652},8,[250,654,600],{"class":486},[199,656,657],{},"Les vues définissent les contrats d'entrée et de sortie de ces opérations.",[233,659,661,664],{"id":660},"fougere-serve-une-frond-son-propre-process",[202,662,663],{},"fougere serve"," — une Frond, son propre process",[241,666,668],{"className":243,"code":667,"language":245,"meta":246,"style":246},"fougere serve blog --port 4100\n",[202,669,670],{"__ignoreMap":246},[250,671,672,674,677,679,682],{"class":252,"line":253},[250,673,257],{"class":256},[250,675,676],{"class":260}," serve",[250,678,271],{"class":260},[250,680,681],{"class":267}," --port",[250,683,685],{"class":684},"srdBf"," 4100\n",[199,687,688,689,692,693,696,697,487],{},"Démarre cette Frond seule et l'expose en JSON-RPC sur ",[202,690,691],{},"POST \u002F_fougere\u002Fcall",". L'app qui la\nconsomme indique son adresse dans ",[202,694,695],{},"remotes:"," pour router les appels vers cet hôte. Voir\n",[417,698,699],{"href":155},"le gradient",[199,701,702,703,400,706,708,709,711],{},"Elle ne suit ",[212,704,705],{},"pas",[202,707,695],{}," elle-même : un hôte ",[426,710,428],{}," la Frond, il ne route pas vers\nl'extérieur.",[207,713,714],{},[199,715,716,719,720,723,724,727],{},[202,717,718],{},"serve()"," écoute ",[202,721,722],{},"127.0.0.1"," sauf si ",[202,725,726],{},"hosts"," dit autre chose : un récepteur lit\nl'identité sur le fil, donc le défaut le garde sur la machine et l'élargir est une\ndécision écrite.",[233,729,731,734],{"id":730},"fougere-call-appeler-une-opération",[202,732,733],{},"fougere call"," — appeler une opération",[241,736,738],{"className":243,"code":737,"language":245,"meta":246,"style":246},"fougere call post.list\nfougere call post.create --title \"Bonjour\" --body \"…\"\n",[202,739,740,750],{"__ignoreMap":246},[250,741,742,744,747],{"class":252,"line":253},[250,743,257],{"class":256},[250,745,746],{"class":260}," call",[250,748,749],{"class":260}," post.list\n",[250,751,752,754,756,759,762,765,768,771,774,776,779],{"class":252,"line":523},[250,753,257],{"class":256},[250,755,746],{"class":260},[250,757,758],{"class":260}," post.create",[250,760,761],{"class":267}," --title",[250,763,764],{"class":497}," \"",[250,766,767],{"class":260},"Bonjour",[250,769,770],{"class":497},"\"",[250,772,773],{"class":267}," --body",[250,775,764],{"class":497},[250,777,778],{"class":260},"…",[250,780,781],{"class":497},"\"\n",[199,783,784,785,788],{},"La commande utilise la même enveloppe, la même validation et les mêmes erreurs typées que\nles autres clients. Une erreur ",[202,786,787],{},"VALIDATION_FAILED"," conserve donc le format reçu par une\npage.",[233,790,792,795],{"id":791},"fougere-sync-consommer-une-frond-distante",[202,793,794],{},"fougere sync"," — consommer une Frond distante",[241,797,799],{"className":243,"code":798,"language":245,"meta":246,"style":246},"fougere sync blog --from http:\u002F\u002Fblog-service:4100\n",[202,800,801],{"__ignoreMap":246},[250,802,803,805,808,810,813],{"class":252,"line":253},[250,804,257],{"class":256},[250,806,807],{"class":260}," sync",[250,809,271],{"class":260},[250,811,812],{"class":267}," --from",[250,814,815],{"class":260}," http:\u002F\u002Fblog-service:4100\n",[199,817,818,819,822,823,826],{},"Demande ",[202,820,821],{},"rpc.discover"," à l'hôte et écrit localement les entités reconstruites depuis les\n",[417,824,825],{"href":68},"cartes"," qu'il renvoie :",[241,828,830],{"className":459,"code":829,"language":461,"meta":246,"style":246},"\u002F\u002F .fougere\u002Fremotes\u002Fblog\u002Fentities\u002FPost.ts — généré\nimport { Card } from '@fougere\u002Fschema';\n\nexport class Post extends Card.fromDescriptor\u003C{\n  id: string;\n  title: string;\n  createdAt: Date;\n}>({ \u002F* la carte, telle quelle *\u002F }).toSchema() {}\n",[202,831,832,837,863,867,887,899,910,922],{"__ignoreMap":246},[250,833,834],{"class":252,"line":253},[250,835,836],{"class":611},"\u002F\u002F .fougere\u002Fremotes\u002Fblog\u002Fentities\u002FPost.ts — généré\n",[250,838,839,842,844,847,850,853,855,858,860],{"class":252,"line":523},[250,840,841],{"class":468},"import",[250,843,593],{"class":486},[250,845,846],{"class":482}," Card",[250,848,849],{"class":486}," }",[250,851,852],{"class":468}," from",[250,854,509],{"class":497},[250,856,857],{"class":260},"@fougere\u002Fschema",[250,859,498],{"class":497},[250,861,862],{"class":486},";\n",[250,864,865],{"class":252,"line":530},[250,866,527],{"emptyLinePlaceholder":526},[250,868,869,871,873,875,877,879,881,884],{"class":252,"line":554},[250,870,469],{"class":468},[250,872,473],{"class":472},[250,874,483],{"class":256},[250,876,479],{"class":472},[250,878,846],{"class":482},[250,880,487],{"class":486},[250,882,883],{"class":490},"fromDescriptor",[250,885,886],{"class":486},"\u003C{\n",[250,888,889,893,895,897],{"class":252,"line":603},[250,890,892],{"class":891},"sucvu","  id",[250,894,571],{"class":570},[250,896,631],{"class":630},[250,898,862],{"class":486},[250,900,901,904,906,908],{"class":252,"line":608},[250,902,903],{"class":891},"  title",[250,905,571],{"class":570},[250,907,631],{"class":630},[250,909,862],{"class":486},[250,911,912,915,917,920],{"class":252,"line":615},[250,913,914],{"class":891},"  createdAt",[250,916,571],{"class":570},[250,918,919],{"class":256}," Date",[250,921,862],{"class":486},[250,923,924,927,929,932,935,937,939,941,944,947],{"class":252,"line":652},[250,925,926],{"class":486},"}>",[250,928,494],{"class":482},[250,930,931],{"class":486},"{",[250,933,934],{"class":611}," \u002F* la carte, telle quelle *\u002F",[250,936,849],{"class":486},[250,938,576],{"class":482},[250,940,487],{"class":486},[250,942,943],{"class":490},"toSchema",[250,945,946],{"class":482},"() ",[250,948,520],{"class":486},[199,950,951,952,954,955,958],{},"Une classe, comme celle qu'on aurait écrite à la main : ",[202,953,587],{}," est la valeur — un juge qui\nvalide localement, sans requête supplémentaire vers l'hôte — et le type d'une ligne qu'il\nrenvoie, si bien que ",[202,956,957],{},"post.titel"," ne compile pas. Les deux se lisent sur la même carte.",[199,960,961,962,965,966,969],{},"À côté, ",[202,963,964],{},"handlers\u002FPostHandler.ts"," énonce ce que la frond sert, pour qu'un consommateur\nécrive ",[202,967,968],{},"Facade\u003CPostHandler>"," sans détenir le code du handler :",[241,971,973],{"className":459,"code":972,"language":461,"meta":246,"style":246},"export interface PostHandler {\n  list(invocation?: Invocation): Promise\u003CPost[] & { total?: number; hasMore?: boolean }>;\n  findById(invocation?: Invocation): Promise\u003CPost | undefined>;\n}\n",[202,974,975,987,1043,1075],{"__ignoreMap":246},[250,976,977,979,982,984],{"class":252,"line":253},[250,978,469],{"class":468},[250,980,981],{"class":472}," interface",[250,983,540],{"class":256},[250,985,986],{"class":486}," {\n",[250,988,989,992,994,997,1000,1003,1005,1007,1009,1011,1013,1016,1019,1021,1024,1026,1029,1032,1035,1037,1040],{"class":252,"line":523},[250,990,991],{"class":560},"  list",[250,993,494],{"class":486},[250,995,996],{"class":566},"invocation",[250,998,999],{"class":570},"?:",[250,1001,1002],{"class":256}," Invocation",[250,1004,576],{"class":486},[250,1006,571],{"class":570},[250,1008,581],{"class":256},[250,1010,584],{"class":486},[250,1012,587],{"class":256},[250,1014,1015],{"class":482},"[] ",[250,1017,1018],{"class":570},"&",[250,1020,593],{"class":486},[250,1022,1023],{"class":891}," total",[250,1025,999],{"class":570},[250,1027,1028],{"class":630}," number",[250,1030,1031],{"class":486},";",[250,1033,1034],{"class":891}," hasMore",[250,1036,999],{"class":570},[250,1038,1039],{"class":630}," boolean",[250,1041,1042],{"class":486}," }>;\n",[250,1044,1045,1048,1050,1052,1054,1056,1058,1060,1062,1064,1066,1069,1072],{"class":252,"line":530},[250,1046,1047],{"class":560},"  findById",[250,1049,494],{"class":486},[250,1051,996],{"class":566},[250,1053,999],{"class":570},[250,1055,1002],{"class":256},[250,1057,576],{"class":486},[250,1059,571],{"class":570},[250,1061,581],{"class":256},[250,1063,584],{"class":486},[250,1065,587],{"class":256},[250,1067,1068],{"class":570}," |",[250,1070,1071],{"class":630}," undefined",[250,1073,1074],{"class":486},">;\n",[250,1076,1077],{"class":252,"line":554},[250,1078,600],{"class":486},[199,1080,1081,1082,1085,1086,1089],{},"La commande écrit aussi ",[202,1083,1084],{},".fougere\u002Fremotes.json",", que le module Nuxt lit pour aliaser\n",[202,1087,1088],{},"@fronds\u002Fblog",". Les pages utilisent ainsi le même chemin d'import pour une entité locale\nou distante.",[199,1091,1092,1093,1096,1097,1100,1101,1104,1105,1108],{},"La relancer ",[212,1094,1095],{},"supprime ce que l'hôte ne sert plus",". Le barrel perd son export tout seul,\nmais le fichier restait — et ",[202,1098,1099],{},"exports"," liste ",[202,1102,1103],{},"'.\u002Fentities\u002F*'"," en joker, si bien que\n",[202,1106,1107],{},"@fronds\u002Fblog\u002Fentities\u002FTicket.js"," résolvait encore vers une classe qui valide parfaitement\net dont plus rien ne répond derrière. Seuls les fichiers portant l'en-tête généré sont\nsupprimés ; ce que vous déposez vous-même dans ce dossier est laissé intact.",[199,1110,1111,1112,1115],{},"L'hôte renvoie les entités associées à une façade, et ",[212,1113,1114],{},"les faits que ses fronds\nannoncent",". Une entité qui n'est ni l'un ni l'autre n'est pas dans le résultat de\ndécouverte — une forme que personne n'expose et que personne n'a déclarée sortante reste\nchez elle.",[199,1117,1118,1119,1122],{},"Un fait n'a pas d'opération : il obtient une classe et aucune interface ",[202,1120,1121],{},"Handler"," à côté.",[241,1124,1126],{"className":459,"code":1125,"language":461,"meta":246,"style":246},"\u002F\u002F .fougere\u002Fremotes\u002Fblog\u002Fentities\u002FPostPublished.ts — généré\nexport class PostPublished extends Card.fromDescriptor\u003C{ id: string; title: string; at: Date }>(…).toSchema() {}\n",[202,1127,1128,1133],{"__ignoreMap":246},[250,1129,1130],{"class":252,"line":253},[250,1131,1132],{"class":611},"\u002F\u002F .fougere\u002Fremotes\u002Fblog\u002Fentities\u002FPostPublished.ts — généré\n",[250,1134,1135,1137,1139,1142,1144,1146,1148,1150,1153,1156,1158,1160,1162,1165,1167,1169,1171,1174,1176,1178,1181,1184,1186,1188,1190],{"class":252,"line":523},[250,1136,469],{"class":468},[250,1138,473],{"class":472},[250,1140,1141],{"class":256}," PostPublished",[250,1143,479],{"class":472},[250,1145,846],{"class":482},[250,1147,487],{"class":486},[250,1149,883],{"class":490},[250,1151,1152],{"class":486},"\u003C{",[250,1154,1155],{"class":891}," id",[250,1157,571],{"class":570},[250,1159,631],{"class":630},[250,1161,1031],{"class":486},[250,1163,1164],{"class":891}," title",[250,1166,571],{"class":570},[250,1168,631],{"class":630},[250,1170,1031],{"class":486},[250,1172,1173],{"class":891}," at",[250,1175,571],{"class":570},[250,1177,919],{"class":256},[250,1179,1180],{"class":486}," }>",[250,1182,1183],{"class":482},"(…)",[250,1185,487],{"class":486},[250,1187,943],{"class":490},[250,1189,946],{"class":482},[250,1191,520],{"class":486},[199,1193,1194,1195,1198,1199,1202],{},"Pour qu'un fait qui arrive soit jugé, réexportez cette classe dans une de vos propres\nfronds — le boot valide contre une entité d'une frond ",[212,1196,1197],{},"scannée",", et ",[202,1200,1201],{},".fougere\u002Fremotes\u002F","\nest un paquet, pas une frond :",[241,1204,1206],{"className":459,"code":1205,"language":461,"meta":246,"style":246},"\u002F\u002F fronds\u002Fsearch\u002Fentities\u002FPostPublished.ts\nexport { default } from '..\u002F..\u002F..\u002F.fougere\u002Fremotes\u002Fblog\u002Fentities\u002FPostPublished.js';\n",[202,1207,1208,1213],{"__ignoreMap":246},[250,1209,1210],{"class":252,"line":253},[250,1211,1212],{"class":611},"\u002F\u002F fronds\u002Fsearch\u002Fentities\u002FPostPublished.ts\n",[250,1214,1215,1217,1219,1221,1223,1225,1227,1230,1232],{"class":252,"line":523},[250,1216,469],{"class":468},[250,1218,593],{"class":486},[250,1220,535],{"class":468},[250,1222,849],{"class":486},[250,1224,852],{"class":468},[250,1226,509],{"class":497},[250,1228,1229],{"class":260},"..\u002F..\u002F..\u002F.fougere\u002Fremotes\u002Fblog\u002Fentities\u002FPostPublished.js",[250,1231,498],{"class":497},[250,1233,862],{"class":486},[1235,1236,1238],"h3",{"id":1237},"les-règles","Les règles",[290,1240,1241,1250],{},[293,1242,1243],{},[296,1244,1245,1247],{},[299,1246,202],{},[299,1248,1249],{},"ce que ça veut dire",[306,1251,1252,1269,1279],{},[296,1253,1254,1266],{},[311,1255,1256,1259,1260,1259,1263],{},[202,1257,1258],{},"directory-unreadable",", ",[202,1261,1262],{},"handler-parse-failed",[202,1264,1265],{},"heritage-unresolved",[311,1267,1268],{},"ce que le scan n'a pas pu faire — une règle sur une absence n'est fondée que si l'analyse atteste avoir regardé",[296,1270,1271,1276],{},[311,1272,1273],{},[202,1274,1275],{},"operation-unbound",[311,1277,1278],{},"une opération déclare des paramètres et n'a aucun plan de liaison : elle est servie, et elle n'en reçoit aucun",[296,1280,1281,1286],{},[311,1282,1283],{},[202,1284,1285],{},"cross-frond-import",[311,1287,1288],{},"un import relatif qui résout dans une autre frond",[199,1290,1291,1292,1295,1296,1299,1300,1302],{},"La dernière est un avertissement, pas un refus — ça résout aujourd'hui et l'app tourne. Ce\nqu'elle énonce, c'est qu'une ",[212,1293,1294],{},"contrainte de colocalisation tient l'application et que rien\nne la déclare"," : ",[202,1297,1298],{},"'..\u002F..\u002Fuser\u002Fentities\u002FUser.js'"," dit que ces deux dossiers sont voisins,\ndans une chaîne que le scan, la carte d'identité et ",[202,1301,695],{}," ignorent tous. Ça marche\njusqu'au jour où ce dossier n'est plus là, et ça casse alors comme un chemin de fichier,\npas comme un modèle.",[199,1304,1305,1308,1309,1314],{},[202,1306,1307],{},"'@fronds\u002Fuser\u002Fentities\u002FUser.js'"," énonce la même dépendance en termes que le modèle lit, et\nc'est la forme qu'écrit ",[417,1310,1312],{"href":1311},"#fougere-sync--consommer-une-frond-distante",[202,1313,794],{}," — elle\nsurvit donc au déménagement de la frond. Le nom résout pareil, que la frond soit locale ou\nsynchronisée.",[233,1316,1318,1321],{"id":1317},"fougere-check-ce-que-le-scan-na-pas-pu-faire",[202,1319,1320],{},"fougere check"," — ce que le scan n'a pas pu faire",[241,1323,1325],{"className":243,"code":1324,"language":245,"meta":246,"style":246},"fougere check                 # depuis une racine de projet ; --root en désigne une autre\n",[202,1326,1327],{"__ignoreMap":246},[250,1328,1329,1331,1334],{"class":252,"line":253},[250,1330,257],{"class":256},[250,1332,1333],{"class":260}," check",[250,1335,1336],{"class":611},"                 # depuis une racine de projet ; --root en désigne une autre\n",[199,1338,1339,1340,1343],{},"Il ",[212,1341,1342],{},"scanne sans booter",", donc il rend compte d'un projet qu'il ne sait pas démarrer.\nCinq règles aujourd'hui, chacune sous un nom stable partagé avec les diagnostics du scan :",[290,1345,1346,1355],{},[293,1347,1348],{},[296,1349,1350,1353],{},[299,1351,1352],{},"signalement",[299,1354,1249],{},[306,1356,1357,1374,1383,1393,1402],{},[296,1358,1359,1367],{},[311,1360,1361,1259,1363,1259,1365],{},[202,1362,1258],{},[202,1364,1262],{},[202,1366,1265],{},[311,1368,1369,1370,1373],{},"ce que le scan n'a pas pu faire — un dossier illisible, un handler qui ne parse pas, un ",[202,1371,1372],{},"extends"," qu'il n'a pas su suivre",[296,1375,1376,1380],{},[311,1377,1378],{},[202,1379,1275],{},[311,1381,1382],{},"une opération dont les paramètres n'ont aucun plan de liaison : elle est servie, et elle ne reçoit rien",[296,1384,1385,1390],{},[311,1386,1387],{},[202,1388,1389],{},"input-contract-ambiguous",[311,1391,1392],{},"deux paramètres pourraient être le contrat d'entrée, la provenance ne peut pas trancher — refusé plutôt que réglé par l'ordre des paramètres",[296,1394,1395,1399],{},[311,1396,1397],{},[202,1398,1285],{},[311,1400,1401],{},"un import relatif qui tombe dans une autre Frond — une contrainte de colocalisation que rien ne déclare, et qui tient jusqu'au jour où cette Frond n'est plus sur ce disque",[296,1403,1404,1409],{},[311,1405,1406],{},[202,1407,1408],{},"frond-holds-several-domains",[311,1410,1411,1412],{},"au-delà de six entités, le même seuil que ",[202,1413,1414],{},"fougere graph",[199,1416,1417,1418,1421,1422,1425],{},"Un signalement est ",[212,1419,1420],{},"bloquant"," ou ",[212,1423,1424],{},"avertissement",", et seul un bloquant sort en code non\nnul — c'est ce qui le rend utilisable en CI. Une classe de base non résolue sans opération\nest ordinaire, et un contrôle qui crie au loup cesse d'être lu.",[233,1427,1429,1431],{"id":1428},"fougere-graph-lire-le-modèle",[202,1430,1414],{}," — lire le modèle",[241,1433,1435],{"className":243,"code":1434,"language":245,"meta":246,"style":246},"fougere graph\n",[202,1436,1437],{"__ignoreMap":246},[250,1438,1439,1441],{"class":252,"line":253},[250,1440,257],{"class":256},[250,1442,1443],{"class":260}," graph\n",[199,1445,1446],{},"Affiche les entités, leurs références et le nombre de références entrantes. Au-delà de\nsix entités, la commande propose aussi des regroupements calculés depuis ce graphe :",[241,1448,1451],{"className":1449,"code":1450,"language":286},[284],"  Post → Author, Category (2 incoming)\n  Author\n",[202,1452,1450],{"__ignoreMap":246},[199,1454,1455,1456,1459],{},"La page ",[417,1457,1458],{"href":46},"chemin le plus court"," décrit les usages actuels\net envisagés de ce graphe.",[233,1461,1463,1466],{"id":1462},"fougere-devtools-ce-que-les-apps-en-marche-dispatchent",[202,1464,1465],{},"fougere devtools"," — ce que les apps en marche dispatchent",[241,1468,1470],{"className":243,"code":1469,"language":245,"meta":246,"style":246},"fougere devtools                      # toutes les adresses que ce projet déclare\nfougere devtools --url http:\u002F\u002F127.0.0.1:4100\nfougere devtools --json               # une page, puis on s'arrête\n",[202,1471,1472,1482,1494],{"__ignoreMap":246},[250,1473,1474,1476,1479],{"class":252,"line":253},[250,1475,257],{"class":256},[250,1477,1478],{"class":260}," devtools",[250,1480,1481],{"class":611},"                      # toutes les adresses que ce projet déclare\n",[250,1483,1484,1486,1488,1491],{"class":252,"line":523},[250,1485,257],{"class":256},[250,1487,1478],{"class":260},[250,1489,1490],{"class":267}," --url",[250,1492,1493],{"class":260}," http:\u002F\u002F127.0.0.1:4100\n",[250,1495,1496,1498,1500,1503],{"class":252,"line":530},[250,1497,257],{"class":256},[250,1499,1478],{"class":260},[250,1501,1502],{"class":267}," --json",[250,1504,1505],{"class":611},"               # une page, puis on s'arrête\n",[199,1507,1508,1509,1515,1516,1519,1520,1523,1524,1526,1527,487],{},"Lit le journal d'appels qu'une app tient quand elle a monté\n",[417,1510,1512],{"href":1511},"\u002Fdocs\u002Finfra\u002Fobservability",[202,1513,1514],{},"@fougere\u002Fcalls",", via ",[202,1517,1518],{},"\u002F_fougere\u002Fcall"," comme n'importe quel\nautre consommateur. ",[212,1521,1522],{},"C'est le lecteur qui tire"," : aucune app ne s'enregistre nulle part,\net une app démarrée seule ne dépend de rien. Le prix, c'est de connaître les adresses — et\nle projet les énonce déjà : ",[202,1525,695],{}," dit où part un appel, donc dit aussi où l'autre\nmoitié de cet appel peut être observée. À défaut, l'adresse par défaut est\n",[202,1528,1529],{},"http:\u002F\u002F127.0.0.1:3000",[199,1531,1532,1533,1536],{},"Une app qui n'a jamais installé le paquet répond ",[202,1534,1535],{},"Unknown rpc operation 'calls'. It serves discover.",", et cette adresse est rapportée comme un refus plutôt que comme un silence.",[233,1538,1540,1543],{"id":1539},"fougere-completion-la-complétion-du-shell",[202,1541,1542],{},"fougere completion"," — la complétion du shell",[241,1545,1547],{"className":243,"code":1546,"language":245,"meta":246,"style":246},"fougere completion zsh >> ~\u002F.zshrc\n",[202,1548,1549],{"__ignoreMap":246},[250,1550,1551,1553,1556,1559,1562],{"class":252,"line":253},[250,1552,257],{"class":256},[250,1554,1555],{"class":260}," completion",[250,1557,1558],{"class":260}," zsh",[250,1560,1561],{"class":570}," >>",[250,1563,1564],{"class":260}," ~\u002F.zshrc\n",[199,1566,1567,390,1570,1572],{},[202,1568,1569],{},"zsh",[202,1571,245],{}," ; le shell est détecté quand l'argument est absent. Les noms complétés\nsortent des mêmes entités que les commandes chevauchent : une nouvelle commande ne demande\npas une seconde liste.",[233,1574,1576,1579],{"id":1575},"fougere-build-frond-publier-les-entités-dune-frond",[202,1577,1578],{},"fougere build-frond"," — publier les entités d'une Frond",[241,1581,1583],{"className":243,"code":1582,"language":245,"meta":246,"style":246},"fougere build-frond blog\n",[202,1584,1585],{"__ignoreMap":246},[250,1586,1587,1589,1592],{"class":252,"line":253},[250,1588,257],{"class":256},[250,1590,1591],{"class":260}," build-frond",[250,1593,1594],{"class":260}," blog\n",[199,1596,1597,1598,1601,1602,1605,1606,1609,1610,487],{},"Compile ",[202,1599,1600],{},"fronds\u002Fblog\u002Fentities\u002F**"," vers ",[202,1603,1604],{},"dist\u002F"," avec les déclarations de types et configure\nle ",[202,1607,1608],{},"package.json"," de la Frond. Un consommateur situé dans un autre dépôt peut ensuite\ninstaller ce paquet. Voir ",[417,1611,1613],{"href":1612},"\u002Ffr\u002Fdocs\u002Finfra\u002Fgradient#o%C3%B9-le-code-vit","où le code vit",[199,1615,1616,1617,487],{},"Suite : ",[417,1618,1619],{"href":38},"La philosophie",[1621,1622,1623],"style",{},"html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .stzsN, html code.shiki .stzsN{--shiki-light:#91B859;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sVXei, html code.shiki .sVXei{--shiki-light:#E53935;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sZMiF, html code.shiki .sZMiF{--shiki-light:#E2931D;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sucvu, html code.shiki .sucvu{--shiki-light:#E53935;--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":246,"searchDepth":523,"depth":523,"links":1625},[1626,1628,1630,1632,1636,1638,1640,1642,1644],{"id":235,"depth":523,"text":1627},"fougere new — composer un workspace",{"id":660,"depth":523,"text":1629},"fougere serve — une Frond, son propre process",{"id":730,"depth":523,"text":1631},"fougere call — appeler une opération",{"id":791,"depth":523,"text":1633,"children":1634},"fougere sync — consommer une Frond distante",[1635],{"id":1237,"depth":530,"text":1238},{"id":1317,"depth":523,"text":1637},"fougere check — ce que le scan n'a pas pu faire",{"id":1428,"depth":523,"text":1639},"fougere graph — lire le modèle",{"id":1462,"depth":523,"text":1641},"fougere devtools — ce que les apps en marche dispatchent",{"id":1539,"depth":523,"text":1643},"fougere completion — la complétion du shell",{"id":1575,"depth":523,"text":1645},"fougere build-frond — publier les entités d'une Frond","fougere new, serve, call, sync, graph — composer un workspace, héberger une Frond, appeler une opération depuis un shell.","md",{},{"title":28,"description":1646},"QUfa26gTe3FnHK46KWbgaHhpGtm7P8Pl7TJi9GZTETM",1788598418931]