doc-detective-common 3.6.1 → 4.0.0-beta.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 (269) hide show
  1. package/.c8rc.json +8 -0
  2. package/.claude/settings.local.json +11 -0
  3. package/.claude/skills/tdd-coverage/SKILL.md +161 -0
  4. package/AGENTS.md +332 -285
  5. package/CLAUDE.md +38 -0
  6. package/LICENSE +661 -661
  7. package/README.md +78 -48
  8. package/coverage-thresholds.json +8 -0
  9. package/dist/detectTests.d.ts +106 -0
  10. package/dist/detectTests.d.ts.map +1 -0
  11. package/dist/detectTests.js +530 -0
  12. package/dist/detectTests.js.map +1 -0
  13. package/dist/files.d.ts +16 -0
  14. package/dist/files.d.ts.map +1 -0
  15. package/dist/files.js +123 -0
  16. package/dist/files.js.map +1 -0
  17. package/dist/index.cjs +122283 -0
  18. package/dist/index.d.cts +4 -0
  19. package/dist/index.d.ts +4 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +4 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/index.mjs +4 -0
  24. package/dist/resolvePaths.d.ts +28 -0
  25. package/dist/resolvePaths.d.ts.map +1 -0
  26. package/dist/resolvePaths.js +236 -0
  27. package/dist/resolvePaths.js.map +1 -0
  28. package/dist/schemas/index.d.ts +5 -0
  29. package/dist/schemas/index.d.ts.map +1 -0
  30. package/dist/schemas/index.js +3 -0
  31. package/dist/schemas/index.js.map +1 -0
  32. package/dist/schemas/schemas.json +121359 -0
  33. package/dist/types/generated/checkLink_v3.d.ts +27 -0
  34. package/dist/types/generated/checkLink_v3.d.ts.map +1 -0
  35. package/dist/types/generated/checkLink_v3.js +7 -0
  36. package/dist/types/generated/checkLink_v3.js.map +1 -0
  37. package/dist/types/generated/click_v3.d.ts +16 -0
  38. package/dist/types/generated/click_v3.d.ts.map +1 -0
  39. package/dist/types/generated/click_v3.js +7 -0
  40. package/dist/types/generated/click_v3.js.map +1 -0
  41. package/dist/types/generated/config_v3.d.ts +398 -0
  42. package/dist/types/generated/config_v3.d.ts.map +1 -0
  43. package/dist/types/generated/config_v3.js +7 -0
  44. package/dist/types/generated/config_v3.js.map +1 -0
  45. package/dist/types/generated/context_v3.d.ts +108 -0
  46. package/dist/types/generated/context_v3.d.ts.map +1 -0
  47. package/dist/types/generated/context_v3.js +7 -0
  48. package/dist/types/generated/context_v3.js.map +1 -0
  49. package/dist/types/generated/dragAndDrop_v3.d.ts +37 -0
  50. package/dist/types/generated/dragAndDrop_v3.d.ts.map +1 -0
  51. package/dist/types/generated/dragAndDrop_v3.js +7 -0
  52. package/dist/types/generated/dragAndDrop_v3.js.map +1 -0
  53. package/dist/types/generated/endRecord_v3.d.ts +9 -0
  54. package/dist/types/generated/endRecord_v3.d.ts.map +1 -0
  55. package/dist/types/generated/endRecord_v3.js +7 -0
  56. package/dist/types/generated/endRecord_v3.js.map +1 -0
  57. package/dist/types/generated/find_v3.d.ts +16 -0
  58. package/dist/types/generated/find_v3.d.ts.map +1 -0
  59. package/dist/types/generated/find_v3.js +7 -0
  60. package/dist/types/generated/find_v3.js.map +1 -0
  61. package/dist/types/generated/goTo_v3.d.ts +46 -0
  62. package/dist/types/generated/goTo_v3.d.ts.map +1 -0
  63. package/dist/types/generated/goTo_v3.js +7 -0
  64. package/dist/types/generated/goTo_v3.js.map +1 -0
  65. package/dist/types/generated/httpRequest_v3.d.ts +16 -0
  66. package/dist/types/generated/httpRequest_v3.d.ts.map +1 -0
  67. package/dist/types/generated/httpRequest_v3.js +7 -0
  68. package/dist/types/generated/httpRequest_v3.js.map +1 -0
  69. package/dist/types/generated/loadCookie_v3.d.ts +16 -0
  70. package/dist/types/generated/loadCookie_v3.d.ts.map +1 -0
  71. package/dist/types/generated/loadCookie_v3.js +7 -0
  72. package/dist/types/generated/loadCookie_v3.js.map +1 -0
  73. package/dist/types/generated/loadVariables_v3.d.ts +9 -0
  74. package/dist/types/generated/loadVariables_v3.d.ts.map +1 -0
  75. package/dist/types/generated/loadVariables_v3.js +7 -0
  76. package/dist/types/generated/loadVariables_v3.js.map +1 -0
  77. package/dist/types/generated/openApi_v3.d.ts +62 -0
  78. package/dist/types/generated/openApi_v3.d.ts.map +1 -0
  79. package/dist/types/generated/openApi_v3.js +7 -0
  80. package/dist/types/generated/openApi_v3.js.map +1 -0
  81. package/dist/types/generated/record_v3.d.ts +32 -0
  82. package/dist/types/generated/record_v3.d.ts.map +1 -0
  83. package/dist/types/generated/record_v3.js +7 -0
  84. package/dist/types/generated/record_v3.js.map +1 -0
  85. package/dist/types/generated/report_v3.d.ts +174 -0
  86. package/dist/types/generated/report_v3.d.ts.map +1 -0
  87. package/dist/types/generated/report_v3.js +7 -0
  88. package/dist/types/generated/report_v3.js.map +1 -0
  89. package/dist/types/generated/resolvedTests_v3.d.ts +571 -0
  90. package/dist/types/generated/resolvedTests_v3.d.ts.map +1 -0
  91. package/dist/types/generated/resolvedTests_v3.js +7 -0
  92. package/dist/types/generated/resolvedTests_v3.js.map +1 -0
  93. package/dist/types/generated/runCode_v3.d.ts +57 -0
  94. package/dist/types/generated/runCode_v3.d.ts.map +1 -0
  95. package/dist/types/generated/runCode_v3.js +7 -0
  96. package/dist/types/generated/runCode_v3.js.map +1 -0
  97. package/dist/types/generated/runShell_v3.d.ts +56 -0
  98. package/dist/types/generated/runShell_v3.d.ts.map +1 -0
  99. package/dist/types/generated/runShell_v3.js +7 -0
  100. package/dist/types/generated/runShell_v3.js.map +1 -0
  101. package/dist/types/generated/saveCookie_v3.d.ts +16 -0
  102. package/dist/types/generated/saveCookie_v3.d.ts.map +1 -0
  103. package/dist/types/generated/saveCookie_v3.js +7 -0
  104. package/dist/types/generated/saveCookie_v3.js.map +1 -0
  105. package/dist/types/generated/screenshot_v3.d.ts +74 -0
  106. package/dist/types/generated/screenshot_v3.d.ts.map +1 -0
  107. package/dist/types/generated/screenshot_v3.js +7 -0
  108. package/dist/types/generated/screenshot_v3.js.map +1 -0
  109. package/dist/types/generated/sourceIntegration_v3.d.ts +30 -0
  110. package/dist/types/generated/sourceIntegration_v3.d.ts.map +1 -0
  111. package/dist/types/generated/sourceIntegration_v3.js +7 -0
  112. package/dist/types/generated/sourceIntegration_v3.js.map +1 -0
  113. package/dist/types/generated/spec_v3.d.ts +159 -0
  114. package/dist/types/generated/spec_v3.d.ts.map +1 -0
  115. package/dist/types/generated/spec_v3.js +7 -0
  116. package/dist/types/generated/spec_v3.js.map +1 -0
  117. package/dist/types/generated/step_v3.d.ts +1270 -0
  118. package/dist/types/generated/step_v3.d.ts.map +1 -0
  119. package/dist/types/generated/step_v3.js +7 -0
  120. package/dist/types/generated/step_v3.js.map +1 -0
  121. package/dist/types/generated/stopRecord_v3.d.ts +9 -0
  122. package/dist/types/generated/stopRecord_v3.d.ts.map +1 -0
  123. package/dist/types/generated/stopRecord_v3.js +7 -0
  124. package/dist/types/generated/stopRecord_v3.js.map +1 -0
  125. package/dist/types/generated/test_v3.d.ts +2915 -0
  126. package/dist/types/generated/test_v3.d.ts.map +1 -0
  127. package/dist/types/generated/test_v3.js +7 -0
  128. package/dist/types/generated/test_v3.js.map +1 -0
  129. package/dist/types/generated/type_v3.d.ts +54 -0
  130. package/dist/types/generated/type_v3.d.ts.map +1 -0
  131. package/dist/types/generated/type_v3.js +7 -0
  132. package/dist/types/generated/type_v3.js.map +1 -0
  133. package/dist/types/generated/wait_v3.d.ts +12 -0
  134. package/dist/types/generated/wait_v3.d.ts.map +1 -0
  135. package/dist/types/generated/wait_v3.js +7 -0
  136. package/dist/types/generated/wait_v3.js.map +1 -0
  137. package/dist/validate.d.ts +41 -0
  138. package/dist/validate.d.ts.map +1 -0
  139. package/dist/validate.js +557 -0
  140. package/dist/validate.js.map +1 -0
  141. package/package.json +60 -36
  142. package/plans/plan-typescriptMigration.prompt.md +25 -0
  143. package/scripts/check-coverage-ratchet.cjs +118 -0
  144. package/scripts/createCjsWrapper.js +25 -0
  145. package/scripts/generateTypes.cjs +54 -0
  146. package/src/detectTests.ts +616 -0
  147. package/src/index.ts +3 -0
  148. package/src/schemas/build/arazzo_v2.schema.json +41 -0
  149. package/src/schemas/build/checkLink_v2.schema.json +1 -1
  150. package/src/schemas/build/checkLink_v3.schema.json +1 -1
  151. package/src/schemas/build/checkLink_v3.schema.yaml +83 -0
  152. package/src/schemas/build/click_v3.schema.json +1 -1
  153. package/src/schemas/build/config_v2.schema.json +14 -14
  154. package/src/schemas/build/config_v3.schema.json +6 -6
  155. package/src/schemas/build/context_v2.schema.json +1 -1
  156. package/src/schemas/build/context_v3.schema.json +1 -1
  157. package/src/schemas/build/dragAndDrop_v3.schema.json +1 -1
  158. package/src/schemas/build/find_v2.schema.json +3 -3
  159. package/src/schemas/build/find_v3.schema.json +4 -4
  160. package/src/schemas/build/goTo_v2.schema.json +1 -1
  161. package/src/schemas/build/goTo_v3.schema.json +1 -1
  162. package/src/schemas/build/httpRequest_v2.schema.json +2 -2
  163. package/src/schemas/build/httpRequest_v3.schema.json +3 -3
  164. package/src/schemas/build/loadCookie_v3.schema.json +1 -1
  165. package/src/schemas/build/loadVariables_v3.schema.json +1 -1
  166. package/src/schemas/build/moveTo_v2.schema.json +1 -1
  167. package/src/schemas/build/openApi_v2.schema.json +1 -1
  168. package/src/schemas/build/openApi_v3.schema.json +1 -1
  169. package/src/schemas/build/record_v3.schema.json +1 -1
  170. package/src/schemas/build/report_v3.schema.json +5 -5
  171. package/src/schemas/build/resolvedTests_v3.schema.json +3 -3
  172. package/src/schemas/build/runCode_v2.schema.json +1 -1
  173. package/src/schemas/build/runCode_v3.schema.json +1 -1
  174. package/src/schemas/build/runShell_v2.schema.json +1 -1
  175. package/src/schemas/build/runShell_v3.schema.json +1 -1
  176. package/src/schemas/build/saveCookie_v3.schema.json +1 -1
  177. package/src/schemas/build/saveScreenshot_v2.schema.json +1 -1
  178. package/src/schemas/build/screenshot_v3.schema.json +2 -2
  179. package/src/schemas/build/setVariables_v2.schema.json +1 -1
  180. package/src/schemas/build/sourceIntegration_v3.schema.json +1 -1
  181. package/src/schemas/build/spec_v2.schema.json +4 -4
  182. package/src/schemas/build/spec_v3.schema.json +4 -4
  183. package/src/schemas/build/startRecording_v2.schema.json +1 -1
  184. package/src/schemas/build/step_v3.schema.json +38 -38
  185. package/src/schemas/build/stopRecord_v3.schema.json +1 -1
  186. package/src/schemas/build/stopRecording_v2.schema.json +1 -1
  187. package/src/schemas/build/terminateScope_v3.schema.json +48 -0
  188. package/src/schemas/build/test_v2.schema.json +15 -15
  189. package/src/schemas/build/test_v3.schema.json +6 -6
  190. package/src/schemas/build/typeKeys_v2.schema.json +1 -1
  191. package/src/schemas/build/type_v3.schema.json +1 -1
  192. package/src/schemas/build/wait_v2.schema.json +1 -1
  193. package/src/schemas/build/wait_v3.schema.json +1 -1
  194. package/src/schemas/{dereferenceSchemas.js → dereferenceSchemas.cjs} +206 -206
  195. package/src/schemas/index.ts +6 -0
  196. package/src/schemas/output_schemas/endRecord_v3.schema.json +13 -13
  197. package/src/schemas/src_schemas/checkLink_v2.schema.json +65 -65
  198. package/src/schemas/src_schemas/checkLink_v3.schema.json +90 -90
  199. package/src/schemas/src_schemas/click_v3.schema.json +143 -143
  200. package/src/schemas/src_schemas/config_v2.schema.json +929 -929
  201. package/src/schemas/src_schemas/config_v3.schema.json +633 -633
  202. package/src/schemas/src_schemas/context_v2.schema.json +108 -108
  203. package/src/schemas/src_schemas/context_v3.schema.json +202 -202
  204. package/src/schemas/src_schemas/dragAndDrop_v3.schema.json +184 -184
  205. package/src/schemas/src_schemas/find_v2.schema.json +155 -155
  206. package/src/schemas/src_schemas/find_v3.schema.json +209 -209
  207. package/src/schemas/src_schemas/goTo_v2.schema.json +57 -57
  208. package/src/schemas/src_schemas/goTo_v3.schema.json +232 -232
  209. package/src/schemas/src_schemas/httpRequest_v2.schema.json +284 -284
  210. package/src/schemas/src_schemas/httpRequest_v3.schema.json +402 -402
  211. package/src/schemas/src_schemas/loadCookie_v3.schema.json +113 -113
  212. package/src/schemas/src_schemas/loadVariables_v3.schema.json +8 -8
  213. package/src/schemas/src_schemas/openApi_v2.schema.json +64 -64
  214. package/src/schemas/src_schemas/openApi_v3.schema.json +160 -160
  215. package/src/schemas/src_schemas/record_v3.schema.json +68 -68
  216. package/src/schemas/src_schemas/report_v3.schema.json +51 -51
  217. package/src/schemas/src_schemas/resolvedTests_v3.schema.json +236 -236
  218. package/src/schemas/src_schemas/runCode_v2.schema.json +181 -181
  219. package/src/schemas/src_schemas/runCode_v3.schema.json +136 -136
  220. package/src/schemas/src_schemas/runShell_v2.schema.json +166 -166
  221. package/src/schemas/src_schemas/runShell_v3.schema.json +154 -154
  222. package/src/schemas/src_schemas/saveCookie_v3.schema.json +124 -124
  223. package/src/schemas/src_schemas/saveScreenshot_v2.schema.json +129 -129
  224. package/src/schemas/src_schemas/screenshot_v3.schema.json +248 -248
  225. package/src/schemas/src_schemas/setVariables_v2.schema.json +37 -37
  226. package/src/schemas/src_schemas/sourceIntegration_v3.schema.json +45 -45
  227. package/src/schemas/src_schemas/spec_v2.schema.json +175 -175
  228. package/src/schemas/src_schemas/spec_v3.schema.json +211 -211
  229. package/src/schemas/src_schemas/startRecording_v2.schema.json +54 -54
  230. package/src/schemas/src_schemas/step_v3.schema.json +632 -632
  231. package/src/schemas/src_schemas/stopRecord_v3.schema.json +13 -13
  232. package/src/schemas/src_schemas/stopRecording_v2.schema.json +31 -31
  233. package/src/schemas/src_schemas/test_v2.schema.json +200 -200
  234. package/src/schemas/src_schemas/test_v3.schema.json +268 -268
  235. package/src/schemas/src_schemas/typeKeys_v2.schema.json +63 -63
  236. package/src/schemas/src_schemas/type_v3.schema.json +118 -118
  237. package/src/schemas/src_schemas/wait_v3.schema.json +35 -35
  238. package/src/types/generated/checkLink_v3.ts +29 -0
  239. package/src/types/generated/click_v3.ts +17 -0
  240. package/src/types/generated/config_v3.ts +405 -0
  241. package/src/types/generated/context_v3.ts +112 -0
  242. package/src/types/generated/dragAndDrop_v3.ts +39 -0
  243. package/src/types/generated/endRecord_v3.ts +10 -0
  244. package/src/types/generated/find_v3.ts +17 -0
  245. package/src/types/generated/goTo_v3.ts +48 -0
  246. package/src/types/generated/httpRequest_v3.ts +17 -0
  247. package/src/types/generated/loadCookie_v3.ts +17 -0
  248. package/src/types/generated/loadVariables_v3.ts +10 -0
  249. package/src/types/generated/openApi_v3.ts +64 -0
  250. package/src/types/generated/record_v3.ts +34 -0
  251. package/src/types/generated/report_v3.ts +183 -0
  252. package/src/types/generated/resolvedTests_v3.ts +585 -0
  253. package/src/types/generated/runCode_v3.ts +59 -0
  254. package/src/types/generated/runShell_v3.ts +58 -0
  255. package/src/types/generated/saveCookie_v3.ts +17 -0
  256. package/src/types/generated/screenshot_v3.ts +76 -0
  257. package/src/types/generated/sourceIntegration_v3.ts +31 -0
  258. package/src/types/generated/spec_v3.ts +166 -0
  259. package/src/types/generated/step_v3.ts +1288 -0
  260. package/src/types/generated/stopRecord_v3.ts +10 -0
  261. package/src/types/generated/test_v3.ts +3048 -0
  262. package/src/types/generated/type_v3.ts +56 -0
  263. package/src/types/generated/wait_v3.ts +13 -0
  264. package/src/{validate.js → validate.ts} +627 -587
  265. package/tsconfig.json +22 -0
  266. package/src/files.js +0 -84
  267. package/src/index.js +0 -12
  268. package/src/resolvePaths.js +0 -252
  269. package/src/schemas/index.js +0 -6
package/AGENTS.md CHANGED
@@ -1,285 +1,332 @@
1
- # Doc Detective Common - AI Coding Agent Guide
2
-
3
- ## Project Overview
4
-
5
- **doc-detective-common** is a shared utilities library for the Doc Detective test automation ecosystem. It provides:
6
- - JSON Schema validation with AJV (50+ schemas for test specifications, configs, steps)
7
- - Automatic schema transformation between versions (v2 → v3)
8
- - Path resolution utilities (relative to absolute conversion)
9
- - File reading with JSON/YAML parsing (local and remote URLs)
10
-
11
- This is a dependency package, not a standalone application. Changes here affect downstream packages.
12
-
13
- ## Architecture
14
-
15
- ### Schema System (Core Component)
16
-
17
- **Three-stage schema pipeline:**
18
-
19
- 1. **Source schemas** (`src/schemas/src_schemas/*.json`) - Hand-maintained with `$ref` pointers
20
- 2. **Build schemas** (`src/schemas/build/`) - References resolved to absolute paths
21
- 3. **Output schemas** (`src/schemas/output_schemas/`) - Fully dereferenced, ready for distribution
22
-
23
- **Build process:** Run `npm run build` which executes `dereferenceSchemas.js`:
24
- - Updates `$ref` paths to absolute file paths
25
- - Dereferences all references using `@apidevtools/json-schema-ref-parser`
26
- - Removes `$id` properties
27
- - Generates `schemas.json` (all schemas as single object)
28
- - Publishes v3 schemas to `dist/schemas/` for external consumption
29
-
30
- **Schema versioning:**
31
- - v2 schemas: Legacy, supported via `compatibleSchemas` transformation map
32
- - v3 schemas: Current version with new naming (e.g., `screenshot_v3`, `step_v3`)
33
- - All schemas **must** include `examples` array (validated in tests)
34
-
35
- ### Validation System
36
-
37
- **Key feature:** Automatic backward compatibility transformation
38
-
39
- When `validate()` is called:
40
- 1. Validates against target schema (e.g., `step_v3`)
41
- 2. If validation fails, checks `compatibleSchemas` map for older versions
42
- 3. Validates against each compatible schema (e.g., `checkLink_v2`, `find_v2`)
43
- 4. On match, calls `transformToSchemaKey()` to upgrade object structure
44
- 5. Revalidates transformed object against target schema
45
-
46
- **Important transformations in `validate.js`:**
47
- - `step_v3` accepts 12 different v2 action schemas (`checkLink_v2`, `find_v2`, etc.)
48
- - `config_v3` ← `config_v2`: Restructures nested `runTests` object
49
- - `context_v3` ← `context_v2`: Changes `app` → `browsers` structure
50
- - Property renames: `typeKeys.delay` → `type.inputDelay`, `maxVariation` (0-100) → (0-1), etc.
51
-
52
- **AJV configuration** (in `validate.js`):
53
- - `coerceTypes: true` - Auto-converts strings to numbers, etc.
54
- - `useDefaults: true` - Applies default values from schema
55
- - Dynamic defaults: `uuid` generates unique IDs for `stepId`, `configId`
56
- - Custom errors via `ajv-errors`
57
- - Formats via `ajv-formats`, keywords via `ajv-keywords`
58
-
59
- ### Path Resolution (`resolvePaths.js`)
60
-
61
- **Resolves relative paths to absolute based on:**
62
- - `config.relativePathBase`: `"file"` (relative to file location) or `"cwd"` (relative to working directory)
63
- - Object type: `config` or `spec` (different path properties)
64
-
65
- **Properties resolved:**
66
- - Config: `input`, `output`, `loadVariables`, `beforeAny`, `afterAll`, `mediaDirectory`, etc.
67
- - Spec: `file`, `path`, `directory`, `before`, `after`, `workingDirectory`, etc.
68
- - Skips: HTTP(S) URLs, already-absolute paths, user data properties (e.g., `requestData`)
69
-
70
- **Recursive handling:**
71
- - Processes nested objects and arrays
72
- - Special case: `path` resolved relative to `directory` if `directory` is absolute
73
-
74
- ### File Reading (`files.js`)
75
-
76
- **Detects remote vs. local:**
77
- - Remote: Uses `axios` for `http://` or `https://` URLs
78
- - Local: Uses `fs.promises.readFile`
79
-
80
- **Format detection by extension:**
81
- - `.json` → JSON.parse()
82
- - `.yaml`/`.yml` → YAML.parse()
83
- - Other → raw string
84
- - Parse errors → returns raw content (graceful degradation)
85
-
86
- ## Development Workflow
87
-
88
- ### Adding or Modifying Schemas
89
-
90
- 1. Edit source schema in `src/schemas/src_schemas/`
91
- 2. Add/update `examples` array (required for tests)
92
- 3. If adding new file, add to `files` array in `dereferenceSchemas.js`
93
- 4. Run `npm run build` (runs `dereferenceSchemas` + tests)
94
- 5. If creating v3 schema, add to published list in `dereferenceSchemas.js` (line ~130)
95
-
96
- ### Schema Compatibility
97
-
98
- When creating new schema version (e.g., v4):
99
- 1. Update `compatibleSchemas` map in `validate.js`
100
- 2. Add transformation logic in `transformToSchemaKey()` function
101
- 3. Handle all property renames, restructuring, and value conversions
102
- 4. Test with examples from old schema versions
103
-
104
- ### Testing
105
-
106
- **Test structure (Mocha + Chai):**
107
- - `test/schema.test.js`: Validates all schema examples (auto-generated from schemas)
108
- - `test/files.test.js`: Unit tests for `readFile()` with Sinon stubs
109
-
110
- **Run tests:** `npm test` (or `mocha`)
111
-
112
- **Example pattern:**
113
- ```javascript
114
- const result = validate({ schemaKey: "step_v3", object: example });
115
- assert.ok(result.valid, `Validation failed: ${result.errors}`);
116
- ```
117
-
118
- ### Version Management & CI/CD Workflows
119
-
120
- #### Auto Dev Release (`.github/workflows/auto-dev-release.yml`)
121
-
122
- **Triggers:** Every push to `main` branch (+ manual via `workflow_dispatch`)
123
-
124
- **Smart skip logic:**
125
- - Skip if commit message contains `[skip ci]` or `Release`
126
- - Skip if only documentation files changed (`.md`, `.txt`, `.yml`, `.yaml`, `.github/`)
127
- - Always runs on manual trigger
128
-
129
- **Version generation:**
130
- 1. Extract base version from `package.json` (e.g., `3.1.0`)
131
- 2. Query npm for latest dev version: `npm view doc-detective-common@dev version`
132
- 3. If exists and matches base: increment dev number (`.dev.2` → `.dev.3`)
133
- 4. If none exists: start with `.dev.1`
134
- 5. Update `package.json` with new version
135
-
136
- **Pipeline steps:**
137
- 1. Validate `package.json` (existence, valid JSON, required fields)
138
- 2. Install dependencies with `npm ci`
139
- 3. Run `npm test` (must pass)
140
- 4. Run `npm run build` (builds schemas + post-build tests)
141
- 5. Update version in `package.json`
142
- 6. Commit with `[skip ci]` to prevent infinite loop
143
- 7. Create and push git tag (e.g., `v3.1.0-dev.2`)
144
- 8. Publish to npm with `dev` tag
145
-
146
- **Key details:**
147
- - Uses `DD_DEP_UPDATE_TOKEN` secret for git push permissions
148
- - Uses `NPM_TOKEN` secret for npm publish
149
- - Timeout: 5 minutes
150
- - Runs on: `ubuntu-latest`, Node 18
151
-
152
- **Install dev releases:** `npm install doc-detective-common@dev`
153
-
154
- #### Test & Publish (`.github/workflows/npm-test.yml`)
155
-
156
- **Triggers:** Push to main, PRs, GitHub releases, manual dispatch
157
-
158
- **Multi-platform matrix testing:**
159
- - OS: `ubuntu-latest`, `windows-latest`, `macos-latest`
160
- - Node: `18`, `20`, `22`, `24`
161
- - Total: 12 test combinations
162
- - Runs `npm run build` which triggers `postbuild` → `npm test`
163
-
164
- **Release pipeline (on GitHub release published):**
165
-
166
- 1. **Test job:** Run full matrix tests
167
- 2. **Threat assessment:** ReversingLabs security scan
168
- - Creates npm pack tarball
169
- - Uploads to RL Portal (`Trial/OSS-MannySilva`)
170
- - Generates security report artifact
171
- - Must pass before publish
172
- 3. **Publish to npm:**
173
- - Publishes to npm (stable, no tag)
174
- - Uses `npm_token` secret
175
- 4. **Update downstream:**
176
- - Triggers `doc-detective/resolver` repository dispatch
177
- - Triggers `doc-detective.github.io` repository dispatch
178
- - Passes new version in payload
179
-
180
- **Repository dispatch pattern:**
181
- ```bash
182
- curl -X POST https://api.github.com/repos/doc-detective/resolver/dispatches \
183
- -d '{"event_type": "update-common-package-event", "client_payload": {"version": "3.1.0"}}'
184
- ```
185
-
186
- **Required secrets:**
187
- - `RLPORTAL_ACCESS_TOKEN`: ReversingLabs security scanning
188
- - `npm_token`: NPM publishing
189
- - `DD_DEP_UPDATE_TOKEN`: Cross-repo dispatches
190
-
191
- #### Release Strategy Summary
192
-
193
- - **Dev releases** (`3.1.0-dev.X`): Automatic on every code commit to main
194
- - **Stable releases** (`3.1.0`): Manual via GitHub releases UI
195
- - **Cross-repo updates**: Automatic dispatch to dependent packages on stable release
196
- - **Security scanning**: Required for all stable releases (threat assessment)
197
-
198
- ## Important Patterns
199
-
200
- ### Error Handling
201
-
202
- - `validate()` returns `{ valid, errors, object }` - never throws
203
- - `transformToSchemaKey()` throws on incompatible schemas or invalid results
204
- - `readFile()` returns `null` on errors, logs warnings to console
205
- - `resolvePaths()` throws on invalid object types or missing nested object types
206
-
207
- ### Object Cloning
208
-
209
- Always clone before validation to avoid mutations:
210
- ```javascript
211
- validationObject = JSON.parse(JSON.stringify(object));
212
- ```
213
-
214
- ### Regular Expression Escaping
215
-
216
- Use `escapeRegExp()` helper when converting user strings to regex patterns (see `transformToSchemaKey()` for fileTypes transformation).
217
-
218
- ### Schema References
219
-
220
- - In source schemas: Use relative paths like `"$ref": "context_v3.schema.json#/properties/example"`
221
- - Build process converts these to absolute file system paths
222
- - Output schemas have all references fully inlined (dereferenced)
223
-
224
- ## Common Tasks
225
-
226
- **Add new schema property:**
227
- 1. Edit `src/schemas/src_schemas/<schema>.json`
228
- 2. Add to relevant `examples` array
229
- 3. If path property, add to `configPaths` or `specPaths` in `resolvePaths.js`
230
- 4. Run `npm run build`
231
-
232
- **Add new step type:**
233
- 1. Create schema in `src_schemas/` (e.g., `newAction_v3.schema.json`)
234
- 2. Add to `files` array in `dereferenceSchemas.js`
235
- 3. Reference in `step_v3.schema.json` oneOf
236
- 4. Add transformation logic if upgrading from v2
237
- 5. Update `compatibleSchemas` if needed
238
-
239
- **Debug validation errors:**
240
- - Check `result.errors` for detailed AJV error messages
241
- - Error format: `${instancePath} ${message} (${JSON.stringify(params)})`
242
- - Common issues: Missing required properties, incorrect types, additional properties when not allowed
243
-
244
- **Trigger dev release:**
245
- - Just push to main branch (automatic)
246
- - Or add `[skip ci]` to commit message to prevent release
247
- - Manual trigger: GitHub Actions → Auto Dev Release → Run workflow
248
-
249
- **Create stable release:**
250
- 1. Go to GitHub repository Releases
251
- 2. Click "Draft a new release"
252
- 3. Create new tag (e.g., `v3.2.0`)
253
- 4. Publish release
254
- 5. Workflow automatically:
255
- - Runs full test matrix
256
- - Performs security scan
257
- - Publishes to npm
258
- - Updates downstream packages
259
-
260
- ## External Dependencies
261
-
262
- **Runtime:**
263
- - `ajv` (v8): JSON Schema validator with strict mode disabled, coercion enabled
264
- - `axios`: HTTP client for remote file reading
265
- - `yaml`: YAML parser for config files
266
- - `uuid`: UUID generation for default IDs
267
- - `@apidevtools/json-schema-ref-parser`: Dereferences schemas
268
-
269
- **Testing:**
270
- - `mocha`: Test runner
271
- - `chai`: Assertions (uses dynamic import for ESM compatibility)
272
- - `sinon`: Mocking/stubbing
273
-
274
- ## Anti-Patterns to Avoid
275
-
276
- - Don't edit schemas in `build/` or `output_schemas/` (regenerated on build)
277
- - Don't skip `examples` in schemas (breaks tests)
278
- - ❌ Don't modify `schemas.json` directly (generated file)
279
- - Don't add schemas without updating `files` array in `dereferenceSchemas.js`
280
- - Don't assume validation mutates objects (it returns new validated object)
281
- - Don't forget to clone objects before validation if original needs preservation
282
- - Don't publish manually to npm (use GitHub releases for stable, auto-dev-release for dev)
283
- - Don't commit version bumps manually (workflows handle this automatically)
284
- - Don't modify `package.json` version in PRs (causes conflicts with auto-dev-release)
285
- - ❌ Don't skip security scanning for releases (threat-assessment job required)
1
+ # Doc Detective Common - AI Coding Agent Guide
2
+
3
+ ## Project Overview
4
+
5
+ **doc-detective-common** is a shared utilities library for the Doc Detective test automation ecosystem. It provides:
6
+ - JSON Schema validation with AJV (50+ schemas for test specifications, configs, steps)
7
+ - Automatic schema transformation between versions (v2 → v3)
8
+ - Path resolution utilities (relative to absolute conversion)
9
+ - File reading with JSON/YAML parsing (local and remote URLs)
10
+
11
+ This is a dependency package, not a standalone application. Changes here affect downstream packages.
12
+
13
+ ## Architecture
14
+
15
+ ### Schema System (Core Component)
16
+
17
+ **Three-stage schema pipeline:**
18
+
19
+ 1. **Source schemas** (`src/schemas/src_schemas/*.json`) - Hand-maintained with `$ref` pointers
20
+ 2. **Build schemas** (`src/schemas/build/`) - References resolved to absolute paths
21
+ 3. **Output schemas** (`src/schemas/output_schemas/`) - Fully dereferenced, ready for distribution
22
+
23
+ **Build process:** Run `npm run build` which executes `dereferenceSchemas.js`:
24
+ - Updates `$ref` paths to absolute file paths
25
+ - Dereferences all references using `@apidevtools/json-schema-ref-parser`
26
+ - Removes `$id` properties
27
+ - Generates `schemas.json` (all schemas as single object)
28
+ - Publishes v3 schemas to `dist/schemas/` for external consumption
29
+
30
+ **Schema versioning:**
31
+ - v2 schemas: Legacy, supported via `compatibleSchemas` transformation map
32
+ - v3 schemas: Current version with new naming (e.g., `screenshot_v3`, `step_v3`)
33
+ - All schemas **must** include `examples` array (validated in tests)
34
+
35
+ ### Validation System
36
+
37
+ **Key feature:** Automatic backward compatibility transformation
38
+
39
+ When `validate()` is called:
40
+ 1. Validates against target schema (e.g., `step_v3`)
41
+ 2. If validation fails, checks `compatibleSchemas` map for older versions
42
+ 3. Validates against each compatible schema (e.g., `checkLink_v2`, `find_v2`)
43
+ 4. On match, calls `transformToSchemaKey()` to upgrade object structure
44
+ 5. Revalidates transformed object against target schema
45
+
46
+ **Important transformations in `validate.js`:**
47
+ - `step_v3` accepts 12 different v2 action schemas (`checkLink_v2`, `find_v2`, etc.)
48
+ - `config_v3` ← `config_v2`: Restructures nested `runTests` object
49
+ - `context_v3` ← `context_v2`: Changes `app` → `browsers` structure
50
+ - Property renames: `typeKeys.delay` → `type.inputDelay`, `maxVariation` (0-100) → (0-1), etc.
51
+
52
+ **AJV configuration** (in `validate.js`):
53
+ - `coerceTypes: true` - Auto-converts strings to numbers, etc.
54
+ - `useDefaults: true` - Applies default values from schema
55
+ - Dynamic defaults: `uuid` generates unique IDs for `stepId`, `configId`
56
+ - Custom errors via `ajv-errors`
57
+ - Formats via `ajv-formats`, keywords via `ajv-keywords`
58
+
59
+ ### Path Resolution (`resolvePaths.js`)
60
+
61
+ **Resolves relative paths to absolute based on:**
62
+ - `config.relativePathBase`: `"file"` (relative to file location) or `"cwd"` (relative to working directory)
63
+ - Object type: `config` or `spec` (different path properties)
64
+
65
+ **Properties resolved:**
66
+ - Config: `input`, `output`, `loadVariables`, `beforeAny`, `afterAll`, `mediaDirectory`, etc.
67
+ - Spec: `file`, `path`, `directory`, `before`, `after`, `workingDirectory`, etc.
68
+ - Skips: HTTP(S) URLs, already-absolute paths, user data properties (e.g., `requestData`)
69
+
70
+ **Recursive handling:**
71
+ - Processes nested objects and arrays
72
+ - Special case: `path` resolved relative to `directory` if `directory` is absolute
73
+
74
+ ### File Reading (`files.js`)
75
+
76
+ **Detects remote vs. local:**
77
+ - Remote: Uses `axios` for `http://` or `https://` URLs
78
+ - Local: Uses `fs.promises.readFile`
79
+
80
+ **Format detection by extension:**
81
+ - `.json` → JSON.parse()
82
+ - `.yaml`/`.yml` → YAML.parse()
83
+ - Other → raw string
84
+ - Parse errors → returns raw content (graceful degradation)
85
+
86
+ ## Development Workflow
87
+
88
+ ### Adding or Modifying Schemas
89
+
90
+ 1. Edit source schema in `src/schemas/src_schemas/`
91
+ 2. Add/update `examples` array (required for tests)
92
+ 3. If adding new file, add to `files` array in `dereferenceSchemas.js`
93
+ 4. Run `npm run build` (runs `dereferenceSchemas` + tests)
94
+ 5. If creating v3 schema, add to published list in `dereferenceSchemas.js` (line ~130)
95
+
96
+ ### Schema Compatibility
97
+
98
+ When creating new schema version (e.g., v4):
99
+ 1. Update `compatibleSchemas` map in `validate.js`
100
+ 2. Add transformation logic in `transformToSchemaKey()` function
101
+ 3. Handle all property renames, restructuring, and value conversions
102
+ 4. Test with examples from old schema versions
103
+
104
+ ### Testing
105
+
106
+ **Test structure (Mocha + Chai):**
107
+ - `test/schema.test.js`: Validates all schema examples (auto-generated from schemas)
108
+ - `test/files.test.js`: Unit tests for `readFile()` with Sinon stubs
109
+ - `test/validate.test.js`: Tests for `validate()` and `transformToSchemaKey()`
110
+ - `test/resolvePaths.test.js`: Tests for path resolution
111
+
112
+ **Run tests:** `npm test` (or `mocha`)
113
+
114
+ **Example pattern:**
115
+ ```javascript
116
+ const result = validate({ schemaKey: "step_v3", object: example });
117
+ assert.ok(result.valid, `Validation failed: ${result.errors}`);
118
+ ```
119
+
120
+ ### Testing Requirements (CRITICAL)
121
+
122
+ **TDD is mandatory for this project.** All code changes must follow test-driven development:
123
+
124
+ 1. **Write tests first** - before any implementation
125
+ 2. **Run tests** - verify they fail (red)
126
+ 3. **Write implementation** - make tests pass
127
+ 4. **Run tests** - verify they pass (green)
128
+ 5. **Check coverage** - must not decrease
129
+
130
+ **Coverage enforcement:**
131
+
132
+ ```bash
133
+ # Run tests with coverage
134
+ npm run test:coverage
135
+
136
+ # Verify coverage baseline (CI enforces this)
137
+ npm run test:coverage:ratchet
138
+
139
+ # Generate HTML report for detailed analysis
140
+ npm run test:coverage:html
141
+ ```
142
+
143
+ **Current coverage thresholds (enforced by CI):**
144
+
145
+ | Metric | Threshold |
146
+ |--------|-----------|
147
+ | Lines | 100% |
148
+ | Statements | 100% |
149
+ | Functions | 100% |
150
+ | Branches | 100% |
151
+
152
+ **Coverage ratchet:** Thresholds in `coverage-thresholds.json` can only increase. CI fails if coverage decreases.
153
+
154
+ **Test file mapping:**
155
+
156
+ | Source | Test File |
157
+ |--------|-----------|
158
+ | `src/validate.js` | `test/validate.test.js` |
159
+ | `src/resolvePaths.js` | `test/resolvePaths.test.js` |
160
+ | `src/files.js` | `test/files.test.js` |
161
+ | Schema examples | `test/schema.test.js` |
162
+
163
+ **AI Tooling:** See `.claude/skills/tdd-coverage/SKILL.md` for detailed TDD workflow.
164
+
165
+ ### Version Management & CI/CD Workflows
166
+
167
+ #### Auto Dev Release (`.github/workflows/auto-dev-release.yml`)
168
+
169
+ **Triggers:** Every push to `main` branch (+ manual via `workflow_dispatch`)
170
+
171
+ **Smart skip logic:**
172
+ - Skip if commit message contains `[skip ci]` or `Release`
173
+ - Skip if only documentation files changed (`.md`, `.txt`, `.yml`, `.yaml`, `.github/`)
174
+ - Always runs on manual trigger
175
+
176
+ **Version generation:**
177
+ 1. Extract base version from `package.json` (e.g., `3.1.0`)
178
+ 2. Query npm for latest dev version: `npm view doc-detective-common@dev version`
179
+ 3. If exists and matches base: increment dev number (`.dev.2` → `.dev.3`)
180
+ 4. If none exists: start with `.dev.1`
181
+ 5. Update `package.json` with new version
182
+
183
+ **Pipeline steps:**
184
+ 1. Validate `package.json` (existence, valid JSON, required fields)
185
+ 2. Install dependencies with `npm ci`
186
+ 3. Run `npm test` (must pass)
187
+ 4. Run `npm run build` (builds schemas + post-build tests)
188
+ 5. Update version in `package.json`
189
+ 6. Commit with `[skip ci]` to prevent infinite loop
190
+ 7. Create and push git tag (e.g., `v3.1.0-dev.2`)
191
+ 8. Publish to npm with `dev` tag
192
+
193
+ **Key details:**
194
+ - Uses `DD_DEP_UPDATE_TOKEN` secret for git push permissions
195
+ - Uses `NPM_TOKEN` secret for npm publish
196
+ - Timeout: 5 minutes
197
+ - Runs on: `ubuntu-latest`, Node 18
198
+
199
+ **Install dev releases:** `npm install doc-detective-common@dev`
200
+
201
+ #### Test & Publish (`.github/workflows/npm-test.yml`)
202
+
203
+ **Triggers:** Push to main, PRs, GitHub releases, manual dispatch
204
+
205
+ **Multi-platform matrix testing:**
206
+ - OS: `ubuntu-latest`, `windows-latest`, `macos-latest`
207
+ - Node: `18`, `20`, `22`, `24`
208
+ - Total: 12 test combinations
209
+ - Runs `npm run build` which triggers `postbuild` → `npm test`
210
+
211
+ **Release pipeline (on GitHub release published):**
212
+
213
+ 1. **Test job:** Run full matrix tests
214
+ 2. **Threat assessment:** ReversingLabs security scan
215
+ - Creates npm pack tarball
216
+ - Uploads to RL Portal (`Trial/OSS-MannySilva`)
217
+ - Generates security report artifact
218
+ - Must pass before publish
219
+ 3. **Publish to npm:**
220
+ - Publishes to npm (stable, no tag)
221
+ - Uses `npm_token` secret
222
+ 4. **Update downstream:**
223
+ - Triggers `doc-detective/resolver` repository dispatch
224
+ - Triggers `doc-detective.github.io` repository dispatch
225
+ - Passes new version in payload
226
+
227
+ **Repository dispatch pattern:**
228
+ ```bash
229
+ curl -X POST https://api.github.com/repos/doc-detective/resolver/dispatches \
230
+ -d '{"event_type": "update-common-package-event", "client_payload": {"version": "3.1.0"}}'
231
+ ```
232
+
233
+ **Required secrets:**
234
+ - `RLPORTAL_ACCESS_TOKEN`: ReversingLabs security scanning
235
+ - `npm_token`: NPM publishing
236
+ - `DD_DEP_UPDATE_TOKEN`: Cross-repo dispatches
237
+
238
+ #### Release Strategy Summary
239
+
240
+ - **Dev releases** (`3.1.0-dev.X`): Automatic on every code commit to main
241
+ - **Stable releases** (`3.1.0`): Manual via GitHub releases UI
242
+ - **Cross-repo updates**: Automatic dispatch to dependent packages on stable release
243
+ - **Security scanning**: Required for all stable releases (threat assessment)
244
+
245
+ ## Important Patterns
246
+
247
+ ### Error Handling
248
+
249
+ - `validate()` returns `{ valid, errors, object }` - never throws
250
+ - `transformToSchemaKey()` throws on incompatible schemas or invalid results
251
+ - `readFile()` returns `null` on errors, logs warnings to console
252
+ - `resolvePaths()` throws on invalid object types or missing nested object types
253
+
254
+ ### Object Cloning
255
+
256
+ Always clone before validation to avoid mutations:
257
+ ```javascript
258
+ validationObject = JSON.parse(JSON.stringify(object));
259
+ ```
260
+
261
+ ### Regular Expression Escaping
262
+
263
+ Use `escapeRegExp()` helper when converting user strings to regex patterns (see `transformToSchemaKey()` for fileTypes transformation).
264
+
265
+ ### Schema References
266
+
267
+ - In source schemas: Use relative paths like `"$ref": "context_v3.schema.json#/properties/example"`
268
+ - Build process converts these to absolute file system paths
269
+ - Output schemas have all references fully inlined (dereferenced)
270
+
271
+ ## Common Tasks
272
+
273
+ **Add new schema property:**
274
+ 1. Edit `src/schemas/src_schemas/<schema>.json`
275
+ 2. Add to relevant `examples` array
276
+ 3. If path property, add to `configPaths` or `specPaths` in `resolvePaths.js`
277
+ 4. Run `npm run build`
278
+
279
+ **Add new step type:**
280
+ 1. Create schema in `src_schemas/` (e.g., `newAction_v3.schema.json`)
281
+ 2. Add to `files` array in `dereferenceSchemas.js`
282
+ 3. Reference in `step_v3.schema.json` oneOf
283
+ 4. Add transformation logic if upgrading from v2
284
+ 5. Update `compatibleSchemas` if needed
285
+
286
+ **Debug validation errors:**
287
+ - Check `result.errors` for detailed AJV error messages
288
+ - Error format: `${instancePath} ${message} (${JSON.stringify(params)})`
289
+ - Common issues: Missing required properties, incorrect types, additional properties when not allowed
290
+
291
+ **Trigger dev release:**
292
+ - Just push to main branch (automatic)
293
+ - Or add `[skip ci]` to commit message to prevent release
294
+ - Manual trigger: GitHub Actions → Auto Dev Release → Run workflow
295
+
296
+ **Create stable release:**
297
+ 1. Go to GitHub repository → Releases
298
+ 2. Click "Draft a new release"
299
+ 3. Create new tag (e.g., `v3.2.0`)
300
+ 4. Publish release
301
+ 5. Workflow automatically:
302
+ - Runs full test matrix
303
+ - Performs security scan
304
+ - Publishes to npm
305
+ - Updates downstream packages
306
+
307
+ ## External Dependencies
308
+
309
+ **Runtime:**
310
+ - `ajv` (v8): JSON Schema validator with strict mode disabled, coercion enabled
311
+ - `axios`: HTTP client for remote file reading
312
+ - `yaml`: YAML parser for config files
313
+ - `uuid`: UUID generation for default IDs
314
+ - `@apidevtools/json-schema-ref-parser`: Dereferences schemas
315
+
316
+ **Testing:**
317
+ - `mocha`: Test runner
318
+ - `chai`: Assertions (uses dynamic import for ESM compatibility)
319
+ - `sinon`: Mocking/stubbing
320
+
321
+ ## Anti-Patterns to Avoid
322
+
323
+ - ❌ Don't edit schemas in `build/` or `output_schemas/` (regenerated on build)
324
+ - ❌ Don't skip `examples` in schemas (breaks tests)
325
+ - ❌ Don't modify `schemas.json` directly (generated file)
326
+ - ❌ Don't add schemas without updating `files` array in `dereferenceSchemas.js`
327
+ - ❌ Don't assume validation mutates objects (it returns new validated object)
328
+ - ❌ Don't forget to clone objects before validation if original needs preservation
329
+ - ❌ Don't publish manually to npm (use GitHub releases for stable, auto-dev-release for dev)
330
+ - ❌ Don't commit version bumps manually (workflows handle this automatically)
331
+ - ❌ Don't modify `package.json` version in PRs (causes conflicts with auto-dev-release)
332
+ - ❌ Don't skip security scanning for releases (threat-assessment job required)