# CLI Reference

All commands are invoked via `npx assuremind <command>` or, after a global install, `assuremind <command>`.

---

## Global flags

| Flag | Description |
|------|-------------|
| `-v, --version` | Print version number |
| `-h, --help` | Show help for any command |

---

## `init`

Initialise Assuremind in the current directory.

```bash
npx assuremind init [options]
```

| Option | Description |
|--------|-------------|
| `--skip-playwright` | Skip Playwright browser installation (useful in CI) |

**What it does:**

- Validates that a `package.json` exists
- Creates directories: `tests/`, `variables/`, `results/`, `fixtures/`
- Copies template files (skips any that already exist):
  - `.env.example` — full AI provider reference
  - `.env` — minimal config to fill in
  - `.gitignore` — ignores `.env`, `node_modules`, `results/`
  - `autotest.config.ts` — framework configuration
  - `variables/global.json` — empty variable store
  - `ASSUREMIND.md` — quick-reference card
- Installs Playwright browsers unless `--skip-playwright` is given
- Runs `npx playwright install` for chromium, firefox, webkit

**Example:**

```bash
cd my-project
npm install assuremind
npx assuremind init
```

---

## `studio`

Open the Assuremind web UI.

```bash
npx assuremind studio [options]
```

| Option | Description |
|--------|-------------|
| `-p, --port <number>` | Override the port (default: value from `autotest.config.ts` → `studioPort`, fallback 4400) |
| `--no-open` | Start the server but do not open the browser automatically |

**Example:**

```bash
npx assuremind studio
npx assuremind studio --port 5000
npx assuremind studio --no-open   # headless server for remote access
```

---

## `run`

Run tests from the command line.

```bash
npx assuremind run [filters] [options]
```

**Filters (combinable with AND logic):**

| Filter | Description |
|--------|-------------|
| `--all` | Run every test suite in the `tests/` directory |
| `--type <type>` | Filter by suite type: `ui`, `api`, or `audit` |
| `--suite <name>` | Run suites whose name contains `<name>` (case-insensitive partial match) |
| `--tag <tag>` | Run all cases that have the given tag |
| `--test <name>` | Run cases whose name contains `<name>` (case-insensitive partial match) |

**Options:**

| Option | Description |
|--------|-------------|
| `--browser <list...>` | Browser(s) to use: `chromium`, `firefox`, `webkit` (default: from config) |
| `--device <name>` | Emulate a real device using Playwright's device descriptor (see Device Emulation below) |
| `--env <name>` | Environment to use: `dev`, `staging`, `prod` (loads matching variable file) |
| `--parallel <n>` | Number of parallel workers (overrides config) |
| `--headed` | Run in headed (visible) mode instead of headless |
| `--ci` | CI mode — no interactive prompts, exit code reflects pass/fail |
| `--reporter <list...>` | Reporter(s): `allure`, `html`, `json` |
| `--no-healing` | Disable self-healing for this run |

**Examples:**

```bash
# Run everything
npx assuremind run --all

# Filter by suite type
npx assuremind run --type ui
npx assuremind run --type api
npx assuremind run --type audit

# Run the Login Tests suite on two browsers
npx assuremind run --suite "Login Tests" --browser chromium firefox

# Run all smoke tests in headed mode
npx assuremind run --tag smoke --headed

# Run a specific test by name (partial match)
npx assuremind run --test "Login with valid credentials"

# Combinations (filters use AND logic)
npx assuremind run --type audit --tag regression
npx assuremind run --suite "Orange HRM" --tag smoke
npx assuremind run --type audit --test "Login Page"

# Device emulation — mobile/tablet testing
npx assuremind run --all --device "iPhone 15 Pro" --browser chromium
npx assuremind run --tag smoke --device "Pixel 7" --browser chromium
npx assuremind run --all --device "iPad Pro 11" --browser webkit
npx assuremind run --suite "Mobile Checkout" --device "Galaxy S9+" --browser chromium --ci

# With additional options
npx assuremind run --type audit --browser chromium --headed
npx assuremind run --tag smoke --parallel 4

# CI pipeline — exit 1 if any test fails
npx assuremind run --all --ci

# Run against staging with more parallelism
npx assuremind run --all --env staging --parallel 4

# Run without self-healing (faster, useful for debugging)
npx assuremind run --all --no-healing
```

### Device Emulation (`--device`)

The `--device` flag emulates a real device using Playwright's built-in device registry. It applies the correct viewport, user-agent, device pixel ratio, `isMobile`, and touch-event flags automatically.

**Device name must be an exact Playwright device descriptor name (case-sensitive).**

| Category | Device Name | Viewport | DPR | Best Browser |
|----------|-------------|----------|-----|-------------|
| Mobile | `iPhone 15 Pro` | 393×852 | 3x | `webkit` |
| Mobile | `iPhone 15` | 390×844 | 3x | `webkit` |
| Mobile | `iPhone 14` | 390×844 | 3x | `webkit` |
| Mobile | `iPhone SE` | 375×667 | 2x | `webkit` |
| Mobile | `Pixel 7` | 412×915 | 2.6x | `chromium` |
| Mobile | `Pixel 5` | 393×851 | 2.75x | `chromium` |
| Mobile | `Galaxy S9+` | 320×658 | 4.5x | `chromium` |
| Mobile | `Galaxy S8` | 360×740 | 3x | `chromium` |
| Tablet | `iPad Pro 11` | 834×1194 | 2x | `webkit` |
| Tablet | `iPad (gen 7)` | 810×1080 | 2x | `webkit` |
| Tablet | `iPad Mini` | 768×1024 | 2x | `webkit` |
| Tablet | `Galaxy Tab S4` | 712×1138 | 2.25x | `chromium` |

> **Note:** Mobile/tablet emulation works best with `--browser chromium`. Full touch-event support and mobile user-agent headers are only guaranteed on Chromium.

---

## `generate`

Generate test cases from a plain-English user story.

```bash
npx assuremind generate [options]
```

**Exactly one of `--story` or `--story-file` is required:**

| Option | Description |
|--------|-------------|
| `--story <text>` | User story text inline |
| `--story-file <path>` | Path to a `.txt` or `.md` file containing the story |
| `--suite <name>` | Name for the generated suite (AI chooses a name if omitted) |
| `--output <path>` | Output directory (default: `tests/`) |

**Examples:**

```bash
# Inline story
npx assuremind generate \
  --story "As a user I want to reset my password via email so I can regain access." \
  --suite "Password Reset"

# Story from file
npx assuremind generate --story-file stories/checkout.md --suite "Checkout Flow"

# Custom output directory
npx assuremind generate --story-file stories/login.md --output e2e/tests/
```

The command outputs the generated suite structure and the number of cases and steps created.

---

## `apply-healing`

Review and apply self-healing suggestions to test files.

```bash
npx assuremind apply-healing [options]
```

| Option | Description |
|--------|-------------|
| `--from <path>` | Path to a specific healing report JSON (default: `results/healing/pending.json`) |
| `-y, --yes` | Accept all pending suggestions without interactive prompting |

**Interactive mode (default):**

For each pending suggestion you are shown:

```
Suite: Login Tests  →  Case: User can log in  →  Step: step-2
Instruction:  Click the Login button
Original:     await page.click('#login-btn');
Healed:       await page.click('button[type="submit"]');

[y] Accept   [n] Reject   [a] Accept all   [q] Quit
```

**Examples:**

```bash
# Interactive review
npx assuremind apply-healing

# Accept everything without prompting
npx assuremind apply-healing --yes

# Apply from a CI-generated healing report
npx assuremind apply-healing --from results/healing/run-2026-03-23.json
```

---

## `validate`

Check config health and consistency.

```bash
npx assuremind validate                # check config
npx assuremind validate --strict       # exit code 1 if errors exist
```

Checks:
- `autotest.config.ts` / `autotest.config.json` is valid
- Required env vars are set (based on `AI_PROVIDER` in `.env`)
- All `*.test.json` files can be parsed
- No duplicate suite or case names

| Flag | Description |
|------|------------|
| `--strict` | Exit code 1 if any validation errors exist |

---

## `ci`

CI/CD pipeline utilities.

```bash
npx assuremind ci gate               # evaluate quality gate for latest run
npx assuremind ci report             # post PR comment for latest run
```

---

## `doctor`

Check system requirements and configuration health.

```bash
npx assuremind doctor
```

Reports:
- Node.js version
- Playwright browser installation status
- `.env` presence and AI provider configuration
- Network connectivity to the configured AI provider
- `autotest.config.ts` validity

---

## Exit Codes

| Code | Meaning |
|------|---------|
| `0` | Success |
| `1` | Test failures, validation errors, or missing configuration |

In non-CI mode, exit code is always `0` unless there is a fatal startup error. Use `--ci` to make the exit code reflect test pass/fail.

---

## Environment Variables Reference

All variables are read from `.env` in the project root. See `.env.example` for the full list. Key variables:

| Variable | Required | Description |
|----------|----------|-------------|
| `AI_PROVIDER` | Yes | Provider name: `anthropic`, `openai`, `google`, `groq`, `deepseek`, `together`, `perplexity`, `qwen`, `bedrock`, `ollama`, `custom` |
| `ANTHROPIC_API_KEY` | If `anthropic` | Your Anthropic API key |
| `OPENAI_API_KEY` | If `openai` | Your OpenAI API key |
| `GOOGLE_API_KEY` | If `google` | Your Google AI Studio key |
| `GROQ_API_KEY` | If `groq` | Your Groq API key |
| `AI_TIERED_ENABLED` | No | `true` to use cheap model for simple steps |
| `AI_TIERED_FAST_PROVIDER` | If tiered | Provider for simple steps |
| `AI_TIERED_FAST_MODEL` | If tiered | Model for simple steps |
| `AI_TIMEOUT` | No | AI request timeout in seconds (default: 30) |
| `AI_MAX_RETRIES` | No | Retry attempts on AI failure (default: 2) |

---

## MCP Configuration

MCP (Model Context Protocol) settings are configured in `autotest.config.json` (or via the Settings page in Studio), not via environment variables.

| Setting | Default | Description |
|---------|---------|-------------|
| `mcp.enabled` | `true` | Enable MCP-enhanced code generation (AI sees live page elements) |
| `mcp.headless` | `true` | Run MCP browser without visible window |
| `mcp.actThenScript` | `false` | Two-phase generation: execute via MCP, then convert to code |
| `mcp.proactiveHealing` | `false` | Validate selectors against live page before test runs |
| `mcp.actionTimeout` | `15000` | Timeout per MCP action in ms |
| `mcp.idleTimeout` | `30000` | Auto-disconnect MCP browser after idle period in ms |

> **Note:** MCP is used only during code generation. Test execution (`npx assuremind run`) is never affected by MCP settings.

---

## RAG Configuration

RAG (Retrieval-Augmented Generation) is **ON by default — zero setup required**. The AI automatically learns from every test run, retrieving similar past steps and healing fixes to improve accuracy over time. No database, no external service — uses local TF-IDF embeddings and file-based JSON storage.

**Most users never need to change these settings.** They exist for power-user scenarios like debugging flaky tests, resetting memory after a major app redesign, or disabling RAG for deterministic CI runs.

Settings are configured in `autotest.config.json` (or via Settings → RAG Memory in Studio).

| Setting | Default | Description |
|---------|---------|-------------|
| `rag.enabled` | `true` | Master switch for semantic memory from past runs |
| `rag.codeCorpus.enabled` | `true` | Remember instruction-to-code mappings from successful runs |
| `rag.codeCorpus.maxEntries` | `500` | Maximum entries in the code corpus |
| `rag.codeCorpus.similarityThreshold` | `0.65` | Minimum similarity score to include as AI prompt example |
| `rag.codeCorpus.directUseThreshold` | `0.90` | Minimum similarity score to use directly as fuzzy cache hit ($0) |
| `rag.healingCorpus.enabled` | `true` | Remember past healing fixes for smarter self-repair |
| `rag.healingCorpus.maxEntries` | `300` | Maximum entries in the healing corpus |
| `rag.healingCorpus.similarityThreshold` | `0.60` | Minimum similarity score for healing retrieval |
| `rag.errorCatalog.enabled` | `true` | Track recurring error patterns per URL |
| `rag.errorCatalog.maxEntries` | `200` | Maximum entries in the error catalog |
| `rag.embedder` | `'tfidf'` | Embedding strategy: `tfidf` (local, free, offline) |

> **Note:** RAG data is stored in `results/.rag/` as JSON files. It persists across runs and is fully Git-friendly. Delete the directory to reset all memory.

### When to change RAG settings

| Scenario | What to do |
|----------|------------|
| Debugging a flaky test | Turn OFF `rag.codeCorpus.enabled` — forces fresh AI generation instead of reusing a possibly stale mapping |
| Healing keeps suggesting a bad fix | Turn OFF `rag.healingCorpus.enabled` — clears bad fix influence |
| Major app redesign (UI overhaul) | Set `rag.enabled: false` — old memory from the previous UI is now misleading |
| Want deterministic CI runs | Disable RAG in CI config, keep ON for local development |
| Error warnings are outdated | Turn OFF `rag.errorCatalog.enabled` — stops AI from avoiding selectors that are fine now |

---

## Recorder API

The Test Recorder is available through the Studio UI (Test Editor → Record button) and also exposes REST endpoints for programmatic access:

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/api/recorder/start` | POST | Launch a headed browser and begin recording (UI & Audit suites only). Body: `{ url?: string }` |
| `/api/recorder/stop` | POST | Stop recording and return all captured actions |
| `/api/recorder/status` | GET | Check if a recording session is active |

Recorded actions are broadcast in real time via WebSocket (`recorder:action` event). When recording stops, a `recorder:stopped` event is sent.

### Soft Assertions

The recorder supports **soft assertions** via `Ctrl+Shift+Click` — these use Playwright's `expect.soft()` so the test continues executing even when the assertion fails. All failures are collected and reported at the end.

For plain-English steps, prefix with "Soft" to generate soft assertion code:
- `Soft verify "Dashboard" text is visible` → `await expect.soft(page.getByText('Dashboard')).toBeVisible();`
- `Soft check the URL contains "/dashboard"` → `await expect.soft(page).toHaveURL(/dashboard/);`

You can also toggle any assertion step between hard and soft using the **Hard/Soft** badge in the Test Editor.

### Recorder locator strategies

The recorder resolves locators against Playwright's live accessibility tree using 6 strategies in priority order:

| Priority | Strategy | Example |
|----------|----------|---------|
| 1 | `data-testid` | `page.getByTestId('login-btn')` |
| 2 | `getByRole()` exact + level | `page.getByRole('heading', { name: 'Dashboard', level: 1 })` |
| 3 | `getByRole()` exact | `page.getByRole('button', { name: 'Login' })` |
| 4 | `getByLabel()` | `page.getByLabel('Email')` |
| 5 | `getByPlaceholder()` | `page.getByPlaceholder('Enter email')` |
| 6 | `getByText()` | `page.getByText('Welcome')` |
| 7 | CSS fallback | `page.locator('#login-btn')` |

Each candidate is verified with `count() === 1` — only uniquely-matching locators are used.

### Iframe support

The recorder automatically handles **same-origin iframes** — essential for enterprise apps like SAP and Salesforce:

- The capture script is injected into **all frames**, not just the main page
- Elements inside iframes produce `frameLocator()` chains:
  ```typescript
  // Element inside an iframe with id="content-frame"
  await page.frameLocator('#content-frame').getByRole('button', { name: 'Submit' }).click();
  ```
- The iframe selector is computed from the iframe's `id`, `name`, `data-testid`, or `src` attribute
- Dynamically loaded iframes are detected and instrumented automatically
- **Limitation:** Cross-origin iframes cannot be instrumented due to browser security restrictions

---

### CI/CD tips

```yaml
# Cache RAG memory between CI runs for persistent learning
- name: Cache RAG memory
  uses: actions/cache@v4
  with:
    path: results/.rag
    key: rag-memory-${{ github.ref }}
    restore-keys: rag-memory-
```
