# Development and testing

[Documentation index](README.md) · [Architecture](architecture.md) · [Contributing](../CONTRIBUTING.md)

## Set up a checkout

```bash
git clone https://github.com/ArtOfIntel/pi-rich-questions.git
cd pi-rich-questions
npm install
npm run check
```

Run the extension from the checkout for an interactive smoke test:

```bash
pi -e ./extensions/index.ts
```

Do not simultaneously load an installed copy; duplicate question extensions can confuse tool selection and command registration.

## Commands

```bash
npm run typecheck       # strict TypeScript, no emit
npm test                # Bun test suite
npm run test:coverage   # Bun tests with text and LCOV coverage
npm run check           # typecheck, then coverage suite
```

`coverage/` is generated and ignored. Development dependencies lock Pi `0.84.4` and TypeBox `1.3.7` exactly as the minimum reproducible baseline. Following [Pi's official package guidance](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/packages.md#dependencies), Pi-provided runtime modules are declared as wildcard peers because the host bundles them. This keeps future Pi releases installable without claiming that untested behavior is verified: the exact development lock and compatibility matrix carry that evidence. Compatibility changes must also run against the current `0.85.x` packages and bundled CLI. Do not add `@earendil-works/pi-server` merely to work around the `0.85.0` coding-agent package-root issue—use the bundled CLI smoke test and move the development lock only after that packaging issue is corrected.

## Test areas

Tests live under `test/`:

- `form-state.test.ts` — defaults, required-answer logic, selections, custom answers, and notes.
- `form-view.test.ts` — question/review rendering and visible-width bounds.
- `layout.test.ts` — ANSI, CJK, emoji, combining text, long-token wrapping, viewport following, and tiny heights.
- `format.test.ts` — self-contained text output, stable values, all option states, notes, custom and empty answers.
- `extraction.test.ts` — structured-tool/text parsing, source-preserving fallback, model/thinking availability, retry order, real `ModelRuntime` native-provider dispatch, and credential-resolved request data.
- `extraction-config.test.ts` — preference validation/persistence and searchable model filtering.
- `integration.test.ts` — public registration, constrained/sequential metadata, TUI guards, demo handoff, refresh recovery, setup picker, configured bindings, fullscreen pointer input, modal scrolling, cancellation, cursor visibility, and submission.

The integration fixtures use synthetic Pi contexts, TUI components, injected selection bindings, normalized mouse events, raw terminal sequences, and terminal row/column constraints. They cover regular/fullscreen behavior, one-row/tiny viewports, and multiple newline protocols. The extraction suite separately uses Pi's actual in-memory model runtime and a native test provider without network access.

## Coverage expectations

There is no numeric coverage gate. A change is complete when relevant behavior has focused tests, `npm run check` passes, and important TUI paths receive a manual smoke test. Do not chase a percentage by testing implementation trivia; protect public schema/result semantics, state transitions, failure recovery, and terminal boundaries.

## Manual TUI smoke-test matrix

Before a release or interaction change, exercise at least:

| Area | Checks |
| --- | --- |
| Install/load | npm or packed install; `/reload`; tool and command appear once |
| Question types | radio, checkbox, text; defaults; optional/required; Other |
| Editing | multiline text, custom answer, option note, review note; cursor keys; `Esc` twice; `Ctrl+C` |
| Navigation | Tab/Shift+Tab, arrows, Enter/Space, review and return |
| Layout | long Markdown, narrow and short terminal, configured Page Up/Page Down, mouse wheel, resize |
| Text width | ANSI-themed Markdown, CJK, emoji, combining characters, long unbroken text |
| Extraction | first run, session/low, dedicated model search/thinking, refresh timeout/partial errors, config/reset, constrained tool arguments, text JSON, malformed response fallback |
| Modes | interactive success; RPC/JSON/print rejection without custom UI |
| Terminal variants | regular and fullscreen Pi; option/model clicks and editor cursor placement in fullscreen; the maintainer's normal terminal; tmux/modified-key protocol when relevant |
| Result | all presented options, values, states, presenter/user notes, custom answer, additional text |

IME composition and hardware-cursor behavior depend strongly on Pi and the terminal. When changing editor integration, test them manually where available and document the exact environment rather than claiming universal support.

## Documentation and pull requests

Update the README, relevant pages under `docs/`, extension quick reference, and changelog when behavior or public contracts change. Run a local Markdown-link check, `npm pack --dry-run --json`, `npm run check`, and `git diff --check` for release-facing changes. See [CONTRIBUTING.md](../CONTRIBUTING.md).
