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.
- package/.c8rc.json +8 -0
- package/.claude/settings.local.json +11 -0
- package/.claude/skills/tdd-coverage/SKILL.md +161 -0
- package/AGENTS.md +332 -285
- package/CLAUDE.md +38 -0
- package/LICENSE +661 -661
- package/README.md +78 -48
- package/coverage-thresholds.json +8 -0
- package/dist/detectTests.d.ts +106 -0
- package/dist/detectTests.d.ts.map +1 -0
- package/dist/detectTests.js +530 -0
- package/dist/detectTests.js.map +1 -0
- package/dist/files.d.ts +16 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +123 -0
- package/dist/files.js.map +1 -0
- package/dist/index.cjs +122283 -0
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +4 -0
- package/dist/resolvePaths.d.ts +28 -0
- package/dist/resolvePaths.d.ts.map +1 -0
- package/dist/resolvePaths.js +236 -0
- package/dist/resolvePaths.js.map +1 -0
- package/dist/schemas/index.d.ts +5 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +3 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/schemas.json +121359 -0
- package/dist/types/generated/checkLink_v3.d.ts +27 -0
- package/dist/types/generated/checkLink_v3.d.ts.map +1 -0
- package/dist/types/generated/checkLink_v3.js +7 -0
- package/dist/types/generated/checkLink_v3.js.map +1 -0
- package/dist/types/generated/click_v3.d.ts +16 -0
- package/dist/types/generated/click_v3.d.ts.map +1 -0
- package/dist/types/generated/click_v3.js +7 -0
- package/dist/types/generated/click_v3.js.map +1 -0
- package/dist/types/generated/config_v3.d.ts +398 -0
- package/dist/types/generated/config_v3.d.ts.map +1 -0
- package/dist/types/generated/config_v3.js +7 -0
- package/dist/types/generated/config_v3.js.map +1 -0
- package/dist/types/generated/context_v3.d.ts +108 -0
- package/dist/types/generated/context_v3.d.ts.map +1 -0
- package/dist/types/generated/context_v3.js +7 -0
- package/dist/types/generated/context_v3.js.map +1 -0
- package/dist/types/generated/dragAndDrop_v3.d.ts +37 -0
- package/dist/types/generated/dragAndDrop_v3.d.ts.map +1 -0
- package/dist/types/generated/dragAndDrop_v3.js +7 -0
- package/dist/types/generated/dragAndDrop_v3.js.map +1 -0
- package/dist/types/generated/endRecord_v3.d.ts +9 -0
- package/dist/types/generated/endRecord_v3.d.ts.map +1 -0
- package/dist/types/generated/endRecord_v3.js +7 -0
- package/dist/types/generated/endRecord_v3.js.map +1 -0
- package/dist/types/generated/find_v3.d.ts +16 -0
- package/dist/types/generated/find_v3.d.ts.map +1 -0
- package/dist/types/generated/find_v3.js +7 -0
- package/dist/types/generated/find_v3.js.map +1 -0
- package/dist/types/generated/goTo_v3.d.ts +46 -0
- package/dist/types/generated/goTo_v3.d.ts.map +1 -0
- package/dist/types/generated/goTo_v3.js +7 -0
- package/dist/types/generated/goTo_v3.js.map +1 -0
- package/dist/types/generated/httpRequest_v3.d.ts +16 -0
- package/dist/types/generated/httpRequest_v3.d.ts.map +1 -0
- package/dist/types/generated/httpRequest_v3.js +7 -0
- package/dist/types/generated/httpRequest_v3.js.map +1 -0
- package/dist/types/generated/loadCookie_v3.d.ts +16 -0
- package/dist/types/generated/loadCookie_v3.d.ts.map +1 -0
- package/dist/types/generated/loadCookie_v3.js +7 -0
- package/dist/types/generated/loadCookie_v3.js.map +1 -0
- package/dist/types/generated/loadVariables_v3.d.ts +9 -0
- package/dist/types/generated/loadVariables_v3.d.ts.map +1 -0
- package/dist/types/generated/loadVariables_v3.js +7 -0
- package/dist/types/generated/loadVariables_v3.js.map +1 -0
- package/dist/types/generated/openApi_v3.d.ts +62 -0
- package/dist/types/generated/openApi_v3.d.ts.map +1 -0
- package/dist/types/generated/openApi_v3.js +7 -0
- package/dist/types/generated/openApi_v3.js.map +1 -0
- package/dist/types/generated/record_v3.d.ts +32 -0
- package/dist/types/generated/record_v3.d.ts.map +1 -0
- package/dist/types/generated/record_v3.js +7 -0
- package/dist/types/generated/record_v3.js.map +1 -0
- package/dist/types/generated/report_v3.d.ts +174 -0
- package/dist/types/generated/report_v3.d.ts.map +1 -0
- package/dist/types/generated/report_v3.js +7 -0
- package/dist/types/generated/report_v3.js.map +1 -0
- package/dist/types/generated/resolvedTests_v3.d.ts +571 -0
- package/dist/types/generated/resolvedTests_v3.d.ts.map +1 -0
- package/dist/types/generated/resolvedTests_v3.js +7 -0
- package/dist/types/generated/resolvedTests_v3.js.map +1 -0
- package/dist/types/generated/runCode_v3.d.ts +57 -0
- package/dist/types/generated/runCode_v3.d.ts.map +1 -0
- package/dist/types/generated/runCode_v3.js +7 -0
- package/dist/types/generated/runCode_v3.js.map +1 -0
- package/dist/types/generated/runShell_v3.d.ts +56 -0
- package/dist/types/generated/runShell_v3.d.ts.map +1 -0
- package/dist/types/generated/runShell_v3.js +7 -0
- package/dist/types/generated/runShell_v3.js.map +1 -0
- package/dist/types/generated/saveCookie_v3.d.ts +16 -0
- package/dist/types/generated/saveCookie_v3.d.ts.map +1 -0
- package/dist/types/generated/saveCookie_v3.js +7 -0
- package/dist/types/generated/saveCookie_v3.js.map +1 -0
- package/dist/types/generated/screenshot_v3.d.ts +74 -0
- package/dist/types/generated/screenshot_v3.d.ts.map +1 -0
- package/dist/types/generated/screenshot_v3.js +7 -0
- package/dist/types/generated/screenshot_v3.js.map +1 -0
- package/dist/types/generated/sourceIntegration_v3.d.ts +30 -0
- package/dist/types/generated/sourceIntegration_v3.d.ts.map +1 -0
- package/dist/types/generated/sourceIntegration_v3.js +7 -0
- package/dist/types/generated/sourceIntegration_v3.js.map +1 -0
- package/dist/types/generated/spec_v3.d.ts +159 -0
- package/dist/types/generated/spec_v3.d.ts.map +1 -0
- package/dist/types/generated/spec_v3.js +7 -0
- package/dist/types/generated/spec_v3.js.map +1 -0
- package/dist/types/generated/step_v3.d.ts +1270 -0
- package/dist/types/generated/step_v3.d.ts.map +1 -0
- package/dist/types/generated/step_v3.js +7 -0
- package/dist/types/generated/step_v3.js.map +1 -0
- package/dist/types/generated/stopRecord_v3.d.ts +9 -0
- package/dist/types/generated/stopRecord_v3.d.ts.map +1 -0
- package/dist/types/generated/stopRecord_v3.js +7 -0
- package/dist/types/generated/stopRecord_v3.js.map +1 -0
- package/dist/types/generated/test_v3.d.ts +2915 -0
- package/dist/types/generated/test_v3.d.ts.map +1 -0
- package/dist/types/generated/test_v3.js +7 -0
- package/dist/types/generated/test_v3.js.map +1 -0
- package/dist/types/generated/type_v3.d.ts +54 -0
- package/dist/types/generated/type_v3.d.ts.map +1 -0
- package/dist/types/generated/type_v3.js +7 -0
- package/dist/types/generated/type_v3.js.map +1 -0
- package/dist/types/generated/wait_v3.d.ts +12 -0
- package/dist/types/generated/wait_v3.d.ts.map +1 -0
- package/dist/types/generated/wait_v3.js +7 -0
- package/dist/types/generated/wait_v3.js.map +1 -0
- package/dist/validate.d.ts +41 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +557 -0
- package/dist/validate.js.map +1 -0
- package/package.json +60 -36
- package/plans/plan-typescriptMigration.prompt.md +25 -0
- package/scripts/check-coverage-ratchet.cjs +118 -0
- package/scripts/createCjsWrapper.js +25 -0
- package/scripts/generateTypes.cjs +54 -0
- package/src/detectTests.ts +616 -0
- package/src/index.ts +3 -0
- package/src/schemas/build/arazzo_v2.schema.json +41 -0
- package/src/schemas/build/checkLink_v2.schema.json +1 -1
- package/src/schemas/build/checkLink_v3.schema.json +1 -1
- package/src/schemas/build/checkLink_v3.schema.yaml +83 -0
- package/src/schemas/build/click_v3.schema.json +1 -1
- package/src/schemas/build/config_v2.schema.json +14 -14
- package/src/schemas/build/config_v3.schema.json +6 -6
- package/src/schemas/build/context_v2.schema.json +1 -1
- package/src/schemas/build/context_v3.schema.json +1 -1
- package/src/schemas/build/dragAndDrop_v3.schema.json +1 -1
- package/src/schemas/build/find_v2.schema.json +3 -3
- package/src/schemas/build/find_v3.schema.json +4 -4
- package/src/schemas/build/goTo_v2.schema.json +1 -1
- package/src/schemas/build/goTo_v3.schema.json +1 -1
- package/src/schemas/build/httpRequest_v2.schema.json +2 -2
- package/src/schemas/build/httpRequest_v3.schema.json +3 -3
- package/src/schemas/build/loadCookie_v3.schema.json +1 -1
- package/src/schemas/build/loadVariables_v3.schema.json +1 -1
- package/src/schemas/build/moveTo_v2.schema.json +1 -1
- package/src/schemas/build/openApi_v2.schema.json +1 -1
- package/src/schemas/build/openApi_v3.schema.json +1 -1
- package/src/schemas/build/record_v3.schema.json +1 -1
- package/src/schemas/build/report_v3.schema.json +5 -5
- package/src/schemas/build/resolvedTests_v3.schema.json +3 -3
- package/src/schemas/build/runCode_v2.schema.json +1 -1
- package/src/schemas/build/runCode_v3.schema.json +1 -1
- package/src/schemas/build/runShell_v2.schema.json +1 -1
- package/src/schemas/build/runShell_v3.schema.json +1 -1
- package/src/schemas/build/saveCookie_v3.schema.json +1 -1
- package/src/schemas/build/saveScreenshot_v2.schema.json +1 -1
- package/src/schemas/build/screenshot_v3.schema.json +2 -2
- package/src/schemas/build/setVariables_v2.schema.json +1 -1
- package/src/schemas/build/sourceIntegration_v3.schema.json +1 -1
- package/src/schemas/build/spec_v2.schema.json +4 -4
- package/src/schemas/build/spec_v3.schema.json +4 -4
- package/src/schemas/build/startRecording_v2.schema.json +1 -1
- package/src/schemas/build/step_v3.schema.json +38 -38
- package/src/schemas/build/stopRecord_v3.schema.json +1 -1
- package/src/schemas/build/stopRecording_v2.schema.json +1 -1
- package/src/schemas/build/terminateScope_v3.schema.json +48 -0
- package/src/schemas/build/test_v2.schema.json +15 -15
- package/src/schemas/build/test_v3.schema.json +6 -6
- package/src/schemas/build/typeKeys_v2.schema.json +1 -1
- package/src/schemas/build/type_v3.schema.json +1 -1
- package/src/schemas/build/wait_v2.schema.json +1 -1
- package/src/schemas/build/wait_v3.schema.json +1 -1
- package/src/schemas/{dereferenceSchemas.js → dereferenceSchemas.cjs} +206 -206
- package/src/schemas/index.ts +6 -0
- package/src/schemas/output_schemas/endRecord_v3.schema.json +13 -13
- package/src/schemas/src_schemas/checkLink_v2.schema.json +65 -65
- package/src/schemas/src_schemas/checkLink_v3.schema.json +90 -90
- package/src/schemas/src_schemas/click_v3.schema.json +143 -143
- package/src/schemas/src_schemas/config_v2.schema.json +929 -929
- package/src/schemas/src_schemas/config_v3.schema.json +633 -633
- package/src/schemas/src_schemas/context_v2.schema.json +108 -108
- package/src/schemas/src_schemas/context_v3.schema.json +202 -202
- package/src/schemas/src_schemas/dragAndDrop_v3.schema.json +184 -184
- package/src/schemas/src_schemas/find_v2.schema.json +155 -155
- package/src/schemas/src_schemas/find_v3.schema.json +209 -209
- package/src/schemas/src_schemas/goTo_v2.schema.json +57 -57
- package/src/schemas/src_schemas/goTo_v3.schema.json +232 -232
- package/src/schemas/src_schemas/httpRequest_v2.schema.json +284 -284
- package/src/schemas/src_schemas/httpRequest_v3.schema.json +402 -402
- package/src/schemas/src_schemas/loadCookie_v3.schema.json +113 -113
- package/src/schemas/src_schemas/loadVariables_v3.schema.json +8 -8
- package/src/schemas/src_schemas/openApi_v2.schema.json +64 -64
- package/src/schemas/src_schemas/openApi_v3.schema.json +160 -160
- package/src/schemas/src_schemas/record_v3.schema.json +68 -68
- package/src/schemas/src_schemas/report_v3.schema.json +51 -51
- package/src/schemas/src_schemas/resolvedTests_v3.schema.json +236 -236
- package/src/schemas/src_schemas/runCode_v2.schema.json +181 -181
- package/src/schemas/src_schemas/runCode_v3.schema.json +136 -136
- package/src/schemas/src_schemas/runShell_v2.schema.json +166 -166
- package/src/schemas/src_schemas/runShell_v3.schema.json +154 -154
- package/src/schemas/src_schemas/saveCookie_v3.schema.json +124 -124
- package/src/schemas/src_schemas/saveScreenshot_v2.schema.json +129 -129
- package/src/schemas/src_schemas/screenshot_v3.schema.json +248 -248
- package/src/schemas/src_schemas/setVariables_v2.schema.json +37 -37
- package/src/schemas/src_schemas/sourceIntegration_v3.schema.json +45 -45
- package/src/schemas/src_schemas/spec_v2.schema.json +175 -175
- package/src/schemas/src_schemas/spec_v3.schema.json +211 -211
- package/src/schemas/src_schemas/startRecording_v2.schema.json +54 -54
- package/src/schemas/src_schemas/step_v3.schema.json +632 -632
- package/src/schemas/src_schemas/stopRecord_v3.schema.json +13 -13
- package/src/schemas/src_schemas/stopRecording_v2.schema.json +31 -31
- package/src/schemas/src_schemas/test_v2.schema.json +200 -200
- package/src/schemas/src_schemas/test_v3.schema.json +268 -268
- package/src/schemas/src_schemas/typeKeys_v2.schema.json +63 -63
- package/src/schemas/src_schemas/type_v3.schema.json +118 -118
- package/src/schemas/src_schemas/wait_v3.schema.json +35 -35
- package/src/types/generated/checkLink_v3.ts +29 -0
- package/src/types/generated/click_v3.ts +17 -0
- package/src/types/generated/config_v3.ts +405 -0
- package/src/types/generated/context_v3.ts +112 -0
- package/src/types/generated/dragAndDrop_v3.ts +39 -0
- package/src/types/generated/endRecord_v3.ts +10 -0
- package/src/types/generated/find_v3.ts +17 -0
- package/src/types/generated/goTo_v3.ts +48 -0
- package/src/types/generated/httpRequest_v3.ts +17 -0
- package/src/types/generated/loadCookie_v3.ts +17 -0
- package/src/types/generated/loadVariables_v3.ts +10 -0
- package/src/types/generated/openApi_v3.ts +64 -0
- package/src/types/generated/record_v3.ts +34 -0
- package/src/types/generated/report_v3.ts +183 -0
- package/src/types/generated/resolvedTests_v3.ts +585 -0
- package/src/types/generated/runCode_v3.ts +59 -0
- package/src/types/generated/runShell_v3.ts +58 -0
- package/src/types/generated/saveCookie_v3.ts +17 -0
- package/src/types/generated/screenshot_v3.ts +76 -0
- package/src/types/generated/sourceIntegration_v3.ts +31 -0
- package/src/types/generated/spec_v3.ts +166 -0
- package/src/types/generated/step_v3.ts +1288 -0
- package/src/types/generated/stopRecord_v3.ts +10 -0
- package/src/types/generated/test_v3.ts +3048 -0
- package/src/types/generated/type_v3.ts +56 -0
- package/src/types/generated/wait_v3.ts +13 -0
- package/src/{validate.js → validate.ts} +627 -587
- package/tsconfig.json +22 -0
- package/src/files.js +0 -84
- package/src/index.js +0 -12
- package/src/resolvePaths.js +0 -252
- 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
|
-
|
|
111
|
-
|
|
112
|
-
**
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
**
|
|
123
|
-
|
|
124
|
-
**
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
**
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
-
|
|
195
|
-
-
|
|
196
|
-
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
-
|
|
221
|
-
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
-
|
|
241
|
-
-
|
|
242
|
-
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
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)
|