@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
@@ -25,7 +25,7 @@ export function parseKey(key) {
25
25
  */
26
26
  export function convexToRequirements(convexReqs) {
27
27
  // Separate roots from children
28
- const roots = convexReqs.filter(r => !r.rootId);
28
+ const roots = convexReqs.filter((r) => !r.rootId);
29
29
  // Build a map of all requirements by their position path for each root
30
30
  const reqsByRoot = new Map();
31
31
  for (const req of convexReqs) {
@@ -35,11 +35,11 @@ export function convexToRequirements(convexReqs) {
35
35
  rootMap = new Map();
36
36
  reqsByRoot.set(req.rootId, rootMap);
37
37
  }
38
- rootMap.set(req.position || '', req);
38
+ rootMap.set(req.position || "", req);
39
39
  }
40
40
  }
41
41
  // Build trees for each root
42
- return roots.map(root => buildTreeFromPositions(root, reqsByRoot.get(root._id)));
42
+ return roots.map((root) => buildTreeFromPositions(root, reqsByRoot.get(root._id)));
43
43
  }
44
44
  /**
45
45
  * Recursively build a RequirementNode tree from position-based flat structure.
@@ -70,9 +70,9 @@ function buildTreeFromPositions(convexReq, positionMap) {
70
70
  // Find direct children based on position paths
71
71
  // If this is a root (no position), find children at positions like ".0", ".1"
72
72
  // If this has position ".0", find children at positions like ".0.0", ".0.1"
73
- const currentPosition = convexReq.position || '';
73
+ const currentPosition = convexReq.position || "";
74
74
  const childPositionPattern = currentPosition
75
- ? new RegExp(`^${currentPosition.replace(/\./g, '\\.')}\\.\\d+$`)
75
+ ? new RegExp(`^${currentPosition.replace(/\./g, "\\.")}\\.\\d+$`)
76
76
  : /^\.\d+$/;
77
77
  const children = [];
78
78
  for (const [pos, req] of positionMap.entries()) {
@@ -82,10 +82,10 @@ function buildTreeFromPositions(convexReq, positionMap) {
82
82
  }
83
83
  // Sort children by position
84
84
  const sortedChildren = children.sort((a, b) => {
85
- return comparePositions(a.position || '', b.position || '');
85
+ return comparePositions(a.position || "", b.position || "");
86
86
  });
87
87
  // Recursively build child nodes
88
- node.children = sortedChildren.map(child => buildTreeFromPositions(child, positionMap));
88
+ node.children = sortedChildren.map((child) => buildTreeFromPositions(child, positionMap));
89
89
  return node;
90
90
  }
91
91
  /**
@@ -93,8 +93,8 @@ function buildTreeFromPositions(convexReq, positionMap) {
93
93
  * Positions are like ".0", ".1", ".0.0", ".0.1"
94
94
  */
95
95
  function comparePositions(a, b) {
96
- const aParts = a.split('.').filter(Boolean).map(Number);
97
- const bParts = b.split('.').filter(Boolean).map(Number);
96
+ const aParts = a.split(".").filter(Boolean).map(Number);
97
+ const bParts = b.split(".").filter(Boolean).map(Number);
98
98
  for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) {
99
99
  const aVal = aParts[i] ?? -1;
100
100
  const bVal = bParts[i] ?? -1;
@@ -125,7 +125,7 @@ function flattenNode(node, projectId, rootId, position, result, documentId) {
125
125
  // Get prefix/index from metadata (if from round-trip) or parse from node.id
126
126
  let prefix;
127
127
  let index;
128
- if (node.metadata?.prefix && typeof node.metadata?.index === 'number') {
128
+ if (node.metadata?.prefix && typeof node.metadata?.index === "number") {
129
129
  // Round-trip case: use stored prefix/index
130
130
  prefix = node.metadata.prefix;
131
131
  index = node.metadata.index;
@@ -181,7 +181,7 @@ export function buildMetadata(version = 1, document) {
181
181
  * Useful for detecting duplicates or tracking which requirements exist.
182
182
  */
183
183
  export function extractRequirementKeys(convexReqs) {
184
- return new Set(convexReqs.map(r => constructKey(r.prefix, r.index)));
184
+ return new Set(convexReqs.map((r) => constructKey(r.prefix, r.index)));
185
185
  }
186
186
  /**
187
187
  * Group Convex requirements by their root.
@@ -4,13 +4,13 @@
4
4
  * This module provides types, validation, parsing, and building utilities
5
5
  * for the Markdown requirements format.
6
6
  */
7
- export { MetadataSchema, RequirementNodeSchema, RequirementsFileSchema, ParsedCriterionSchema, RequirementPrefixSchema, RequirementKeySchema, REQUIREMENT_PREFIX_PATTERN, REQUIREMENT_KEY_PATTERN, ValidationError, validateMetadata, validateRequirementNode, validateRequirementsFile, validatePrefix, validateKey, validateForPush, CONVEX_ID_PATTERN, normalizePrefix, parseRequirementKey, buildRequirementKey, } from './schemas.js';
8
- export type { Metadata, RequirementNode, RequirementsFile, ParsedCriterion, RequirementPrefix, RequirementKey, PushValidationResult, } from './schemas.js';
9
- export { parseCriterionLine, parseRequirementBlock, parseRequirementsFile, parseRequirementsFromFile, flattenRequirementTree, findRequirementById, getAllRequirements, } from './parser.js';
10
- export { buildRequirementsMarkdown, buildRequirementMarkdown, buildRequirementsFile, } from './builder.js';
11
- export { parseRequirementPath, parsePathSegment, findChildrenByLabel, resolvePathSegment, resolveRequirementPath, resolveToNumericPath, getAllLabelPaths, checkPathAmbiguity, } from './resolver.js';
12
- export type { ConvexRequirement, } from './conversions.js';
13
- export { convexToRequirements, requirementsToConvex, buildMetadata, extractRequirementKeys, groupByRoot, constructKey, parseKey, } from './conversions.js';
14
- export { buildScenarioFromRequirements, requirementTreeToScenario, } from './scenario.js';
15
- export type { Scenario, ScenarioStep, ScenarioAssertionSource, BuildScenarioOptions, } from './scenario.js';
7
+ export { buildRequirementMarkdown, buildRequirementsFile, buildRequirementsMarkdown, } from "./builder.js";
8
+ export type { ConvexRequirement } from "./conversions.js";
9
+ export { buildMetadata, constructKey, convexToRequirements, extractRequirementKeys, groupByRoot, parseKey, requirementsToConvex, } from "./conversions.js";
10
+ export { findRequirementById, flattenRequirementTree, getAllRequirements, parseCriterionLine, parseRequirementBlock, parseRequirementsFile, parseRequirementsFromFile, } from "./parser.js";
11
+ export { checkPathAmbiguity, findChildrenByLabel, getAllLabelPaths, parsePathSegment, parseRequirementPath, resolvePathSegment, resolveRequirementPath, resolveToNumericPath, } from "./resolver.js";
12
+ export type { BuildScenarioOptions, Scenario, ScenarioAssertionSource, ScenarioStep, } from "./scenario.js";
13
+ export { buildScenarioFromRequirements, requirementTreeToScenario, } from "./scenario.js";
14
+ export type { Metadata, ParsedCriterion, PushValidationResult, RequirementKey, RequirementNode, RequirementPrefix, RequirementsFile, } from "./schemas.js";
15
+ export { buildRequirementKey, CONVEX_ID_PATTERN, MetadataSchema, normalizePrefix, ParsedCriterionSchema, parseRequirementKey, REQUIREMENT_KEY_PATTERN, REQUIREMENT_PREFIX_PATTERN, RequirementKeySchema, RequirementNodeSchema, RequirementPrefixSchema, RequirementsFileSchema, ValidationError, validateForPush, validateKey, validateMetadata, validatePrefix, validateRequirementNode, validateRequirementsFile, } from "./schemas.js";
16
16
  //# sourceMappingURL=index.d.ts.map
@@ -4,23 +4,23 @@
4
4
  * This module provides types, validation, parsing, and building utilities
5
5
  * for the Markdown requirements format.
6
6
  */
7
+ // Building
8
+ export { buildRequirementMarkdown, buildRequirementsFile, buildRequirementsMarkdown, } from "./builder.js";
9
+ export { buildMetadata, constructKey, convexToRequirements, extractRequirementKeys, groupByRoot, parseKey, requirementsToConvex, } from "./conversions.js";
10
+ // Parsing
11
+ export { findRequirementById, flattenRequirementTree, getAllRequirements, parseCriterionLine, parseRequirementBlock, parseRequirementsFile, parseRequirementsFromFile, } from "./parser.js";
12
+ // Path resolution
13
+ export { checkPathAmbiguity, findChildrenByLabel, getAllLabelPaths, parsePathSegment, parseRequirementPath, resolvePathSegment, resolveRequirementPath, resolveToNumericPath, } from "./resolver.js";
14
+ // Scenario building (for browser-automation / runScenario)
15
+ export { buildScenarioFromRequirements, requirementTreeToScenario, } from "./scenario.js";
7
16
  // Schemas and types
8
- export {
17
+ export { buildRequirementKey, CONVEX_ID_PATTERN,
9
18
  // Zod schemas
10
- MetadataSchema, RequirementNodeSchema, RequirementsFileSchema, ParsedCriterionSchema, RequirementPrefixSchema, RequirementKeySchema,
19
+ MetadataSchema,
20
+ // Prefix/key utilities
21
+ normalizePrefix, ParsedCriterionSchema, parseRequirementKey, REQUIREMENT_KEY_PATTERN,
11
22
  // Patterns (for external validation)
12
- REQUIREMENT_PREFIX_PATTERN, REQUIREMENT_KEY_PATTERN,
23
+ REQUIREMENT_PREFIX_PATTERN, RequirementKeySchema, RequirementNodeSchema, RequirementPrefixSchema, RequirementsFileSchema,
13
24
  // Validation
14
- ValidationError, validateMetadata, validateRequirementNode, validateRequirementsFile, validatePrefix, validateKey, validateForPush, CONVEX_ID_PATTERN,
15
- // Prefix/key utilities
16
- normalizePrefix, parseRequirementKey, buildRequirementKey, } from './schemas.js';
17
- // Parsing
18
- export { parseCriterionLine, parseRequirementBlock, parseRequirementsFile, parseRequirementsFromFile, flattenRequirementTree, findRequirementById, getAllRequirements, } from './parser.js';
19
- // Building
20
- export { buildRequirementsMarkdown, buildRequirementMarkdown, buildRequirementsFile, } from './builder.js';
21
- // Path resolution
22
- export { parseRequirementPath, parsePathSegment, findChildrenByLabel, resolvePathSegment, resolveRequirementPath, resolveToNumericPath, getAllLabelPaths, checkPathAmbiguity, } from './resolver.js';
23
- export { convexToRequirements, requirementsToConvex, buildMetadata, extractRequirementKeys, groupByRoot, constructKey, parseKey, } from './conversions.js';
24
- // Scenario building (for browser-automation / runScenario)
25
- export { buildScenarioFromRequirements, requirementTreeToScenario, } from './scenario.js';
25
+ ValidationError, validateForPush, validateKey, validateMetadata, validatePrefix, validateRequirementNode, validateRequirementsFile, } from "./schemas.js";
26
26
  //# sourceMappingURL=index.js.map
@@ -4,7 +4,7 @@
4
4
  * This module contains pure parsing functions with no Node.js dependencies,
5
5
  * making it safe to import in Convex runtime or browser environments.
6
6
  */
7
- import { RequirementNode, ParsedCriterion } from './schemas.js';
7
+ import { type ParsedCriterion, type RequirementNode } from "./schemas.js";
8
8
  /**
9
9
  * Default delimiter for requirements.
10
10
  * Can be overridden for organization-specific preferences.
@@ -4,13 +4,13 @@
4
4
  * This module contains pure parsing functions with no Node.js dependencies,
5
5
  * making it safe to import in Convex runtime or browser environments.
6
6
  */
7
- import { ValidationError, } from './schemas.js';
7
+ import { ValidationError, } from "./schemas.js";
8
8
  /**
9
9
  * Default delimiter for requirements.
10
10
  * Can be overridden for organization-specific preferences.
11
11
  */
12
- export const DEFAULT_DELIMITER = '→';
13
- export const DELIMITER_PATTERN = '(?:→|->)'; // Non-capturing group for both Unicode and ASCII
12
+ export const DEFAULT_DELIMITER = "→";
13
+ export const DELIMITER_PATTERN = "(?:→|->)"; // Non-capturing group for both Unicode and ASCII
14
14
  /**
15
15
  * Parse a criterion line in "position. Label → content" format.
16
16
  * Example: "0. Given → user has valid credentials"
@@ -27,7 +27,7 @@ export function parseCriterionLine(line, delimiter = DELIMITER_PATTERN) {
27
27
  }
28
28
  return {
29
29
  position: match[1],
30
- label: match[2] ? match[2].trim() : '', // Preserve original case, empty if no label
30
+ label: match[2] ? match[2].trim() : "", // Preserve original case, empty if no label
31
31
  content: match[3].trim(),
32
32
  };
33
33
  }
@@ -43,7 +43,7 @@ export function parseRootLine(line, delimiter = DELIMITER_PATTERN) {
43
43
  if (keyMatch) {
44
44
  return {
45
45
  key: keyMatch[1],
46
- label: '', // Keys use empty string for unlabeled requirements
46
+ label: "", // Keys use empty string for unlabeled requirements
47
47
  content: keyMatch[2].trim(),
48
48
  };
49
49
  }
@@ -53,12 +53,12 @@ export function parseRootLine(line, delimiter = DELIMITER_PATTERN) {
53
53
  if (!match) {
54
54
  // If no delimiter found, treat entire line as content with empty label
55
55
  return {
56
- label: '',
56
+ label: "",
57
57
  content: trimmed,
58
58
  };
59
59
  }
60
60
  return {
61
- label: match[1] ? match[1].trim() : '',
61
+ label: match[1] ? match[1].trim() : "",
62
62
  content: match[2].trim(),
63
63
  };
64
64
  }
@@ -68,20 +68,20 @@ export function parseRootLine(line, delimiter = DELIMITER_PATTERN) {
68
68
  * Subsequent lines are criteria with position paths.
69
69
  */
70
70
  export function parseRequirementBlock(key, blockContent) {
71
- const lines = blockContent.trim().split('\n');
71
+ const lines = blockContent.trim().split("\n");
72
72
  if (lines.length === 0) {
73
- throw new ValidationError('Empty requirement block', key);
73
+ throw new ValidationError("Empty requirement block", key);
74
74
  }
75
75
  // First line is the requirement content
76
76
  const rootParsed = parseRootLine(lines[0]);
77
77
  if (!rootParsed.content) {
78
- throw new ValidationError('Requirement content (first line) cannot be empty', key);
78
+ throw new ValidationError("Requirement content (first line) cannot be empty", key);
79
79
  }
80
80
  const root = {
81
81
  id: key,
82
82
  // Root requirements always use "requirementHeader" label for indexing/querying
83
83
  // The markdown format doesn't preserve root labels, but we standardize on this value
84
- label: 'requirementHeader',
84
+ label: "requirementHeader",
85
85
  content: rootParsed.content,
86
86
  children: [],
87
87
  };
@@ -90,7 +90,7 @@ export function parseRequirementBlock(key, blockContent) {
90
90
  for (let i = 1; i < lines.length; i++) {
91
91
  const line = lines[i];
92
92
  // Skip empty lines and comments
93
- if (!line.trim() || line.trim().startsWith('#')) {
93
+ if (!line.trim() || line.trim().startsWith("#")) {
94
94
  continue;
95
95
  }
96
96
  const criterion = parseCriterionLine(line);
@@ -98,7 +98,7 @@ export function parseRequirementBlock(key, blockContent) {
98
98
  // Check if this looks like another requirement key (KEY: content format)
99
99
  const trimmedLine = line.trim();
100
100
  if (/^[\w-]+:\s*.+/.test(trimmedLine)) {
101
- throw new ValidationError(`Multiple requirements in single block. Found "${trimmedLine.split(':')[0]}" at line ${i + 1}, but each requirement must have its own \`\`\`dotrequirements code block.`, key);
101
+ throw new ValidationError(`Multiple requirements in single block. Found "${trimmedLine.split(":")[0]}" at line ${i + 1}, but each requirement must have its own \`\`\`dotrequirements code block.`, key);
102
102
  }
103
103
  throw new ValidationError(`Invalid criterion format at line ${i + 1}: "${trimmedLine}". Expected format: "N. Label → content" (e.g., "0. Given → user is logged in")`, key);
104
104
  }
@@ -115,8 +115,8 @@ export function parseRequirementBlock(key, blockContent) {
115
115
  function buildTreeFromPositions(root, rootKey, criteriaByPosition) {
116
116
  // Get all top-level children (single digit positions: "0", "1", "2")
117
117
  const topLevelPositions = Array.from(criteriaByPosition.keys())
118
- .filter(pos => !pos.includes('.'))
119
- .sort((a, b) => parseInt(a) - parseInt(b));
118
+ .filter((pos) => !pos.includes("."))
119
+ .sort((a, b) => parseInt(a, 10) - parseInt(b, 10));
120
120
  for (const position of topLevelPositions) {
121
121
  const criterion = criteriaByPosition.get(position);
122
122
  const childNode = {
@@ -136,9 +136,9 @@ function buildTreeFromPositions(root, rootKey, criteriaByPosition) {
136
136
  function buildChildrenFromPositions(parent, parentPosition, rootKey, criteriaByPosition) {
137
137
  // Find direct children (e.g., if parent is "1", find "1.0", "1.1", etc.)
138
138
  const childPositions = Array.from(criteriaByPosition.keys())
139
- .filter(pos => {
140
- const parts = pos.split('.');
141
- const parentParts = parentPosition.split('.');
139
+ .filter((pos) => {
140
+ const parts = pos.split(".");
141
+ const parentParts = parentPosition.split(".");
142
142
  // Must be exactly one level deeper
143
143
  if (parts.length !== parentParts.length + 1) {
144
144
  return false;
@@ -152,8 +152,8 @@ function buildChildrenFromPositions(parent, parentPosition, rootKey, criteriaByP
152
152
  return true;
153
153
  })
154
154
  .sort((a, b) => {
155
- const aLast = parseInt(a.split('.').pop());
156
- const bLast = parseInt(b.split('.').pop());
155
+ const aLast = parseInt(a.split(".").pop(), 10);
156
+ const bLast = parseInt(b.split(".").pop(), 10);
157
157
  return aLast - bLast;
158
158
  });
159
159
  for (const position of childPositions) {
@@ -177,8 +177,8 @@ export function extractRequirementBlocks(body) {
177
177
  const blocks = [];
178
178
  // Find all ```dotrequirements code blocks
179
179
  const blockRegex = /```dotrequirements\n([\s\S]*?)```/gm;
180
- let match;
181
- while ((match = blockRegex.exec(body)) !== null) {
180
+ let match = blockRegex.exec(body);
181
+ while (match !== null) {
182
182
  const blockContent = match[1];
183
183
  // Extract key from first line of block (format: "KEY: content")
184
184
  const firstLineMatch = blockContent.match(/^([\w-]+):\s*(.+)/);
@@ -187,6 +187,7 @@ export function extractRequirementBlocks(body) {
187
187
  }
188
188
  const key = firstLineMatch[1];
189
189
  blocks.push({ key, blockContent: blockContent.trim() });
190
+ match = blockRegex.exec(body);
190
191
  }
191
192
  return blocks;
192
193
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Parse Markdown requirements files into typed structures.
3
3
  */
4
- import { RequirementNode, RequirementsFile, ParsedCriterion } from './schemas.js';
4
+ import { type ParsedCriterion, type RequirementNode, type RequirementsFile } from "./schemas.js";
5
5
  /**
6
6
  * Parse a criterion line in "position. Label → content" format.
7
7
  * Example: "0. Given → user has valid credentials"
@@ -18,14 +18,14 @@ export declare function parseRequirementBlock(key: string, blockContent: string)
18
18
  * Parse a complete requirements Markdown file.
19
19
  */
20
20
  export declare function parseRequirementsFile(markdownContent: string): {
21
- metadata: RequirementsFile['_meta'];
21
+ metadata: RequirementsFile["_meta"];
22
22
  requirements: RequirementNode[];
23
23
  };
24
24
  /**
25
25
  * Parse requirements file from disk.
26
26
  */
27
27
  export declare function parseRequirementsFromFile(filePath: string): {
28
- metadata: RequirementsFile['_meta'];
28
+ metadata: RequirementsFile["_meta"];
29
29
  requirements: RequirementNode[];
30
30
  };
31
31
  /**
@@ -1,15 +1,10 @@
1
1
  /**
2
2
  * Parse Markdown requirements files into typed structures.
3
3
  */
4
- import YAML from 'yaml';
5
- import * as fs from 'fs';
6
- import { ValidationError, validateMetadata, } from './schemas.js';
7
- /**
8
- * Default delimiter for requirements.
9
- * Can be overridden for organization-specific preferences.
10
- */
11
- const DEFAULT_DELIMITER = '→';
12
- const DELIMITER_PATTERN = '(?:→|->)'; // Non-capturing group for both Unicode and ASCII
4
+ import * as fs from "node:fs";
5
+ import YAML from "yaml";
6
+ import { ValidationError, validateMetadata, } from "./schemas.js";
7
+ const DELIMITER_PATTERN = "(?:→|->)"; // Non-capturing group for both Unicode and ASCII
13
8
  /**
14
9
  * Parse a criterion line in "position. Label → content" format.
15
10
  * Example: "0. Given → user has valid credentials"
@@ -26,7 +21,7 @@ export function parseCriterionLine(line, delimiter = DELIMITER_PATTERN) {
26
21
  }
27
22
  return {
28
23
  position: match[1],
29
- label: match[2] ? match[2].trim() : '', // Preserve original case, empty if no label
24
+ label: match[2] ? match[2].trim() : "", // Preserve original case, empty if no label
30
25
  content: match[3].trim(),
31
26
  };
32
27
  }
@@ -41,7 +36,7 @@ function parseRootLine(line, delimiter = DELIMITER_PATTERN) {
41
36
  const keyMatch = trimmed.match(/^([\w-]+):\s*(.+)$/);
42
37
  if (keyMatch) {
43
38
  return {
44
- label: '', // Keys use empty string for unlabeled requirements
39
+ label: "", // Keys use empty string for unlabeled requirements
45
40
  content: keyMatch[2].trim(),
46
41
  };
47
42
  }
@@ -51,12 +46,12 @@ function parseRootLine(line, delimiter = DELIMITER_PATTERN) {
51
46
  if (!match) {
52
47
  // If no delimiter found, treat entire line as content with empty label
53
48
  return {
54
- label: '',
49
+ label: "",
55
50
  content: trimmed,
56
51
  };
57
52
  }
58
53
  return {
59
- label: match[1] ? match[1].trim() : '',
54
+ label: match[1] ? match[1].trim() : "",
60
55
  content: match[2].trim(),
61
56
  };
62
57
  }
@@ -66,20 +61,20 @@ function parseRootLine(line, delimiter = DELIMITER_PATTERN) {
66
61
  * Subsequent lines are criteria with position paths.
67
62
  */
68
63
  export function parseRequirementBlock(key, blockContent) {
69
- const lines = blockContent.trim().split('\n');
64
+ const lines = blockContent.trim().split("\n");
70
65
  if (lines.length === 0) {
71
- throw new ValidationError('Empty requirement block', key);
66
+ throw new ValidationError("Empty requirement block", key);
72
67
  }
73
68
  // First line is the requirement content
74
69
  const rootParsed = parseRootLine(lines[0]);
75
70
  if (!rootParsed.content) {
76
- throw new ValidationError('Requirement content (first line) cannot be empty', key);
71
+ throw new ValidationError("Requirement content (first line) cannot be empty", key);
77
72
  }
78
73
  const root = {
79
74
  id: key,
80
75
  // Root requirements always use "requirementHeader" label for indexing/querying
81
76
  // The markdown format doesn't preserve root labels, but we standardize on this value
82
- label: 'requirementHeader',
77
+ label: "requirementHeader",
83
78
  content: rootParsed.content,
84
79
  children: [],
85
80
  };
@@ -88,7 +83,7 @@ export function parseRequirementBlock(key, blockContent) {
88
83
  for (let i = 1; i < lines.length; i++) {
89
84
  const line = lines[i];
90
85
  // Skip empty lines and comments
91
- if (!line.trim() || line.trim().startsWith('#')) {
86
+ if (!line.trim() || line.trim().startsWith("#")) {
92
87
  continue;
93
88
  }
94
89
  const criterion = parseCriterionLine(line);
@@ -108,8 +103,8 @@ export function parseRequirementBlock(key, blockContent) {
108
103
  function buildTreeFromPositions(root, rootKey, criteriaByPosition) {
109
104
  // Get all top-level children (single digit positions: "0", "1", "2")
110
105
  const topLevelPositions = Array.from(criteriaByPosition.keys())
111
- .filter(pos => !pos.includes('.'))
112
- .sort((a, b) => parseInt(a) - parseInt(b));
106
+ .filter((pos) => !pos.includes("."))
107
+ .sort((a, b) => parseInt(a, 10) - parseInt(b, 10));
113
108
  for (const position of topLevelPositions) {
114
109
  const criterion = criteriaByPosition.get(position);
115
110
  const childNode = {
@@ -129,9 +124,9 @@ function buildTreeFromPositions(root, rootKey, criteriaByPosition) {
129
124
  function buildChildrenFromPositions(parent, parentPosition, rootKey, criteriaByPosition) {
130
125
  // Find direct children (e.g., if parent is "1", find "1.0", "1.1", etc.)
131
126
  const childPositions = Array.from(criteriaByPosition.keys())
132
- .filter(pos => {
133
- const parts = pos.split('.');
134
- const parentParts = parentPosition.split('.');
127
+ .filter((pos) => {
128
+ const parts = pos.split(".");
129
+ const parentParts = parentPosition.split(".");
135
130
  // Must be exactly one level deeper
136
131
  if (parts.length !== parentParts.length + 1) {
137
132
  return false;
@@ -145,8 +140,8 @@ function buildChildrenFromPositions(parent, parentPosition, rootKey, criteriaByP
145
140
  return true;
146
141
  })
147
142
  .sort((a, b) => {
148
- const aLast = parseInt(a.split('.').pop());
149
- const bLast = parseInt(b.split('.').pop());
143
+ const aLast = parseInt(a.split(".").pop(), 10);
144
+ const bLast = parseInt(b.split(".").pop(), 10);
150
145
  return aLast - bLast;
151
146
  });
152
147
  for (const position of childPositions) {
@@ -171,7 +166,7 @@ function extractFrontmatter(content) {
171
166
  const frontmatterRegex = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/;
172
167
  const match = content.match(frontmatterRegex);
173
168
  if (!match) {
174
- throw new ValidationError('Missing YAML frontmatter (should start with ---)');
169
+ throw new ValidationError("Missing YAML frontmatter (should start with ---)");
175
170
  }
176
171
  const [, frontmatterYaml, body] = match;
177
172
  let frontmatter;
@@ -179,7 +174,7 @@ function extractFrontmatter(content) {
179
174
  frontmatter = YAML.parse(frontmatterYaml);
180
175
  }
181
176
  catch (error) {
182
- throw new ValidationError('Failed to parse YAML frontmatter', undefined, error);
177
+ throw new ValidationError("Failed to parse YAML frontmatter", undefined, error);
183
178
  }
184
179
  return { frontmatter, body: body.trim() };
185
180
  }
@@ -194,8 +189,8 @@ function extractRequirementBlocks(body) {
194
189
  const blocks = new Map();
195
190
  // Find all ```dotrequirements code blocks
196
191
  const blockRegex = /```dotrequirements\n([\s\S]*?)```/gm;
197
- let match;
198
- while ((match = blockRegex.exec(body)) !== null) {
192
+ let match = blockRegex.exec(body);
193
+ while (match !== null) {
199
194
  const blockContent = match[1];
200
195
  // Extract key from first line of block (format: "KEY: content")
201
196
  const firstLineMatch = blockContent.match(/^([\w-]+):\s*(.+)/);
@@ -209,6 +204,7 @@ function extractRequirementBlocks(body) {
209
204
  const headingMatch = textBeforeBlock.match(/^#{2,6}\s+([^\n]+)\s*$/m);
210
205
  const title = headingMatch ? headingMatch[1].trim() : key;
211
206
  blocks.set(key, { title, blockContent: blockContent.trim() });
207
+ match = blockRegex.exec(body);
212
208
  }
213
209
  return blocks;
214
210
  }
@@ -223,7 +219,7 @@ export function parseRequirementsFile(markdownContent) {
223
219
  // Extract requirement blocks
224
220
  const blocks = extractRequirementBlocks(body);
225
221
  if (blocks.size === 0) {
226
- throw new ValidationError('No requirement blocks found in document');
222
+ throw new ValidationError("No requirement blocks found in document");
227
223
  }
228
224
  // Parse each requirement block
229
225
  const requirements = [];
@@ -246,7 +242,7 @@ export function parseRequirementsFile(markdownContent) {
246
242
  */
247
243
  export function parseRequirementsFromFile(filePath) {
248
244
  try {
249
- const content = fs.readFileSync(filePath, 'utf-8');
245
+ const content = fs.readFileSync(filePath, "utf-8");
250
246
  return parseRequirementsFile(content);
251
247
  }
252
248
  catch (error) {
@@ -2,7 +2,7 @@
2
2
  * Resolve label-based requirement paths to numeric paths.
3
3
  * Supports: REQ123.given, REQ123.when.then, REQ123.given#1
4
4
  */
5
- import { RequirementNode } from './schemas.js';
5
+ import type { RequirementNode } from "./schemas.js";
6
6
  /**
7
7
  * Parse a requirement path into segments.
8
8
  * E.g., "REQ123.given.then" → ["REQ123", "given", "then"]
@@ -8,7 +8,7 @@
8
8
  * E.g., "REQ123.given#1" → ["REQ123", "given#1"]
9
9
  */
10
10
  export function parseRequirementPath(path) {
11
- return path.split('.');
11
+ return path.split(".");
12
12
  }
13
13
  /**
14
14
  * Parse a path segment that may include disambiguation.
@@ -22,7 +22,7 @@ export function parsePathSegment(segment) {
22
22
  }
23
23
  return {
24
24
  label: match[1],
25
- index: match[2] ? parseInt(match[2]) : 0,
25
+ index: match[2] ? parseInt(match[2], 10) : 0,
26
26
  };
27
27
  }
28
28
  /**
@@ -31,7 +31,7 @@ export function parsePathSegment(segment) {
31
31
  * Examples: "Several-words" -> "several words", "AC" -> "ac"
32
32
  */
33
33
  function normalizeLabel(label) {
34
- return label.replace(/-/g, ' ').toLowerCase();
34
+ return label.replace(/-/g, " ").toLowerCase();
35
35
  }
36
36
  /**
37
37
  * Find children matching a label.
@@ -40,7 +40,7 @@ function normalizeLabel(label) {
40
40
  */
41
41
  export function findChildrenByLabel(node, label) {
42
42
  const normalizedLabel = normalizeLabel(label);
43
- return node.children.filter(child => normalizeLabel(child.label) === normalizedLabel);
43
+ return node.children.filter((child) => normalizeLabel(child.label) === normalizedLabel);
44
44
  }
45
45
  /**
46
46
  * Resolve a label-based path segment to a numeric index.
@@ -49,7 +49,7 @@ export function findChildrenByLabel(node, label) {
49
49
  export function resolvePathSegment(node, segment) {
50
50
  // Check if segment is numeric (direct index)
51
51
  if (/^\d+$/.test(segment)) {
52
- const index = parseInt(segment);
52
+ const index = parseInt(segment, 10);
53
53
  if (index < node.children.length) {
54
54
  return {
55
55
  child: node.children[index],
@@ -94,7 +94,7 @@ export function resolveRequirementPath(requirements, path) {
94
94
  }
95
95
  // First segment should be the root requirement ID
96
96
  const rootId = segments[0];
97
- let currentNode = requirements.find(r => r.id === rootId);
97
+ let currentNode = requirements.find((r) => r.id === rootId);
98
98
  if (!currentNode) {
99
99
  return null;
100
100
  }
@@ -130,7 +130,7 @@ export function resolveToNumericPath(requirements, path) {
130
130
  *
131
131
  * Returns paths like: ["REQ123", "REQ123.given", "REQ123.when", ...]
132
132
  */
133
- export function getAllLabelPaths(node, prefix = '') {
133
+ export function getAllLabelPaths(node, prefix = "") {
134
134
  const currentPath = prefix ? `${prefix}.${node.label}` : node.id;
135
135
  const paths = [currentPath];
136
136
  for (const child of node.children) {
@@ -148,7 +148,7 @@ export function checkPathAmbiguity(requirements, path) {
148
148
  return 0;
149
149
  }
150
150
  const rootId = segments[0];
151
- let currentNode = requirements.find(r => r.id === rootId);
151
+ let currentNode = requirements.find((r) => r.id === rootId);
152
152
  if (!currentNode) {
153
153
  return 0;
154
154
  }
@@ -160,7 +160,7 @@ export function checkPathAmbiguity(requirements, path) {
160
160
  const segment = segments[i];
161
161
  // Numeric segments are never ambiguous
162
162
  if (/^\d+$/.test(segment)) {
163
- const index = parseInt(segment);
163
+ const index = parseInt(segment, 10);
164
164
  if (index >= currentNode.children.length) {
165
165
  return 0; // Invalid path
166
166
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Scenario builder — turns a requirement tree into a browser-automation Scenario.
3
3
  *
4
- * Used by both the CLI (via `dotreq browsertest`) and the Convex Node action
4
+ * Used by both the CLI (via `dotreq acceptance-test`) and the Convex Node action
5
5
  * (`testCoverage/browserRun:run`) so the two paths produce identical scenarios
6
6
  * for the same input.
7
7
  *
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Scenario builder — turns a requirement tree into a browser-automation Scenario.
3
3
  *
4
- * Used by both the CLI (via `dotreq browsertest`) and the Convex Node action
4
+ * Used by both the CLI (via `dotreq acceptance-test`) and the Convex Node action
5
5
  * (`testCoverage/browserRun:run`) so the two paths produce identical scenarios
6
6
  * for the same input.
7
7
  *
@@ -2,7 +2,7 @@
2
2
  * Zod schemas for Markdown requirements format.
3
3
  * TypeScript types are inferred from these schemas using z.infer<>.
4
4
  */
5
- import { z } from 'zod';
5
+ import { z } from "zod";
6
6
  /**
7
7
  * Requirement prefix format: uppercase letters and hyphens, 1-30 chars.
8
8
  * First char must be a letter.
@@ -100,7 +100,7 @@ export declare const CONVEX_ID_PATTERN: RegExp;
100
100
  */
101
101
  export type PushValidationResult = {
102
102
  valid: true;
103
- action: 'create' | 'update';
103
+ action: "create" | "update";
104
104
  warning?: string;
105
105
  } | {
106
106
  valid: false;
@@ -246,7 +246,7 @@ export declare const RequirementsFileSchema: z.ZodObject<{
246
246
  }>;
247
247
  }, z.ZodTypeAny, "passthrough">>;
248
248
  export type RequirementsFile = z.infer<typeof RequirementsFileSchema> & {
249
- [key: string]: any;
249
+ [key: string]: unknown;
250
250
  };
251
251
  /**
252
252
  * Parsed criterion from Markdown (position. Label: content format)