{
  "markdown": "# gemma-e2e-android\n\nRun end-to-end tests from natural-language prompts, on an Android device or in\nChrome. You write something like *\"check that the user can log in\"*; an agent\ndriven by a local [Gemma](https://ai.google.dev/gemma) model reads the live UI\ntree, decides the next tap or type, performs it, and judges whether the goal was\nmet. Everything runs on your machine — the LLM is served locally by LM Studio,\nso no screenshots or app data leave it.\n\nEach test case names its own target, so one scenario can cover both platforms\nand the prompts stay the same on either.\n\n## How it works\n\n```text\n              ┌── adb uiautomator dump ──┐\nscenario ─▶   │                          ├─▶ UI tree (text)\nprompt        └── CDP DOM walk ──────────┘         │\n                     ▲                      Gemma 4 (LM Studio)\n                     │                             │\n              tap / type / scroll ◀── structured Action\n                     │\n                     ▼\n     Firestore history + screenshots + video ─▶ dashboard (live via SSE)\n```\n\nBoth platforms produce the same `UiNode` tree, so the serializer the model\nreads, the action vocabulary it answers in, and the prompt behind it are one\nimplementation rather than two.\n\n## Repository layout\n\n| Path | What it is |\n| --- | --- |\n| `packages/core` | Shared Zod schemas (UI tree, actions, runs) and the YAML scenario loader |\n| `packages/adb` | adb wrapper: UI dump parsing and input commands |\n| `packages/cdp` | Chrome DevTools Protocol client: page reading, input, screencast |\n| `packages/agent` | Genkit-based decision loop, and the drivers that adapt each platform to it |\n| `packages/store` | Run/step history in Firestore (local emulator via `firebase-admin`) |\n| `apps/web` | Dashboard: Hono API + SSE, Vite/React/MUI frontend |\n| `apps/cli` | `gemma-e2e` command-line client for the dashboard API |\n| `apps/example-shared` | \"Kexi Coffee Shop\" domain data, so the two fixture apps cannot disagree |\n| `apps/example-android` | The Expo build of the shop, driven over adb |\n| `apps/example-web` | The browser build of the shop, driven over CDP |\n| `scenarios/` | Test scenarios (`*.yaml`) — natural-language goals, each naming an Android or web target |\n| `e2e/scenarios/` | CLI test scenarios (`*.yaml`) — [pitty](https://github.com/kexi/pitty) cases that drive the `gemma-e2e` binary itself |\n\nThe two scenario directories are unrelated despite the similar names.\n`scenarios/` is *input to the product*: prompts Gemma executes against the\nemulator or the browser. `e2e/scenarios/` is *test code for the CLI*: PTY\nsessions asserting what `gemma-e2e` prints and which exit code it returns.\n\n## Quick start\n\n```sh\ndirenv allow      # devshell: every CLI tool, the Android SDK, and the emulator\njust install      # JavaScript dependencies\njust llm          # start LM Studio's local API (manual app install required)\njust web          # dashboard → http://localhost:5173\n```\n\nThen bring up whichever platform a scenario targets:\n\n```sh\n# Android (scenarios/login.yaml, shop.yaml)\njust emu          # boot the emulator          (first time: just avd-create)\njust android      # build & install the example app\n\n# Web (scenarios/login.web.yaml, shop.web.yaml)\njust example-web  # the shop, in the browser → http://localhost:5174\njust chrome       # Chrome with the DevTools port the driver connects to\n```\n\n`just --list` shows every task; `just check` runs the same gates as CI.\nFull onboarding, including Nix/direnv and LM Studio setup: [SETUP.md](SETUP.md).\n\n## CLI\n\n`gemma-e2e` drives the same API the dashboard uses, so scenarios and runs can be\nmanaged from a terminal or a CI job. It needs the dashboard running (`just web`).\n\n```sh\njust cli          # compile ./apps/cli/dist/gemma-e2e for this machine\njust cli-dist     # cross-compile for macOS, Linux, and Windows\n```\n\n```sh\ngemma-e2e scenario list                  # every scenario the server knows\ngemma-e2e scenario get login             # one scenario and its cases\ngemma-e2e scenario apply scenarios/*.yaml  # create or update from YAML\ngemma-e2e scenario delete login\n\ngemma-e2e run start login --watch        # run a scenario, follow it, exit with its verdict\ngemma-e2e run start --prompt \"buy a coffee\" --title Coffee\ngemma-e2e run list                       # the most recent runs\ngemma-e2e run get <runId>                # one run, its cases and steps\ngemma-e2e run watch <runId>              # follow a run already in flight\n\ngemma-e2e models                         # models the LLM endpoint serves\ngemma-e2e device                         # emulator status\n```\n\nThe server is taken from `--server`, then `GEMMA_E2E_SERVER`, then\n`http://127.0.0.1:5175`. `--json` prints raw API responses (`run watch` emits\none JSON document per line), and colour turns off under `NO_COLOR`, `--no-color`,\nor a non-TTY stdout.\n\nExit status makes the CLI usable as a CI gate directly:\n\n| Code | Meaning |\n| --- | --- |\n| 0 | the command succeeded, or the run passed |\n| 1 | the run failed |\n| 2 | the command could not be carried out (bad usage, unreachable server, errored run) |\n\n```sh\ngemma-e2e run start checkout --watch || exit $?\n```\n\nCross-compilation covers macOS (arm64/x64), Linux (x64/arm64), and Windows\n(x64). musl targets such as Alpine are not built yet.\n\n### CLI end-to-end tests\n\n[pitty](https://github.com/kexi/pitty) runs the compiled binary on a real PTY\nand asserts its output, exit codes, and argument handling. It ships with the\ndevshell, so no separate install is needed.\n\n```sh\njust cli-e2e                # compiles the binary, then runs e2e/scenarios/\njust cli-e2e-server         # needs `just web` up\njust cli-e2e-server-models  # needs `just web` up *and* LM Studio serving\n```\n\n`e2e/scenarios/` needs no server: it covers `--help` / `--version`, usage errors\nand their exit codes, the `--` option terminator, colour suppression, local\nscenario-file validation, and the guidance shown when the dashboard is\nunreachable. `e2e/scenarios/server/` is kept separate because it expects a live\ndashboard on `:5175`; `just cli-e2e` does not descend into it.\n\nWithin that directory `models.yaml` is split off again and run only by\n`just cli-e2e-server-models`, because `models` is the one read-only command that\nreaches past the dashboard: `/api/models` proxies LM Studio, and with LM Studio\ndown the server answers 503 and the CLI exits 2. `just cli-e2e-server` names\n`read-only.yaml` explicitly so it stays green with only `just web` running.\n\n`just check` deliberately leaves these out — pitty has to compile the binary\nfirst, which is far slower than the rest of the gates. Run `just cli-e2e`\nalongside `just check` when touching `apps/cli`.\n\n## Documentation\n\n- [SETUP.md](SETUP.md) — development environment onboarding\n- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) — overview and data flow\n- [docs/knowledge/](docs/knowledge/index.md) — every technical decision, one file each (OKF v0.2)\n\n日本語版: [docs/ja/SETUP.md](docs/ja/SETUP.md) / [docs/ja/ARCHITECTURE.md](docs/ja/ARCHITECTURE.md) / [docs/ja/knowledge/](docs/ja/knowledge/index.md)\n\n## License\n\n[MIT](LICENSE)\n",
  "bytes": 7118,
  "sha": "b594985209a01adb90ae4fd3b1e33b0bbbee04b4ccc67346ce9ea7dc9937bcb5",
  "repo_slug": "kexi/gemma-e2e-android",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/okf_kexi_gemma_e2e_android_docs_knowledge_in_0c64361f/readme"
}