CLI
The dot•requirements CLI (dotreq) manages your requirements workflow: initialize projects, sync with the cloud, validate files, and configure AI integrations.
Installation
npm
npm install @popoverai/dotrequirementsIf AI assistants will be running dotreq commands across your projects, a global install is often more convenient:
npm install -g @popoverai/dotrequirementsNote: Examples use
dotreqfor brevity, and because we’re pretty sure that’s what you’re going to end up using too. The full commanddotrequirementsalso works.
Commands
dotreq init
Initialize a project in the current directory. You’ll be prompted to choose between:
- Create a new project — Creates a new cloud project (or local-only if not authenticated)
- Connect to an existing project — Links to a project that already exists in the cloud
dotreq init
dotreq init --name my-project
dotreq init --invite abc123xyzInit will:
- Show which account you signed in as (
Signed in as you@example.com) after browser authentication, so a wrong-account init is visible before anything is saved - Create
.requirements/directory with example requirements - Save project credentials to
.requirements/project-settings.json(if authenticated) - Update
.gitignoreto protect credentials - Pull existing requirements (if connecting to an existing project)
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, you can join the team and connect to a project in one step:
npx @popoverai/dotrequirements@latest init --invite abc123xyzThis will:
- Show you the team name before authentication
- Open a browser for sign-in (or sign-up if you’re new)
- Add you to the team automatically
- Prompt you to select a project to connect
- Pull the project’s requirements
dotreq link
Connect your local project to the cloud — whatever the cloud side’s state. Opens a browser for authentication, then prompts you to select your team and a project, or to create one when the team has room. After you sign in, link prints the account it authenticated as (Signed in as you@example.com) — worth a glance if you hold more than one Google/GitHub identity, so a codebase-to-spec doc never lands on the wrong team.
dotreq link
dotreq link --yes --json # non-interactive (for AI assistants/scripts)
dotreq link --connect my-project # connect to a specific project
dotreq link --create -n my-api # create a new project with this nameUse link when:
- You have local requirements (hand-written or generated by codebase-to-spec) and want them in the cloud
- You’re on a new machine or clone and need to connect to an existing project
- Your credentials have expired and need refreshing
Options:
| Option | Description |
|---|---|
-y, --yes | Non-interactive: resolve every decision from defaults or flags; never prompt |
--json | Machine-readable output (one JSON object on stdout) |
--team <nameOrId> | Use this team (implies --yes) |
--connect <slug> | Connect to this existing project (implies --yes) |
--create | Create a new project (implies --yes) |
-n, --name <name> | Project name when creating (or for the automatic rename below) |
Non-interactive mode is built for AI assistants: the only human step is completing the browser login. A brand-new account’s single team is used automatically, and its untouched default project is connected and renamed to match your repository. When a genuine choice exists — multiple teams, existing projects, a plan at its project limit — link exits with code 2 and (with --json) a decision_needed object listing the options and the exact flag to retry with. Non-interactive link never syncs the cloud down, so freshly generated local requirements are never overwritten.
The --json result includes a signedInAs field with the authenticated account’s email, so an AI assistant relaying setup can confirm which identity it connected as. A successful non-interactive link also returns ready-to-share artifacts: an inviteUrl a teammate can open to join your team and review in the web app, and a shareSyncCommand that gives a teammate read-only access to the spec in their IDE without an account. (The invite URL requires team admin rights to mint; without them, link still succeeds and simply omits it.)
dotreq diff
Show how the repo and the cloud differ, without changing anything.
dotreq diff # every document, with a verdict each
dotreq diff auth.requirements.md # one or more documents, in detail
dotreq diff --exit-code # exit 1 on any drift (for CI)Each document gets one verdict: in sync, additions in repo, additions in cloud, conflict, only in repo, only in cloud, or invalid file. With a document scope, the output unfolds one level — the requirement keys and criterion positions that differ. A conflict prints the command that resolves it.
dotreq sync
Reconcile the repo and the cloud. With no flags, both sides contribute their additions and nothing contested is touched — the daily gesture.
dotreq sync # both sides contribute (additive, safe)
dotreq sync --cloud-contributes # bring the cloud's additions down only
dotreq sync --repo-contributes # send the repo's additions up only
dotreq sync --repo-wins # repo is authoritative (may delete in cloud)
dotreq sync --cloud-wins # cloud is authoritative (may delete locally)
dotreq sync auth.requirements.md # limit to one or more documentsOptions:
| Option | Description |
|---|---|
--cloud-contributes | Apply only the cloud’s additions locally |
--repo-contributes | Apply only the repo’s additions to the cloud |
--repo-wins | Repo is the authority for the scope; the cloud is made to match (can delete cloud documents) |
--cloud-wins | Cloud is the authority for the scope; the repo is made to match (can delete local files) |
--share <token> | Sync down using a read-only share token (no auth required) |
-y, --yes | Skip the deletion confirmation prompt |
Additive modes never delete; a --wins mode can, and always lists every document it will permanently delete before writing anything. A conflict (both sides changed the same thing) is left untouched under additive modes and reported with the --wins command that resolves it. After a sync that writes to the cloud, the output lists each synced document’s URL — that’s where your team reviews it.
First-time setup with a share token:
If a team member shares a sync command with you, you can sync requirements down without creating an account:
npx @popoverai/dotrequirements@latest sync --share drt_abc123...This gives you read-only access to view requirements. To contribute changes or report coverage, run dotreq link afterward to set up full access.
Where files are written:
Sync writes new documents to the .requirements/ directory. Files are matched by document ID (stored in frontmatter), so renaming a file won’t cause duplicates; a file moved outside .requirements/ is updated in place. New documents are named by sanitized title (e.g., “Login Flow” → login-flow.requirements.md).
When sync rewrites a file, fields you added to its frontmatter — owner:, tags:, whatever your tooling reads — are kept, along with your comments and formatting, in either direction and under every mode. The cloud has no competing value for them, so nothing is authoritative over them.
defaultPrefix is different, because the cloud document has one too. A prefix that exists on only one side is not itself a difference: if that’s all that differs, dotreq diff reports the document in sync and nothing is written either way. When a sync does rewrite the file — because its content diverged — the prefix follows the same authority as everything else: the cloud’s prefix replaces yours when the cloud has one, an additive sync leaves yours alone when it doesn’t, and --cloud-wins removes it.
dotreq validate
Validate requirements files against the schema. This checks file structure and format—it does not run your test suite.
dotreq validate
dotreq validate --file .requirements/auth.requirements.mdOptions:
| Option | Description |
|---|---|
--file <path> | Validate specific file only |
dotreq search
Search requirements by text or regex across every .requirements.md file in the project. Searches requirement IDs, content, and labels.
dotreq search "login"
dotreq search "AUTH-.*" --regexOptions:
| Option | Description |
|---|---|
--regex | Interpret the query as a case-insensitive regular expression |
dotreq get
Print a requirement (or subtree) by ID, with its test references and source code locations.
dotreq get AUTH-LOGIN-1
dotreq get AUTH-LOGIN-1.0Both numeric paths (AUTH-LOGIN-1.0.1) and label paths (AUTH-LOGIN-1.given.and) resolve to the same node.
dotreq list
Summarize requirements in the project. Without flags, lists every root requirement with its child count. With --untested, filters to roots that have no requirement() references anywhere in the codebase.
dotreq list
dotreq list --untestedOptions:
| Option | Description |
|---|---|
--untested | Filter to root requirements with no test references |
dotreq requirements-for
Show which requirements a test file references, with the line where each requirement() call lives.
dotreq requirements-for src/auth.test.tsUseful when you’ve inherited tests and want to see what requirements they claim to cover.
dotreq tests-for
Show which tests reference each requirement in a .requirements.md file. The inverse of requirements-for.
dotreq tests-for .requirements/auth.requirements.mdUseful for spotting requirements that have drifted out of test coverage.
dotreq acceptance-test
Run browser-based acceptance tests against requirements. Uses AI-powered browser automation to verify that your application behaves as specified.
dotreq acceptance-test LOGIN-1
dotreq acceptance-test LOGIN-1 https://example.com
dotreq acceptance-test LOGIN-1 --jsonGiven a requirement like:
LOGIN-1: User can log in with valid credentials
0. given → user is on login page
1. when → user enters valid email and password
2. then → user sees dashboardRunning dotreq acceptance-test LOGIN-1 produces:
Testing LOGIN-1 against https://your-app.com...
✓ LOGIN-1: User can log in with valid credentials
✓ LOGIN-1.0 (given): user is on login page
✓ LOGIN-1.1 (when): user enters valid email and password
✓ LOGIN-1.2 (then): user sees dashboard
4/4 passedOptions:
| Option | Description |
|---|---|
--json | Output results as JSON (for CI/CD integration) |
Configuration required:
Browser testing needs a Stagehand model and the API key for that model’s provider in project-settings.json:
{
"projectId": "your-project-id",
"projectSecret": "your-project-secret",
"defaultURL": "https://your-app.com",
"browserTest": {
"modelName": "gateway/anthropic/claude-haiku-4-5",
"modelApiKey": "your-api-key"
}
}See Browser Test Configuration for all available settings.
dotreq cts skill-install (Alpha)
Generate behavioral requirements from an existing codebase. This command installs the codebase-to-spec skill, worker agent, and workflow into .claude/ — no global install required. You then run it from Claude Code , where it plans a behavioral outline, drafts each area’s requirements through an independent review loop, and writes .requirements/*.requirements.md files.
npx -y @popoverai/dotrequirements@latest cts skill-installthen, in Claude Code:
/codebase-to-specThis is alpha-quality and prompt-sensitive — output quality varies by codebase and we’re actively iterating. See Codebase to Spec for full documentation, prerequisites, and exit codes.
dotreq ai-setup
Configure AI assistants to use the requirements-driven workflow. Interactive setup that installs the workflow guidance into your project’s context file (CLAUDE.md / AGENTS.md) and removes any MCP configuration written by earlier versions.
dotreq ai-setupSupports: Claude Code, Cursor, Google Antigravity, OpenAI Codex, GitHub Copilot.
Pass --assistant <id> to skip the interactive selector — useful when an AI assistant configures itself (e.g. dotreq ai-setup --assistant claude-code). Supported identifiers: claude-code, cursor, antigravity, codex, github-copilot.
See Agent Workflow for details.
dotreq mcp (Retired)
Earlier versions shipped a local MCP server started with this command. It’s retired — the command now exits with a message pointing at the migration path. Coding assistants use the CLI verbs directly; chat apps use the MCP server. See Local MCP (Retired).
dotreq harness prepare
Parse requirements and build a lookup cache for multi-language test tracking. Run before tests in non-JavaScript projects.
dotreq harness prepare
dotreq harness prepare --quietCreates .requirements/.cache/lookup.json (requirement lookup) and .requirements/.cache/tracking.jsonl (empty tracking file). JavaScript projects don’t need this — the test harness calls prepare() automatically.
Options:
| Option | Description |
|---|---|
--quiet | Suppress output (for scripting) |
dotreq harness finalize
Aggregate test tracking data and print a coverage report. Run after tests in non-JavaScript projects.
dotreq harness finalize
dotreq harness finalize --push
dotreq harness finalize --quiet
dotreq harness finalize --push --context pytestOptions:
| Option | Description |
|---|---|
--push | Push coverage to dot•requirements cloud |
--quiet | Output only coverage percentage (for scripting) |
--context <label> | Attribution label identifying the reporter (e.g. "pytest", "Jest"). Stored on each cloud coverage row so you can see which tool produced the result. Free-form; any string works. |
dotreq report
View coverage from the most recent local test run, or from the cloud-persisted record.
dotreq report # local cache (default)
dotreq report --source cloud # cloud-persisted record
dotreq report --source cloud --branch main # filter to a branch
dotreq report --source cloud --since 1700000000000 # filter to records after a timestamp
dotreq report --requirement AUTH-LOGIN # scope to one requirement
dotreq report --format jsonOptions:
| Option | Description |
|---|---|
--source <source> | Where to read coverage from: local (default) or cloud |
--format <format> | Output format: console (default), json, markdown |
--requirement <id> | Filter to a specific requirement (and its children for local source) |
--branch <name> | Cloud-only: filter coverage to a specific git branch |
--since <timestamp> | Cloud-only: only show coverage recorded after this Unix-ms timestamp |
Local source (the default) reads from .requirements/.cache/tracking.jsonl populated by your most recent test run on this machine. Warns if requirements have changed since the last harness prepare, or if no tracking data exists.
Whatever the source or format, if coverage has stopped reaching the cloud the command leads with how long it has been since coverage last recorded and why the last attempt failed. The notice goes to stderr, so --format json stays parseable, and it stops once a report succeeds.
Cloud source reads the persisted record from dot•requirements cloud. Covers every root requirement — both those with cloud coverage records and those that have never been tested. Requires cloud authentication (run dotreq link first).
--branch and --since only apply with --source cloud; using them with the local source errors out.
dotreq style-check
Style review of a requirements file or a test file. By default it emits judgment-ready review materials — your project’s style guide, the content under review, and judgment instructions — for the calling agent (typically a fresh-eyes subagent) to perform the review. Pass --source cloud to have the hosted reviewer do the judging instead.
dotreq style-check .requirements/auth.requirements.md
dotreq style-check .requirements/auth.requirements.md --keys AUTH-LOGIN-1,AUTH-LOGIN-2
dotreq style-check src/auth.test.ts --source cloudOptions:
| Option | Description |
|---|---|
--keys <list> | Comma-separated requirement keys to limit the review (requirements files only) |
--source <local|cloud> | Where the judgment runs: local (default) emits review materials; cloud uses the hosted reviewer |
--model <name> | Override the AI model used for the review (cloud mode only) |
When .requirements/STYLE.md exists in your project, its contents are the style guide — in the emitted materials and in the hosted reviewer’s prompt alike.
The default local mode needs no account and works offline. --source cloud requires cloud authentication — run dotreq link first.
dotreq review-test
Semantic review of a test file against its referenced requirements: does test setup match GIVEN conditions, do actions match WHEN triggers, do assertions match THEN outcomes? By default it emits the referenced requirement trees, the test content, and judgment instructions for the calling agent to review (unresolvable requirement references are flagged mechanically either way). Pass --source cloud for the hosted reviewer.
dotreq review-test src/auth.test.ts
dotreq review-test src/auth.test.ts --source cloudCatches tests that reference a requirement but don’t actually validate what the requirement specifies — especially valuable when AI assistants write tests.
The default local mode needs no account. --source cloud requires cloud authentication.
dotreq create-requirement-document
Print a Markdown template demonstrating the requirements file format, with format guidance and style examples. Use it to seed a new .requirements.md file or to prime an AI assistant’s context before authoring.
dotreq create-requirement-document
dotreq create-requirement-document .requirements/auth.requirements.mdWhen a file path is provided, the template references that filename. If .requirements/STYLE.md exists, its contents replace the bundled default style body in the output. The template is printed to stdout — redirect it into a new file or pipe it into your editor.
Configuration
The CLI stores project credentials in .requirements/project-settings.json:
{
"projectId": "your-project-id",
"projectSecret": "your-project-secret"
}This file is automatically added to .gitignore during initialization.
Environment Variables
| Variable | Description |
|---|---|
DOTREQUIREMENTS_PROJECT_ROOT | Override project root detection |
Browser Test Configuration
For dotreq acceptance-test, add these settings to project-settings.json:
{
"defaultURL": "https://your-app.com",
"browserTest": {
"modelName": "gateway/anthropic/claude-haiku-4-5",
"modelApiKey": "your-api-key",
"vercelBypassSecret": "optional-vercel-secret",
"browserbaseApiKey": "optional-browserbase-key",
"browserbaseProjectId": "optional-browserbase-project"
}
}Pick any Stagehand-supported model. Example values: gateway/anthropic/claude-haiku-4-5 (Vercel AI Gateway key), google/gemini-3-flash-preview (Gemini key).
Setting both browserbaseApiKey and browserbaseProjectId switches runs from LOCAL (spawns Playwright on your machine) to BROWSERBASE (managed cloud browsers).
| Setting | Required | Description |
|---|---|---|
defaultURL | No | Default URL when none provided to acceptance-test |
browserTest.modelName | Yes | Stagehand model string (e.g. gateway/anthropic/claude-haiku-4-5) |
browserTest.modelApiKey | Yes | API key for the provider of modelName |
browserTest.vercelBypassSecret | No | Bypass Vercel authentication for automated testing |
browserTest.browserbaseApiKey | No | Browserbase API key for cloud browser sessions |
browserTest.browserbaseProjectId | No | Browserbase project ID |
File Discovery
The CLI finds **/*.requirements.md files anywhere in your project, not just in .requirements/. This enables colocation with components or tests.
Ignored directories: node_modules/, dist/, .git/, build/, example/, examples/, __tests__/, fixtures/, .fixtures/, .claude/worktrees/
Note that __tests__/, fixtures/, and .fixtures/ are ignored so that sample requirements written for a test suite are not mistaken for your own. If you colocate requirements with tests, keep them beside the test directory rather than inside it — a file in __tests__/ is skipped silently.
Claude Code worktrees under .claude/worktrees/ hold other sessions’ checkouts of your repo, so a stale copy of your requirements inside one never affects discovery or validation of the workspace itself.
Project Root Detection
The CLI determines project root in this order:
- Explicit
DOTREQUIREMENTS_PROJECT_ROOTenvironment variable - Walking up from current directory looking for
.requirements/ - Current working directory
Monorepo Considerations
We recommend initializing at the monorepo root. Dot•requirements projects are designed to be analogous to codebases. In this configuration, all packages share the same project and credentials.
Supported configurations:
- Single root at monorepo level
- Peer directories with separate projects (independent projects)
Unsupported configurations:
- Nested roots (a directory containing
.requirements/with another.requirements/in a child directory) - Same project accessed from different directories without shared root
What Works Offline
These features work without cloud authentication:
- Write requirements (
.requirements.mdfiles) - Validate requirements (
dotreq validate) - Search and explore (
dotreq search,get,list,requirements-for,tests-for) - Reference requirements in tests (
requirement()) - Local coverage reporting (
dotreq report, default--source local) - Generate a requirements template (
dotreq create-requirement-document)
These features require cloud authentication:
- Sync requirements (
sync/diff) - Cloud coverage queries (
dotreq report --source cloud) - AI-powered style checking and test review (
dotreq style-check,dotreq review-test) - Team collaboration