@popoverai/dotrequirements 0.22.0 → 0.24.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 (230) hide show
  1. package/README.md +173 -23
  2. package/dist/cli.js +121 -61
  3. package/dist/codebase-to-spec/budget.d.ts +53 -0
  4. package/dist/codebase-to-spec/budget.js +80 -0
  5. package/dist/codebase-to-spec/cache.d.ts +49 -0
  6. package/dist/codebase-to-spec/cache.js +54 -0
  7. package/dist/codebase-to-spec/claude.d.ts +69 -0
  8. package/dist/codebase-to-spec/claude.js +126 -0
  9. package/dist/codebase-to-spec/compose.d.ts +49 -0
  10. package/dist/codebase-to-spec/compose.js +124 -0
  11. package/dist/codebase-to-spec/edit-loop.d.ts +54 -0
  12. package/dist/codebase-to-spec/edit-loop.js +195 -0
  13. package/dist/codebase-to-spec/editor.d.ts +54 -0
  14. package/dist/codebase-to-spec/editor.js +74 -0
  15. package/dist/codebase-to-spec/exit-codes.d.ts +40 -0
  16. package/dist/codebase-to-spec/exit-codes.js +58 -0
  17. package/dist/codebase-to-spec/fan-out.d.ts +63 -0
  18. package/dist/codebase-to-spec/fan-out.js +215 -0
  19. package/dist/codebase-to-spec/interactive.d.ts +30 -0
  20. package/dist/codebase-to-spec/interactive.js +48 -0
  21. package/dist/codebase-to-spec/outline-review-loop.d.ts +51 -0
  22. package/dist/codebase-to-spec/outline-review-loop.js +187 -0
  23. package/dist/codebase-to-spec/pack.d.ts +51 -0
  24. package/dist/codebase-to-spec/pack.js +127 -0
  25. package/dist/codebase-to-spec/planner.d.ts +41 -0
  26. package/dist/codebase-to-spec/planner.js +76 -0
  27. package/dist/codebase-to-spec/present.d.ts +94 -0
  28. package/dist/codebase-to-spec/present.js +288 -0
  29. package/dist/codebase-to-spec/progress.d.ts +33 -0
  30. package/dist/codebase-to-spec/progress.js +28 -0
  31. package/dist/codebase-to-spec/prompts/editor.d.ts +13 -0
  32. package/dist/codebase-to-spec/prompts/editor.js +57 -0
  33. package/dist/codebase-to-spec/prompts/outline-reviewer.d.ts +12 -0
  34. package/dist/codebase-to-spec/prompts/outline-reviewer.js +87 -0
  35. package/dist/codebase-to-spec/prompts/planner-apply.d.ts +12 -0
  36. package/dist/codebase-to-spec/prompts/planner-apply.js +32 -0
  37. package/dist/codebase-to-spec/prompts/planner-initial.d.ts +11 -0
  38. package/dist/codebase-to-spec/prompts/planner-initial.js +125 -0
  39. package/dist/codebase-to-spec/prompts/planner-revise.d.ts +14 -0
  40. package/dist/codebase-to-spec/prompts/planner-revise.js +60 -0
  41. package/dist/codebase-to-spec/prompts/spec-reviewer.d.ts +16 -0
  42. package/dist/codebase-to-spec/prompts/spec-reviewer.js +96 -0
  43. package/dist/codebase-to-spec/prompts/specifier.d.ts +12 -0
  44. package/dist/codebase-to-spec/prompts/specifier.js +100 -0
  45. package/dist/codebase-to-spec/prompts/style-check.d.ts +12 -0
  46. package/dist/codebase-to-spec/prompts/style-check.js +78 -0
  47. package/dist/codebase-to-spec/schemas.d.ts +257 -0
  48. package/dist/codebase-to-spec/schemas.js +183 -0
  49. package/dist/codebase-to-spec/skill-install.d.ts +57 -0
  50. package/dist/codebase-to-spec/skill-install.js +79 -0
  51. package/dist/codebase-to-spec/slice.d.ts +49 -0
  52. package/dist/codebase-to-spec/slice.js +111 -0
  53. package/dist/codebase-to-spec/specifier.d.ts +60 -0
  54. package/dist/codebase-to-spec/specifier.js +79 -0
  55. package/dist/codebase-to-spec/style-check.d.ts +29 -0
  56. package/dist/codebase-to-spec/style-check.js +33 -0
  57. package/dist/codebase-to-spec/summary.d.ts +51 -0
  58. package/dist/codebase-to-spec/summary.js +183 -0
  59. package/dist/codebase-to-spec/validate.d.ts +46 -0
  60. package/dist/codebase-to-spec/validate.js +130 -0
  61. package/dist/commands/acceptance-test.d.ts +6 -0
  62. package/dist/commands/acceptance-test.js +212 -0
  63. package/dist/commands/ai-setup.d.ts +5 -0
  64. package/dist/commands/ai-setup.js +441 -0
  65. package/dist/commands/browsertest.d.ts +0 -1
  66. package/dist/commands/browsertest.js +51 -26
  67. package/dist/commands/codebase-to-spec/compose.d.ts +14 -0
  68. package/dist/commands/codebase-to-spec/compose.js +57 -0
  69. package/dist/commands/codebase-to-spec/edit-loop.d.ts +16 -0
  70. package/dist/commands/codebase-to-spec/edit-loop.js +83 -0
  71. package/dist/commands/codebase-to-spec/fan-out.d.ts +19 -0
  72. package/dist/commands/codebase-to-spec/fan-out.js +77 -0
  73. package/dist/commands/codebase-to-spec/index.d.ts +9 -0
  74. package/dist/commands/codebase-to-spec/index.js +135 -0
  75. package/dist/commands/codebase-to-spec/pack.d.ts +22 -0
  76. package/dist/commands/codebase-to-spec/pack.js +76 -0
  77. package/dist/commands/codebase-to-spec/plan-loop.d.ts +26 -0
  78. package/dist/commands/codebase-to-spec/plan-loop.js +105 -0
  79. package/dist/commands/codebase-to-spec/present.d.ts +21 -0
  80. package/dist/commands/codebase-to-spec/present.js +92 -0
  81. package/dist/commands/codebase-to-spec/run.d.ts +20 -0
  82. package/dist/commands/codebase-to-spec/run.js +85 -0
  83. package/dist/commands/codebase-to-spec/skill-install.d.ts +20 -0
  84. package/dist/commands/codebase-to-spec/skill-install.js +51 -0
  85. package/dist/commands/codebase-to-spec/specify-area.d.ts +18 -0
  86. package/dist/commands/codebase-to-spec/specify-area.js +82 -0
  87. package/dist/commands/codebase-to-spec/style-check.d.ts +15 -0
  88. package/dist/commands/codebase-to-spec/style-check.js +42 -0
  89. package/dist/commands/codebase-to-spec/validate.d.ts +18 -0
  90. package/dist/commands/codebase-to-spec/validate.js +38 -0
  91. package/dist/commands/create-requirement-document.d.ts +2 -0
  92. package/dist/commands/create-requirement-document.js +41 -0
  93. package/dist/commands/finalize.js +7 -7
  94. package/dist/commands/get.d.ts +2 -0
  95. package/dist/commands/get.js +55 -0
  96. package/dist/commands/init.js +132 -117
  97. package/dist/commands/link.js +27 -27
  98. package/dist/commands/list.d.ts +6 -0
  99. package/dist/commands/list.js +43 -0
  100. package/dist/commands/mcp-setup.js +159 -149
  101. package/dist/commands/mcp.js +1 -1
  102. package/dist/commands/prepare.js +4 -4
  103. package/dist/commands/pull.js +116 -121
  104. package/dist/commands/push.js +106 -112
  105. package/dist/commands/report.d.ts +6 -2
  106. package/dist/commands/report.js +177 -122
  107. package/dist/commands/requirements-for.d.ts +2 -0
  108. package/dist/commands/requirements-for.js +29 -0
  109. package/dist/commands/review-test.d.ts +2 -0
  110. package/dist/commands/review-test.js +75 -0
  111. package/dist/commands/search.d.ts +6 -0
  112. package/dist/commands/search.js +39 -0
  113. package/dist/commands/style-check.d.ts +7 -0
  114. package/dist/commands/style-check.js +75 -0
  115. package/dist/commands/test.js +53 -59
  116. package/dist/commands/tests-for.d.ts +2 -0
  117. package/dist/commands/tests-for.js +80 -0
  118. package/dist/commands/validate.d.ts +6 -0
  119. package/dist/commands/validate.js +72 -0
  120. package/dist/config.js +1 -1
  121. package/dist/convex.d.ts +34 -22
  122. package/dist/convex.js +38 -22
  123. package/dist/harness/cache.d.ts +1 -5
  124. package/dist/harness/cache.js +49 -59
  125. package/dist/harness/convexReporting.d.ts +1 -1
  126. package/dist/harness/convexReporting.js +9 -7
  127. package/dist/harness/coverageCache.js +3 -3
  128. package/dist/harness/finalize.js +59 -46
  129. package/dist/harness/index.d.ts +6 -7
  130. package/dist/harness/index.js +9 -10
  131. package/dist/harness/prepare.js +6 -5
  132. package/dist/harness/requirementsLoader.d.ts +2 -2
  133. package/dist/harness/requirementsLoader.js +13 -35
  134. package/dist/harness/tracking.js +18 -18
  135. package/dist/harness/types.d.ts +1 -1
  136. package/dist/mcp/convexClient.d.ts +0 -39
  137. package/dist/mcp/convexClient.js +2 -107
  138. package/dist/mcp/grep.d.ts +1 -1
  139. package/dist/mcp/grep.js +87 -42
  140. package/dist/mcp/handlers/authoring.d.ts +1 -1
  141. package/dist/mcp/handlers/authoring.js +30 -234
  142. package/dist/mcp/handlers/coverage.d.ts +1 -1
  143. package/dist/mcp/handlers/coverage.js +13 -15
  144. package/dist/mcp/handlers/debug.d.ts +2 -3
  145. package/dist/mcp/handlers/debug.js +10 -10
  146. package/dist/mcp/handlers/get.d.ts +1 -1
  147. package/dist/mcp/handlers/get.js +11 -10
  148. package/dist/mcp/handlers/index.d.ts +20 -20
  149. package/dist/mcp/handlers/index.js +10 -10
  150. package/dist/mcp/handlers/list.d.ts +4 -33
  151. package/dist/mcp/handlers/list.js +16 -38
  152. package/dist/mcp/handlers/push.d.ts +1 -1
  153. package/dist/mcp/handlers/push.js +28 -18
  154. package/dist/mcp/handlers/report.d.ts +16 -0
  155. package/dist/mcp/handlers/report.js +134 -0
  156. package/dist/mcp/handlers/review.d.ts +1 -1
  157. package/dist/mcp/handlers/review.js +40 -59
  158. package/dist/mcp/handlers/search.d.ts +1 -1
  159. package/dist/mcp/handlers/search.js +7 -9
  160. package/dist/mcp/handlers/test-mapping.d.ts +1 -1
  161. package/dist/mcp/handlers/test-mapping.js +14 -14
  162. package/dist/mcp/handlers/types.d.ts +3 -3
  163. package/dist/mcp/handlers/types.js +2 -2
  164. package/dist/mcp/index.d.ts +1 -1
  165. package/dist/mcp/index.js +156 -178
  166. package/dist/mcp/requirements.d.ts +2 -2
  167. package/dist/mcp/requirements.js +30 -30
  168. package/dist/mcp/testCodeExtractor.js +24 -26
  169. package/dist/mcp/types.d.ts +1 -1
  170. package/dist/push/core.d.ts +2 -2
  171. package/dist/push/core.js +20 -20
  172. package/dist/push/index.d.ts +1 -1
  173. package/dist/push/index.js +2 -2
  174. package/dist/requirements/cloud-ai.d.ts +57 -0
  175. package/dist/requirements/cloud-ai.js +104 -0
  176. package/dist/requirements/cloud-coverage.d.ts +41 -0
  177. package/dist/requirements/cloud-coverage.js +60 -0
  178. package/dist/requirements/coverage.d.ts +45 -0
  179. package/dist/requirements/coverage.js +114 -0
  180. package/dist/requirements/grep.d.ts +33 -0
  181. package/dist/requirements/grep.js +306 -0
  182. package/dist/requirements/index.d.ts +73 -0
  183. package/dist/requirements/index.js +174 -0
  184. package/dist/requirements/style-guide.d.ts +67 -0
  185. package/dist/requirements/style-guide.js +299 -0
  186. package/dist/requirements/testCodeExtractor.d.ts +22 -0
  187. package/dist/requirements/testCodeExtractor.js +150 -0
  188. package/dist/schema/browser.d.ts +8 -6
  189. package/dist/schema/browser.js +14 -14
  190. package/dist/schema/builder.d.ts +1 -1
  191. package/dist/schema/builder.js +13 -44
  192. package/dist/schema/conversions.d.ts +2 -2
  193. package/dist/schema/conversions.js +11 -11
  194. package/dist/schema/index.d.ts +9 -7
  195. package/dist/schema/index.js +15 -13
  196. package/dist/schema/parser-core.d.ts +1 -1
  197. package/dist/schema/parser-core.js +23 -22
  198. package/dist/schema/parser.d.ts +3 -3
  199. package/dist/schema/parser.js +27 -31
  200. package/dist/schema/resolver.d.ts +1 -1
  201. package/dist/schema/resolver.js +9 -9
  202. package/dist/schema/scenario.d.ts +91 -0
  203. package/dist/schema/scenario.js +82 -0
  204. package/dist/schema/schemas.d.ts +3 -3
  205. package/dist/schema/schemas.js +41 -28
  206. package/dist/schema/test-schema.js +27 -27
  207. package/dist/templates/context-file-section.md +3 -2
  208. package/dist/templates/example-requirements.js +1 -1
  209. package/dist/templates/example-requirements.ts +3 -1
  210. package/dist/templates/requirements-readme.js +1 -1
  211. package/dist/templates/requirements-readme.ts +1 -1
  212. package/dist/templates/skills/codebase-to-spec/SKILL.md +118 -0
  213. package/dist/utils/brand.js +3 -3
  214. package/dist/utils/browser-launch.js +4 -4
  215. package/dist/utils/context-file.d.ts +1 -1
  216. package/dist/utils/context-file.js +26 -26
  217. package/dist/utils/env.js +7 -7
  218. package/dist/utils/gitignore.js +7 -7
  219. package/dist/utils/oauth-callback-server.d.ts +1 -1
  220. package/dist/utils/oauth-callback-server.js +27 -25
  221. package/dist/utils/oauth-flow.js +32 -29
  222. package/dist/utils/project-discovery.d.ts +3 -3
  223. package/dist/utils/project-discovery.js +18 -17
  224. package/dist/utils/project-name.js +8 -8
  225. package/dist/utils/project-selector.d.ts +1 -1
  226. package/dist/utils/project-selector.js +24 -21
  227. package/dist/utils/project-settings.d.ts +5 -4
  228. package/dist/utils/project-settings.js +28 -20
  229. package/dist/utils/templates.js +6 -6
  230. package/package.json +2 -1
package/README.md CHANGED
@@ -155,23 +155,66 @@ dotreq push .requirements/auth.requirements.md
155
155
  dotreq push --yes # Skip confirmation
156
156
  ```
157
157
 
158
- ### `dotreq test`
158
+ ### `dotreq validate`
159
159
 
160
160
  Validate requirements files against the schema.
161
161
 
162
162
  ```bash
163
- dotreq test
164
- dotreq test --file .requirements/auth.requirements.md
163
+ dotreq validate
164
+ dotreq validate --file .requirements/auth.requirements.md
165
165
  ```
166
166
 
167
- ### `dotreq browsertest`
167
+ ### `dotreq search`
168
+
169
+ Search requirements by text or regex across every `.requirements.md` file. Searches IDs, content, and labels.
170
+
171
+ ```bash
172
+ dotreq search "login"
173
+ dotreq search "AUTH-.*" --regex
174
+ ```
175
+
176
+ ### `dotreq get`
177
+
178
+ Print a requirement (or subtree) by ID, with test references and source locations. Accepts both numeric paths (`AUTH-LOGIN-1.0.1`) and label paths (`AUTH-LOGIN-1.given.and`).
179
+
180
+ ```bash
181
+ dotreq get AUTH-LOGIN-1
182
+ dotreq get AUTH-LOGIN-1.0
183
+ ```
184
+
185
+ ### `dotreq list`
186
+
187
+ Summarize requirements in the project. Without flags, lists every root with its child count. With `--untested`, filters to roots with no `requirement()` references in any test.
188
+
189
+ ```bash
190
+ dotreq list
191
+ dotreq list --untested
192
+ ```
193
+
194
+ ### `dotreq requirements-for`
195
+
196
+ Show which requirements a test file references, with the line where each `requirement()` call lives.
197
+
198
+ ```bash
199
+ dotreq requirements-for src/auth.test.ts
200
+ ```
201
+
202
+ ### `dotreq tests-for`
203
+
204
+ Show which tests reference each requirement in a `.requirements.md` file. The inverse of `requirements-for`.
205
+
206
+ ```bash
207
+ dotreq tests-for .requirements/auth.requirements.md
208
+ ```
209
+
210
+ ### `dotreq acceptance-test`
168
211
 
169
212
  Run browser-based acceptance tests against requirements. Uses AI-powered browser automation to verify that your application behaves as specified.
170
213
 
171
214
  ```bash
172
- dotreq browsertest LOGIN-1
173
- dotreq browsertest LOGIN-1 https://example.com
174
- dotreq browsertest LOGIN-1 --json
215
+ dotreq acceptance-test LOGIN-1
216
+ dotreq acceptance-test LOGIN-1 https://example.com
217
+ dotreq acceptance-test LOGIN-1 --json
175
218
  ```
176
219
 
177
220
  **Options:**
@@ -182,35 +225,140 @@ dotreq browsertest LOGIN-1 --json
182
225
 
183
226
  **Configuration required:**
184
227
 
185
- Browser testing requires credentials in `project-settings.json`:
228
+ Browser testing needs a Stagehand model and the API key for that model's provider in `project-settings.json`:
186
229
 
187
230
  ```json
188
231
  {
189
232
  "defaultURL": "https://your-app.com",
190
233
  "browserTest": {
191
- "geminiApiKey": "your-gemini-api-key"
234
+ "modelName": "gateway/anthropic/claude-haiku-4-5",
235
+ "modelApiKey": "your-api-key"
192
236
  }
193
237
  }
194
238
  ```
195
239
 
196
- Optional settings: `vercelBypassSecret`, `browserbaseApiKey`, `browserbaseProjectId`.
240
+ Pick any Stagehand-supported model. Example values: `gateway/anthropic/claude-haiku-4-5` (Vercel AI Gateway key), `google/gemini-3-flash-preview` (Gemini key).
197
241
 
198
- ### `dotreq mcp-setup`
242
+ Optional settings: `vercelBypassSecret`, `browserbaseApiKey`, `browserbaseProjectId`. Setting both Browserbase fields switches runs from LOCAL (spawns Playwright on your machine) to BROWSERBASE (managed cloud browsers).
243
+
244
+ ### `dotreq cts` *(Alpha)*
245
+
246
+ Generate behavioral requirements from an existing codebase. Packs the codebase, plans a behavioral outline, fans out per-area specifier agents to draft per-area requirements, runs a dual review loop, and writes the result to `.requirements/`.
247
+
248
+ ```bash
249
+ dotreq cts run --scope src # full pipeline end-to-end
250
+ dotreq cts run --scope src --fresh # discard cache and start over
251
+ dotreq cts skill-install # install the conversational skill wrapper
252
+ ```
253
+
254
+ `cts` shells out to `claude -p` and uses whatever auth mode you've configured for Claude Code. Each pipeline stage is also runnable on its own (`dotreq cts pack`, `plan-loop`, `fan-out`, `compose`, `edit-loop`, `present`) for partial re-runs and debugging.
255
+
256
+ > **Alpha:** output quality is prompt-sensitive and varies by codebase. See the [Codebase to Spec docs](https://dotrequirements.io/tools/cli/codebase-to-spec) for prerequisites, options, exit codes, and known rough edges. Feedback to support@popover.ca welcome.
257
+
258
+ > **Heads up:** as of June 15, 2026, `claude -p` bills against your Claude subscription's API credit instead of the subscription seat (per Anthropic's May 13, 2026 announcement). `cts` runs will draw from that credit.
259
+
260
+ ### `dotreq ai-setup`
199
261
 
200
262
  Configure the MCP server for AI assistants (Claude Code, Cursor, etc.).
201
263
 
202
264
  ```bash
203
- dotreq mcp-setup
265
+ dotreq ai-setup
204
266
  ```
205
267
 
206
268
  ### `dotreq mcp`
207
269
 
208
- Start the MCP server manually (typically not needed—AI assistants start it automatically after `mcp-setup`).
270
+ Start the MCP server manually (typically not needed—AI assistants start it automatically after `ai-setup`).
209
271
 
210
272
  ```bash
211
273
  dotreq mcp
212
274
  ```
213
275
 
276
+ ### `dotreq harness prepare`
277
+
278
+ 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.
279
+
280
+ ```bash
281
+ dotreq harness prepare
282
+ dotreq harness prepare --quiet
283
+ ```
284
+
285
+ ### `dotreq harness finalize`
286
+
287
+ Aggregate test tracking data and print a coverage report. Run after tests in non-JavaScript projects.
288
+
289
+ ```bash
290
+ dotreq harness finalize
291
+ dotreq harness finalize --push
292
+ dotreq harness finalize --push --context pytest
293
+ ```
294
+
295
+ | Option | Description |
296
+ |--------|-------------|
297
+ | `--push` | Push coverage to dot•requirements cloud |
298
+ | `--quiet` | Output only coverage percentage (for scripting) |
299
+ | `--context <label>` | Attribution label identifying the reporter (e.g. `pytest`, `Jest`) |
300
+
301
+ ### `dotreq report`
302
+
303
+ View coverage from the most recent local test run, or from the cloud-persisted record.
304
+
305
+ ```bash
306
+ dotreq report # local cache (default)
307
+ dotreq report --source cloud # cloud-persisted record
308
+ dotreq report --source cloud --branch main # filter to a branch
309
+ dotreq report --source cloud --since 1700000000000 # filter to records after a timestamp
310
+ dotreq report --requirement AUTH-LOGIN # scope to one requirement
311
+ dotreq report --format json
312
+ ```
313
+
314
+ | Option | Description |
315
+ |--------|-------------|
316
+ | `--source <source>` | Where to read coverage from: `local` (default) or `cloud` |
317
+ | `--format <format>` | Output format: `console` (default), `json`, `markdown` |
318
+ | `--requirement <id>` | Filter to a specific requirement (and its children for local source) |
319
+ | `--branch <name>` | Cloud-only: filter coverage to a specific git branch |
320
+ | `--since <timestamp>` | Cloud-only: only show coverage recorded after this Unix-ms timestamp |
321
+
322
+ `--branch` and `--since` only apply with `--source cloud`; using them with the local source errors out. Cloud queries require running `dotreq link` first.
323
+
324
+ ### `dotreq style-check`
325
+
326
+ Get AI feedback on a requirements file or a test file. Works on both `*.requirements.md` files (catches vagueness, missing preconditions, untestable assertions) and test files (checks semantic alignment with referenced requirements).
327
+
328
+ ```bash
329
+ dotreq style-check .requirements/auth.requirements.md
330
+ dotreq style-check src/auth.test.ts
331
+ dotreq style-check .requirements/auth.requirements.md --keys AUTH-LOGIN-1,AUTH-LOGIN-2
332
+ ```
333
+
334
+ | Option | Description |
335
+ |--------|-------------|
336
+ | `--keys <list>` | Comma-separated requirement keys to limit the review (requirements files only) |
337
+ | `--model <name>` | Override the AI model used for the review |
338
+
339
+ 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.
340
+
341
+ ### `dotreq review-test`
342
+
343
+ AI-powered semantic review of a test file against its referenced requirements. Validates that test setup matches GIVEN conditions, actions match WHEN triggers, and assertions match THEN outcomes.
344
+
345
+ ```bash
346
+ dotreq review-test src/auth.test.ts
347
+ ```
348
+
349
+ 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.
350
+
351
+ ### `dotreq create-requirement-document`
352
+
353
+ 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.
354
+
355
+ ```bash
356
+ dotreq create-requirement-document
357
+ dotreq create-requirement-document .requirements/auth.requirements.md
358
+ ```
359
+
360
+ When 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.
361
+
214
362
  ---
215
363
 
216
364
  ## What Works Locally
@@ -218,16 +366,18 @@ dotreq mcp
218
366
  The following features work fully offline—no account required:
219
367
 
220
368
  - Write requirements (`.requirements.md` files)
221
- - Validate requirements (`dotreq test`)
369
+ - Validate requirements (`dotreq validate`)
370
+ - Search and explore (`dotreq search`, `get`, `list`, `requirements-for`, `tests-for`)
222
371
  - Reference requirements in tests (`requirement()`)
223
- - Coverage reporting (console output)
224
- - MCP tools (search, validate, explore)
372
+ - Local coverage reporting (`dotreq report`, default `--source local`)
373
+ - Generate a requirements template (`dotreq create-requirement-document`)
374
+ - MCP tools that mirror the offline CLI verbs
225
375
 
226
376
  The following features require a dot•requirements cloud account:
227
377
 
228
378
  - Sync requirements (`pull` / `push`)
229
- - Historical coverage tracking
230
- - AI-powered style checking
379
+ - Cloud coverage queries (`dotreq report --source cloud`)
380
+ - AI-powered style checking and test review (`dotreq style-check`, `dotreq review-test`)
231
381
  - Team collaboration
232
382
 
233
383
  To enable cloud features, run `dotreq link` to connect your project to the cloud.
@@ -471,7 +621,7 @@ AI assistants can read your requirements in context, draft new ones, and verify
471
621
  ### Setup
472
622
 
473
623
  ```bash
474
- dotreq mcp-setup
624
+ dotreq ai-setup
475
625
  ```
476
626
 
477
627
  Follow the prompts to configure for your AI assistant (Claude Code, Cursor, etc.).
@@ -481,8 +631,7 @@ Follow the prompts to configure for your AI assistant (Claude Code, Cursor, etc.
481
631
  **Exploration:**
482
632
  - `search_requirements` — Search by text or regex
483
633
  - `get_requirement` — Get a requirement with its children and coverage
484
- - `list_all_requirements` — List all requirements in the project
485
- - `list_untested_requirements` — Find requirements without test coverage
634
+ - `list_requirements` — List all requirements in the project (set `untested: true` to filter to coverage gaps)
486
635
  - `get_requirements_by_test` — Get requirements referenced by a test file
487
636
  - `get_tests_by_requirement` — Get tests that reference a requirement
488
637
 
@@ -492,10 +641,11 @@ Follow the prompts to configure for your AI assistant (Claude Code, Cursor, etc.
492
641
  - `style_check` — AI-powered style feedback on requirements (supports optional `requirementKeys` filter)
493
642
  - `review_test` — Comprehensive test review (style + semantic correctness)
494
643
 
644
+ **Coverage:**
645
+ - `report_coverage` — Coverage from local cache or cloud, with optional requirement / branch / since filters
646
+
495
647
  **Cloud:**
496
648
  - `push_requirements` — Push to dot•requirements cloud
497
- - `get_requirement_coverage` — Query coverage data
498
- - `get_project_coverage_summary` — Project-wide coverage stats
499
649
 
500
650
  **Diagnostic:**
501
651
  - `debug_mcp_environment` — Debug MCP server configuration
package/dist/cli.js CHANGED
@@ -1,24 +1,33 @@
1
1
  #!/usr/bin/env node
2
- import { Command } from 'commander';
3
- import { initCommand } from './commands/init.js';
4
- import { linkCommand } from './commands/link.js';
5
- import { pullCommand } from './commands/pull.js';
6
- import { pushCommand } from './commands/push.js';
7
- import { testCommand } from './commands/test.js';
8
- import { browserTestCommand } from './commands/browsertest.js';
9
- import { prepareCommand } from './commands/prepare.js';
10
- import { finalizeCommand } from './commands/finalize.js';
11
- import { reportCommand } from './commands/report.js';
12
- import { mcpCommand } from './commands/mcp.js';
13
- import { mcpSetupCommand } from './commands/mcp-setup.js';
14
- import { loadEnvFile } from './utils/env.js';
15
- import { readFileSync } from 'fs';
16
- import { fileURLToPath } from 'url';
17
- import { dirname, join } from 'path';
2
+ import { readFileSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { Command } from "commander";
6
+ import { acceptanceTestCommand } from "./commands/acceptance-test.js";
7
+ import { aiSetupCommand } from "./commands/ai-setup.js";
8
+ import { registerCodebaseToSpec } from "./commands/codebase-to-spec/index.js";
9
+ import { createRequirementDocumentCommand } from "./commands/create-requirement-document.js";
10
+ import { finalizeCommand } from "./commands/finalize.js";
11
+ import { getCommand } from "./commands/get.js";
12
+ import { initCommand } from "./commands/init.js";
13
+ import { linkCommand } from "./commands/link.js";
14
+ import { listCommand } from "./commands/list.js";
15
+ import { mcpCommand } from "./commands/mcp.js";
16
+ import { prepareCommand } from "./commands/prepare.js";
17
+ import { pullCommand } from "./commands/pull.js";
18
+ import { pushCommand } from "./commands/push.js";
19
+ import { reportCommand } from "./commands/report.js";
20
+ import { requirementsForCommand } from "./commands/requirements-for.js";
21
+ import { reviewTestCommand } from "./commands/review-test.js";
22
+ import { searchCommand } from "./commands/search.js";
23
+ import { styleCheckCommand } from "./commands/style-check.js";
24
+ import { testsForCommand } from "./commands/tests-for.js";
25
+ import { validateCommand } from "./commands/validate.js";
26
+ import { loadEnvFile } from "./utils/env.js";
18
27
  // Read version from package.json
19
28
  const __filename = fileURLToPath(import.meta.url);
20
29
  const __dirname = dirname(__filename);
21
- const packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));
30
+ const packageJson = JSON.parse(readFileSync(join(__dirname, "../package.json"), "utf-8"));
22
31
  const VERSION = packageJson.version;
23
32
  // Load environment variables from .env.local if it exists
24
33
  loadEnvFile();
@@ -44,67 +53,118 @@ function wrapCommand(fn) {
44
53
  }
45
54
  const program = new Command();
46
55
  program
47
- .name('dotrequirements')
48
- .description('Requirements tracking CLI with test harness and MCP server')
56
+ .name("dotrequirements")
57
+ .description("Requirements tracking CLI with test harness and MCP server")
49
58
  .version(VERSION);
50
59
  program
51
- .command('init')
52
- .description('Initialize a new dotrequirements project')
53
- .option('-n, --name <name>', 'Project name (defaults to package.json name or directory name)')
54
- .option('-i, --invite <token>', 'Join a team using an invite token')
60
+ .command("init")
61
+ .description("Initialize a new dotrequirements project")
62
+ .option("-n, --name <name>", "Project name (defaults to package.json name or directory name)")
63
+ .option("-i, --invite <token>", "Join a team using an invite token")
55
64
  .action(wrapCommand(initCommand));
56
65
  program
57
- .command('link')
58
- .description('Link local environment to an existing project')
66
+ .command("link")
67
+ .description("Link local environment to an existing project")
59
68
  .action(wrapCommand(linkCommand));
60
69
  program
61
- .command('pull')
62
- .description('Sync requirements from cloud to local .requirements/ files')
63
- .option('-p, --project <id>', 'Project ID to sync')
64
- .option('-d, --document <id>', 'Specific document ID to sync')
65
- .option('-s, --share <token>', 'Read-only share token for quick onboarding (no setup required)')
70
+ .command("pull")
71
+ .description("Sync requirements from cloud to local .requirements/ files")
72
+ .option("-p, --project <id>", "Project ID to sync")
73
+ .option("-d, --document <id>", "Specific document ID to sync")
74
+ .option("-s, --share <token>", "Read-only share token for quick onboarding (no setup required)")
66
75
  .action(wrapCommand(pullCommand));
67
76
  program
68
- .command('push [file]')
69
- .description('Push local requirements from .requirements/ to cloud')
70
- .option('-y, --yes', 'Skip confirmation prompt')
77
+ .command("push [file]")
78
+ .description("Push local requirements from .requirements/ to cloud")
79
+ .option("-y, --yes", "Skip confirmation prompt")
71
80
  .action(wrapCommand(pushCommand));
72
81
  program
73
- .command('test')
74
- .description('Validate requirements files in .requirements/')
75
- .option('-f, --file <path>', 'Specific file to validate')
76
- .action(wrapCommand(testCommand));
82
+ .command("validate")
83
+ .description("Validate requirements files in .requirements/")
84
+ .option("-f, --file <path>", "Specific file to validate")
85
+ .action(wrapCommand(validateCommand));
77
86
  program
78
- .command('browsertest <requirement-key> [url]')
79
- .description('Run browser-based acceptance test for a requirement')
80
- .option('--json', 'Output results as JSON')
81
- .option('--useAgent', 'Encourage Claude to use the Agent tool for multi-step tasks')
82
- .action(wrapCommand(browserTestCommand));
83
- program
84
- .command('prepare')
85
- .description('Parse requirements and build lookup cache for multi-language test tracking')
86
- .option('-q, --quiet', 'Suppress output (for scripting)')
87
+ .command("acceptance-test <requirement-key> [url]")
88
+ .description("Run browser-based acceptance test for a requirement")
89
+ .option("--json", "Output results as JSON")
90
+ .action(wrapCommand(acceptanceTestCommand));
91
+ const harness = program
92
+ .command("harness")
93
+ .description("Test-harness lifecycle commands (prepare, finalize)");
94
+ harness
95
+ .command("prepare")
96
+ .description("Parse requirements and build lookup cache for multi-language test tracking")
97
+ .option("-q, --quiet", "Suppress output (for scripting)")
87
98
  .action(wrapCommand(prepareCommand));
88
- program
89
- .command('finalize')
90
- .description('Aggregate test tracking data and generate coverage report')
91
- .option('--push', 'Push coverage to DotRequirements Cloud')
92
- .option('-q, --quiet', 'Output only coverage percentage (for scripting)')
93
- .option('--context <label>', 'Attribution label identifying the reporter (e.g. "Vitest", "pytest")')
99
+ harness
100
+ .command("finalize")
101
+ .description("Aggregate test tracking data and generate coverage report")
102
+ .option("--push", "Push coverage to DotRequirements Cloud")
103
+ .option("-q, --quiet", "Output only coverage percentage (for scripting)")
104
+ .option("--context <label>", 'Attribution label identifying the reporter (e.g. "Vitest", "pytest")')
94
105
  .action(wrapCommand(finalizeCommand));
95
106
  program
96
- .command('report')
97
- .description('Display coverage report from most recent test run')
98
- .option('-f, --format <format>', 'Output format: console, json, markdown', 'console')
99
- .option('-r, --requirement <id>', 'Filter to specific requirement and its children')
107
+ .command("report")
108
+ .description("Display coverage. Defaults to local (most recent test run on this machine); use --source cloud for the persisted record.")
109
+ .option("--source <source>", "Where to read coverage from: local | cloud", "local")
110
+ .option("-f, --format <format>", "Output format: console, json, markdown", "console")
111
+ .option("-r, --requirement <id>", "Filter to a specific requirement (and its children for local source)")
112
+ .option("--branch <name>", "Cloud-only: filter coverage to a specific git branch")
113
+ .option("--since <timestamp>", "Cloud-only: only show coverage recorded after this Unix-ms timestamp", (v) => {
114
+ const n = Number(v);
115
+ if (!Number.isFinite(n)) {
116
+ throw new Error(`--since must be a numeric Unix-ms timestamp (got "${v}")`);
117
+ }
118
+ return n;
119
+ })
100
120
  .action(wrapCommand(reportCommand));
101
121
  program
102
- .command('mcp')
103
- .description('Start the MCP (Model Context Protocol) server for AI assistant integration')
122
+ .command("mcp")
123
+ .description("Start the MCP (Model Context Protocol) server for AI assistant integration")
104
124
  .action(wrapCommand(mcpCommand));
105
125
  program
106
- .command('mcp-setup')
107
- .description('Configure MCP server for your AI assistant (Claude Code, Claude Desktop, etc.)')
108
- .action(wrapCommand(mcpSetupCommand));
126
+ .command("ai-setup")
127
+ .description("Configure MCP server for your AI assistant (Claude Code, Claude Desktop, etc.)")
128
+ .action(wrapCommand(aiSetupCommand));
129
+ program
130
+ .command("search <query>")
131
+ .description("Search requirements by text or regex query")
132
+ .option("--regex", "Interpret query as a case-insensitive regular expression")
133
+ .action(wrapCommand(searchCommand));
134
+ program
135
+ .command("get <id>")
136
+ .description("Print a requirement (or subtree) by ID, with test references and code")
137
+ .action(wrapCommand(getCommand));
138
+ program
139
+ .command("list")
140
+ .description("Summarize every root requirement in the workspace")
141
+ .option("--untested", "Only show requirements with no requirement() references")
142
+ .action(wrapCommand(listCommand));
143
+ program
144
+ .command("requirements-for <test-file>")
145
+ .description("Show every requirement() reference in a test file")
146
+ .action(wrapCommand(requirementsForCommand));
147
+ program
148
+ .command("tests-for <requirements-file>")
149
+ .description("Show which requirements in a *.requirements.md file have test coverage")
150
+ .action(wrapCommand(testsForCommand));
151
+ program
152
+ .command("style-check <file>")
153
+ .description("AI style review of a requirements or test file (requires cloud auth)")
154
+ .option("--keys <keys>", "Comma-separated requirement keys to limit the review (requirements files only)", (value) => value
155
+ .split(",")
156
+ .map((k) => k.trim())
157
+ .filter(Boolean))
158
+ .option("--model <name>", "Override the AI model used for the review")
159
+ .action(wrapCommand(styleCheckCommand));
160
+ program
161
+ .command("review-test <test-file>")
162
+ .description("AI semantic review of a test file against its referenced requirements (requires cloud auth)")
163
+ .action(wrapCommand(reviewTestCommand));
164
+ program
165
+ .command("create-requirement-document [file-path]")
166
+ .description("Print the project style guide; optional [file-path] annotates the output for that target")
167
+ .action(wrapCommand(createRequirementDocumentCommand));
168
+ registerCodebaseToSpec(program);
109
169
  program.parse();
110
170
  //# sourceMappingURL=cli.js.map
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Working-context budget check for codebase-to-spec.
3
+ *
4
+ * After packing, we measure the compressed pack's token count. If it exceeds
5
+ * the working-context budget (the practical context-window ceiling for the
6
+ * planner and reviewer agents), the pipeline exits before any LLM-using stage
7
+ * runs.
8
+ *
9
+ * Requirements covered:
10
+ * - CTS-CLI-3: Pipeline refuses to spec a codebase that exceeds the working context budget
11
+ */
12
+ /**
13
+ * Default budget in tokens for the compressed pack.
14
+ *
15
+ * Sized to leave generous headroom in a 1M-token context window for the
16
+ * planner's outline output, the reviewer's critique, and conversation overhead
17
+ * across review turns.
18
+ */
19
+ export declare const DEFAULT_BUDGET_TOKENS = 600000;
20
+ /**
21
+ * Estimate token count from a file size in bytes.
22
+ *
23
+ * We use a conservative estimate of 3.5 chars/token (typical for source code
24
+ * with some markdown overhead). This is deliberately approximate — the goal
25
+ * is to refuse the codebase BEFORE we pay the cost of an LLM-tokenizing pass.
26
+ * For exact counts, use `countTokens` on the file content.
27
+ */
28
+ export declare function estimateTokensFromBytes(bytes: number): number;
29
+ /**
30
+ * Count tokens in a file using the same conservative estimate.
31
+ * If the file does not exist, returns 0.
32
+ */
33
+ export declare function countTokensInFile(path: string): number;
34
+ /**
35
+ * Read the file (UTF-8) and count tokens from its actual character length.
36
+ * More accurate than the size-based estimate for non-ASCII content.
37
+ */
38
+ export declare function countTokensInFileExact(path: string): number;
39
+ export interface BudgetCheckResult {
40
+ withinBudget: boolean;
41
+ measuredTokens: number;
42
+ budgetTokens: number;
43
+ }
44
+ export declare function checkBudget(measuredTokens: number, budgetTokens?: number): BudgetCheckResult;
45
+ /**
46
+ * Format the budget-exceeded message for the user.
47
+ *
48
+ * Per CTS-CLI-3.2 (and its sub-criteria): the message states the codebase is
49
+ * too large for a single agent's context window, includes the measured token
50
+ * count and the configured budget, and suggests narrowing the scope path.
51
+ */
52
+ export declare function formatBudgetExceededMessage(result: BudgetCheckResult): string;
53
+ //# sourceMappingURL=budget.d.ts.map
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Working-context budget check for codebase-to-spec.
3
+ *
4
+ * After packing, we measure the compressed pack's token count. If it exceeds
5
+ * the working-context budget (the practical context-window ceiling for the
6
+ * planner and reviewer agents), the pipeline exits before any LLM-using stage
7
+ * runs.
8
+ *
9
+ * Requirements covered:
10
+ * - CTS-CLI-3: Pipeline refuses to spec a codebase that exceeds the working context budget
11
+ */
12
+ import { readFileSync, statSync } from "node:fs";
13
+ /**
14
+ * Default budget in tokens for the compressed pack.
15
+ *
16
+ * Sized to leave generous headroom in a 1M-token context window for the
17
+ * planner's outline output, the reviewer's critique, and conversation overhead
18
+ * across review turns.
19
+ */
20
+ export const DEFAULT_BUDGET_TOKENS = 600_000;
21
+ /**
22
+ * Estimate token count from a file size in bytes.
23
+ *
24
+ * We use a conservative estimate of 3.5 chars/token (typical for source code
25
+ * with some markdown overhead). This is deliberately approximate — the goal
26
+ * is to refuse the codebase BEFORE we pay the cost of an LLM-tokenizing pass.
27
+ * For exact counts, use `countTokens` on the file content.
28
+ */
29
+ export function estimateTokensFromBytes(bytes) {
30
+ // 3.5 chars per token, 1 byte per char for ASCII-leaning code
31
+ return Math.ceil(bytes / 3.5);
32
+ }
33
+ /**
34
+ * Count tokens in a file using the same conservative estimate.
35
+ * If the file does not exist, returns 0.
36
+ */
37
+ export function countTokensInFile(path) {
38
+ try {
39
+ const size = statSync(path).size;
40
+ return estimateTokensFromBytes(size);
41
+ }
42
+ catch {
43
+ return 0;
44
+ }
45
+ }
46
+ /**
47
+ * Read the file (UTF-8) and count tokens from its actual character length.
48
+ * More accurate than the size-based estimate for non-ASCII content.
49
+ */
50
+ export function countTokensInFileExact(path) {
51
+ const content = readFileSync(path, "utf-8");
52
+ return Math.ceil(content.length / 3.5);
53
+ }
54
+ export function checkBudget(measuredTokens, budgetTokens = DEFAULT_BUDGET_TOKENS) {
55
+ return {
56
+ withinBudget: measuredTokens <= budgetTokens,
57
+ measuredTokens,
58
+ budgetTokens,
59
+ };
60
+ }
61
+ /**
62
+ * Format the budget-exceeded message for the user.
63
+ *
64
+ * Per CTS-CLI-3.2 (and its sub-criteria): the message states the codebase is
65
+ * too large for a single agent's context window, includes the measured token
66
+ * count and the configured budget, and suggests narrowing the scope path.
67
+ */
68
+ export function formatBudgetExceededMessage(result) {
69
+ const measured = result.measuredTokens.toLocaleString();
70
+ const budget = result.budgetTokens.toLocaleString();
71
+ return [
72
+ `Your codebase is too large for a single agent's context window.`,
73
+ ``,
74
+ ` Compressed pack: ${measured} tokens`,
75
+ ` Working budget: ${budget} tokens`,
76
+ ``,
77
+ `Try narrowing the scope with --scope <path> to focus on a specific package, module, or directory.`,
78
+ ].join("\n");
79
+ }
80
+ //# sourceMappingURL=budget.js.map