@owasp-aghast/aghast 0.8.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 (178) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +127 -0
  3. package/assets/img/aghastowaspcaption.png +0 -0
  4. package/assets/txt/logo.txt +52 -0
  5. package/config/pricing.json +42 -0
  6. package/config/prompts/false-positive-validation.md +78 -0
  7. package/config/prompts/general-vuln-discovery.md +99 -0
  8. package/config/prompts/generic-instructions.md +59 -0
  9. package/config/prompts/test-cheaper-instructions.md +57 -0
  10. package/dist/budget.d.ts +62 -0
  11. package/dist/budget.d.ts.map +1 -0
  12. package/dist/budget.js +137 -0
  13. package/dist/budget.js.map +1 -0
  14. package/dist/build-config.d.ts +15 -0
  15. package/dist/build-config.d.ts.map +1 -0
  16. package/dist/build-config.js +568 -0
  17. package/dist/build-config.js.map +1 -0
  18. package/dist/check-library.d.ts +88 -0
  19. package/dist/check-library.d.ts.map +1 -0
  20. package/dist/check-library.js +461 -0
  21. package/dist/check-library.js.map +1 -0
  22. package/dist/check-types.d.ts +35 -0
  23. package/dist/check-types.d.ts.map +1 -0
  24. package/dist/check-types.js +66 -0
  25. package/dist/check-types.js.map +1 -0
  26. package/dist/claude-code-provider.d.ts +29 -0
  27. package/dist/claude-code-provider.d.ts.map +1 -0
  28. package/dist/claude-code-provider.js +347 -0
  29. package/dist/claude-code-provider.js.map +1 -0
  30. package/dist/cli.d.ts +13 -0
  31. package/dist/cli.d.ts.map +1 -0
  32. package/dist/cli.js +109 -0
  33. package/dist/cli.js.map +1 -0
  34. package/dist/colors.d.ts +7 -0
  35. package/dist/colors.d.ts.map +1 -0
  36. package/dist/colors.js +18 -0
  37. package/dist/colors.js.map +1 -0
  38. package/dist/cost-calculator.d.ts +80 -0
  39. package/dist/cost-calculator.d.ts.map +1 -0
  40. package/dist/cost-calculator.js +226 -0
  41. package/dist/cost-calculator.js.map +1 -0
  42. package/dist/defaults.d.ts +21 -0
  43. package/dist/defaults.d.ts.map +1 -0
  44. package/dist/defaults.js +21 -0
  45. package/dist/defaults.js.map +1 -0
  46. package/dist/diff-filter.d.ts +50 -0
  47. package/dist/diff-filter.d.ts.map +1 -0
  48. package/dist/diff-filter.js +130 -0
  49. package/dist/diff-filter.js.map +1 -0
  50. package/dist/diff-parser.d.ts +40 -0
  51. package/dist/diff-parser.d.ts.map +1 -0
  52. package/dist/diff-parser.js +112 -0
  53. package/dist/diff-parser.js.map +1 -0
  54. package/dist/diff-unit-matcher.d.ts +53 -0
  55. package/dist/diff-unit-matcher.d.ts.map +1 -0
  56. package/dist/diff-unit-matcher.js +156 -0
  57. package/dist/diff-unit-matcher.js.map +1 -0
  58. package/dist/discoveries/openant-discovery.d.ts +10 -0
  59. package/dist/discoveries/openant-discovery.d.ts.map +1 -0
  60. package/dist/discoveries/openant-discovery.js +56 -0
  61. package/dist/discoveries/openant-discovery.js.map +1 -0
  62. package/dist/discoveries/sarif-discovery.d.ts +9 -0
  63. package/dist/discoveries/sarif-discovery.d.ts.map +1 -0
  64. package/dist/discoveries/sarif-discovery.js +56 -0
  65. package/dist/discoveries/sarif-discovery.js.map +1 -0
  66. package/dist/discoveries/semgrep-discovery.d.ts +9 -0
  67. package/dist/discoveries/semgrep-discovery.d.ts.map +1 -0
  68. package/dist/discoveries/semgrep-discovery.js +61 -0
  69. package/dist/discoveries/semgrep-discovery.js.map +1 -0
  70. package/dist/discovery.d.ts +100 -0
  71. package/dist/discovery.d.ts.map +1 -0
  72. package/dist/discovery.js +49 -0
  73. package/dist/discovery.js.map +1 -0
  74. package/dist/error-codes.d.ts +46 -0
  75. package/dist/error-codes.d.ts.map +1 -0
  76. package/dist/error-codes.js +70 -0
  77. package/dist/error-codes.js.map +1 -0
  78. package/dist/formatters/index.d.ts +10 -0
  79. package/dist/formatters/index.d.ts.map +1 -0
  80. package/dist/formatters/index.js +23 -0
  81. package/dist/formatters/index.js.map +1 -0
  82. package/dist/formatters/json-formatter.d.ts +11 -0
  83. package/dist/formatters/json-formatter.d.ts.map +1 -0
  84. package/dist/formatters/json-formatter.js +11 -0
  85. package/dist/formatters/json-formatter.js.map +1 -0
  86. package/dist/formatters/sarif-formatter.d.ts +18 -0
  87. package/dist/formatters/sarif-formatter.d.ts.map +1 -0
  88. package/dist/formatters/sarif-formatter.js +103 -0
  89. package/dist/formatters/sarif-formatter.js.map +1 -0
  90. package/dist/formatters/types.d.ts +11 -0
  91. package/dist/formatters/types.d.ts.map +1 -0
  92. package/dist/formatters/types.js +6 -0
  93. package/dist/formatters/types.js.map +1 -0
  94. package/dist/index.d.ts +7 -0
  95. package/dist/index.d.ts.map +1 -0
  96. package/dist/index.js +754 -0
  97. package/dist/index.js.map +1 -0
  98. package/dist/logging.d.ts +140 -0
  99. package/dist/logging.d.ts.map +1 -0
  100. package/dist/logging.js +344 -0
  101. package/dist/logging.js.map +1 -0
  102. package/dist/mock-agent-provider.d.ts +24 -0
  103. package/dist/mock-agent-provider.d.ts.map +1 -0
  104. package/dist/mock-agent-provider.js +38 -0
  105. package/dist/mock-agent-provider.js.map +1 -0
  106. package/dist/mock-ai-provider.d.ts +21 -0
  107. package/dist/mock-ai-provider.d.ts.map +1 -0
  108. package/dist/mock-ai-provider.js +31 -0
  109. package/dist/mock-ai-provider.js.map +1 -0
  110. package/dist/new-check.d.ts +13 -0
  111. package/dist/new-check.d.ts.map +1 -0
  112. package/dist/new-check.js +515 -0
  113. package/dist/new-check.js.map +1 -0
  114. package/dist/openant-loader.d.ts +105 -0
  115. package/dist/openant-loader.d.ts.map +1 -0
  116. package/dist/openant-loader.js +135 -0
  117. package/dist/openant-loader.js.map +1 -0
  118. package/dist/openant-runner.d.ts +30 -0
  119. package/dist/openant-runner.d.ts.map +1 -0
  120. package/dist/openant-runner.js +113 -0
  121. package/dist/openant-runner.js.map +1 -0
  122. package/dist/opencode-provider.d.ts +63 -0
  123. package/dist/opencode-provider.d.ts.map +1 -0
  124. package/dist/opencode-provider.js +719 -0
  125. package/dist/opencode-provider.js.map +1 -0
  126. package/dist/prompt-template.d.ts +12 -0
  127. package/dist/prompt-template.d.ts.map +1 -0
  128. package/dist/prompt-template.js +36 -0
  129. package/dist/prompt-template.js.map +1 -0
  130. package/dist/provider-registry.d.ts +15 -0
  131. package/dist/provider-registry.d.ts.map +1 -0
  132. package/dist/provider-registry.js +29 -0
  133. package/dist/provider-registry.js.map +1 -0
  134. package/dist/provider-utils.d.ts +52 -0
  135. package/dist/provider-utils.d.ts.map +1 -0
  136. package/dist/provider-utils.js +40 -0
  137. package/dist/provider-utils.js.map +1 -0
  138. package/dist/repository-analyzer.d.ts +68 -0
  139. package/dist/repository-analyzer.d.ts.map +1 -0
  140. package/dist/repository-analyzer.js +238 -0
  141. package/dist/repository-analyzer.js.map +1 -0
  142. package/dist/response-parser.d.ts +14 -0
  143. package/dist/response-parser.d.ts.map +1 -0
  144. package/dist/response-parser.js +111 -0
  145. package/dist/response-parser.js.map +1 -0
  146. package/dist/runtime-config.d.ts +15 -0
  147. package/dist/runtime-config.d.ts.map +1 -0
  148. package/dist/runtime-config.js +187 -0
  149. package/dist/runtime-config.js.map +1 -0
  150. package/dist/sarif-parser.d.ts +20 -0
  151. package/dist/sarif-parser.d.ts.map +1 -0
  152. package/dist/sarif-parser.js +76 -0
  153. package/dist/sarif-parser.js.map +1 -0
  154. package/dist/scan-history.d.ts +82 -0
  155. package/dist/scan-history.d.ts.map +1 -0
  156. package/dist/scan-history.js +127 -0
  157. package/dist/scan-history.js.map +1 -0
  158. package/dist/scan-runner.d.ts +122 -0
  159. package/dist/scan-runner.d.ts.map +1 -0
  160. package/dist/scan-runner.js +928 -0
  161. package/dist/scan-runner.js.map +1 -0
  162. package/dist/semgrep-runner.d.ts +25 -0
  163. package/dist/semgrep-runner.d.ts.map +1 -0
  164. package/dist/semgrep-runner.js +100 -0
  165. package/dist/semgrep-runner.js.map +1 -0
  166. package/dist/snippet-extractor.d.ts +25 -0
  167. package/dist/snippet-extractor.d.ts.map +1 -0
  168. package/dist/snippet-extractor.js +56 -0
  169. package/dist/snippet-extractor.js.map +1 -0
  170. package/dist/stats.d.ts +11 -0
  171. package/dist/stats.d.ts.map +1 -0
  172. package/dist/stats.js +197 -0
  173. package/dist/stats.js.map +1 -0
  174. package/dist/types.d.ts +321 -0
  175. package/dist/types.d.ts.map +1 -0
  176. package/dist/types.js +19 -0
  177. package/dist/types.js.map +1 -0
  178. package/package.json +61 -0
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Check Library / Config Manager.
3
+ * Two-layer config: Layer 1 (registry) maps checks to repos,
4
+ * Layer 2 (<id>.json) defines each check in its own folder.
5
+ * Implements spec Appendix B.1.
6
+ */
7
+ import type { SecurityCheck, CheckDetails, CheckRegistryEntry, CheckDefinition } from './types.js';
8
+ export interface CheckRegistry {
9
+ checks: CheckRegistryEntry[];
10
+ }
11
+ /**
12
+ * Load and parse the Layer 1 registry from <configDir>/checks-config.json.
13
+ * Throws on missing file, malformed JSON, or invalid structure.
14
+ */
15
+ export declare function loadCheckRegistry(configDir: string): Promise<CheckRegistry>;
16
+ /**
17
+ * Load and parse a Layer 2 check definition from <checkFolderPath>/<id>.json.
18
+ * Throws on missing file, malformed JSON, or missing required fields.
19
+ */
20
+ export declare function loadCheckDefinition(checkFolderPath: string): Promise<CheckDefinition>;
21
+ /**
22
+ * Scan check directories for subfolders containing <id>.json.
23
+ * Returns a map of check id → folder path.
24
+ */
25
+ export declare function discoverCheckFolders(checksDirs: string[]): Promise<Map<string, string>>;
26
+ /**
27
+ * Merge Layer 1 registry entries with Layer 2 check definitions.
28
+ * Resolves instructionsFile and checkTarget.rules paths relative to check folder.
29
+ * Throws if a registry entry has no matching check folder.
30
+ */
31
+ export declare function resolveChecks(registry: CheckRegistry, checkFolders: Map<string, string>): Promise<SecurityCheck[]>;
32
+ export interface CheckLibraryConfig {
33
+ checks: SecurityCheck[];
34
+ }
35
+ /**
36
+ * Load and parse a flat JSON config file (old format).
37
+ * Kept for backward compatibility with existing test fixtures.
38
+ */
39
+ export declare function loadConfig(configPath: string): Promise<CheckLibraryConfig>;
40
+ export interface ValidationResult {
41
+ valid: boolean;
42
+ errors: string[];
43
+ }
44
+ /**
45
+ * Validate a single SecurityCheck definition.
46
+ * Checks that id is present and non-empty, and instructionsFile exists on disk.
47
+ * basePath is used to resolve instructionsFile if it's a relative path.
48
+ * If instructionsFile is already absolute, basePath is ignored.
49
+ */
50
+ export declare function validateCheck(check: SecurityCheck, basePath: string): Promise<ValidationResult>;
51
+ export { normalizeRepoPath } from './repository-analyzer.js';
52
+ /**
53
+ * Check if a single check matches the given repository URL/path.
54
+ * Empty repositories array matches all repos.
55
+ * Entries in excludeRepositories override matches (exclusion wins).
56
+ * Uses bidirectional substring matching on normalized paths.
57
+ */
58
+ export declare function checkMatchesRepository(check: SecurityCheck, repositoryUrl: string): boolean;
59
+ /**
60
+ * Filter checks to those matching the given repository URL/path.
61
+ * Also filters out disabled checks (enabled === false).
62
+ */
63
+ export declare function filterChecksForRepository(checks: SecurityCheck[], repositoryUrl: string): SecurityCheck[];
64
+ /**
65
+ * Parse a markdown check file into CheckDetails.
66
+ * Extracts name from first ### heading, overview from #### Overview section.
67
+ */
68
+ export declare function parseCheckMarkdown(id: string, markdown: string): CheckDetails;
69
+ /**
70
+ * Load check instructions from the markdown file referenced by a SecurityCheck.
71
+ * Resolves instructionsFile relative to basePath (or uses absolute path if already resolved).
72
+ */
73
+ export declare function loadCheckDetails(check: SecurityCheck, basePath: string): Promise<CheckDetails>;
74
+ /**
75
+ * Filter files to those matching applicablePaths globs.
76
+ * If applicablePaths is undefined or empty, returns all files.
77
+ */
78
+ export declare function filterApplicablePaths(files: string[], applicablePaths?: string[]): string[];
79
+ /**
80
+ * Filter out files matching excludedPaths globs.
81
+ * If excludedPaths is undefined or empty, returns all files.
82
+ */
83
+ export declare function filterExcludedPaths(files: string[], excludedPaths?: string[]): string[];
84
+ /**
85
+ * Apply both applicablePaths and excludedPaths filtering.
86
+ */
87
+ export declare function filterCheckPaths(files: string[], check: SecurityCheck): string[];
88
+ //# sourceMappingURL=check-library.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-library.d.ts","sourceRoot":"","sources":["../src/check-library.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,kBAAkB,EAClB,eAAe,EAChB,MAAM,YAAY,CAAC;AAMpB,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,kBAAkB,EAAE,CAAC;CAC9B;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAwEjF;AAID;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CA0I3F;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CA2B9B;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,aAAa,EACvB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,OAAO,CAAC,aAAa,EAAE,CAAC,CAqD1B;AAID,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,aAAa,EAAE,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAiChF;AAID,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,CAAC,CAqC3B;AAKD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,aAAa,EACpB,aAAa,EAAE,MAAM,GACpB,OAAO,CAoBT;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,aAAa,EAAE,EACvB,aAAa,EAAE,MAAM,GACpB,aAAa,EAAE,CAIjB;AAID;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,CAoB7E;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,aAAa,EACpB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,YAAY,CAAC,CAgBvB;AAOD;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,EAAE,EACf,eAAe,CAAC,EAAE,MAAM,EAAE,GACzB,MAAM,EAAE,CAOV;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EAAE,EACf,aAAa,CAAC,EAAE,MAAM,EAAE,GACvB,MAAM,EAAE,CAOV;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EAAE,EACf,KAAK,EAAE,aAAa,GACnB,MAAM,EAAE,CAGV"}
@@ -0,0 +1,461 @@
1
+ /**
2
+ * Check Library / Config Manager.
3
+ * Two-layer config: Layer 1 (registry) maps checks to repos,
4
+ * Layer 2 (<id>.json) defines each check in its own folder.
5
+ * Implements spec Appendix B.1.
6
+ */
7
+ import { readFile, readdir, access, constants } from 'node:fs/promises';
8
+ import { resolve, join, basename } from 'node:path';
9
+ import picomatch from 'picomatch';
10
+ import { normalizeRepoPath } from './repository-analyzer.js';
11
+ import { getCheckType, getValidCheckTypes } from './check-types.js';
12
+ import { getRegisteredDiscoveries } from './discovery.js';
13
+ /**
14
+ * Load and parse the Layer 1 registry from <configDir>/checks-config.json.
15
+ * Throws on missing file, malformed JSON, or invalid structure.
16
+ */
17
+ export async function loadCheckRegistry(configDir) {
18
+ const configPath = resolve(configDir, 'checks-config.json');
19
+ let raw;
20
+ try {
21
+ raw = await readFile(configPath, 'utf-8');
22
+ }
23
+ catch (err) {
24
+ throw new Error(`Failed to read config file "${configPath}": ${err instanceof Error ? err.message : String(err)}`, { cause: err });
25
+ }
26
+ let parsed;
27
+ try {
28
+ parsed = JSON.parse(raw);
29
+ }
30
+ catch (err) {
31
+ throw new Error(`Config file "${configPath}" contains invalid JSON: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
32
+ }
33
+ if (typeof parsed !== 'object' ||
34
+ parsed === null ||
35
+ !('checks' in parsed) ||
36
+ !Array.isArray(parsed.checks)) {
37
+ throw new Error(`Config file "${configPath}" has invalid structure: must contain a "checks" array`);
38
+ }
39
+ // Validate each registry entry has required fields with correct types
40
+ const checks = parsed.checks;
41
+ for (let i = 0; i < checks.length; i++) {
42
+ const entry = checks[i];
43
+ if (typeof entry !== 'object' || entry === null) {
44
+ throw new Error(`Config file "${configPath}": checks[${i}] must be an object`);
45
+ }
46
+ const obj = entry;
47
+ if (typeof obj.id !== 'string' || obj.id.trim() === '') {
48
+ throw new Error(`Config file "${configPath}": checks[${i}].id must be a non-empty string`);
49
+ }
50
+ if (!Array.isArray(obj.repositories)) {
51
+ throw new Error(`Config file "${configPath}": checks[${i}].repositories must be an array`);
52
+ }
53
+ for (let j = 0; j < obj.repositories.length; j++) {
54
+ if (typeof obj.repositories[j] !== 'string') {
55
+ throw new Error(`Config file "${configPath}": checks[${i}].repositories[${j}] must be a string`);
56
+ }
57
+ }
58
+ if (obj.excludeRepositories !== undefined) {
59
+ if (!Array.isArray(obj.excludeRepositories)) {
60
+ throw new Error(`Config file "${configPath}": checks[${i}].excludeRepositories must be an array`);
61
+ }
62
+ for (let j = 0; j < obj.excludeRepositories.length; j++) {
63
+ if (typeof obj.excludeRepositories[j] !== 'string') {
64
+ throw new Error(`Config file "${configPath}": checks[${i}].excludeRepositories[${j}] must be a string`);
65
+ }
66
+ }
67
+ }
68
+ if (obj.enabled !== undefined && typeof obj.enabled !== 'boolean') {
69
+ throw new Error(`Config file "${configPath}": checks[${i}].enabled must be a boolean`);
70
+ }
71
+ }
72
+ return parsed;
73
+ }
74
+ // --- Layer 2: Check Definitions ---
75
+ /**
76
+ * Load and parse a Layer 2 check definition from <checkFolderPath>/<id>.json.
77
+ * Throws on missing file, malformed JSON, or missing required fields.
78
+ */
79
+ export async function loadCheckDefinition(checkFolderPath) {
80
+ const defPath = resolve(checkFolderPath, basename(checkFolderPath) + '.json');
81
+ let raw;
82
+ try {
83
+ raw = await readFile(defPath, 'utf-8');
84
+ }
85
+ catch (err) {
86
+ throw new Error(`Failed to read check definition "${defPath}": ${err instanceof Error ? err.message : String(err)}`, { cause: err });
87
+ }
88
+ let parsed;
89
+ try {
90
+ parsed = JSON.parse(raw);
91
+ }
92
+ catch (err) {
93
+ throw new Error(`Check definition "${defPath}" contains invalid JSON: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
94
+ }
95
+ // Validate field types before casting
96
+ const obj = parsed;
97
+ if (typeof obj.id !== 'string' || obj.id.trim() === '') {
98
+ throw new Error(`Check definition "${defPath}": "id" must be a non-empty string`);
99
+ }
100
+ if (typeof obj.name !== 'string' || obj.name.trim() === '') {
101
+ throw new Error(`Check definition "${defPath}": "name" must be a non-empty string`);
102
+ }
103
+ if (obj.instructionsFile !== undefined && typeof obj.instructionsFile !== 'string') {
104
+ throw new Error(`Check definition "${defPath}": "instructionsFile" must be a string`);
105
+ }
106
+ if (obj.severity !== undefined && typeof obj.severity !== 'string') {
107
+ throw new Error(`Check definition "${defPath}": "severity" must be a string`);
108
+ }
109
+ if (obj.confidence !== undefined && typeof obj.confidence !== 'string') {
110
+ throw new Error(`Check definition "${defPath}": "confidence" must be a string`);
111
+ }
112
+ if (obj.model !== undefined && typeof obj.model !== 'string') {
113
+ throw new Error(`Check definition "${defPath}": "model" must be a string`);
114
+ }
115
+ if (obj.applicablePaths !== undefined && !Array.isArray(obj.applicablePaths)) {
116
+ throw new Error(`Check definition "${defPath}": "applicablePaths" must be an array`);
117
+ }
118
+ if (obj.excludedPaths !== undefined && !Array.isArray(obj.excludedPaths)) {
119
+ throw new Error(`Check definition "${defPath}": "excludedPaths" must be an array`);
120
+ }
121
+ if (obj.checkTarget !== undefined) {
122
+ if (typeof obj.checkTarget !== 'object' || obj.checkTarget === null) {
123
+ throw new Error(`Check definition "${defPath}": "checkTarget" must be an object`);
124
+ }
125
+ const ct = obj.checkTarget;
126
+ const validTypes = getValidCheckTypes();
127
+ if (typeof ct.type !== 'string' || !validTypes.includes(ct.type)) {
128
+ throw new Error(`Check definition "${defPath}": "checkTarget.type" must be one of: ${validTypes.join(', ')}`);
129
+ }
130
+ if (ct.rules !== undefined && typeof ct.rules !== 'string' && !Array.isArray(ct.rules)) {
131
+ throw new Error(`Check definition "${defPath}": "checkTarget.rules" must be a string or array`);
132
+ }
133
+ if (ct.config !== undefined && typeof ct.config !== 'string') {
134
+ throw new Error(`Check definition "${defPath}": "checkTarget.config" must be a string`);
135
+ }
136
+ if (ct.maxTargets !== undefined && (typeof ct.maxTargets !== 'number' || ct.maxTargets <= 0 || !Number.isInteger(ct.maxTargets))) {
137
+ throw new Error(`Check definition "${defPath}": "checkTarget.maxTargets" must be a positive integer`);
138
+ }
139
+ if (ct.concurrency !== undefined && (typeof ct.concurrency !== 'number' || ct.concurrency <= 0 || !Number.isInteger(ct.concurrency))) {
140
+ throw new Error(`Check definition "${defPath}": "checkTarget.concurrency" must be a positive integer`);
141
+ }
142
+ if (ct.maxIssuesPerTarget !== undefined && (typeof ct.maxIssuesPerTarget !== 'number' || ct.maxIssuesPerTarget < 1 || !Number.isInteger(ct.maxIssuesPerTarget))) {
143
+ throw new Error(`Check definition "${defPath}": "checkTarget.maxIssuesPerTarget" must be a positive integer`);
144
+ }
145
+ // Validate discovery field is present for targeted/static types (actual type
146
+ // validation happens in validateCheck, after repo filtering, so unknown
147
+ // discovery types don't crash the entire scan for unrelated checks)
148
+ if (ct.type === 'targeted' || ct.type === 'static') {
149
+ if (typeof ct.discovery !== 'string' || ct.discovery.trim() === '') {
150
+ throw new Error(`Check definition "${defPath}": "checkTarget.discovery" is required for type "${ct.type}"`);
151
+ }
152
+ }
153
+ if (ct.sarifFile !== undefined && typeof ct.sarifFile !== 'string') {
154
+ throw new Error(`Check definition "${defPath}": "checkTarget.sarifFile" must be a string`);
155
+ }
156
+ if (ct.discovery === 'sarif' && !ct.sarifFile) {
157
+ throw new Error(`Check definition "${defPath}": "checkTarget.sarifFile" is required when discovery is "sarif"`);
158
+ }
159
+ // Validate diff filter fields
160
+ if (ct.diffFilter !== undefined && typeof ct.diffFilter !== 'boolean') {
161
+ throw new Error(`Check definition "${defPath}": "checkTarget.diffFilter" must be a boolean`);
162
+ }
163
+ if (ct.diffRef !== undefined && typeof ct.diffRef !== 'string') {
164
+ throw new Error(`Check definition "${defPath}": "checkTarget.diffRef" must be a string`);
165
+ }
166
+ // Validate openant filter config
167
+ if (ct.openant !== undefined) {
168
+ if (typeof ct.openant !== 'object' || ct.openant === null) {
169
+ throw new Error(`Check definition "${defPath}": "checkTarget.openant" must be an object`);
170
+ }
171
+ const oa = ct.openant;
172
+ if (oa.unitTypes !== undefined && !Array.isArray(oa.unitTypes)) {
173
+ throw new Error(`Check definition "${defPath}": "checkTarget.openant.unitTypes" must be an array`);
174
+ }
175
+ if (oa.excludeUnitTypes !== undefined && !Array.isArray(oa.excludeUnitTypes)) {
176
+ throw new Error(`Check definition "${defPath}": "checkTarget.openant.excludeUnitTypes" must be an array`);
177
+ }
178
+ if (oa.securityClassifications !== undefined && !Array.isArray(oa.securityClassifications)) {
179
+ throw new Error(`Check definition "${defPath}": "checkTarget.openant.securityClassifications" must be an array`);
180
+ }
181
+ if (oa.reachableOnly !== undefined && typeof oa.reachableOnly !== 'boolean') {
182
+ throw new Error(`Check definition "${defPath}": "checkTarget.openant.reachableOnly" must be a boolean`);
183
+ }
184
+ if (oa.entryPointsOnly !== undefined && typeof oa.entryPointsOnly !== 'boolean') {
185
+ throw new Error(`Check definition "${defPath}": "checkTarget.openant.entryPointsOnly" must be a boolean`);
186
+ }
187
+ if (oa.minConfidence !== undefined && (typeof oa.minConfidence !== 'number' || oa.minConfidence < 0 || oa.minConfidence > 1)) {
188
+ throw new Error(`Check definition "${defPath}": "checkTarget.openant.minConfidence" must be a number between 0 and 1`);
189
+ }
190
+ }
191
+ }
192
+ const def = parsed;
193
+ // instructionsFile is required for check types where needsInstructions is true,
194
+ // UNLESS analysisMode is a built-in mode (false-positive-validation, general-vuln-discovery)
195
+ // which provides its own prompt template.
196
+ const builtInMode = def.checkTarget?.analysisMode === 'false-positive-validation'
197
+ || def.checkTarget?.analysisMode === 'general-vuln-discovery';
198
+ if (getCheckType(def.checkTarget?.type).needsInstructions && !builtInMode && !def.instructionsFile) {
199
+ throw new Error(`Check definition "${defPath}" is missing required field "instructionsFile"`);
200
+ }
201
+ return def;
202
+ }
203
+ /**
204
+ * Scan check directories for subfolders containing <id>.json.
205
+ * Returns a map of check id → folder path.
206
+ */
207
+ export async function discoverCheckFolders(checksDirs) {
208
+ const result = new Map();
209
+ for (const dir of checksDirs) {
210
+ let entries;
211
+ try {
212
+ entries = await readdir(dir);
213
+ }
214
+ catch {
215
+ // Directory doesn't exist — skip
216
+ continue;
217
+ }
218
+ for (const entry of entries) {
219
+ const folderPath = join(dir, entry);
220
+ const checkJsonPath = join(folderPath, entry + '.json');
221
+ try {
222
+ await access(checkJsonPath, constants.R_OK);
223
+ // Load just to get the id
224
+ const def = await loadCheckDefinition(folderPath);
225
+ result.set(def.id, folderPath);
226
+ }
227
+ catch {
228
+ // Not a check folder or can't read — skip
229
+ }
230
+ }
231
+ }
232
+ return result;
233
+ }
234
+ /**
235
+ * Merge Layer 1 registry entries with Layer 2 check definitions.
236
+ * Resolves instructionsFile and checkTarget.rules paths relative to check folder.
237
+ * Throws if a registry entry has no matching check folder.
238
+ */
239
+ export async function resolveChecks(registry, checkFolders) {
240
+ const checks = [];
241
+ for (const entry of registry.checks) {
242
+ const folderPath = checkFolders.get(entry.id);
243
+ if (!folderPath) {
244
+ throw new Error(`Check "${entry.id}" is registered but no matching check folder was found in any checks directory`);
245
+ }
246
+ const def = await loadCheckDefinition(folderPath);
247
+ if (def.id !== entry.id) {
248
+ throw new Error(`Check ID mismatch: registry has "${entry.id}" but ${entry.id}.json has "${def.id}"`);
249
+ }
250
+ // Merge Layer 1 + Layer 2
251
+ const merged = {
252
+ id: entry.id,
253
+ name: def.name,
254
+ repositories: entry.repositories,
255
+ excludeRepositories: entry.excludeRepositories,
256
+ instructionsFile: def.instructionsFile ? resolve(folderPath, def.instructionsFile) : undefined,
257
+ enabled: entry.enabled,
258
+ checkDir: folderPath,
259
+ };
260
+ if (def.severity)
261
+ merged.severity = def.severity;
262
+ if (def.confidence)
263
+ merged.confidence = def.confidence;
264
+ if (def.model)
265
+ merged.model = def.model;
266
+ if (def.applicablePaths)
267
+ merged.applicablePaths = def.applicablePaths;
268
+ if (def.excludedPaths)
269
+ merged.excludedPaths = def.excludedPaths;
270
+ if (def.checkTarget) {
271
+ merged.checkTarget = { ...def.checkTarget };
272
+ // Resolve rules paths relative to check folder
273
+ if (merged.checkTarget.rules) {
274
+ const rules = merged.checkTarget.rules;
275
+ merged.checkTarget.rules = Array.isArray(rules)
276
+ ? rules.map((r) => resolve(folderPath, r))
277
+ : resolve(folderPath, rules);
278
+ }
279
+ if (merged.checkTarget.config) {
280
+ merged.checkTarget.config = resolve(folderPath, merged.checkTarget.config);
281
+ }
282
+ }
283
+ checks.push(merged);
284
+ }
285
+ return checks;
286
+ }
287
+ /**
288
+ * Load and parse a flat JSON config file (old format).
289
+ * Kept for backward compatibility with existing test fixtures.
290
+ */
291
+ export async function loadConfig(configPath) {
292
+ let raw;
293
+ try {
294
+ raw = await readFile(configPath, 'utf-8');
295
+ }
296
+ catch (err) {
297
+ throw new Error(`Failed to read config file "${configPath}": ${err instanceof Error ? err.message : String(err)}`, { cause: err });
298
+ }
299
+ let parsed;
300
+ try {
301
+ parsed = JSON.parse(raw);
302
+ }
303
+ catch (err) {
304
+ throw new Error(`Config file "${configPath}" contains invalid JSON: ${err instanceof Error ? err.message : String(err)}`, { cause: err });
305
+ }
306
+ if (typeof parsed !== 'object' ||
307
+ parsed === null ||
308
+ !('checks' in parsed) ||
309
+ !Array.isArray(parsed.checks)) {
310
+ throw new Error(`Config file "${configPath}" has invalid structure: must contain a "checks" array`);
311
+ }
312
+ return parsed;
313
+ }
314
+ /**
315
+ * Validate a single SecurityCheck definition.
316
+ * Checks that id is present and non-empty, and instructionsFile exists on disk.
317
+ * basePath is used to resolve instructionsFile if it's a relative path.
318
+ * If instructionsFile is already absolute, basePath is ignored.
319
+ */
320
+ export async function validateCheck(check, basePath) {
321
+ const errors = [];
322
+ if (!check.id || typeof check.id !== 'string' || check.id.trim() === '') {
323
+ errors.push('Check is missing a valid "id" field');
324
+ }
325
+ // Validate discovery type is registered (checked here, after repo filtering,
326
+ // so unknown discovery types in unrelated checks don't crash the scan).
327
+ // Only validates when discoveries have been registered (skips in unit tests
328
+ // where scan-runner.ts hasn't been imported).
329
+ const discovery = check.checkTarget?.discovery;
330
+ const registered = getRegisteredDiscoveries();
331
+ if (discovery && registered.length > 0 && !registered.includes(discovery)) {
332
+ errors.push(`Unknown discovery type "${discovery}". Available: ${registered.join(', ')}`);
333
+ }
334
+ // Built-in analysis modes provide their own prompt template — no instructionsFile needed
335
+ const builtInModeV = check.checkTarget?.analysisMode === 'false-positive-validation'
336
+ || check.checkTarget?.analysisMode === 'general-vuln-discovery';
337
+ if (!getCheckType(check.checkTarget?.type).needsInstructions || builtInModeV) {
338
+ // No instructionsFile validation needed for this check type/discovery
339
+ }
340
+ else if (!check.instructionsFile) {
341
+ errors.push('Check is missing required "instructionsFile" field');
342
+ }
343
+ else {
344
+ // instructionsFile may already be an absolute path (from resolveChecks)
345
+ const instructionsPath = resolve(basePath, check.instructionsFile);
346
+ try {
347
+ await access(instructionsPath, constants.R_OK);
348
+ }
349
+ catch {
350
+ errors.push(`Instructions file "${check.instructionsFile}" not found at "${instructionsPath}"`);
351
+ }
352
+ }
353
+ return { valid: errors.length === 0, errors };
354
+ }
355
+ // --- Repository Matching (spec C.6) ---
356
+ // Re-export normalizeRepoPath from repository-analyzer for convenience
357
+ export { normalizeRepoPath } from './repository-analyzer.js';
358
+ /**
359
+ * Check if a single check matches the given repository URL/path.
360
+ * Empty repositories array matches all repos.
361
+ * Entries in excludeRepositories override matches (exclusion wins).
362
+ * Uses bidirectional substring matching on normalized paths.
363
+ */
364
+ export function checkMatchesRepository(check, repositoryUrl) {
365
+ const normalizedRepo = normalizeRepoPath(repositoryUrl);
366
+ const matches = (entry) => {
367
+ const normalizedEntry = normalizeRepoPath(entry);
368
+ return (normalizedRepo.includes(normalizedEntry) ||
369
+ normalizedEntry.includes(normalizedRepo));
370
+ };
371
+ if (check.excludeRepositories && check.excludeRepositories.some(matches)) {
372
+ return false;
373
+ }
374
+ if (check.repositories.length === 0) {
375
+ return true;
376
+ }
377
+ return check.repositories.some(matches);
378
+ }
379
+ /**
380
+ * Filter checks to those matching the given repository URL/path.
381
+ * Also filters out disabled checks (enabled === false).
382
+ */
383
+ export function filterChecksForRepository(checks, repositoryUrl) {
384
+ return checks
385
+ .filter((check) => check.enabled !== false)
386
+ .filter((check) => checkMatchesRepository(check, repositoryUrl));
387
+ }
388
+ // --- Markdown Parsing (spec A.7) ---
389
+ /**
390
+ * Parse a markdown check file into CheckDetails.
391
+ * Extracts name from first ### heading, overview from #### Overview section.
392
+ */
393
+ export function parseCheckMarkdown(id, markdown) {
394
+ // Extract name from first ### heading
395
+ const nameMatch = markdown.match(/^###\s+(.+)$/m);
396
+ const name = nameMatch ? nameMatch[1].trim() : 'Unknown Check';
397
+ // Extract overview from #### Overview section
398
+ let overview = '';
399
+ const overviewMatch = markdown.match(/^####\s+Overview\s*\n([\s\S]*?)(?=^####\s|\s*$)/m);
400
+ if (overviewMatch) {
401
+ overview = overviewMatch[1].trim();
402
+ }
403
+ return {
404
+ id,
405
+ name,
406
+ overview,
407
+ content: markdown,
408
+ };
409
+ }
410
+ /**
411
+ * Load check instructions from the markdown file referenced by a SecurityCheck.
412
+ * Resolves instructionsFile relative to basePath (or uses absolute path if already resolved).
413
+ */
414
+ export async function loadCheckDetails(check, basePath) {
415
+ if (!check.instructionsFile) {
416
+ throw new Error(`Check "${check.id}" has no instructionsFile`);
417
+ }
418
+ const instructionsPath = resolve(basePath, check.instructionsFile);
419
+ let markdown;
420
+ try {
421
+ markdown = await readFile(instructionsPath, 'utf-8');
422
+ }
423
+ catch (err) {
424
+ throw new Error(`Failed to load instructions file "${check.instructionsFile}": ${err instanceof Error ? err.message : String(err)}`, { cause: err });
425
+ }
426
+ return parseCheckMarkdown(check.id, markdown);
427
+ }
428
+ // --- Path Filtering ---
429
+ // Note: These path filtering functions are implemented and tested but not yet
430
+ // wired into the scan execution path. They will be integrated in a future
431
+ // iteration when the agent provider interface supports scoped file lists.
432
+ /**
433
+ * Filter files to those matching applicablePaths globs.
434
+ * If applicablePaths is undefined or empty, returns all files.
435
+ */
436
+ export function filterApplicablePaths(files, applicablePaths) {
437
+ if (!applicablePaths || applicablePaths.length === 0) {
438
+ return files;
439
+ }
440
+ const matcher = picomatch(applicablePaths);
441
+ return files.filter((file) => matcher(file));
442
+ }
443
+ /**
444
+ * Filter out files matching excludedPaths globs.
445
+ * If excludedPaths is undefined or empty, returns all files.
446
+ */
447
+ export function filterExcludedPaths(files, excludedPaths) {
448
+ if (!excludedPaths || excludedPaths.length === 0) {
449
+ return files;
450
+ }
451
+ const matcher = picomatch(excludedPaths);
452
+ return files.filter((file) => !matcher(file));
453
+ }
454
+ /**
455
+ * Apply both applicablePaths and excludedPaths filtering.
456
+ */
457
+ export function filterCheckPaths(files, check) {
458
+ const applicable = filterApplicablePaths(files, check.applicablePaths);
459
+ return filterExcludedPaths(applicable, check.excludedPaths);
460
+ }
461
+ //# sourceMappingURL=check-library.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-library.js","sourceRoot":"","sources":["../src/check-library.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Check type descriptor system.
3
+ *
4
+ * Each check type declares its characteristics (needs AI, needs instructions, etc.)
5
+ * in one place. Code throughout the codebase queries these descriptors instead
6
+ * of comparing raw type strings.
7
+ *
8
+ * Check types describe *execution mode* (what happens with targets).
9
+ * Discovery type (how targets are found) is a separate axis — see src/discovery.ts.
10
+ */
11
+ /** Characteristics of a check type. */
12
+ export interface CheckTypeDescriptor {
13
+ /** The string value used in check definitions. */
14
+ readonly type: string;
15
+ /** Whether the check requires AI analysis. */
16
+ readonly needsAI: boolean;
17
+ /** Whether the check requires an instructions markdown file. */
18
+ readonly needsInstructions: boolean;
19
+ /** Whether the check supports maxTargets (multi-target checks). */
20
+ readonly supportsMaxTargets: boolean;
21
+ }
22
+ /**
23
+ * Get the descriptor for a check type string.
24
+ * Returns conservative defaults for unknown/undefined types.
25
+ */
26
+ export declare function getCheckType(type: string | undefined): CheckTypeDescriptor;
27
+ /** All valid check type strings. */
28
+ export declare function getValidCheckTypes(): string[];
29
+ /** Check type string constants for use in routing (scan-runner switch). */
30
+ export declare const CHECK_TYPE: {
31
+ readonly REPOSITORY: string;
32
+ readonly TARGETED: string;
33
+ readonly STATIC: string;
34
+ };
35
+ //# sourceMappingURL=check-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-types.d.ts","sourceRoot":"","sources":["../src/check-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,uCAAuC;AACvC,MAAM,WAAW,mBAAmB;IAClC,kDAAkD;IAClD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,gEAAgE;IAChE,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC,mEAAmE;IACnE,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;CACtC;AA6CD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,mBAAmB,CAG1E;AAED,oCAAoC;AACpC,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CAE7C;AAED,2EAA2E;AAC3E,eAAO,MAAM,UAAU;;;;CAIb,CAAC"}