@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.
- package/LICENSE +661 -0
- package/README.md +127 -0
- package/assets/img/aghastowaspcaption.png +0 -0
- package/assets/txt/logo.txt +52 -0
- package/config/pricing.json +42 -0
- package/config/prompts/false-positive-validation.md +78 -0
- package/config/prompts/general-vuln-discovery.md +99 -0
- package/config/prompts/generic-instructions.md +59 -0
- package/config/prompts/test-cheaper-instructions.md +57 -0
- package/dist/budget.d.ts +62 -0
- package/dist/budget.d.ts.map +1 -0
- package/dist/budget.js +137 -0
- package/dist/budget.js.map +1 -0
- package/dist/build-config.d.ts +15 -0
- package/dist/build-config.d.ts.map +1 -0
- package/dist/build-config.js +568 -0
- package/dist/build-config.js.map +1 -0
- package/dist/check-library.d.ts +88 -0
- package/dist/check-library.d.ts.map +1 -0
- package/dist/check-library.js +461 -0
- package/dist/check-library.js.map +1 -0
- package/dist/check-types.d.ts +35 -0
- package/dist/check-types.d.ts.map +1 -0
- package/dist/check-types.js +66 -0
- package/dist/check-types.js.map +1 -0
- package/dist/claude-code-provider.d.ts +29 -0
- package/dist/claude-code-provider.d.ts.map +1 -0
- package/dist/claude-code-provider.js +347 -0
- package/dist/claude-code-provider.js.map +1 -0
- package/dist/cli.d.ts +13 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +109 -0
- package/dist/cli.js.map +1 -0
- package/dist/colors.d.ts +7 -0
- package/dist/colors.d.ts.map +1 -0
- package/dist/colors.js +18 -0
- package/dist/colors.js.map +1 -0
- package/dist/cost-calculator.d.ts +80 -0
- package/dist/cost-calculator.d.ts.map +1 -0
- package/dist/cost-calculator.js +226 -0
- package/dist/cost-calculator.js.map +1 -0
- package/dist/defaults.d.ts +21 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/defaults.js +21 -0
- package/dist/defaults.js.map +1 -0
- package/dist/diff-filter.d.ts +50 -0
- package/dist/diff-filter.d.ts.map +1 -0
- package/dist/diff-filter.js +130 -0
- package/dist/diff-filter.js.map +1 -0
- package/dist/diff-parser.d.ts +40 -0
- package/dist/diff-parser.d.ts.map +1 -0
- package/dist/diff-parser.js +112 -0
- package/dist/diff-parser.js.map +1 -0
- package/dist/diff-unit-matcher.d.ts +53 -0
- package/dist/diff-unit-matcher.d.ts.map +1 -0
- package/dist/diff-unit-matcher.js +156 -0
- package/dist/diff-unit-matcher.js.map +1 -0
- package/dist/discoveries/openant-discovery.d.ts +10 -0
- package/dist/discoveries/openant-discovery.d.ts.map +1 -0
- package/dist/discoveries/openant-discovery.js +56 -0
- package/dist/discoveries/openant-discovery.js.map +1 -0
- package/dist/discoveries/sarif-discovery.d.ts +9 -0
- package/dist/discoveries/sarif-discovery.d.ts.map +1 -0
- package/dist/discoveries/sarif-discovery.js +56 -0
- package/dist/discoveries/sarif-discovery.js.map +1 -0
- package/dist/discoveries/semgrep-discovery.d.ts +9 -0
- package/dist/discoveries/semgrep-discovery.d.ts.map +1 -0
- package/dist/discoveries/semgrep-discovery.js +61 -0
- package/dist/discoveries/semgrep-discovery.js.map +1 -0
- package/dist/discovery.d.ts +100 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +49 -0
- package/dist/discovery.js.map +1 -0
- package/dist/error-codes.d.ts +46 -0
- package/dist/error-codes.d.ts.map +1 -0
- package/dist/error-codes.js +70 -0
- package/dist/error-codes.js.map +1 -0
- package/dist/formatters/index.d.ts +10 -0
- package/dist/formatters/index.d.ts.map +1 -0
- package/dist/formatters/index.js +23 -0
- package/dist/formatters/index.js.map +1 -0
- package/dist/formatters/json-formatter.d.ts +11 -0
- package/dist/formatters/json-formatter.d.ts.map +1 -0
- package/dist/formatters/json-formatter.js +11 -0
- package/dist/formatters/json-formatter.js.map +1 -0
- package/dist/formatters/sarif-formatter.d.ts +18 -0
- package/dist/formatters/sarif-formatter.d.ts.map +1 -0
- package/dist/formatters/sarif-formatter.js +103 -0
- package/dist/formatters/sarif-formatter.js.map +1 -0
- package/dist/formatters/types.d.ts +11 -0
- package/dist/formatters/types.d.ts.map +1 -0
- package/dist/formatters/types.js +6 -0
- package/dist/formatters/types.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +754 -0
- package/dist/index.js.map +1 -0
- package/dist/logging.d.ts +140 -0
- package/dist/logging.d.ts.map +1 -0
- package/dist/logging.js +344 -0
- package/dist/logging.js.map +1 -0
- package/dist/mock-agent-provider.d.ts +24 -0
- package/dist/mock-agent-provider.d.ts.map +1 -0
- package/dist/mock-agent-provider.js +38 -0
- package/dist/mock-agent-provider.js.map +1 -0
- package/dist/mock-ai-provider.d.ts +21 -0
- package/dist/mock-ai-provider.d.ts.map +1 -0
- package/dist/mock-ai-provider.js +31 -0
- package/dist/mock-ai-provider.js.map +1 -0
- package/dist/new-check.d.ts +13 -0
- package/dist/new-check.d.ts.map +1 -0
- package/dist/new-check.js +515 -0
- package/dist/new-check.js.map +1 -0
- package/dist/openant-loader.d.ts +105 -0
- package/dist/openant-loader.d.ts.map +1 -0
- package/dist/openant-loader.js +135 -0
- package/dist/openant-loader.js.map +1 -0
- package/dist/openant-runner.d.ts +30 -0
- package/dist/openant-runner.d.ts.map +1 -0
- package/dist/openant-runner.js +113 -0
- package/dist/openant-runner.js.map +1 -0
- package/dist/opencode-provider.d.ts +63 -0
- package/dist/opencode-provider.d.ts.map +1 -0
- package/dist/opencode-provider.js +719 -0
- package/dist/opencode-provider.js.map +1 -0
- package/dist/prompt-template.d.ts +12 -0
- package/dist/prompt-template.d.ts.map +1 -0
- package/dist/prompt-template.js +36 -0
- package/dist/prompt-template.js.map +1 -0
- package/dist/provider-registry.d.ts +15 -0
- package/dist/provider-registry.d.ts.map +1 -0
- package/dist/provider-registry.js +29 -0
- package/dist/provider-registry.js.map +1 -0
- package/dist/provider-utils.d.ts +52 -0
- package/dist/provider-utils.d.ts.map +1 -0
- package/dist/provider-utils.js +40 -0
- package/dist/provider-utils.js.map +1 -0
- package/dist/repository-analyzer.d.ts +68 -0
- package/dist/repository-analyzer.d.ts.map +1 -0
- package/dist/repository-analyzer.js +238 -0
- package/dist/repository-analyzer.js.map +1 -0
- package/dist/response-parser.d.ts +14 -0
- package/dist/response-parser.d.ts.map +1 -0
- package/dist/response-parser.js +111 -0
- package/dist/response-parser.js.map +1 -0
- package/dist/runtime-config.d.ts +15 -0
- package/dist/runtime-config.d.ts.map +1 -0
- package/dist/runtime-config.js +187 -0
- package/dist/runtime-config.js.map +1 -0
- package/dist/sarif-parser.d.ts +20 -0
- package/dist/sarif-parser.d.ts.map +1 -0
- package/dist/sarif-parser.js +76 -0
- package/dist/sarif-parser.js.map +1 -0
- package/dist/scan-history.d.ts +82 -0
- package/dist/scan-history.d.ts.map +1 -0
- package/dist/scan-history.js +127 -0
- package/dist/scan-history.js.map +1 -0
- package/dist/scan-runner.d.ts +122 -0
- package/dist/scan-runner.d.ts.map +1 -0
- package/dist/scan-runner.js +928 -0
- package/dist/scan-runner.js.map +1 -0
- package/dist/semgrep-runner.d.ts +25 -0
- package/dist/semgrep-runner.d.ts.map +1 -0
- package/dist/semgrep-runner.js +100 -0
- package/dist/semgrep-runner.js.map +1 -0
- package/dist/snippet-extractor.d.ts +25 -0
- package/dist/snippet-extractor.d.ts.map +1 -0
- package/dist/snippet-extractor.js +56 -0
- package/dist/snippet-extractor.js.map +1 -0
- package/dist/stats.d.ts +11 -0
- package/dist/stats.d.ts.map +1 -0
- package/dist/stats.js +197 -0
- package/dist/stats.js.map +1 -0
- package/dist/types.d.ts +321 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +19 -0
- package/dist/types.js.map +1 -0
- 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
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/colors.d.ts
ADDED
|
@@ -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"}
|