Apunta un agente a un repositorio de GitHub y recibes un tablero operativo: cada issue como una historia, en el estado que dicta su historial, con las listas de tareas, las etiquetas y los milestones trasladados. Después ese mismo agente toma una historia, la reclama, la mueve por la máquina de estados y enlaza el pull request que abrió.
Esta página recorre ese ciclo de principio a fin. El paso de poblado tiene dos rutas: GitHub-to-EAT, el importador de código abierto de East Agile, lo hace en un solo comando (paso 3); la API de importación hace el mismo trabajo llamada a llamada (pasos 4 y 5), que es lo que conduce un agente cuando quiere el identificador del trabajo. Todo lo demás va por la API, porque el objetivo es que un agente pueda hacer el resto sin supervisión.
Esto no es una «importación con IA» aparte. El paso de poblado usa el mismo importador de GitHub que puedes ejecutar a mano desde Ajustes del proyecto → Importar / Exportar, descrito en Instrucciones de uso → Importar desde otras herramientas. El agente llama al mismo endpoint que llamarías tú. Lo que añade esta página es todo lo que lo rodea: quién guarda la clave, cómo comprobar la importación antes de que escriba, y qué hace el agente con el tablero una vez existe.

Lo que necesitas
Sección titulada «Lo que necesitas»- Un proyecto — y una sesión o una clave
ea_user_…para crearlo. - Una clave de agente — una clave
ea_agent_…limitada a ese proyecto. El rol que necesita depende de cuánto del ciclo quieras que ejecute el agente; consulta el paso 2. Consulta también Guía de la API → Dos tipos de claves. - Un token de acceso personal de GitHub — con acceso de lectura a las issues del repositorio. Toda importación se autentica, porque la descarga va por la API GraphQL de GitHub y GraphQL rechaza una petición que no lleva token. Solo puedes omitirlo cuando el Tracker descarga en tu nombre: un repositorio público, en un despliegue que tiene un token compartido de reserva (el alojado eastagiletracker.com tiene uno; una instalación autoalojada no tiene ninguno hasta que su operador defina
GITHUB_IMPORT_PAT), y nunca con--engine directde GitHub-to-EAT. Consulta Tokens y límites de uso. - Node.js 22+ — solo para la ruta de GitHub-to-EAT del paso 3. La ruta por API no necesita más que
curl.
1. Crear el proyecto
Sección titulada «1. Crear el proyecto»El proyecto tiene que existir antes que la clave de agente, y tiene que crearlo una persona: las claves de agente quedan ligadas a un proyecto al emitirse y no pueden crear proyectos. Créalo en la interfaz, o con tu propia clave ea_user_…:
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}'La respuesta lleva el project_id que necesitan todas las llamadas de abajo.
2. Emitir una clave de agente
Sección titulada «2. Emitir una clave de agente»Un propietario del proyecto crea las claves de agente en Ajustes del proyecto → Agentes. El rol que elijas decide cuánto de esta página puede hacer el agente por su cuenta, y hay dos respuestas sensatas:
owner— una sola clave ejecuta todo el ciclo, importación incluida. Importar es exclusivo del propietario, porque una importación reescribe la forma del proyecto entera. Emitir un agente con rolownerexige que tú mismo seas propietario del proyecto: el rol de un agente nunca puede superar al de quien lo creó.member— mínimo privilegio. El agente reclama historias, las mueve, comenta y enlaza pull requests, pero no puede importar. La importación la ejecutas tú (paso 5) con tu propia clave y luego le entregas el tablero al agente.
En cualquier caso, no lo dejes en el valor por defecto. Una clave de agente nueva es viewer mientras no digas otra cosa, y un viewer puede leer el tablero pero no reclamar ni mover una historia — que es casi todo este ciclo.
Las claves de agente importan aquí por una razón que va más allá del acceso. Una clave de agente actúa como participante con nombre en un solo proyecto, así que cada historia que crea, cada cambio de estado que hace y cada comentario que escribe se le atribuye a ese agente en el historial — distinguible de tu propio trabajo en lugar de mezclado con él.
export TRACKER_TOKEN="ea_agent_xxxxx"Haz que el agente lea /meta antes que nada:
curl https://eastagiletracker.com/api/v1/meta \ -H "X-TrackerToken: $TRACKER_TOKEN"Eso responde las dos preguntas que el agente tendría que adivinar: a qué proyecto está ligada la clave (auth.project_id) y qué cambios de estado son legales para cada tipo de historia (transitions). Una feature recorre unstarted → started → finished → delivered → accepted; una chore es solo unstarted → started → accepted. Leer el mapa gana a codificarlo a mano.
3. Importar con GitHub-to-EAT
Sección titulada «3. Importar con GitHub-to-EAT»GitHub-to-EAT es el importador de código abierto de East Agile: una herramienta de línea de comandos con licencia MIT que hace todo el paso de poblado — los pasos 4 y 5 de abajo — en un solo comando. Recurre a ella cuando hay una persona ante un terminal. Recurre a la API que hay debajo cuando conduce un agente sin supervisión y quiere el identificador del trabajo para consultarlo.
Necesita Node.js 22+ y no tiene dependencias de ejecución propias. Todavía no está publicada en npm, así que instálala desde el repositorio:
git clone git@github.com:EastAgile/GitHub-to-EAT.gitcd GitHub-to-EATnpm install --global .Después apúntala a la clave que emitiste en el paso 2 y al proyecto que hiciste en el paso 1:
export EAT_AGENT_KEY="ea_agent_xxxxx"github-to-eat --project $PROJECT_ID --repo octocat/hello-worldPrimero imprime una leyenda de correspondencias — exactamente cómo va a aterrizar cada tipo seleccionado — y te pide confirmación antes de escribir nada. Fuera de un terminal, en una tubería, en CI o dentro de un agente, no hay dónde mostrar esa pregunta, así que una ejecución que fuera a escribir tiene que pasar --yes; sin él la herramienta sale con 2 y no escribe nada en lugar de adivinar tu respuesta. Volver a ejecutarla es seguro: lo ya importado se salta, nunca se duplica.
| Bandera | Qué hace |
|---|---|
--dry-run | Comprobación previa y luego imprime el plan que llevaría a cabo — cuántas historias importaría, cuántas saltaría por estar ya ahí — sin escribir nada. No necesita --yes. |
--include | Qué tipos importar, separados por comas: issues,prs,milestones,releases,deps. Por defecto issues, y toda selección tiene que contenerlo. Son las mismas opciones que la tabla del paso 6. |
--token | Tu token de acceso personal de GitHub (GITHUB_TOKEN en el entorno o en un .env también cuenta). Necesita repo, o el permiso granular Issues: Read, sobre ese repositorio. Obligatorio para un repositorio privado, para un servidor sin token compartido de reserva y siempre para --engine direct. Omítelo en el motor por defecto del servicio alojado y el Tracker gasta su propio presupuesto compartido — consulta Tokens y límites de uso. |
--engine | server, el valor por defecto, envía una sola llamada /import/json y deja que el Tracker descargue, mapee y escriba. direct ejecuta esa misma tubería en tu máquina y escribe a través de la API pública — así que lee GitHub él mismo y siempre necesita un token, saliendo con 2 sin él. |
--states, --milestones, --story-type, --no-comments, --no-tasks | Acotan o sobrescriben la correspondencia para una ejecución; nada se persiste. Cada una implica --engine direct. |
Define EAT_API_BASE y EAT_APP_BASE para apuntarla a un Tracker autoalojado o local; ambas apuntan por defecto al servicio alojado. El README lleva la referencia completa de banderas, los códigos de salida y la resolución de problemas.
Todo lo de abajo es esa misma importación conducida llamada a llamada, que es lo que quieres cuando la ejecuta un agente.
4. Primero una prueba en seco
Sección titulada «4. Primero una prueba en seco»Importar es exclusivo del propietario — usa una clave de agente con rol owner, o tu propia clave si dejaste al agente como member. Ejecútala primero con dry_run, antes de dejar que escriba nada:
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 }'Una prueba en seco descarga de GitHub, resuelve y de-duplica exactamente igual que la real, informa de los mismos recuentos — imported, skipped, errors, unmatched — y luego revierte toda la transacción. Nada persiste y ningún evento de importación completada llega a tu registro de auditoría. Es la forma más barata de descubrir que querías incluir los milestones, o que un repo es mayor de lo que creías, mientras todavía no te cuesta nada.
Toda llamada a /import/json es asíncrona, la prueba en seco incluida: el endpoint devuelve 202 con un identificador de trabajo, no un resultado, y los recuentos llegan en el trabajo cuando lo consultas (paso 5). El trabajo de una prueba en seco alcanza done igual que el de una real; la diferencia es que no se escribió nada.
5. Ejecutar la importación
Sección titulada «5. Ejecutar la importación»Quita dry_run y vuelve a enviarla. Como antes, el endpoint devuelve 202 con un identificador de trabajo:
{ "import_id": "…", "status": "pending" }Consulta el trabajo hasta que alcance un estado terminal:
curl https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/imports/$IMPORT_ID \ -H "X-TrackerToken: $TRACKER_TOKEN"El estado recorre pending → fetching → writing → done | failed. Solo los dos últimos son terminales: done lleva los recuentos del resultado, failed lleva un mensaje de error y un código de máquina estable sobre el que ramificar. Mientras la descarga pagina, progress_current y progress_total dicen por qué página va — merece la pena mostrarlo si hay una persona mirando.
Tokens. Pasa "token": "github_pat_…". Omítelo y el servidor pone el token de plataforma compartido, que solo lee repositorios públicos y cuya cuota se descuenta entre todos los llamantes del despliegue — Tokens y límites de uso cubre lo que eso te cuesta. Sea cual sea el token que se use, sirve para las llamadas ascendentes a GitHub y para nada más: nunca se registra, nunca se audita, nunca se almacena y nunca se devuelve en una respuesta ni en un error.
Volver a ejecutarla es seguro. Una fila ya importada se reconoce por su id de origen y se salta, no se duplica. Una segunda importación completa el tablero con lo que ha aparecido desde la primera.
6. Qué aterriza en el tablero
Sección titulada «6. Qué aterriza en el tablero»Las issues se importan por defecto. Todo lo demás es opcional, una bandera por tipo:
| Desde GitHub | Se convierte en | Bandera |
|---|---|---|
| Issue | Una historia. Abierta → unstarted en el Backlog. Cerrada → accepted, o rejected cuando GitHub dice que la issue se cerró como not_planned o duplicate (la historia lleva entonces una etiqueta acorde). | por defecto |
| Lista de tareas del cuerpo de la issue | Tareas — cada línea - [ ] / - [x] se convierte en una tarea en el orden del cuerpo, y [x] llega completada. La lista también permanece en la descripción. | por defecto |
| Etiquetas | Etiquetas, trasladadas tal cual. | por defecto |
| Pull request | Una historia con la etiqueta pull-request. Abierto → started, fusionado → accepted, cerrado sin fusionar → rejected. | include_pull_requests |
| Milestone | Una épica, titulada como el milestone y de-duplicada por título — dos issues que comparten milestone caen en una misma épica. Con la bandera desactivada viaja como etiqueta milestone:<título>. | include_milestones |
| Release | Una historia de release. Publicada → accepted, borrador → unstarted. | include_releases |
| Dependencia de issue | Un bloqueo sobre la historia. Solo issues, nunca pull requests. | include_dependencies |
El tipo de historia se infiere cuando la issue no lo dice. Una etiqueta que contenga bug, fix o defect — o un título que empiece por fix o bug — la convierte en un bug; chore, maintenance, devops o infra la convierten en una chore; cualquier otra cosa es una feature. Conviene saberlo antes de importar, porque en East Agile Tracker solo las features llevan puntos y solo las features alimentan la velocidad. Consulta Introducción → Historias.

7. El agente trabaja una historia
Sección titulada «7. El agente trabaja una historia»Ahora el tablero tiene historial y el agente tiene una clave. A partir de aquí el ciclo son cuatro llamadas.
Encontrar una historia, o escribir una. Filtra el tablero buscando algo que tomar:
curl "https://eastagiletracker.com/api/v1/projects/$PROJECT_ID/stories?state=unstarted" \ -H "X-TrackerToken: $TRACKER_TOKEN"import_source=github lo acota a lo que trajo la importación. Si el agente ha encontrado trabajo que el repo nunca capturó, crea la historia en su lugar — consulta Guía de la API → Crear una historia.
Reclamarla. Un agente se añade como propietario enviando un cuerpo vacío:
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 '{}'Un cuerpo vacío significa quien llama, así que el agente no necesita conocer su propio id. El tablero muestra ya al agente como propietario, que es como una persona que mira sabe que el trabajo está tomado.
Empezarla.
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"}'Después el agente va y hace el trabajo — lee el repo, escribe el código, abre el pull request. Esa parte ocurre en tu herramienta de programación, no aquí.
Adjuntar el pull request.
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"}'Una URL de pull request de GitHub se reconoce como tal — no hace falta decirlo. La historia y el código que la cierra quedan a un clic una del otro, en ambas direcciones.
Terminarla. Pásala a finished y párate ahí. A una feature aún le quedan delivered y accepted por delante, y esas son las puertas de revisión: alguien distinto del agente decide que el trabajo está bien. Una chore no tiene esa puerta — started → accepted es todo su camino restante.

Tokens y límites de uso
Sección titulada «Tokens y límites de uso»Toda importación se autentica. La descarga de issues, comentarios y pull requests va por la API GraphQL de GitHub, y GraphQL rechaza una petición que no lleva token — no hay nivel anónimo, ni en un repositorio público ni en uno privado. La pregunta nunca es si llega un token a GitHub, solo de quién.
Tu propio token
Sección titulada «Tu propio token»Pasa token en la llamada de importación, o --token a GitHub-to-EAT. Basta con un token de acceso personal granular con acceso de lectura a las issues del repositorio. Sirve para las llamadas ascendentes a GitHub y para nada más: nunca se registra, nunca se audita, nunca se almacena y nunca se devuelve en una respuesta ni en un error.
Trae el tuyo para cualquier cosa que pase de una demo. Así gastas un presupuesto que nadie más toca, y ninguna comprobación previa puede rechazarte por la importación de otro.
--engine direct no te deja elección. Ese motor lee GitHub desde tu máquina en vez de a través del Tracker, así que el token del servidor queda fuera de alcance; una ejecución sin token sale con 2 y un error de uso antes de descargar o escribir nada. GITHUB_TOKEN en tu entorno o en tu .env cuenta igual que --token.
Lo que obliga al token es el recorrido de las issues, no el motor entero. direct lee issues, comentarios y pull requests por GraphQL, que no tiene modo anónimo; solo toca REST para el listado de releases y la sonda gratuita /rate_limit. La herramienta todavía incluye un lector REST anónimo antiguo que ejecutaba una importación de repositorio público dentro del presupuesto de 60 por hora, pero ninguna ruta de la CLI llega ya hasta él y está previsto borrarlo, así que trata --token como obligatorio para direct.
El token compartido del despliegue
Sección titulada «El token compartido del despliegue»No envíes ningún token y el servidor pondrá el token de plataforma que configuró su operador (GITHUB_IMPORT_PAT). Vienen con él tres límites:
- Es configuración opcional. El alojado eastagiletracker.com provisiona uno, así que allí funciona una importación de repositorio público sin token. Una instalación autoalojada — el binario descargado — no tiene ninguno hasta que su operador defina
GITHUB_IMPORT_PATen el entorno, y hasta entonces rechaza toda importación sin token con400import_github_no_token. - Solo lee repositorios públicos. El servicio alojado lo emite de solo lectura sobre repos públicos, así que un repositorio privado siempre necesita tu propio token.
- Todos los llamantes del despliegue comparten un presupuesto. Antes de que corra una importación sin token, el servidor lee los puntos GraphQL que le quedan al token compartido y la rechaza con
400import_github_shared_quota_lowpor debajo de 500. Un presupuesto que se agota a mitad de importación hace fallar el trabajo conimport_github_rate_limited_platform. Ambos mensajes nombran el mismo remedio: aportar tu propio token.
Qué te compra el token
Sección titulada «Qué te compra el token»GitHub mide sus dos API por separado, y el techo sin autenticar es dos órdenes de magnitud más bajo.
| API de GitHub | Se usa para | Con token | Sin token |
|---|---|---|---|
| GraphQL | Issues, comentarios, pull requests, sub-issues, dependencias | 5.000 puntos por hora, puntuados sobre los nodos que devuelve la consulta | Rechazado — GraphQL no tiene nivel anónimo |
| REST | Releases (include_releases) y la comprobación previa /rate_limit | 5.000 peticiones por hora | 60 peticiones por hora, contadas por dirección IP y compartidas con todos los que están detrás |
Una importación nunca cae a ese nivel de 60 por hora: sin token que enviar, la petición se rechaza de entrada en vez de reintentarse de forma anónima. El número importa por lo que haces alrededor de la importación — un script que lee GitHub directamente, o una shell en la misma red que otros clientes, agota 60 peticiones en segundos.
Lee tu presupuesto restante cuando quieras; GET /rate_limit está exento de ambos límites, así que la comprobación no cuesta nada:
curl -H "Authorization: Bearer $GITHUB_TOKEN" https://api.github.com/rate_limitLos puntos GraphQL no son peticiones. GitHub puntúa una consulta por los nodos que devuelve, así que una página de 100 issues con sus comentarios y asignados cuesta muchos puntos, y un repositorio grande gasta el presupuesto horario en muchas menos llamadas de lo que sugieren las cifras de la era REST. --dry-run (paso 3) y dry_run (paso 4) cuestan cada uno los mismos puntos que la descarga real — eso es lo que hace fiables sus recuentos — así que presupuesta dos pasadas cuando prepares una importación grande.
A dónde ir después
Sección titulada «A dónde ir después»- Guía de la API — la gramática de búsqueda, el flujo de eventos, las transiciones en lote, las escrituras idempotentes y el resto de la superficie.
- Instrucciones de uso — las mismas operaciones desde la interfaz, y los otros diez importadores.
- Introducción — por qué la máquina de estados y los cuatro tipos de historia tienen esta forma.
- GitHub-to-EAT — el repositorio del importador: cada bandera, ambos motores, y cómo contribuir.