Zo werkt het
Je schrijft een stukje C#. Wat dat teruggeeft, staat binnen een paar seconden online op een openbaar adres, via HTTPS. Hier staat alles, in de volgorde waarin je het tegenkomt.
Wat een lambda is
Een lambda is een snippet die een GenHTTP-handler teruggeeft. Het platform compileert hem, laadt hem en hangt wat hij teruggeeft onder je eigen adres. Er is geen project, geen buildbestand en geen using nodig. Alle GenHTTP-modules zijn al voor je geïmporteerd.
return Content.From(Resource.FromString("hello"));
Dat is een complete lambda. Gedeployd beantwoordt hij op een eigen adres, vernoemd naar zijn sleutel, zoals your-key.genhttp.run, elk request met het woord hello.
De snippet bestaat uit statements, niet uit een class. Het laatste wat hij doet, is iets teruggeven dat requests kan afhandelen: een handler, of een builder daarvoor.
Je eerste lambda
- 1Klik op Lambda aanmaken. Je krijgt een openbaar adres en een editorsleutel. De sleutel is de enige weg terug, dus bewaar hem goed. Niemand kan hem voor je herstellen.
- 2Je komt terecht in het dashboard, waar als eerste versie al een kleine REST-service klaarstaat. Dat is maar een beginpunt.
- 3Geef de editorsleutel aan een agent en vertel wat hij moet bouwen. Hij schrijft nieuwe versies via MCP. Of open Code en schrijf het zelf: Controleren compileert zonder iets op te slaan en laat zien wat de compiler ervan vindt, met bestand en regel.
- 4Klik op Deployen. Nu staat hij online. Tot dan is er niets bereikbaar. Opnieuw deployen verlengt hoe lang hij online blijft.
Het dashboard
De editorlink opent geen tekstvak maar een dashboard. De meeste code hier schrijven agents, dus het eerste wat je ziet, is hoe het met je lambda gaat. In de zijbalk staat de lambda zelf: of hij online is, zijn adres, en een knop als er een nieuwere versie klaarstaat om online te gaan. Daaronder staan de onderdelen. Wat je zelden doet, zoals het adres wijzigen of de lambda verwijderen, zit daar achter het menu ⋯.
- Overzicht
- Wat de app is, of hij online is, hoeveel requests hij vandaag had en hoeveel daarvan misgingen, de laatste wijziging, en hoeveel ruimte er nog over is.
- Documentatie
- Wat de app is, voor wie hij is en waarom, en waarom hij gebouwd is zoals hij is – geschreven door agents, bewaard bij elke versie.
- Aanpassen
- Zeg wat er anders moet, en de agent op deze server doet het terwijl jij meekijkt. Hij probeert de wijziging uit in een concept – een kopie met een eigen adres – en zet het online zodra het werkt. Zet Online zetten als het klaar is uit als je het concept eerst zelf wilt uitproberen. Hij werkt alleen aan je app: een verzoek dat er niets mee te maken heeft, of dat schade moet aanrichten, wijst hij af, en hij zegt waarom.
- Concepten
- Wijzigingen die worden uitgeprobeerd voordat ze online gaan, elk op een eigen adres en met eigen testdata. Open je een concept, dan heeft het zijn eigen code, testdata en logs. Het onderdeel verschijnt zodra er een concept is.
- Data
- Wat de lambda bewaart terwijl hij draait, gedeeld door elke versie: de database, de workspace en de sleutels en wachtwoorden, elk met een eigen tabblad. Bekijk de tabellen en bestanden, upload bestanden, stel sleutels en wachtwoorden in of zet een soort aan of uit. De eenvoudige weergave toont het zodra de app iets bewaart.
- Versies
- Wat elke versie veranderde en wat er gevraagd werd, en het verschil met de vorige. Van hieruit deploy je of zet je een versie terug, en vanuit elke versie kun je een concept starten.
- Deployments
- Wat wanneer online stond, en waardoor het offline ging.
- Statistieken
- Requests, fouten, responstijden en de meest opgevraagde paden, over het afgelopen uur of de afgelopen dag.
- Logs
- Requests, output en de stacktrace van alles wat misging, live.
- Code
- Elk bestand van een versie, de code en de resources, in een boom naast de editor – met hoeveel ruimte ze innemen en of het publiek erbij kan. Kies erboven een oudere versie om die te lezen. Controleren compileert, Opslaan maakt een versie, Deployen zet hem online. In een concept bewaart Opslaan de code in het concept en toont die op het adres van het concept.
Ctrl-Sslaat op;F12springt naar een declaratie. - Tests
- Hoe de app automatisch getest wordt, met de scripts en testdata daarvoor. Alleen in de volledige weergave.
Elk onderdeel werkt hetzelfde: een titel, een ⓘ met uitleg, acties rechts en, als er meer dan één weergave is, een rij tabs eronder. De volledige weergave deelt de onderdelen in groepen in: hoe mensen hem vinden, waar een wijziging gemaakt wordt, de versies en de data, en hoe hij draait.
Het verkeer en de logs staan in het geheugen. Ze zijn om mee te kijken, niet om te bewaren: na een herstart van de server beginnen ze opnieuw. Versies en de deploygeschiedenis worden wel opgeslagen.
Uitleggen waarom
Een versie is de code, plus eventueel twee notities: de specificatie (wat de gebruiker wil en waarom, zo veel mogelijk in eigen woorden) en de wijziging (één regel over wat de versie doet). Ze staan naast de diff in de versiegeschiedenis. Zo blijft het waarom bewaard naast het wat, voor jou en voor de volgende agent die de geschiedenis leest voordat hij iets verandert.
POST /api/v1/lambdas/{editorKey}/versions { "files": [ { "name": "lambda.cs", "code": "..." } ], "specification": "Een gastenboek dat mensen kunnen tekenen; berichten moeten een herstart overleven", "change": "Bewaart berichten in de database, zodat ze een herstart overleven" }
Agents geven dezelfde twee velden mee aan write_code. In Code wordt bij het opslaan om de wijziging gevraagd. Beide zijn optioneel. Een lange specificatie wordt afgekapt op 4000 tekens en een wijziging op 500, in plaats van geweigerd. Een concept heeft zijn eigen twee, en de versie waarin het wordt samengevoegd, neemt ze over.
Documentatie en tests
Bij elke versie hoort, naast het programma, wat erover geschreven is: de documentatie – wat de app is, voor wie hij is en waarom, en waarom hij gebouwd is zoals hij is – en de tests: hoe je automatisch controleert dat hij werkt, met de scripts en testdata daarvoor. Agents schrijven ze bij een nieuwe lambda en houden ze bij met elke wijziging. De volgende agent die de lambda aanpast, leest ze eerst, zodat hij weet waar de app voor is en wat moet blijven werken – wat de code alleen niet vertelt.
- docs/product.md
- wat de app is, voor wie hij is, wat mensen ermee doen en waarom
- docs/decisions.md
- de technische beslissingen, en waarom ze genomen zijn
- tests/README.md
- hoe de app automatisch getest wordt, en hoe je de tests uitvoert
- tests/…
- de scripts en testdata die de tests gebruiken
Het zijn bestanden van de code van de versie zoals alle andere, in de mappen docs en tests: de geschiedenis laat zien wat een versie erin veranderde, terugzetten haalt de documentatie terug die voor die versie gold, en een concept heeft een eigen kopie die met het concept mee online gaat. Ze worden nooit gecompileerd en nooit geserveerd, en tellen mee voor de ruimte die een versie mag innemen.
In het dashboard toont Documentatie de pagina's om te lezen, en Tests hoe de app getest wordt en de bestanden ernaast; de versie kies je net als bij de bestanden. Je kunt een pagina daar ook bewerken; dat slaat de volgende versie op. De eenvoudige weergave noemt de documentatie Over de app en toont alleen waar de app voor is – wil je dat verbeteren, zeg het dan tegen de agent.
Ze worden geschreven in de taal die je met de agent gebruikt, voor wie de app hierna aanpast – een mens of een agent. Geen kopie van de code: waar hij voor is, en waarom.
Veilig aanpassen
Een versie verandert nooit meer als hij eenmaal is opgeslagen, en juist daardoor is elke versie het bewaren waard: je kunt ze allemaal vergelijken en precies zoals ze waren weer online zetten. Wil je een lambda aanpassen die mensen gebruiken, probeer de wijziging dan eerst uit in een concept.
- 1Start het vanuit een willekeurige versie onder Versies, of laat de agent er een starten. Het is een kopie van de code en de resources van die versie, met de documentatie en tests erbij, en van de data van de lambda.
- 2Pas het zo vaak aan als nodig, in Code of door het aan de agent te vragen. De voorvertoning draait op een eigen adres,
/features/…/, met eigen testdata. Bezoekers van de lambda zien er niets van, en niets wat het wegschrijft, komt in de data van de lambda terecht. - 3Klik op Online zetten zodra het goed is: het wordt de volgende versie, met zijn notities, en gaat online. Het concept verdwijnt dan, met zijn voorvertoning en zijn testdata.
POST /api/v1/lambdas/{editorKey}/features { "name": "Ranglijst" } PUT /api/v1/lambdas/{editorKey}/features/{feature}/files?deploy=true POST /api/v1/lambdas/{editorKey}/features/{feature}/merge { "deploy": true }
Je kunt aan meerdere concepten tegelijk werken. Alleen een concept dat up-to-date is met de nieuwste versie kan online gaan, zodat het nooit een versie ongedaan maakt die is opgeslagen nadat het concept begon. Is er eerst een ander online gezet, haal dan de wijzigingen daarvan binnen - of vraag de agent dat te doen - en markeer het concept als bijgewerkt. Niets gaat vanzelf online; dat is met opzet. De API noemt een concept een feature, en het online zetten een merge.
Code en resources
Een versie bestaat uit een willekeurig aantal bestanden, in twee delen. De code is elk bestand behalve de resources: de .cs-bestanden worden gecompileerd, in elke map, zoals in elk C#-project, en elk ander bestand wordt bij de versie bewaard en nooit gecompileerd of geserveerd: de documentatie, de tests, waaruit een front end wordt gebouwd. De resources, in resources/, zijn wat de versie leest en serveert terwijl hij draait – pagina’s, scripts, stijlen, afbeeldingen, de migraties van de database – en zijn vanuit de code bereikbaar als Resources.
lambda.cs the snippet: what it returns is served Shelf.cs more C#, compiled beside it models/Book.cs C# in a folder, compiled the same docs/ tests/ what is written about it frontend/ whatever else - kept, never compiled or served resources/ what it reads and serves while it runs
Types hoeven niet onder de code te staan die ze gebruikt. Klik in Code op + naast de code en typ een naam: een .cs-bestand wordt naast de snippet gecompileerd, in dezelfde namespace, in welke map het ook staat, dus je hoeft niets te importeren om erbij te kunnen. Een naam zonder extensie en zonder map wordt als C# gezien.
var shelf = new Shelf(); return Inline.Create() .Get(() => shelf.All()) .Post((Book book) => shelf.Add(book));
public sealed class Shelf { private readonly List<Book> _books = []; public IEnumerable<Book> All() => _books; public Book Add(Book book) { _books.Add(book); return book; } } public record Book(string Title, string Author);
Hoe de code is ingedeeld, is aan wie hem schrijft – een map voor types, een voor de bronnen van een front end, een voor scripts. Elk .cs-bestand wordt in de app gecompileerd, dus C# die er geen deel van uitmaakt – een test, een eigen tool – hoort niet als .cs-bestand in de code. De code en de resources van een versie delen één hoeveelheid ruimte, die het overzicht laat zien.
Een pagina serveren
Er zijn twee manieren om een pagina te serveren, en nog een voor wat mensen ernaast uploaden.
Eén pagina, inline geschreven
Prima voor iets kleins. De pagina zit in de snippet zelf.
var page = Resource.FromString(""" <!doctype html> <title>Mine</title> <h1>It works</h1> """) .Type(new ContentType("text/html; charset=utf-8")); return Content.From(page);
Een map met echte bestanden
De juiste keuze voor alles met een stylesheet en een script. De bestanden zijn resources van de versie en worden precies zo geserveerd als je ze schreef. Er wordt niets gecompileerd.
return Layout.Create() .Add("api", api) .Add(Resources.App("site"));
Geüploade bestanden, uit de data
Voor wat mensen uploaden of wat de lambda aanmaakt, zoals foto’s en documenten, geserveerd naast de app. Niet voor de pagina’s van de app zelf: die horen in de resources, zodat ze in dezelfde versie zitten als de code die ze nodig heeft.
return Layout.Create() .Add("api", api) .Add("uploads", Workspace.Files("uploads")) .Add(Resources.App("site"));
Een frontend, stap voor stap
De tweede manier, helemaal uitgewerkt. Elke demo serveert zijn pagina zo, vanuit resources/web. Open demo-crud om er een te bekijken. Demo’s zijn alleen-lezen; hun editorsleutel is hun naam.
- 1Klik in Code op + naast de resources en typ
site/index.html: het wordtresources/site/index.html. Een slash in de naam zet het bestand in een map; de extensie bepaalt wat voor bestand het is. - 2Voeg
site/app.cssensite/app.jsop dezelfde manier toe. Je pagina verwijst ernaar met alleen de naam, zoalshref="app.css". De map is namelijk de root van wat er geserveerd wordt, geen deel van het adres. - 3Voor alles wat geen tekst is, zoals een afbeelding of een font, open je een bestand in
siteen klik je op de uploadknop naast de resources: het komt in dezelfde map terecht. Een PNG kun je niet in een teksteditor typen, dus zo krijg je hem erin. - 4Serveer de map in
lambda.cs:return Layout.Create().Add(Resources.App("site"));
- 5Klik op Deployen.
site/index.htmlantwoordt op/,site/app.cssop/app.css, en elk adres dat bij geen enkel bestand past, krijgt de pagina als antwoord. Zo blijft een frontend met eigen routing werken als iemand een deeplink herlaadt. - 6Zet er een API naast, dan heeft de pagina iets om mee te praten:
var api = Inline.Create().Get("notes", () => notes); return Layout.Create() .Add("api", api) .Add(Resources.App("site"));
Waaruit het is gebouwd
Een deel van een lambda kan door een buildtool worden gemaakt in plaats van te worden geschreven zoals het wordt geserveerd of gecompileerd: gecompileerd, gebundeld of gegenereerd. De versie bevat wat de tool maakt – als resources of als code – en de bestanden waaruit de tool het maakt, horen bij de code, in een eigen map: frontend/ bijvoorbeeld, met een README die zegt hoe het wordt gebouwd. Jouw agent wijzigt die bestanden, draait de build op de plek waar hij werkt en slaat beide op in dezelfde versie. Dit platform bouwt niets.
frontend/ what it is built from, in whatever shape the tool wants frontend/README.md how it is built, and where the build goes frontend/.gitignore what the build installs or keeps for itself, left out resources/web/ what the build wrote, if it makes resources *.cs what it wrote, if it makes code # run the build where you work, then git add -A && git commit -m "…" && git push -o deploy
Net als de documentatie horen ze bij de versie: ze worden vergeleken in de geschiedenis, teruggezet, gekopieerd naar een concept, gekloond, gedownload en samen met de rest van de code gepubliceerd – en nooit gecompileerd of geserveerd. In het dashboard staan ze in Code, samen met elk ander bestand van de versie.
Wat wordt geschreven zoals het wordt geserveerd of gecompileerd, heeft dat niet nodig. Wat een build installeert of voor zichzelf bewaart – node_modules bijvoorbeeld – hoort nooit bij een versie: een .gitignore in de eigen map ervan houdt het erbuiten.
Een versie en zijn data
Een lambda bewaart bestanden op twee plekken, en de editor toont ze apart: Code bevat de bestanden van een versie (het programma), en Data bevat de workspace (wat het programma bewaart). Het verschil zit in van wie ze zijn. De bestanden van een versie horen bij die versie; de data hoort bij de lambda, en elke versie deelt die. Elk heeft één gedeelde hoeveelheid ruimte: de code en de resources van een versie delen er één, en de database en de workspace van de lambda delen de andere.
| In een versie | In de data | |
|---|---|---|
| wat erin staat | de code en de resources: het programma, frontend inbegrepen – en de documentatie, de tests en waaruit het ook is gebouwd | alles wat de lambda wegschrijft of iemand uploadt |
| wanneer het verandert | nooit: een wijziging is een nieuwe versie | zodra er iets naar wordt geschreven |
| een deploy | zet precies deze bestanden online | raakt het nooit aan |
| terugzetten | haalt de oude bestanden terug | geen effect: elke versie deelt het |
| een concept | begint als kopie ervan | werkt met een kopie ervan |
| wanneer het verdwijnt | met oude versies, boven de limiet | met de lambda, of als je het uitzet |
| in code te bereiken als | Resources | Workspace |
Het kan niet één en dezelfde plek zijn. Dan zou een deploy alles wissen wat je lambda sindsdien had weggeschreven, of zou er nooit iets weg kunnen uit wat hij meelevert. Een spel met een ranglijst wil het tweede; de pagina die het serveert wil het eerste. Dus de pagina gaat in de versie, en de ranglijst in de data.
Records bewaren
Records – berichten, accounts, bestellingen, stemmen – horen in de database: een eigen SQLite-database van de lambda, die je aanzet onder Data. De code opent een verbinding met Database.GetConnection() en leest en schrijft erin via Entity Framework Core, met een eigen context die de tabellen mapt:
// resources/migrations/V1__Create_notes.sql: // CREATE TABLE notes (id INTEGER PRIMARY KEY, text TEXT NOT NULL); using (var connection = Database.GetConnection()) { new Evolve(connection) { Locations = [Resources.Root + "migrations"] }.Migrate(); } return Inline.Create() .Get("notes", () => { using var db = new Notes(Database.GetConnection()); return db.Entries.OrderBy(n => n.Id).Select(n => n.Text).ToList(); }) .Post("notes", (NoteInput input) => { using var db = new Notes(Database.GetConnection()); db.Entries.Add(new Note { Text = input.Text }); return db.SaveChanges(); }); record NoteInput(string Text); class Note { public long Id { get; set; } public string Text { get; set; } } // maps the table the migration made, on the connection it is handed class Notes(SqliteConnection connection) : DbContext { public DbSet<Note> Entries => Set<Note>(); protected override void OnConfiguring(DbContextOptionsBuilder options) => options.UseSqlite(connection, contextOwnsConnection: true); protected override void OnModelCreating(ModelBuilder model) => model.Entity<Note>().ToTable("notes"); }
De tabellen worden gemaakt door migraties: SQL-bestanden die met de versie meekomen in resources/migrations/, en die Evolve op volgorde toepast als de lambda start – elk één keer, dus een nieuwe versie voert alleen uit wat nieuw is. Verander nooit een migratie die al is toegepast; een wijziging aan een tabel is het volgende bestand.
Zoals alle data wordt de database gedeeld door elke versie, laten deploys en terugzetten hem met rust, en werkt een concept op een kopie. Onder Data zie je de tabellen en wat erin staat – de eenvoudige weergave noemt ze items. Downloaden als .NET-project neemt hem mee als gewoon SQLite-bestand.
Maak een context waar je hem nodig hebt en ruim hem daarna weer op, en gebruik hem synchroon: ToList en SaveChanges, niet ToListAsync en SaveChangesAsync. De tabellen worden gemaakt door de migraties, nooit door Entity Framework. De demo demo-crud doet het allemaal voor.
Bestanden bewaren
Workspace is een privémap waarin je lambda mag lezen en schrijven: de plek voor bestanden – foto's die iemand uploadt, een document dat hij maakt, een model dat hij laadt. Records horen in de database, en wat je over een bestand weet – wie het uploadde, en wanneer – is ook een record.
// uploads go into a folder of their own, served as they are Workspace.CreateFolder("photos"); return Layout.Create() .Add("photos", Workspace.Files("photos")) .Add("upload", Inline.Create().Post(async (Stream body) => { using var content = new MemoryStream(); await body.CopyToAsync(content); Workspace.WriteBytes($"photos/{Guid.NewGuid():N}.jpg", content.ToArray()); }));
Er zijn ook ReadBytes, WriteBytes, Delete, List, CreateFolder, en Tree/Files/App om hem te serveren. Verder is niets op het bestandssysteem bereikbaar.
Sleutels en wachtwoorden
Een API-sleutel, een wachtwoord of een token hoort in de secrets, niet in de code – waar elke versie, elke download en iedereen die de geschiedenis leest hem zou hebben. De code leest een secret op naam:
var weather = new System.Net.Http.HttpClient(); weather.DefaultRequestHeaders.Add("X-Api-Key", Secret.Read("WEATHER_API_KEY")); return Inline.Create() .Get("today", async () => await weather.GetStringAsync("https://weather.example/today"));
Zet secrets aan onder Data en stel de waarde daar in. Eenmaal opgeslagen wordt hij nooit meer getoond – niet aan jou en niet aan een agent; je kunt hem alleen vervangen. De lijst laat zien welke namen de code leest waarvoor nog geen waarde is ingesteld, en het overzicht vraagt erom. Secret.Exists zegt of er een is ingesteld, voor code die ook zonder kan. Zoals alle data delen alle versies de secrets, en een concept werkt op een kopie.
Ze worden versleuteld opgeslagen, met een sleutel die niet in de database staat. In een gedownload project leest Secret.Read("NAME") de omgevingsvariabele NAME – de waarden zelf blijven hier.
Websockets
Ondersteund, en niet als bijzaak. De demo demo-game koppelt spelers aan elkaar en laat elk spel op de server draaien. De simpelste vorm is drie callbacks:
var room = new ConcurrentDictionary<IReactiveConnection, string>(); var socket = Websocket.Functional() .OnOpen(c => { room[c] = "someone"; return ValueTask.CompletedTask; }) .OnMessage(async (c, text) => { foreach (var other in room.Keys) { await other.WritePayloadAsync(text); } }) .OnClose((c, _) => { room.TryRemove(c, out _); return ValueTask.CompletedTask; }); return Layout.Create().Add("chat", socket);
Als de pagina alleen luistert - een teller, een feed, een scorebord - zijn server-sent events eenvoudiger: één lang antwoord waar de server steeds in schrijft en waarmee de browser zelf opnieuw verbindt. De demo-live-demo stuurt zo elke stem naar iedereen die meekijkt. In beide gevallen pusht de server wat er veranderd is. Een pagina die om de paar seconden opnieuw vraagt, stuurt elke keer een request, of er nu iets veranderd is of niet, en loopt toch achter.
Waar iedereen in trapt: een browser kan geen headers meesturen bij een websocket-handshake. Geef wat de handler nodig heeft mee in de query, waar hij het leest uit connection.Request.Header.Query, of stuur geheimen als eerste bericht.
Wat niet mag
Je code draait op een gedeelde server, dus een deel van C# wordt al vóór het compileren geweigerd: processen starten, eigen sockets openen, assemblies laden, het bestandssysteem buiten je workspace benaderen, en reflection om daar omheen te komen. Net als wachten op een task met .Result of .Wait() in plaats van await: requests draaien op één thread per core, en de task zou moeten afronden op precies de thread die erop wacht.
Al het andere is er, inclusief de hele module-API van GenHTTP. Wordt er iets geweigerd, dan hoor je welke regel en waarom, niet alleen dat het misging.
Alles meenemen
Met Downloaden als .NET-project in de editor krijg je alles mee: een solution die je kunt openen, kunt draaien met dotnet run en mag houden. Hij heeft alleen het GenHTTP-package nodig, en er zit een Dockerfile bij om hem als container te bouwen en te draaien.
Je snippet wordt Project.cs, en Program.cs serveert wat hij teruggeeft. Je andere bestanden komen precies mee zoals je ze schreef, op dezelfde plek – de resources in resources, de documentatie in docs, de tests in tests. Workspace en Resources worden twee mappen naast het programma, met dezelfde methodes, apart in een map Platform - dus er hoeft niets in je code te veranderen. Secret leest daar omgevingsvariabelen met dezelfde naam; de waarden blijven hier. Database opent database/database.db, dat de download meelevert met de records die je app bewaarde.
Goed om te weten voordat je hier iets bouwt: wat je schrijft is van jou, en je neemt het in zijn geheel mee. Dat je code hier draait, betekent niet dat hij hier vastzit.
Werken met git
Elke lambda is ook een git-repository. Klonen, in het overzicht van het dashboard en naast de code, toont het adres - het adres van je editor met de naam van de app erachter - en git clone geeft je het project dat Downloaden je geeft, met van elke versie een commit van main, getagd als v1, v2 enzovoort, en van elk concept een branch. Open het in je eigen editor, geef het aan je coding agent, voer het uit met dotnet run.
git clone https://genhttp.dev/editor/<editor key>/my-app.git cd my-app # change, commit git push -o deploy
Push en het staat hier. Elke commit die je naar main pusht wordt de volgende versie, met de eerste regel als de wijziging die hij doorvoert - eerst gecompileerd, en geweigerd als dat niet lukt - en git push -o deploy zet hem online. Een branch die je pusht wordt een concept, met de voorvertoning online op een eigen adres; push hem naar main, of voeg -o merge toe aan de laatste push, en hij is de volgende versie. Wat het platform om je code heen zet om er een project van te maken - Program.cs, het projectbestand, Platform - hoort niet bij je app, dus een push die dat wijzigt wordt geweigerd, met uitleg waarom. AGENTS.md in de repository vertelt een coding agent de rest.
Het adres bevat je editorsleutel, net als het adres van de editor: wie het heeft, kan pushen. Wat je app bewaart - de items, bestanden, sleutels en wachtwoorden - staat nooit in de repository.
De code publiceren
Kan wat je gebouwd hebt iemand anders helpen, publiceer dan de code: open Open source in het dashboard, kies een licentie – MIT, tenzij je een andere wilt – en zet het aan. De code krijgt een eigen pagina tussen de open-source-apps, waar iedereen hem kan lezen, een ster kan geven, elke versie kan downloaden als hetzelfde project dat Downloaden je geeft, met de licentie erbij, of elke versie met git kan klonen.
Elke versie wordt gepubliceerd, ook de eerdere, met al zijn code – de documentatie en de tests daarbij inbegrepen – en de wijziging die elke versie maakte. Wat de app bewaart, wordt nooit gepubliceerd – de records, de bestanden die hij opsloeg, de waarden van zijn sleutels en wachtwoorden – en ook niet wat je in je eigen woorden vroeg, of wie de app gebruikt. Zet je het uit, dan is de pagina weg; de sterren blijven bewaard voor als je de code opnieuw publiceert.
Alles in de code wordt openbaar, de eerdere versies inbegrepen. Een sleutel of wachtwoord hoort bij de sleutels en wachtwoorden onder Data, nooit in de code – gepubliceerd of niet.
Het aan een agent overlaten
Er is een MCP-endpoint op /mcp. Koppel er een agent aan en hij kan alles wat de editor kan: de handleiding lezen, een demo helemaal lezen, bestanden schrijven, ze compileren en deployen. Eronder zit dezelfde API.
Onderweg legt hij uit waarom: write_code krijgt de specificatie en de wijziging mee. En hij kan bekijken wat hij heeft gedeployd: read_logs geeft de recente requests van de lambda, de output en de stacktrace van elke exception. Zo controleert een agent of zijn code werkt, in plaats van het aan te nemen. Jij ziet hetzelfde in het dashboard. Hij schrijft de documentatie en de tests terwijl hij werkt, leest ze voordat hij iets verandert, en voert de tests uit op het adres van een concept voordat hij het concept online zet. Een pagina die gevonden moet worden, krijgt een titel, een beschrijving, een icoon en een preview voor als iemand de link deelt. Onderaan de pagina’s die hij bouwt, zet hij een klein regeltje dat ze met GenHTTP Lambda zijn gemaakt - zeg het hem als je dat liever niet wilt, dan haalt hij het weg.