Onboard a public GitHub repository's issues into an East Agile Tracker (EAT) project — in one command.
Status: the v1 CLI is built and works end-to-end against the bundled mock server. Running against production EAT additionally needs the server-side v1 features described in CONTRACT.md (owner-role agent keys, agent-callable import, optional token), which are tracked separately.
Point it at a public GitHub repo and an EAT project; the EAT server imports the
repo's issues into your project's backlog as stories — title, body + a link back
to the issue, open/closed state, and labels. Pull requests, milestones, and
releases are excluded by default; opt in with --include (see below).
Re-running an import never duplicates: items that were already imported are
skipped.
You never supply a GitHub token for public repos: the EAT server fetches the issues with a platform credential, so all you provide is your EAT project key.
- Node.js 22+
- An East Agile Tracker project and an owner-role agent API key (mint one in the SPA under Project Settings → API keys)
Until the tool is published to npm, install from source. First clone it:
git clone git@github.com:EastAgile/GitHub-to-EAT.git
cd GitHub-to-EATThe CLI has zero runtime dependencies, so installing it just puts the command on your PATH:
npm install --global .Or skip installing and run it straight from the clone:
node bin/github-to-eat.js --project <project id> --repo <owner>/<name>(Once the package is published, npx github-to-eat will work with no install
step at all.)
Copy the example env file and set your key. A local .env is loaded
automatically (and never overrides variables already in your environment).
cp .env.example .env
# edit .env: EAT_AGENT_KEY=<your owner-role agent key>| Variable | Required | Default | Description |
|---|---|---|---|
EAT_AGENT_KEY |
yes | — | Owner-role agent API key for the project |
EAT_API_BASE |
no | https://api.eastagiletracker.com/api/v1 |
API base URL (override for self-hosted/local) |
EAT_APP_BASE |
no | https://eastagiletracker.com |
Web app base URL, used for the board link |
GITHUB_TOKEN |
no | — | GitHub token for private repos (or use --token); public repos need none |
# Format
github-to-eat --project <project id> --repo <owner>/<name>
# Example: import github.com/octocat/hello-world into project 147
github-to-eat --project 147 --repo octocat/hello-worldExample output:
Importing octocat/hello-world into project 147 (My Board)...
Imported 42 stories (0 labels), skipped 0, 0 error(s).
Board: https://eastagiletracker.com/projects/147
Other flags:
github-to-eat --project 147 --repo octocat/hello-world --include issues,prs # also import pull requests
github-to-eat --project 147 --repo octocat/hello-world --dry-run # preflight only, no writes
github-to-eat --version
github-to-eat --helpBefore importing, the CLI prints a mapping legend — exactly how each
selected GitHub type lands in EAT — and asks for confirmation ([y/N],
defaulting to no). Pass --yes/-y to skip the prompt.
Off a terminal (pipes, CI, agents) there is nowhere to show that prompt, so a
run that would write must pass --yes. Without it the CLI exits 2 with a
usage error and writes nothing — it never guesses your answer. --dry-run is
exempt: it writes nothing, so it needs no --yes and prints the same legend.
--include chooses what gets imported (default: issues). Every selection
must contain issues — the other types only add to an issue import:
prs— pull requests become stories: open → started, merged → accepted (with apull-requestlabel), closed-unmerged → rejected; a merged PR that closes an imported issue folds into that issue's story instead of creating its own.milestones— GitHub milestones become epics.releases— GitHub Releases become release-type stories (tag → title, notes → description, publish date kept).
By default every issue is imported with the standard mapping. To narrow or
override that for a single run — nothing is persisted — pick one of two ways.
Both are direct-engine only, and imply --engine direct:
- Interactively:
--customizeasks the questions one at a time on your terminal (it needs one, and refuses to run off a TTY). - Declaratively: the flags below need no terminal, so agents, scripts, and CI can drive them:
| Flag | Values | Default |
|---|---|---|
--states |
all, open, closed |
all |
--milestones |
milestone titles, matched exactly; comma-separated, repeatable | every milestone |
--story-type |
infer, feature, bug, chore |
infer (from labels/title) |
--no-comments |
— | comments are imported |
--no-tasks |
— | body checklists become tasks |
github-to-eat --project 147 --repo octocat/hello-world \
--states open --milestones "v1.0,v1.1" --no-comments --yes--milestones can also be repeated (--milestones v1.0 --milestones v1.1), and
\, inside a title is a literal comma — --milestones 'v1.0\, beta' selects the
single milestone named v1.0, beta.
The choices are echoed in a Customized: block under the legend, so the plan is
visible before anything is written — and under --dry-run, which writes nothing.
A milestone title no matching issue carries is called out with a warning rather
than silently importing nothing, and so is a set of filters that together match
no issue at all (--states open --milestones v2.0, where v2.0 is only on
closed issues, warns on both counts).
The two ways are mutually exclusive: combining a customization flag with
--customize is a usage error, since a run either declares its answers or asks
to be asked for them.
--dry-run validates your key, the project, and connectivity (and warns if the
project already has stories), then asks the server for a real, dedup-aware
import plan — how many stories it would import and how many it would skip
as already imported — without writing anything. Against older servers that
don't support plan computation, it falls back to a local preview.
Private repos: public repos need no GitHub token (the server uses its platform
credential). For a private repo — or a server without that platform credential
— supply a GitHub token with --token <TOKEN> or the GITHUB_TOKEN env var (it
needs repo, or fine-grained Issues: Read, on that repo).
| Code | Meaning |
|---|---|
0 |
Success |
1 |
Runtime error (bad key, project not found, timeout) or the import reported per-item errors |
2 |
Usage error (bad or missing arguments, or a writing run off a terminal without --yes) |
no interactive terminal to confirm on— the run would write but has no TTY to show the[y/N]prompt on (a pipe, CI, an agent). Add--yesto import without confirmation, or--dry-runto preview the plan instead.authentication failed— checkEAT_AGENT_KEYis an owner-role agent key for this project and hasn't been revoked.not found: /projects/<id>— the project id is wrong or the key can't access it.... timed out— a large repo can take a while; the server may still be finishing. Check the board in a moment, or re-run. (v2 will stream progress.)
See CONTRIBUTING.md for the dev setup, tests, and linting.