Richt een agent op een GitHub-repository en je krijgt een werkend board terug: elke issue als story, in de status die zijn historie voorschrijft, met checklists, labels en milestones mee overgenomen. Daarna pakt diezelfde agent een story op, claimt hem, beweegt hem door de toestandsmachine en koppelt de pull request die hij heeft geopend.
Deze pagina beschrijft die lus van begin tot eind. De vulstap heeft twee routes: GitHub-to-EAT, de opensource-importeur van East Agile, doet het in één commando (stap 3); de import-API doet hetzelfde werk aanroep voor aanroep (stappen 4 en 5), en dat is wat een agent aanstuurt als hij de job-handle wil. Alles daarna loopt over de API, want het punt is juist dat een agent de rest onbewaakt kan doen.
Dit is geen aparte «AI-import». De vulstap is dezelfde GitHub-importeur die je met de hand kunt draaien via Projectinstellingen → Importeren / Exporteren, beschreven in Bedieningsinstructies → Importeren uit andere trackers. De agent roept hetzelfde endpoint aan als jij. Wat deze pagina toevoegt, is alles eromheen: wie de sleutel houdt, hoe je de import controleert voordat hij schrijft, en wat de agent met het board doet zodra het bestaat.

Wat je nodig hebt
Section titled “Wat je nodig hebt”- Een project — en een sessie of een
ea_user_…-sleutel om het aan te maken. - Een agent-sleutel — een
ea_agent_…-sleutel die tot dat project beperkt is. Welke rol hij nodig heeft, hangt af van hoeveel van de lus je de agent wilt laten draaien; zie stap 2. Zie ook API-gids → Twee soorten sleutels. - Een GitHub personal access token — met leestoegang tot de issues van de repository. Elke import authenticeert zich, omdat het ophalen via GitHubs GraphQL-API loopt en GraphQL een verzoek zonder token weigert. Je mag hem alleen weglaten wanneer de Tracker namens jou ophaalt: een publieke repository, op een deployment dat een gedeeld terugvaltoken heeft (het gehoste eastagiletracker.com heeft er een; een zelfgehoste installatie heeft er geen totdat de beheerder
GITHUB_IMPORT_PATinstelt), en niet met--engine directvan GitHub-to-EAT. Zie Tokens en rate limits. - Node.js 22+ — alleen voor de GitHub-to-EAT-route in stap 3. De API-route heeft niets meer nodig dan
curl.
1. Het project aanmaken
Section titled “1. Het project aanmaken”Het project moet bestaan vóór de agent-sleutel, en het moet door een mens worden aangemaakt: agent-sleutels zijn bij uitgifte aan één project gebonden en kunnen zelf geen project opstarten. Maak het in de interface, of met je eigen ea_user_…-sleutel:
curl -X POST https://eastagiletracker.com/api/v1/projects \ -H "X-TrackerToken: $TRACKER_USER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name": "hello-world", "iteration_length_weeks": 1}'Het antwoord draagt de project_id die elke aanroep hieronder nodig heeft.
2. Een agent-sleutel uitgeven
Section titled “2. Een agent-sleutel uitgeven”Een projecteigenaar maakt agent-sleutels aan in Projectinstellingen → Agents. De rol die je kiest bepaalt hoeveel van deze pagina de agent zelfstandig kan doen, en er zijn twee zinnige antwoorden:
owner— één sleutel draait de hele lus, import inbegrepen. Importeren is alleen voor de eigenaar, omdat een import de vorm van een project in zijn geheel herschrijft. Een agent met de rolowneruitgeven vereist dat je zelf projecteigenaar bent: de rol van een agent kan die van zijn maker nooit overtreffen.member— minste privilege. De agent claimt stories, beweegt ze, becommentarieert en koppelt pull requests, maar kan niet importeren. De import draai je zelf (stap 5) met je eigen sleutel, en daarna geef je het board aan de agent.
Laat het hoe dan ook niet op de standaardwaarde staan. Een nieuwe agent-sleutel is viewer zolang je niets anders zegt, en een viewer kan het board lezen maar geen story claimen of verplaatsen — en dat is het grootste deel van deze lus.
Agent-sleutels tellen hier om een reden die verder gaat dan toegang. Een agent-sleutel handelt als benoemde deelnemer in één project, dus elke story die hij aanmaakt, elke statuswijziging die hij doet en elke opmerking die hij schrijft wordt in de historie aan die agent toegeschreven — te onderscheiden van je eigen werk in plaats van ermee versmolten.
export TRACKER_TOKEN="ea_agent_xxxxx"Laat de agent vóór alles /meta lezen:
curl https://eastagiletracker.com/api/v1/meta \ -H "X-TrackerToken: $TRACKER_TOKEN"Dat beantwoordt de twee vragen waar de agent anders naar zou raden: aan welk project de sleutel gebonden is (auth.project_id), en welke statuswijzigingen per storytype toegestaan zijn (transitions). Een feature loopt unstarted → started → finished → delivered → accepted; een chore is enkel unstarted → started → accepted. De kaart lezen wint het van hem hard coderen.
3. Importeren met GitHub-to-EAT
Section titled “3. Importeren met GitHub-to-EAT”GitHub-to-EAT is East Agiles eigen opensource-importeur: een MIT-gelicentieerd opdrachtregelprogramma dat de hele vulstap — stappen 4 en 5 hieronder — in één commando doet. Grijp ernaar als er een mens achter een terminal zit. Grijp naar de API eronder als een agent onbewaakt aanstuurt en de job-handle wil om te pollen.
Het vereist Node.js 22+ en heeft geen eigen runtime-afhankelijkheden. Het staat nog niet op npm, dus installeer het vanuit de repository:
git clone git@github.com:EastAgile/GitHub-to-EAT.gitcd GitHub-to-EATnpm install --global .Richt het daarna op de sleutel uit stap 2 en het project uit stap 1:
export EAT_AGENT_KEY="ea_agent_xxxxx"github-to-eat --project $PROJECT_ID --repo octocat/hello-worldHet drukt eerst een mappinglegenda af — precies hoe elk geselecteerd type gaat landen — en vraagt om bevestiging voordat het iets schrijft. Buiten een terminal, in een pipe, in CI of in een agent is er nergens om die vraag te tonen, dus een run die zou schrijven moet --yes meegeven; zonder dat stopt het programma met 2 en schrijft het niets in plaats van je antwoord te raden. Opnieuw draaien is veilig: wat al geïmporteerd is wordt overgeslagen, nooit gedupliceerd.
| Vlag | Wat die doet |
|---|---|
--dry-run | Voorcontrole, daarna het plan afdrukken dat het zou uitvoeren — hoeveel stories het zou importeren, hoeveel het zou overslaan als reeds aanwezig — en niets wegschrijven. Heeft geen --yes nodig. |
--include | Welke typen te importeren, kommagescheiden: issues,prs,milestones,releases,deps. Standaard issues, en elke keuze moet dat bevatten. Dit zijn dezelfde opt-ins als de tabel in stap 6. |
--token | Jouw GitHub personal access token (GITHUB_TOKEN in de omgeving of in een .env telt ook). Het heeft repo nodig, of fijnmazig Issues: Read, op die repository. Verplicht voor een private repository, voor een server zonder gedeeld terugvaltoken, en altijd voor --engine direct. Laat het weg op de standaardengine van de gehoste dienst en de Tracker geeft zijn eigen gedeelde budget uit — zie Tokens en rate limits. |
--engine | server, de standaard, stuurt één /import/json-aanroep en laat de Tracker ophalen, mappen en schrijven. direct draait diezelfde pijplijn op jouw machine en schrijft in plaats daarvan via de publieke API — het leest GitHub dus zelf en heeft altijd een token nodig, anders stopt het met 2. |
--states, --milestones, --story-type, --no-comments, --no-tasks | Beperken of overschrijven de mapping voor één run; niets wordt bewaard. Elk ervan impliceert --engine direct. |
Zet EAT_API_BASE en EAT_APP_BASE om het naar een zelf-gehoste of lokale Tracker te wijzen; beide wijzen standaard naar de gehoste dienst. De README draagt de volledige vlaggenreferentie, de exitcodes en het oplossen van problemen.
Alles hieronder is diezelfde import, aanroep voor aanroep aangestuurd — en dat is wat je wilt wanneer een agent hem draait.
4. Eerst een proefrun
Section titled “4. Eerst een proefrun”Importeren is alleen voor de eigenaar — gebruik een agent-sleutel met de rol owner, of je eigen sleutel als je de agent op member hebt gelaten. Draai hem eerst met dry_run, voordat je hem laat schrijven:
curl -X POST https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/import/json \ -H "X-TrackerToken: $TRACKER_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "source": "github", "owner": "octocat", "repo": "hello-world", "include_pull_requests": true, "include_milestones": true, "dry_run": true }'Een proefrun haalt op bij GitHub, herleidt en ontdubbelt precies als de echte, meldt dezelfde tellingen — imported, skipped, errors, unmatched — en draait daarna de hele transactie terug. Niets blijft staan en geen enkele voltooide-import-gebeurtenis bereikt je auditlog. Het is de goedkoopste manier om te ontdekken dat je milestones wilde meenemen, of dat een repo groter is dan je dacht, zolang het je nog niets kost.
Elke aanroep van /import/json is asynchroon, de proefrun inbegrepen: het endpoint geeft 202 terug met een job-handle, geen resultaat, en de tellingen komen op de job binnen wanneer je die opvraagt (stap 5). De job van een proefrun bereikt done net als die van een echte import; het verschil is dat er niets is weggeschreven.
5. De import draaien
Section titled “5. De import draaien”Laat dry_run weg en stuur hem opnieuw. Net als daarvoor geeft het endpoint 202 terug met een job-handle:
{ "import_id": "…", "status": "pending" }Poll de job tot hij een eindtoestand bereikt:
curl https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/imports/$IMPORT_ID \ -H "X-TrackerToken: $TRACKER_TOKEN"De status loopt pending → fetching → writing → done | failed. Alleen de laatste twee zijn eindtoestanden: done draagt de resultaattellingen, failed draagt een foutmelding en een stabiele machinecode waarop je kunt vertakken. Terwijl het ophalen pagineert, vertellen progress_current en progress_total op welke pagina het zit — de moeite waard om te tonen als er een mens meekijkt.
Tokens. Geef "token": "github_pat_…" mee. Laat je hem weg, dan zet de server het gedeelde platformtoken in, dat alleen publieke repositories leest en over elke aanroeper op de deployment wordt afgerekend — Tokens en rate limits beschrijft wat je dat kost. Welk token ook wordt gebruikt: het stuurt de bovenstroomse GitHub-aanroepen aan en verder niets. Het wordt nooit gelogd, nooit in het auditlog gezet, nooit opgeslagen en nooit teruggegeven in een antwoord of een fout.
Opnieuw draaien is veilig. Een rij die al geïmporteerd was, wordt op zijn bron-id herkend en overgeslagen, niet gedupliceerd. Een tweede import vult het board aan met wat er sinds de eerste bij is gekomen.
6. Wat er op het board landt
Section titled “6. Wat er op het board landt”Issues worden standaard geïmporteerd. Al het andere is opt-in, één vlag per type:
| Van GitHub | Wordt | Vlag |
|---|---|---|
| Issue | Een story. Open → unstarted in de Backlog. Gesloten → accepted, of rejected wanneer GitHub zegt dat de issue als not_planned of duplicate is gesloten (de story draagt dan een bijpassend label). | standaard |
| Checklist in de issue-tekst | Taken — elke regel - [ ] / - [x] wordt één taak in de volgorde van de tekst, waarbij [x] al voltooid aankomt. De checklist blijft ook in de beschrijving staan. | standaard |
| Labels | Labels, ongewijzigd overgenomen. | standaard |
| Pull request | Een story met het label pull-request. Open → started, gemerged → accepted, ongemerged gesloten → rejected. | include_pull_requests |
| Milestone | Een epic, genoemd naar de milestone en op titel ontdubbeld — twee issues die een milestone delen landen in één epic. Staat de vlag uit, dan reist hij mee als label milestone:<titel>. | include_milestones |
| Release | Een release-story. Gepubliceerd → accepted, concept → unstarted. | include_releases |
| Issue-afhankelijkheid | Een blocker op de story. Alleen issues, nooit pull requests. | include_dependencies |
Het storytype wordt afgeleid wanneer de issue het niet zegt. Een label met bug, fix of defect — of een titel die met fix of bug begint — maakt er een bug van; chore, maintenance, devops of infra maken er een chore van; al het andere is een feature. Dat is de moeite waard om te weten vóór je importeert, want in East Agile Tracker dragen alleen features punten en voeden alleen features de velocity. Zie Inleiding → Stories.

7. De agent werkt aan een story
Section titled “7. De agent werkt aan een story”Nu heeft het board historie en de agent een sleutel. De lus is vanaf hier vier aanroepen.
Een story vinden, of er een schrijven. Filter het board op iets om op te pakken:
curl "https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories?state=unstarted" \ -H "X-TrackerToken: $TRACKER_TOKEN"import_source=github beperkt het tot wat de import heeft binnengebracht. Heeft de agent werk gevonden dat de repo nooit heeft vastgelegd, dan maakt hij in plaats daarvan de story aan — zie API-gids → Een story aanmaken.
Hem claimen. Een agent voegt zichzelf als eigenaar toe door een lege body te posten:
curl -X POST https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories/$STORY_ID/owners \ -H "X-TrackerToken: $TRACKER_TOKEN" \ -H "Content-Type: application/json" \ -d '{}'Een lege body betekent de aanroeper, dus de agent hoeft zijn eigen id niet te kennen. Het board toont de agent nu als eigenaar, en zo weet een meekijkende mens dat het werk is opgepakt.
Hem starten.
curl -X POST https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories/$STORY_ID/transitions \ -H "X-TrackerToken: $TRACKER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"to": "started"}'Daarna gaat de agent het werk doen — de repo lezen, de code schrijven, de pull request openen. Dat deel gebeurt in je ontwikkeltool, niet hier.
De pull request koppelen.
curl -X POST https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories/$STORY_ID/links \ -H "X-TrackerToken: $TRACKER_TOKEN" \ -H "Content-Type: application/json" \ -d '{"url": "https://github.com/octocat/hello-world/pull/42"}'Een GitHub-pull-request-URL wordt als zodanig herkend — je hoeft het er niet bij te zeggen. De story en de code die hem afsluit liggen nu in beide richtingen één klik uit elkaar.
Hem afronden. Ga naar finished en stop daar. Een feature heeft delivered en accepted nog voor zich, en dat zijn de reviewpoorten: iemand anders dan de agent besluit dat het werk klopt. Een chore heeft die poort niet — started → accepted is haar hele resterende pad.

Tokens en rate limits
Section titled “Tokens en rate limits”Elke import authenticeert zich. Het ophalen van issues, opmerkingen en pull requests loopt via GitHubs GraphQL-API, en GraphQL weigert een verzoek zonder token — er is geen anonieme laag, niet bij een publieke repository en niet bij een private. De vraag is nooit of er een token naar GitHub gaat, alleen wiens.
Je eigen token
Section titled “Je eigen token”Geef token mee bij de importaanroep, of --token aan GitHub-to-EAT. Een fijnmazig personal access token met leestoegang tot de issues van de repository volstaat. Het stuurt de bovenstroomse GitHub-aanroepen aan en verder niets: het wordt nooit gelogd, nooit in het auditlog gezet, nooit opgeslagen en nooit teruggegeven in een antwoord of een fout.
Neem je eigen token mee voor alles voorbij een demo. Dan geef je een budget uit waar niemand anders aan zit, en kan geen voorcontrole je weigeren vanwege de import van iemand anders.
--engine direct laat je geen keuze. Die engine leest GitHub vanaf jouw machine in plaats van via de Tracker, dus het token van de server is buiten bereik; een run zonder token stopt met 2 en een gebruiksfout voordat hij ophaalt of schrijft. GITHUB_TOKEN in je omgeving of je .env telt net zo goed als --token.
Wat het token afdwingt is de doorloop van de issues, niet de hele engine. direct leest issues, reacties en pull requests via GraphQL, dat geen anonieme modus kent; REST raakt hij alleen aan voor de release-lijst en de gratis /rate_limit-peiling. Het gereedschap levert nog steeds een oudere anonieme REST-ophaler mee die een import van een publieke repository binnen het budget van 60 per uur draaide, maar geen enkel CLI-pad bereikt hem nog en hij wordt verwijderd — beschouw --token dus als verplicht voor direct.
Het gedeelde token van de deployment
Section titled “Het gedeelde token van de deployment”Stuur geen token mee en de server zet het platformtoken in dat de beheerder heeft ingesteld (GITHUB_IMPORT_PAT). Er horen drie grenzen bij:
- Het is optionele configuratie. Het gehoste eastagiletracker.com voorziet er een, dus daar werkt een import van een publieke repository zonder token. Een zelfgehoste installatie — het gedownloade binaire bestand — heeft er geen totdat de beheerder
GITHUB_IMPORT_PATin de omgeving instelt, en tot die tijd weigert die elke import zonder token met400import_github_no_token. - Het leest alleen publieke repositories. De gehoste dienst geeft het alleen-lezen uit over publieke repos, dus een private repository heeft altijd je eigen token nodig.
- Elke aanroeper op de deployment deelt één budget. Voordat een import zonder token draait, leest de server de resterende GraphQL-punten van het gedeelde token en weigert onder de 500 met
400import_github_shared_quota_low. Een budget dat halverwege de import opraakt, laat de job falen metimport_github_rate_limited_platform. Beide meldingen noemen dezelfde oplossing: lever je eigen token aan.
Wat het token oplevert
Section titled “Wat het token oplevert”GitHub meet zijn twee API’s afzonderlijk, en het niet-geauthenticeerde plafond ligt twee ordes van grootte lager.
| GitHub-API | Gebruikt voor | Met token | Zonder token |
|---|---|---|---|
| GraphQL | Issues, opmerkingen, pull requests, sub-issues, afhankelijkheden | 5.000 punten per uur, gescoord op de nodes die een query teruggeeft | Geweigerd — GraphQL heeft geen anonieme laag |
| REST | Releases (include_releases) en de /rate_limit-voorcontrole | 5.000 verzoeken per uur | 60 verzoeken per uur, per IP-adres geteld en gedeeld met iedereen erachter |
Een import valt nooit terug op die laag van 60 per uur: zonder token om te sturen wordt het verzoek meteen geweigerd in plaats van anoniem opnieuw geprobeerd. Het getal doet ertoe voor wat je rondom de import doet — een script dat GitHub rechtstreeks leest, of een shell in hetzelfde netwerk als andere clients, put 60 verzoeken in seconden uit.
Lees je resterende budget wanneer je wilt; GET /rate_limit is van beide limieten vrijgesteld, dus de controle kost niets:
curl -H "Authorization: Bearer $GITHUB_TOKEN" https://api.github.com/rate_limitGraphQL-punten zijn geen verzoeken. GitHub scoort een query op de nodes die hij teruggeeft, dus één pagina van 100 issues met hun opmerkingen en toegewezen personen kost veel punten, en een grote repository geeft het uurbudget uit in veel minder aanroepen dan de getallen uit het REST-tijdperk doen vermoeden. --dry-run (stap 3) en dry_run (stap 4) kosten elk dezelfde punten als het echte ophalen — dat is wat hun tellingen betrouwbaar maakt — dus reken op twee passages als je een grote import voorbereidt.
Waar je hierna heen gaat
Section titled “Waar je hierna heen gaat”- API-gids — de zoekgrammatica, de gebeurtenisstroom, bulkovergangen, idempotente schrijfacties en de rest van het oppervlak.
- Bedieningsinstructies — dezelfde handelingen vanuit de interface, en de andere tien importeurs.
- Inleiding — waarom de toestandsmachine en de vier storytypen deze vorm hebben.
- GitHub-to-EAT — de repository van de importeur: elke vlag, beide engines, en hoe je eraan bijdraagt.