terramend 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/README.md +145 -0
- package/dist/agents/claude.d.ts +73 -0
- package/dist/agents/claudePretoolGate.d.ts +99 -0
- package/dist/agents/gateServer.d.ts +7 -0
- package/dist/agents/index.d.ts +6 -0
- package/dist/agents/nativeFsDenies.d.ts +28 -0
- package/dist/agents/opencode.d.ts +231 -0
- package/dist/agents/opencodePlugin.d.ts +85 -0
- package/dist/agents/opencodeShared.d.ts +40 -0
- package/dist/agents/postRun.d.ts +132 -0
- package/dist/agents/reviewer.d.ts +38 -0
- package/dist/agents/sessionLabeler.d.ts +97 -0
- package/dist/agents/shared.d.ts +189 -0
- package/dist/agents/subagentModels.d.ts +19 -0
- package/dist/agents/subagentToolGates.d.ts +55 -0
- package/dist/cli.mjs +197426 -0
- package/dist/external.d.ts +227 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +196783 -0
- package/dist/internal/index.d.ts +18 -0
- package/dist/internal.js +1714 -0
- package/dist/lifecycle.d.ts +2 -0
- package/dist/main.d.ts +8 -0
- package/dist/mcp/arkConfig.d.ts +1 -0
- package/dist/mcp/checkSuite.d.ts +25 -0
- package/dist/mcp/checkout.d.ts +77 -0
- package/dist/mcp/comment.d.ts +119 -0
- package/dist/mcp/commitInfo.d.ts +9 -0
- package/dist/mcp/crosswalk.d.ts +105 -0
- package/dist/mcp/dependencies.d.ts +8 -0
- package/dist/mcp/geminiSanitizer.d.ts +28 -0
- package/dist/mcp/git.d.ts +46 -0
- package/dist/mcp/guardrails.d.ts +104 -0
- package/dist/mcp/issue.d.ts +18 -0
- package/dist/mcp/issueComments.d.ts +9 -0
- package/dist/mcp/issueEvents.d.ts +9 -0
- package/dist/mcp/issueInfo.d.ts +9 -0
- package/dist/mcp/labels.d.ts +12 -0
- package/dist/mcp/localContext.d.ts +19 -0
- package/dist/mcp/moduleExtraction.d.ts +71 -0
- package/dist/mcp/moduleTests.d.ts +104 -0
- package/dist/mcp/modules.d.ts +179 -0
- package/dist/mcp/output.d.ts +12 -0
- package/dist/mcp/pathSafety.d.ts +14 -0
- package/dist/mcp/policy.d.ts +48 -0
- package/dist/mcp/pr.d.ts +49 -0
- package/dist/mcp/prInfo.d.ts +9 -0
- package/dist/mcp/providerSchema.d.ts +50 -0
- package/dist/mcp/review.d.ts +199 -0
- package/dist/mcp/reviewComments.d.ts +178 -0
- package/dist/mcp/roots.d.ts +58 -0
- package/dist/mcp/scope.d.ts +15 -0
- package/dist/mcp/selectMode.d.ts +18 -0
- package/dist/mcp/server.d.ts +48 -0
- package/dist/mcp/shared.d.ts +47 -0
- package/dist/mcp/shell.d.ts +37 -0
- package/dist/mcp/staleFix.d.ts +51 -0
- package/dist/mcp/terraform/cost.d.ts +55 -0
- package/dist/mcp/terraform/currency.d.ts +94 -0
- package/dist/mcp/terraform/decisions.d.ts +178 -0
- package/dist/mcp/terraform/findings.d.ts +75 -0
- package/dist/mcp/terraform/plan.d.ts +157 -0
- package/dist/mcp/terraform/scanners.d.ts +131 -0
- package/dist/mcp/terraform/tools.d.ts +63 -0
- package/dist/mcp/terraform/types.d.ts +172 -0
- package/dist/mcp/terraform.d.ts +22 -0
- package/dist/mcp/terratest.d.ts +83 -0
- package/dist/mcp/upload.d.ts +6 -0
- package/dist/models.d.ts +171 -0
- package/dist/modes.d.ts +26 -0
- package/dist/prep/index.d.ts +7 -0
- package/dist/prep/installNodeDependencies.d.ts +2 -0
- package/dist/prep/installPythonDependencies.d.ts +2 -0
- package/dist/prep/types.d.ts +31 -0
- package/dist/reviewQuality.d.ts +64 -0
- package/dist/skills/terraform-best-practices/SKILL.md +369 -0
- package/dist/toolState.d.ts +135 -0
- package/dist/utils/activity.d.ts +40 -0
- package/dist/utils/agent.d.ts +20 -0
- package/dist/utils/agentHangReport.d.ts +38 -0
- package/dist/utils/apiFetch.d.ts +19 -0
- package/dist/utils/apiKeys.d.ts +41 -0
- package/dist/utils/apiUrl.d.ts +20 -0
- package/dist/utils/assets.d.ts +8 -0
- package/dist/utils/billingErrors.d.ts +85 -0
- package/dist/utils/body.d.ts +34 -0
- package/dist/utils/buildTerramendFooter.d.ts +25 -0
- package/dist/utils/byokFallback.d.ts +85 -0
- package/dist/utils/claudeSubscription.d.ts +30 -0
- package/dist/utils/cli.d.ts +10 -0
- package/dist/utils/codexHome.d.ts +29 -0
- package/dist/utils/codexOAuth.d.ts +60 -0
- package/dist/utils/diffCoverage.d.ts +63 -0
- package/dist/utils/errorReport.d.ts +17 -0
- package/dist/utils/exitHandler.d.ts +8 -0
- package/dist/utils/fixDoubleEscapedString.d.ts +1 -0
- package/dist/utils/gitAuth.d.ts +84 -0
- package/dist/utils/gitAuthServer.d.ts +24 -0
- package/dist/utils/github.d.ts +78 -0
- package/dist/utils/globals.d.ts +3 -0
- package/dist/utils/install.d.ts +60 -0
- package/dist/utils/instructions.d.ts +48 -0
- package/dist/utils/leapingComment.d.ts +11 -0
- package/dist/utils/learnings.d.ts +62 -0
- package/dist/utils/learningsTruncate.d.ts +25 -0
- package/dist/utils/lifecycle.d.ts +57 -0
- package/dist/utils/log.d.ts +111 -0
- package/dist/utils/normalizeEnv.d.ts +30 -0
- package/dist/utils/openCodeModels.d.ts +11 -0
- package/dist/utils/overrides.d.ts +40 -0
- package/dist/utils/packageManager.d.ts +49 -0
- package/dist/utils/patchWorkflowRunFields.d.ts +29 -0
- package/dist/utils/payload.d.ts +105 -0
- package/dist/utils/prSummary.d.ts +61 -0
- package/dist/utils/progressComment.d.ts +146 -0
- package/dist/utils/providerErrors.d.ts +31 -0
- package/dist/utils/rangeDiff.d.ts +51 -0
- package/dist/utils/remediationCommand.d.ts +55 -0
- package/dist/utils/retry.d.ts +13 -0
- package/dist/utils/reviewCleanup.d.ts +14 -0
- package/dist/utils/run.d.ts +9 -0
- package/dist/utils/runContext.d.ts +60 -0
- package/dist/utils/runContextData.d.ts +23 -0
- package/dist/utils/runErrorRenderer.d.ts +64 -0
- package/dist/utils/runLifecycle.d.ts +86 -0
- package/dist/utils/runStartupLog.d.ts +15 -0
- package/dist/utils/secrets.d.ts +22 -0
- package/dist/utils/setup.d.ts +90 -0
- package/dist/utils/shell.d.ts +32 -0
- package/dist/utils/skills.d.ts +10 -0
- package/dist/utils/subprocess.d.ts +80 -0
- package/dist/utils/terraformMcp.d.ts +42 -0
- package/dist/utils/time.d.ts +15 -0
- package/dist/utils/timer.d.ts +23 -0
- package/dist/utils/todoTracking.d.ts +16 -0
- package/dist/utils/token.d.ts +39 -0
- package/dist/utils/version.d.ts +2 -0
- package/dist/utils/versioning.d.ts +7 -0
- package/dist/utils/vertex.d.ts +16 -0
- package/dist/utils/workflow.d.ts +13 -0
- package/package.json +119 -0
- package/src/agents/claude.test.ts +1016 -0
- package/src/agents/claude.ts +1246 -0
- package/src/agents/claudePretoolGate.test.ts +28 -0
- package/src/agents/claudePretoolGate.ts +173 -0
- package/src/agents/gateServer.test.ts +204 -0
- package/src/agents/gateServer.ts +124 -0
- package/src/agents/index.ts +10 -0
- package/src/agents/nativeFsDenies.ts +82 -0
- package/src/agents/opencode.test.ts +1440 -0
- package/src/agents/opencode.ts +1312 -0
- package/src/agents/opencodePlugin.ts +222 -0
- package/src/agents/opencodeShared.test.ts +34 -0
- package/src/agents/opencodeShared.ts +121 -0
- package/src/agents/postRun.test.ts +549 -0
- package/src/agents/postRun.ts +535 -0
- package/src/agents/reviewer.ts +104 -0
- package/src/agents/sessionLabeler.test.ts +247 -0
- package/src/agents/sessionLabeler.ts +178 -0
- package/src/agents/shared.test.ts +76 -0
- package/src/agents/shared.ts +292 -0
- package/src/agents/subagentModels.test.ts +113 -0
- package/src/agents/subagentModels.ts +40 -0
- package/src/agents/subagentRegistration.test.ts +41 -0
- package/src/agents/subagentToolGates.ts +114 -0
- package/src/cli.test.ts +129 -0
- package/src/cli.ts +105 -0
- package/src/commands/gha.test.ts +192 -0
- package/src/commands/gha.ts +188 -0
- package/src/commands/mcp.ts +122 -0
- package/src/config.ts +1 -0
- package/src/entry.ts +7 -0
- package/src/entryPost.stdlibOnly.test.ts +109 -0
- package/src/entryPost.ts +99 -0
- package/src/external.test.ts +16 -0
- package/src/external.ts +302 -0
- package/src/index.ts +11 -0
- package/src/internal/index.ts +71 -0
- package/src/lifecycle.ts +2 -0
- package/src/main.test.ts +873 -0
- package/src/main.ts +712 -0
- package/src/mcp/__fixtures__/terramend-scratch-pr-49-review-3485940013.json +110 -0
- package/src/mcp/__fixtures__/terramend-scratch-pr-64-review-3531000326.json +14 -0
- package/src/mcp/__fixtures__/terramend-test-repo-pr-1.diff.json +67 -0
- package/src/mcp/__snapshots__/checkout.test.ts.snap +109 -0
- package/src/mcp/__snapshots__/reviewComments.test.ts.snap +71 -0
- package/src/mcp/arkConfig.ts +7 -0
- package/src/mcp/checkSuite.test.ts +245 -0
- package/src/mcp/checkSuite.ts +255 -0
- package/src/mcp/checkout.test.ts +752 -0
- package/src/mcp/checkout.ts +886 -0
- package/src/mcp/comment.test.ts +772 -0
- package/src/mcp/comment.ts +582 -0
- package/src/mcp/commitInfo.test.ts +127 -0
- package/src/mcp/commitInfo.ts +61 -0
- package/src/mcp/crosswalk.test.ts +106 -0
- package/src/mcp/crosswalk.ts +339 -0
- package/src/mcp/dependencies.test.ts +309 -0
- package/src/mcp/dependencies.ts +189 -0
- package/src/mcp/geminiSanitizer.test.ts +287 -0
- package/src/mcp/geminiSanitizer.ts +207 -0
- package/src/mcp/git.test.ts +1083 -0
- package/src/mcp/git.ts +890 -0
- package/src/mcp/guardrails.test.ts +705 -0
- package/src/mcp/guardrails.ts +465 -0
- package/src/mcp/issue.test.ts +113 -0
- package/src/mcp/issue.ts +73 -0
- package/src/mcp/issueComments.test.ts +69 -0
- package/src/mcp/issueComments.ts +48 -0
- package/src/mcp/issueEvents.test.ts +134 -0
- package/src/mcp/issueEvents.ts +100 -0
- package/src/mcp/issueInfo.test.ts +104 -0
- package/src/mcp/issueInfo.ts +72 -0
- package/src/mcp/labels.test.ts +52 -0
- package/src/mcp/labels.ts +34 -0
- package/src/mcp/localContext.ts +28 -0
- package/src/mcp/localServer.test.ts +75 -0
- package/src/mcp/localServer.ts +131 -0
- package/src/mcp/moduleExtraction.test.ts +261 -0
- package/src/mcp/moduleExtraction.ts +313 -0
- package/src/mcp/moduleTests.test.ts +269 -0
- package/src/mcp/moduleTests.ts +421 -0
- package/src/mcp/modules.test.ts +640 -0
- package/src/mcp/modules.ts +696 -0
- package/src/mcp/output.test.ts +96 -0
- package/src/mcp/output.ts +70 -0
- package/src/mcp/pathSafety.test.ts +44 -0
- package/src/mcp/pathSafety.ts +28 -0
- package/src/mcp/policy.test.ts +282 -0
- package/src/mcp/policy.ts +199 -0
- package/src/mcp/pr.test.ts +387 -0
- package/src/mcp/pr.ts +194 -0
- package/src/mcp/prInfo.test.ts +96 -0
- package/src/mcp/prInfo.ts +91 -0
- package/src/mcp/providerSchema.test.ts +85 -0
- package/src/mcp/providerSchema.ts +175 -0
- package/src/mcp/review.test.ts +936 -0
- package/src/mcp/review.ts +923 -0
- package/src/mcp/reviewComments.test.ts +549 -0
- package/src/mcp/reviewComments.ts +896 -0
- package/src/mcp/roots.test.ts +175 -0
- package/src/mcp/roots.ts +217 -0
- package/src/mcp/scope.test.ts +59 -0
- package/src/mcp/scope.ts +65 -0
- package/src/mcp/security.test.ts +720 -0
- package/src/mcp/selectMode.test.ts +210 -0
- package/src/mcp/selectMode.ts +181 -0
- package/src/mcp/server.test.ts +292 -0
- package/src/mcp/server.ts +403 -0
- package/src/mcp/shared.ts +100 -0
- package/src/mcp/shell.test.ts +520 -0
- package/src/mcp/shell.ts +505 -0
- package/src/mcp/staleFix.test.ts +237 -0
- package/src/mcp/staleFix.ts +277 -0
- package/src/mcp/terraform/cost.ts +163 -0
- package/src/mcp/terraform/currency.test.ts +338 -0
- package/src/mcp/terraform/currency.ts +336 -0
- package/src/mcp/terraform/decisions.ts +527 -0
- package/src/mcp/terraform/findings.ts +333 -0
- package/src/mcp/terraform/plan.ts +348 -0
- package/src/mcp/terraform/scanners.ts +809 -0
- package/src/mcp/terraform/tools.test.ts +1071 -0
- package/src/mcp/terraform/tools.ts +908 -0
- package/src/mcp/terraform/types.ts +305 -0
- package/src/mcp/terraform.test.ts +1957 -0
- package/src/mcp/terraform.ts +23 -0
- package/src/mcp/terratest.test.ts +105 -0
- package/src/mcp/terratest.ts +196 -0
- package/src/mcp/toolFiltering.test.ts +85 -0
- package/src/mcp/upload.test.ts +180 -0
- package/src/mcp/upload.ts +112 -0
- package/src/models.test.ts +300 -0
- package/src/models.ts +708 -0
- package/src/modes.test.ts +107 -0
- package/src/modes.ts +880 -0
- package/src/prep/index.ts +43 -0
- package/src/prep/installNodeDependencies.test.ts +298 -0
- package/src/prep/installNodeDependencies.ts +196 -0
- package/src/prep/installPythonDependencies.test.ts +268 -0
- package/src/prep/installPythonDependencies.ts +199 -0
- package/src/prep/types.ts +38 -0
- package/src/reviewQuality.test.ts +63 -0
- package/src/reviewQuality.ts +134 -0
- package/src/runCli.test.ts +214 -0
- package/src/runCli.ts +282 -0
- package/src/skills/terraform-best-practices/SKILL.md +369 -0
- package/src/toolState.test.ts +45 -0
- package/src/toolState.ts +252 -0
- package/src/utils/activity.test.ts +188 -0
- package/src/utils/activity.ts +210 -0
- package/src/utils/agent.test.ts +251 -0
- package/src/utils/agent.ts +139 -0
- package/src/utils/agentHangReport.test.ts +203 -0
- package/src/utils/agentHangReport.ts +170 -0
- package/src/utils/apiFetch.test.ts +115 -0
- package/src/utils/apiFetch.ts +62 -0
- package/src/utils/apiKeys.test.ts +344 -0
- package/src/utils/apiKeys.ts +206 -0
- package/src/utils/apiUrl.test.ts +30 -0
- package/src/utils/apiUrl.ts +59 -0
- package/src/utils/assets.test.ts +153 -0
- package/src/utils/assets.ts +107 -0
- package/src/utils/billingErrors.test.ts +121 -0
- package/src/utils/billingErrors.ts +189 -0
- package/src/utils/body.test.ts +217 -0
- package/src/utils/body.ts +168 -0
- package/src/utils/buildTerramendFooter.test.ts +38 -0
- package/src/utils/buildTerramendFooter.ts +82 -0
- package/src/utils/byokFallback.test.ts +205 -0
- package/src/utils/byokFallback.ts +128 -0
- package/src/utils/claudeSubscription.test.ts +179 -0
- package/src/utils/claudeSubscription.ts +93 -0
- package/src/utils/cli.ts +31 -0
- package/src/utils/codexHome.test.ts +190 -0
- package/src/utils/codexHome.ts +191 -0
- package/src/utils/codexOAuth.ts +147 -0
- package/src/utils/codexRefreshDetect.test.ts +85 -0
- package/src/utils/codexRefreshDetect.ts +35 -0
- package/src/utils/diffCoverage.test.ts +468 -0
- package/src/utils/diffCoverage.ts +404 -0
- package/src/utils/errorReport.test.ts +135 -0
- package/src/utils/errorReport.ts +83 -0
- package/src/utils/exitHandler.ts +35 -0
- package/src/utils/fixDoubleEscapedString.ts +9 -0
- package/src/utils/ghaCore.ts +13 -0
- package/src/utils/gitAuth.test.ts +322 -0
- package/src/utils/gitAuth.ts +263 -0
- package/src/utils/gitAuthServer.test.ts +260 -0
- package/src/utils/gitAuthServer.ts +182 -0
- package/src/utils/github.test.ts +615 -0
- package/src/utils/github.ts +538 -0
- package/src/utils/globals.ts +9 -0
- package/src/utils/humanEditCapture.test.ts +100 -0
- package/src/utils/humanEditCapture.ts +193 -0
- package/src/utils/install.test.ts +768 -0
- package/src/utils/install.ts +492 -0
- package/src/utils/instructions.test.ts +240 -0
- package/src/utils/instructions.ts +543 -0
- package/src/utils/leapingComment.test.ts +51 -0
- package/src/utils/leapingComment.ts +18 -0
- package/src/utils/learnings.test.ts +87 -0
- package/src/utils/learnings.ts +138 -0
- package/src/utils/learningsTocRender.test.ts +116 -0
- package/src/utils/learningsTruncate.test.ts +39 -0
- package/src/utils/learningsTruncate.ts +42 -0
- package/src/utils/lifecycle.test.ts +195 -0
- package/src/utils/lifecycle.ts +198 -0
- package/src/utils/log.test.ts +402 -0
- package/src/utils/log.ts +432 -0
- package/src/utils/normalizeEnv.test.ts +91 -0
- package/src/utils/normalizeEnv.ts +106 -0
- package/src/utils/openCodeModels.ts +82 -0
- package/src/utils/overrides.test.ts +89 -0
- package/src/utils/overrides.ts +98 -0
- package/src/utils/packageManager.test.ts +321 -0
- package/src/utils/packageManager.ts +257 -0
- package/src/utils/patchWorkflowRunFields.test.ts +92 -0
- package/src/utils/patchWorkflowRunFields.ts +150 -0
- package/src/utils/payload.test.ts +497 -0
- package/src/utils/payload.ts +371 -0
- package/src/utils/postApiFetch.ts +51 -0
- package/src/utils/prSummary.test.ts +224 -0
- package/src/utils/prSummary.ts +147 -0
- package/src/utils/progressComment.ts +261 -0
- package/src/utils/providerErrors.test.ts +315 -0
- package/src/utils/providerErrors.ts +172 -0
- package/src/utils/rangeDiff.test.ts +236 -0
- package/src/utils/rangeDiff.ts +182 -0
- package/src/utils/remediationCommand.test.ts +163 -0
- package/src/utils/remediationCommand.ts +119 -0
- package/src/utils/retry.test.ts +153 -0
- package/src/utils/retry.ts +58 -0
- package/src/utils/reviewCleanup.ts +106 -0
- package/src/utils/run.ts +99 -0
- package/src/utils/runContext.ts +145 -0
- package/src/utils/runContextData.ts +58 -0
- package/src/utils/runErrorRenderer.test.ts +95 -0
- package/src/utils/runErrorRenderer.ts +259 -0
- package/src/utils/runFixture.ts +76 -0
- package/src/utils/runLifecycle.ts +237 -0
- package/src/utils/runStartupLog.ts +60 -0
- package/src/utils/secrets.test.ts +103 -0
- package/src/utils/secrets.ts +177 -0
- package/src/utils/setup.test.ts +509 -0
- package/src/utils/setup.ts +352 -0
- package/src/utils/shell.ts +103 -0
- package/src/utils/skills.test.ts +46 -0
- package/src/utils/skills.ts +67 -0
- package/src/utils/subprocess.test.ts +170 -0
- package/src/utils/subprocess.ts +438 -0
- package/src/utils/terraformMcp.test.ts +63 -0
- package/src/utils/terraformMcp.ts +83 -0
- package/src/utils/time.test.ts +105 -0
- package/src/utils/time.ts +59 -0
- package/src/utils/timer.test.ts +91 -0
- package/src/utils/timer.ts +72 -0
- package/src/utils/todoTracking.test.ts +223 -0
- package/src/utils/todoTracking.ts +167 -0
- package/src/utils/token.test.ts +239 -0
- package/src/utils/token.ts +186 -0
- package/src/utils/version.ts +10 -0
- package/src/utils/versioning.test.ts +34 -0
- package/src/utils/versioning.ts +44 -0
- package/src/utils/vertex.ts +85 -0
- package/src/utils/workflow.ts +25 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { type Concern, type ScannerOutcome } from "#app/mcp/terraform/types";
|
|
2
|
+
export declare function scanFmt(cwd: string): ScannerOutcome;
|
|
3
|
+
/** `terraform fmt -check -list=true` prints one unformatted file path per line. */
|
|
4
|
+
export declare function parseFmtOutput(stdout: string, cwd?: string): Concern[];
|
|
5
|
+
/**
|
|
6
|
+
* Run `terraform validate` across EVERY root and aggregate. `validate` is the
|
|
7
|
+
* one scanner that's per-root (fmt/tflint/trivy/checkov are recursive over the
|
|
8
|
+
* whole tree), so a multi-root repo only catches subdir-root validate errors
|
|
9
|
+
* when we visit each root.
|
|
10
|
+
*/
|
|
11
|
+
export declare function scanValidate(cwd: string): ScannerOutcome;
|
|
12
|
+
/** parse `terraform validate -json`; keeps real errors, drops uninitialized-dir noise. */
|
|
13
|
+
export declare function parseValidateOutput(stdout: string, cwd?: string): Concern[];
|
|
14
|
+
export interface ProviderRequirement {
|
|
15
|
+
/** local name, e.g. `aws`. */
|
|
16
|
+
name: string;
|
|
17
|
+
/** registry source, e.g. `hashicorp/aws`, or null (legacy string form). */
|
|
18
|
+
source: string | null;
|
|
19
|
+
/** raw version constraint, e.g. `~> 5.0`, or null when unconstrained. */
|
|
20
|
+
version: string | null;
|
|
21
|
+
/** the pinned MAJOR (the lower-bound major of the constraint) — the number a
|
|
22
|
+
* fix must target, since argument schemas differ across provider majors. */
|
|
23
|
+
major: number | null;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Parse every `required_providers { … }` block in some HCL text into the pinned
|
|
27
|
+
* provider requirements. Handles the modern object form
|
|
28
|
+
* (`aws = { source = "hashicorp/aws", version = "~> 5.0" }`) and the legacy
|
|
29
|
+
* string form (`aws = "~> 5.0"`). A repo's "correct" fix depends on the provider
|
|
30
|
+
* MAJOR — argument names and valid blocks differ across AWS/Azure majors — so
|
|
31
|
+
* surfacing the pinned major lets a fix target the right schema instead of
|
|
32
|
+
* breaking `plan`. Brace-matched (not a fragile single regex) so nested objects
|
|
33
|
+
* don't confuse it. First declaration of a name wins (dedup across files).
|
|
34
|
+
*/
|
|
35
|
+
export declare function parseRequiredProviders(hcl: string): ProviderRequirement[];
|
|
36
|
+
/** read the repo's `*.tf` files (recursively — root + subdir roots + nested
|
|
37
|
+
* modules) and parse their pinned provider requirements (best-effort; an
|
|
38
|
+
* unreadable tree yields none). First declaration of a provider wins. */
|
|
39
|
+
export declare function collectProviderRequirements(cwd: string): ProviderRequirement[];
|
|
40
|
+
/** the top-level arguments of a single `resource` block. */
|
|
41
|
+
export interface ResourceArguments {
|
|
42
|
+
resourceType: string;
|
|
43
|
+
/** the resource's local name (`resource "aws_s3_bucket" "<name>"`). */
|
|
44
|
+
name: string;
|
|
45
|
+
/** top-level attribute + nested-block names (meta-arguments excluded). */
|
|
46
|
+
args: string[];
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Parse every `resource "<type>" "<name>" { … }` block's TOP-LEVEL argument
|
|
50
|
+
* names (attributes assigned with `=` and nested block labels) from some HCL.
|
|
51
|
+
* Conservative by design — it skips `"…"` strings and `#`/`//` line comments so
|
|
52
|
+
* an interpolation's braces or a commented line can't corrupt the brace depth or
|
|
53
|
+
* fabricate an argument, and only reports depth-0 names. A `dynamic "x"` block
|
|
54
|
+
* contributes `x` (the generated block type). Used to cross-check written
|
|
55
|
+
* arguments against the installed provider schema; pure.
|
|
56
|
+
*/
|
|
57
|
+
export declare function parseResourceArguments(hcl: string): ResourceArguments[];
|
|
58
|
+
export interface UnknownArgument {
|
|
59
|
+
resource_type: string;
|
|
60
|
+
/** the resource's local name. */
|
|
61
|
+
name: string;
|
|
62
|
+
/** repo-relative file the resource is declared in. */
|
|
63
|
+
file: string;
|
|
64
|
+
/** the argument names not present in the installed provider's schema. */
|
|
65
|
+
unknown: string[];
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* §4.15-next — cross-check every resource's written arguments against the
|
|
69
|
+
* INSTALLED provider's schema, so an argument that's invalid for the pinned
|
|
70
|
+
* provider major (a "correct" fix for the wrong version) is caught at validate
|
|
71
|
+
* time, not as a later `plan` failure. Degrades green: returns
|
|
72
|
+
* `{ checked: false }` when the schema is unavailable (terraform not installed /
|
|
73
|
+
* dir not init-ed). A resource type absent from the schema is skipped (can't
|
|
74
|
+
* judge), never flagged.
|
|
75
|
+
*/
|
|
76
|
+
export declare function checkArgumentsAgainstSchema(cwd: string): {
|
|
77
|
+
checked: boolean;
|
|
78
|
+
unknown_arguments: UnknownArgument[];
|
|
79
|
+
};
|
|
80
|
+
export declare function scanTflint(cwd: string): ScannerOutcome;
|
|
81
|
+
/** parse `tflint --format json` output into concerns. */
|
|
82
|
+
export declare function parseTflintOutput(stdout: string, cwd?: string): Concern[];
|
|
83
|
+
/**
|
|
84
|
+
* Parse `trivy config --format json` output into concerns. Trivy nests
|
|
85
|
+
* misconfigurations under `Results[].Misconfigurations[]`, keyed to the result's
|
|
86
|
+
* `Target` file. `trivy config` reports only failures by default, but we
|
|
87
|
+
* defensively drop any `Status: "PASS"` entry so an `--include-non-failures`
|
|
88
|
+
* run can't leak passing checks into the concern set.
|
|
89
|
+
*/
|
|
90
|
+
export declare function parseTrivyOutput(stdout: string, cwd?: string): Concern[];
|
|
91
|
+
/** parse `checkov -o json` output (object for one framework, array for several). */
|
|
92
|
+
export declare function parseCheckovOutput(stdout: string, cwd?: string): Concern[];
|
|
93
|
+
/**
|
|
94
|
+
* Terraform files changed on the current branch vs the base. Returns null when
|
|
95
|
+
* the base can't be determined (caller then falls back to a full scan).
|
|
96
|
+
*/
|
|
97
|
+
export declare function changedTerraformFiles(cwd: string): Set<string> | null;
|
|
98
|
+
/** run every scanner once over `cwd`. shared by `terraform_scan` and the
|
|
99
|
+
* deterministic remediation verifier so both see the identical toolchain. */
|
|
100
|
+
export declare function runScanners(cwd: string): ScannerOutcome[];
|
|
101
|
+
export interface RemediationVerdict {
|
|
102
|
+
/** true only when every original concern id is absent from the re-scan. */
|
|
103
|
+
verified: boolean;
|
|
104
|
+
/** original ids no longer present (the fix cleared them). */
|
|
105
|
+
resolved: string[];
|
|
106
|
+
/** original ids still present (the fix did NOT clear them). */
|
|
107
|
+
remaining: string[];
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Deterministic ✗→✓ check: partition the group's original `concern_ids` into
|
|
111
|
+
* those gone from a fresh scan (`resolved`) and those still present
|
|
112
|
+
* (`remaining`). Concern ids are content hashes (`sha1(source|rule|file|line)`),
|
|
113
|
+
* so a missing id means that exact concern is gone — the correct primitive for
|
|
114
|
+
* "did the fix clear it", independent of severity/scope filtering. This is the
|
|
115
|
+
* code-level replacement for the agent eyeballing a re-scan and self-reporting.
|
|
116
|
+
*/
|
|
117
|
+
export declare function computeRemediationVerdict(originalConcernIds: string[], currentConcernIds: Set<string>): RemediationVerdict;
|
|
118
|
+
/**
|
|
119
|
+
* §1.4 Regression guard. The full re-scan (`terraform_verify_remediation`)
|
|
120
|
+
* already sees the whole workspace, so a concern the fix *introduced* shows up
|
|
121
|
+
* in the current scan. Regressions are exactly the content ids present after the
|
|
122
|
+
* fix that were not in the pre-fix baseline — `current − baseline`. A non-empty
|
|
123
|
+
* result means the fix traded one defect for another (e.g. an encryption block
|
|
124
|
+
* that trips a different tflint rule) and must downgrade the PR to needs-human.
|
|
125
|
+
*
|
|
126
|
+
* Both id sets are computed the same way (the deduped union of every scanner's
|
|
127
|
+
* concern ids, unfiltered by severity) so the diff is apples-to-apples — a
|
|
128
|
+
* regression at ANY severity is caught, not just ones above the run threshold.
|
|
129
|
+
* Returns sorted ids for a stable PR body.
|
|
130
|
+
*/
|
|
131
|
+
export declare function computeRegressions(baselineConcernIds: Iterable<string>, currentConcernIds: Iterable<string>): string[];
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { LocalToolContext } from "#app/mcp/localContext";
|
|
2
|
+
export declare const TerraformScanParams: import("arktype/internal/variants/object.ts").ObjectType<{
|
|
3
|
+
scan_scope?: "diff" | "full";
|
|
4
|
+
severity_threshold?: "critical" | "high" | "medium" | "low" | "info";
|
|
5
|
+
group_by?: "file" | "rule";
|
|
6
|
+
}, {}>;
|
|
7
|
+
export declare function TerraformScanTool(ctx: LocalToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<{
|
|
8
|
+
scan_scope?: "diff" | "full";
|
|
9
|
+
severity_threshold?: "critical" | "high" | "medium" | "low" | "info";
|
|
10
|
+
group_by?: "file" | "rule";
|
|
11
|
+
}, {
|
|
12
|
+
scan_scope?: "diff" | "full";
|
|
13
|
+
severity_threshold?: "critical" | "high" | "medium" | "low" | "info";
|
|
14
|
+
group_by?: "file" | "rule";
|
|
15
|
+
}>>;
|
|
16
|
+
export declare const TerraformValidateParams: import("arktype/internal/variants/object.ts").ObjectType<{
|
|
17
|
+
paths?: string[];
|
|
18
|
+
}, {}>;
|
|
19
|
+
export declare function TerraformValidateTool(ctx: LocalToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<{
|
|
20
|
+
paths?: string[];
|
|
21
|
+
}, {
|
|
22
|
+
paths?: string[];
|
|
23
|
+
}>>;
|
|
24
|
+
export declare const TerraformVerifyRemediationParams: import("arktype/internal/variants/object.ts").ObjectType<{
|
|
25
|
+
concern_ids: string[];
|
|
26
|
+
}, {}>;
|
|
27
|
+
export declare function TerraformVerifyRemediationTool(ctx: LocalToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<{
|
|
28
|
+
concern_ids: string[];
|
|
29
|
+
}, {
|
|
30
|
+
concern_ids: string[];
|
|
31
|
+
}>>;
|
|
32
|
+
export declare const InfracostDiffParams: import("arktype/internal/variants/object.ts").ObjectType<object, {}>;
|
|
33
|
+
export declare function InfracostDiffTool(ctx: LocalToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<object, object>>;
|
|
34
|
+
export declare const TerraformEmitSarifParams: import("arktype/internal/variants/object.ts").ObjectType<{
|
|
35
|
+
output_path?: string;
|
|
36
|
+
severity_threshold?: "critical" | "high" | "medium" | "low" | "info";
|
|
37
|
+
}, {}>;
|
|
38
|
+
export declare function TerraformEmitSarifTool(ctx: LocalToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<{
|
|
39
|
+
output_path?: string;
|
|
40
|
+
severity_threshold?: "critical" | "high" | "medium" | "low" | "info";
|
|
41
|
+
}, {
|
|
42
|
+
output_path?: string;
|
|
43
|
+
severity_threshold?: "critical" | "high" | "medium" | "low" | "info";
|
|
44
|
+
}>>;
|
|
45
|
+
export declare function collectCloudCredentials(): Record<string, string>;
|
|
46
|
+
export declare const TerraformPlanParams: import("arktype/internal/variants/object.ts").ObjectType<object, {}>;
|
|
47
|
+
export declare function TerraformPlanTool(ctx: LocalToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<object, object>>;
|
|
48
|
+
export declare const ReadFindingsParams: import("arktype/internal/variants/object.ts").ObjectType<{
|
|
49
|
+
path?: string;
|
|
50
|
+
severity_threshold?: "critical" | "high" | "medium" | "low" | "info";
|
|
51
|
+
group_by?: "file" | "rule";
|
|
52
|
+
}, {}>;
|
|
53
|
+
export declare function ReadFindingsTool(ctx: LocalToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<{
|
|
54
|
+
path?: string;
|
|
55
|
+
severity_threshold?: "critical" | "high" | "medium" | "low" | "info";
|
|
56
|
+
group_by?: "file" | "rule";
|
|
57
|
+
}, {
|
|
58
|
+
path?: string;
|
|
59
|
+
severity_threshold?: "critical" | "high" | "medium" | "low" | "info";
|
|
60
|
+
group_by?: "file" | "rule";
|
|
61
|
+
}>>;
|
|
62
|
+
export declare const TerraformVersionCurrencyParams: import("arktype/internal/variants/object.ts").ObjectType<object, {}>;
|
|
63
|
+
export declare function TerraformVersionCurrencyTool(ctx: LocalToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<object, object>>;
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A degrade-green skip result carrying the structured §3.5 envelope
|
|
3
|
+
* (`ok: false` + machine `code` + human `detail`) PLUS the legacy alias the tool
|
|
4
|
+
* returned before it converged on the envelope — `ran`/`found` and
|
|
5
|
+
* `skipped_reason`/`reason` — so existing prompt + test contracts keep working.
|
|
6
|
+
* Additive, never breaking. `extra` folds in any tool-specific fields (e.g.
|
|
7
|
+
* read_findings' empty `concerns`/`groups`).
|
|
8
|
+
*/
|
|
9
|
+
export declare function skipResult(code: string, detail: string, opts?: {
|
|
10
|
+
key?: "ran" | "found";
|
|
11
|
+
reasonKey?: "skipped_reason" | "reason";
|
|
12
|
+
extra?: Record<string, any>;
|
|
13
|
+
}): Record<string, any>;
|
|
14
|
+
/**
|
|
15
|
+
* Internal "concern" model — the Remediator's ground truth for "what is not
|
|
16
|
+
* best practice". Produced by `terraform_scan` from the fork's own deterministic
|
|
17
|
+
* Terraform check tools (fmt / validate / tflint / trivy / checkov).
|
|
18
|
+
*
|
|
19
|
+
* This is a deliberate SUBSET of the reviewer's `findings.schema.json` v1.0
|
|
20
|
+
* (../terraform-reviewer/schemas/findings.schema.json). The reviewer's findings
|
|
21
|
+
* add `lens` / `standard` / `control_id` / `state` on top. Keeping the shape a
|
|
22
|
+
* subset means a future reviewer integration (read_findings) can emit the same
|
|
23
|
+
* Concern[] with no change to the modes or the rest of the tools — only the
|
|
24
|
+
* SOURCE of concerns swaps.
|
|
25
|
+
*/
|
|
26
|
+
export interface Concern {
|
|
27
|
+
/** stable content id: sha1(source|rule_id|file|line). idempotency key for branch/PR naming. */
|
|
28
|
+
id: string;
|
|
29
|
+
/** producing tool. `reviewer` marks a concern loaded from a terraform-reviewer
|
|
30
|
+
* findings.json whose original tool isn't one Terramend re-runs (tfsec / infracost
|
|
31
|
+
* / llm) — its provenance lives in `rule_id`. */
|
|
32
|
+
source: "terraform-fmt" | "terraform-validate" | "tflint" | "trivy" | "checkov" | "reviewer";
|
|
33
|
+
/** original namespaced rule, e.g. "trivy:AVD-AWS-0088" */
|
|
34
|
+
rule_id: string;
|
|
35
|
+
severity: Severity;
|
|
36
|
+
category: "security" | "style" | "correctness" | "cost";
|
|
37
|
+
/** the scanner message — what is wrong */
|
|
38
|
+
evidence: string;
|
|
39
|
+
location: {
|
|
40
|
+
file: string;
|
|
41
|
+
line: number | null;
|
|
42
|
+
};
|
|
43
|
+
remediation_hint: string | null;
|
|
44
|
+
}
|
|
45
|
+
export declare const SEVERITIES: readonly ["critical", "high", "medium", "low", "info"];
|
|
46
|
+
export type Severity = (typeof SEVERITIES)[number];
|
|
47
|
+
export declare const SEVERITY_RANK: Record<Severity, number>;
|
|
48
|
+
export declare function concernId(source: string, ruleId: string, file: string, line: number | null): string;
|
|
49
|
+
/**
|
|
50
|
+
* Normalize a scanner-reported path to a repo-relative POSIX path. Each scanner
|
|
51
|
+
* reports the file differently — tflint gives `main.tf` (relative), trivy a
|
|
52
|
+
* scan-dir-relative `Target`, terraform an absolute path (`/repo/main.tf` or
|
|
53
|
+
* `D:\repo\main.tf`), checkov a leading-slash path (`/main.tf`). Left
|
|
54
|
+
* unnormalized, these leak into `location.file` AND the
|
|
55
|
+
* content-derived `concernId`, making the id (and the `remediate/<id>` branch)
|
|
56
|
+
* machine-dependent and breaking the ✗→✓ re-scan id match across environments.
|
|
57
|
+
* So normalize BEFORE building any Concern.
|
|
58
|
+
*/
|
|
59
|
+
export declare function toRepoRelative(raw: string | undefined, cwd: string): string;
|
|
60
|
+
export type RunResult = {
|
|
61
|
+
status: number;
|
|
62
|
+
stdout: string;
|
|
63
|
+
stderr: string;
|
|
64
|
+
missing: boolean;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Hard wall-clock cap on any single scanner/terraform invocation. Bounds a hung
|
|
68
|
+
* subprocess (e.g. `terraform init`/`plan` stalling on a private registry, a
|
|
69
|
+
* tflint plugin fetch that never returns) so it can't block the run forever.
|
|
70
|
+
* Generous (5 min) so it only ever fires on a genuine hang, never a slow-but-
|
|
71
|
+
* progressing plan. A timeout surfaces as a non-zero/`-1` status the caller
|
|
72
|
+
* already treats as "this scanner did not produce results".
|
|
73
|
+
*/
|
|
74
|
+
export declare const SUBPROCESS_TIMEOUT_MS = 300000;
|
|
75
|
+
/**
|
|
76
|
+
* Run a scanner without throwing. Terraform tools exit non-zero when they FIND
|
|
77
|
+
* issues, so a non-zero status is normal, not an error. `missing` is set when
|
|
78
|
+
* the binary isn't on PATH (ENOENT) — the scanner then degrades to "skipped"
|
|
79
|
+
* rather than failing the run (plan §9.2: a tool being absent must not block).
|
|
80
|
+
*
|
|
81
|
+
* `extraEnv` opts a specific command back into a needed credential: the scanners
|
|
82
|
+
* run with a restricted env that strips every `*_KEY`/secret, but infracost
|
|
83
|
+
* legitimately needs its `INFRACOST_API_KEY`. resolveEnv(object) merges the
|
|
84
|
+
* restricted base with the explicit vars, so only the named keys get through.
|
|
85
|
+
*/
|
|
86
|
+
export declare function run(cmd: string, args: string[], cwd: string, extraEnv?: Record<string, string>): RunResult;
|
|
87
|
+
export type ScannerOutcome = {
|
|
88
|
+
source: Concern["source"];
|
|
89
|
+
ran: boolean;
|
|
90
|
+
skipped_reason?: string;
|
|
91
|
+
concerns: Concern[];
|
|
92
|
+
/**
|
|
93
|
+
* For `terraform validate` only: count of roots where terraform RAN but its
|
|
94
|
+
* `-json` output could not be parsed (a real CLI-level failure, not a missing
|
|
95
|
+
* binary). Lets the validate tool report `passed` as fail-closed instead of
|
|
96
|
+
* silently treating an un-validated root as clean. Undefined/0 elsewhere.
|
|
97
|
+
*/
|
|
98
|
+
unvalidated?: number;
|
|
99
|
+
};
|
|
100
|
+
export declare function skipped(source: Concern["source"], reason: string): ScannerOutcome;
|
|
101
|
+
export interface ResolvedRoot {
|
|
102
|
+
/** absolute dir the per-root command (init/plan/validate) runs in. */
|
|
103
|
+
absDir: string;
|
|
104
|
+
/** that root's path relative to the scan `cwd` ("" when the root IS cwd) —
|
|
105
|
+
* prepended to per-root concern files so they stay cwd-relative. */
|
|
106
|
+
relDir: string;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* The Terraform root modules to operate on under `cwd`. A repo can hold several
|
|
110
|
+
* roots (hepcare: `terraform/` + `terraform/core/`); `terraform validate` /
|
|
111
|
+
* `plan` are per-root, so they must run in EACH. Falls back to `cwd` itself as a
|
|
112
|
+
* single root when none is detected — so a normal single-root repo behaves
|
|
113
|
+
* exactly as before (no rebasing, one iteration).
|
|
114
|
+
*/
|
|
115
|
+
export declare function resolveRoots(cwd: string): ResolvedRoot[];
|
|
116
|
+
/**
|
|
117
|
+
* Re-base a concern produced by a per-root command (its file is relative to the
|
|
118
|
+
* root dir) onto the scan `cwd` by prefixing the root's `relDir`, and recompute
|
|
119
|
+
* the content id so it stays consistent with the cwd-relative scanners (✗→✓).
|
|
120
|
+
* A no-op when `relDir` is "" (the root IS cwd).
|
|
121
|
+
*/
|
|
122
|
+
export declare function rebaseConcern(c: Concern, relDir: string): Concern;
|
|
123
|
+
/** true when a path is a Terraform source file Terramend may remediate. */
|
|
124
|
+
export declare function isTerraformFile(file: string): boolean;
|
|
125
|
+
/**
|
|
126
|
+
* Terramend is Terraform-only. A concern in a non-`.tf`/`.tfvars` file can never
|
|
127
|
+
* be remediated (the `allowed_paths` push guardrail blocks it) and is pure noise,
|
|
128
|
+
* so any scanner that also inspects other IaC — checkov's github_actions, trivy's
|
|
129
|
+
* dockerfile/kubernetes — gets filtered down to Terraform here. This is the
|
|
130
|
+
* catch-all backstop; `scanCheckov` also scopes itself with `--framework terraform`.
|
|
131
|
+
*/
|
|
132
|
+
export declare function isTerraformConcern(c: Concern): boolean;
|
|
133
|
+
export declare function dedupe(concerns: Concern[]): Concern[];
|
|
134
|
+
export declare function sortConcerns(concerns: Concern[]): Concern[];
|
|
135
|
+
export declare function lowerSeverity(s: string | undefined): Severity;
|
|
136
|
+
/** the repo's base ref for diff-scope, or null when one can't be determined. */
|
|
137
|
+
export declare function resolveBaseRef(cwd: string): string | null;
|
|
138
|
+
/**
|
|
139
|
+
* A scoped unit of work = all concerns in one file. Different scanners flag the
|
|
140
|
+
* same underlying defect under different rule ids (trivy ∩ checkov overlap
|
|
141
|
+
* heavily on e.g. S3 buckets), so per-concern PRs would spam many PRs for one
|
|
142
|
+
* bad file. Remediate acts on ONE group per PR (branch `remediate/<group.id>`),
|
|
143
|
+
* fixing every concern in the file together and proving them all cleared (✗→✓).
|
|
144
|
+
*/
|
|
145
|
+
export interface ConcernGroup {
|
|
146
|
+
/** stable id — the remediation branch/PR key (`remediate/<id>`). Derived from
|
|
147
|
+
* the file (by-file grouping) or the rule (by-rule grouping). */
|
|
148
|
+
id: string;
|
|
149
|
+
/** the group's primary file (by-file) or a human label like "3 files"
|
|
150
|
+
* (by-rule); `files` carries the full list for by-rule groups. */
|
|
151
|
+
file: string;
|
|
152
|
+
/** §3.11 — every file the group spans. one entry for a by-file group; the
|
|
153
|
+
* full set for a by-rule group (the agent must fix the rule in all of them). */
|
|
154
|
+
files?: string[];
|
|
155
|
+
/** how the group was formed — `file` (default) or `rule` (§3.11). */
|
|
156
|
+
grouping?: "file" | "rule";
|
|
157
|
+
/** highest severity among the group's concerns. */
|
|
158
|
+
severity: Severity;
|
|
159
|
+
concern_count: number;
|
|
160
|
+
/** distinct rule ids in the group, for the PR body. */
|
|
161
|
+
rule_ids: string[];
|
|
162
|
+
/** the concern ids the re-scan must confirm are gone to call this ✓. */
|
|
163
|
+
concern_ids: string[];
|
|
164
|
+
/** §3.9 — `auto` (open a normal PR) or `needs-human` (escalate). attached by
|
|
165
|
+
* the scan tool from the group's concerns, not by `groupConcerns` (which has
|
|
166
|
+
* no autonomy threshold). undefined until the scan tool annotates it. */
|
|
167
|
+
autonomy?: Autonomy;
|
|
168
|
+
/** §3.9 — why the group was escalated (empty/absent for `auto`). */
|
|
169
|
+
autonomy_reasons?: string[];
|
|
170
|
+
}
|
|
171
|
+
export type Autonomy = "auto" | "needs-human";
|
|
172
|
+
export type BlastTier = "low" | "medium" | "high";
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Facade for the Terraform MCP toolchain. The implementation lives in the
|
|
3
|
+
* per-concern modules under `./terraform/`; this file re-exports every symbol so
|
|
4
|
+
* existing importers (`#app/mcp/terraform`) keep resolving unchanged.
|
|
5
|
+
*
|
|
6
|
+
* types — Concern + shared types/helpers (ids, paths, roots, severity)
|
|
7
|
+
* scanners — fmt / validate / tflint / trivy / checkov + provider/arg schema
|
|
8
|
+
* decisions — grouping, autonomy, confidence, refusal, prevention, co-location
|
|
9
|
+
* cost — infracost breakdown / delta / escalation
|
|
10
|
+
* currency — registry version currency (provider + module upgrade intel)
|
|
11
|
+
* findings — reviewer findings + SARIF ingest/emit
|
|
12
|
+
* plan — plan parsing + destroy/blast/stability/aggregation
|
|
13
|
+
* tools — the MCP Tool factories + their *Params schemas
|
|
14
|
+
*/
|
|
15
|
+
export * from "#app/mcp/terraform/cost";
|
|
16
|
+
export * from "#app/mcp/terraform/currency";
|
|
17
|
+
export * from "#app/mcp/terraform/decisions";
|
|
18
|
+
export * from "#app/mcp/terraform/findings";
|
|
19
|
+
export * from "#app/mcp/terraform/plan";
|
|
20
|
+
export * from "#app/mcp/terraform/scanners";
|
|
21
|
+
export * from "#app/mcp/terraform/tools";
|
|
22
|
+
export * from "#app/mcp/terraform/types";
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { ToolContext } from "#app/mcp/server";
|
|
2
|
+
/**
|
|
3
|
+
* §28 Terratest scaffolding (opt-in via the `terratest` input). When Terramend
|
|
4
|
+
* GENERATES a reusable module, it can also scaffold a minimal Go
|
|
5
|
+
* [Terratest](https://terratest.gruntwork.io/) smoke test + a Terraform-native
|
|
6
|
+
* `*.tftest.hcl` so the generated infrastructure is testable from the first
|
|
7
|
+
* commit. Both tests plan the module **directly** — Terramend does not generate
|
|
8
|
+
* `examples/` fixtures.
|
|
9
|
+
*
|
|
10
|
+
* Design choices:
|
|
11
|
+
* - **Plan-only, never apply.** The scaffolded tests run `terraform init` +
|
|
12
|
+
* `plan` against the module and assert it plans cleanly. Terramend never
|
|
13
|
+
* applies (no cloud credentials — the sovereignty stance), so the generated
|
|
14
|
+
* tests mirror that: they're a deployability smoke test the USER runs in their
|
|
15
|
+
* own pipeline (with creds) for real apply/assert coverage.
|
|
16
|
+
* - **Pure generation.** The file contents are computed deterministically here
|
|
17
|
+
* and unit-tested; the agent writes the returned files with its own tools.
|
|
18
|
+
* - The Go test + native test files fall outside the Terraform-only default
|
|
19
|
+
* allow-list, so the `terratest` input also widens the push guardrail (see
|
|
20
|
+
* guardrails.ts).
|
|
21
|
+
*/
|
|
22
|
+
export interface ScaffoldFile {
|
|
23
|
+
/** repo-relative path to write. */
|
|
24
|
+
path: string;
|
|
25
|
+
content: string;
|
|
26
|
+
}
|
|
27
|
+
export interface TerratestScaffold {
|
|
28
|
+
files: ScaffoldFile[];
|
|
29
|
+
notes: string[];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Build a Terratest smoke-test + native test for a generated module. Pure:
|
|
33
|
+
* `moduleName` names the module, `modulePath` is its repo-relative dir, and
|
|
34
|
+
* `variables` (optional) are surfaced as TODO placeholders so the test author
|
|
35
|
+
* fills in real values. Both tests plan the module directly (no `examples/`
|
|
36
|
+
* fixture). Returns the files to write + operator notes.
|
|
37
|
+
*/
|
|
38
|
+
export declare function scaffoldTerratest(opts: {
|
|
39
|
+
moduleName: string;
|
|
40
|
+
modulePath: string;
|
|
41
|
+
variables?: {
|
|
42
|
+
name: string;
|
|
43
|
+
required?: boolean;
|
|
44
|
+
}[];
|
|
45
|
+
}): TerratestScaffold;
|
|
46
|
+
/**
|
|
47
|
+
* §28 (native variant) — scaffold a Terraform-native test (Terraform 1.6+) that
|
|
48
|
+
* lives in the module's own `tests/` dir and plans the module in place. Lighter
|
|
49
|
+
* than Terratest: no Go toolchain, just HCL that Terraform runs with
|
|
50
|
+
* `terraform test`. Plan-only `run` block (no apply, so no cloud needed to
|
|
51
|
+
* construct the test). Pure.
|
|
52
|
+
*/
|
|
53
|
+
export declare function scaffoldTerraformTest(opts: {
|
|
54
|
+
moduleName: string;
|
|
55
|
+
modulePath: string;
|
|
56
|
+
variables?: {
|
|
57
|
+
name: string;
|
|
58
|
+
required?: boolean;
|
|
59
|
+
}[];
|
|
60
|
+
}): ScaffoldFile;
|
|
61
|
+
export declare const ScaffoldTerratestParams: import("arktype/internal/variants/object.ts").ObjectType<{
|
|
62
|
+
module_name: string;
|
|
63
|
+
module_path: string;
|
|
64
|
+
variables?: {
|
|
65
|
+
name: string;
|
|
66
|
+
required?: boolean;
|
|
67
|
+
}[];
|
|
68
|
+
}, {}>;
|
|
69
|
+
export declare function ScaffoldTerratestTool(ctx: ToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<{
|
|
70
|
+
module_name: string;
|
|
71
|
+
module_path: string;
|
|
72
|
+
variables?: {
|
|
73
|
+
name: string;
|
|
74
|
+
required?: boolean;
|
|
75
|
+
}[];
|
|
76
|
+
}, {
|
|
77
|
+
module_name: string;
|
|
78
|
+
module_path: string;
|
|
79
|
+
variables?: {
|
|
80
|
+
name: string;
|
|
81
|
+
required?: boolean;
|
|
82
|
+
}[];
|
|
83
|
+
}>>;
|
package/dist/models.d.ts
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* model alias registry.
|
|
3
|
+
*
|
|
4
|
+
* slugs use the format `provider/model-id` (e.g. "anthropic/claude-opus").
|
|
5
|
+
* bump `resolve` when a new model generation ships — the alias (slug) stays stable.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* routing discriminant for entries whose `resolve` is dynamic — looked up
|
|
9
|
+
* from a separate env var at run time rather than fixed in the catalog.
|
|
10
|
+
*
|
|
11
|
+
* `"bedrock"` means the actual model ID comes from `BEDROCK_MODEL_ID`
|
|
12
|
+
* (an AWS-canonical Bedrock model ID like `eu.anthropic.claude-opus-4-7`
|
|
13
|
+
* or `amazon.nova-pro-v1:0`). `"vertex"` means the actual model ID comes
|
|
14
|
+
* from `VERTEX_MODEL_ID` (a Vertex AI model ID like
|
|
15
|
+
* `claude-opus-4-1@20250805` or `gemini-2.5-pro`). enterprise hosted-model
|
|
16
|
+
* customers self-select for version control — silent alias bumps would break
|
|
17
|
+
* compliance review, model-access enrollment, and provisioned-throughput
|
|
18
|
+
* contracts. so the single `bedrock/byok` and `vertex/byok` entries are
|
|
19
|
+
* routing slugs, not model aliases: the harness reads the backend-specific
|
|
20
|
+
* env var and routes to claude-code for Anthropic IDs or opencode for
|
|
21
|
+
* everything else.
|
|
22
|
+
*/
|
|
23
|
+
export type ModelRouting = "bedrock" | "vertex";
|
|
24
|
+
export interface ModelAlias {
|
|
25
|
+
/** stable alias stored in DB, e.g. "anthropic/claude-opus" */
|
|
26
|
+
slug: string;
|
|
27
|
+
/** provider key (matches providers keys) */
|
|
28
|
+
provider: string;
|
|
29
|
+
/** human-readable name shown in dropdowns */
|
|
30
|
+
displayName: string;
|
|
31
|
+
/** concrete models.dev specifier, e.g. "anthropic/claude-opus-4-6". sentinel for routing entries — never passed to a CLI directly. */
|
|
32
|
+
resolve: string;
|
|
33
|
+
/** full models.dev specifier for the OpenRouter equivalent (undefined for free models and routing entries) */
|
|
34
|
+
openRouterResolve: string | undefined;
|
|
35
|
+
/** top-tier pick for this provider — preferred during auto-select */
|
|
36
|
+
preferred: boolean;
|
|
37
|
+
/** whether this alias is free and requires no API key */
|
|
38
|
+
isFree: boolean;
|
|
39
|
+
/** slug of a replacement model — presence implies this model is deprecated */
|
|
40
|
+
fallback: string | undefined;
|
|
41
|
+
/** dynamic-resolution discriminant — see ModelRouting docs */
|
|
42
|
+
routing: ModelRouting | undefined;
|
|
43
|
+
/** alias key (within same provider) of the cheaper sibling reviewfrog should
|
|
44
|
+
* use as its lens-fanout subagent. e.g. claude-opus → "claude-sonnet". */
|
|
45
|
+
subagentModel: string | undefined;
|
|
46
|
+
/** hide from selectable lists (UI dropdowns, CLI pickers). does NOT affect
|
|
47
|
+
* resolution — for that use `fallback`. used for internal-only tier targets
|
|
48
|
+
* (e.g. gpt-5.4 as a subagent target without exposing it to users). */
|
|
49
|
+
hidden: boolean;
|
|
50
|
+
}
|
|
51
|
+
interface ModelDef {
|
|
52
|
+
displayName: string;
|
|
53
|
+
/** concrete models.dev specifier, e.g. "anthropic/claude-opus-4-6" */
|
|
54
|
+
resolve: string;
|
|
55
|
+
/** full models.dev specifier for the OpenRouter equivalent, e.g. "openrouter/anthropic/claude-opus-4.6" */
|
|
56
|
+
openRouterResolve?: string;
|
|
57
|
+
preferred?: boolean;
|
|
58
|
+
envVars?: readonly string[];
|
|
59
|
+
isFree?: boolean;
|
|
60
|
+
/** slug of a replacement model — presence implies this model is deprecated */
|
|
61
|
+
fallback?: string;
|
|
62
|
+
/** dynamic-resolution discriminant — see ModelRouting docs */
|
|
63
|
+
routing?: ModelRouting;
|
|
64
|
+
/** alias key (within same provider) of the cheaper sibling reviewfrog should
|
|
65
|
+
* use as its lens-fanout subagent (e.g. claude-opus → "claude-sonnet"). */
|
|
66
|
+
subagentModel?: string;
|
|
67
|
+
/** hide from selectable lists. does NOT affect resolution; for that use `fallback`. */
|
|
68
|
+
hidden?: boolean;
|
|
69
|
+
}
|
|
70
|
+
export interface ProviderConfig {
|
|
71
|
+
displayName: string;
|
|
72
|
+
envVars: readonly string[];
|
|
73
|
+
/** credentials authored only via `terramend auth <provider>` — never
|
|
74
|
+
* user-facing in `init`, never documented as a manual GHA secret. counted
|
|
75
|
+
* for hasAnyKey / log-redaction purposes but excluded from any prompt /
|
|
76
|
+
* paste flow. CLI-managed magic. see wiki/codex-auth.md. */
|
|
77
|
+
managedCredentials?: readonly string[];
|
|
78
|
+
models: Record<string, ModelDef>;
|
|
79
|
+
}
|
|
80
|
+
export declare const providers: {
|
|
81
|
+
anthropic: ProviderConfig;
|
|
82
|
+
openai: ProviderConfig;
|
|
83
|
+
google: ProviderConfig;
|
|
84
|
+
xai: ProviderConfig;
|
|
85
|
+
deepseek: ProviderConfig;
|
|
86
|
+
moonshotai: ProviderConfig;
|
|
87
|
+
opencode: ProviderConfig;
|
|
88
|
+
bedrock: ProviderConfig;
|
|
89
|
+
vertex: ProviderConfig;
|
|
90
|
+
openrouter: ProviderConfig;
|
|
91
|
+
};
|
|
92
|
+
export type ModelProvider = keyof typeof providers;
|
|
93
|
+
export declare function parseModel(slug: string): {
|
|
94
|
+
provider: string;
|
|
95
|
+
model: string;
|
|
96
|
+
};
|
|
97
|
+
export declare function getModelProvider(slug: string): string;
|
|
98
|
+
export declare function getProviderDisplayName(slug: string): string | undefined;
|
|
99
|
+
export declare function getModelEnvVars(slug: string): string[];
|
|
100
|
+
/** managed credentials are authored only via `terramend auth <provider>` — they
|
|
101
|
+
* count as "configured" for hasAnyKey-style UI checks but are never offered as
|
|
102
|
+
* a manual-paste option in `init` or the AgentSettings env-var button row.
|
|
103
|
+
* see `provider.managedCredentials` and wiki/codex-auth.md. */
|
|
104
|
+
export declare function getModelManagedCredentials(slug: string): string[];
|
|
105
|
+
export declare const modelAliases: ModelAlias[];
|
|
106
|
+
export declare const DEFAULT_PROXY_MODEL: string;
|
|
107
|
+
/** short label for the model auto-select picks today (console hint copy). */
|
|
108
|
+
export declare function getAutoSelectHintModel(): string;
|
|
109
|
+
/** resolve a model slug to its concrete models.dev specifier (e.g. "anthropic/claude-opus-4-6") */
|
|
110
|
+
export declare function resolveModelSlug(slug: string): string | undefined;
|
|
111
|
+
/**
|
|
112
|
+
* walk the fallback chain to the terminal (non-deprecated) alias.
|
|
113
|
+
* returns undefined if the chain is broken, exhausted, or cyclic.
|
|
114
|
+
*
|
|
115
|
+
* use this in UI display sites (dropdown trigger labels, PR-comment footers,
|
|
116
|
+
* etc.) so a deprecated stored slug renders as the model the user actually
|
|
117
|
+
* runs against — not the historical name. selectable lists should still hide
|
|
118
|
+
* deprecated and internal-only aliases by filtering on `!a.fallback && !a.hidden`.
|
|
119
|
+
*/
|
|
120
|
+
export declare function resolveDisplayAlias(slug: string): ModelAlias | undefined;
|
|
121
|
+
/**
|
|
122
|
+
* resolve a model slug to the CLI-ready model string, following the fallback
|
|
123
|
+
* chain when a model is deprecated. returns the first non-deprecated resolve
|
|
124
|
+
* target, or undefined if the chain is exhausted or broken.
|
|
125
|
+
*/
|
|
126
|
+
export declare function resolveCliModel(slug: string): string | undefined;
|
|
127
|
+
/**
|
|
128
|
+
* resolve a model slug to the OpenRouter-ready model string, following the
|
|
129
|
+
* fallback chain when a model is deprecated. returns undefined if the chain
|
|
130
|
+
* is exhausted/broken or the terminal alias has no openrouter equivalent
|
|
131
|
+
* (e.g. free opencode models).
|
|
132
|
+
*/
|
|
133
|
+
export declare function resolveOpenRouterModel(slug: string): string | undefined;
|
|
134
|
+
/** env var that supplies the Bedrock model ID for the `bedrock/byok` slug. */
|
|
135
|
+
export declare const BEDROCK_MODEL_ID_ENV = "BEDROCK_MODEL_ID";
|
|
136
|
+
/** env var that supplies the Vertex AI model ID for the `vertex/byok` slug. */
|
|
137
|
+
export declare const VERTEX_MODEL_ID_ENV = "VERTEX_MODEL_ID";
|
|
138
|
+
/**
|
|
139
|
+
* the Bedrock model ID passed to claude-code or opencode is whatever the
|
|
140
|
+
* user set in `BEDROCK_MODEL_ID` — Terramend never resolves or upgrades it.
|
|
141
|
+
* we route by checking whether the ID names an Anthropic model: claude-code
|
|
142
|
+
* handles Anthropic-on-Bedrock natively (with `CLAUDE_CODE_USE_BEDROCK=1`),
|
|
143
|
+
* everything else goes through opencode's `amazon-bedrock` provider.
|
|
144
|
+
*
|
|
145
|
+
* AWS Bedrock IDs come in two shapes:
|
|
146
|
+
* - dotted foundation IDs: `eu.anthropic.claude-opus-4-7`,
|
|
147
|
+
* `anthropic.claude-haiku-4-5-20251001-v1:0`, `amazon.nova-pro-v1:0`,
|
|
148
|
+
* `meta.llama4-scout-17b-instruct-v1:0`. AWS-published, lowercase, the
|
|
149
|
+
* foundation provider always appears as a discrete dot-segment.
|
|
150
|
+
* - inference-profile ARNs: `arn:aws:bedrock:eu-west-2:<acct>:application-inference-profile/<user-name>`.
|
|
151
|
+
* `<user-name>` is operator-chosen, so a naive substring check is fragile
|
|
152
|
+
* in both directions (Anthropic profile named without "anthropic" → routes
|
|
153
|
+
* to opencode and misses CLAUDE_CODE_USE_BEDROCK; non-Anthropic profile
|
|
154
|
+
* whose name happens to contain "anthropic" → routes to claude-code).
|
|
155
|
+
*
|
|
156
|
+
* we anchor on a discrete dot-segment match (case-insensitive). this catches
|
|
157
|
+
* every published foundation ID and is conservative for ARN-form IDs: ARN
|
|
158
|
+
* names that don't include "anthropic" as their own dot-segment route to
|
|
159
|
+
* opencode by default. operators using ARN-form IDs whose backing model is
|
|
160
|
+
* Anthropic should set `TERRAMEND_AGENT=claude` to force the right route, or
|
|
161
|
+
* include the foundation segment in the profile name.
|
|
162
|
+
*/
|
|
163
|
+
export declare function isBedrockAnthropicId(bedrockModelId: string): boolean;
|
|
164
|
+
/**
|
|
165
|
+
* Vertex Anthropic model IDs start with the Claude family name, e.g.
|
|
166
|
+
* `claude-opus-4-1@20250805`. partner-model resource paths can contain the
|
|
167
|
+
* substring "anthropic" elsewhere, so the Bedrock segment check does not
|
|
168
|
+
* transfer — anchor on the model ID prefix instead.
|
|
169
|
+
*/
|
|
170
|
+
export declare function isVertexAnthropicId(vertexModelId: string): boolean;
|
|
171
|
+
export {};
|