Apps bouwen, voor agents

Hoe een agent een Laze-app bouwt die mensen willen gebruiken: ontwerpregels, de kit, vastzetten en delen, trunk-pushes en het eigen werk controleren.

Deze pagina is geschreven voor een AI-agent die wordt gevraagd een Laze-app te bouwen of te wijzigen. Lees dit vóór je eerste laze app create. Mensen beoordelen een app in de eerste vijf seconden: zorg dat hij af voelt, zet hem waar ze erom vroegen en controleer hem zelf voordat je zegt dat hij klaar is.

De workflow

  1. Maak hem in het gesprek waarin erom werd gevraagd:

    laze app create "Insights" --channel <channel>

    De app begint leeg, met een map die van jou is: bouw hem vanaf nul, beginnend bij index.html en daarna laze app push. --channel zet de app vast als tab van dat gesprek. Iedereen in dat gesprek, en hun agents, kan hem openen en erop voortbouwen (Bouwer). Geef de app een naam in woorden die mensen lezen, geen slug.

    Koppel de platformkit en client vanaf je pagina:

    <link rel="stylesheet" href="/_laze/theme.css" />
    <link rel="stylesheet" href="/_laze/kit.css" />
    <script src="/_laze/laze.js"></script>

    Slides, een deck of een presentatie zijn de enige uitzondering: die beginnen vanaf --template slides, het enige sjabloon. De bestanden daarvan zijn de eerste live versie van de app, die jij kunt aanpassen. Elke slide is één bestand in slides/, in volgorde vermeld in slides/deck.json; de README.md van het sjabloon legt uit hoe je slides toevoegt, herschikt en opmaakt. Het deck heeft een slidebalk, toetsenbordnavigatie, Presenteren op volledig scherm en knoppen voor PDF exporteren en HTML exporteren, dus bouw die niet opnieuw. Via MCP doet create_app met template: "slides" hetzelfde, en write_app_files wijzigt één slide tegelijk.

    Het slides-sjabloon is alleen voor een nieuw deck. Wanneer iemand bestanden stuurt die al een pagina of deck zijn (een HTML-export, een zip met index.html, een statische site), zet je ze neer zoals ze zijn: maak de app zonder --template, pak de bestanden uit in de map met index.html bovenaan, kopieer elk script dat via een CDN wordt geladen naar binnen en push. "Verplaats ze hierheen" of "zet dit hier" met een bijlage betekent precies dat: doe het, vraag niet wat het betekent.

  2. Een app die al bestaat gaat in een gesprek met een vastgezette tab, niet in een bericht met een link:

    laze app pin <app> --channel <channel>

    Met --role editor kunnen leden gegevens wijzigen maar niet de code, met --view-only kunnen ze alleen kijken. laze app pins <channel> toont de tabs. Zet een app die iemand heeft losgemaakt nooit opnieuw vast.

  3. Geef de data vorm in laze.app.json: één collectie per soort ding, met getypte velden en een paar voorbeeldrecords. Data staat in records, nooit in de code van de pagina. Een pagina waarin getallen, rijen of tekst hard-coded staan is fout: als de data verandert, moet de app veranderen zonder push.

  4. Wijzig de pagina en bekijk hem daarna lokaal voordat hij live gaat (zie Controleer je eigen werk).

  5. Push:

    laze app push -m "Added the pipeline board" --seed

    Elke push is meteen de live app. Er zijn geen concepten, branches of pull requests: apps zijn trunk-based. Schrijf het bericht als een gewone zin over wat er voor mensen is veranderd. --seed vult alleen collecties die nog geen records hebben.

  6. Ga terug wanneer een push verkeerd was: laze app versions en daarna laze app revert <version> -m "<why>". Dat is een nieuwe live versie; er gaat geen record verloren. De gitgeschiedenis in een app is hier alleen voor bedoeld.

Wie kan hem openen

ZichtbaarheidWie opent hem
BeperktMensen, agents en gesprekken waarmee hij is gedeeld of waarin hij is vastgezet, plus eigenaren en admins van de werkruimte
KanaalLeden van het kanaal van de app
InternIedereen in de werkruimte
OpenbaarIedereen met het adres

Een nieuwe app is Beperkt. Een app die in een gesprek is vastgezet, opent voor iedereen daar. Daarom is vastzetten meestal alles wat een teamapp nodig heeft om te worden gedeeld. Deel een app niet alleen met de persoon die erom vroeg als diegene er in een kanaal om vroeg: zet hem daar vast. Maak de toegang alleen breder met laze app access visibility internal|public wanneer daarom wordt gevraagd; de opdracht zegt wanneer een admin moet goedkeuren. laze app members laat zien wie hem nu kan openen. Controleer dit voordat je mensen vertelt dat de app klaar is.

Ontwerpregels

Begin bij waar de app over gaat, niet bij een lay-out. Vraag hoe iemand die om het onderwerp geeft het op een whiteboard zou tekenen, en bouw dat: een threat model is een aanvalskaart, een roadmap is een tijdlijn, een budget is een geldstroom, een proces is een diagram. Een pagina met stattegels en bulletlists leest als een rapport, en dat is de app die je wilt vermijden.

Wees heel visueel: gebruik motion graphics en flows waar het kan, en leid mensen stap voor stap tot ze het helemaal begrijpen. Schrijf nooit muren van tekst: waar je woorden nodig hebt, gebruik je eenvoudige, korte zinnen. Een app is er om mensen iets te laten begrijpen, niet voor je eigen braindump.

De Laze-kit komt van het platform (/_laze/theme.css, /_laze/kit.css, /_laze/laze.js). Het is een gereedschapskist, geen lay-out om in te vullen: gebruik de tokens en de controls die je nodig hebt, en zet je eigen CSS erbovenop in je eigen bestand. Kopieer de kit nooit naar de app.

  • Eerst visueel. Maak het beeld van het onderwerp de app zelf: inline SVG, canvas, een kaart, een tijdlijn, een diagram, iets waar mensen op klikken en dat ze verkennen. Geef het een eigen uitstraling, met je eigen lay-out en beweging op de tokens van de kit.
  • Eén taak per scherm. Het eerste scherm beantwoordt de vraag waarvoor de app bestaat. Zet een tweede taak op een tab (lz-tabs), niet onder de eerste.
  • De juiste vorm. Gebruik een tabel (lz-table) of een board (lz-board) wanneer mensen rijen scannen of verplaatsen, een stattegel (lz-stats, lz-stat-value) wanneer één getal centraal staat, een grafiek (lz-chart) voor getallen door de tijd heen en genummerde stappen (lz-steps) voor een korte reeks. Tekst langer dan drie regels hoort in een document, niet in een app.
  • Echte data. Toon de records die belangrijk zijn voor mensen, met hun echte namen en datums. Geen "Lorem", "Item 1" of placeholdergrafieken. Elke bewering op de pagina komt uit een record of een link.
  • Typeschaal. Eén paginatitel (lz-title), één regel eronder (lz-lede), sectietitels (lz-h2 of lz-card-title), bodytekst. Voeg geen andere groottes toe.
  • Afstand. Gebruik de klassen voor pagina (lz-page), kaart (lz-card lz-card-body) en grid (lz-grid, lz-row); ze houden het ritme van 12 tot 20 px aan. Stapel geen kaarten in kaarten.
  • Beide thema's. Kleuren komen alleen uit tokens (var(--color-fg), var(--color-bg-surface), var(--color-primary), var(--color-border) en de lz-badge-*-tinten). Een hexkleur breekt de donkere modus.
  • Smalle breedte. Apps openen in een zijpaneel van ongeveer 380 px breed. Geef tabelcellen data-label zodat rijen stapelen, en houd koppen op één regel.
  • Lege en foutstatussen. Een lege lijst zegt wat er zal verschijnen en hoe je het eerste item toevoegt. Een mislukte call toont Laze.fail(error), nooit een lege pagina.
  • Status als badges. Toon statussen met lz-badge en een tint (-success, -warning, -danger, -info, -primary), niet met gekleurde tekst.
  • Formulieren zitten niet in de weg. Zet "Nieuw item" achter een knop; de lijst is de hoofdinhoud.

Kitreferentie

NodigKlassen
Pagina en koplz-page, lz-header, lz-title, lz-lede
Lay-outlz-row, lz-grow, lz-grid, lz-stats
Kaartenlz-card, lz-card-body, lz-card-title, lz-h2
Tabellenlz-table-wrap, lz-table, lz-num (rechts uitgelijnde getallen)
Boardslz-board, lz-column, lz-column-head, lz-tile
Getallenlz-stat-value, lz-chart, lz-chart-col, lz-chart-track, lz-chart-bar, lz-chart-value, lz-chart-label
Stappenol.lz-steps met één li per stap
Controlslz-btn, lz-btn-primary, lz-btn-ghost, lz-input, lz-select, lz-textarea, lz-field, lz-form, lz-tabs, lz-tab
Statussenlz-badge (+ tint), lz-callout, lz-empty, lz-muted

Scripts laden alleen vanaf de eigen origin van de app: een CDN <script> wordt geweigerd, dus kopieer een bibliotheek die je nodig hebt naar de appmap. Als je een claude.ai artifact of een andere React-pagina porteert, compileer dan de JSX voordat je pusht (bijvoorbeeld npx esbuild app.jsx --bundle --minify --outfile=app.js) en link het gebouwde bestand. Babel in de browser werkt ook, maar laadt bij elke keer openen megabytes.

In het paginascript vermeldt, maakt, werkt en verwijdert Laze.records("<collection>") records, laadt Laze.subscribe opnieuw bij wijzigingen, bouwt Laze.h elementen en tekent Laze.mount ze.

Sneltoetsen

Laze geeft zijn eigen sneltoetsen door vanuit je app naar Laze, tenzij je app ze afhandelt. Zo kunnen mensen op Cmd+K drukken (Ctrl+K op Windows en Linux) om een app te verlaten zonder eerst buiten de app te klikken. De sneltoetsen die worden doorgegeven zijn Cmd+K, Cmd+[ en Cmd+], Cmd+1 tot en met Cmd+9, Cmd+Shift+A, Cmd+Shift+T, Cmd+Shift+M, Cmd+Shift+D, Cmd+. en Cmd+/, plus Alt+Up en Alt+Down buiten tekstvelden. Elke andere toets blijft in je app.

Als je een van deze voor je app wilt houden, handel je de toets af en roep je event.preventDefault() aan; Laze laat hem dan met rust:

document.addEventListener("keydown", (event) => {
  if ((event.metaKey || event.ctrlKey) && event.key === "k") {
    event.preventDefault();
    openSearch();
  }
});

Controleer je eigen werk

Bekijk elke wijziging voordat je hem pusht:

laze app serve --port 4173

Dit serveert je map op http://127.0.0.1:4173/ met de platformkit en de records van de live app, alleen-lezen. Er is een live versie nodig, dus voer eerst één keer laze app push uit. Open hem met je browsertool en maak een screenshot in beide thema's en op paneelbreedte, bijvoorbeeld:

npx -y playwright install chromium   # once
npx -y playwright screenshot --viewport-size=1100,800 http://127.0.0.1:4173/ light.png
npx -y playwright screenshot --viewport-size=1100,800 "http://127.0.0.1:4173/?theme=dark" dark.png
npx -y playwright screenshot --viewport-size=390,800 http://127.0.0.1:4173/ narrow.png

Bekijk elke afbeelding. Repareer tekst die overloopt, kolommen die niet passen, kleuren die verdwijnen in de donkere modus en alles waar nog "demo" staat.

Voordat je de app post:

  • Hij is vastgezet waar erom werd gevraagd, en laze app members vermeldt de mensen die hem moeten kunnen openen.
  • Het eerste scherm beantwoordt het verzoek zonder scrollen.
  • Screenshots in licht, donker en 390 px zien er af uit.
  • Je bericht geeft de naam van de app en één regel over wat hij doet. De tab in het gesprek is de link.

Vraag het als je twijfelt

Stel de persoon één korte vraag in plaats van het verkeerde te bouwen. Wacht niet op een "go" voor stappen waar al om is gevraagd: als ze om een app in dit kanaal vroegen, maak hem daar, zet hem vast en vertel het ze.