@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,66 @@
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
+ // --- Check Type Definitions ---
12
+ const REPOSITORY = {
13
+ type: 'repository',
14
+ needsAI: true,
15
+ needsInstructions: true,
16
+ supportsMaxTargets: false,
17
+ };
18
+ const TARGETED = {
19
+ type: 'targeted',
20
+ needsAI: true,
21
+ needsInstructions: true,
22
+ supportsMaxTargets: true,
23
+ };
24
+ const STATIC = {
25
+ type: 'static',
26
+ needsAI: false,
27
+ needsInstructions: false,
28
+ supportsMaxTargets: true,
29
+ };
30
+ /** All registered check types, keyed by their type string. */
31
+ const CHECK_TYPES = new Map([
32
+ [REPOSITORY.type, REPOSITORY],
33
+ [TARGETED.type, TARGETED],
34
+ [STATIC.type, STATIC],
35
+ ]);
36
+ /**
37
+ * Default descriptor used when the type is unknown or undefined.
38
+ * Conservative defaults: requires AI and instructions (the common case).
39
+ */
40
+ const DEFAULT_DESCRIPTOR = {
41
+ type: '',
42
+ needsAI: true,
43
+ needsInstructions: true,
44
+ supportsMaxTargets: false,
45
+ };
46
+ // --- Public API ---
47
+ /**
48
+ * Get the descriptor for a check type string.
49
+ * Returns conservative defaults for unknown/undefined types.
50
+ */
51
+ export function getCheckType(type) {
52
+ if (!type)
53
+ return DEFAULT_DESCRIPTOR;
54
+ return CHECK_TYPES.get(type) ?? DEFAULT_DESCRIPTOR;
55
+ }
56
+ /** All valid check type strings. */
57
+ export function getValidCheckTypes() {
58
+ return [...CHECK_TYPES.keys()];
59
+ }
60
+ /** Check type string constants for use in routing (scan-runner switch). */
61
+ export const CHECK_TYPE = {
62
+ REPOSITORY: REPOSITORY.type,
63
+ TARGETED: TARGETED.type,
64
+ STATIC: STATIC.type,
65
+ };
66
+ //# sourceMappingURL=check-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-types.js","sourceRoot":"","sources":["../src/check-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAcH,iCAAiC;AAEjC,MAAM,UAAU,GAAwB;IACtC,IAAI,EAAE,YAAY;IAClB,OAAO,EAAE,IAAI;IACb,iBAAiB,EAAE,IAAI;IACvB,kBAAkB,EAAE,KAAK;CAC1B,CAAC;AAEF,MAAM,QAAQ,GAAwB;IACpC,IAAI,EAAE,UAAU;IAChB,OAAO,EAAE,IAAI;IACb,iBAAiB,EAAE,IAAI;IACvB,kBAAkB,EAAE,IAAI;CACzB,CAAC;AAEF,MAAM,MAAM,GAAwB;IAClC,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,KAAK;IACd,iBAAiB,EAAE,KAAK;IACxB,kBAAkB,EAAE,IAAI;CACzB,CAAC;AAEF,8DAA8D;AAC9D,MAAM,WAAW,GAA6C,IAAI,GAAG,CAAC;IACpE,CAAC,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC;IAC7B,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACzB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,kBAAkB,GAAwB;IAC9C,IAAI,EAAE,EAAE;IACR,OAAO,EAAE,IAAI;IACb,iBAAiB,EAAE,IAAI;IACvB,kBAAkB,EAAE,KAAK;CAC1B,CAAC;AAEF,qBAAqB;AAErB;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,IAAwB;IACnD,IAAI,CAAC,IAAI;QAAE,OAAO,kBAAkB,CAAC;IACrC,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,kBAAkB,CAAC;AACrD,CAAC;AAED,oCAAoC;AACpC,MAAM,UAAU,kBAAkB;IAChC,OAAO,CAAC,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;AACjC,CAAC;AAED,2EAA2E;AAC3E,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,UAAU,EAAE,UAAU,CAAC,IAAI;IAC3B,QAAQ,EAAE,QAAQ,CAAC,IAAI;IACvB,MAAM,EAAE,MAAM,CAAC,IAAI;CACX,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Claude Code agent provider implementation.
3
+ * Uses @anthropic-ai/claude-agent-sdk per spec Section 6.2 / Appendix C.8.
4
+ */
5
+ import type { AgentProvider, AgentResponse, ProviderConfig, ProviderModelInfo } from './types.js';
6
+ /** Type for the SDK query function — injectable for testing. */
7
+ export type QueryFn = (params: {
8
+ prompt: string;
9
+ options: Record<string, unknown>;
10
+ }) => AsyncIterable<Record<string, unknown>>;
11
+ export declare class ClaudeCodeProvider implements AgentProvider {
12
+ private apiKey;
13
+ private useLocalClaude;
14
+ private model;
15
+ private _queryFn;
16
+ constructor(options?: {
17
+ _queryFn?: QueryFn;
18
+ });
19
+ checkPrerequisites(): void;
20
+ initialize(config: ProviderConfig): Promise<void>;
21
+ getModelName(): string;
22
+ setModel(model: string): void;
23
+ listModels(): Promise<readonly ProviderModelInfo[]>;
24
+ executeCheck(instructions: string, repositoryPath: string, logPrefix?: string, options?: {
25
+ maxTurns?: number;
26
+ }): Promise<AgentResponse>;
27
+ validateConfig(): Promise<boolean>;
28
+ }
29
+ //# sourceMappingURL=claude-code-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code-provider.d.ts","sourceRoot":"","sources":["../src/claude-code-provider.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAiB,iBAAiB,EAAc,MAAM,YAAY,CAAC;AA8D7H,gEAAgE;AAChE,MAAM,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC,KAAK,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAE7C,qBAAa,kBAAmB,YAAW,aAAa;IACtD,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,QAAQ,CAAsB;gBAC1B,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE;IAI5C,kBAAkB,IAAI,IAAI;IAMpB,UAAU,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBvD,YAAY,IAAI,MAAM;IAItB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIvB,UAAU,IAAI,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC;IAcnD,YAAY,CAChB,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,EACtB,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAC9B,OAAO,CAAC,aAAa,CAAC;IAyQnB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;CAGzC"}
@@ -0,0 +1,347 @@
1
+ /**
2
+ * Claude Code agent provider implementation.
3
+ * Uses @anthropic-ai/claude-agent-sdk per spec Section 6.2 / Appendix C.8.
4
+ */
5
+ import { DEFAULT_MODEL, FatalProviderError } from './types.js';
6
+ // import { parseAgentResponse } from './response-parser.js';
7
+ import { logProgress, logDebug, logDebugFull, createTimer, getLogLevel } from './logging.js';
8
+ import { OUTPUT_SCHEMA } from './provider-utils.js';
9
+ const TAG = 'agent-provider';
10
+ /** Hit the Anthropic API /v1/models endpoint (full canonical model list). */
11
+ async function listModelsViaApiKey(apiKey) {
12
+ const { default: Anthropic } = await import('@anthropic-ai/sdk');
13
+ const client = new Anthropic({ apiKey });
14
+ const out = [];
15
+ // `limit` is the page size, NOT a total cap — `for await` keeps fetching pages
16
+ // via the SDK's auto-pagination until the server reports no more.
17
+ for await (const m of client.models.list({ limit: 100 })) {
18
+ out.push({ id: m.id, label: m.display_name });
19
+ }
20
+ return out;
21
+ }
22
+ /** Ask the Claude Code agent SDK for its curated alias list (works with local-Claude auth).
23
+ *
24
+ * The SDK's `supportedModels()` is only available on a `Query` instance, not as a static
25
+ * call, so we have to spin up a streaming-input query just to issue one control request.
26
+ * The async generator never yields — we just await `block` so the SDK doesn't think the
27
+ * input stream has ended, then `interrupt()` it after `supportedModels()` returns.
28
+ *
29
+ * Best-effort cleanup: `release()` ends the prompt generator, then `interrupt()` cancels
30
+ * the query. Both are wrapped in a 5s timeout so a misbehaving SDK can't hang the CLI.
31
+ */
32
+ async function listModelsViaAgentSdk() {
33
+ const { query } = await import('@anthropic-ai/claude-agent-sdk');
34
+ let release;
35
+ const block = new Promise((resolve) => {
36
+ release = resolve;
37
+ });
38
+ // eslint-disable-next-line require-yield -- intentional: streaming-input prompt that never yields, kept alive by `block` so `supportedModels()` can run.
39
+ const prompt = (async function* () {
40
+ await block;
41
+ await new Promise(() => { });
42
+ })();
43
+ const q = query({ prompt, options: {} });
44
+ try {
45
+ const models = await q.supportedModels();
46
+ return models.map((m) => ({
47
+ id: m.value,
48
+ label: m.displayName,
49
+ description: m.description,
50
+ }));
51
+ }
52
+ finally {
53
+ release?.();
54
+ await Promise.race([
55
+ q.interrupt().catch(() => undefined),
56
+ new Promise((resolve) => setTimeout(resolve, 5000)),
57
+ ]);
58
+ }
59
+ }
60
+ const HEARTBEAT_INTERVAL_MS = 15000; // Log heartbeat every 15s if no activity
61
+ const MAX_API_ERROR_RETRIES = 3; // Fail after this many consecutive API errors
62
+ const MAX_ERROR_DETECTION_LENGTH = 200; // Only check short text chunks for SDK error patterns — longer text is AI analysis content
63
+ export class ClaudeCodeProvider {
64
+ apiKey;
65
+ useLocalClaude = false;
66
+ model = DEFAULT_MODEL;
67
+ _queryFn;
68
+ constructor(options) {
69
+ this._queryFn = options?._queryFn;
70
+ }
71
+ checkPrerequisites() {
72
+ if (!process.env.ANTHROPIC_API_KEY && process.env.AGHAST_LOCAL_CLAUDE !== 'true') {
73
+ throw new Error('ANTHROPIC_API_KEY environment variable is required');
74
+ }
75
+ }
76
+ async initialize(config) {
77
+ this.useLocalClaude = process.env.AGHAST_LOCAL_CLAUDE === 'true';
78
+ this.apiKey = config.apiKey ?? process.env.ANTHROPIC_API_KEY;
79
+ // Model selection priority: config.model (from AGHAST_AI_MODEL env or runtime config) > DEFAULT_MODEL
80
+ if (config.model) {
81
+ this.model = config.model;
82
+ }
83
+ if (!this.apiKey && !this.useLocalClaude) {
84
+ throw new Error('ANTHROPIC_API_KEY is required');
85
+ }
86
+ if (this.useLocalClaude) {
87
+ logProgress(TAG, 'Using local Claude Code session for authentication');
88
+ }
89
+ else {
90
+ logDebug(TAG, 'Using API key for authentication');
91
+ }
92
+ logDebug(TAG, `Provider initialized with model ${this.model}`);
93
+ }
94
+ getModelName() {
95
+ return this.model;
96
+ }
97
+ setModel(model) {
98
+ this.model = model;
99
+ }
100
+ async listModels() {
101
+ // Tier 1: if ANTHROPIC_API_KEY is set, hit /v1/models for the full canonical list.
102
+ const apiKey = this.apiKey ?? process.env.ANTHROPIC_API_KEY;
103
+ if (apiKey) {
104
+ try {
105
+ return await listModelsViaApiKey(apiKey);
106
+ }
107
+ catch (err) {
108
+ logDebug(TAG, `models.list() via API key failed, falling back to agent-SDK: ${err instanceof Error ? err.message : String(err)}`);
109
+ }
110
+ }
111
+ // Tier 2: ask the Claude Code agent SDK for its curated list (works with local Claude auth).
112
+ return await listModelsViaAgentSdk();
113
+ }
114
+ async executeCheck(instructions, repositoryPath, logPrefix, options) {
115
+ const queryFn = this._queryFn ?? (await import('@anthropic-ai/claude-agent-sdk')).query;
116
+ const timer = createTimer();
117
+ const prefix = logPrefix ? `${logPrefix} ` : '';
118
+ const effectiveMaxTurns = options?.maxTurns ?? 100;
119
+ const prompt = instructions;
120
+ logDebug(TAG, `${prefix}Starting query: model=${this.model}, cwd=${repositoryPath}, promptLen=${prompt.length}, maxTurns=${effectiveMaxTurns}`);
121
+ logDebugFull(TAG, `${prefix}Full prompt sent to AI`, prompt);
122
+ const conversation = queryFn({
123
+ prompt,
124
+ options: {
125
+ model: this.model,
126
+ cwd: repositoryPath,
127
+ allowedTools: ['Read', 'Glob', 'Grep'],
128
+ maxTurns: effectiveMaxTurns,
129
+ permissionMode: 'bypassPermissions',
130
+ outputFormat: {
131
+ type: 'json_schema',
132
+ schema: OUTPUT_SCHEMA,
133
+ },
134
+ },
135
+ });
136
+ // Consume all messages from the async generator to get the result
137
+ let resultText = '';
138
+ let structuredOutput;
139
+ let errorMessage;
140
+ let turnCount = 0;
141
+ let toolCallCount = 0;
142
+ let tokenUsage;
143
+ let consecutiveApiErrors = 0;
144
+ let currentToolName;
145
+ let lastActivityTime = Date.now();
146
+ const trace = getLogLevel() === 'trace';
147
+ // Background heartbeat timer - logs if no activity for a while
148
+ const heartbeatInterval = setInterval(() => {
149
+ const silentSeconds = Math.round((Date.now() - lastActivityTime) / 1000);
150
+ if (silentSeconds >= HEARTBEAT_INTERVAL_MS / 1000) {
151
+ const status = currentToolName ? `running ${currentToolName}` : 'waiting';
152
+ logDebug(TAG, `${prefix}Still ${status}... (${timer.elapsedStr()})`);
153
+ }
154
+ }, HEARTBEAT_INTERVAL_MS);
155
+ try {
156
+ for await (const message of conversation) {
157
+ lastActivityTime = Date.now();
158
+ // Tool progress events - emitted during long-running tool executions
159
+ if (message.type === 'tool_progress') {
160
+ const progress = message;
161
+ currentToolName = progress.tool_name;
162
+ logDebug(TAG, `${prefix}Running ${progress.tool_name}... (${Math.round(progress.elapsed_time_seconds)}s)`);
163
+ }
164
+ if (message.type === 'assistant') {
165
+ turnCount++;
166
+ currentToolName = undefined;
167
+ // Activity indicator at debug level (scan-runner provides periodic summary at info)
168
+ logDebug(TAG, `${prefix}Turn ${turnCount} (${timer.elapsedStr()})`);
169
+ const content = message.message?.content;
170
+ if (Array.isArray(content)) {
171
+ // Count and log tool calls at debug level (compact)
172
+ for (const block of content) {
173
+ if (block?.type === 'tool_use') {
174
+ toolCallCount++;
175
+ currentToolName = block.name;
176
+ const inputStr = JSON.stringify(block.input);
177
+ const inputPreview = inputStr.length > 100 ? inputStr.slice(0, 100) + '...' : inputStr;
178
+ logDebug(TAG, `${prefix}Tool[${toolCallCount}]: ${block.name} ${inputPreview}`);
179
+ if (trace && inputStr.length > 100)
180
+ logDebugFull(TAG, `${prefix}Full tool call input`, inputStr);
181
+ }
182
+ }
183
+ // Log thinking blocks
184
+ const thinkingBlocks = content.filter((c) => c?.type === 'thinking' && typeof c.thinking === 'string').map((c) => c.thinking.trim()).filter(Boolean);
185
+ for (const thinking of thinkingBlocks) {
186
+ logDebug(TAG, `${prefix}Thinking: [${thinking.length} chars] ${thinking.slice(0, 100)}...`);
187
+ if (trace)
188
+ logDebugFull(TAG, `${prefix}Full thinking block`, thinking);
189
+ }
190
+ // Log assistant text at debug level
191
+ const textChunks = content
192
+ .filter((c) => c?.type === 'text' && typeof c.text === 'string')
193
+ .map((c) => c.text.trim())
194
+ .filter(Boolean);
195
+ if (textChunks.length > 0) {
196
+ for (const chunk of textChunks) {
197
+ if (chunk.length > 200) {
198
+ logDebug(TAG, `${prefix}Assistant: [${chunk.length} chars] ${chunk.slice(0, 100)}...`);
199
+ if (trace)
200
+ logDebugFull(TAG, `${prefix}Full assistant text`, chunk);
201
+ }
202
+ else {
203
+ logDebug(TAG, `${prefix}Assistant: ${chunk}`);
204
+ }
205
+ }
206
+ // Error detection: only check short text chunks to avoid matching the AI's
207
+ // own analysis text (e.g., a security finding mentioning "rate limiting").
208
+ // SDK/API error messages are typically short (under 200 chars), while AI analysis
209
+ // text is much longer.
210
+ const shortChunks = textChunks.filter((t) => t.length < MAX_ERROR_DETECTION_LENGTH);
211
+ // Detect rate-limit messages — fail immediately since retrying won't help.
212
+ const rateLimitMatch = shortChunks.find((t) => /you've hit your limit|API Error:\s*429|rate.?limit.?exceeded/i.test(t));
213
+ if (rateLimitMatch) {
214
+ throw new FatalProviderError(`Agent provider rate limit reached: ${rateLimitMatch}`);
215
+ }
216
+ // Detect authentication errors (401) — fail immediately, unrecoverable
217
+ const authErrorMatch = shortChunks.find((t) => /API Error:\s*401/i.test(t));
218
+ if (authErrorMatch) {
219
+ throw new FatalProviderError(`Agent provider authentication failed (401): ${authErrorMatch}`);
220
+ }
221
+ // Detect login required — fail immediately, unrecoverable without user action
222
+ const loginRequiredMatch = shortChunks.find((t) => /not logged in/i.test(t));
223
+ if (loginRequiredMatch) {
224
+ throw new FatalProviderError(`Agent provider not logged in: ${loginRequiredMatch}. Please authenticate before running scans.`);
225
+ }
226
+ // Detect API errors surfaced as assistant text by the SDK
227
+ const apiErrorMatch = shortChunks.find((t) => t.includes('API Error:'));
228
+ if (apiErrorMatch) {
229
+ consecutiveApiErrors++;
230
+ if (consecutiveApiErrors >= MAX_API_ERROR_RETRIES) {
231
+ throw new Error(`Agent provider API error (after ${MAX_API_ERROR_RETRIES} attempts): ${apiErrorMatch}`);
232
+ }
233
+ }
234
+ else {
235
+ consecutiveApiErrors = 0;
236
+ }
237
+ }
238
+ }
239
+ }
240
+ if (message.type === 'tool_result') {
241
+ const toolResult = message;
242
+ const outputText = toolResult.content?.filter((c) => c.type === 'text').map((c) => c.text).join('\n') ?? '(no output)';
243
+ const isMultiline = outputText.includes('\n');
244
+ const preview = outputText.length > 300 ? outputText.slice(0, 300) + '...' : outputText;
245
+ if (isMultiline || outputText.length > 300) {
246
+ logDebug(TAG, `${prefix}Tool result [${outputText.length} chars]: ${preview}`);
247
+ if (trace)
248
+ logDebugFull(TAG, `${prefix}Full tool result`, outputText);
249
+ }
250
+ else {
251
+ logDebug(TAG, `${prefix}Tool result: ${outputText}`);
252
+ }
253
+ }
254
+ if (message.type === 'result') {
255
+ if (message.subtype === 'success') {
256
+ resultText = message.result;
257
+ // Extract structured output if available
258
+ const resultMsg = message;
259
+ if (resultMsg.structured_output) {
260
+ structuredOutput = resultMsg.structured_output;
261
+ logDebug(TAG, `${prefix}Structured output: ${structuredOutput.issues.length} issues`);
262
+ }
263
+ // Extract token usage if available.
264
+ // Prefer modelUsage (camelCase, per-model breakdown) over usage (snake_case, raw API).
265
+ // Always use total_cost_usd from the result message as the authoritative cost.
266
+ if (resultMsg.modelUsage && Object.keys(resultMsg.modelUsage).length > 0) {
267
+ let inputTokens = 0;
268
+ let outputTokens = 0;
269
+ let cacheCreationInputTokens;
270
+ let cacheReadInputTokens;
271
+ for (const model of Object.values(resultMsg.modelUsage)) {
272
+ inputTokens += model.inputTokens;
273
+ outputTokens += model.outputTokens;
274
+ if (model.cacheCreationInputTokens !== undefined) {
275
+ cacheCreationInputTokens = (cacheCreationInputTokens ?? 0) + model.cacheCreationInputTokens;
276
+ }
277
+ if (model.cacheReadInputTokens !== undefined) {
278
+ cacheReadInputTokens = (cacheReadInputTokens ?? 0) + model.cacheReadInputTokens;
279
+ }
280
+ }
281
+ tokenUsage = {
282
+ inputTokens,
283
+ outputTokens,
284
+ cacheCreationInputTokens,
285
+ cacheReadInputTokens,
286
+ totalTokens: inputTokens + outputTokens,
287
+ ...(resultMsg.total_cost_usd !== undefined
288
+ ? { reportedCost: { amountUsd: resultMsg.total_cost_usd, source: 'claude-agent-sdk', ...(this.useLocalClaude ? { coveredBySubscription: true } : {}) } }
289
+ : {}),
290
+ };
291
+ logDebug(TAG, `${prefix}Token usage: ${tokenUsage.inputTokens} in, ${tokenUsage.outputTokens} out, ${cacheReadInputTokens ?? 0} cache-read, ${cacheCreationInputTokens ?? 0} cache-write, $${resultMsg.total_cost_usd ?? 0} reported`);
292
+ }
293
+ else if (resultMsg.usage) {
294
+ const cacheCreation = resultMsg.usage.cache_creation_input_tokens;
295
+ const cacheRead = resultMsg.usage.cache_read_input_tokens;
296
+ tokenUsage = {
297
+ inputTokens: resultMsg.usage.input_tokens,
298
+ outputTokens: resultMsg.usage.output_tokens,
299
+ ...(cacheCreation !== undefined ? { cacheCreationInputTokens: cacheCreation } : {}),
300
+ ...(cacheRead !== undefined ? { cacheReadInputTokens: cacheRead } : {}),
301
+ totalTokens: resultMsg.usage.input_tokens + resultMsg.usage.output_tokens,
302
+ ...(resultMsg.total_cost_usd !== undefined
303
+ ? { reportedCost: { amountUsd: resultMsg.total_cost_usd, source: 'claude-agent-sdk', ...(this.useLocalClaude ? { coveredBySubscription: true } : {}) } }
304
+ : {}),
305
+ };
306
+ logDebug(TAG, `${prefix}Token usage: ${tokenUsage.inputTokens} in, ${tokenUsage.outputTokens} out, ${cacheRead ?? 0} cache-read, ${cacheCreation ?? 0} cache-write, $${resultMsg.total_cost_usd ?? 0} reported`);
307
+ }
308
+ logProgress(TAG, `${prefix}Completed in ${timer.elapsedStr()} (${turnCount} turns, ${toolCallCount} tool calls)`);
309
+ }
310
+ else {
311
+ const errorResult = message;
312
+ errorMessage = errorResult.errors?.join('; ') ?? `Agent provider error: ${errorResult.subtype}`;
313
+ logProgress(TAG, `${prefix}Failed: ${errorResult.subtype} (${timer.elapsedStr()})`);
314
+ }
315
+ }
316
+ }
317
+ }
318
+ finally {
319
+ clearInterval(heartbeatInterval);
320
+ }
321
+ if (errorMessage) {
322
+ logDebug(TAG, `${prefix}Error: ${errorMessage}`);
323
+ throw new Error(errorMessage);
324
+ }
325
+ if (!resultText && !structuredOutput && !errorMessage) {
326
+ throw new Error('Agent provider returned no result');
327
+ }
328
+ logDebug(TAG, `${prefix}Result: ${resultText.length} chars`);
329
+ logDebugFull(TAG, `${prefix}Full AI response`, resultText);
330
+ // Structured output from SDK is required - we enforce JSON schema output mode.
331
+ // The response parser (parseAgentResponse) is kept in the codebase as a potential
332
+ // fallback for future use cases (e.g., alternative agent providers that don't support
333
+ // structured output), but this provider always requires structured output.
334
+ if (structuredOutput) {
335
+ return { raw: resultText, parsed: structuredOutput, tokenUsage };
336
+ }
337
+ // No fallback parsing - structured output is mandatory for this provider.
338
+ // If needed in the future, uncomment:
339
+ // const parsed = parseAgentResponse(resultText);
340
+ // return { raw: resultText, parsed: parsed ?? undefined };
341
+ throw new Error('Agent provider did not return structured output');
342
+ }
343
+ async validateConfig() {
344
+ return !!this.apiKey || this.useLocalClaude;
345
+ }
346
+ }
347
+ //# sourceMappingURL=claude-code-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code-provider.js","sourceRoot":"","sources":["../src/claude-code-provider.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Unified CLI entry point for aghast.
4
+ * Subcommand router: delegates to `scan` or `new-check`.
5
+ *
6
+ * Usage:
7
+ * aghast scan <repo-path> [options]
8
+ * aghast new-check [options]
9
+ * aghast --help
10
+ * aghast --version
11
+ */
12
+ import 'dotenv/config';
13
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG;AAEH,OAAO,eAAe,CAAC"}
package/dist/cli.js ADDED
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Unified CLI entry point for aghast.
4
+ * Subcommand router: delegates to `scan` or `new-check`.
5
+ *
6
+ * Usage:
7
+ * aghast scan <repo-path> [options]
8
+ * aghast new-check [options]
9
+ * aghast --help
10
+ * aghast --version
11
+ */
12
+ import 'dotenv/config';
13
+ import { createRequire } from 'node:module';
14
+ import { readFileSync } from 'node:fs';
15
+ import { resolve, dirname } from 'node:path';
16
+ import { fileURLToPath } from 'node:url';
17
+ import { ERROR_CODES, formatError, formatFatalError } from './error-codes.js';
18
+ // Signal to subcommand modules that they're being imported, not run directly
19
+ process.env._AGHAST_CLI = '1';
20
+ const USAGE = `Usage: aghast <command> [options]
21
+
22
+ Commands:
23
+ scan Run security checks against a repository
24
+ new-check Scaffold a new security check
25
+ build-config Build or edit a runtime-config.json (interactive or flag-driven)
26
+ stats Print a cost summary from the scan history
27
+
28
+ Options:
29
+ --help Show this help message
30
+ --version Show version number
31
+
32
+ Run 'aghast <command> --help' for more information on a command.`;
33
+ function getVersion() {
34
+ const require = createRequire(import.meta.url);
35
+ const pkg = require('../package.json');
36
+ return pkg.version;
37
+ }
38
+ function printVersion() {
39
+ console.log(getVersion());
40
+ }
41
+ function printLogo() {
42
+ const __dirname = dirname(fileURLToPath(import.meta.url));
43
+ const logoPath = resolve(__dirname, '..', 'assets', 'txt', 'logo.txt');
44
+ try {
45
+ const logo = readFileSync(logoPath, 'utf-8');
46
+ console.log(logo);
47
+ }
48
+ catch {
49
+ // Logo file not found — continue without it
50
+ }
51
+ }
52
+ async function main() {
53
+ // Graceful shutdown on POSIX signals
54
+ process.on('SIGINT', () => {
55
+ process.exit(130);
56
+ });
57
+ process.on('SIGTERM', () => {
58
+ process.exit(143);
59
+ });
60
+ const args = process.argv.slice(2);
61
+ const command = args[0];
62
+ // Skip the logo for `stats --json` so machine-readable output is parseable.
63
+ const isStatsJson = command === 'stats' && args.includes('--json');
64
+ if (!isStatsJson) {
65
+ printLogo();
66
+ }
67
+ if (!command || command === '--help' || command === '-h') {
68
+ console.log(USAGE);
69
+ process.exit(0);
70
+ }
71
+ if (command === '--version' || command === '-V') {
72
+ printVersion();
73
+ process.exit(0);
74
+ }
75
+ const subArgs = args.slice(1);
76
+ switch (command) {
77
+ case 'scan': {
78
+ const { runScan } = await import('./index.js');
79
+ await runScan(subArgs);
80
+ break;
81
+ }
82
+ case 'new-check': {
83
+ const { runNewCheck } = await import('./new-check.js');
84
+ await runNewCheck(subArgs);
85
+ break;
86
+ }
87
+ case 'build-config': {
88
+ const { runBuildConfig } = await import('./build-config.js');
89
+ await runBuildConfig(subArgs);
90
+ break;
91
+ }
92
+ case 'stats': {
93
+ const { runStats } = await import('./stats.js');
94
+ await runStats(subArgs);
95
+ break;
96
+ }
97
+ default:
98
+ console.error(formatError(ERROR_CODES.E1002, `Unknown command: ${command}`));
99
+ console.error('');
100
+ console.error(USAGE);
101
+ process.exit(1);
102
+ }
103
+ }
104
+ main().catch((err) => {
105
+ console.error('');
106
+ console.error(formatFatalError(err instanceof Error ? err.message : String(err), getVersion()));
107
+ process.exit(1);
108
+ });
109
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Color helpers for CLI output.
3
+ * Uses picocolors which automatically respects NO_COLOR env var and non-TTY.
4
+ */
5
+ export declare function colorStatus(status: string): string;
6
+ export declare function colorError(message: string): string;
7
+ //# sourceMappingURL=colors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../src/colors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAQlD;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAElD"}
package/dist/colors.js ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Color helpers for CLI output.
3
+ * Uses picocolors which automatically respects NO_COLOR env var and non-TTY.
4
+ */
5
+ import pc from 'picocolors';
6
+ export function colorStatus(status) {
7
+ switch (status) {
8
+ case 'NO ISSUES DETECTED': return pc.green(status);
9
+ case 'ISSUES DETECTED': return pc.red(status);
10
+ case 'REVIEW REQUIRED': return pc.yellow(status);
11
+ case 'SCAN ERROR': return pc.red(status);
12
+ default: return status;
13
+ }
14
+ }
15
+ export function colorError(message) {
16
+ return pc.red(message);
17
+ }
18
+ //# sourceMappingURL=colors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.js","sourceRoot":"","sources":["../src/colors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,UAAU,WAAW,CAAC,MAAc;IACxC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,oBAAoB,CAAC,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACnD,KAAK,iBAAiB,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC9C,KAAK,iBAAiB,CAAC,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACjD,KAAK,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACzC,OAAO,CAAC,CAAC,OAAO,MAAM,CAAC;IACzB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,OAAe;IACxC,OAAO,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AACzB,CAAC"}