Gå til hovedindhold

frembench — udviklerbenches

frembench er en Linux-maskine, du lejer pr. minut og når fra din browser — en udviklerbench. Den har den samme sprogværktøjskæde som dine CI-runners, så det, der bygger på en bench, også bygger i CI.

Hvad det koster

En bench-bruger koster 39 € om måneden og inkluderer 200 timers kørsel. Ud over puljen koster det 0,20 € i timen, og det samlede beløb har et fast loft — så din regning kan aldrig overstige 99 € pr. bench-bruger om måneden, uanset hvor hårdt du kører dem. For en enkelt bruger nås loftet ved 500 timers kørsel; derefter kører benchen videre uden yderligere betaling. Alle beløb her er i EUR, som er den valuta, benches afregnes i — ligesom resten af dit abonnement.

Timerne deles på tværs af bench-brugere, på samme måde som CI-minutter. Kvoten er 200 timer × brugere, målt mod alt, hvad organisationens benches har kørt, så to brugere deler 400 timer: en travl bench trækker på en mere stille kollegas kvote i stedet for at gå direkte over i merforbrug. Loftet deles på samme måde — loftet er 99 € pr. bench-bruger, ikke pr. maskine, så en enkelt bench i en organisation med to brugere kan stå for mere end 99 €, mens organisationen holder sig inden for 198 €.

To størrelser

StandardLarge
Maskine2 vCPU, 8 GB4 vCPU, 16 GB
Bruger39 € / måned78 € / måned
Bidrag til den fælles pulje200 timer400 timer
Pulje-timer brugt pr. kørende time12
Ud over puljen0,20 € / time0,40 € / time
Det meste, en bruger kan koste på en måned99 €198 €

En Large-bruger tæller som to bench-brugere i alle henseender, så alt på denne side gælder for den med fordoblede tal: én pulje for hele organisationen, den samme måling pr. sekund, det samme loft. En stille bruger af den ene størrelse dækker en travl af den anden. En administrator i organisationen køber Large-brugere på faktureringssiden og vælger størrelsen, når en bruger tildeles en person; benchen oprettes i den størrelse, som ejerens bruger har.

To detaljer, der er værd at kende, fordi de ændrer, hvad du faktisk betaler:

  • Tiden måles i sekunder og rundes én gang, ved periodens slutning. En bench går i dvale efter 30 minutters inaktivitet og vågner, når du forbinder dig, så en arbejdsdag består af mange korte intervaller. Rundede vi hvert interval op til et minut, ville tyve opvågninger på ti sekunder blive faktureret som tyve minutter — og du ville betale for vores egen optimering med dvale.
  • 200 timer er langt mere end en arbejdsmåneds tilkoblet tid. Puljen er dimensioneret efter den faktiske tid, en bench er vågen, ikke de timer, du sidder ved tastaturet; en agent, der kører et langt job, tæller, en inaktiv editor gør ikke.

Brugere afregnes forholdsmæssigt, når du tilføjer eller fjerner dem, som enhver anden bruger. Se prissiden for, hvordan det passer ind i resten af planen.

Du skal ikke administrere den. Den vågner, når du forbinder dig, og går selv i dvale, når ingen er forbundet, og intet kører.

Hvad der overlever, og hvad der ikke gør

Det er den ene ting, der er værd at forstå, før du bruger en bench, fordi den former alt andet.

Din bench har to diske. Profilvolumenen på 50 GB er din og bevares. Boot-disken bygges op fra et nyt image ved hver opvågning, og det er sådan, du får opdateringer uden et servicevindue og uden nogensinde at blive bedt om at genstarte.

$HOME ligger på profilvolumenen. Så:

HvadOverlever dvale
Din kode, dine node_modules, dit build-outputja
Dotfiler, shell-historik, git-konfiguration, SSH-nøglerja
npm i -g, pip --user, uv tool, pipx, cargo install, go installja
Dit login i Claude Codeja
apt installnej

apt er den bevidste undtagelse: systempakker er det, imaget er til. Har du brug for en hver morgen, hører den hjemme i imaget — opret et issue i stedet for at scripte den ind i din shell-profil, så sørger den ugentlige genopbygning for, at det ikke er dit problem.

Tag dine filer med dig

Din profilvolumen overlever dvale, men ikke din bench. Når en administrator i organisationen fjerner din bench-bruger, fjernes benchen med den:

  • Den stopper med det samme, og du kan ikke åbne den igen, hverken i browseren eller med fremforge bench attach.
  • Dens profilvolumen bevares i 30 dage. I de 30 dage kan en administrator i organisationen fortryde fjernelsen på organisationens administrationsside Benches. Det bringer benchen tilbage, som den var, i dvale, på den samme disk og med din bruger.
  • Efter 30 dage slettes profilvolumenen. Den kan ikke kobles på igen eller gendannes, og en ny bench starter altid med en tom profil.

Så tag det med, du vil beholde, mens du stadig har benchen, for eksempel før du forlader et projekt eller organisationen. Er den allerede fjernet, så bed en administrator i organisationen om at fortryde fjernelsen inden for de 30 dage, kopiér dine filer ud som beskrevet nedenfor, og lad vedkommende fjerne den igen.

Der er ingen scp, rsync eller SSH ind i en bench: den har ingen indgående netværksvej, og fremforge bench attach giver dig en terminal, ikke en filoverførsel. Det, du tager med dig, forlader benchen gennem frem.sh, på en af de tre måder nedenfor.

Push dit arbejde

Kode hører hjemme i git, og benchen har allerede en git-legitimation til frem.sh. Sådan finder du hvert repository under din hjemmemappe med noget, der endnu ikke er pushet (ikke-committede ændringer eller commits på en branch, der ikke findes på noget remote):

find ~ \( -name node_modules -o -name .cache \) -prune -o -name .git -print 2>/dev/null |
while read -r g; do
  r=$(dirname "$g")
  if [ -n "$(git -C "$r" status --porcelain)" ] ||
     [ -n "$(git -C "$r" log --branches --not --remotes --oneline -1)" ]; then
    echo "not pushed: $r"
  fi
done

Commit og push hvert af dem. Kan du ikke pushe til den branch, du står på, så push til din egen branch (git switch -c wip/<topic>, derefter git push -u origin HEAD). git stash list viser stashes, som et push ikke tager med.

Alt andet: et privat repository

Dotfiler, noter og kladdefiler, der ikke hører til noget repository, kan lægges i et privat repository for sig. Opret et i din organisation fra frem.sh' webbrugerflade (New repository, synlighed Private), for eksempel bench-files-<your-login>. Kan du ikke oprette repositories i organisationen, så spørg en organisationsejer. Derefter, på benchen:

mkdir ~/bench-files && cd ~/bench-files
cp -a ~/.bashrc ~/.tmux.conf ~/notes .   # whatever you want to keep
git init -b bench-files
git add -A
git commit -m "Files from my bench"
git remote add origin https://frem.sh/<org>/bench-files-<your-login>.git
git push -u origin bench-files

Branchen hedder bench-files i stedet for main, så organisationens branch-beskyttelse, som som standard dækker main, ikke afviser pushet. På din egen maskine:

git clone -b bench-files https://frem.sh/<org>/bench-files-<your-login>.git

To ting, du ikke skal kopiere:

  • ~/.git-credentials og ~/.config/fremforge/token. De er udstedt til benchen, tilbagekaldes, når den forsvinder, og virker ingen andre steder.
  • Dine egne hemmeligheder, såsom private SSH-nøgler eller loginoplysninger til cloud-CLI’er. Alle med adgang til repositoriet kan læse dem, også organisationens ejere. Opret nye på din næste maskine i stedet.

Git egner sig dårligt til store binære filer, så hold repositoriet til det, du faktisk har brug for.

En enkelt lille fil: download den i din browser

Til en enkelt lille fil er der en genvej gennem Viderestillede porte. Pak det, du vil have med, i én fil, og server dens mappe:

mkdir -p ~/outbox
tar -czf ~/outbox/dotfiles.tar.gz -C ~ .bashrc .tmux.conf
cd ~/outbox && python3 -m http.server 8000

Port 8000 vises under Viderestillede porte. Åbn den, klik på filen for at downloade den, og stop derefter serveren med Ctrl-c. Et viderestillet svar er begrænset til 8 MB, så det virker kun til små filer; brug et repository til alt, der er større.

Kør en agent

Codex og opencode er forudinstalleret. Begge har open source-licenser, så vi leverer dem.

Claude Code er ikke forudinstalleret, og grunden er en licens, ikke en forglemmelse: dens vilkår er ikke en open source-licens, og dette er et produkt, vi sælger, så at levere den ville være at videredistribuere proprietær software. Det er én kommando, under din egen aftale med Anthropic:

frembench-install-claude-code
claude

Den installeres fra det offentlige npm-registry gennem benchens udgående proxy, som enhver anden pakke, du installerer på benchen. Det skal du kun gøre én gang — installationen og login ligger på din profilvolumen.

Ingen telemetri fra de forudinstallerede værktøjer. Brugsrapportering og opdateringstjek er slået fra for de agenter og værktøjer, en bench leveres med (OpenChamber, opencode, Codex, Mistral Vibe, Claude Code, når du installerer det, og cloud-, build- og pakkeværktøjerne), og hvert build af bench-imaget kontrollerer det. Nogle få værktøjer henter stadig indhold, de skal bruge for at virke, ikke data om dig: opencodes modelliste, Codex’ plugin-katalog og Azure CLI’ens versionstjek første gang den køres. Vil du slå et værktøjs rapportering til igen, så sæt selv dets variabel.

Kør flere ting på én gang

Din bench-terminal er ikke en nøgen shell — den forbinder til en tmux-session ved navn frembench:

tmux new-session -A -s frembench

Det er det, der får en agent til at overleve en lukket bærbar, og det er også sådan, du kører flere på én gang. Præfikstasten er standarden Ctrl-b, og musen er slået til.

TasterHvad det gør
Ctrl-b cNyt vindue — start en agent mere her
Ctrl-b n / Ctrl-b pNæste / forrige vindue
Ctrl-b 0 … Ctrl-b 9Gå direkte til et vindue
Ctrl-b wVælg fra en liste over vinduer
Ctrl-b ,Omdøb det aktuelle vindue — værd at gøre, navngiv dem efter opgave
Ctrl-b %Del i ruder side om side
Ctrl-b "Del i ruder over hinanden
Ctrl-b zZoom én rude til fuld skærm og tilbage
Ctrl-b dKobl fra — alt kører videre

En ekstra browserfane spejler; den forgrener ikke. Hver forbindelse går til den samme frembench-session, så to faner viser det samme vindue og vil kæmpe om det. Brug vinduer og ruder til parallelt arbejde, ikke flere faner.

Vil du gerne have to faner, der viser forskellige ting, så giv den anden sin egen visning af de samme vinduer:

Ctrl-b :  new-session -t frembench -s second
Ctrl-b :  switch-client -t second

-t frembench grupperer den nye session med den oprindelige, så begge ser den samme liste over vinduer, men hver kan stå på sit eget vindue. En nyåbnet fane lander altid på frembench, så du skal køre switch-client igen for hver fane.

To detaljer, der overrasker folk:

  • Et nyt vindue er en almindelig login-shell. ~/.frembench/startup kører kun, når sessionen oprettes første gang, så den kører ikke igen for hvert vindue.
  • Faner i forskellig størrelse krymper ikke hinanden. aggressive-resize er slået til, så et vindue får størrelse efter den klient, der faktisk ser på det, og ikke efter den mindste, der er forbundet.

Åbn en udviklingsserver i din browser

En bench har ingen indgående netværksvej. Intet på internettet kan nå den, og det er ikke en begrænsning, vi har planer om at fjerne — det er derfor, at fladen til at forbinde sig kan forsvares.

Udviklingsservere virker stadig. Start en, som du plejer:

npm run dev

Inden for få sekunder vises porten under Viderestillede porte — et kort for sig på frembench-siden, under Hvad holder den vågen; under shellen på siden med terminalen i fuld skærm. Klik på den. Forbindelsen går udgående over den samme kanal som din terminal; ingen port åbnes, og der er ingen tunnel-binær involveret.

Kortet viser både, hvad der lytter, og hvor:

PortTjeneste
5173node
8000python3

Nogle ting, der er værd at vide:

  • Kun porte, din bench faktisk lytter på, tilbydes. Du kan ikke bede om en vilkårlig port, og det kan intet andet, der har et link, heller.
  • Kolonnen med tjenesten er processens eget korte navn, læst fra benchen — node snarere end vite, fordi det er det, processen kalder sig selv. Der står Unknown for en port, hvis proces ikke kunne identificeres, og på en bench, der kører et image fra før denne funktion kom, som får den ved sin næste opvågning.
  • En server, der kun er bundet til benchens private adresse, vises ikke, fordi en viderestilling til den ville fejle. Bind til localhost eller 0.0.0.0.
  • SSH tilbydes aldrig. Brug terminalen.
  • Hot reload virker. En viderestillet side serveres fra benchens egen oprindelse, og en WebSocket åbnet fra den oprindelse føres også igennem — og det er det, en udviklingsservers live reload-kanal har brug for. Denne note sagde tidligere, at det ikke virkede; det blev skrevet, før oprindelsen pr. bench fandtes, og blev stående, efter at den kom.

Det er også sådan, du når en webbrugerflade til agenter som OpenChamber. Den er installeret på hver bench og starter ved hver opvågning, på port 3000, bag en adgangskode, der er genereret til din bench (OPENCHAMBER_UI_PASSWORD i ~/.frembench/openchamber.env): åbn den port. Kør ikke openchamber tunnel — det er en Cloudflare-tunnel, og viderestillingen ovenfor er både den suveræne vej og den, der allerede godkender dig.

API-legitimationen på en bench

En bench godkender sig mod frem.sh med to legitimationer, og det sparer dig en eftermiddag at vide, hvilken der er hvilken.

LegitimationHvorHvad den når
Git-legitimation~/.git-credentialsgit clone / push / pull og Forgejos eget API på /api/v1/…
API-legitimation~/.config/fremforge/tokenfremforge-API’et på /_app/api/v1/…

Begge udstedes til dig af platformen. Du skal ikke oprette dem, indsætte dem eller forny dem, og du bør ikke erstatte dem med et personligt token.

Den udstedes ved hver opvågning

API-legitimationen er et ffp_…-token, der udstedes, når din bench starter, er gyldigt i omkring et døgn og tilbagekaldes, når benchen går i dvale. Den næste opvågning udsteder et nyt. Derfor er det sikkert, at det ligger på profilvolumenen: et token læst fra en kasseret disk er allerede tilbagekaldt.

Den praktiske konsekvens: en ændring af, hvad din bench må, træder i kraft ved næste opvågning, ikke med det samme. Er en funktion netop slået til for dig, og API’et stadig afviser, så lad benchen gå i dvale og vågne, før du rapporterer en fejl.

Den handler som dig, med en snævrere rækkevidde

Tokenet er bundet til din identitet, ikke til en organisation. Hver anmodning kontrolleres stadig mod dit reelle ejerskab af organisationer, så en bench aldrig kan nå en organisation, du ikke kunne nå fra din bærbare.

Hvad det bevidst ikke har: fakturering, SSO-konfiguration, ændringer af brugere og muligheden for at udstede flere tokens. Det er de omfang, hvis konsekvenser ville leve længere end benchen, der bliver smidt væk. Alt andet, en bench har brug for i det daglige — organisationer, runners, fund, SBOM’er, læsning af revisionsloggen, afhængighedsopdateringer, udrulningsmiljøer og secrets samt at starte og downloade en dataeksport — er med.

403 Token lacks required scope '…' fra en bench betyder, at endpointet findes, og at din bench-legitimation ikke har det omfang. Det betyder ikke, at funktionen mangler. Formuleringen er let at misforstå som “intet sådant endpoint” — kontrollér omfanget, før du konkluderer noget om API’et.

Organisationens ejere kan slå benchens API-legitimation helt fra for hele organisationen under administration → Godkendelsespolitik. Den er slået til som standard.

Sådan bruger du den

curl -fsS https://frem.sh/_app/api/v1/orgs/<your-org>/environments \
  -H "Authorization: Bearer $(cat ~/.config/fremforge/token)"

Bemærk præfikset /_app. Den bare sti /api/v1/… er Forgejos eget API, som ikke accepterer dette token — og dets afvisning citerer det token, du sendte, så undgå at indsætte output fra et fejlet kald i en sag eller en chat.

Dvale, opvågning, og hvad du betaler for

Du betaler for de minutter, din bench er vågen. En bench i dvale koster kun sin profilvolumen, så det er værd at vide præcist, hvad der holder den vågen.

Hvad der holder den vågen

Din bench forbliver oppe, så længe et af disse er opfyldt:

  • Nogen er forbundet — en browserfane eller en SSH-session, der faktisk er forbundet.
  • En agent arbejder. Ikke blot kører: se nedenfor.
  • Du har sat den til at holde sig vågen, fra bench-siden.

Når ingen af dem er opfyldt, går benchen i dvale efter 30 minutter.

Hvad “en agent arbejder” betyder

En agent, der står ved en prompt, arbejder ikke, og det er den skelnen, der afgør din regning. En Claude-session, der står åben natten over, ser travl ud efter ethvert naivt mål — den tikker stadig af sted med omkring 1 % af en CPU — så vi bruger ikke CPU alene til at afgøre det.

En agent tæller som arbejdende, når et af disse er opfyldt:

  • den har skrevet til sin egen sessionshistorik inden for de seneste 10 minutter, eller
  • den eller noget, den har startet, bruger mindst 10 % af en CPU-kerne.

Det andet findes for lange værktøjskald. Starter din agent et build på tredive minutter, skriver den intet i tredive minutter, mens den venter — men compileren, den startede, har travlt, så benchen forbliver oppe.

En reelt inaktiv agent holder altså op med at holde din bench vågen omkring 10 minutter efter sin sidste aktivitet, og benchen går i dvale omkring 30 minutter efter det: cirka 40 minutter efter din sidste interaktion, hvis intet andet holder den.

Det ene tilfælde, du skal fortælle os om

Et langt job, du selv har startet — ikke gennem en agent — holder ikke benchen vågen. En make -j, en dataimport, en udholdenhedstest: starter du det i en shell og lukker din bærbare, går benchen i dvale under det.

Det er bevidst. Hvis enhver travl proces holdt en maskine vågen, kunne en inaktiv bench blive ved med at koste penge for evigt på grund af hvad som helst, og det billigste at køre på en andens maskine er en kryptominer. Så reglen er, at vi kun tæller arbejde, vi kan tilskrive en agent, og alt andet er dit valg: sæt benchen til at holde sig vågen, og slå det fra igen, når jobbet er færdigt.

At forblive forbundet virker også, da en forbundet klient i sig selv holder den vågen.

Opvågning sker automatisk — forbind dig, så kommer den tilbage. Dine filer er, hvor du forlod dem, og dit terminallayout kommer tilbage med dem: de vinduer, du havde åbne, genskabes i de samme mapper, og Claude, Codex, opencode og OpenChamber startes igen — hver genoptaget i den session, den var i, og venter ved en prompt. Intet afspilles igen for dig; en agent handler ikke, mens du er væk.

To ting kommer ikke tilbage. En session, der blev startet uden et id, der kan genoptages, kommer tilbage som en ny i den rigtige mappe, og enhver anden langvarig proces — din egen udviklingsserver, et build — genstartes ikke. Angiv den i ~/.frembench/restore-commands.txt, ét kommandonavn pr. linje, hvis du vil have den genstartet.

Sæt en bench til at holde sig vågen, når du har et langt job, som vores sporing ikke ville se, fra bench-siden. Det er ikke permanent: en bench, der har gået for længe uden genopbygning, opdateres alligevel, fordi en maskine på internettet uden opdateringer ikke er noget, man skal kunne købe sig til ved at holde den vågen.

Sådan får du en

Udviklerbenches slås til pr. tenant. Har din organisation dem, ligger siden under Indstillinger → Dev benches; har den ikke, siger siden det. Din organisations administrator bestemmer, hvor mange benches din tenant må køre samtidig.

Én bench pr. organisation

En bench tilhører en organisation, ikke dig. Er du medlem af flere organisationer, der har bench-brugere, får du én bench i hver — separate maskiner, separate profiler, faktureret hver for sig til den organisation, der tildelte brugeren. Du kan ikke oprette en bench i en organisation, der ikke har købt bench-brugere, så ingen organisation kan blive opkrævet for en maskine, den ikke har sagt ja til.

Profiler følger ikke med dig mellem organisationer. Hver bench har sin egen profilvolumen, så de værktøjer, den shell-konfiguration og de loginoplysninger, du installerer på én bench, findes ikke på en bench i en anden organisation. Sæt hver af dem, du bruger, op.

Det er en konsekvens af grænsen mellem tenants snarere end en begrænsning, vi har planer om at fjerne: en fælles profil ville betyde, at én organisation betalte for at opbevare en anden organisations arbejde, og den ville føre filer over en grænse, kunderne er afhængige af.

Benches går uafhængigt af hinanden i dvale efter tredive minutters inaktivitet, så benches i flere organisationer holder ikke flere maskiner kørende — kun den, du faktisk bruger, forbliver vågen.

Hvorfor Claude Code ikke er forudinstalleret

Bench-imaget leverer codex (Apache-2.0) og opencode (MIT) klar til brug. Claude Code er ikke forudinstalleret, og det er en licensbeslutning snarere end en forglemmelse: dens licens er ikke open source, og frembench er et produkt, vi sælger. At levere den i vores image ville være at videredistribuere den som en del af noget, vi tager betaling for.

At installere den selv er én kommando, og den kører derefter under din aftale med Anthropic i stedet for vores — og det er også derfor, den overlever dvale: din profilvolumen beholder den, så du installerer den én gang pr. bench.

Det er den samme regel, der gælder overalt i produktet: de afhængigheder, vi leverer, er suveræne, opdaterede og har fuldt open source-licenser. Alt, der ikke består den test, er noget, du selv tager med, ikke noget, vi pakker med.