@codacy/analysis-runner 0.11.0 → 0.13.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/README.md CHANGED
@@ -1,7 +1,9 @@
1
1
  # @codacy/analysis-runner
2
2
 
3
3
  ## Table of Contents
4
+
4
5
  - [Overview](#overview)
6
+ - [Quick start](#quick-start)
5
7
  - [API](#api)
6
8
  - [Pipeline steps](#pipeline-steps)
7
9
  - [Output formats](#output-formats)
@@ -13,17 +15,90 @@
13
15
 
14
16
  Core orchestration engine for the Codacy Analysis CLI. Discovers tools, checks capabilities, calls `analyze()` on each adapter, aggregates results, and transforms output. Usable programmatically by both the CLI and IDE integrations.
15
17
 
18
+ ## Quick start
19
+
20
+ Tool adapters live in a companion preset package, **`@codacy/analysis-adapters`**. A
21
+ consumer installs both and registers the built-in adapters **once** before running
22
+ anything tool-related — the runner's adapter registry starts empty and nothing
23
+ auto-populates it.
24
+
25
+ ```ts
26
+ import { registerBuiltinAdapters } from "@codacy/analysis-adapters";
27
+ import { analyze, createNullLogger } from "@codacy/analysis-runner";
28
+
29
+ // Register all built-in tools + cloud-only descriptors (call once at startup).
30
+ registerBuiltinAdapters();
31
+
32
+ // Run analysis. `repositoryRoot` must be a git work tree.
33
+ const result = await analyze({
34
+ repositoryRoot: "/abs/path/to/repo",
35
+ // files: ["src/index.ts"], // optional: scope to specific files
36
+ logger: createNullLogger(), // or bring your own Logger (see below)
37
+ });
38
+
39
+ // Issue paths are repo-relative; line/column are 1-based.
40
+ for (const issue of result.issues) {
41
+ console.log(
42
+ `${issue.filePath}:${issue.line}:${issue.column} ${issue.patternId} ${issue.message}`,
43
+ );
44
+ }
45
+ ```
46
+
47
+ To register only a subset of tools, import `builtinAdapterEntries` from the preset and
48
+ call `registerLazyAdapter(descriptor, load)` for the ones you want.
49
+
50
+ ### Creating a config
51
+
52
+ `analyze()` reads `.codacy/codacy.config.json`. Generate one programmatically with the
53
+ `init*` family — they build a `CodacyConfig` from the registered adapters; `writeCodacyConfig`
54
+ persists it:
55
+
56
+ ```ts
57
+ import {
58
+ getRegisteredAdapters,
59
+ initLocalConfig, // local-config detection only (offline)
60
+ // initDefaultConfig / initAutoConfig / initRemoteConfig also available
61
+ writeCodacyConfig,
62
+ } from "@codacy/analysis-runner";
63
+
64
+ const adapters = await getRegisteredAdapters();
65
+ const { config } = await initLocalConfig(repositoryRoot, adapters);
66
+ await writeCodacyConfig(repositoryRoot, config);
67
+ ```
68
+
69
+ `initAutoConfig` additionally takes the registered descriptors (`getRegisteredDescriptors()`)
70
+ and the preset's `loadUnsupportedPatterns` to gate stack-specific patterns; `initRemoteConfig`
71
+ pulls the config from Codacy Cloud (pass an API token — see credential helpers below).
72
+
73
+ ### Custom logging & cancellation
74
+
75
+ - Pass your own `Logger` (the `@codacy/tooling` contract: `debug` / `info` / `warn` / `error`)
76
+ to route progress into your UI, or `createNullLogger()` for silence. Do **not** use
77
+ `createLogger()` in an embedder — it writes to files/stderr. Drive progress UI from the
78
+ `onToolStart` / `onToolComplete` / `onToolProgress` callbacks on `AnalyzeOptions`.
79
+ - Pass `signal: AbortSignal` on `AnalyzeOptions` to cancel an in-flight run; signal-honoring
80
+ adapters return partial results and remaining tools are marked cancelled.
81
+
16
82
  ## API
17
83
 
18
- | Export | Purpose |
19
- |--------|---------|
20
- | `analyze(options)` | Main entry point — runs the full analysis pipeline |
21
- | `registerAdapter(adapter)` | Register a tool adapter |
22
- | `clearAdapters()` | Reset adapter registry (for tests) |
23
- | `getRegisteredAdapters()` | List registered adapters |
24
- | `formatOutput(result, format)` | Transform AnalysisResult into a formatted string |
25
- | `buildToolConfig()` | Assemble CodacyToolConfig from CodacyConfig + local config |
26
- | `readCodacyConfig()` / `writeCodacyConfig()` | Read/write `.codacy/codacy.config.json` |
84
+ | Export | Purpose |
85
+ | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
86
+ | `analyze(options)` | Main entry point — runs the full analysis pipeline. Options include `repositoryRoot`, `tools`, `files`, `logger`, `signal`, and `onTool*` progress callbacks |
87
+ | `registerAdapter(adapter)` / `registerLazyAdapter(descriptor, load)` | Register a tool adapter (eager / lazy) |
88
+ | `clearAdapters()` | Reset adapter registry (for tests) |
89
+ | `getRegisteredAdapters()` / `getRegisteredDescriptors()` | List registered adapters / descriptors |
90
+ | `initLocalConfig()` / `initDefaultConfig()` / `initAutoConfig()` / `initRemoteConfig()` | Build a `CodacyConfig` (local, default, stack-aware, or Cloud-sourced) |
91
+ | `readCodacyConfig()` / `writeCodacyConfig()` | Read/write `.codacy/codacy.config.json` |
92
+ | `buildToolConfig()` | Assemble CodacyToolConfig from CodacyConfig + local config |
93
+ | `discover(path)` | Scan a repo and report languages, frameworks, libraries, notable files |
94
+ | `formatOutput(result, format)` | Transform AnalysisResult into a formatted string |
95
+ | `createLogger()` / `createNullLogger()` | File/stderr logger (CLI) / no-op logger (embedders) |
96
+ | `saveCredentials()` / `loadCredentials()` / `deleteCredentials()` / `resolveApiToken()` | Machine-stored API-token storage in `~/.codacy/credentials` |
97
+ | `validateApiToken()` / `configureApiToken()` / `listIgnoredFiles()` | Codacy Cloud API helpers |
98
+
99
+ > Adapter **registration** lives in the companion preset `@codacy/analysis-adapters`
100
+ > (`registerBuiltinAdapters`, `builtinAdapterEntries`), not here — the runner stays
101
+ > tool-agnostic.
27
102
 
28
103
  ## Pipeline steps
29
104
 
@@ -38,18 +113,18 @@ Core orchestration engine for the Codacy Analysis CLI. Discovers tools, checks c
38
113
 
39
114
  ## Output formats
40
115
 
41
- | Format | Description |
42
- |--------|-------------|
43
- | `json` | Pretty-printed AnalysisResult (default) |
44
- | `sarif` | SARIF v2.1.0 document |
45
- | `container` | One JSON object per line (Codacy Docker runners) |
46
- | `text` | Human-readable terminal summary with colors and grouping |
116
+ | Format | Description |
117
+ | ----------- | -------------------------------------------------------- |
118
+ | `json` | Pretty-printed AnalysisResult (default) |
119
+ | `sarif` | SARIF v2.1.0 document |
120
+ | `container` | One JSON object per line (Codacy Docker runners) |
121
+ | `text` | Human-readable terminal summary with colors and grouping |
47
122
 
48
123
  ## Execution modes
49
124
 
50
- | Mode | Behavior |
51
- |------|----------|
52
- | `standard` | Skip unavailable tools, report them (default) |
53
- | `strict` | Fail if any configured tool is unavailable |
54
- | `auto-install` | Attempt to install missing tools before analysis |
55
- | `inspect` | Dry-run: report capability without running analysis |
125
+ | Mode | Behavior |
126
+ | -------------- | --------------------------------------------------- |
127
+ | `standard` | Skip unavailable tools, report them (default) |
128
+ | `strict` | Fail if any configured tool is unavailable |
129
+ | `auto-install` | Attempt to install missing tools before analysis |
130
+ | `inspect` | Dry-run: report capability without running analysis |
package/dist/index.d.ts CHANGED
@@ -27,7 +27,7 @@ interface AnalyzeOptions {
27
27
  outputFormat?: OutputFormat;
28
28
  /** Execution mode. Defaults to "standard". */
29
29
  mode?: ExecutionMode;
30
- /** Maximum time in ms for each tool invocation. Defaults to 600000 (10 minutes). */
30
+ /** Maximum time in ms for each tool invocation. Defaults to 900000 (15 minutes). */
31
31
  toolTimeout?: number;
32
32
  /** Maximum number of tools to run in parallel. 1 = sequential. Defaults to 1. */
33
33
  parallelTools?: number;
@@ -51,6 +51,15 @@ interface AnalyzeOptions {
51
51
  configFile?: string;
52
52
  /** Logger for pipeline progress messages (install status, etc.). Defaults to no-op. */
53
53
  logger?: Logger;
54
+ /**
55
+ * Optional caller abort signal for cancelling an in-flight analysis (e.g. an
56
+ * embedder like VSCode or an MCP server). When aborted, `analyze()` stops
57
+ * launching new tools, in-flight signal-honoring adapters return partial
58
+ * results, and remaining tools are marked cancelled. If the signal is already
59
+ * aborted when `analyze()` is called, it returns immediately without doing any
60
+ * work.
61
+ */
62
+ signal?: AbortSignal;
54
63
  /** Called when a tool starts executing. */
55
64
  onToolStart?: (toolId: string, displayName: string) => void;
56
65
  /** Called when a tool finishes executing. */
@@ -601,11 +610,10 @@ interface PatternMetadataLookup {
601
610
  declare function computePatternSummary(issues: readonly Issue[], lookup: ReadonlyMap<string, PatternMetadataLookup>): PatternSummary;
602
611
 
603
612
  /**
604
- * File discovery and routing — finds files in a repository, applies exclusion
605
- * layers (.gitignore, global exclude, per-tool exclude), and routes files to
606
- * the appropriate tool adapters based on file patterns.
613
+ * Git-scope file resolution — resolves the set of files implied by the
614
+ * `--staged`, `--diff`, and `--pr` flags. Each helper returns paths relative
615
+ * to the repository root, excluding deleted files, sorted for stable output.
607
616
  */
608
-
609
617
  /**
610
618
  * Returns files changed in the git staging area (index), excluding deleted files.
611
619
  * Used by `--staged` to analyze only what's about to be committed.
@@ -660,6 +668,15 @@ interface LoggerOptions {
660
668
  */
661
669
  onStderrMessage?: (text: string, level: LogLevel) => void;
662
670
  }
671
+ /**
672
+ * Creates a no-op Logger that discards all messages.
673
+ *
674
+ * Intended for embedders (VSCode extension, MCP server, other library
675
+ * consumers) that call `analyze()` programmatically and do not want the
676
+ * pipeline writing to a log file or stderr. Passing this — or simply omitting
677
+ * `options.logger`, which defaults to it — keeps analysis completely silent.
678
+ */
679
+ declare function createNullLogger(): Logger;
663
680
  /**
664
681
  * Removes old log files beyond the retention limit.
665
682
  *
@@ -678,6 +695,50 @@ declare function rotateLogFiles(logsDir: string, maxFiles: number): void;
678
695
  */
679
696
  declare function createLogger(options?: LoggerOptions): Logger;
680
697
 
698
+ /**
699
+ * Credential storage — encrypts and persists API tokens to ~/.codacy/credentials,
700
+ * and resolves an API token from the environment or stored credentials.
701
+ *
702
+ * Lives in the runner so that any embedder (CLI, MCP server, IDE integration) can
703
+ * reuse credential storage. The interactive prompt stays in the CLI.
704
+ *
705
+ * Replicates the encryption scheme from codacy-cloud-cli — the byte format,
706
+ * algorithm, key derivation, and file location are SHARED, so credentials written
707
+ * by one tool are readable by the other. DO NOT change any of the following:
708
+ * - File location: ~/.codacy/credentials
709
+ * - Machine key: [hostname, username, homedir, platform].join("|")
710
+ * - Key derivation: PBKDF2 (100k iterations, SHA-512, 32-byte key)
711
+ * - Encryption: AES-256-GCM with random salt (32B) and IV (16B)
712
+ * - Storage: JSON with hex-encoded { salt, iv, authTag, encrypted }
713
+ * - File permissions: 0o600 (owner read/write only)
714
+ *
715
+ * All crypto uses Node.js built-in `crypto` — no external dependencies.
716
+ */
717
+ /**
718
+ * Encrypts and saves an API token to ~/.codacy/credentials.
719
+ * Creates the ~/.codacy/ directory if it doesn't exist.
720
+ */
721
+ declare function saveCredentials(token: string): Promise<void>;
722
+ /**
723
+ * Reads and decrypts the stored API token from ~/.codacy/credentials.
724
+ * Returns null if the file is missing, corrupt, or cannot be decrypted.
725
+ */
726
+ declare function loadCredentials(): Promise<string | null>;
727
+ /**
728
+ * Deletes the stored credentials file.
729
+ * Returns true if the file existed and was deleted, false otherwise.
730
+ */
731
+ declare function deleteCredentials(): Promise<boolean>;
732
+ /**
733
+ * Resolves a Codacy API token from the environment or stored credentials.
734
+ *
735
+ * Resolution order:
736
+ * 1. CODACY_API_TOKEN environment variable
737
+ * 2. Encrypted credentials saved via `codacy-analysis login`
738
+ * 3. Throws with instructions if neither source has a token.
739
+ */
740
+ declare function resolveApiToken(): Promise<string>;
741
+
681
742
  /**
682
743
  * Repository discovery — scans a codebase and identifies languages, file patterns,
683
744
  * notable files, frameworks, and libraries.
@@ -700,4 +761,21 @@ interface DiscoverOptions {
700
761
  */
701
762
  declare function discover(repositoryRoot: string, options?: DiscoverOptions): Promise<DiscoveryResult>;
702
763
 
703
- export { type AdapterFactory, type AnalyzeOptions, type AutoFilters, type CategoryFilter, type CodacyYamlConfig, type CodacyYamlEngineConfig, type ConfigOperation, type DiscoverOptions, type ExecutionMode, type IgnoredFilesResult, type InitAutoStats, type InitDefaultStats, type InitLocalStats, type InitRemoteStats, type LoggerOptions, type PatternMetadataLookup, type SeverityFilter, analyze, applyCodacyYamlExcludes, applyConfigOperation, buildToolConfig, clearAdapters, computePatternSummary, configureApiToken, createCodacyConfig, createLogger, detectLanguages, diffConfigs, discover, formatOutput, formatTextSummary, getAdapter, getRegisteredAdapters, getRegisteredDescriptors, initAutoConfig, initContainerConfig, initDefaultConfig, initLocalConfig, initRemoteConfig, intersectConfigs, listDiffFiles, listIgnoredFiles, listPrFiles, listStagedFiles, mergeConfigs, parseAutoFilters, readCodacyConfig, readCodacyYaml, registerAdapter, registerLazyAdapter, registerUnsupportedTool, resolveConfigPath, resolveEngineToAdapter, rotateLogFiles, validateApiToken, writeCodacyConfig, writeCodacyConfigFile };
764
+ /**
765
+ * Discovery catalog — static knowledge base for the discover command.
766
+ *
767
+ * Contains manifest file parsers, a curated dependency classification catalog,
768
+ * and notable file detection rules. All parsers are pure functions that accept
769
+ * raw file content and return dependency name arrays. They never throw.
770
+ */
771
+
772
+ /**
773
+ * Every display name discovery can emit from a dependency/file/package.json signal.
774
+ * This is the authoritative set a framework-mapping key must belong to (together
775
+ * with detected language names) for its patterns to ever gate on. The drift-guard
776
+ * test uses it to catch mapping keys that no signal can produce (e.g. a rename
777
+ * like react-intl → formatjs that updates the mapping but not the catalog).
778
+ */
779
+ declare function getKnownDisplayNames(): Set<string>;
780
+
781
+ export { type AdapterFactory, type AnalyzeOptions, type AutoFilters, type CategoryFilter, type CodacyYamlConfig, type CodacyYamlEngineConfig, type ConfigOperation, type DiscoverOptions, type ExecutionMode, type IgnoredFilesResult, type InitAutoStats, type InitDefaultStats, type InitLocalStats, type InitRemoteStats, type LoggerOptions, type PatternMetadataLookup, type SeverityFilter, analyze, applyCodacyYamlExcludes, applyConfigOperation, buildToolConfig, clearAdapters, computePatternSummary, configureApiToken, createCodacyConfig, createLogger, createNullLogger, deleteCredentials, detectLanguages, diffConfigs, discover, formatOutput, formatTextSummary, getAdapter, getKnownDisplayNames, getRegisteredAdapters, getRegisteredDescriptors, initAutoConfig, initContainerConfig, initDefaultConfig, initLocalConfig, initRemoteConfig, intersectConfigs, listDiffFiles, listIgnoredFiles, listPrFiles, listStagedFiles, loadCredentials, mergeConfigs, parseAutoFilters, readCodacyConfig, readCodacyYaml, registerAdapter, registerLazyAdapter, registerUnsupportedTool, resolveApiToken, resolveConfigPath, resolveEngineToAdapter, rotateLogFiles, saveCredentials, validateApiToken, writeCodacyConfig, writeCodacyConfigFile };