@popoverai/dotrequirements 0.23.0 → 0.24.1

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 (235) hide show
  1. package/README.md +169 -22
  2. package/dist/cli.js +121 -60
  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-initial.d.ts +11 -0
  36. package/dist/codebase-to-spec/prompts/planner-initial.js +125 -0
  37. package/dist/codebase-to-spec/prompts/planner-revise.d.ts +14 -0
  38. package/dist/codebase-to-spec/prompts/planner-revise.js +60 -0
  39. package/dist/codebase-to-spec/prompts/spec-reviewer.d.ts +16 -0
  40. package/dist/codebase-to-spec/prompts/spec-reviewer.js +96 -0
  41. package/dist/codebase-to-spec/prompts/specifier.d.ts +12 -0
  42. package/dist/codebase-to-spec/prompts/specifier.js +100 -0
  43. package/dist/codebase-to-spec/prompts/style-check.d.ts +12 -0
  44. package/dist/codebase-to-spec/prompts/style-check.js +78 -0
  45. package/dist/codebase-to-spec/schemas.d.ts +257 -0
  46. package/dist/codebase-to-spec/schemas.js +183 -0
  47. package/dist/codebase-to-spec/skill-install.d.ts +57 -0
  48. package/dist/codebase-to-spec/skill-install.js +79 -0
  49. package/dist/codebase-to-spec/slice.d.ts +49 -0
  50. package/dist/codebase-to-spec/slice.js +111 -0
  51. package/dist/codebase-to-spec/specifier.d.ts +60 -0
  52. package/dist/codebase-to-spec/specifier.js +79 -0
  53. package/dist/codebase-to-spec/style-check.d.ts +29 -0
  54. package/dist/codebase-to-spec/style-check.js +33 -0
  55. package/dist/codebase-to-spec/summary.d.ts +51 -0
  56. package/dist/codebase-to-spec/summary.js +183 -0
  57. package/dist/codebase-to-spec/validate.d.ts +46 -0
  58. package/dist/codebase-to-spec/validate.js +130 -0
  59. package/dist/commands/acceptance-test.d.ts +6 -0
  60. package/dist/commands/{browsertest.js → acceptance-test.js} +36 -29
  61. package/dist/commands/ai-setup.d.ts +5 -0
  62. package/dist/commands/ai-setup.js +441 -0
  63. package/dist/commands/codebase-to-spec/compose.d.ts +14 -0
  64. package/dist/commands/codebase-to-spec/compose.js +57 -0
  65. package/dist/commands/codebase-to-spec/edit-loop.d.ts +16 -0
  66. package/dist/commands/codebase-to-spec/edit-loop.js +83 -0
  67. package/dist/commands/codebase-to-spec/fan-out.d.ts +19 -0
  68. package/dist/commands/codebase-to-spec/fan-out.js +77 -0
  69. package/dist/commands/codebase-to-spec/index.d.ts +9 -0
  70. package/dist/commands/codebase-to-spec/index.js +135 -0
  71. package/dist/commands/codebase-to-spec/pack.d.ts +22 -0
  72. package/dist/commands/codebase-to-spec/pack.js +76 -0
  73. package/dist/commands/codebase-to-spec/plan-loop.d.ts +26 -0
  74. package/dist/commands/codebase-to-spec/plan-loop.js +105 -0
  75. package/dist/commands/codebase-to-spec/present.d.ts +21 -0
  76. package/dist/commands/codebase-to-spec/present.js +92 -0
  77. package/dist/commands/codebase-to-spec/run.d.ts +20 -0
  78. package/dist/commands/codebase-to-spec/run.js +85 -0
  79. package/dist/commands/codebase-to-spec/skill-install.d.ts +20 -0
  80. package/dist/commands/codebase-to-spec/skill-install.js +51 -0
  81. package/dist/commands/codebase-to-spec/specify-area.d.ts +18 -0
  82. package/dist/commands/codebase-to-spec/specify-area.js +82 -0
  83. package/dist/commands/codebase-to-spec/style-check.d.ts +15 -0
  84. package/dist/commands/codebase-to-spec/style-check.js +42 -0
  85. package/dist/commands/codebase-to-spec/validate.d.ts +18 -0
  86. package/dist/commands/codebase-to-spec/validate.js +38 -0
  87. package/dist/commands/create-requirement-document.d.ts +2 -0
  88. package/dist/commands/create-requirement-document.js +41 -0
  89. package/dist/commands/finalize.js +7 -7
  90. package/dist/commands/get.d.ts +2 -0
  91. package/dist/commands/get.js +55 -0
  92. package/dist/commands/init.js +132 -117
  93. package/dist/commands/link.js +27 -27
  94. package/dist/commands/list.d.ts +6 -0
  95. package/dist/commands/list.js +43 -0
  96. package/dist/commands/mcp.js +1 -1
  97. package/dist/commands/prepare.js +4 -4
  98. package/dist/commands/pull.js +116 -121
  99. package/dist/commands/push.js +106 -112
  100. package/dist/commands/report.d.ts +6 -2
  101. package/dist/commands/report.js +177 -122
  102. package/dist/commands/requirements-for.d.ts +2 -0
  103. package/dist/commands/requirements-for.js +29 -0
  104. package/dist/commands/review-test.d.ts +2 -0
  105. package/dist/commands/review-test.js +75 -0
  106. package/dist/commands/search.d.ts +6 -0
  107. package/dist/commands/search.js +39 -0
  108. package/dist/commands/style-check.d.ts +7 -0
  109. package/dist/commands/style-check.js +75 -0
  110. package/dist/commands/tests-for.d.ts +2 -0
  111. package/dist/commands/tests-for.js +80 -0
  112. package/dist/commands/validate.d.ts +6 -0
  113. package/dist/commands/validate.js +72 -0
  114. package/dist/config.js +1 -1
  115. package/dist/convex.d.ts +34 -22
  116. package/dist/convex.js +38 -22
  117. package/dist/harness/cache.d.ts +1 -5
  118. package/dist/harness/cache.js +49 -59
  119. package/dist/harness/convexReporting.d.ts +1 -1
  120. package/dist/harness/convexReporting.js +9 -7
  121. package/dist/harness/coverageCache.js +3 -3
  122. package/dist/harness/finalize.js +59 -46
  123. package/dist/harness/index.d.ts +6 -7
  124. package/dist/harness/index.js +9 -10
  125. package/dist/harness/prepare.js +6 -5
  126. package/dist/harness/requirementsLoader.d.ts +2 -2
  127. package/dist/harness/requirementsLoader.js +13 -35
  128. package/dist/harness/tracking.js +18 -18
  129. package/dist/harness/types.d.ts +1 -1
  130. package/dist/mcp/convexClient.d.ts +0 -39
  131. package/dist/mcp/convexClient.js +2 -107
  132. package/dist/mcp/handlers/authoring.d.ts +1 -1
  133. package/dist/mcp/handlers/authoring.js +30 -234
  134. package/dist/mcp/handlers/debug.d.ts +2 -3
  135. package/dist/mcp/handlers/debug.js +10 -10
  136. package/dist/mcp/handlers/get.d.ts +1 -1
  137. package/dist/mcp/handlers/get.js +11 -10
  138. package/dist/mcp/handlers/index.d.ts +20 -20
  139. package/dist/mcp/handlers/index.js +10 -10
  140. package/dist/mcp/handlers/list.d.ts +4 -33
  141. package/dist/mcp/handlers/list.js +16 -38
  142. package/dist/mcp/handlers/push.d.ts +1 -1
  143. package/dist/mcp/handlers/push.js +28 -18
  144. package/dist/mcp/handlers/report.d.ts +16 -0
  145. package/dist/mcp/handlers/report.js +134 -0
  146. package/dist/mcp/handlers/review.d.ts +1 -1
  147. package/dist/mcp/handlers/review.js +40 -59
  148. package/dist/mcp/handlers/search.d.ts +1 -1
  149. package/dist/mcp/handlers/search.js +7 -9
  150. package/dist/mcp/handlers/test-mapping.d.ts +1 -1
  151. package/dist/mcp/handlers/test-mapping.js +14 -14
  152. package/dist/mcp/handlers/types.d.ts +3 -3
  153. package/dist/mcp/handlers/types.js +2 -2
  154. package/dist/mcp/index.d.ts +1 -1
  155. package/dist/mcp/index.js +147 -167
  156. package/dist/push/core.d.ts +2 -2
  157. package/dist/push/core.js +20 -20
  158. package/dist/push/index.d.ts +1 -1
  159. package/dist/push/index.js +2 -2
  160. package/dist/requirements/cloud-ai.d.ts +57 -0
  161. package/dist/requirements/cloud-ai.js +104 -0
  162. package/dist/requirements/cloud-coverage.d.ts +41 -0
  163. package/dist/requirements/cloud-coverage.js +60 -0
  164. package/dist/requirements/coverage.d.ts +45 -0
  165. package/dist/requirements/coverage.js +114 -0
  166. package/dist/{mcp → requirements}/grep.d.ts +10 -1
  167. package/dist/{mcp → requirements}/grep.js +89 -44
  168. package/dist/{mcp/requirements.d.ts → requirements/index.d.ts} +19 -3
  169. package/dist/{mcp/requirements.js → requirements/index.js} +54 -35
  170. package/dist/requirements/style-guide.d.ts +67 -0
  171. package/dist/requirements/style-guide.js +299 -0
  172. package/dist/{mcp → requirements}/testCodeExtractor.js +24 -26
  173. package/dist/schema/browser.d.ts +8 -8
  174. package/dist/schema/browser.js +13 -15
  175. package/dist/schema/builder.d.ts +1 -1
  176. package/dist/schema/builder.js +13 -44
  177. package/dist/schema/conversions.d.ts +2 -2
  178. package/dist/schema/conversions.js +11 -11
  179. package/dist/schema/index.d.ts +9 -9
  180. package/dist/schema/index.js +15 -15
  181. package/dist/schema/parser-core.d.ts +1 -1
  182. package/dist/schema/parser-core.js +23 -22
  183. package/dist/schema/parser.d.ts +3 -3
  184. package/dist/schema/parser.js +27 -31
  185. package/dist/schema/resolver.d.ts +1 -1
  186. package/dist/schema/resolver.js +9 -9
  187. package/dist/schema/scenario.d.ts +1 -1
  188. package/dist/schema/scenario.js +1 -1
  189. package/dist/schema/schemas.d.ts +3 -3
  190. package/dist/schema/schemas.js +41 -28
  191. package/dist/schema/test-schema.js +27 -27
  192. package/dist/templates/context-file-section.md +3 -2
  193. package/dist/templates/example-requirements.js +1 -1
  194. package/dist/templates/example-requirements.ts +3 -1
  195. package/dist/templates/requirements-readme.js +1 -1
  196. package/dist/templates/requirements-readme.ts +1 -1
  197. package/dist/templates/skills/codebase-to-spec/SKILL.md +118 -0
  198. package/dist/utils/brand.js +3 -3
  199. package/dist/utils/browser-launch.js +4 -4
  200. package/dist/utils/context-file.d.ts +1 -1
  201. package/dist/utils/context-file.js +26 -26
  202. package/dist/utils/env.js +7 -7
  203. package/dist/utils/gitignore.js +7 -7
  204. package/dist/utils/oauth-callback-server.d.ts +1 -1
  205. package/dist/utils/oauth-callback-server.js +27 -25
  206. package/dist/utils/oauth-flow.js +32 -29
  207. package/dist/utils/project-discovery.d.ts +3 -3
  208. package/dist/utils/project-discovery.js +18 -17
  209. package/dist/utils/project-name.js +8 -8
  210. package/dist/utils/project-selector.d.ts +1 -1
  211. package/dist/utils/project-selector.js +24 -21
  212. package/dist/utils/project-settings.d.ts +1 -1
  213. package/dist/utils/project-settings.js +24 -22
  214. package/dist/utils/templates.js +6 -6
  215. package/package.json +3 -2
  216. package/dist/commands/browsertest.d.ts +0 -6
  217. package/dist/commands/login.d.ts +0 -12
  218. package/dist/commands/login.js +0 -117
  219. package/dist/commands/logout.d.ts +0 -5
  220. package/dist/commands/logout.js +0 -17
  221. package/dist/commands/mcp-setup.d.ts +0 -5
  222. package/dist/commands/mcp-setup.js +0 -431
  223. package/dist/commands/test.d.ts +0 -6
  224. package/dist/commands/test.js +0 -78
  225. package/dist/mcp/handlers/coverage.d.ts +0 -44
  226. package/dist/mcp/handlers/coverage.js +0 -105
  227. package/dist/mcp/types.d.ts +0 -27
  228. package/dist/mcp/types.js +0 -2
  229. package/dist/utils/local-project.d.ts +0 -31
  230. package/dist/utils/local-project.js +0 -33
  231. package/dist/utils/token-refresh.d.ts +0 -24
  232. package/dist/utils/token-refresh.js +0 -69
  233. package/dist/utils/token-storage.d.ts +0 -31
  234. package/dist/utils/token-storage.js +0 -57
  235. /package/dist/{mcp → requirements}/testCodeExtractor.d.ts +0 -0
package/README.md CHANGED
@@ -9,7 +9,7 @@ Tests prove *something* works—but nobody is certain it's the right something.
9
9
 
10
10
  **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.
11
11
 
12
- > **Alpha Software** — Under active development. Please report issues to support@popover.ca.
12
+ > **Alpha Software** — Under active development. Please report issues to support@dotrequirements.io.
13
13
 
14
14
  ## Who Is This For?
15
15
 
@@ -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:**
@@ -198,22 +241,124 @@ Pick any Stagehand-supported model. Example values: `gateway/anthropic/claude-ha
198
241
 
199
242
  Optional settings: `vercelBypassSecret`, `browserbaseApiKey`, `browserbaseProjectId`. Setting both Browserbase fields switches runs from LOCAL (spawns Playwright on your machine) to BROWSERBASE (managed cloud browsers).
200
243
 
201
- ### `dotreq mcp-setup`
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://docs.dotrequirements.io/tools/cli/codebase-to-spec) for prerequisites, options, exit codes, and known rough edges. Feedback to support@dotrequirements.io 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`
202
261
 
203
262
  Configure the MCP server for AI assistants (Claude Code, Cursor, etc.).
204
263
 
205
264
  ```bash
206
- dotreq mcp-setup
265
+ dotreq ai-setup
207
266
  ```
208
267
 
209
268
  ### `dotreq mcp`
210
269
 
211
- 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`).
212
271
 
213
272
  ```bash
214
273
  dotreq mcp
215
274
  ```
216
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
+
217
362
  ---
218
363
 
219
364
  ## What Works Locally
@@ -221,16 +366,18 @@ dotreq mcp
221
366
  The following features work fully offline—no account required:
222
367
 
223
368
  - Write requirements (`.requirements.md` files)
224
- - Validate requirements (`dotreq test`)
369
+ - Validate requirements (`dotreq validate`)
370
+ - Search and explore (`dotreq search`, `get`, `list`, `requirements-for`, `tests-for`)
225
371
  - Reference requirements in tests (`requirement()`)
226
- - Coverage reporting (console output)
227
- - 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
228
375
 
229
376
  The following features require a dot•requirements cloud account:
230
377
 
231
378
  - Sync requirements (`pull` / `push`)
232
- - Historical coverage tracking
233
- - 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`)
234
381
  - Team collaboration
235
382
 
236
383
  To enable cloud features, run `dotreq link` to connect your project to the cloud.
@@ -474,7 +621,7 @@ AI assistants can read your requirements in context, draft new ones, and verify
474
621
  ### Setup
475
622
 
476
623
  ```bash
477
- dotreq mcp-setup
624
+ dotreq ai-setup
478
625
  ```
479
626
 
480
627
  Follow the prompts to configure for your AI assistant (Claude Code, Cursor, etc.).
@@ -484,8 +631,7 @@ Follow the prompts to configure for your AI assistant (Claude Code, Cursor, etc.
484
631
  **Exploration:**
485
632
  - `search_requirements` — Search by text or regex
486
633
  - `get_requirement` — Get a requirement with its children and coverage
487
- - `list_all_requirements` — List all requirements in the project
488
- - `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)
489
635
  - `get_requirements_by_test` — Get requirements referenced by a test file
490
636
  - `get_tests_by_requirement` — Get tests that reference a requirement
491
637
 
@@ -495,10 +641,11 @@ Follow the prompts to configure for your AI assistant (Claude Code, Cursor, etc.
495
641
  - `style_check` — AI-powered style feedback on requirements (supports optional `requirementKeys` filter)
496
642
  - `review_test` — Comprehensive test review (style + semantic correctness)
497
643
 
644
+ **Coverage:**
645
+ - `report_coverage` — Coverage from local cache or cloud, with optional requirement / branch / since filters
646
+
498
647
  **Cloud:**
499
648
  - `push_requirements` — Push to dot•requirements cloud
500
- - `get_requirement_coverage` — Query coverage data
501
- - `get_project_coverage_summary` — Project-wide coverage stats
502
649
 
503
650
  **Diagnostic:**
504
651
  - `debug_mcp_environment` — Debug MCP server configuration
@@ -578,7 +725,7 @@ This file is automatically added to `.gitignore` during initialization.
578
725
 
579
726
  - [Documentation](https://docs.dotrequirements.io)
580
727
  - [Getting Started Guide](https://docs.dotrequirements.io/getting-started)
581
- - [Support](mailto:support@popover.ca)
728
+ - [Support](mailto:support@dotrequirements.io)
582
729
 
583
730
  ---
584
731
 
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,66 +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
- .action(wrapCommand(browserTestCommand));
82
- program
83
- .command('prepare')
84
- .description('Parse requirements and build lookup cache for multi-language test tracking')
85
- .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)")
86
98
  .action(wrapCommand(prepareCommand));
87
- program
88
- .command('finalize')
89
- .description('Aggregate test tracking data and generate coverage report')
90
- .option('--push', 'Push coverage to DotRequirements Cloud')
91
- .option('-q, --quiet', 'Output only coverage percentage (for scripting)')
92
- .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")')
93
105
  .action(wrapCommand(finalizeCommand));
94
106
  program
95
- .command('report')
96
- .description('Display coverage report from most recent test run')
97
- .option('-f, --format <format>', 'Output format: console, json, markdown', 'console')
98
- .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
+ })
99
120
  .action(wrapCommand(reportCommand));
100
121
  program
101
- .command('mcp')
102
- .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")
103
124
  .action(wrapCommand(mcpCommand));
104
125
  program
105
- .command('mcp-setup')
106
- .description('Configure MCP server for your AI assistant (Claude Code, Claude Desktop, etc.)')
107
- .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);
108
169
  program.parse();
109
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