@bouncesecurity/aghast 0.0.13 → 0.2.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 (67) hide show
  1. package/README.md +8 -6
  2. package/config/prompts/generic-instructions.md +2 -0
  3. package/config/prompts/openant-security-instructions.md +94 -0
  4. package/config/prompts/sarif-validation-instructions.md +58 -0
  5. package/dist/check-library.d.ts.map +1 -1
  6. package/dist/check-library.js +61 -7
  7. package/dist/check-library.js.map +1 -1
  8. package/dist/check-types.d.ts +35 -0
  9. package/dist/check-types.d.ts.map +1 -0
  10. package/dist/check-types.js +66 -0
  11. package/dist/check-types.js.map +1 -0
  12. package/dist/claude-code-provider.d.ts +4 -1
  13. package/dist/claude-code-provider.d.ts.map +1 -1
  14. package/dist/claude-code-provider.js +23 -8
  15. package/dist/claude-code-provider.js.map +1 -1
  16. package/dist/discoveries/openant-discovery.d.ts +10 -0
  17. package/dist/discoveries/openant-discovery.d.ts.map +1 -0
  18. package/dist/discoveries/openant-discovery.js +44 -0
  19. package/dist/discoveries/openant-discovery.js.map +1 -0
  20. package/dist/discoveries/sarif-discovery.d.ts +9 -0
  21. package/dist/discoveries/sarif-discovery.d.ts.map +1 -0
  22. package/dist/discoveries/sarif-discovery.js +55 -0
  23. package/dist/discoveries/sarif-discovery.js.map +1 -0
  24. package/dist/discoveries/semgrep-discovery.d.ts +9 -0
  25. package/dist/discoveries/semgrep-discovery.d.ts.map +1 -0
  26. package/dist/discoveries/semgrep-discovery.js +51 -0
  27. package/dist/discoveries/semgrep-discovery.js.map +1 -0
  28. package/dist/discovery.d.ts +74 -0
  29. package/dist/discovery.d.ts.map +1 -0
  30. package/dist/discovery.js +41 -0
  31. package/dist/discovery.js.map +1 -0
  32. package/dist/error-codes.d.ts +3 -1
  33. package/dist/error-codes.d.ts.map +1 -1
  34. package/dist/error-codes.js +4 -1
  35. package/dist/error-codes.js.map +1 -1
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +123 -30
  38. package/dist/index.js.map +1 -1
  39. package/dist/logging.d.ts +108 -8
  40. package/dist/logging.d.ts.map +1 -1
  41. package/dist/logging.js +269 -43
  42. package/dist/logging.js.map +1 -1
  43. package/dist/mock-ai-provider.d.ts +4 -1
  44. package/dist/mock-ai-provider.d.ts.map +1 -1
  45. package/dist/mock-ai-provider.js +4 -1
  46. package/dist/mock-ai-provider.js.map +1 -1
  47. package/dist/new-check.d.ts.map +1 -1
  48. package/dist/new-check.js +81 -33
  49. package/dist/new-check.js.map +1 -1
  50. package/dist/openant-loader.d.ts +105 -0
  51. package/dist/openant-loader.d.ts.map +1 -0
  52. package/dist/openant-loader.js +135 -0
  53. package/dist/openant-loader.js.map +1 -0
  54. package/dist/openant-runner.d.ts +22 -0
  55. package/dist/openant-runner.d.ts.map +1 -0
  56. package/dist/openant-runner.js +102 -0
  57. package/dist/openant-runner.js.map +1 -0
  58. package/dist/runtime-config.d.ts.map +1 -1
  59. package/dist/runtime-config.js +15 -0
  60. package/dist/runtime-config.js.map +1 -1
  61. package/dist/scan-runner.d.ts.map +1 -1
  62. package/dist/scan-runner.js +175 -143
  63. package/dist/scan-runner.js.map +1 -1
  64. package/dist/types.d.ts +24 -2
  65. package/dist/types.d.ts.map +1 -1
  66. package/dist/types.js.map +1 -1
  67. package/package.json +4 -3
package/dist/logging.js CHANGED
@@ -1,34 +1,269 @@
1
- const LOG_PRIORITY = {
2
- silent: 0,
3
- info: 1,
4
- debug: 2,
1
+ /**
2
+ * Pluggable logging system with standard log levels and handler-based architecture.
3
+ *
4
+ * Log levels (standard, syslog-inspired):
5
+ * error (0) > warn (1) > info (2) > debug (3) > trace (4)
6
+ *
7
+ * Handlers receive structured LogEntry objects and decide how to output them.
8
+ * A ConsoleHandler is registered by default. Additional handlers (e.g. FileHandler)
9
+ * can be added at runtime via addHandler().
10
+ */
11
+ import { createWriteStream, mkdirSync } from 'node:fs';
12
+ import { dirname } from 'node:path';
13
+ const LOG_LEVEL_PRIORITY = {
14
+ error: 0,
15
+ warn: 1,
16
+ info: 2,
17
+ debug: 3,
18
+ trace: 4,
5
19
  };
6
- let cachedLogLevel;
7
- export function getLogLevel() {
8
- if (cachedLogLevel)
9
- return cachedLogLevel;
10
- cachedLogLevel = 'info';
11
- return cachedLogLevel;
20
+ const VALID_LOG_LEVELS = new Set(Object.keys(LOG_LEVEL_PRIORITY));
21
+ /**
22
+ * Check whether a string is a valid LogLevel.
23
+ */
24
+ export function isValidLogLevel(s) {
25
+ return VALID_LOG_LEVELS.has(s);
26
+ }
27
+ /**
28
+ * A "silent" sentinel: priority -1 means no messages pass the threshold check.
29
+ * Used internally when setLogLevel('silent') is called.
30
+ */
31
+ const SILENT_PRIORITY = -1;
32
+ // --- Console Handler ---
33
+ export class ConsoleHandler {
34
+ name = 'console';
35
+ level;
36
+ priority;
37
+ constructor(level = 'info') {
38
+ this.level = level;
39
+ this.priority = level === 'silent' ? SILENT_PRIORITY : LOG_LEVEL_PRIORITY[level];
40
+ }
41
+ setLevel(level) {
42
+ this.level = level;
43
+ this.priority = level === 'silent' ? SILENT_PRIORITY : LOG_LEVEL_PRIORITY[level];
44
+ }
45
+ handle(entry) {
46
+ const entryPriority = LOG_LEVEL_PRIORITY[entry.level];
47
+ if (entryPriority > this.priority)
48
+ return;
49
+ const levelTag = entry.level === 'info' ? '' : `[${entry.level}]`;
50
+ if (entry.data === undefined) {
51
+ console.log(`${entry.timestamp} [${entry.tag}]${levelTag} ${entry.message}`);
52
+ }
53
+ else {
54
+ const formatted = typeof entry.data === 'string' ? entry.data : JSON.stringify(entry.data);
55
+ // Truncate at debug level for console readability (matching legacy behavior)
56
+ if (entry.level === 'debug') {
57
+ const truncated = formatted.length > 200 ? formatted.slice(0, 200) + '...' : formatted;
58
+ console.log(`${entry.timestamp} [${entry.tag}]${levelTag} ${entry.message}: ${truncated}`);
59
+ }
60
+ else if (entry.level === 'trace') {
61
+ // Trace: full data, newline-separated (matching legacy logDebugFull)
62
+ console.log(`${entry.timestamp} [${entry.tag}]${levelTag} ${entry.message}:\n${formatted}`);
63
+ }
64
+ else {
65
+ console.log(`${entry.timestamp} [${entry.tag}]${levelTag} ${entry.message}: ${formatted}`);
66
+ }
67
+ }
68
+ }
12
69
  }
70
+ // --- File Handler ---
71
+ export class FileHandler {
72
+ name;
73
+ level;
74
+ priority;
75
+ stream = null;
76
+ constructor(filePath, level = 'trace', name = 'file') {
77
+ this.name = name;
78
+ this.level = level;
79
+ this.priority = level === 'silent' ? SILENT_PRIORITY : LOG_LEVEL_PRIORITY[level];
80
+ try {
81
+ mkdirSync(dirname(filePath), { recursive: true });
82
+ this.stream = createWriteStream(filePath, { flags: 'w', encoding: 'utf-8', mode: 0o600 });
83
+ this.stream.on('error', (err) => {
84
+ console.warn(`[logging] File handler write error: ${err.message}`);
85
+ this.stream = null;
86
+ });
87
+ }
88
+ catch (err) {
89
+ const msg = err instanceof Error ? err.message : String(err);
90
+ console.warn(`[logging] Failed to open log file "${filePath}": ${msg}`);
91
+ this.stream = null;
92
+ }
93
+ }
94
+ handle(entry) {
95
+ if (!this.stream)
96
+ return;
97
+ const entryPriority = LOG_LEVEL_PRIORITY[entry.level];
98
+ if (entryPriority > this.priority)
99
+ return;
100
+ const levelTag = `[${entry.level}]`;
101
+ let line;
102
+ if (entry.data === undefined) {
103
+ line = `${entry.timestamp} [${entry.tag}]${levelTag} ${entry.message}`;
104
+ }
105
+ else {
106
+ const formatted = typeof entry.data === 'string' ? entry.data : JSON.stringify(entry.data);
107
+ line = `${entry.timestamp} [${entry.tag}]${levelTag} ${entry.message}: ${formatted}`;
108
+ }
109
+ this.stream.write(line + '\n');
110
+ }
111
+ close() {
112
+ if (!this.stream)
113
+ return Promise.resolve();
114
+ const stream = this.stream;
115
+ this.stream = null;
116
+ if (stream.destroyed || stream.closed)
117
+ return Promise.resolve();
118
+ return new Promise((resolve) => {
119
+ stream.end(() => {
120
+ stream.destroy();
121
+ resolve();
122
+ });
123
+ });
124
+ }
125
+ }
126
+ // --- Log Type Registry ---
127
+ const LOG_TYPE_REGISTRY = {
128
+ file: (path, level) => new FileHandler(path, level),
129
+ };
13
130
  /**
14
- * Programmatically set the log level (avoids env var race conditions with --debug flag).
131
+ * Create a log handler by type name.
132
+ * @throws Error if the type is not registered
133
+ */
134
+ export function createHandlerByType(type, path, level = 'trace') {
135
+ const factory = LOG_TYPE_REGISTRY[type];
136
+ if (!factory) {
137
+ const available = Object.keys(LOG_TYPE_REGISTRY).join(', ');
138
+ throw new Error(`Unknown log type "${type}". Available types: ${available}`);
139
+ }
140
+ return factory(path, level);
141
+ }
142
+ /**
143
+ * Get the list of available log type names.
144
+ */
145
+ export function getAvailableLogTypes() {
146
+ return Object.keys(LOG_TYPE_REGISTRY);
147
+ }
148
+ // --- Handler Registry ---
149
+ const handlers = [];
150
+ let consoleHandler;
151
+ function ensureConsoleHandler() {
152
+ if (!consoleHandler) {
153
+ consoleHandler = new ConsoleHandler('info');
154
+ handlers.push(consoleHandler);
155
+ }
156
+ return consoleHandler;
157
+ }
158
+ // Initialize the default console handler
159
+ ensureConsoleHandler();
160
+ /**
161
+ * Add a log handler to the registry.
162
+ */
163
+ export function addHandler(handler) {
164
+ handlers.push(handler);
165
+ }
166
+ /**
167
+ * Remove a log handler by name.
168
+ */
169
+ export function removeHandler(name) {
170
+ const idx = handlers.findIndex((h) => h.name === name);
171
+ if (idx !== -1)
172
+ handlers.splice(idx, 1);
173
+ }
174
+ /**
175
+ * Close all handlers (flush file streams, etc.) and clear the registry.
176
+ * Re-initializes the console handler afterward.
177
+ */
178
+ export async function closeAllHandlers() {
179
+ const closePromises = handlers
180
+ .map((h) => h.close?.())
181
+ .filter(Boolean)
182
+ .map((p) => p.catch((err) => console.warn(`[logging] Handler close failed: ${err.message}`)));
183
+ await Promise.all(closePromises);
184
+ handlers.length = 0;
185
+ consoleHandler = new ConsoleHandler('info');
186
+ handlers.push(consoleHandler);
187
+ }
188
+ /**
189
+ * Convenience: create a file handler via the type registry and add it.
190
+ */
191
+ export function initFileHandler(filePath, type = 'file', level = 'trace') {
192
+ const handler = createHandlerByType(type, filePath, level);
193
+ addHandler(handler);
194
+ }
195
+ // --- Log Level Management (backward compatible) ---
196
+ const LEGACY_LEVEL_MAP = {
197
+ silent: 'silent',
198
+ info: 'info',
199
+ debug: 'debug',
200
+ };
201
+ /**
202
+ * Set the console handler's log level.
203
+ * Accepts both new standard levels and legacy 3-level names ('silent', 'info', 'debug').
15
204
  */
16
205
  export function setLogLevel(level) {
17
- cachedLogLevel = level;
206
+ const mapped = LEGACY_LEVEL_MAP[level] ?? level;
207
+ if (mapped !== 'silent' && !VALID_LOG_LEVELS.has(mapped)) {
208
+ throw new Error(`Invalid log level: "${level}". Valid levels: ${[...VALID_LOG_LEVELS].join(', ')}, silent`);
209
+ }
210
+ ensureConsoleHandler().setLevel(mapped);
18
211
  }
19
- function formatTimestamp() {
20
- return new Date().toISOString().replace('T', ' ').replace('Z', '');
212
+ /**
213
+ * Get the console handler's current log level.
214
+ */
215
+ export function getLogLevel() {
216
+ return ensureConsoleHandler().level;
21
217
  }
218
+ // --- Timestamp ---
219
+ export function formatTimestamp() {
220
+ return new Date().toISOString().replace('T', ' ').replace('Z', ' UTC');
221
+ }
222
+ // --- Central Log Dispatcher ---
223
+ function log(level, tag, message, data) {
224
+ const entry = {
225
+ timestamp: formatTimestamp(),
226
+ level,
227
+ tag,
228
+ message,
229
+ data,
230
+ };
231
+ for (const handler of handlers) {
232
+ handler.handle(entry);
233
+ }
234
+ }
235
+ // --- Convenience Wrappers (signatures unchanged for backward compat) ---
22
236
  /**
23
237
  * Log a progress/activity message at info level.
24
238
  */
25
239
  export function logProgress(tag, message, details) {
26
- if (LOG_PRIORITY['info'] <= LOG_PRIORITY[getLogLevel()]) {
27
- const timestamp = formatTimestamp();
28
- const detailStr = details ? ` ${JSON.stringify(details)}` : '';
29
- console.log(`${timestamp} [${tag}] ${message}${detailStr}`);
30
- }
240
+ log('info', tag, message, details);
241
+ }
242
+ /**
243
+ * Log debug information (single line, compact — console truncates at 200 chars).
244
+ */
245
+ export function logDebug(tag, message, data) {
246
+ log('debug', tag, message, data);
247
+ }
248
+ /**
249
+ * Log debug information without truncation (for full prompts and responses).
250
+ */
251
+ export function logDebugFull(tag, message, data) {
252
+ log('trace', tag, message, data);
31
253
  }
254
+ /**
255
+ * Log a warning message.
256
+ */
257
+ export function logWarn(tag, message, data) {
258
+ log('warn', tag, message, data);
259
+ }
260
+ /**
261
+ * Log an error message.
262
+ */
263
+ export function logError(tag, message, data) {
264
+ log('error', tag, message, data);
265
+ }
266
+ // --- Timer ---
32
267
  /**
33
268
  * Create a timer for measuring elapsed time.
34
269
  */
@@ -46,34 +281,25 @@ export function createTimer() {
46
281
  },
47
282
  };
48
283
  }
284
+ // --- Test Helpers ---
49
285
  /**
50
- * Log debug information (single line, compact).
286
+ * Reset the handler registry to a clean state (for testing only).
287
+ * Removes all handlers and re-adds a fresh ConsoleHandler.
51
288
  */
52
- export function logDebug(tag, message, data) {
53
- if (getLogLevel() !== 'debug')
54
- return;
55
- const timestamp = formatTimestamp();
56
- if (data === undefined) {
57
- console.log(`${timestamp} [${tag}][debug] ${message}`);
58
- }
59
- else {
60
- const formatted = typeof data === 'string' ? data : JSON.stringify(data);
61
- const truncated = formatted.length > 200 ? formatted.slice(0, 200) + '...' : formatted;
62
- console.log(`${timestamp} [${tag}][debug] ${message}: ${truncated}`);
63
- }
289
+ export async function _resetHandlers(level = 'info') {
290
+ const closePromises = handlers
291
+ .map((h) => h.close?.())
292
+ .filter(Boolean)
293
+ .map((p) => p.catch(() => { }));
294
+ await Promise.all(closePromises);
295
+ handlers.length = 0;
296
+ consoleHandler = new ConsoleHandler(level);
297
+ handlers.push(consoleHandler);
64
298
  }
65
299
  /**
66
- * Log debug information without truncation (for full prompts and responses).
300
+ * Get a snapshot of currently registered handler names (for testing only).
67
301
  */
68
- export function logDebugFull(tag, message, data) {
69
- if (getLogLevel() !== 'debug')
70
- return;
71
- const timestamp = formatTimestamp();
72
- if (data === undefined) {
73
- console.log(`${timestamp} [${tag}][debug] ${message}`);
74
- }
75
- else {
76
- console.log(`${timestamp} [${tag}][debug] ${message}:\n${data}`);
77
- }
302
+ export function _getHandlerNames() {
303
+ return handlers.map((h) => h.name);
78
304
  }
79
305
  //# sourceMappingURL=logging.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"logging.js","sourceRoot":"","sources":["../src/logging.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"logging.js","sourceRoot":"","sources":["../src/logging.ts"],"names":[],"mappings":"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"}
@@ -11,8 +11,11 @@ export declare class MockAIProvider implements AIProvider {
11
11
  rawResponse: string;
12
12
  });
13
13
  initialize(_config: ProviderConfig): Promise<void>;
14
- executeCheck(_instructions: string, _repositoryPath: string, _logPrefix?: string): Promise<AIResponse>;
14
+ executeCheck(_instructions: string, _repositoryPath: string, _logPrefix?: string, _options?: {
15
+ maxTurns?: number;
16
+ }): Promise<AIResponse>;
15
17
  validateConfig(): Promise<boolean>;
18
+ setModel(_model: string): void;
16
19
  enableDebug(): void;
17
20
  }
18
21
  //# sourceMappingURL=mock-ai-provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mock-ai-provider.d.ts","sourceRoot":"","sources":["../src/mock-ai-provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEzE,qBAAa,cAAe,YAAW,UAAU;IAC/C,OAAO,CAAC,WAAW,CAAS;gBAEhB,OAAO,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE;IAItC,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlD,YAAY,CAChB,aAAa,EAAE,MAAM,EACrB,eAAe,EAAE,MAAM,EACvB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,UAAU,CAAC;IAOhB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IAIxC,WAAW,IAAI,IAAI;CAGpB"}
1
+ {"version":3,"file":"mock-ai-provider.d.ts","sourceRoot":"","sources":["../src/mock-ai-provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEzE,qBAAa,cAAe,YAAW,UAAU;IAC/C,OAAO,CAAC,WAAW,CAAS;gBAEhB,OAAO,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE;IAItC,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlD,YAAY,CAChB,aAAa,EAAE,MAAM,EACrB,eAAe,EAAE,MAAM,EACvB,UAAU,CAAC,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAC/B,OAAO,CAAC,UAAU,CAAC;IAOhB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IAIxC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI9B,WAAW,IAAI,IAAI;CAGpB"}
@@ -12,7 +12,7 @@ export class MockAIProvider {
12
12
  async initialize(_config) {
13
13
  // No-op
14
14
  }
15
- async executeCheck(_instructions, _repositoryPath, _logPrefix) {
15
+ async executeCheck(_instructions, _repositoryPath, _logPrefix, _options) {
16
16
  return {
17
17
  raw: this.rawResponse,
18
18
  parsed: undefined,
@@ -21,6 +21,9 @@ export class MockAIProvider {
21
21
  async validateConfig() {
22
22
  return true;
23
23
  }
24
+ setModel(_model) {
25
+ // No-op for mock provider
26
+ }
24
27
  enableDebug() {
25
28
  // No-op
26
29
  }
@@ -1 +1 @@
1
- {"version":3,"file":"mock-ai-provider.js","sourceRoot":"","sources":["../src/mock-ai-provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,OAAO,cAAc;IACjB,WAAW,CAAS;IAE5B,YAAY,OAAgC;QAC1C,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,OAAuB;QACtC,QAAQ;IACV,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,aAAqB,EACrB,eAAuB,EACvB,UAAmB;QAEnB,OAAO;YACL,GAAG,EAAE,IAAI,CAAC,WAAW;YACrB,MAAM,EAAE,SAAS;SAClB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,WAAW;QACT,QAAQ;IACV,CAAC;CACF"}
1
+ {"version":3,"file":"mock-ai-provider.js","sourceRoot":"","sources":["../src/mock-ai-provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,OAAO,cAAc;IACjB,WAAW,CAAS;IAE5B,YAAY,OAAgC;QAC1C,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,OAAuB;QACtC,QAAQ;IACV,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,aAAqB,EACrB,eAAuB,EACvB,UAAmB,EACnB,QAAgC;QAEhC,OAAO;YACL,GAAG,EAAE,IAAI,CAAC,WAAW;YACrB,MAAM,EAAE,SAAS;SAClB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,QAAQ,CAAC,MAAc;QACrB,0BAA0B;IAC5B,CAAC;IAED,WAAW;QACT,QAAQ;IACV,CAAC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"new-check.d.ts","sourceRoot":"","sources":["../src/new-check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA2YH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAyF/D"}
1
+ {"version":3,"file":"new-check.d.ts","sourceRoot":"","sources":["../src/new-check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAgcH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA0F/D"}
package/dist/new-check.js CHANGED
@@ -15,6 +15,7 @@ import { createInterface } from 'node:readline/promises';
15
15
  import { stdin, stdout } from 'node:process';
16
16
  import { createRequire } from 'node:module';
17
17
  import { ERROR_CODES, formatError, formatFatalError } from './error-codes.js';
18
+ import { getCheckType, getValidCheckTypes } from './check-types.js';
18
19
  const ID_PREFIX = 'aghast-';
19
20
  const SUPPORTED_LANGUAGES = {
20
21
  python: { semgrepId: 'python', extension: '.py', commentPrefix: '#' },
@@ -31,6 +32,7 @@ const CLI_FLAG_MAP = {
31
32
  '--name': 'name',
32
33
  '--severity': 'severity',
33
34
  '--confidence': 'confidence',
35
+ '--model': 'model',
34
36
  '--repositories': 'repositories',
35
37
  '--check-overview': 'checkOverview',
36
38
  '--check-items': 'checkItems',
@@ -38,7 +40,9 @@ const CLI_FLAG_MAP = {
38
40
  '--fail-condition': 'failCondition',
39
41
  '--flag-condition': 'flagCondition',
40
42
  '--check-type': 'checkType',
43
+ '--discovery': 'discovery',
41
44
  '--semgrep-rules': 'semgrepRules',
45
+ '--sarif-file': 'sarifFile',
42
46
  '--max-targets': 'maxTargets',
43
47
  '--language': 'language',
44
48
  '--config-dir': 'configDir',
@@ -109,28 +113,40 @@ async function promptForMissing(flags) {
109
113
  name: await ask('Check name (e.g. XSS Prevention)', flags.name),
110
114
  severity: await askOptional('Severity (critical/high/medium/low/informational)', flags.severity),
111
115
  confidence: await askOptional('Confidence (high/medium/low)', flags.confidence),
116
+ model: flags.model !== undefined ? flags.model : await askOptional('AI model override (e.g. claude-sonnet-4-6)', undefined),
112
117
  repositories: flags.repositories !== undefined ? flags.repositories : await askOptional('Repositories (comma-separated URLs, or empty for all)', undefined),
113
118
  checkOverview: await ask('Check overview / description', flags.checkOverview),
114
119
  checkItems: await ask('Check items (comma-separated)', flags.checkItems),
115
120
  passCondition: await ask('PASS condition', flags.passCondition),
116
121
  failCondition: await ask('FAIL condition', flags.failCondition),
117
122
  flagCondition: await askOptional('FLAG condition (requires human investigation)', flags.flagCondition),
118
- checkType: await askWithDefault('Check type (repository/semgrep/semgrep-only)', 'repository', flags.checkType),
123
+ checkType: await askWithDefault(`Check type (${getValidCheckTypes().join('/')})`, 'repository', flags.checkType),
124
+ discovery: '',
119
125
  semgrepRules: '',
126
+ sarifFile: '',
120
127
  maxTargets: '',
121
128
  language: '',
122
129
  };
123
- if (result.checkType === 'semgrep' || result.checkType === 'semgrep-only') {
124
- result.semgrepRules = flags.semgrepRules !== undefined
125
- ? flags.semgrepRules
126
- : await askOptional('Semgrep rule file paths (comma-separated, or press Enter to generate template)', undefined);
130
+ if (result.checkType === 'targeted' || result.checkType === 'static') {
131
+ const discoveryChoices = result.checkType === 'targeted' ? 'semgrep/openant/sarif' : 'semgrep';
132
+ result.discovery = await askWithDefault(`Discovery (${discoveryChoices})`, 'semgrep', flags.discovery);
127
133
  result.maxTargets = await askOptional('Max targets', flags.maxTargets);
128
- if (!result.semgrepRules) {
129
- // Language is required when generating a rule template + test file
130
- result.language = await ask(`Language (${LANGUAGE_CHOICES.join('/')})`, flags.language);
134
+ if (result.discovery === 'semgrep') {
135
+ result.semgrepRules = flags.semgrepRules !== undefined
136
+ ? flags.semgrepRules
137
+ : await askOptional('Semgrep rule file paths (comma-separated, or press Enter to generate template)', undefined);
138
+ if (!result.semgrepRules) {
139
+ // Language is required when generating a rule template + test file
140
+ result.language = await ask(`Language (${LANGUAGE_CHOICES.join('/')})`, flags.language);
141
+ }
142
+ else {
143
+ result.language = flags.language ?? '';
144
+ }
131
145
  }
132
- else {
133
- result.language = flags.language ?? '';
146
+ else if (result.discovery === 'sarif') {
147
+ result.sarifFile = flags.sarifFile !== undefined
148
+ ? flags.sarifFile
149
+ : await ask('SARIF file path (relative to target repo, e.g. ./sast-results.sarif)', flags.sarifFile);
134
150
  }
135
151
  }
136
152
  if (rl)
@@ -163,9 +179,9 @@ function validateInputs(inputs, registry) {
163
179
  if (inputs.confidence && !validConfidences.includes(inputs.confidence)) {
164
180
  errors.push(`Invalid confidence "${inputs.confidence}". Must be one of: ${validConfidences.join(', ')}`);
165
181
  }
166
- const validCheckTypes = ['repository', 'semgrep', 'semgrep-only', ''];
167
- if (!validCheckTypes.includes(inputs.checkType)) {
168
- errors.push(`Invalid check type "${inputs.checkType}". Must be one of: repository, semgrep, semgrep-only`);
182
+ const validCheckTypes = getValidCheckTypes();
183
+ if (inputs.checkType && !validCheckTypes.includes(inputs.checkType)) {
184
+ errors.push(`Invalid check type "${inputs.checkType}". Must be one of: ${validCheckTypes.join(', ')}`);
169
185
  }
170
186
  if (inputs.maxTargets) {
171
187
  const parsed = parseInt(inputs.maxTargets, 10);
@@ -173,7 +189,16 @@ function validateInputs(inputs, registry) {
173
189
  errors.push(`Invalid maxTargets "${inputs.maxTargets}". Must be a positive integer`);
174
190
  }
175
191
  }
176
- if ((inputs.checkType === 'semgrep' || inputs.checkType === 'semgrep-only') && inputs.language && !SUPPORTED_LANGUAGES[inputs.language]) {
192
+ if ((inputs.checkType === 'targeted' || inputs.checkType === 'static') && inputs.checkType) {
193
+ const validDiscoveries = inputs.checkType === 'targeted' ? ['semgrep', 'openant', 'sarif'] : ['semgrep'];
194
+ if (!inputs.discovery || !validDiscoveries.includes(inputs.discovery)) {
195
+ errors.push(`Invalid discovery "${inputs.discovery}" for check type "${inputs.checkType}". Must be one of: ${validDiscoveries.join(', ')}`);
196
+ }
197
+ if (inputs.discovery === 'sarif' && !inputs.sarifFile) {
198
+ errors.push('sarifFile is required for sarif discovery');
199
+ }
200
+ }
201
+ if (inputs.discovery === 'semgrep' && inputs.language && !SUPPORTED_LANGUAGES[inputs.language]) {
177
202
  errors.push(`Invalid language "${inputs.language}". Must be one of: ${Object.keys(SUPPORTED_LANGUAGES).join(', ')}`);
178
203
  }
179
204
  return errors;
@@ -240,8 +265,10 @@ function generateCheckDefinition(inputs) {
240
265
  id: inputs.id,
241
266
  name: inputs.name,
242
267
  };
243
- // semgrep-only checks don't have an instructionsFile
244
- if (inputs.checkType !== 'semgrep-only') {
268
+ // Only check types that need instructions get an instructionsFile.
269
+ // Discovery types with self-contained prompts (openant, sarif) don't need instructions.
270
+ const selfContained = inputs.discovery === 'openant' || inputs.discovery === 'sarif';
271
+ if (getCheckType(inputs.checkType).needsInstructions && !selfContained) {
245
272
  def.instructionsFile = `${inputs.id}.md`;
246
273
  }
247
274
  if (inputs.severity) {
@@ -250,14 +277,25 @@ function generateCheckDefinition(inputs) {
250
277
  if (inputs.confidence) {
251
278
  def.confidence = inputs.confidence;
252
279
  }
253
- if (inputs.checkType === 'semgrep' || inputs.checkType === 'semgrep-only') {
254
- const checkTarget = { type: inputs.checkType };
255
- if (inputs.semgrepRules) {
256
- const rules = inputs.semgrepRules.split(',').map((r) => r.trim()).filter(Boolean);
257
- checkTarget.rules = rules.length === 1 ? rules[0] : rules;
280
+ if (inputs.model) {
281
+ def.model = inputs.model;
282
+ }
283
+ if (inputs.checkType === 'targeted' || inputs.checkType === 'static') {
284
+ const checkTarget = {
285
+ type: inputs.checkType,
286
+ discovery: inputs.discovery,
287
+ };
288
+ if (inputs.discovery === 'semgrep') {
289
+ if (inputs.semgrepRules) {
290
+ const rules = inputs.semgrepRules.split(',').map((r) => r.trim()).filter(Boolean);
291
+ checkTarget.rules = rules.length === 1 ? rules[0] : rules;
292
+ }
293
+ else {
294
+ checkTarget.rules = `${inputs.id}.yaml`;
295
+ }
258
296
  }
259
- else {
260
- checkTarget.rules = `${inputs.id}.yaml`;
297
+ else if (inputs.discovery === 'sarif') {
298
+ checkTarget.sarifFile = inputs.sarifFile;
261
299
  }
262
300
  if (inputs.maxTargets) {
263
301
  checkTarget.maxTargets = parseInt(inputs.maxTargets, 10);
@@ -290,15 +328,18 @@ Options:
290
328
  --name <name> Human-readable check name (e.g. "XSS Prevention")
291
329
  --severity <level> Severity: critical, high, medium, low, informational
292
330
  --confidence <level> Confidence: high, medium, low
331
+ --model <model> AI model override for this check (e.g. claude-sonnet-4-6)
293
332
  --repositories <urls> Comma-separated repository URLs (empty = all repos)
294
333
  --check-overview <text> Description of what this check does
295
334
  --check-items <items> Comma-separated list of things to check
296
335
  --pass-condition <text> Condition for a PASS result
297
336
  --fail-condition <text> Condition for a FAIL result
298
337
  --flag-condition <text> Condition for a FLAG result (optional)
299
- --check-type <type> Check type: repository (default), semgrep, semgrep-only
300
- --semgrep-rules <paths> Comma-separated Semgrep rule file paths
301
- --max-targets <n> Maximum number of Semgrep targets to analyze
338
+ --check-type <type> Check type (default: repository). See 'Check types' below
339
+ --discovery <name> Discovery mechanism for targeted/static checks. See below
340
+ --semgrep-rules <paths> Comma-separated Semgrep rule file paths (for semgrep discovery)
341
+ --sarif-file <path> SARIF file path in check definition, relative to repo (for sarif discovery)
342
+ --max-targets <n> Maximum number of targets to analyze
302
343
  --language <lang> Language for Semgrep template: python, javascript, typescript
303
344
  -h, --help Show this help message
304
345
 
@@ -306,14 +347,20 @@ Environment variables:
306
347
  AGHAST_CONFIG_DIR Default config directory (CLI --config-dir takes precedence)
307
348
 
308
349
  Check types:
309
- repository AI analyzes the whole repository (no Semgrep)
310
- semgrep Semgrep finds targets, AI analyzes each one
311
- semgrep-only Semgrep findings mapped directly to issues (no AI)
350
+ repository AI analyzes the whole repository
351
+ targeted Discovery finds specific targets, AI analyzes each one
352
+ static Discovery finds targets, mapped directly to issues (no AI)
353
+
354
+ Discovery mechanisms:
355
+ semgrep Semgrep rules find targets (targeted or static)
356
+ openant OpenAnt code analysis finds units (targeted only)
357
+ sarif External SARIF file provides findings (targeted only)
312
358
 
313
359
  Examples:
314
360
  aghast new-check --config-dir ./my-checks
315
361
  aghast new-check --config-dir ./my-checks --id xss --name "XSS Prevention"
316
- aghast new-check --config-dir ./my-checks --check-type semgrep --language typescript`;
362
+ aghast new-check --config-dir ./my-checks --check-type targeted --discovery semgrep --language typescript
363
+ aghast new-check --config-dir ./my-checks --check-type targeted --discovery sarif --sarif-file ./sast-results.sarif`;
317
364
  export async function runNewCheck(args) {
318
365
  if (args.includes('--help') || args.includes('-h')) {
319
366
  console.log(NEW_CHECK_HELP);
@@ -362,14 +409,15 @@ export async function runNewCheck(args) {
362
409
  const checkDef = generateCheckDefinition(inputs);
363
410
  await writeFile(resolve(checkFolder, `${inputs.id}.json`), JSON.stringify(checkDef, null, 2) + '\n', 'utf-8');
364
411
  console.log(`Created: ${checkFolder}/${inputs.id}.json`);
365
- // Generate and write instructions.md (skipped for semgrep-only)
366
- if (inputs.checkType !== 'semgrep-only') {
412
+ // Generate and write instructions.md (only when instructions are needed)
413
+ const selfContainedDiscovery = inputs.discovery === 'openant' || inputs.discovery === 'sarif';
414
+ if (getCheckType(inputs.checkType).needsInstructions && !selfContainedDiscovery) {
367
415
  const markdown = generateMarkdown(inputs);
368
416
  await writeFile(resolve(checkFolder, `${inputs.id}.md`), markdown, 'utf-8');
369
417
  console.log(`Created: ${checkFolder}/${inputs.id}.md`);
370
418
  }
371
419
  // Generate Semgrep rule template and test file if needed
372
- if ((inputs.checkType === 'semgrep' || inputs.checkType === 'semgrep-only') && !inputs.semgrepRules) {
420
+ if (inputs.discovery === 'semgrep' && !inputs.semgrepRules) {
373
421
  const rulePath = resolve(checkFolder, `${inputs.id}.yaml`);
374
422
  await writeFile(rulePath, generateSemgrepRule(inputs.id, inputs.language), 'utf-8');
375
423
  console.log(`Created: ${checkFolder}/${inputs.id}.yaml (template — edit before running)`);