diff --git a/CLAUDE.md b/CLAUDE.md index 2423e6e..a80e644 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -18,7 +18,7 @@ Project-wide Claude Code instructions. Keep this file short — it's loaded into - **Host language:** TypeScript (Claude Agent SDK `@anthropic-ai/claude-agent-sdk`) - **Ruby subprocesses** for Rails AST / ERB / migration work (called from TypeScript) -- **External MCP:** [`mobile-next/mobile-mcp`](https://github.com/mobile-next/mobile-mcp) for iOS Simulator + Android Emulator UI automation (`npx -y @mobilenext/mobile-mcp@latest`) +- **External MCP:** [`mobile-next/mobile-mcp`](https://github.com/mobile-next/mobile-mcp) for iOS Simulator + Android Emulator UI automation. **Pin `npx -y @mobilenext/mobile-mcp@0.0.54`** — 0.0.55+ closes the stdio connection on startup (the pin lives in `src/mobile.ts` and the plugin's `.mcp.json`). - **Node 22+ required.** ## Coding conventions @@ -110,11 +110,12 @@ Each is an independent, buildable git repo. ## Packaging -Ships as two surfaces today: +Ships as three surfaces today: - `npx nativeapptemplate-agent "your spec"` — standalone CLI (primary) - `npx -y -p nativeapptemplate-agent nativeapptemplate-agent-mcp` — stdio MCP server wrapping `dispatch()` as a `generate_app` tool, for any MCP-capable assistant (Claude Code, Cursor, Cline, Goose). The distribution multiplier. (The `-mcp` entry point is a *bin* of the `nativeapptemplate-agent` package, not its own package — hence `-p`; `npx -y nativeapptemplate-agent-mcp` 404s.) +- **Claude Code plugin** in `plugin/` — `claude --plugin-dir ./plugin` loads two skills: `/nativeapptemplate-agent:generate-app` (generate → validate → explain) and `/nativeapptemplate-agent:walk-app` (drive the running app via `mobile-mcp`). Bundles the generator MCP server + mobile-mcp. See `plugin/README.md`. -A Claude Code plugin (slash command + orchestration skill) is **post-v0.1 backlog**, gated on streaming progress out of `dispatch()` and a skill that chains validation + a `mobile-mcp` walkthrough — against today's single-tool MCP a plugin would be a thin wrapper. See `ROADMAP.md` → Post-v0.1 backlog. +Plugin `.mcp.json` pins are load-bearing: `nativeapptemplate-agent@latest` (MCP servers spawn with cwd = repo root; without `@latest`, `npx -p` resolves the *local* package and fails) and `@mobilenext/mobile-mcp@0.0.54` (0.0.55+ closes stdio). ## Hackathon success criteria (quick reminder — details in docs/SPEC.md section 11) diff --git a/README.md b/README.md index 006f64a..6027ae5 100644 --- a/README.md +++ b/README.md @@ -126,7 +126,7 @@ tree ./out/clinic-queue/ # └── validation-report.html ← self-contained visual report (open in a browser) ``` -The same generator also ships as an MCP server — `npx -y -p nativeapptemplate-agent nativeapptemplate-agent-mcp` exposes a `generate_app` tool, so any MCP-capable assistant (Claude Code, Cursor, Cline, Goose) can invoke it without leaving the editor. A Claude Code plugin (a discoverable slash command plus an orchestration skill that chains validation and a `mobile-mcp` walkthrough) is planned post-v0.1 — see the [roadmap](./ROADMAP.md#post-v01-backlog). +The same generator also ships as an MCP server — `npx -y -p nativeapptemplate-agent nativeapptemplate-agent-mcp` exposes a `generate_app` tool, so any MCP-capable assistant (Claude Code, Cursor, Cline, Goose) can invoke it without leaving the editor. And a **Claude Code plugin** ships in [`plugin/`](./plugin/) — `claude --plugin-dir ./plugin` loads two skills: `/nativeapptemplate-agent:generate-app` (generate → validate → explain) and `/nativeapptemplate-agent:walk-app` (launch the app on a simulator/emulator and walk its UI via `mobile-mcp`, screenshots inline). See [`plugin/README.md`](./plugin/README.md). ## Requirements diff --git a/ROADMAP.md b/ROADMAP.md index b5a8a08..a196f47 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -31,7 +31,7 @@ The strategy is two-track. ### Track 1 — Open source (this repository) -`npx nativeapptemplate-agent "your spec"` — the CLI form of the agent, and the primary surface. A second surface ships alongside it: `npx -y -p nativeapptemplate-agent nativeapptemplate-agent-mcp`, a stdio MCP server exposing a `generate_app` tool so any MCP-capable assistant (Claude Code, Cursor, Cline, Goose) can invoke the agent without a terminal — the distribution multiplier. Both target the free-edition substrate and require an Anthropic API key; every generation run reproduces end-to-end on the reviewer's machine. A Claude Code plugin is a planned third surface — see Post-v0.1 backlog. +`npx nativeapptemplate-agent "your spec"` — the CLI form of the agent, and the primary surface. A second surface ships alongside it: `npx -y -p nativeapptemplate-agent nativeapptemplate-agent-mcp`, a stdio MCP server exposing a `generate_app` tool so any MCP-capable assistant (Claude Code, Cursor, Cline, Goose) can invoke the agent without a terminal — the distribution multiplier. Both target the free-edition substrate and require an Anthropic API key; every generation run reproduces end-to-end on the reviewer's machine. A **Claude Code plugin** is the third surface (in [`plugin/`](plugin/)) — `claude --plugin-dir ./plugin` loads the `generate-app` and `walk-app` skills; see [Claude Code plugin](#claude-code-plugin) below. This track is permanent. It is not a free trial of a commercial product — it is how we believe a generator like this should ship by default in 2026. @@ -86,15 +86,14 @@ No interactive prompts — keeps the CLI scriptable and CI-friendly, no TTY assu ### Claude Code plugin -**Status: deferred.** Long named as a packaging surface, not yet built. The shipped MCP server (`nativeapptemplate-agent-mcp`) already covers in-assistant invocation across *every* MCP-capable client — strictly wider reach than a Claude-Code-only plugin. Against today's MCP, which wraps `dispatch()` as a single `generate_app` tool, a plugin would be a thin wrapper: a discoverable slash command plus a one-step install, and little else. +**Status: shipped.** Lives in [`plugin/`](plugin/); load it locally with `claude --plugin-dir ./plugin`. Two skills, bundling two MCP servers (the generator + `mobile-mcp`): -The plugin earns its place once there is depth for it to add — work that doesn't exist yet and that the bare MCP tool can't carry cleanly: +1. **`/nativeapptemplate-agent:generate-app `** — runs the generator, parses `out//report.json`, and explains per-platform / per-layer results, the domain mapping, and any failures with the specific evidence and the next move. +2. **`/nativeapptemplate-agent:walk-app ios|android`** — launches a generated app on a booted simulator/emulator and drives `mobile-mcp` to capture the home screen and walk the UI conversationally, screenshots inline. -1. **Streaming progress out of `dispatch()`** so a 3–5 min build-mode run isn't a frozen wait. (Flagged non-negotiable for the MCP surface in the monetization notes; the plugin inherits the same need.) -2. **An orchestration skill** that owns the *post*-generation story — chaining a `mobile-mcp` home-screen walkthrough, running the validation layers, and surfacing the report. This is genuinely plugin-shaped (a skill plus bundled MCP wiring), and it's the piece a single `generate_app` tool can't express. -3. **Bundling the generator MCP + `mobile-mcp` pre-wired** so "generate a clinic queue, then walk its home screen" works out of the box. +The original plan gated this on `dispatch()` streaming + an orchestration skill. In practice the skill carries the value without streaming: `generate-app` drives the CLI and narrates around it, delivering the post-generation story (validate → explain; generate → walk) with no streaming needed. Streaming remains a nice-to-have for the single-tool MCP surface, not a blocker for the plugin. -Gate building the plugin on (1) and (2) landing first; until then it adds slash-command discoverability over the MCP and not much more. +Verified end-to-end 2026-05-24: `generate-app` (barbershop-queue, all layers green) and `walk-app` (Android launch + interactive tap-through with inline screenshots on the Pixel emulator). ## What stays out of scope diff --git a/docs/SPEC.md b/docs/SPEC.md index 6097cbc..d70f3d7 100644 --- a/docs/SPEC.md +++ b/docs/SPEC.md @@ -27,14 +27,14 @@ This document was originally a **pre-hackathon specification** (v1.0). It's pres | §6 Layer 2 Stage 1 (boot, build, launch) | **Shipped** | Default behavior. | | §6 Layer 2 Stage 2 (UI-driven scenario) | **Shipped** | Behind `NATIVEAPPTEMPLATE_VISUAL=2`; see §5 Stage 2 row. The original spec mentioned an HTTP-tail watcher for 4xx/5xx; the actual implementation walks the UI directly and lets the scenario `wait_for_text`/`assert_text` catch error states. | | §7 Evaluation plan (3 specs × 3 platforms = 9 projects) | **Exceeded** | Validated against 12 PASS combinations (full 6-cell matrix × 2 platforms): free × 3 specs × 2 platforms (6) + paid × 3 specs × 2 platforms (6). Both new paid cells (sushi waitlist, task tracker) passed first-try with no code changes — strong evidence the parameterized scenario is genuinely edition-agnostic. | -| §8 Packaging (CLI + Claude Code plugin) | **Changed** | The planned Claude Code plugin was **not** built. The actually-shipped second surface is the **MCP server** (`nativeapptemplate-agent-mcp`, PR #60) — stdio, wrapping `dispatch()` as a `generate_app` tool, drivable from any MCP-capable assistant (Claude Code, Cursor, Cline, Goose) without the CLI. The §8 prose below still reads "two surfaces (CLI + plugin)" as the frozen pre-hackathon plan; **today's reality is CLI + MCP**, with the plugin deferred to ROADMAP → Post-v0.1 backlog (gated on streaming progress + an orchestration skill, since against the single-tool MCP a plugin would be a thin wrapper). | +| §8 Packaging (CLI + Claude Code plugin) | **Shipped (3 surfaces)** | Shipped surfaces are now **CLI + MCP server + Claude Code plugin**. The MCP server (`nativeapptemplate-agent-mcp`, PR #60) was added as the wide-reach surface. The Claude Code plugin (`plugin/`) was deferred mid-stream, then built post-launch on `epic/claude-code-plugin` — two skills (`generate-app`, `walk-app`) bundling the generator MCP + `mobile-mcp`, both verified end-to-end 2026-05-24. The §8 prose below ("two surfaces (CLI + plugin)") is the frozen pre-hackathon plan; today's reality is **CLI + MCP + plugin**. | | §8 Packaging — env bridging (new) | **Shipped** | At run time the agent mirrors `NATIVEAPPTEMPLATE_API_*` (HOST/PORT/SCHEME) into renamed-product variants (`_API_*`) so the generated Android app picks them up via `~/.gradle/gradle.properties` and the iOS sim launch picks them up via `SIMCTL_CHILD_*` (PR #64). Safety knobs: `NATIVEAPPTEMPLATE_BRIDGE=off` skips the file write; `NATIVEAPPTEMPLATE_BRIDGE_DRY_RUN=1` previews. | | §9 Non-goals (paid-edition features) | **Stable** | Paid-edition features (multi-tenancy URL routing, invitations, role permissions, org switching) remain out of the rename pipeline by design. The agent operates against paid substrates fine — it just doesn't generate new paid-only features into renamed projects. | | §11 Hackathon must-haves | **All met** | All Must-have + Stretch criteria green at v0.2.0; see release notes for the post-hackathon delta. | ### What changed structurally since v1.0 of this spec -- **Distribution surfaces: planned CLI + Claude Code plugin → shipped CLI + MCP server.** The MCP server replaced the plugin as the second surface — wider reach (every MCP client, not just Claude Code) for the same `dispatch()` core. The plugin is deferred to the Post-v0.1 backlog. +- **Distribution surfaces: planned CLI + Claude Code plugin → shipped CLI + MCP server + Claude Code plugin** (three). The MCP server was added as the wide-reach surface (every MCP client, same `dispatch()` core); the plugin (two skills, bundling the generator MCP + `mobile-mcp`) shipped post-launch on top. - **Substrate scope went from "free-only" to "free + paid"** without code changes; same pipeline. - **Validation went from "9 generated projects, target Layer 1+2 pass + Layer 3 score"** to a concrete 12-cell PASS matrix. - **Stage 2 went from aspirational ("stretch") to default-when-opted-in** (`NATIVEAPPTEMPLATE_VISUAL=2`). diff --git a/plugin/.claude-plugin/plugin.json b/plugin/.claude-plugin/plugin.json new file mode 100644 index 0000000..429f074 --- /dev/null +++ b/plugin/.claude-plugin/plugin.json @@ -0,0 +1,9 @@ +{ + "name": "nativeapptemplate-agent", + "version": "0.2.0", + "description": "Generate a validated three-platform SaaS app (Rails 8.1 API + SwiftUI iOS + Jetpack Compose Android) from a one-sentence spec, explain the validation report, and walk the running app on a simulator/emulator via mobile-mcp — without leaving Claude Code.", + "author": { "name": "Daisuke" }, + "homepage": "https://github.com/nativeapptemplate/nativeapptemplate-agent", + "repository": "https://github.com/nativeapptemplate/nativeapptemplate-agent", + "license": "MIT" +} diff --git a/plugin/.mcp.json b/plugin/.mcp.json new file mode 100644 index 0000000..29571ab --- /dev/null +++ b/plugin/.mcp.json @@ -0,0 +1,12 @@ +{ + "mcpServers": { + "nativeapptemplate-agent": { + "command": "npx", + "args": ["-y", "-p", "nativeapptemplate-agent@latest", "nativeapptemplate-agent-mcp"] + }, + "mobile-mcp": { + "command": "npx", + "args": ["-y", "@mobilenext/mobile-mcp@0.0.54"] + } + } +} diff --git a/plugin/README.md b/plugin/README.md new file mode 100644 index 0000000..9d1e9e8 --- /dev/null +++ b/plugin/README.md @@ -0,0 +1,82 @@ +# nativeapptemplate-agent — Claude Code plugin + +Drive the [`nativeapptemplate-agent`](https://github.com/nativeapptemplate/nativeapptemplate-agent) +generator from inside Claude Code. Describe an app in one sentence; the plugin +generates a validated three-platform implementation (Rails 8.1 API + SwiftUI iOS ++ Jetpack Compose Android), then reads the validation report back to you in plain +language. + +Two skills: **generate → validate → explain**, and an interactive **walk the +running app** layer over `mobile-mcp`. + +## What's in here + +``` +plugin/ +├── .claude-plugin/plugin.json # manifest +├── .mcp.json # bundles the generator MCP server + mobile-mcp +├── skills/ +│ ├── generate-app/SKILL.md # generate → validate → explain +│ └── walk-app/SKILL.md # launch on a device, walk the UI with mobile-mcp +└── README.md +``` + +- **`/nativeapptemplate-agent:generate-app `** — runs the generator on your + spec, parses `out//report.json`, and summarizes per-platform / per-layer + results, the domain mapping, and any failures with the specific evidence and the + next move. +- **`/nativeapptemplate-agent:walk-app ios|android`** — launches a generated + app on a **booted simulator/emulator** and drives `mobile-mcp` to capture the + home screen and walk the UI conversationally, surfacing screenshots inline. + Needs a booted device + an installed build (easiest via a + `NATIVEAPPTEMPLATE_VISUAL=1` generate run — see the skill for details). +- **Bundled MCP servers** (`/mcp` to check): the generator server + (`nativeapptemplate-agent`, wired as + `npx -y -p nativeapptemplate-agent@latest nativeapptemplate-agent-mcp`) and + `mobile-mcp` (`@mobilenext/mobile-mcp@0.0.54`) for device automation. + + Two non-obvious bits in that generator command: the MCP entry point is a **bin** + of the `nativeapptemplate-agent` package, not its own package, so `-p` is + required; and the **`@latest`** is load-bearing — without a version spec, `npx` + resolves the *local* package when the server is spawned from inside the agent's + own repo (cwd shadowing) and fails with `command not found`. `@latest` forces + registry resolution regardless of cwd. + + `mobile-mcp` is **pinned to 0.0.54** on purpose: 0.0.55+ closes the stdio + connection on startup (`Connection closed` ~6s in), so `@latest` fails. This + matches the agent's own pin in `src/mobile.ts`. If you have a global `mobile-mcp` + config on `@latest`, it'll show ✘ failed in `/mcp` — this bundled, pinned one is + the working copy (different command, so it won't dedup against your global). + +## Requirements + +- Node.js 22+ and an `ANTHROPIC_API_KEY` with access to `claude-opus-4-7`. +- For the generated apps to validate, the substrate env vars + (`NATIVEAPPTEMPLATE_API` / `_IOS` / `_ANDROID`) must point at the substrate + repos, as documented in the main README. The plugin reads them from your + environment and does not change them. + +## Try it locally (no marketplace needed) + +```bash +# from the agent repo root +claude --plugin-dir ./plugin +``` + +Then in the session: + +``` +/nativeapptemplate-agent:generate-app a walk-in queue for a barbershop +``` + +After editing plugin files, run `/reload-plugins` to pick up changes. Confirm the +skill is loaded via `/help` and the MCP server via `/mcp`. + +## Install from git + +``` +/plugin install github.com/nativeapptemplate/nativeapptemplate-agent +``` + +> Note: the plugin lives in the `plugin/` subdirectory of the repo. If installing +> by path, point at `plugin/`, not the repo root. diff --git a/plugin/skills/generate-app/SKILL.md b/plugin/skills/generate-app/SKILL.md new file mode 100644 index 0000000..5a081fb --- /dev/null +++ b/plugin/skills/generate-app/SKILL.md @@ -0,0 +1,128 @@ +--- +name: generate-app +description: >- + Generate a validated three-platform SaaS app — Rails 8.1 API + SwiftUI iOS + + Jetpack Compose Android — from a one-sentence natural-language spec, then read + the validation report and explain in plain language what passed and what + failed. Use when the user wants to scaffold, generate, bootstrap, or create a + new mobile or SaaS app from a description (e.g. "a walk-in queue for a + barbershop", "a restaurant waitlist", "a task tracker"). +--- + +# Generate a three-platform app and explain the result + +You orchestrate the `nativeapptemplate-agent` generator end-to-end: run it on the +user's spec, then turn its machine-readable validation report into a clear +summary. You are the conversational layer over a one-shot CLI — narrate each +step, never just dump raw output. + +## 1. Resolve the spec + +The user's spec (and any flags) arrive in `$ARGUMENTS`. If empty, ask for a +one-sentence description of the app before doing anything else. Examples that +work well: "a walk-in queue for a barbershop", "a restaurant waitlist for casual +dining", "a personal task tracker with due dates". The generator is scoped to +the queue / booking / simple-CRUD SaaS family — if the spec is far outside that +(e.g. a multiplayer game, a video app), say so and offer the closest in-scope +shape rather than generating something that will fail validation. + +Optional overrides the user may include, passed straight through to the CLI: +- `--project-name="Vet Clinic"` — fixes the display name + output slug. +- `--rename Shopkeeper=Vet` (repeatable) — overrides one of the planner's chosen + renames. Only renames the planner *already planned* are overridable; an + override that matches nothing is reported and dropped. + +## 2. Set expectations before running + +Tell the user, briefly, before you start: +- This makes real Anthropic API calls and takes ~3–5 minutes (longer with visual + validation). It needs `ANTHROPIC_API_KEY` in the environment. +- Output lands in `./out//{rails,ios,android}/` in the current directory, + each an independent git-initialized project. +- Substrate selection comes from the environment (`NATIVEAPPTEMPLATE_API` / + `_IOS` / `_ANDROID`); the defaults target the paid edition. Don't change these + unless the user asks. + +## 3. Run the generator + +Prefer a local build when present, otherwise the published CLI: +- If you are inside the agent's own repo and `dist/index.js` exists (or + `$NATIVEAPPTEMPLATE_AGENT_HOME` is set), run `node dist/index.js …`. +- Otherwise run `npx -y nativeapptemplate-agent …`. + +Always pass `--report-format=both` (so `report.json` is written for parsing) and +`--exit-zero` (so a validation FAIL doesn't abort the command before you can +read and explain the report — you decide pass/fail from the report yourself). + +Pass the spec as a **single quoted argument**, then append any flags. Example: + +```bash +node dist/index.js "a walk-in queue for a barbershop" --report-format=both --exit-zero +# or, outside this repo: +npx -y nativeapptemplate-agent "a restaurant waitlist" --report-format=both --exit-zero +``` + +The run prints a `report: file://…/out//validation-report.html` line on +completion. Note the `` — `report.json` sits next to that HTML file at +`out//report.json`. + +## 4. Read and interpret the report + +Read `out//report.json`. Its shape: + +```jsonc +{ + "meta": { "spec", "slug", "displayName", "visualLevel" /* 0|1|2 */, "durationMs", ... }, + "overallPass": true, + "summary": "one-line human summary", + "platforms": [ + { "platform": "rails"|"ios"|"android", + "layer1": { "pass": bool, "findings": [ /* leftover-token findings */ ] }, + "layer2": { "pass": bool, "command", "mode": "fast"|"build", "exitCode", "stderrTail"? }, + "layer3": { /* present only when visualLevel > 0 — vision-judge scores */ } } + ], + "reviewer": { "contractParity": "pass"|"fail", "diffs": [ /* OpenAPI mismatches */ ] }, + "domain": { + "renamePlan": [ { "from": "Shop", "to": "…" }, … ], + "entities": [ { "name", "replaces", "fields", "states"? }, … ] + }, + "repairAttempts": [ /* present only if the self-repair loop ran */ ] +} +``` + +Layers: **Layer 1** = structural (leftover domain tokens + OpenAPI parity), +**Layer 2** = runtime (Rails boots / iOS builds / Android builds; `mode: "build"` +means a full build was run), **Layer 3** = semantic vision judge (only when +`visualLevel > 0`). + +## 5. Summarize for the user + +Lead with the headline (`overallPass` + `summary` + total time from +`meta.durationMs`). Then a compact per-platform table — Layer 1 / Layer 2 (/ +Layer 3 if present) as ✅/❌ for rails, ios, android — plus reviewer contract +parity. Then the domain mapping the planner chose (`domain.renamePlan`, e.g. +`Shop → Clinic`, `Shopkeeper → Vet`) and the entities. Finish with the path to +`validation-report.html` and offer to open it (`open ` on macOS). + +## 6. On failure, be specific and offer the next move + +Don't just say "it failed." Pull the exact evidence and propose a fix: +- **Layer 1 fail** → list `layer1.findings` (leftover substrate tokens). Often a + rename the planner missed; suggest a targeted re-run with `--rename From=To`. +- **Layer 2 fail** → show `layer2.stderrTail` for the failing platform and name + the likely cause (Jetpack Compose compile + Hilt DI are the known-cryptic ones + — slow down there). Offer to opt into the self-repair loop by re-running with + `NATIVEAPPTEMPLATE_REPAIR=on` (targets Layer 1/2, hard-capped at 5 iterations). +- **reviewer parity fail** → list `reviewer.diffs` (Rails ↔ iOS ↔ Android + contract drift). +- For semantic checks, mention `NATIVEAPPTEMPLATE_VISUAL=1` (build + home-screen + judge) or `=2` (full mobile-mcp walk-through) as opt-in deeper validation. + +## 7. Hand off to the rest of the session + +The generated projects are real, git-initialized, and buildable. Offer concrete +follow-ups: open the report, tweak generated code, commit a project, or re-run +with overrides. If the user wants to **see the app running** — capture the home +screen, walk the UI, screenshots inline — hand off to the `walk-app` skill +(`/nativeapptemplate-agent:walk-app ios|android`), which drives `mobile-mcp` +against a booted simulator/emulator. diff --git a/plugin/skills/walk-app/SKILL.md b/plugin/skills/walk-app/SKILL.md new file mode 100644 index 0000000..7a0b409 --- /dev/null +++ b/plugin/skills/walk-app/SKILL.md @@ -0,0 +1,103 @@ +--- +name: walk-app +description: >- + Launch a generated app on a booted iOS Simulator or Android emulator and walk + its UI with mobile-mcp — capture the home screen, show screenshots inline, list + on-screen elements, and optionally drive a guided tap-through. Use when the + user wants to see, preview, screenshot, or interact with the running generated + app, or asks to "walk the home screen" / "show me the UI" after a generation. +--- + +# Walk a generated app's UI with mobile-mcp + +This is the interactive companion to `generate-app`. Where `generate-app` produces +and validates the projects, this skill puts a generated app **on screen** and lets +you explore it conversationally — capture the current screen, list its elements, +and tap through a flow, surfacing screenshots inline as you go. + +It depends on `mobile-mcp` (bundled with this plugin — check `/mcp`) and on a real +booted device + an installed build. Those parts are environment-dependent and the +flakiest link in the chain; be explicit with the user about what's required rather +than failing silently. + +## 1. Resolve the target + +- **Project:** a slug from `$ARGUMENTS`, else the most recently modified directory + under `./out/`. Confirm the chosen `out//` exists. +- **Platform:** `ios` or `android` from `$ARGUMENTS`. If unspecified, ask — they + need different devices and you can only drive one at a time. + +## 2. Get the app onto a device (the heavy prerequisite) + +mobile-mcp drives an app that is already **installed and running** on a **booted** +device. Two routes: + +**Recommended — let the generator build + install it.** The agent's visual mode +already does the full build → install → launch on both platforms and is the +tested path. Re-run the generator for this spec with `NATIVEAPPTEMPLATE_VISUAL=1` +(home-screen build) or `=2` (full scripted walk). After it finishes the app is +installed and launched on the booted device, and you can pick up here for +interactive exploration. + +**Manual — build it yourself** from `out//`: +- **iOS:** the scheme is the project's PascalCase name (run `xcodebuild -list` in + `out//ios/` to confirm it). Build for the iPhone 17 Pro simulator + (`xcodebuild -scheme -destination 'platform=iOS Simulator,name=iPhone 17 Pro,OS=26.2' build`), + then install/launch on the booted sim. +- **Android:** from `out//android/`, `./gradlew assembleDebug && ./gradlew installDebug`. + +Device readiness: +- **iOS:** ensure a simulator is booted (`xcrun simctl list devices | grep Booted`; + boot iPhone 17 Pro + `open -a Simulator` if none). mobile-mcp's iOS-sim driver + also needs **WebDriverAgent running on :8100** — start it first (the dev machine + has a `wda-up` helper for this). Android needs no WDA; mobile-mcp drives the + emulator directly over `adb`. +- **Android:** ensure an emulator is running. Boot it from **Android Studio's + Device Manager** — don't start it with the CLI `emulator -avd` on this machine + (Android Studio owns adb here). Confirm with `adb devices`. + +If the app needs live data past the welcome screen, the generated Rails API must +be running: in `out//rails/`, `mise exec -- bin/dev` (after `bundle install` ++ `db:prepare` + `db:seed_fu`). + +## 3. Connect mobile-mcp to the device + +Use mobile-mcp to list available devices and select the booted simulator/emulator. +Then list installed apps and launch the generated one (match on the project's +display name / PascalCase name) — launching by name via mobile-mcp avoids hunting +for the bundle id / package name. + +## 4. Capture and walk + +The point of this skill is showing, not narrating: +1. Take a screenshot of the current screen and **surface it inline** to the user. +2. List on-screen elements (mobile-mcp prefers the accessibility tree — more + reliable than coordinate taps) so you and the user can see what's actionable. +3. Briefly describe what's on screen in domain terms (the renamed entities, not + substrate tokens — e.g. "Barbershop list", "Add Ticket"). + +Then offer to walk a short flow. A sensible default for these apps mirrors the +validated scenario: Welcome → Sign Up → Sign In → drill into the seeded sample. +Take a fresh screenshot after each meaningful step and show it. Keep steps small +and confirm before destructive actions. + +## 5. Stay interactive + +This is exploratory, not a fixed script. After the home-screen capture, let the +user drive: "tap Sign Up", "go back", "what's on this screen?". Drive mobile-mcp +per request and return a screenshot each time. That conversational loop — generate, +then walk the running app together — is the whole reason this skill exists. + +## 6. When it fails + +The device layer fails in known ways; diagnose, don't just retry: +- **No device / mobile-mcp finds nothing** → the sim/emulator isn't booted, or + (Android) Studio isn't running and adb sees no device. Point the user at §2. +- **App not installed** → the build/install step didn't run or failed; fall back to + the recommended `NATIVEAPPTEMPLATE_VISUAL=1` route. +- **App launches but screens are blank / error** → the Rails API likely isn't + running or the app can't reach it; start it (§2) and check the + `NATIVEAPPTEMPLATE_API_*` env the app was built against. +- **Build fails** → surface the compiler output; Jetpack Compose + Hilt are the + known-cryptic ones. Offer a repair re-run of `generate-app` with + `NATIVEAPPTEMPLATE_REPAIR=on`.