feat(cli): flag per e2e init wizard question

Merged
OK
12d ago
+417-97

Closes #1114.

e2e init takes a flag for every wizard question, so a host that sets up e2e for its users can pick each answer without a TTY.

npx e2e init --yes \
  --engine web \
  --gateway openrouter \
  --skills .agents/skills \
  --mcp .mcp.json \
  --install
FlagValuesPrompt it answers
--engine <id>web, mobile, noneWhich engine?
--gateway <id>vercel, openrouter, openai-compatible, chatgpt, copilot, opencode-console, grok, noneWhich model gateway?
--endpoint <url>HTTPS, or HTTP on loopbackBase URL of the OpenAI-compatible API
--skills <dirs>.agents/skills, .claude/skills, comma-separated or repeated, or noneInstall the e2e skill?
--mcp <files>.mcp.json, .cursor/mcp.json, comma-separated or repeated, or noneRegister the MCP server?
--install / --no-installInstall dependencies?
  • Values are the ids the wizard already uses (GATEWAYS, getEnginePresets(), SKILL_LOCATIONS, MCP_LOCATIONS), so a new preset gets a flag value for free.
  • The flag is --gateway, not the --provider the issue proposed. The code, the prompt, and telemetry all say gateway, and e2e login [provider] already uses provider ids (openai, github-copilot) that differ from these.
  • A flag skips its prompt with or without --yes. Without --yes, the prompts for omitted flags and the "Apply these changes?" confirmation still appear. An omitted flag under --yes keeps today's default, so init --yes output is byte-identical to main.
  • Bad values exit 2 through commander before init runs, so nothing is written. --endpoint without --gateway openai-compatible is also rejected.
  • --skills/--mcp override the locations found by an earlier run (chooseLocations, packages/e2e/src/cli/init.ts). --engine/--gateway/--endpoint with an existing config log a warning naming the flags that were ignored.
  • Telemetry: usedFlags still sends flag names only, never values. It used to report both --install and --no-install when either was given, because the pair shares one attribute; it now reports only the one that was passed. --endpoint never leaves the machine.
  • --yes help said "Playwright, AI on, no installation". It now lists the real defaults: web, vercel, every skill and MCP location, no installation.
  • validateEndpoint moved to init/gateways.ts so the CLI parser and the prompt share it.
  • Docs: reference/cli.mdx flag table, skills/e2e/references/setup.md, and telemetry.mdx (which was missing opencode-console). The Detox and Maestro migration prompts now use init --yes --engine mobile instead of swapping @e2e-dev/web by hand. Those prompts run npx e2e init, so the new flag needs a release to work.

Verified

Ran it locally: yes

  • Built packages/e2e on main (/tmp/e2e-main) and on this branch, then ran init --yes from each in an empty /tmp dir. Stdout is identical. The only file that differs is the skill's references/setup.md, which this PR edits.
$ node dist/cli/bin.js init --yes --engine web --gateway openrouter --skills .agents/skills --mcp .mcp.json --install
●  Add dev dependencies: e2e@^0.20.0, @e2e-dev/web@^0.14.0, ai@^7.0.0, zod@^4.1.8, @openrouter/ai-sdk-provider@^3.0.0
●  Add scripts: test:e2e (e2e run)
◆  Created package.json
◆  Created e2e.config.ts
◆  Created tests/example.e2e.ts
◆  Created .agents/skills/e2e/ (9 files)
◆  Created .mcp.json (e2e mcp server)
◆  Updated .gitignore (10 entries)
added 55 packages, and audited 56 packages in 4s
└  Next: APP_URL=http://localhost:3000 npm run test:e2e

$ ls -A
.agents  .gitignore  .mcp.json  e2e.config.ts  node_modules  package-lock.json  package.json  tests
$ npx e2e list
tests/example.e2e.ts › app opens [web]

No .claude/ and no .cursor/. npm install ran, and the installed CLI lists the example test.

$ init --yes --engine none --gateway none --skills none --mcp none
●  Skipped the agent skill; agents can still print it with npm exec -- e2e guide
●  Skipped the MCP server; register it later with: claude mcp add e2e -- npx e2e mcp
$ ls -A
.gitignore  e2e.config.ts  package.json  tests

$ init --yes --engine playwright
error: option '--engine <id>' argument 'playwright' is invalid. Allowed choices are web, mobile, none.   (exit 2)
$ init --yes --mcp claude
error: option '--mcp <files>' argument 'claude' is invalid. unknown MCP config file "claude"; expected .mcp.json, .cursor/mcp.json, none   (exit 2)
$ init --yes --endpoint https://llm.example/v1
error: --endpoint is the base URL for --gateway openai-compatible; pass that gateway with it   (exit 2)

None of the rejected runs wrote anything (the directory stayed empty). I also ran init --engine web --gateway none --skills none --mcp .mcp.json --no-install interactively in a pty. The only prompt was "Apply these changes?", and it wrote .mcp.json with no skill directory.