infraweaver 0.3.7 → 0.3.9
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 +2 -2
- package/dist/agents/claude.d.ts +1 -1
- package/dist/agents/claudePretoolGate.d.ts +0 -36
- package/dist/agents/toolPlaneWatch.d.ts +31 -0
- package/dist/cli.mjs +31908 -18736
- package/dist/external.d.ts +2 -1
- package/dist/index.js +31992 -18749
- package/dist/internal.js +133 -52
- package/dist/mcp/baseBranch.d.ts +41 -0
- package/dist/mcp/changeSummary.d.ts +1 -1
- package/dist/mcp/findingAudit.d.ts +2 -0
- package/dist/mcp/guardrails.d.ts +38 -0
- package/dist/mcp/localContext.d.ts +1 -1
- package/dist/mcp/moduleExtraction.d.ts +5 -0
- package/dist/mcp/pr.d.ts +0 -31
- package/dist/mcp/reproveSuggestions.d.ts +27 -0
- package/dist/mcp/review.d.ts +126 -2
- package/dist/mcp/reviewCommentLimit.d.ts +17 -0
- package/dist/mcp/reviewComments.d.ts +9 -5
- package/dist/mcp/reviewDedup.d.ts +1 -0
- package/dist/mcp/reviewMarkers.d.ts +10 -0
- package/dist/mcp/reviewProvenance.d.ts +20 -6
- package/dist/mcp/shared.d.ts +15 -0
- package/dist/mcp/suggestionProver.d.ts +3 -2
- package/dist/mcp/terraform/checkovSeverities.d.ts +7 -0
- package/dist/mcp/terraform/consolidation.d.ts +26 -0
- package/dist/mcp/terraform/cost.d.ts +2 -2
- package/dist/mcp/terraform/currency.d.ts +11 -0
- package/dist/mcp/terraform/deltaSummary.d.ts +11 -1
- package/dist/mcp/terraform/emittedArtefacts.d.ts +11 -0
- package/dist/mcp/terraform/evidence.d.ts +10 -0
- package/dist/mcp/terraform/gateScan.d.ts +2 -16
- package/dist/mcp/terraform/hcl.d.ts +15 -0
- package/dist/mcp/terraform/initArtefacts.d.ts +21 -0
- package/dist/mcp/terraform/localModules.d.ts +29 -0
- package/dist/mcp/terraform/moduleFindings.d.ts +38 -0
- package/dist/mcp/terraform/refactor/attribution.d.ts +1 -1
- package/dist/mcp/terraform/refactor/equivalence.d.ts +7 -0
- package/dist/mcp/terraform/refactor/expressions.d.ts +62 -0
- package/dist/mcp/terraform/refactor/references.d.ts +15 -0
- package/dist/mcp/terraform/refactor/resources.d.ts +11 -0
- package/dist/mcp/terraform/refactor/substitution.d.ts +55 -37
- package/dist/mcp/terraform/scanDelta.d.ts +28 -0
- package/dist/mcp/terraform/scanSession.d.ts +13 -0
- package/dist/mcp/terraform/scanners.d.ts +67 -18
- package/dist/mcp/terraform/secretScan.d.ts +19 -0
- package/dist/mcp/terraform/standardsReport.d.ts +1 -1
- package/dist/mcp/terraform/tools/plan.d.ts +1 -1
- package/dist/mcp/terraform/tools/scan.d.ts +7 -7
- package/dist/mcp/terraform/tools/validate.d.ts +7 -2
- package/dist/mcp/terraform/tools/verifyRemediation.d.ts +1 -1
- package/dist/mcp/terraform/treeLayout.d.ts +57 -0
- package/dist/mcp/terraform/types.d.ts +1 -1
- package/dist/phases/applyPlan.d.ts +0 -2
- package/dist/toolState.d.ts +3 -0
- package/dist/utils/agent/codexOAuth.d.ts +1 -1
- package/dist/utils/cli.d.ts +1 -7
- package/dist/utils/cloud/cloudReport.d.ts +1 -1
- package/dist/utils/config/baseRefConfig.d.ts +1 -1
- package/dist/utils/config/infraweaverConfig.d.ts +1 -1
- package/dist/utils/config/payload.d.ts +5 -0
- package/dist/utils/markdownTable.d.ts +6 -0
- package/dist/utils/setup/toolLicensing.d.ts +1 -1
- package/dist/utils/unifiedDiff.d.ts +69 -0
- package/package.json +34 -28
- package/src/agents/claude.ts +48 -13
- package/src/agents/claudePretoolGate.ts +9 -17
- package/src/agents/sessionLabeler.ts +3 -3
- package/src/agents/toolPlaneWatch.ts +71 -0
- package/src/external.ts +3 -1
- package/src/mcp/assess.ts +8 -8
- package/src/mcp/baseBranch.ts +96 -0
- package/src/mcp/changeSummary.ts +10 -11
- package/src/mcp/checkSuite.ts +7 -10
- package/src/mcp/checkout.ts +13 -40
- package/src/mcp/crosswalk.ts +5 -0
- package/src/mcp/findingAudit.ts +1 -1
- package/src/mcp/git.ts +44 -2
- package/src/mcp/guardrails.ts +188 -36
- package/src/mcp/localContext.ts +2 -0
- package/src/mcp/localServer.ts +1 -0
- package/src/mcp/moduleExtraction.ts +17 -5
- package/src/mcp/moduleTests.ts +9 -2
- package/src/mcp/modules.ts +10 -7
- package/src/mcp/pr.ts +17 -65
- package/src/mcp/reproveSuggestions.ts +86 -0
- package/src/mcp/review.ts +249 -75
- package/src/mcp/reviewAnchor.ts +11 -23
- package/src/mcp/reviewCommentLimit.ts +79 -0
- package/src/mcp/reviewComments.ts +34 -81
- package/src/mcp/reviewDedup.ts +1 -1
- package/src/mcp/reviewMarkers.ts +25 -2
- package/src/mcp/reviewProvenance.ts +56 -21
- package/src/mcp/roots.ts +3 -2
- package/src/mcp/server.ts +2 -1
- package/src/mcp/shared.ts +40 -1
- package/src/mcp/shell.ts +27 -28
- package/src/mcp/suggestionProver.ts +8 -4
- package/src/mcp/terraform/checkovSeverities.ts +1156 -0
- package/src/mcp/terraform/concernResult.ts +2 -1
- package/src/mcp/terraform/consolidation.ts +232 -19
- package/src/mcp/terraform/cost.ts +16 -7
- package/src/mcp/terraform/cspm.ts +8 -4
- package/src/mcp/terraform/currency.ts +28 -12
- package/src/mcp/terraform/decisions.ts +1 -1
- package/src/mcp/terraform/deltaSummary.ts +50 -1
- package/src/mcp/terraform/emittedArtefacts.ts +63 -0
- package/src/mcp/terraform/evidence.ts +23 -3
- package/src/mcp/terraform/gateScan.ts +191 -128
- package/src/mcp/terraform/hcl.ts +27 -2
- package/src/mcp/terraform/idleFloor.ts +2 -1
- package/src/mcp/terraform/initArtefacts.ts +76 -0
- package/src/mcp/terraform/localModules.ts +112 -0
- package/src/mcp/terraform/moduleDocs.ts +2 -5
- package/src/mcp/terraform/moduleFindings.ts +102 -0
- package/src/mcp/terraform/moduleVersionConstraints.ts +1 -1
- package/src/mcp/terraform/planPairs.ts +2 -20
- package/src/mcp/terraform/policyGate.ts +0 -15
- package/src/mcp/terraform/refactor/attribution.ts +39 -5
- package/src/mcp/terraform/refactor/equivalence.ts +49 -10
- package/src/mcp/terraform/refactor/expressions.ts +323 -0
- package/src/mcp/terraform/refactor/references.ts +101 -0
- package/src/mcp/terraform/refactor/resources.ts +79 -7
- package/src/mcp/terraform/refactor/substitution.ts +852 -256
- package/src/mcp/terraform/scanDelta.ts +41 -0
- package/src/mcp/terraform/scanSession.ts +30 -0
- package/src/mcp/terraform/scannerCache.ts +4 -0
- package/src/mcp/terraform/scanners.ts +553 -233
- package/src/mcp/terraform/secretScan.ts +131 -0
- package/src/mcp/terraform/standardsReport.ts +14 -13
- package/src/mcp/terraform/tools/consolidationCandidates.ts +3 -0
- package/src/mcp/terraform/tools/emitEvidence.ts +13 -5
- package/src/mcp/terraform/tools/emitOscal.ts +3 -2
- package/src/mcp/terraform/tools/emitVex.ts +10 -4
- package/src/mcp/terraform/tools/equivalenceCheck.ts +139 -21
- package/src/mcp/terraform/tools/infracostDiff.ts +2 -2
- package/src/mcp/terraform/tools/plan.ts +30 -17
- package/src/mcp/terraform/tools/reviewScanDelta.ts +3 -0
- package/src/mcp/terraform/tools/scan.ts +5 -3
- package/src/mcp/terraform/tools/standardsReport.ts +1 -1
- package/src/mcp/terraform/tools/validate.ts +20 -5
- package/src/mcp/terraform/tools/verifyRemediation.ts +14 -7
- package/src/mcp/terraform/tools/versionCurrency.ts +3 -1
- package/src/mcp/terraform/treeLayout.ts +378 -0
- package/src/mcp/terraform/types.ts +4 -1
- package/src/mcp/terraform/versionRequirements.ts +11 -2
- package/src/modes/__snapshots__/assemblePrompt.test.ts.snap +2 -0
- package/src/modes/modernize-deprecated.ts +2 -2
- package/src/modes/refactor.ts +9 -9
- package/src/modes/remediate.ts +1 -1
- package/src/modes/terraform-code-review.ts +7 -3
- package/src/modes/update-dependencies.ts +6 -6
- package/src/phases/applyPlan.ts +33 -14
- package/src/phases/applySuggestions.ts +2 -2
- package/src/phases/runAgentWithWatchdogs.ts +2 -1
- package/src/toolState.ts +7 -0
- package/src/utils/agent/codexOAuth.ts +7 -7
- package/src/utils/agent/openCodeModels.ts +4 -6
- package/src/utils/cli.ts +1 -31
- package/src/utils/cloud/runContext.ts +1 -8
- package/src/utils/config/baseRefConfig.ts +6 -0
- package/src/utils/config/infraweaverConfig.ts +2 -0
- package/src/utils/config/payload.ts +41 -0
- package/src/utils/github/assets.ts +1 -6
- package/src/utils/github/github.ts +42 -150
- package/src/utils/github/token.ts +6 -11
- package/src/utils/log.ts +4 -5
- package/src/utils/markdownTable.ts +11 -0
- package/src/utils/prompt/changeImpact.ts +18 -26
- package/src/utils/prompt/instructions.ts +1 -1
- package/src/utils/prompt/promptDirectives.ts +1 -1
- package/src/utils/prompt/toolSelection.ts +11 -2
- package/src/utils/setup/toolLicensing.ts +7 -0
- package/src/utils/telemetry.ts +2 -1
- package/src/utils/unifiedDiff.ts +120 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `source` a module block in `fromDir` writes to call the module at
|
|
3
|
+
* `moduleDir`, both repo-relative POSIX paths. A local source is relative to the
|
|
4
|
+
* CALLER's directory, so `./modules/s3` is right only from the repo root; from
|
|
5
|
+
* `env/dev` the same module is `../../modules/s3`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function localSourceFrom(fromDir: string, moduleDir: string): string;
|
|
8
|
+
interface LocalModuleCall {
|
|
9
|
+
/** absolute path of the file declaring the call. */
|
|
10
|
+
file: string;
|
|
11
|
+
/** 1-based line of the `module` header; null in JSON configuration. */
|
|
12
|
+
line: number | null;
|
|
13
|
+
name: string;
|
|
14
|
+
source: string;
|
|
15
|
+
/** absolute directory the source resolves to. */
|
|
16
|
+
dir: string;
|
|
17
|
+
/** whether that directory holds any Terraform configuration. */
|
|
18
|
+
exists: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface LocalModuleClosure {
|
|
21
|
+
/** every local call reached from the root, missing ones included. */
|
|
22
|
+
calls: LocalModuleCall[];
|
|
23
|
+
/** the root and every existing local module directory it reaches. */
|
|
24
|
+
dirs: string[];
|
|
25
|
+
}
|
|
26
|
+
/** the configuration files directly in `dir` (not beneath it). */
|
|
27
|
+
export declare function configFilesIn(dir: string): string[];
|
|
28
|
+
export declare function localModuleClosure(rootDir: string): LocalModuleClosure;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type Concern } from "./types.js";
|
|
2
|
+
/** Where a scanner was told to put the modules it fetched, outside the tree. */
|
|
3
|
+
export interface FetchDir {
|
|
4
|
+
/** the directory the scanner's paths are relative to. */
|
|
5
|
+
cwd: string;
|
|
6
|
+
dir: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* True when a scanner-reported path is a fetched module's copy, not repository
|
|
10
|
+
* code: under terraform's or checkov's module directory in the tree, or under
|
|
11
|
+
* the directory a scan had checkov download into. A path that merely leaves the
|
|
12
|
+
* scanned directory is not enough — a scan of one root reports the repository's
|
|
13
|
+
* own local modules as `../../modules/x`.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isFetchedModulePath(file: string, fetchedInto?: FetchDir): boolean;
|
|
16
|
+
/** 1-based line of `module "<name>"` in `file`, or null when it is not there. */
|
|
17
|
+
export declare function moduleCallLine(cwd: string, file: string, name: string): number | null;
|
|
18
|
+
/** `module.<name>…` → `<name>`, the call in the root that instantiates it. */
|
|
19
|
+
export declare function topModuleName(address: string): string | null;
|
|
20
|
+
export interface ModuleFinding {
|
|
21
|
+
/** the concern as the scanner reported it, against the fetched copy. */
|
|
22
|
+
concern: Concern;
|
|
23
|
+
/** the call that instantiates the module, in the repository. */
|
|
24
|
+
call: {
|
|
25
|
+
file: string;
|
|
26
|
+
line: number | null;
|
|
27
|
+
};
|
|
28
|
+
/** the module resource the finding is about, e.g. `module.data.aws_s3_bucket.this`. */
|
|
29
|
+
address: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Re-locate each finding to its call, saying in the evidence which module
|
|
33
|
+
* resource it is about and where in the module. Findings that land on the same
|
|
34
|
+
* call under the same rule are one concern — a concern's identity is its rule
|
|
35
|
+
* and location — so they are merged, every resource named: one concern per
|
|
36
|
+
* resource would be collapsed by the dedupe anyway, and silently.
|
|
37
|
+
*/
|
|
38
|
+
export declare function relocateToCalls(findings: ModuleFinding[]): Concern[];
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
* the walk rather than throwing — a truncated attribution makes the proof
|
|
21
21
|
* refuse, which is the safe direction.
|
|
22
22
|
*/
|
|
23
|
-
import type { FetchedModules } from "./workspace.js";
|
|
24
23
|
import { type MovedBlock } from "./movedBlocks.js";
|
|
25
24
|
import { type ResourceRef } from "./resources.js";
|
|
25
|
+
import type { FetchedModules } from "./workspace.js";
|
|
26
26
|
import type { SourceFile } from "../tree.js";
|
|
27
27
|
export interface Attribution {
|
|
28
28
|
resources: ResourceRef[];
|
|
@@ -91,6 +91,13 @@ export interface EquivalenceResult {
|
|
|
91
91
|
before: string;
|
|
92
92
|
after: string;
|
|
93
93
|
}[];
|
|
94
|
+
/** relocations that changed the provider configuration managing the resource
|
|
95
|
+
* (G16) — another region or account, with every argument unchanged. */
|
|
96
|
+
provider_diffs: {
|
|
97
|
+
resource: string;
|
|
98
|
+
before: string;
|
|
99
|
+
after: string;
|
|
100
|
+
}[];
|
|
94
101
|
/** relocations where the repetition changed LEVEL — it sat on the resource and
|
|
95
102
|
* now sits on a module call, or the reverse (G15). The instance key moves to a
|
|
96
103
|
* different position in the address, so the same instances live at entirely
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A Terraform expression read into its SHAPE, for the refactor proof's value
|
|
3
|
+
* comparison ([[substitution]]).
|
|
4
|
+
*
|
|
5
|
+
* Not an evaluator and not a full HCL grammar. It recognises the forms whose
|
|
6
|
+
* value can be followed without running anything — literals, quoted templates,
|
|
7
|
+
* tuples, objects, traversals (`var.x`, `aws_s3_bucket.b.arn`, `data.t.n.json`)
|
|
8
|
+
* and a top-level conditional — and keeps everything else (function calls,
|
|
9
|
+
* operators, `for` expressions) as `raw`: the code text, with the traversals
|
|
10
|
+
* and strings inside it lifted out so they can still be resolved. A raw
|
|
11
|
+
* expression is only ever compared as "the same code over the same values",
|
|
12
|
+
* which can say equal, never different.
|
|
13
|
+
*
|
|
14
|
+
* Pure.
|
|
15
|
+
*/
|
|
16
|
+
export type Step = {
|
|
17
|
+
attr: string;
|
|
18
|
+
} | {
|
|
19
|
+
index: Expr;
|
|
20
|
+
};
|
|
21
|
+
export type Expr = {
|
|
22
|
+
kind: "literal";
|
|
23
|
+
value: string | number | boolean | null;
|
|
24
|
+
}
|
|
25
|
+
/** a quoted string; `parts` alternate text and `${…}` interpolations. */
|
|
26
|
+
| {
|
|
27
|
+
kind: "template";
|
|
28
|
+
parts: (string | Expr)[];
|
|
29
|
+
} | {
|
|
30
|
+
kind: "tuple";
|
|
31
|
+
items: Expr[];
|
|
32
|
+
} | {
|
|
33
|
+
kind: "object";
|
|
34
|
+
entries: {
|
|
35
|
+
key: string;
|
|
36
|
+
value: Expr;
|
|
37
|
+
}[];
|
|
38
|
+
}
|
|
39
|
+
/** `root.step.step[index]…` — `root` is `var`, `local`, a resource type, … */
|
|
40
|
+
| {
|
|
41
|
+
kind: "traversal";
|
|
42
|
+
root: string;
|
|
43
|
+
steps: Step[];
|
|
44
|
+
text: string;
|
|
45
|
+
} | {
|
|
46
|
+
kind: "conditional";
|
|
47
|
+
cond: Expr;
|
|
48
|
+
whenTrue: Expr;
|
|
49
|
+
whenFalse: Expr;
|
|
50
|
+
}
|
|
51
|
+
/** anything else: code text interleaved with the expressions found inside it. */
|
|
52
|
+
| {
|
|
53
|
+
kind: "raw";
|
|
54
|
+
parts: (string | Expr)[];
|
|
55
|
+
}
|
|
56
|
+
/** text whose inside cannot be read safely — a heredoc, a template directive. */
|
|
57
|
+
| {
|
|
58
|
+
kind: "opaque";
|
|
59
|
+
text: string;
|
|
60
|
+
};
|
|
61
|
+
/** read one expression's text into its shape. */
|
|
62
|
+
export declare function parseExpression(text: string): Expr;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { MovedBlock } from "./movedBlocks.js";
|
|
2
|
+
import type { SourceFile } from "../tree.js";
|
|
3
|
+
export interface StaleReference {
|
|
4
|
+
file: string;
|
|
5
|
+
line: number;
|
|
6
|
+
/** the relocated address the reference still names, without instance key. */
|
|
7
|
+
address: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Every place in a relocation's root that still names the address it moved
|
|
11
|
+
* away from. Each reference found is a defect the proof must refuse.
|
|
12
|
+
*/
|
|
13
|
+
export declare function staleReferences(after: readonly SourceFile[], relocations: readonly MovedBlock[]): StaleReference[];
|
|
14
|
+
/** The proof's reason for a set of stale references; null when there are none. */
|
|
15
|
+
export declare function staleReferenceReason(stale: readonly StaleReference[]): string | null;
|
|
@@ -39,7 +39,17 @@ export interface ResourceRef {
|
|
|
39
39
|
* single instance. See [[Multiplicity]] — this is deliberately NOT folded into
|
|
40
40
|
* `argNames`, because a correct extraction MOVES it onto the module call. */
|
|
41
41
|
multiplicity: Multiplicity[];
|
|
42
|
+
/** the provider configuration that manages the resource, as the ROOT names it
|
|
43
|
+
* (`aws`, `aws.replica`): the resource's own `provider` meta-argument, or the
|
|
44
|
+
* default for its type, resolved through every module call's `providers`
|
|
45
|
+
* map. Absent on a hand-built ref, which is not compared. See
|
|
46
|
+
* [[moduleCallProviders]]. */
|
|
47
|
+
provider?: string;
|
|
42
48
|
}
|
|
49
|
+
/** `module "<name>" { … }` call name → its `providers` map (the module's name
|
|
50
|
+
* for a configuration → the caller's), or null when the call passes none and
|
|
51
|
+
* the module inherits the caller's default configurations. */
|
|
52
|
+
export declare function moduleCallProviders(hcl: string): Map<string, Map<string, string> | null>;
|
|
43
53
|
/**
|
|
44
54
|
* How many instances of a resource exist, and keyed by what.
|
|
45
55
|
*
|
|
@@ -142,4 +152,5 @@ export declare function parseResourcesWithArgs(hcl: string): {
|
|
|
142
152
|
name: string;
|
|
143
153
|
argNames: string[];
|
|
144
154
|
multiplicity: Multiplicity | null;
|
|
155
|
+
provider: string | null;
|
|
145
156
|
}[];
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The VALUE half of a refactor proof:
|
|
3
|
-
* it
|
|
2
|
+
* The VALUE half of a refactor proof: does every resource the change touches
|
|
3
|
+
* still say what it said?
|
|
4
4
|
*
|
|
5
5
|
* [[equivalence]] compares argument NAMES and never values, for a good reason —
|
|
6
|
-
* the names are what survives being moved behind a module boundary
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* one shared module does to every value that differs between them:
|
|
6
|
+
* the names are what survives being moved behind a module boundary. On its own
|
|
7
|
+
* that is a hole wherever the change PARAMETERISES a value, which is what
|
|
8
|
+
* consolidating N environments onto one shared module does to every value that
|
|
9
|
+
* differs between them:
|
|
11
10
|
*
|
|
12
11
|
* before env/dev/main.tf bucket = "acme-dev-logs"
|
|
13
12
|
* env/prod/main.tf bucket = "acme-prod-logs"
|
|
@@ -15,61 +14,80 @@
|
|
|
15
14
|
* env/dev/main.tf module "logging" { bucket = "acme-prod-logs" } ← swapped
|
|
16
15
|
* env/prod/main.tf module "logging" { bucket = "acme-dev-logs" } ← swapped
|
|
17
16
|
*
|
|
18
|
-
* Every
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
17
|
+
* Every name-level gate passes that tree, and so does a plan. The apply
|
|
18
|
+
* destroys prod. The same hole has other doors: a shared module whose body was
|
|
19
|
+
* edited on the way (every caller changes, moved or not), a nested block whose
|
|
20
|
+
* value now comes from a call input, a `dynamic` block fed one rule fewer, a
|
|
21
|
+
* data source the moved resource reads.
|
|
22
22
|
*
|
|
23
|
-
* WHAT THIS DOES
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
23
|
+
* WHAT THIS DOES. Every resource present on both sides — matched through the
|
|
24
|
+
* relocations — is read into VALUES ([[expressions]]) and compared. A value is
|
|
25
|
+
* followed, never run: `var.x` back up the call chain to what the call site
|
|
26
|
+
* wrote (or the module's default), `local.x` to its definition, `module.m.o` to
|
|
27
|
+
* the output's expression, a `data` source to its body, a reference to another
|
|
28
|
+
* resource to that resource's identity (through the relocations, so
|
|
29
|
+
* `aws_s3_bucket.data.id` in the root and `aws_s3_bucket.this.id` in the module
|
|
30
|
+
* are the same value). A `dynamic` block is expanded when its `for_each`
|
|
31
|
+
* resolves to a literal collection; a conditional is folded when its condition
|
|
32
|
+
* does; a template whose parts are all literals is joined. Nothing else is
|
|
33
|
+
* evaluated — a function call or an operator is compared only as "the same
|
|
34
|
+
* code over the same values".
|
|
31
35
|
*
|
|
32
|
-
* AND WHAT IT REFUSES TO SAY.
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* is missed instances, never false ones.
|
|
36
|
+
* AND WHAT IT REFUSES TO SAY. A comparison has three outcomes: equal, CHANGED,
|
|
37
|
+
* or NOT CHECKED. CHANGED is reported only when the difference is established
|
|
38
|
+
* — two literals that differ, a collection of a different length, a field one
|
|
39
|
+
* side lacks, a block that has no counterpart at all. Anything that would need
|
|
40
|
+
* evaluating is NOT CHECKED. The trade is missed instances, never false ones.
|
|
41
|
+
*
|
|
42
|
+
* Root-scoped values are never resolved further: `var.x` in a root means
|
|
43
|
+
* whatever tfvars says on both sides, so it is equal to itself and to nothing
|
|
44
|
+
* else.
|
|
37
45
|
*
|
|
38
46
|
* Pure: two already-read trees and the relocations in, findings out.
|
|
39
47
|
*/
|
|
40
48
|
import type { MovedBlock } from "./movedBlocks.js";
|
|
41
49
|
import type { SourceFile } from "../tree.js";
|
|
42
50
|
interface ValueSubstitution {
|
|
43
|
-
/** the root the
|
|
51
|
+
/** the root module the resource belongs to. */
|
|
44
52
|
root: string;
|
|
45
53
|
/** the BEFORE address, as `expected_moves` spells it. */
|
|
46
54
|
resource: string;
|
|
55
|
+
/** the argument, with a path into nested blocks: `versioning_configuration[0].status`. */
|
|
47
56
|
argument: string;
|
|
48
|
-
/** the value the
|
|
57
|
+
/** the value as the before tree writes it. */
|
|
49
58
|
before: string;
|
|
50
|
-
/** the value
|
|
59
|
+
/** the value as the after tree writes it — often `var.<x>`. */
|
|
51
60
|
after: string;
|
|
52
|
-
/** what `after` resolves to
|
|
53
|
-
*
|
|
61
|
+
/** what `after` resolves to, followed back to the root's scope. `null` when
|
|
62
|
+
* the comparison was NOT CHECKED. */
|
|
54
63
|
after_resolved: string | null;
|
|
55
|
-
/** `true`/`false` only when
|
|
64
|
+
/** `true`/`false` only when the comparison settled; `null` = NOT CHECKED. */
|
|
56
65
|
match: boolean | null;
|
|
57
|
-
/** why this
|
|
66
|
+
/** why this value was not checked, or null when it was. */
|
|
58
67
|
not_checked: string | null;
|
|
59
68
|
}
|
|
60
69
|
export interface SubstitutionResult {
|
|
61
|
-
/** every
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
* relocations were examined and none had a comparable argument. */
|
|
70
|
+
/** every value compared on a RELOCATED resource, plus every established
|
|
71
|
+
* change anywhere. `null` means the question did not arise: nothing moved
|
|
72
|
+
* and nothing changed. */
|
|
65
73
|
value_substitutions: ValueSubstitution[] | null;
|
|
66
|
-
/** the established
|
|
74
|
+
/** the established changes — the subset with `match: false`. A non-empty
|
|
67
75
|
* list is a violation, not a warning. */
|
|
68
76
|
value_mismatches: ValueSubstitution[];
|
|
77
|
+
/** calls of a module this tree does not contain — a registry module, a git
|
|
78
|
+
* module nothing fetched — whose `source` or `version` changed. The code the
|
|
79
|
+
* resources come from was swapped outside the tree, so no comparison here
|
|
80
|
+
* can say what changed: never a proof, in either direction. */
|
|
81
|
+
opaque_module_changes: {
|
|
82
|
+
root: string;
|
|
83
|
+
call: string;
|
|
84
|
+
before: string;
|
|
85
|
+
after: string;
|
|
86
|
+
}[];
|
|
69
87
|
reasons: string[];
|
|
70
88
|
}
|
|
71
89
|
/**
|
|
72
|
-
*
|
|
90
|
+
* Compare the values of every resource present on both sides.
|
|
73
91
|
*
|
|
74
92
|
* `moves` is `computeEquivalence`'s `expected_moves` — the authoritative set of
|
|
75
93
|
* relocations, so this check and the proof it augments always speak about the
|
|
@@ -8,6 +8,11 @@ export interface DeltaFinding {
|
|
|
8
8
|
block?: string;
|
|
9
9
|
/** an introduced finding whose resource may be an undeclared rename. */
|
|
10
10
|
possiblyPreexisting?: true;
|
|
11
|
+
/** with `possiblyPreexisting`: the vanished resource it pairs with on the base. */
|
|
12
|
+
renamedFrom?: {
|
|
13
|
+
address: string;
|
|
14
|
+
file: string;
|
|
15
|
+
};
|
|
11
16
|
}
|
|
12
17
|
export interface ScanDelta {
|
|
13
18
|
introduced: DeltaFinding[];
|
|
@@ -60,6 +65,29 @@ export interface ScanDeltaInput {
|
|
|
60
65
|
*/
|
|
61
66
|
export declare function findingKey(f: DeltaFinding): string;
|
|
62
67
|
export declare function computeScanDelta(input: ScanDeltaInput): ScanDelta;
|
|
68
|
+
/** One resource that looks renamed (or moved to another directory) without a
|
|
69
|
+
* `moved` block, and how many introduced findings ride on it. */
|
|
70
|
+
export interface UndeclaredRename {
|
|
71
|
+
from: {
|
|
72
|
+
address: string;
|
|
73
|
+
dir: string;
|
|
74
|
+
};
|
|
75
|
+
to: {
|
|
76
|
+
address: string;
|
|
77
|
+
dir: string;
|
|
78
|
+
};
|
|
79
|
+
findings: number;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The possibly-pre-existing findings grouped by the rename behind them.
|
|
83
|
+
*
|
|
84
|
+
* Fifteen findings on one renamed bucket are one thing for the author to do —
|
|
85
|
+
* add a `moved` block — not fifteen, and without that block `terraform apply`
|
|
86
|
+
* destroys the old resource and creates the new one. So a verdict reads better
|
|
87
|
+
* naming the resource once than listing every rule it carries. Order follows
|
|
88
|
+
* the findings (which are sorted by location), so the output is stable.
|
|
89
|
+
*/
|
|
90
|
+
export declare function undeclaredRenames(introduced: readonly DeltaFinding[]): UndeclaredRename[];
|
|
63
91
|
/** Every `resource` / `data` address declared in one file. */
|
|
64
92
|
export declare function declaredAddresses(hcl: string): string[];
|
|
65
93
|
/** A scan delta pinned to the commits it compared. */
|
|
@@ -43,6 +43,7 @@ export interface ScanSession {
|
|
|
43
43
|
baselineConcernKeys?: string[];
|
|
44
44
|
baselineFmtDriftFiles?: string[];
|
|
45
45
|
lastScanConcerns?: Concern[];
|
|
46
|
+
concernsById?: Map<string, Concern>;
|
|
46
47
|
gateConcerns?: Concern[];
|
|
47
48
|
policyRules?: unknown[] | null;
|
|
48
49
|
policyGate?: PolicyGateResult;
|
|
@@ -73,6 +74,7 @@ export interface ScanSession {
|
|
|
73
74
|
lastCostDirection?: "increase" | "decrease" | "no-change" | "unknown";
|
|
74
75
|
lastIdleFloor?: IdleFloorReport | undefined;
|
|
75
76
|
lastDrift?: DriftEvidenceStatement | undefined;
|
|
77
|
+
emittedArtefacts?: Record<string, string[]>;
|
|
76
78
|
emittedSarifPath?: string;
|
|
77
79
|
refactorEquivalence?: {
|
|
78
80
|
equivalent: boolean;
|
|
@@ -129,6 +131,10 @@ export interface ScanSession {
|
|
|
129
131
|
fingerprint: string;
|
|
130
132
|
pairs: PairAnalysis;
|
|
131
133
|
};
|
|
134
|
+
baselineValidateErrors?: {
|
|
135
|
+
base: string;
|
|
136
|
+
errors: string[];
|
|
137
|
+
};
|
|
132
138
|
planFollowedUpgradeDetection?: boolean;
|
|
133
139
|
}
|
|
134
140
|
/**
|
|
@@ -153,6 +159,13 @@ export declare function createScanSession(): ScanSession;
|
|
|
153
159
|
export declare function scanSessionOf(toolState: {
|
|
154
160
|
scanSession?: ScanSession;
|
|
155
161
|
}): ScanSession;
|
|
162
|
+
/** Publish a scan's reported concern set, and remember each concern for the
|
|
163
|
+
* rest of the run (see `concernsById`). */
|
|
164
|
+
export declare function recordScanConcerns(session: ScanSession, concerns: Concern[]): void;
|
|
165
|
+
/** Remember each concern for the rest of the run, so
|
|
166
|
+
* terraform_verify_remediation can key an id from ANY concern source — a
|
|
167
|
+
* findings file or an external report as much as a scan. */
|
|
168
|
+
export declare function recordConcernKeys(session: ScanSession, concerns: Concern[]): void;
|
|
156
169
|
/**
|
|
157
170
|
* true once terraform_scan / read_findings captured a pre-fix baseline this
|
|
158
171
|
* session. terraform_verify_remediation key-maps requested ids against the
|
|
@@ -1,20 +1,40 @@
|
|
|
1
1
|
import { type ToolsNetworkDirective } from "./scannerEgress.js";
|
|
2
|
+
import { type TreeLayout, type VarFileMapping } from "./treeLayout.js";
|
|
2
3
|
import { type Concern, type ScannerOutcome } from "./types.js";
|
|
3
4
|
import { type ResolvedToolSelection } from "../../utils/prompt/toolSelection.js";
|
|
4
|
-
/**
|
|
5
|
-
* Run `terraform init -backend=false` once per dir so `terraform validate` has
|
|
6
|
-
* provider schemas to check against (Bug 3 / gap B). Without init, validate only
|
|
7
|
-
* emits "missing required provider" — which VALIDATE_NOISE drops — so it was
|
|
8
|
-
* effectively inert. `-backend=false` avoids needing real backend credentials;
|
|
9
|
-
* `-input=false` keeps it non-interactive. Network-dependent and best-effort: if
|
|
10
|
-
* it fails (offline, private module, etc.) validate still runs, just shallow.
|
|
11
|
-
*/
|
|
12
5
|
/** Forget every init, so the next validate re-runs it — after its artefacts were removed. */
|
|
13
6
|
export declare function resetTerraformInitCache(): void;
|
|
14
|
-
|
|
7
|
+
/**
|
|
8
|
+
* The roots under `cwd` whose last `terraform init` failed, with init's error.
|
|
9
|
+
* Their validate is shallow — "Module not installed" is all it can say, and that
|
|
10
|
+
* is dropped as noise — so nothing that leans on validate may count them as
|
|
11
|
+
* checked.
|
|
12
|
+
*/
|
|
13
|
+
export declare function initFailures(cwd: string): {
|
|
14
|
+
root: string;
|
|
15
|
+
error: string;
|
|
16
|
+
}[];
|
|
17
|
+
/** {@link initFailures}, the roots only. */
|
|
18
|
+
export declare function initFailedRoots(cwd: string): string[];
|
|
19
|
+
/**
|
|
20
|
+
* `terraform` when installed, else `tofu` — OpenTofu-only runners keep fmt
|
|
21
|
+
* coverage (identical CLI surface; the source label stays "terraform-fmt" so
|
|
22
|
+
* rule ids and content hashes never fork on the binary name).
|
|
23
|
+
*
|
|
24
|
+
* Safe to run alongside `terraform init`: `fmt -recursive` skips dot-directories,
|
|
25
|
+
* so it never reads the `.terraform/` tree init is writing (verified against the
|
|
26
|
+
* installed CLI — an unformatted file planted under `.terraform/` is not reported).
|
|
27
|
+
*/
|
|
28
|
+
export declare function scanFmt(cwd: string): Promise<ScannerOutcome>;
|
|
15
29
|
/** `terraform fmt -check -list=true` prints one unformatted file path per line. */
|
|
16
30
|
export declare function parseFmtOutput(stdout: string, cwd?: string): Concern[];
|
|
17
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Run `terraform validate` across EVERY root and aggregate. `validate` is the
|
|
33
|
+
* one scanner that's per-root (fmt/tflint/trivy/checkov are recursive over the
|
|
34
|
+
* whole tree), so a multi-root repo only catches subdir-root validate errors
|
|
35
|
+
* when we visit each root. Inits first, through the same queue a scan uses.
|
|
36
|
+
*/
|
|
37
|
+
export declare function scanValidate(cwd: string, extraEnv?: Record<string, string>): Promise<ScannerOutcome>;
|
|
18
38
|
/** parse `terraform validate -json`; keeps real errors, drops uninitialized-dir noise. */
|
|
19
39
|
export declare function parseValidateOutput(stdout: string, cwd?: string): Concern[];
|
|
20
40
|
export interface ProviderRequirement {
|
|
@@ -84,17 +104,30 @@ export interface LocatedResource extends ResourceArguments {
|
|
|
84
104
|
* way as `collectProviderRequirements` — an unreadable file is skipped rather
|
|
85
105
|
* than failing the walk. */
|
|
86
106
|
export declare function collectResourceArguments(cwd: string): LocatedResource[];
|
|
87
|
-
export declare function scanTflint(cwd: string, network?: ToolsNetworkDirective): ScannerOutcome
|
|
107
|
+
export declare function scanTflint(cwd: string, network?: ToolsNetworkDirective): Promise<ScannerOutcome>;
|
|
88
108
|
/** parse `tflint --format json` output into concerns. */
|
|
89
109
|
export declare function parseTflintOutput(stdout: string, cwd?: string): Concern[];
|
|
110
|
+
/** One `trivy config` run: the variable files it loads, the directories it skips. */
|
|
111
|
+
interface TrivyRun {
|
|
112
|
+
tfVars: string[];
|
|
113
|
+
skipDirs: string[];
|
|
114
|
+
/** a root's run keeps only findings in that root's closure */
|
|
115
|
+
keep?: string[];
|
|
116
|
+
}
|
|
90
117
|
/**
|
|
91
|
-
*
|
|
92
|
-
* defaults unless told otherwise, so a value set in
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
118
|
+
* The trivy runs that cover `layout`. trivy evaluates variables from their
|
|
119
|
+
* defaults unless told otherwise, so a value set in a `.tfvars` file is
|
|
120
|
+
* invisible to a plain run, and a file passed to a whole-tree run applies to
|
|
121
|
+
* every root in it. So the whole tree is scanned once without variable files,
|
|
122
|
+
* then each root that has some once per file set, with every other root
|
|
123
|
+
* skipped (a root's own directory alone would lose its `../modules`): its
|
|
124
|
+
* auto-loaded files, then those plus each `-var-file` file in turn, as each
|
|
125
|
+
* `terraform plan` would load them. A tree with a single root loads its
|
|
126
|
+
* auto-loaded files in the whole-tree run.
|
|
96
127
|
*/
|
|
97
|
-
export declare function
|
|
128
|
+
export declare function trivyRuns(layout: TreeLayout, scope: readonly string[] | undefined): TrivyRun[];
|
|
129
|
+
/** `trivy config` arguments for one run over the scan directory. */
|
|
130
|
+
export declare function trivyArgs(run: TrivyRun): string[];
|
|
98
131
|
/**
|
|
99
132
|
* Parse `trivy config --format json` output into concerns. Trivy nests
|
|
100
133
|
* misconfigurations under `Results[].Misconfigurations[]`, keyed to the result's
|
|
@@ -114,10 +147,19 @@ export declare function parseTrivyOutput(stdout: string, cwd?: string): Concern[
|
|
|
114
147
|
* unreadable file just leaves the snippet null. Pure-ish (read-only I/O).
|
|
115
148
|
*/
|
|
116
149
|
export declare function attachSourceSnippets(concerns: Concern[], cwd: string): Concern[];
|
|
150
|
+
/**
|
|
151
|
+
* checkov `--skip-path` values for the directories a scoped scan leaves out.
|
|
152
|
+
* checkov matches each as a regular expression against a path whose form
|
|
153
|
+
* depends on how it walked there, so a pattern is anchored at a path
|
|
154
|
+
* separator and the end; one that would also match a directory the scan
|
|
155
|
+
* keeps (`envs/prod` and `nested/envs/prod`) is not passed — the scope filter
|
|
156
|
+
* still drops its findings, the scan just reads it.
|
|
157
|
+
*/
|
|
158
|
+
export declare function checkovSkipPaths(tfDirs: readonly string[], skip: readonly string[]): string[];
|
|
117
159
|
/** parse `checkov -o json` output (object for one framework, array for several).
|
|
118
160
|
* Each block's `check_type` names the framework that produced it (terraform /
|
|
119
161
|
* cloudformation / kubernetes / …) — carried onto every concern as its language. */
|
|
120
|
-
export declare function parseCheckovOutput(stdout: string, cwd?: string): Concern[];
|
|
162
|
+
export declare function parseCheckovOutput(stdout: string, cwd?: string, downloadDir?: string): Concern[];
|
|
121
163
|
/**
|
|
122
164
|
* Terraform files changed on the current branch vs the base. Returns null when
|
|
123
165
|
* the base can't be determined (caller then falls back to a full scan).
|
|
@@ -150,6 +192,12 @@ export interface RunScannersOptions {
|
|
|
150
192
|
* `"partial"` accordingly. Absent ⇒ open egress (today's behaviour) — deny is
|
|
151
193
|
* opt-in. */
|
|
152
194
|
toolsNetwork?: ToolsNetworkDirective | undefined;
|
|
195
|
+
/** the directories a scoped scan covers (`scopeFor`), relative to the scan
|
|
196
|
+
* directory; a finding elsewhere is dropped and roots outside are not
|
|
197
|
+
* initialised. Undefined scans the whole tree. */
|
|
198
|
+
scope?: string[] | undefined;
|
|
199
|
+
/** `-var-file` files whose root the `var_files` setting names. */
|
|
200
|
+
varFiles?: VarFileMapping[] | undefined;
|
|
153
201
|
}
|
|
154
202
|
/** run every scanner once over `cwd`. shared by `terraform_scan` and the
|
|
155
203
|
* deterministic remediation verifier so both see the identical toolchain. A
|
|
@@ -210,3 +258,4 @@ export declare function regressionIdsByKey(current: {
|
|
|
210
258
|
id: string;
|
|
211
259
|
key: string;
|
|
212
260
|
}[], baselineKeys: Set<string>): string[];
|
|
261
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type Concern } from "./types.js";
|
|
2
|
+
export interface SecretScan {
|
|
3
|
+
ran: boolean;
|
|
4
|
+
/** why it did not run */
|
|
5
|
+
reason?: string;
|
|
6
|
+
concerns: Concern[];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Parse a betterleaks v2 JSON report into concerns, paths made relative to the
|
|
10
|
+
* scan directory (`prefix` is its path in the repository), and whether the
|
|
11
|
+
* scan completed: an incomplete one keeps the findings it made before it
|
|
12
|
+
* stopped. Throws on a report that is not v2's.
|
|
13
|
+
*/
|
|
14
|
+
export declare function parseBetterleaksReport(json: string, prefix?: string): {
|
|
15
|
+
concerns: Concern[];
|
|
16
|
+
complete: boolean;
|
|
17
|
+
};
|
|
18
|
+
/** Scan the lines the commits after `mergeBase` add, from the scan directory `cwd`. */
|
|
19
|
+
export declare function scanAddedSecrets(cwd: string, mergeBase: string, tmp: string): Promise<SecretScan>;
|
|
@@ -212,7 +212,7 @@ export declare function buildStandardsReport(files: SourceFile[], concerns: Conc
|
|
|
212
212
|
* offered — `buildStandardsReport` is the pure seam for a caller that already
|
|
213
213
|
* holds both.
|
|
214
214
|
*/
|
|
215
|
-
export declare function standardsReport(cwd: string): StandardsReport
|
|
215
|
+
export declare function standardsReport(cwd: string): Promise<StandardsReport>;
|
|
216
216
|
/**
|
|
217
217
|
* The report as Markdown — the handover artefact.
|
|
218
218
|
*
|
|
@@ -17,7 +17,7 @@ export declare function collectCloudCredentials(): Record<string, string>;
|
|
|
17
17
|
export interface PlanRunners {
|
|
18
18
|
/** `tmpdir` is where the saved plan file goes — outside the repository,
|
|
19
19
|
* because it holds attribute values. */
|
|
20
|
-
planOneRoot: (absDir: string, creds: Record<string, string>, tmpdir?: string) => RootPlanOutcome
|
|
20
|
+
planOneRoot: (absDir: string, creds: Record<string, string>, tmpdir?: string) => Promise<RootPlanOutcome>;
|
|
21
21
|
hasCloudCredentials: () => boolean;
|
|
22
22
|
}
|
|
23
23
|
export declare function runPlan(ctx: LocalToolContext, runners?: PlanRunners): Promise<Record<string, any> | import("../../shared.js").ToolOk<{
|
|
@@ -21,9 +21,9 @@ export declare function runScan(ctx: LocalToolContext, { scan_scope, severity_th
|
|
|
21
21
|
scope: string;
|
|
22
22
|
scope_note?: string;
|
|
23
23
|
grouping: "file" | "rule";
|
|
24
|
-
scanners_ran: ("checkov" | "infraweaver" | "reviewer" | "terraform-fmt" | "terraform-validate" | "tflint" | "trivy")[];
|
|
24
|
+
scanners_ran: ("betterleaks" | "checkov" | "infraweaver" | "reviewer" | "terraform-fmt" | "terraform-validate" | "tflint" | "trivy")[];
|
|
25
25
|
scanners_skipped: {
|
|
26
|
-
source: "checkov" | "infraweaver" | "reviewer" | "terraform-fmt" | "terraform-validate" | "tflint" | "trivy";
|
|
26
|
+
source: "betterleaks" | "checkov" | "infraweaver" | "reviewer" | "terraform-fmt" | "terraform-validate" | "tflint" | "trivy";
|
|
27
27
|
reason: string | undefined;
|
|
28
28
|
}[];
|
|
29
29
|
scanners_partial?: import("../types.js").CoverageGap[];
|
|
@@ -41,7 +41,6 @@ export declare function runScan(ctx: LocalToolContext, { scan_scope, severity_th
|
|
|
41
41
|
by_severity: Record<string, number>;
|
|
42
42
|
};
|
|
43
43
|
groups: {
|
|
44
|
-
doc_urls: Record<string, string>;
|
|
45
44
|
id: string;
|
|
46
45
|
file: string;
|
|
47
46
|
files?: string[];
|
|
@@ -53,6 +52,7 @@ export declare function runScan(ctx: LocalToolContext, { scan_scope, severity_th
|
|
|
53
52
|
autonomy?: import("../types.js").Autonomy;
|
|
54
53
|
autonomy_reasons?: string[];
|
|
55
54
|
priority?: import("../types.js").PriorityBand;
|
|
55
|
+
doc_urls: Record<string, string>;
|
|
56
56
|
}[];
|
|
57
57
|
batch_plan: import("../decisions.js").BatchPlan;
|
|
58
58
|
co_located: import("../decisions.js").LocationCluster[];
|
|
@@ -64,11 +64,8 @@ export declare function runScan(ctx: LocalToolContext, { scan_scope, severity_th
|
|
|
64
64
|
top_risks: import("../risk.js").RankedConcern[];
|
|
65
65
|
reintroduced?: import("../lineage.js").ReintroducedFinding[];
|
|
66
66
|
concerns: {
|
|
67
|
-
doc_url: string | null;
|
|
68
|
-
risk_score: number;
|
|
69
|
-
noise_reason?: string;
|
|
70
67
|
id: string;
|
|
71
|
-
source: "terraform-fmt" | "terraform-validate" | "tflint" | "trivy" | "checkov" | "infraweaver" | "reviewer";
|
|
68
|
+
source: "terraform-fmt" | "terraform-validate" | "tflint" | "trivy" | "checkov" | "infraweaver" | "betterleaks" | "reviewer";
|
|
72
69
|
rule_id: string;
|
|
73
70
|
severity: Severity;
|
|
74
71
|
category: "security" | "style" | "correctness" | "cost";
|
|
@@ -83,6 +80,9 @@ export declare function runScan(ctx: LocalToolContext, { scan_scope, severity_th
|
|
|
83
80
|
suppression?: import("../types.js").ConcernSuppression;
|
|
84
81
|
canonical_class?: string;
|
|
85
82
|
flagged_by?: string[];
|
|
83
|
+
doc_url: string | null;
|
|
84
|
+
risk_score: number;
|
|
85
|
+
noise_reason?: string;
|
|
86
86
|
}[];
|
|
87
87
|
orphan_native_skips?: {
|
|
88
88
|
file: string;
|