npm package: @popoverai/dotrequirements
Description: Requirements tracking CLI, test harness, and MCP server
Author: Will Raymer @Popover
Latest version: 0.21.1

# dot•requirements

**One source of truth for what your software should do.**
Readable. Testable. AI-accessible.

---

Tests prove *something* works—but nobody is certain it's the right something. Requirements live scattered across docs, issue trackers, and people's heads. They drift out of sync with actual code. And AI assistants can't access them at all.

**dot•requirements** closes this gap. Write requirements as structured Markdown, reference them directly in tests, and see coverage update automatically. When a requirement changes, the tests that validate it are one click away.

> **Alpha Software** — Under active development. Please report issues to support@popover.ca.

## Who Is This For?

- **Developers** who want tests that prove the right behavior, not just "80% coverage"
- **Product managers** who want visibility into what's actually being tested
- **AI-first builders** who want clear requirements for faster, more accurate implementations

## Installation

```bash
npm install @popoverai/dotrequirements
# or
pnpm add @popoverai/dotrequirements
```

> **Note:** Examples use `dotreq` for brevity. The full command `dotrequirements` also works.

## Quick Start

### 1. Initialize a project

```bash
npx dotreq init
```

This creates a `.requirements/` directory with example requirements and configures your project.

### 2. Write requirements

Create `*.requirements.md` files in `.requirements/` or colocate them with your code:

```markdown
---
document:
  title: "Authentication Requirements"
---

## User Authentication

```dotrequirements
AUTH-LOGIN-1: A registered user, Jamie, can log in to their account
  0. → When Jamie provides a valid username and password, they are authenticated and brought to their dashboard
  1. → When Jamie provides an incorrect password, they see an error message and remain on the login page
  2. → When Jamie's account has been deactivated, but they provide otherwise correct credentials, they see a message explaining their account status
```

If your team prefers a structure such as Gherkin, you can add labels:

```dotrequirements
AUTH-LOGIN-2: A user with two-factor authentication enabled must provide an OTP
  0. Given → Jamie has two-factor authentication enabled on their account
  1. When → Jamie provides valid credentials
  2. Then → Jamie is prompted to enter an OTP before accessing their dashboard
```

### 3. Reference requirements in tests

```typescript
import { requirement } from '@popoverai/dotrequirements/test';

describe(requirement('AUTH-LOGIN-1'), () => {
  it(requirement('AUTH-LOGIN-1.0'), () => {
    // valid credentials → authenticated
  });

  it(requirement('AUTH-LOGIN-1.1'), () => {
    // incorrect password → error message
  });
});
```

### 4. Track coverage

After running tests, you'll see a coverage report showing which requirements have been tested.

---

## CLI Commands

### `dotreq init`

Initialize a new project. Creates `.requirements/` directory, example files, and configuration.

```bash
dotreq init
dotreq init --name my-project
dotreq init --invite abc123xyz
```

**Options:**

| Option | Description |
|--------|-------------|
| `--name <name>` | Set project name (skips prompt) |
| `--invite <token>` | Join a team using an invite token |

**Joining a team via invite:**

If a team admin shares an invite command with you, join the team and connect in one step:

```bash
npx dotrequirements init --invite abc123xyz
```

This shows the team name, prompts you to sign in, adds you to the team, and lets you select a project.

### `dotreq link`

Link your local environment to an existing project (when you already have a project in dot•requirements cloud).

```bash
dotreq link
```

### `dotreq pull`

Sync requirements from dot•requirements cloud to local `.requirements/` files.

```bash
dotreq pull
dotreq pull --project <project-id>
dotreq pull --document <document-id>
dotreq pull --share <token>
```

**First-time setup with a share token:**

If a team member shares a pull command with you, you can pull requirements without creating an account:

```bash
npx @popoverai/dotrequirements pull --share drt_abc123...
```

This gives you read-only access to view requirements. To push changes or report coverage, run `dotreq link` afterward.

### `dotreq push`

Push local requirements to dot•requirements cloud.

```bash
dotreq push
dotreq push .requirements/auth.requirements.md
dotreq push --yes  # Skip confirmation
```

### `dotreq test`

Validate requirements files against the schema.

```bash
dotreq test
dotreq test --file .requirements/auth.requirements.md
```

### `dotreq browsertest`

Run browser-based acceptance tests against requirements. Uses AI-powered browser automation to verify that your application behaves as specified.

```bash
dotreq browsertest LOGIN-1
dotreq browsertest LOGIN-1 https://example.com
dotreq browsertest LOGIN-1 --json
```

**Options:**

| Option | Description |
|--------|-------------|
| `--json` | Output results as JSON (for CI/CD integration) |

**Configuration required:**

Browser testing requires credentials in `project-settings.json`:

```json
{
  "defaultURL": "https://your-app.com",
  "browserTest": {
    "geminiApiKey": "your-gemini-api-key"
  }
}
```

Optional settings: `vercelBypassSecret`, `browserbaseApiKey`, `browserbaseProjectId`.

### `dotreq mcp-setup`

Configure the MCP server for AI assistants (Claude Code, Cursor, etc.).

```bash
dotreq mcp-setup
```

### `dotreq mcp`

Start the MCP server manually (typically not needed—AI assistants start it automatically after `mcp-setup`).

```bash
dotreq mcp
```

---

## What Works Locally

The following features work fully offline—no account required:

- Write requirements (`.requirements.md` files)
- Validate requirements (`dotreq test`)
- Reference requirements in tests (`requirement()`)
- Coverage reporting (console output)
- MCP tools (search, validate, explore)

The following features require a dot•requirements cloud account:

- Sync requirements (`pull` / `push`)
- Historical coverage tracking
- AI-powered style checking
- Team collaboration

To enable cloud features, run `dotreq link` to connect your project to the cloud.

---

## Test Harness

Stop wondering "did we test that?" The test harness tracks which requirements are exercised by your tests and shows gaps instantly.

### Setup with Vitest

**vitest.config.ts:**

```typescript
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    globalSetup: './vitest.setup.ts',
  },
});
```

**vitest.setup.ts:**

```typescript
import { prepare, finalize } from '@popoverai/dotrequirements/test';

// Named exports: Vitest calls setup() before tests, teardown() after
export function setup() {
  prepare();
}

export async function teardown() {
  await finalize();
}
```

Alternatively, you can use the default export pattern that returns a teardown function—see the [Vitest globalSetup docs](https://vitest.dev/config/globalsetup).

**Customizing output:** `finalize()` accepts options to control verbosity:

```typescript
await finalize({ showTestedList: true }); // Include tested requirements
await finalize({ showSummary: false, showUntestedList: false }); // Quiet mode
```

By default, only untested requirements are shown. See the [test harness docs](https://docs.dotrequirements.io/tools/test-harness) for all options.

### Setup with Jest

**jest.config.cjs:**

```javascript
module.exports = {
  globalSetup: './jest.setup.cjs',
  globalTeardown: './jest.teardown.cjs',
};
```

**jest.setup.cjs:**

```javascript
const { prepare } = require('@popoverai/dotrequirements/test');

module.exports = async function setup() {
  prepare();
};
```

**jest.teardown.cjs:**

```javascript
const { finalize } = require('@popoverai/dotrequirements/test');

module.exports = async function teardown() {
  await finalize();
};
```

> **Note:** Jest global setup/teardown files run in a separate process from your tests. If using ES modules, configure Jest's `transform` option accordingly.

### Using `requirement()` in Tests

The `requirement()` function returns a formatted string for test descriptions and tracks coverage:

```typescript
import { requirement } from '@popoverai/dotrequirements/test';

// Reference root requirement
test(requirement('AUTH-LOGIN-1'), () => {
  // Returns: "A registered user, Jamie, can log in to their account"
});

// Reference by numeric path
test(requirement('AUTH-LOGIN-1.0'), () => {
  // Returns: "When Jamie provides a valid username and password..."
});

// Reference by label path (for requirements with labels)
test(requirement('AUTH-LOGIN-2.given'), () => {
  // Returns: "Given: Jamie has two-factor authentication enabled on their account"
});

// Track multiple requirements in one test
test(requirement('AUTH-LOGIN-1', 'AUTH-SECURITY-1'), () => {
  // Both requirements tracked; returns first one's content
});
```

### Path Reference Patterns

| Pattern | Example | Description |
|---------|---------|-------------|
| Root | `AUTH-LOGIN-1` | Root requirement |
| Numeric | `AUTH-LOGIN-1.0` | First child (position 0) |
| Numeric nested | `AUTH-LOGIN-1.2.0` | First child of third child |
| Label | `AUTH-LOGIN-2.given` | First "Given" criterion |
| Label disambiguated | `AUTH-LOGIN-2.given#1` | Second "Given" criterion |
| Label nested | `AUTH-LOGIN-2.then.and` | First "And" under first "Then" |

### Coverage Reporting

Coverage isn't just a number—it's a map of which features have been tested and which haven't.

#### Local Report

After tests complete, a coverage summary prints to the console:

```
=== Requirements Coverage Report ===

Total Requirements: 12
Tested Requirements: 10
Untested Requirements: 2
Coverage: 83.3%

✓ Tested Requirements:
  - AUTH-LOGIN-1: A registered user, Jamie, can log in to their account
  - AUTH-LOGIN-1.0: When Jamie provides a valid username and password...

✗ Untested Requirements:
  - AUTH-LOGIN-2: A user with two-factor auth must provide an OTP
  - AUTH-SECURITY-1: Session tokens expire after 8 hours

====================================
```

#### Cloud Reporting

With cloud credentials configured, coverage is automatically reported to dot•requirements cloud:

- Historical tracking of when requirements were last tested
- Branch-based coverage (tracks `main`, feature branches, etc.)
- Query coverage via the MCP server

Run `dotreq link` to connect your project to the cloud and enable coverage reporting.

Cloud reporting is fire-and-forget—it never blocks or fails your tests.

---

## Requirements File Format

Requirements use Markdown with YAML frontmatter and `dotrequirements` fenced code blocks.

### File Naming

Files must match the pattern `*.requirements.md`:

```
.requirements/
  auth.requirements.md
  checkout.requirements.md

src/components/
  Button.requirements.md    # Colocated with implementation
  Button.tsx
```

### Structure

```markdown
---
document:
  title: "Document Title"
---

# Optional Markdown Content

You can include any Markdown here for context.

## Requirement Heading

```dotrequirements
AUTH-LOGIN-1: A registered user, Jamie, can log in to their account
  0. → When Jamie provides valid credentials, they are authenticated
  1. → When Jamie provides an incorrect password, they see an error
  2. → When Jamie's account is deactivated, they see a status message
```

More Markdown content between requirements...

## Another Requirement (with labels)

```dotrequirements
AUTH-LOGIN-2: A user with two-factor auth must provide an OTP
  0. Given → Jamie has two-factor authentication enabled
  1. When → Jamie provides valid credentials
  2. Then → Jamie is prompted to enter an OTP
```
```

### Format Details

- **Frontmatter**: YAML metadata (only `document.title` required for push)
- **Headings**: Optional documentation (not parsed as requirement data)
- **Fenced blocks**: `dotrequirements` blocks contain structured requirement data
- **First line**: `KEY: content` — the requirement identifier and summary
- **Criteria**: `position. → content` or `position. Label → content`
- **Arrow delimiter**: `→` (Unicode) or `->` (ASCII) both work
- **Labels**: Optional — use `Given`, `When`, `Then`, `And` if your team prefers BDD style

See [MARKDOWN_SCHEMA.md](https://github.com/PopoverAI/dotrequirements/blob/main/docs/reference/MARKDOWN_SCHEMA.md) for the complete specification.

---

## MCP Server

AI assistants can read your requirements in context, draft new ones, and verify tests actually validate what they claim to. The MCP server makes this possible through a standard protocol that works with Claude Code, Cursor, and other AI coding assistants.

### Setup

```bash
dotreq mcp-setup
```

Follow the prompts to configure for your AI assistant (Claude Code, Cursor, etc.).

### Available Tools

**Exploration:**
- `search_requirements` — Search by text or regex
- `get_requirement` — Get a requirement with its children and coverage
- `list_all_requirements` — List all requirements in the project
- `list_untested_requirements` — Find requirements without test coverage
- `get_requirements_by_test` — Get requirements referenced by a test file
- `get_tests_by_requirement` — Get tests that reference a requirement

**Authoring:**
- `create_requirement_document` — Get a Markdown template with format examples
- `validate_requirements` — Validate file schema (works offline)
- `style_check` — AI-powered style feedback on requirements (supports optional `requirementKeys` filter)
- `review_test` — Comprehensive test review (style + semantic correctness)

**Cloud:**
- `push_requirements` — Push to dot•requirements cloud
- `get_requirement_coverage` — Query coverage data
- `get_project_coverage_summary` — Project-wide coverage stats

**Diagnostic:**
- `debug_mcp_environment` — Debug MCP server configuration

### CI/CD Mode

For CI/CD environments (GitHub Actions, etc.), use the `--auth-from-env` flag to read credentials from environment variables instead of `project-settings.json`:

```bash
node packages/cli/dist/mcp/index.js --auth-from-env
```

Required environment variables:
- `DOTREQ_PROJECT_ID` — Your project slug
- `DOTREQ_PROJECT_SECRET` — Your project secret

**Important:** Without `--auth-from-env`, these environment variables are ignored. This explicit opt-in prevents credential conflicts between local and CI environments.

Example MCP config for GitHub Actions:

```json
{
  "mcpServers": {
    "dotrequirements": {
      "command": "node",
      "args": ["packages/cli/dist/mcp/index.js", "--auth-from-env"],
      "env": {
        "DOTREQ_PROJECT_ID": "${DOTREQ_PROJECT_ID}",
        "DOTREQ_PROJECT_SECRET": "${DOTREQ_PROJECT_SECRET}"
      }
    }
  }
}
```

See the [CI/CD Integration docs](https://docs.dotrequirements.io/tools/ai/ci-cd) for complete examples.

---

## Package Exports

```typescript
// CLI (main entry point)
import '@popoverai/dotrequirements';

// Test harness
import { requirement, prepare, finalize } from '@popoverai/dotrequirements/test';

// Schema utilities
import { parseRequirementsFile, validateRequirementsFile } from '@popoverai/dotrequirements/schema';

// Browser-compatible schema (no Node.js dependencies)
import { parseRequirementBlock } from '@popoverai/dotrequirements/schema/browser';

// MCP server
import '@popoverai/dotrequirements/mcp';
```

---

## Configuration

The CLI stores project credentials in `.requirements/project-settings.json`:

```json
{
  "projectId": "your-project-id",
  "projectSecret": "your-project-secret"
}
```

This file is automatically added to `.gitignore` during initialization.

---

## Links

- [Documentation](https://docs.dotrequirements.io)
- [Getting Started Guide](https://docs.dotrequirements.io/getting-started)
- [Support](mailto:support@popover.ca)

---

## License

MIT