@popoverai/dotrequirements 0.26.1 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/README.md +13 -69
  2. package/dist/cli.js +19 -7
  3. package/dist/codebase-to-spec/present.js +4 -5
  4. package/dist/codebase-to-spec/validate.js +3 -2
  5. package/dist/commands/acceptance-test.js +4 -2
  6. package/dist/commands/ai-setup.d.ts +8 -2
  7. package/dist/commands/ai-setup.js +154 -310
  8. package/dist/commands/get.js +6 -2
  9. package/dist/commands/init.js +8 -6
  10. package/dist/commands/link-resolution.d.ts +3 -1
  11. package/dist/commands/link-resolution.js +4 -2
  12. package/dist/commands/mcp.d.ts +8 -2
  13. package/dist/commands/mcp.js +17 -6
  14. package/dist/commands/pull.js +36 -3
  15. package/dist/commands/push.js +54 -16
  16. package/dist/commands/report.js +18 -3
  17. package/dist/commands/review-test.d.ts +5 -1
  18. package/dist/commands/review-test.js +117 -15
  19. package/dist/commands/style-check.d.ts +1 -0
  20. package/dist/commands/style-check.js +137 -13
  21. package/dist/commands/tests-for.js +13 -13
  22. package/dist/commands/validate.js +14 -14
  23. package/dist/convex.d.ts +1 -3
  24. package/dist/convex.js +3 -3
  25. package/dist/harness/cache.d.ts +19 -3
  26. package/dist/harness/cache.js +38 -12
  27. package/dist/harness/finalize.js +33 -1
  28. package/dist/harness/index.js +16 -9
  29. package/dist/harness/requirementsLoader.js +12 -0
  30. package/dist/harness/tracking.d.ts +17 -2
  31. package/dist/harness/tracking.js +83 -9
  32. package/dist/push/core.d.ts +50 -0
  33. package/dist/push/core.js +149 -11
  34. package/dist/push/index.d.ts +1 -1
  35. package/dist/push/index.js +1 -1
  36. package/dist/requirements/cloud-ai.d.ts +21 -8
  37. package/dist/requirements/cloud-ai.js +10 -8
  38. package/dist/requirements/cloud-coverage.d.ts +12 -2
  39. package/dist/requirements/cloud-coverage.js +30 -3
  40. package/dist/requirements/grep.d.ts +7 -2
  41. package/dist/requirements/grep.js +75 -47
  42. package/dist/schema/builder.d.ts +1 -1
  43. package/dist/schema/builder.js +13 -0
  44. package/dist/schema/conversions.d.ts +7 -2
  45. package/dist/schema/conversions.js +13 -4
  46. package/dist/schema/parser-core.d.ts +41 -0
  47. package/dist/schema/parser-core.js +113 -18
  48. package/dist/schema/parser.d.ts +8 -26
  49. package/dist/schema/parser.js +23 -251
  50. package/dist/schema/resolver.js +18 -8
  51. package/dist/templates/context-file-section.md +25 -22
  52. package/dist/utils/context-file.d.ts +7 -3
  53. package/dist/utils/context-file.js +10 -7
  54. package/dist/utils/env.js +17 -1
  55. package/dist/utils/oauth-flow.js +8 -0
  56. package/dist/utils/project-settings.d.ts +5 -0
  57. package/dist/utils/project-settings.js +36 -1
  58. package/package.json +3 -5
  59. package/dist/mcp/convexClient.d.ts +0 -19
  60. package/dist/mcp/convexClient.js +0 -24
  61. package/dist/mcp/handlers/authoring.d.ts +0 -41
  62. package/dist/mcp/handlers/authoring.js +0 -104
  63. package/dist/mcp/handlers/debug.d.ts +0 -16
  64. package/dist/mcp/handlers/debug.js +0 -37
  65. package/dist/mcp/handlers/get.d.ts +0 -24
  66. package/dist/mcp/handlers/get.js +0 -65
  67. package/dist/mcp/handlers/index.d.ts +0 -28
  68. package/dist/mcp/handlers/index.js +0 -19
  69. package/dist/mcp/handlers/list.d.ts +0 -7
  70. package/dist/mcp/handlers/list.js +0 -43
  71. package/dist/mcp/handlers/push.d.ts +0 -26
  72. package/dist/mcp/handlers/push.js +0 -186
  73. package/dist/mcp/handlers/report.d.ts +0 -16
  74. package/dist/mcp/handlers/report.js +0 -134
  75. package/dist/mcp/handlers/review.d.ts +0 -51
  76. package/dist/mcp/handlers/review.js +0 -200
  77. package/dist/mcp/handlers/search.d.ts +0 -30
  78. package/dist/mcp/handlers/search.js +0 -58
  79. package/dist/mcp/handlers/test-mapping.d.ts +0 -39
  80. package/dist/mcp/handlers/test-mapping.js +0 -133
  81. package/dist/mcp/handlers/types.d.ts +0 -75
  82. package/dist/mcp/handlers/types.js +0 -25
  83. package/dist/mcp/index.d.ts +0 -45
  84. package/dist/mcp/index.js +0 -634
package/README.md CHANGED
@@ -258,20 +258,12 @@ Then, in Claude Code, run `/codebase-to-spec` (or just ask — e.g. "spec the au
258
258
 
259
259
  ### `dotreq ai-setup`
260
260
 
261
- Configure the MCP server for AI assistants (Claude Code, Cursor, etc.).
261
+ Install the requirements-driven workflow guidance for AI assistants (Claude Code, Cursor, Codex, Antigravity, GitHub Copilot) — and clean up any MCP configuration an earlier version wrote (the local MCP server is retired; agents use the CLI verbs directly).
262
262
 
263
263
  ```bash
264
264
  dotreq ai-setup
265
265
  ```
266
266
 
267
- ### `dotreq mcp`
268
-
269
- Start the MCP server manually (typically not needed—AI assistants start it automatically after `ai-setup`).
270
-
271
- ```bash
272
- dotreq mcp
273
- ```
274
-
275
267
  ### `dotreq harness prepare`
276
268
 
277
269
  Parse requirements and build a lookup cache for multi-language test tracking. Run before tests in non-JavaScript projects. JavaScript projects don't need this — the test harness calls `prepare()` automatically.
@@ -332,10 +324,11 @@ dotreq style-check .requirements/auth.requirements.md --keys AUTH-LOGIN-1,AUTH-L
332
324
 
333
325
  | Option | Description |
334
326
  |--------|-------------|
327
+ | `--source <local\|cloud>` | Where the review runs. Default `local` emits the style guide plus your content for your AI agent to judge — no account needed. `cloud` runs a hosted review (requires `dotreq link`). |
335
328
  | `--keys <list>` | Comma-separated requirement keys to limit the review (requirements files only) |
336
- | `--model <name>` | Override the AI model used for the review |
329
+ | `--model <name>` | Override the AI model used for the review (`--source cloud` only) |
337
330
 
338
- When `.requirements/STYLE.md` exists in your project, its contents are included in the AI's prompt so project-specific style preferences influence the feedback. Requires cloud authentication.
331
+ When `.requirements/STYLE.md` exists in your project, its contents are included so project-specific style preferences influence the feedback.
339
332
 
340
333
  ### `dotreq review-test`
341
334
 
@@ -345,7 +338,7 @@ AI-powered semantic review of a test file against its referenced requirements. V
345
338
  dotreq review-test src/auth.test.ts
346
339
  ```
347
340
 
348
- Catches tests that reference a requirement but don't actually validate what the requirement specifies — especially valuable when AI assistants write tests. Requires cloud authentication.
341
+ Catches tests that reference a requirement but don't actually validate what the requirement specifies — especially valuable when AI assistants write tests. By default this emits the referenced requirements plus your test content for your AI agent to judge locally — no account needed. Add `--source cloud` for a hosted review (requires `dotreq link`).
349
342
 
350
343
  ### `dotreq create-requirement-document`
351
344
 
@@ -370,7 +363,7 @@ The following features work fully offline—no account required:
370
363
  - Reference requirements in tests (`requirement()`)
371
364
  - Local coverage reporting (`dotreq report`, default `--source local`)
372
365
  - Generate a requirements template (`dotreq create-requirement-document`)
373
- - MCP tools that mirror the offline CLI verbs
366
+ - Local style-review materials for AI agents (`dotreq style-check`, `dotreq review-test`)
374
367
 
375
368
  The following features require a dot•requirements cloud account:
376
369
 
@@ -540,7 +533,7 @@ With cloud credentials configured, coverage is automatically reported to dot•r
540
533
 
541
534
  - Historical tracking of when requirements were last tested
542
535
  - Branch-based coverage (tracks `main`, feature branches, etc.)
543
- - Query coverage via the MCP server
536
+ - Query cloud coverage from the terminal (`dotreq report --source cloud`)
544
537
 
545
538
  Run `dotreq link` to connect your project to the cloud and enable coverage reporting.
546
539
 
@@ -613,48 +606,19 @@ See [MARKDOWN_SCHEMA.md](https://github.com/PopoverAI/dotrequirements/blob/main/
613
606
 
614
607
  ---
615
608
 
616
- ## MCP Server
617
-
618
- 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.
619
-
620
- ### Setup
621
-
622
- ```bash
623
- dotreq ai-setup
624
- ```
625
-
626
- Follow the prompts to configure for your AI assistant (Claude Code, Cursor, etc.).
609
+ ## AI Assistant Integration
627
610
 
628
- ### Available Tools
611
+ AI coding assistants use the CLI verbs directly — no MCP server to install or configure. `dotreq ai-setup` writes the requirements-driven workflow guidance into your assistant's context file (CLAUDE.md / AGENTS.md), which tells the agent when to explore, validate, style-review, and push. For chat apps (Claude, ChatGPT), use the dot•requirements remote connector instead.
629
612
 
630
- **Exploration:**
631
- - `search_requirements` — Search by text or regex
632
- - `get_requirement` — Get a requirement with its children and coverage
633
- - `list_requirements` — List all requirements in the project (set `untested: true` to filter to coverage gaps)
634
- - `get_requirements_by_test` — Get requirements referenced by a test file
635
- - `get_tests_by_requirement` — Get tests that reference a requirement
636
-
637
- **Authoring:**
638
- - `create_requirement_document` — Get a Markdown template with format examples
639
- - `validate_requirements` — Validate file schema (works offline)
640
- - `style_check` — AI-powered style feedback on requirements (supports optional `requirementKeys` filter)
641
- - `review_test` — Comprehensive test review (style + semantic correctness)
642
-
643
- **Coverage:**
644
- - `report_coverage` — Coverage from local cache or cloud, with optional requirement / branch / since filters
645
-
646
- **Cloud:**
647
- - `push_requirements` — Push to dot•requirements cloud
648
-
649
- **Diagnostic:**
650
- - `debug_mcp_environment` — Debug MCP server configuration
613
+ > The local MCP server shipped by earlier versions is retired. `dotreq ai-setup` removes stale MCP registrations; `dotreq mcp` now exits with a pointer to this migration.
651
614
 
652
615
  ### CI/CD Mode
653
616
 
654
- For CI/CD environments (GitHub Actions, etc.), use the `--auth-from-env` flag to read credentials from environment variables instead of `project-settings.json`:
617
+ For CI/CD environments (GitHub Actions, etc.), use the global `--auth-from-env` flag so cloud commands read credentials from environment variables instead of `project-settings.json`:
655
618
 
656
619
  ```bash
657
- node packages/cli/dist/mcp/index.js --auth-from-env
620
+ dotreq --auth-from-env push
621
+ dotreq --auth-from-env style-check .requirements/auth.requirements.md --source cloud
658
622
  ```
659
623
 
660
624
  Required environment variables:
@@ -663,23 +627,6 @@ Required environment variables:
663
627
 
664
628
  **Important:** Without `--auth-from-env`, these environment variables are ignored. This explicit opt-in prevents credential conflicts between local and CI environments.
665
629
 
666
- Example MCP config for GitHub Actions:
667
-
668
- ```json
669
- {
670
- "mcpServers": {
671
- "dotrequirements": {
672
- "command": "node",
673
- "args": ["packages/cli/dist/mcp/index.js", "--auth-from-env"],
674
- "env": {
675
- "DOTREQ_PROJECT_ID": "${DOTREQ_PROJECT_ID}",
676
- "DOTREQ_PROJECT_SECRET": "${DOTREQ_PROJECT_SECRET}"
677
- }
678
- }
679
- }
680
- }
681
- ```
682
-
683
630
  See the [CI/CD Integration docs](https://docs.dotrequirements.io/tools/ai/ci-cd) for complete examples.
684
631
 
685
632
  ---
@@ -698,9 +645,6 @@ import { parseRequirementsFile, validateRequirementsFile } from '@popoverai/dotr
698
645
 
699
646
  // Browser-compatible schema (no Node.js dependencies)
700
647
  import { parseRequirementBlock } from '@popoverai/dotrequirements/schema/browser';
701
-
702
- // MCP server
703
- import '@popoverai/dotrequirements/mcp';
704
648
  ```
705
649
 
706
650
  ---
package/dist/cli.js CHANGED
@@ -24,6 +24,7 @@ import { styleCheckCommand } from "./commands/style-check.js";
24
24
  import { testsForCommand } from "./commands/tests-for.js";
25
25
  import { validateCommand } from "./commands/validate.js";
26
26
  import { loadEnvFile } from "./utils/env.js";
27
+ import { setAuthFromEnv } from "./utils/project-settings.js";
27
28
  // Read version from package.json
28
29
  const __filename = fileURLToPath(import.meta.url);
29
30
  const __dirname = dirname(__filename);
@@ -54,8 +55,17 @@ function wrapCommand(fn) {
54
55
  const program = new Command();
55
56
  program
56
57
  .name("dotrequirements")
57
- .description("Requirements tracking CLI with test harness and MCP server")
58
- .version(VERSION);
58
+ .description("Requirements tracking CLI with test harness")
59
+ .version(VERSION)
60
+ // AUTHZ-6: explicit CI/CD credential injection — with this flag, cloud
61
+ // commands read DOTREQ_PROJECT_ID / DOTREQ_PROJECT_SECRET instead of
62
+ // project-settings.json; without it those variables are ignored.
63
+ .option("--auth-from-env", "Read cloud credentials from DOTREQ_PROJECT_ID and DOTREQ_PROJECT_SECRET (CI/CD)")
64
+ .hook("preAction", (thisCommand) => {
65
+ if (thisCommand.opts().authFromEnv) {
66
+ setAuthFromEnv(true);
67
+ }
68
+ });
59
69
  program
60
70
  .command("init")
61
71
  .description("Initialize a new dotrequirements project")
@@ -126,11 +136,11 @@ program
126
136
  .action(wrapCommand(reportCommand));
127
137
  program
128
138
  .command("mcp")
129
- .description("Start the MCP (Model Context Protocol) server for AI assistant integration")
139
+ .description("(retired) The local MCP server was removed — run `dotreq ai-setup` to update your configuration")
130
140
  .action(wrapCommand(mcpCommand));
131
141
  program
132
142
  .command("ai-setup")
133
- .description("Configure MCP server for your AI assistant (Claude Code, Claude Desktop, etc.)")
143
+ .description("Set up your coding assistant to use the dotreq workflow (Claude Code, Cursor, Codex, Antigravity, GitHub Copilot)")
134
144
  .option("-a, --assistant <id>", "Configure for this assistant without prompting (e.g. claude-code)")
135
145
  .action(wrapCommand(aiSetupCommand));
136
146
  program
@@ -157,16 +167,18 @@ program
157
167
  .action(wrapCommand(testsForCommand));
158
168
  program
159
169
  .command("style-check <file>")
160
- .description("AI style review of a requirements or test file (requires cloud auth)")
170
+ .description("Style review of a requirements or test file — emits judgment-ready review materials for the calling agent by default; --source cloud sends it for hosted AI review")
161
171
  .option("--keys <keys>", "Comma-separated requirement keys to limit the review (requirements files only)", (value) => value
162
172
  .split(",")
163
173
  .map((k) => k.trim())
164
174
  .filter(Boolean))
165
- .option("--model <name>", "Override the AI model used for the review")
175
+ .option("--source <source>", 'Where the judgment runs: "local" (default) emits review materials for the caller; "cloud" uses the hosted review endpoint (requires cloud auth)')
176
+ .option("--model <name>", "Override the AI model used for the review (cloud mode only)")
166
177
  .action(wrapCommand(styleCheckCommand));
167
178
  program
168
179
  .command("review-test <test-file>")
169
- .description("AI semantic review of a test file against its referenced requirements (requires cloud auth)")
180
+ .description("Semantic review of a test file against its referenced requirements — emits judgment-ready review materials for the calling agent by default; --source cloud sends it for hosted AI review")
181
+ .option("--source <source>", 'Where the judgment runs: "local" (default) emits review materials for the caller; "cloud" uses the hosted review endpoint (requires cloud auth)')
170
182
  .action(wrapCommand(reviewTestCommand));
171
183
  program
172
184
  .command("create-requirement-document [file-path]")
@@ -16,6 +16,7 @@
16
16
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
17
17
  import { dirname, join } from "node:path";
18
18
  import { parseRequirementsFile } from "../schema/parser.js";
19
+ import { stripFrontmatterBlock } from "../schema/parser-core.js";
19
20
  import { generateRunMarker } from "../schema/run-marker.js";
20
21
  import { sanitizeAreaName } from "./area-name.js";
21
22
  import { promptOverwriteChoice } from "./interactive.js";
@@ -187,11 +188,9 @@ async function resolveOverwriteAction(policy, path) {
187
188
  */
188
189
  function mergeContent(existingPath, newContent) {
189
190
  const existing = readFileSync(existingPath, "utf-8").trimEnd();
190
- // Strip frontmatter from newContent (it would conflict with existing frontmatter)
191
- const fmMatch = newContent.match(/^---\n[\s\S]+?\n---\n+/);
192
- const body = fmMatch
193
- ? newContent.slice(fmMatch[0].length).trimStart()
194
- : newContent;
191
+ // Strip frontmatter from newContent (it would conflict with existing
192
+ // frontmatter) via the shared CRLF-normalizing helper.
193
+ const body = stripFrontmatterBlock(newContent).trimStart();
195
194
  return [
196
195
  existing,
197
196
  "",
@@ -87,8 +87,9 @@ function describeValidationError(err) {
87
87
  const parts = [err.message];
88
88
  let cursor = err.cause;
89
89
  while (cursor instanceof Error) {
90
- // Don't repeat the same message twice if the wrapper just rethrew.
91
- if (cursor.message && cursor.message !== parts[parts.length - 1]) {
90
+ // Don't repeat the same message twice if the wrapper just rethrew
91
+ // (or already embedded the inner message in its own).
92
+ if (cursor.message && !parts[parts.length - 1].includes(cursor.message)) {
92
93
  parts.push(cursor.message);
93
94
  }
94
95
  cursor = cursor.cause;
@@ -127,8 +127,10 @@ export async function acceptanceTestCommand(requirementKey, url, options) {
127
127
  else {
128
128
  displayResults(requirementTree, results);
129
129
  }
130
- // 11. Exit with appropriate code
131
- const failedCount = results.filter((r) => r.status !== "passed").length;
130
+ // 11. Exit with appropriate code — computed over the requirement tree so
131
+ // a requirement with a missing result counts as not passing, agreeing
132
+ // with the displayed counts (ACCEPTANCE-1.0/.1/.2)
133
+ const failedCount = requirementTree.filter((_, i) => results[i]?.status !== "passed").length;
132
134
  if (failedCount > 0) {
133
135
  process.exit(1);
134
136
  }
@@ -1,13 +1,19 @@
1
1
  /**
2
2
  * Assistant identifiers accepted by the non-interactive --assistant flag
3
3
  * (AISETUP-1). "other" is interactive-only: it prompts for a custom path.
4
+ *
5
+ * Claude Desktop was dropped: it consumed only the retired local MCP server
6
+ * (no terminal, no context file), so setup has nothing to install for it. Its
7
+ * path forward is the remote MCP connector.
4
8
  */
5
- export declare const SUPPORTED_ASSISTANTS: readonly ["claude-code", "claude-desktop", "cursor", "antigravity", "codex", "github-copilot"];
9
+ export declare const SUPPORTED_ASSISTANTS: readonly ["claude-code", "cursor", "antigravity", "codex", "github-copilot"];
6
10
  export interface AiSetupOptions {
7
11
  assistant?: string;
8
12
  }
9
13
  /**
10
- * AI setup command - configures the MCP server for AI assistants
14
+ * AI setup command — installs the requirements-driven workflow guidance into
15
+ * the assistant's context file, and removes any MCP configuration an earlier
16
+ * version wrote (the local MCP server is retired).
11
17
  *
12
18
  * AISETUP-1: with --assistant <id>, setup runs without any interactive prompt
13
19
  * (an AI assistant configuring itself knows which assistant it is).