Nitpick reads nitpick.yaml from the current directory (or pass -c <path>). Generated by nitpick init.
Full example
project:
name:"Brooklyn"
base_url:"https://app.example.com"
roles:
admin:
username_env:"TEST_ADMIN_USERNAME"
password_env:"TEST_ADMIN_PASSWORD"
# login_url is optional — omit for SPAs that auto-redirect to login
# or show a login modal on the base URL. Set it if your app has a
# dedicated login route like "/login" or "/auth/sign-in".
scope:
critical_pages:
-"/dashboard"
-"/login"
exclusions:
-"/admin/delete/*"
-"/logout"
terminal_guards_global:
-"Delete Account"
# Free-form directive the scope router honors on every run.
# Example uses: narrow focus ("only test /tasks/new"), guardrails
# ("never touch billing"), or tone ("treat admin as read-only").
instructions: |
Only test the task creation page.
Skip the billing and admin sections entirely.
flows:
- name:"Onboarding"
description: |
Admin invites a candidate at /admin/invitations.
Candidate signs up at /signup.
Admin approves at /admin/candidates.
testing:
browsers: ["chromium"]
parallel_workers:"50%"
retries: 0
timeout_per_test_ms: 60000
runner:"playwright"
knowledge_base:
path:"./knowledge-base"
persist_models: true
persist_baselines: true
flaky_registry_window_runs: 3
llm:
provider:"anthropic"
api_key_env:"ANTHROPIC_API_KEY"
model:"claude-opus-4-6"
fast_model:"claude-haiku-4-5"
temperature: 0
max_iterations: 100
human_in_the_loop:
require_page_understanding_approval: true
require_scope_confirmation: true
project
| Field | Type | Required | Description |
|---|
name | string | yes | Project display name |
base_url | string (URL) | yes | Root URL all crawled paths are relative to this |
roles
A map of role name → credentials. Keys are arbitrary (admin, customer, org).
| Field | Type | Default | Description |
|---|
username_env | string | (required) | Env var name holding the username/email |
password_env | string | (required) | Env var name holding the password |
login_url | string | optional | Login page path. Omit for SPAs that auto-redirect to login, or apps that show a login modal on the base URL — the crawler will navigate to base_url, wait for any input[type=password] to appear, fill it, and continue. |
Credentials are never stored in config. They’re referenced by env var name and read from .env (auto-loaded from the current directory on every CLI run) or the shell.
scope
| Field | Type | Default | Description |
|---|
critical_pages | string[] | [] | Paths that should be smoke-checked on every iterative run |
exclusions | string[] | [] | Glob patterns paths never crawled or tested |
terminal_guards_global | string[] | [] | Button labels Nitpick must never click |
instructions
Optional string. A free-form directive the scope router and page testers honor on every run. Injected into the scope-inferrer’s system prompt as a “Persistent directives” block. When set, --scope full also runs LLM inference against these directives to narrow down which pages get deep-tested — useful for saying things like:
"Only test the task creation page."
"Skip all admin and billing flows."
"Treat admin as read-only. Never click destructive buttons."
Different from --change (which is one-off, per-run) and terminal_guards_global (which is a hard click-blocker). Instructions are persistent guidance.
flows
Array of natural-language flow definitions.
| Field | Type | Description |
|---|
name | string | Unique flow identifier |
description | string (multi-line) | Plain-language narrative the Flow Lead parses |
testing
| Field | Type | Default | Description |
|---|
browsers | string[] | ["chromium"] | chromium / firefox / webkit / mobile variants |
parallel_workers | string / number | "50%" | Playwright workers |
retries | number | 0 | Playwright retries (always 0 Junior QA owns retries) |
timeout_per_test_ms | number | 60000 | Per-test timeout |
runner | string | "playwright" | Browser automation backend |
knowledge_base
| Field | Type | Default | Description |
|---|
path | string | ./knowledge-base | KB root directory |
persist_models | boolean | true | Archive previous model versions |
persist_baselines | boolean | true | Keep visual regression baselines (future release) |
flaky_registry_window_runs | number | 3 | Consecutive stable runs before removing from flaky registry |
llm
| Field | Type | Default | Description |
|---|
provider | string | anthropic | anthropic / openai / claude-code |
model | string | provider default | Override the main model |
fast_model | string | provider default | Cheap/fast model for scope inference, smoker |
api_key_env | string | provider default | Env var holding API key |
temperature | number | 0 | 0 = deterministic; higher = more creative |
max_iterations | number | 100 | Safety cap on agent loop |
use_openai_skills | boolean | false | v1.1+. When true (with provider: openai), uses the Responses API + a server-hosted skill bundle instead of re-shipping the skill content on every call. Requires skill_id. Ignored for other providers. |
skill_id | string | – | v1.1+. ID returned by nitpick skill publish. Looks like skill_abc123.... |
skill_version | string | "latest" | v1.1+. Pin to a specific version for repeatability. Omit to track latest. |
human_in_the_loop
| Field | Type | Default | Description |
|---|
require_page_understanding_approval | boolean | true | Pause at Phase 3.5 per page |
require_scope_confirmation | boolean | true | Pause at scope proposal for iterative runs |