---
name: setup-test-stores
description: Provision a disposable Jurassic Ninja store for the Maestro smoke suite, connect Jetpack to the developer's own WordPress.com test account, create WooCommerce API keys, and write .maestro/.env.local. Use when Maestro setup is missing, when .env.local points at an expired store, or when a clean store is wanted.
user-invocable: true
allowed-tools: "Bash, Read, mcp__context-a8c__context-a8c-load-provider, mcp__context-a8c__context-a8c-execute-tool"
argument-hint: "[--fresh]"
---

# Set up a Maestro test store

Provisions a Jurassic Ninja (JN) site and configures it as the Maestro lab store.
Site creation is only possible through the `jurassic-ninja` ContextA8C MCP, so this
skill drives that part; everything after "site exists and its password is known" is
handled by `.maestro/scripts/setup-jn-store.sh`, which a developer can also run by
hand against a site created in a browser.

## Prerequisites

- ContextA8C MCP configured with the `jurassic-ninja` provider.
- `wc.oauth.app_id` and `wc.oauth.app_secret` present in
  `~/.configure/woocommerce-android/secrets/secrets.properties` (see Environment Setup in `AGENTS.md`).
- `expect` on PATH (ships with macOS) for password-based SSH.
- A **WordPress.com test account with two-factor authentication disabled**. The OAuth
  password grant used to connect Jetpack cannot answer a 2FA challenge non-interactively.
  Never use a personal or production account. The account is read from `.env.local`, or
  from `MAESTRO_WOO_LAB_WPCOM_EMAIL` / `MAESTRO_WOO_LAB_WPCOM_PASSWORD` in the
  environment; see step 0.

## Steps

0. **Make sure the WordPress.com account is available.** The script needs a test account
   to connect Jetpack to, and it cannot prompt when run by an agent because there is no
   terminal attached; it will exit with a message naming what is missing.

   If `.env.local` has no `MAESTRO_WOO_LAB_WPCOM_EMAIL` / `MAESTRO_WOO_LAB_WPCOM_PASSWORD`,
   stop and ask the user to either add those two lines themselves, or run the script
   directly in their own terminal, where it prompts without echoing:

   ```bash
   .maestro/scripts/setup-jn-store.sh --site <domain>.jurassic.ninja
   ```

   Do not ask the user to paste a password into the conversation, and never pass one as a
   command-line argument.

1. **Check whether setup is already usable.** If `.maestro/.env.local` exists, probe the
   store in one bash call that sources the file, so no credential is read into the chat:

   ```bash
   ( set -a; . .maestro/.env.local; set +a
     curl -s -o /dev/null -w '%{http_code}' \
       -u "${MAESTRO_WOO_LAB_CONSUMER_KEY:-$MAESTRO_WOO_CONSUMER_KEY}:${MAESTRO_WOO_LAB_CONSUMER_SECRET:-$MAESTRO_WOO_CONSUMER_SECRET}" \
       "$MAESTRO_WOO_LAB_JETPACK_STORE_URL/wp-json/wc/v3/products?per_page=1" )
   ```

   A `200` means the store is alive and the keys work; report that and stop, unless the
   user passed `--fresh`. Anything else means the store is gone or expired: continue, and
   reuse the existing WP.com account lines rather than asking for them again.

2. **Provision two sites.** The lab store, and a WooCommerce site without Jetpack for
   `login_no_jetpack`:

   ```
   provision-site  features: {"woocommerce":"true","woocommerce-import-sample-data":"true","jetpack":"true"}
   provision-site  features: {"woocommerce":"true","jetpack":"false"}
   ```

   Note both returned domains.

3. **Fetch their passwords.**

   ```
   list-sites  domain: <domain>, include_passwords: true, include_config: true
   ```

   `JN_PASSWORD` in the returned config is both the wp-admin and the SSH password. The
   admin username is `demo`.

   Do not echo these values in your reply.

4. **Configure the stores.** Pass the passwords through the environment so they never land
   in `ps` output:

   ```bash
   JN_SSH_PASS='<lab JN_PASSWORD>' JN_NO_JETPACK_SSH_PASS='<no-Jetpack JN_PASSWORD>' \
     .maestro/scripts/setup-jn-store.sh --site <lab domain> --no-jetpack-site <no-Jetpack domain>
   ```

   The script waits for JN to finish provisioning (it answers HTTP before its plugins
   finish installing), connects Jetpack, creates the API keys, and writes
   `.maestro/.env.local`.

   This assumes `.env.local` already has `MAESTRO_WOO_LAB_WPCOM_EMAIL` and
   `MAESTRO_WOO_LAB_WPCOM_PASSWORD`. If it does not, see step 0.

5. **Report** the store URL and blog ID. Do not print any credential.

## Verifying

```bash
.maestro/scripts/lint-env.py --seed
```

## What the provisioned store supports

A fresh store has the WooCommerce sample products, and the script adds 25 completed
orders, one customer and a `maestro10` coupon, so the product, order and dashboard flows
run against it.

The no-Jetpack fixture (`MAESTRO_WOO_NO_JETPACK_*`) is written from the second site. The
other negative-login fixtures (`MAESTRO_WOO_NOT_A_WOO_STORE_*`,
`MAESTRO_WOO_WRONG_ACCOUNT_STORE_URL`) are shared read-only sites from the smoke testing
guide and are filled in by hand.

## Notes

- JN sites expire after 7 days of inactivity. Re-run this skill when a store stops
  responding; it reuses the WordPress.com account already in `.env.local`.
- Only test stores and test accounts. Destructive flows publish and delete real data.
- The previous `.env.local` is backed up outside the repository, because `.gitignore`
  matches `.env.local` exactly and a sibling backup file would not be ignored.
