infraweaver 0.1.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 +244 -0
- package/dist/agents/claude.d.ts +113 -0
- package/dist/agents/claudePretoolGate.d.ts +137 -0
- package/dist/agents/dispatchMetrics.d.ts +77 -0
- package/dist/agents/gateServer.d.ts +7 -0
- package/dist/agents/index.d.ts +6 -0
- package/dist/agents/nativeFsDenies.d.ts +46 -0
- package/dist/agents/opencode.d.ts +284 -0
- package/dist/agents/opencodePlugin.d.ts +96 -0
- package/dist/agents/opencodeShared.d.ts +40 -0
- package/dist/agents/postRun.d.ts +126 -0
- package/dist/agents/reviewer.d.ts +41 -0
- package/dist/agents/sessionLabeler.d.ts +97 -0
- package/dist/agents/shared.d.ts +246 -0
- package/dist/agents/subagentModels.d.ts +19 -0
- package/dist/agents/tokenQuota.d.ts +118 -0
- package/dist/agents/writeGateSource.d.ts +22 -0
- package/dist/agents/writePolicy.d.ts +79 -0
- package/dist/brand.d.ts +67 -0
- package/dist/cli.mjs +247846 -0
- package/dist/external.d.ts +227 -0
- package/dist/i18n/scaffolding.d.ts +59 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +247061 -0
- package/dist/internal/index.d.ts +18 -0
- package/dist/internal.js +2398 -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/assess.d.ts +157 -0
- package/dist/mcp/capabilityContext.d.ts +71 -0
- package/dist/mcp/changeSummary.d.ts +52 -0
- package/dist/mcp/checkSuite.d.ts +27 -0
- package/dist/mcp/checkout.d.ts +92 -0
- package/dist/mcp/comment.d.ts +127 -0
- package/dist/mcp/commitInfo.d.ts +11 -0
- package/dist/mcp/crosswalk.d.ts +178 -0
- package/dist/mcp/crosswalkDigest.d.ts +1 -0
- package/dist/mcp/cyberEssentials.d.ts +24 -0
- package/dist/mcp/dashboard.d.ts +125 -0
- package/dist/mcp/dependencies.d.ts +12 -0
- package/dist/mcp/frameworks.d.ts +74 -0
- package/dist/mcp/geminiSanitizer.d.ts +28 -0
- package/dist/mcp/git.d.ts +60 -0
- package/dist/mcp/guardrails.d.ts +222 -0
- package/dist/mcp/issue.d.ts +20 -0
- package/dist/mcp/issueComments.d.ts +11 -0
- package/dist/mcp/issueEvents.d.ts +11 -0
- package/dist/mcp/issueInfo.d.ts +11 -0
- package/dist/mcp/labels.d.ts +14 -0
- package/dist/mcp/localContext.d.ts +26 -0
- package/dist/mcp/moduleExtraction.d.ts +79 -0
- package/dist/mcp/moduleTests.d.ts +106 -0
- package/dist/mcp/modules.d.ts +198 -0
- package/dist/mcp/output.d.ts +16 -0
- package/dist/mcp/pathSafety.d.ts +14 -0
- package/dist/mcp/policy.d.ts +50 -0
- package/dist/mcp/pr.d.ts +64 -0
- package/dist/mcp/prInfo.d.ts +11 -0
- package/dist/mcp/providerSchema.d.ts +52 -0
- package/dist/mcp/review.d.ts +212 -0
- package/dist/mcp/reviewComments.d.ts +245 -0
- package/dist/mcp/roots.d.ts +60 -0
- package/dist/mcp/scope.d.ts +26 -0
- package/dist/mcp/selectMode.d.ts +20 -0
- package/dist/mcp/server.d.ts +61 -0
- package/dist/mcp/shared.d.ts +62 -0
- package/dist/mcp/shell.d.ts +58 -0
- package/dist/mcp/staleFix.d.ts +138 -0
- package/dist/mcp/terraform/azurePrices.d.ts +8 -0
- package/dist/mcp/terraform/baseline.d.ts +57 -0
- package/dist/mcp/terraform/concernResult.d.ts +38 -0
- package/dist/mcp/terraform/cost.d.ts +55 -0
- package/dist/mcp/terraform/cspm.d.ts +80 -0
- package/dist/mcp/terraform/currency.d.ts +110 -0
- package/dist/mcp/terraform/decisions.d.ts +178 -0
- package/dist/mcp/terraform/eidas.d.ts +100 -0
- package/dist/mcp/terraform/evidence.d.ts +343 -0
- package/dist/mcp/terraform/findings.d.ts +76 -0
- package/dist/mcp/terraform/fixMemory.d.ts +81 -0
- package/dist/mcp/terraform/governance.d.ts +56 -0
- package/dist/mcp/terraform/hcl.d.ts +115 -0
- package/dist/mcp/terraform/iacLanguages.d.ts +120 -0
- package/dist/mcp/terraform/idleFloor.d.ts +78 -0
- package/dist/mcp/terraform/keyless.d.ts +68 -0
- package/dist/mcp/terraform/moduleDocs.d.ts +56 -0
- package/dist/mcp/terraform/nativeRules.d.ts +38 -0
- package/dist/mcp/terraform/nativeScan.d.ts +11 -0
- package/dist/mcp/terraform/noiseProfile.d.ts +100 -0
- package/dist/mcp/terraform/normalization.d.ts +52 -0
- package/dist/mcp/terraform/oscal.d.ts +103 -0
- package/dist/mcp/terraform/packs/azurerm-3-4.d.ts +2 -0
- package/dist/mcp/terraform/packs/cloudflare-4-5.d.ts +2 -0
- package/dist/mcp/terraform/paths.d.ts +28 -0
- package/dist/mcp/terraform/plan.d.ts +157 -0
- package/dist/mcp/terraform/planDrift.d.ts +199 -0
- package/dist/mcp/terraform/policyAuthor.d.ts +191 -0
- package/dist/mcp/terraform/prowlerOcsf.d.ts +136 -0
- package/dist/mcp/terraform/refactor.d.ts +183 -0
- package/dist/mcp/terraform/registry.d.ts +108 -0
- package/dist/mcp/terraform/risk.d.ts +41 -0
- package/dist/mcp/terraform/scanSession.d.ts +116 -0
- package/dist/mcp/terraform/scannerCache.d.ts +15 -0
- package/dist/mcp/terraform/scannerEgress.d.ts +72 -0
- package/dist/mcp/terraform/scannerJson.d.ts +13 -0
- package/dist/mcp/terraform/scanners.d.ts +205 -0
- package/dist/mcp/terraform/signing.d.ts +61 -0
- package/dist/mcp/terraform/stateLocking.d.ts +18 -0
- package/dist/mcp/terraform/subprocess.d.ts +43 -0
- package/dist/mcp/terraform/suppressions.d.ts +90 -0
- package/dist/mcp/terraform/taxonomy.d.ts +39 -0
- package/dist/mcp/terraform/tfquery.d.ts +47 -0
- package/dist/mcp/terraform/toolchainIntegrity.d.ts +82 -0
- package/dist/mcp/terraform/tools/authorPolicy.d.ts +59 -0
- package/dist/mcp/terraform/tools/detectPlanDrift.d.ts +20 -0
- package/dist/mcp/terraform/tools/emitCost.d.ts +11 -0
- package/dist/mcp/terraform/tools/emitSarif.d.ts +14 -0
- package/dist/mcp/terraform/tools/fixMemory.d.ts +19 -0
- package/dist/mcp/terraform/tools/infracostDiff.d.ts +22 -0
- package/dist/mcp/terraform/tools/ingestExternalFindings.d.ts +21 -0
- package/dist/mcp/terraform/tools/moduleLookup.d.ts +14 -0
- package/dist/mcp/terraform/tools/moduleSearch.d.ts +23 -0
- package/dist/mcp/terraform/tools/plan.d.ts +59 -0
- package/dist/mcp/terraform/tools/providerUpgrade.d.ts +55 -0
- package/dist/mcp/terraform/tools/readFindings.d.ts +17 -0
- package/dist/mcp/terraform/tools/scan.d.ts +114 -0
- package/dist/mcp/terraform/tools/validate.d.ts +31 -0
- package/dist/mcp/terraform/tools/verifyRemediation.d.ts +31 -0
- package/dist/mcp/terraform/tools/versionCurrency.d.ts +5 -0
- package/dist/mcp/terraform/tools.d.ts +16 -0
- package/dist/mcp/terraform/transformPacks.d.ts +267 -0
- package/dist/mcp/terraform/types.d.ts +226 -0
- package/dist/mcp/terraform/verification.d.ts +81 -0
- package/dist/mcp/terraform/vex.d.ts +115 -0
- package/dist/mcp/terraform/writeOnly.d.ts +67 -0
- package/dist/mcp/terraform.d.ts +51 -0
- package/dist/mcp/terratest.d.ts +85 -0
- package/dist/mcp/untrustedContent.d.ts +76 -0
- package/dist/mcp/upload.d.ts +8 -0
- package/dist/models.d.ts +181 -0
- package/dist/modes/address-reviews.d.ts +2 -0
- package/dist/modes/assess.d.ts +2 -0
- package/dist/modes/build.d.ts +2 -0
- package/dist/modes/compliance-audit.d.ts +2 -0
- package/dist/modes/cost-optimization.d.ts +2 -0
- package/dist/modes/drift-detect.d.ts +2 -0
- package/dist/modes/fix.d.ts +2 -0
- package/dist/modes/incremental-review.d.ts +2 -0
- package/dist/modes/index.d.ts +24 -0
- package/dist/modes/modernize-deprecated.d.ts +2 -0
- package/dist/modes/plan.d.ts +2 -0
- package/dist/modes/policy-gate.d.ts +2 -0
- package/dist/modes/prFormats.d.ts +3 -0
- package/dist/modes/refactor.d.ts +2 -0
- package/dist/modes/refresh-remediation.d.ts +2 -0
- package/dist/modes/remediate-and-refactor.d.ts +2 -0
- package/dist/modes/remediate.d.ts +2 -0
- package/dist/modes/resolve-conflicts.d.ts +2 -0
- package/dist/modes/review.d.ts +2 -0
- package/dist/modes/summarize-pr.d.ts +2 -0
- package/dist/modes/task.d.ts +2 -0
- package/dist/modes/terraform-code-review.d.ts +2 -0
- package/dist/modes/types.d.ts +9 -0
- package/dist/modes/update-dependencies.d.ts +2 -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 +107 -0
- package/dist/skills/terraform-best-practices/SKILL.md +379 -0
- package/dist/toolState.d.ts +123 -0
- package/dist/utils/activity.d.ts +40 -0
- package/dist/utils/agent.d.ts +47 -0
- package/dist/utils/agentHangReport.d.ts +38 -0
- package/dist/utils/annotations.d.ts +17 -0
- package/dist/utils/apiFetch.d.ts +11 -0
- package/dist/utils/apiKeys.d.ts +48 -0
- package/dist/utils/apiUrl.d.ts +28 -0
- package/dist/utils/assets.d.ts +8 -0
- package/dist/utils/baseRefConfig.d.ts +121 -0
- package/dist/utils/billingErrors.d.ts +85 -0
- package/dist/utils/body.d.ts +34 -0
- package/dist/utils/buildInfraweaverFooter.d.ts +29 -0
- package/dist/utils/byokFallback.d.ts +85 -0
- package/dist/utils/changeImpact.d.ts +101 -0
- package/dist/utils/claudeSubscription.d.ts +30 -0
- package/dist/utils/cli.d.ts +10 -0
- package/dist/utils/cloudClient.d.ts +33 -0
- package/dist/utils/cloudFetchCore.d.ts +42 -0
- package/dist/utils/cloudReport.d.ts +114 -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/env.d.ts +46 -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 +104 -0
- package/dist/utils/globals.d.ts +3 -0
- package/dist/utils/infraweaverConfig.d.ts +56 -0
- package/dist/utils/install.d.ts +37 -0
- package/dist/utils/instructions.d.ts +48 -0
- package/dist/utils/keylessOidc.d.ts +28 -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/modelResolver.d.ts +63 -0
- package/dist/utils/moduleFetch.d.ts +39 -0
- package/dist/utils/normalizeEnv.d.ts +30 -0
- package/dist/utils/openCodeModels.d.ts +11 -0
- package/dist/utils/openaiCompatible.d.ts +26 -0
- package/dist/utils/opentofuMcp.d.ts +50 -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 +249 -0
- package/dist/utils/prSummary.d.ts +61 -0
- package/dist/utils/presets.d.ts +36 -0
- package/dist/utils/progressComment.d.ts +146 -0
- package/dist/utils/providerErrors.d.ts +31 -0
- package/dist/utils/proxyModel.d.ts +76 -0
- package/dist/utils/rangeDiff.d.ts +51 -0
- package/dist/utils/redact.d.ts +33 -0
- package/dist/utils/registryAuth.d.ts +52 -0
- package/dist/utils/remediationCommand.d.ts +58 -0
- package/dist/utils/retry.d.ts +38 -0
- package/dist/utils/reviewCleanup.d.ts +14 -0
- package/dist/utils/run.d.ts +9 -0
- package/dist/utils/runContext.d.ts +112 -0
- package/dist/utils/runContextData.d.ts +42 -0
- package/dist/utils/runErrorRenderer.d.ts +64 -0
- package/dist/utils/runLifecycle.d.ts +89 -0
- package/dist/utils/runStartupLog.d.ts +15 -0
- package/dist/utils/secrets.d.ts +34 -0
- package/dist/utils/setup.d.ts +90 -0
- package/dist/utils/shell.d.ts +44 -0
- package/dist/utils/skills.d.ts +10 -0
- package/dist/utils/subprocess.d.ts +81 -0
- package/dist/utils/terraformMcp.d.ts +46 -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 +52 -0
- package/dist/utils/toolLicensing.d.ts +56 -0
- package/dist/utils/toolSelection.d.ts +73 -0
- package/dist/utils/toon.d.ts +16 -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 +132 -0
- package/src/agents/claude.ts +1588 -0
- package/src/agents/claudePretoolGate.ts +286 -0
- package/src/agents/dispatchMetrics.ts +162 -0
- package/src/agents/gateServer.ts +178 -0
- package/src/agents/index.ts +10 -0
- package/src/agents/nativeFsDenies.ts +164 -0
- package/src/agents/opencode.ts +1600 -0
- package/src/agents/opencodePlugin.ts +304 -0
- package/src/agents/opencodeShared.ts +134 -0
- package/src/agents/postRun.ts +615 -0
- package/src/agents/reviewer.ts +134 -0
- package/src/agents/sessionLabeler.ts +185 -0
- package/src/agents/shared.ts +377 -0
- package/src/agents/subagentModels.ts +40 -0
- package/src/agents/tokenQuota.ts +203 -0
- package/src/agents/writeGateSource.ts +148 -0
- package/src/agents/writePolicy.ts +132 -0
- package/src/brand.ts +84 -0
- package/src/cli.ts +117 -0
- package/src/commands/gha.ts +188 -0
- package/src/commands/mcp.ts +126 -0
- package/src/commands/verifyEvidence.ts +100 -0
- package/src/entry.ts +7 -0
- package/src/entryPost.ts +109 -0
- package/src/external.ts +308 -0
- package/src/i18n/scaffolding.ts +191 -0
- package/src/index.ts +7 -0
- package/src/internal/index.ts +74 -0
- package/src/lifecycle.ts +2 -0
- package/src/main.ts +815 -0
- package/src/mcp/__fixtures__/infraweaver-scratch-pr-49-review-3485940013.json +110 -0
- package/src/mcp/__fixtures__/infraweaver-scratch-pr-64-review-3531000326.json +14 -0
- package/src/mcp/__fixtures__/infraweaver-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/assess.ts +723 -0
- package/src/mcp/capabilityContext.ts +80 -0
- package/src/mcp/changeSummary.ts +145 -0
- package/src/mcp/checkSuite.ts +261 -0
- package/src/mcp/checkout.ts +1015 -0
- package/src/mcp/comment.ts +683 -0
- package/src/mcp/commitInfo.ts +57 -0
- package/src/mcp/crosswalk.ts +1253 -0
- package/src/mcp/crosswalkDigest.ts +5 -0
- package/src/mcp/cyberEssentials.ts +60 -0
- package/src/mcp/dashboard.ts +232 -0
- package/src/mcp/dependencies.ts +190 -0
- package/src/mcp/frameworks.ts +236 -0
- package/src/mcp/geminiSanitizer.ts +212 -0
- package/src/mcp/git.ts +1116 -0
- package/src/mcp/guardrails.ts +771 -0
- package/src/mcp/issue.ts +74 -0
- package/src/mcp/issueComments.ts +48 -0
- package/src/mcp/issueEvents.ts +100 -0
- package/src/mcp/issueInfo.ts +72 -0
- package/src/mcp/labels.ts +35 -0
- package/src/mcp/localContext.ts +65 -0
- package/src/mcp/localServer.ts +217 -0
- package/src/mcp/moduleExtraction.ts +368 -0
- package/src/mcp/moduleTests.ts +421 -0
- package/src/mcp/modules.ts +752 -0
- package/src/mcp/output.ts +71 -0
- package/src/mcp/pathSafety.ts +28 -0
- package/src/mcp/policy.ts +226 -0
- package/src/mcp/pr.ts +238 -0
- package/src/mcp/prInfo.ts +91 -0
- package/src/mcp/providerSchema.ts +175 -0
- package/src/mcp/review.ts +1081 -0
- package/src/mcp/reviewComments.ts +1137 -0
- package/src/mcp/roots.ts +217 -0
- package/src/mcp/scope.ts +82 -0
- package/src/mcp/selectMode.ts +207 -0
- package/src/mcp/server.ts +498 -0
- package/src/mcp/shared.ts +120 -0
- package/src/mcp/shell.ts +631 -0
- package/src/mcp/staleFix.ts +557 -0
- package/src/mcp/terraform/__snapshots__/moduleDocs.test.ts.snap +40 -0
- package/src/mcp/terraform/azurePrices.ts +38 -0
- package/src/mcp/terraform/baseline.ts +172 -0
- package/src/mcp/terraform/concernResult.ts +111 -0
- package/src/mcp/terraform/cost.ts +175 -0
- package/src/mcp/terraform/cspm.ts +326 -0
- package/src/mcp/terraform/currency.ts +354 -0
- package/src/mcp/terraform/decisions.ts +590 -0
- package/src/mcp/terraform/eidas.ts +134 -0
- package/src/mcp/terraform/evidence.ts +771 -0
- package/src/mcp/terraform/findings.ts +383 -0
- package/src/mcp/terraform/fixMemory.ts +253 -0
- package/src/mcp/terraform/governance.ts +231 -0
- package/src/mcp/terraform/hcl.ts +273 -0
- package/src/mcp/terraform/iacLanguages.ts +431 -0
- package/src/mcp/terraform/idleFloor.ts +304 -0
- package/src/mcp/terraform/keyless.ts +123 -0
- package/src/mcp/terraform/moduleDocs.ts +303 -0
- package/src/mcp/terraform/nativeRules.ts +152 -0
- package/src/mcp/terraform/nativeScan.ts +67 -0
- package/src/mcp/terraform/noiseProfile.ts +183 -0
- package/src/mcp/terraform/normalization.ts +265 -0
- package/src/mcp/terraform/oscal.ts +283 -0
- package/src/mcp/terraform/packs/azurerm-3-4.ts +382 -0
- package/src/mcp/terraform/packs/cloudflare-4-5.ts +114 -0
- package/src/mcp/terraform/paths.ts +59 -0
- package/src/mcp/terraform/plan.ts +377 -0
- package/src/mcp/terraform/planDrift.ts +520 -0
- package/src/mcp/terraform/policyAuthor.ts +886 -0
- package/src/mcp/terraform/prowlerOcsf.ts +380 -0
- package/src/mcp/terraform/refactor.ts +879 -0
- package/src/mcp/terraform/registry.ts +317 -0
- package/src/mcp/terraform/risk.ts +99 -0
- package/src/mcp/terraform/scanSession.ts +242 -0
- package/src/mcp/terraform/scannerCache.ts +86 -0
- package/src/mcp/terraform/scannerEgress.ts +141 -0
- package/src/mcp/terraform/scannerJson.ts +22 -0
- package/src/mcp/terraform/scanners.ts +1134 -0
- package/src/mcp/terraform/signing.ts +151 -0
- package/src/mcp/terraform/stateLocking.ts +106 -0
- package/src/mcp/terraform/subprocess.ts +102 -0
- package/src/mcp/terraform/suppressions.ts +551 -0
- package/src/mcp/terraform/taxonomy.ts +0 -0
- package/src/mcp/terraform/tfquery.ts +159 -0
- package/src/mcp/terraform/toolchainIntegrity.ts +151 -0
- package/src/mcp/terraform/tools/authorPolicy.ts +185 -0
- package/src/mcp/terraform/tools/detectPlanDrift.ts +279 -0
- package/src/mcp/terraform/tools/emitCost.ts +130 -0
- package/src/mcp/terraform/tools/emitSarif.ts +108 -0
- package/src/mcp/terraform/tools/fixMemory.ts +82 -0
- package/src/mcp/terraform/tools/infracostDiff.ts +110 -0
- package/src/mcp/terraform/tools/ingestExternalFindings.ts +259 -0
- package/src/mcp/terraform/tools/moduleLookup.ts +86 -0
- package/src/mcp/terraform/tools/moduleSearch.ts +46 -0
- package/src/mcp/terraform/tools/plan.ts +384 -0
- package/src/mcp/terraform/tools/providerUpgrade.ts +217 -0
- package/src/mcp/terraform/tools/readFindings.ts +138 -0
- package/src/mcp/terraform/tools/scan.ts +303 -0
- package/src/mcp/terraform/tools/validate.ts +160 -0
- package/src/mcp/terraform/tools/verifyRemediation.ts +190 -0
- package/src/mcp/terraform/tools/versionCurrency.ts +64 -0
- package/src/mcp/terraform/tools.ts +62 -0
- package/src/mcp/terraform/transformPacks.ts +594 -0
- package/src/mcp/terraform/types.ts +382 -0
- package/src/mcp/terraform/verification.ts +150 -0
- package/src/mcp/terraform/vex.ts +367 -0
- package/src/mcp/terraform/writeOnly.ts +252 -0
- package/src/mcp/terraform.ts +52 -0
- package/src/mcp/terratest.ts +215 -0
- package/src/mcp/untrustedContent.ts +126 -0
- package/src/mcp/upload.ts +123 -0
- package/src/models.ts +753 -0
- package/src/modes/address-reviews.ts +35 -0
- package/src/modes/assess.ts +27 -0
- package/src/modes/build.ts +86 -0
- package/src/modes/compliance-audit.ts +25 -0
- package/src/modes/cost-optimization.ts +36 -0
- package/src/modes/drift-detect.ts +31 -0
- package/src/modes/fix.ts +29 -0
- package/src/modes/incremental-review.ts +103 -0
- package/src/modes/index.ts +94 -0
- package/src/modes/modernize-deprecated.ts +36 -0
- package/src/modes/plan.ts +21 -0
- package/src/modes/policy-gate.ts +27 -0
- package/src/modes/prFormats.ts +325 -0
- package/src/modes/refactor.ts +74 -0
- package/src/modes/refresh-remediation.ts +40 -0
- package/src/modes/remediate-and-refactor.ts +42 -0
- package/src/modes/remediate.ts +78 -0
- package/src/modes/resolve-conflicts.ts +32 -0
- package/src/modes/review.ts +135 -0
- package/src/modes/summarize-pr.ts +42 -0
- package/src/modes/task.ts +26 -0
- package/src/modes/terraform-code-review.ts +68 -0
- package/src/modes/types.ts +17 -0
- package/src/modes/update-dependencies.ts +44 -0
- package/src/prep/index.ts +96 -0
- package/src/prep/installNodeDependencies.ts +251 -0
- package/src/prep/installPythonDependencies.ts +235 -0
- package/src/prep/types.ts +38 -0
- package/src/reviewQuality.ts +237 -0
- package/src/runCli.ts +335 -0
- package/src/skills/terraform-best-practices/SKILL.md +379 -0
- package/src/toolState.ts +241 -0
- package/src/utils/activity.ts +210 -0
- package/src/utils/agent.ts +245 -0
- package/src/utils/agentHangReport.ts +180 -0
- package/src/utils/annotations.ts +56 -0
- package/src/utils/apiFetch.ts +19 -0
- package/src/utils/apiKeys.ts +305 -0
- package/src/utils/apiUrl.ts +42 -0
- package/src/utils/assets.ts +123 -0
- package/src/utils/baseRefConfig.ts +254 -0
- package/src/utils/billingErrors.ts +210 -0
- package/src/utils/body.ts +168 -0
- package/src/utils/buildInfraweaverFooter.ts +104 -0
- package/src/utils/byokFallback.ts +137 -0
- package/src/utils/changeImpact.ts +330 -0
- package/src/utils/claudeSubscription.ts +93 -0
- package/src/utils/cli.ts +36 -0
- package/src/utils/cloudClient.ts +57 -0
- package/src/utils/cloudFetchCore.ts +139 -0
- package/src/utils/cloudReport.ts +316 -0
- package/src/utils/codexHome.ts +204 -0
- package/src/utils/codexOAuth.ts +154 -0
- package/src/utils/codexRefreshDetect.ts +36 -0
- package/src/utils/diffCoverage.ts +404 -0
- package/src/utils/env.ts +84 -0
- package/src/utils/errorReport.ts +94 -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.ts +268 -0
- package/src/utils/gitAuthServer.ts +186 -0
- package/src/utils/github.ts +676 -0
- package/src/utils/globals.ts +9 -0
- package/src/utils/humanEditCapture.ts +198 -0
- package/src/utils/infraweaverConfig.ts +202 -0
- package/src/utils/install.ts +279 -0
- package/src/utils/instructions.ts +640 -0
- package/src/utils/keylessOidc.ts +47 -0
- package/src/utils/leapingComment.ts +20 -0
- package/src/utils/learnings.ts +145 -0
- package/src/utils/learningsTruncate.ts +42 -0
- package/src/utils/lifecycle.ts +198 -0
- package/src/utils/log.ts +452 -0
- package/src/utils/modelResolver.ts +105 -0
- package/src/utils/moduleFetch.ts +138 -0
- package/src/utils/normalizeEnv.ts +106 -0
- package/src/utils/openCodeModels.ts +86 -0
- package/src/utils/openaiCompatible.ts +52 -0
- package/src/utils/opentofuMcp.ts +61 -0
- package/src/utils/overrides.ts +100 -0
- package/src/utils/packageManager.ts +257 -0
- package/src/utils/patchWorkflowRunFields.ts +173 -0
- package/src/utils/payload.ts +1206 -0
- package/src/utils/prSummary.ts +148 -0
- package/src/utils/presets.ts +105 -0
- package/src/utils/progressComment.ts +266 -0
- package/src/utils/providerErrors.ts +189 -0
- package/src/utils/proxyModel.ts +239 -0
- package/src/utils/rangeDiff.ts +182 -0
- package/src/utils/redact.ts +86 -0
- package/src/utils/registryAuth.ts +115 -0
- package/src/utils/remediationCommand.ts +144 -0
- package/src/utils/retry.ts +180 -0
- package/src/utils/reviewCleanup.ts +116 -0
- package/src/utils/run.ts +100 -0
- package/src/utils/runContext.ts +276 -0
- package/src/utils/runContextData.ts +121 -0
- package/src/utils/runErrorRenderer.ts +282 -0
- package/src/utils/runFixture.ts +91 -0
- package/src/utils/runLifecycle.ts +360 -0
- package/src/utils/runStartupLog.ts +67 -0
- package/src/utils/secrets.ts +208 -0
- package/src/utils/setup.ts +368 -0
- package/src/utils/shell.ts +132 -0
- package/src/utils/skills.ts +67 -0
- package/src/utils/subprocess.ts +474 -0
- package/src/utils/terraformMcp.ts +99 -0
- package/src/utils/time.ts +59 -0
- package/src/utils/timer.ts +72 -0
- package/src/utils/todoTracking.ts +168 -0
- package/src/utils/token.ts +294 -0
- package/src/utils/toolLicensing.ts +152 -0
- package/src/utils/toolSelection.ts +239 -0
- package/src/utils/toon.ts +76 -0
- package/src/utils/version.ts +10 -0
- package/src/utils/versioning.ts +44 -0
- package/src/utils/vertex.ts +94 -0
- package/src/utils/workflow.ts +25 -0
|
@@ -0,0 +1,594 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Versioned provider-upgrade transform packs (TC-2.2).
|
|
3
|
+
*
|
|
4
|
+
* WHAT A PACK IS — AND, MORE IMPORTANTLY, WHAT IT IS NOT. A pack is *codified
|
|
5
|
+
* knowledge* about one provider major-version boundary: which resource types
|
|
6
|
+
* disappeared, which arguments were renamed, and — the part that actually
|
|
7
|
+
* matters — which of those changes cannot be made without moving state. It is
|
|
8
|
+
* modelled on `fix_memory` deliberately (same shape: identity, match, merge,
|
|
9
|
+
* coerce, fleet stats): a pack entry is a **PRIOR, never a patch**. Nothing here
|
|
10
|
+
* rewrites HCL. The agent edits, `terraform plan` proves, and the existing
|
|
11
|
+
* destroy/replace guardrail blocks.
|
|
12
|
+
*
|
|
13
|
+
* WHY NOT A CODEMOD. A rewriter that silently renamed `enable_x` to `x_enabled`
|
|
14
|
+
* across a repo would be the single most dangerous thing in this codebase: a
|
|
15
|
+
* wrong rename that still parses produces a plan that destroys and recreates
|
|
16
|
+
* live infrastructure, and the failure surfaces in production, not in CI. The
|
|
17
|
+
* whole product thesis is proof over assertion, so the upgrade path is: detect
|
|
18
|
+
* deterministically → hand the agent leads → make it prove the plan → route
|
|
19
|
+
* anything state-moving to a human.
|
|
20
|
+
*
|
|
21
|
+
* ⚠️ THE SELF-TEST IS THE LOAD-BEARING PART. A hand-written migration table goes
|
|
22
|
+
* stale, and a stale entry is worse than no entry. So a rename entry is checked
|
|
23
|
+
* against the **installed provider schema** before it is offered
|
|
24
|
+
* (`verifyEntry`): a pack claiming `a → b` is believed only when the schema
|
|
25
|
+
* agrees that exactly one of the two exists. That is the same discipline §5.2
|
|
26
|
+
* applies to generated rules — a rule that can never fire is refused rather
|
|
27
|
+
* than shipped.
|
|
28
|
+
*
|
|
29
|
+
* What the self-test does NOT cover, stated rather than implied: a whole-resource
|
|
30
|
+
* rename (asking the schema about a type that v4 removed cannot distinguish
|
|
31
|
+
* "removed" from "provider not installed"), a pure deletion (absence of the old
|
|
32
|
+
* name is equally consistent with a misattributed entry), and `argument_required`
|
|
33
|
+
* (a schema says what exists, not what is mandatory). Those come back
|
|
34
|
+
* `unverified`, which is reported honestly and — the part that matters —
|
|
35
|
+
* **excluded from fleet capture**, so doubt is never laundered into a proven
|
|
36
|
+
* counter. It still reaches the agent as a lead, because a lead it can check is
|
|
37
|
+
* more use than silence.
|
|
38
|
+
*
|
|
39
|
+
* PACKS ARE NOT EXHAUSTIVE AND SAY SO. `terraform_validate`'s `unknown_arguments`
|
|
40
|
+
* (checked against the installed schema, not a table) remains the authoritative
|
|
41
|
+
* answer to "what did I miss". A pack's job is to say what to replace a thing
|
|
42
|
+
* WITH — the direction `unknown_arguments` can't give you.
|
|
43
|
+
*/
|
|
44
|
+
import { AZURERM_3_TO_4 } from "#app/mcp/terraform/packs/azurerm-3-4";
|
|
45
|
+
import { CLOUDFLARE_4_TO_5 } from "#app/mcp/terraform/packs/cloudflare-4-5";
|
|
46
|
+
import { STATEFUL_RESOURCE_TYPES } from "#app/mcp/terraform/plan";
|
|
47
|
+
import type {
|
|
48
|
+
LocatedResource,
|
|
49
|
+
ProviderRequirement,
|
|
50
|
+
} from "#app/mcp/terraform/scanners";
|
|
51
|
+
|
|
52
|
+
/** Bumped when the pack SHAPE changes (not when an individual pack's content
|
|
53
|
+
* does — each pack carries its own `version`). Mirrors `FixMemoryFile.version`. */
|
|
54
|
+
export const TRANSFORM_PACK_SCHEMA = "infraweaver-transform-pack/v1" as const;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The built-in packs.
|
|
58
|
+
*
|
|
59
|
+
* Built in rather than fetched: a migration table pulled at runtime is a remote
|
|
60
|
+
* input that decides how live infrastructure gets edited, which is the last
|
|
61
|
+
* thing that should be mutable outside a reviewed release. Adding a pack is a
|
|
62
|
+
* code change with a diff, a review and a version — exactly like the crosswalk.
|
|
63
|
+
*
|
|
64
|
+
* These ship to everyone, OSS included, with no input to enable. The only
|
|
65
|
+
* Cloud-gated part of TC-2.2 is the fleet-wide *proven* counters.
|
|
66
|
+
*/
|
|
67
|
+
export const BUILTIN_TRANSFORM_PACKS: readonly TransformPack[] = [
|
|
68
|
+
AZURERM_3_TO_4,
|
|
69
|
+
CLOUDFLARE_4_TO_5,
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* How a transform's state has to move.
|
|
74
|
+
*
|
|
75
|
+
* This is the field the whole feature turns on, because it — not the size of the
|
|
76
|
+
* diff — decides whether a human must look. `auto` is a pure config edit that
|
|
77
|
+
* `plan` should show as a no-op. `moved_block` needs a `moved {}` block authored
|
|
78
|
+
* (Terraform ≥ 1.8) but keeps the resource. `manual_import` means the state
|
|
79
|
+
* entry cannot be carried across: without `state rm` + `import`, applying the
|
|
80
|
+
* change DESTROYS and RECREATES the resource.
|
|
81
|
+
*/
|
|
82
|
+
export type StateMove = "auto" | "moved_block" | "manual_import";
|
|
83
|
+
|
|
84
|
+
export type TransformKind =
|
|
85
|
+
| "resource_renamed"
|
|
86
|
+
| "resource_removed"
|
|
87
|
+
| "argument_renamed"
|
|
88
|
+
| "argument_removed"
|
|
89
|
+
| "argument_required"
|
|
90
|
+
| "provider_setting";
|
|
91
|
+
|
|
92
|
+
/** One codified breaking change. */
|
|
93
|
+
export interface TransformEntry {
|
|
94
|
+
/** stable id, `<provider>.<from>-<to>.<slug>` — the fleet-sharing match key. */
|
|
95
|
+
id: string;
|
|
96
|
+
kind: TransformKind;
|
|
97
|
+
/** the resource type the change applies to; `null` for provider-block changes. */
|
|
98
|
+
resource_type: string | null;
|
|
99
|
+
/** what the config says today (old resource type, old argument name). */
|
|
100
|
+
from: string;
|
|
101
|
+
/** what it becomes; `null` when the thing was removed with no replacement. */
|
|
102
|
+
to: string | null;
|
|
103
|
+
state_move: StateMove;
|
|
104
|
+
/** true when applying this change is expected to force replacement even after
|
|
105
|
+
* the config edit — the pre-plan signal that a human will be needed. */
|
|
106
|
+
forces_replacement: boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Set when the VALUE must change too, not just the identifier.
|
|
109
|
+
*
|
|
110
|
+
* This exists because the most dangerous entry in any migration table is the
|
|
111
|
+
* one that looks like a pure rename and isn't: `disable_bgp_route_propagation`
|
|
112
|
+
* → `bgp_route_propagation_enabled` inverts the boolean, and a mechanical
|
|
113
|
+
* rename would silently flip the routing behaviour of a live network while
|
|
114
|
+
* `validate`, `plan` and every scanner stayed green. When this is set, the
|
|
115
|
+
* transform is never presented as a rename.
|
|
116
|
+
*/
|
|
117
|
+
value_change?: string;
|
|
118
|
+
/** one line the agent can act on. */
|
|
119
|
+
note: string;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export interface TransformPack {
|
|
123
|
+
/** registry provider name, e.g. `azurerm`. */
|
|
124
|
+
provider: string;
|
|
125
|
+
from_major: number;
|
|
126
|
+
to_major: number;
|
|
127
|
+
/** pack content version — bump when entries change. */
|
|
128
|
+
version: string;
|
|
129
|
+
/** the upstream guide these entries were transcribed from. Every claim in this
|
|
130
|
+
* file is someone else's documented breaking change, so it gets a citation. */
|
|
131
|
+
source: string;
|
|
132
|
+
/** ALWAYS false in practice, and stated rather than implied: no pack here is a
|
|
133
|
+
* complete migration. `unknown_arguments` is the exhaustive check. */
|
|
134
|
+
exhaustive: boolean;
|
|
135
|
+
/** upstream's own migration tool, when one exists. Preferring it over our own
|
|
136
|
+
* leads is "integrate upward, don't compete" applied to migrations. */
|
|
137
|
+
official_tool?: string;
|
|
138
|
+
entries: TransformEntry[];
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Whether the installed provider schema CORROBORATES a pack entry.
|
|
143
|
+
*
|
|
144
|
+
* - `pre-upgrade` — schema has `from`, not `to`. Consistent with the old major
|
|
145
|
+
* still being installed; the entry is a valid lead.
|
|
146
|
+
* - `post-upgrade` — schema has `to`, not `from`. The new major is installed, so
|
|
147
|
+
* any remaining use of `from` is a confirmed must-fix.
|
|
148
|
+
* - `unverified` — schema has both, neither, or wasn't loadable. The pack is
|
|
149
|
+
* not believed; the entry is reported but never actionable.
|
|
150
|
+
*/
|
|
151
|
+
export type SchemaAgreement = "pre-upgrade" | "post-upgrade" | "unverified";
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* How sure we are that this entry applies to a specific piece of the config.
|
|
155
|
+
*
|
|
156
|
+
* `absent` exists because one entry kind — `argument_required` — fires on the
|
|
157
|
+
* argument NOT being there. Reporting that as `confirmed` (which is documented
|
|
158
|
+
* as "the identifier was found") would tell the reader the exact opposite of
|
|
159
|
+
* what happened.
|
|
160
|
+
*/
|
|
161
|
+
export type MatchConfidence = "confirmed" | "nested" | "absent";
|
|
162
|
+
|
|
163
|
+
export interface TransformMatch {
|
|
164
|
+
entry: TransformEntry;
|
|
165
|
+
/** the pack that produced it. Carried per-match rather than read from the
|
|
166
|
+
* run's primary pack, because a repo can be mid-upgrade on two providers and
|
|
167
|
+
* the fleet row's provider/major columns must describe the right one. */
|
|
168
|
+
provider: string;
|
|
169
|
+
from_major: number;
|
|
170
|
+
to_major: number;
|
|
171
|
+
/** where it was found. */
|
|
172
|
+
file: string;
|
|
173
|
+
/** the resource block's local name (`""` for provider-block matches). */
|
|
174
|
+
resource_name: string;
|
|
175
|
+
/**
|
|
176
|
+
* `confirmed` — the exact top-level identifier was found in the parsed config.
|
|
177
|
+
* `nested` — the entry names a path inside a block (`a.b.c`) and the parser
|
|
178
|
+
* only sees top-level argument names, so the resource TYPE
|
|
179
|
+
* matched but the argument itself was not confirmed. Reported as
|
|
180
|
+
* a lead to check by hand, never as a certainty.
|
|
181
|
+
*/
|
|
182
|
+
confidence: MatchConfidence;
|
|
183
|
+
schema_agreement: SchemaAgreement;
|
|
184
|
+
/** true when this match must not be applied autonomously. */
|
|
185
|
+
needs_human: boolean;
|
|
186
|
+
/** why, when it does. */
|
|
187
|
+
needs_human_reason: string | null;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/** A pack entry is nested when it names a path inside a block. */
|
|
191
|
+
function isNestedPath(arg: string): boolean {
|
|
192
|
+
return arg.includes(".");
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/** The leaf identifier of a possibly-dotted path. */
|
|
196
|
+
function leafOf(path: string): string {
|
|
197
|
+
const parts = path.split(".");
|
|
198
|
+
return parts[parts.length - 1] ?? path;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Does this transform need a human?
|
|
203
|
+
*
|
|
204
|
+
* Two independent triggers, both deliberately conservative:
|
|
205
|
+
* 1. `manual_import` — the state cannot be carried across automatically, so an
|
|
206
|
+
* unattended apply destroys and recreates. Always human, every resource type.
|
|
207
|
+
* 2. `forces_replacement` on a STATEFUL resource type. Stateful-ness is read
|
|
208
|
+
* from `plan.ts`'s `STATEFUL_RESOURCE_TYPES` — the exact set the push-time
|
|
209
|
+
* `assertNoBlockedDestroy` guardrail uses — and NOT from `governance.ts`'s
|
|
210
|
+
* regex heuristic, because the point of pre-declaring this is to predict
|
|
211
|
+
* what the guard will actually block. Predicting it with a different
|
|
212
|
+
* definition than the guard uses would be worse than not predicting it.
|
|
213
|
+
*/
|
|
214
|
+
export function transformNeedsHuman(entry: TransformEntry): {
|
|
215
|
+
needs: boolean;
|
|
216
|
+
reason: string | null;
|
|
217
|
+
} {
|
|
218
|
+
if (entry.state_move === "manual_import") {
|
|
219
|
+
return {
|
|
220
|
+
needs: true,
|
|
221
|
+
reason:
|
|
222
|
+
"state cannot be moved automatically — without `terraform state rm` + `import` this destroys and recreates the resource",
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
if (entry.forces_replacement) {
|
|
226
|
+
const type = entry.resource_type ?? "";
|
|
227
|
+
if (STATEFUL_RESOURCE_TYPES.has(type)) {
|
|
228
|
+
return {
|
|
229
|
+
needs: true,
|
|
230
|
+
reason: `forces replacement of ${type}, which holds data — the push guardrail blocks this unless explicitly allowed`,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
return {
|
|
234
|
+
needs: true,
|
|
235
|
+
reason: "forces resource replacement — confirm the plan before shipping",
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
return { needs: false, reason: null };
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/** Schema lookup seam. Returns the argument names known for a resource type, or
|
|
242
|
+
* `null` when the schema could not be loaded / the type is unknown to it. */
|
|
243
|
+
export type SchemaLookup = (resourceType: string) => ReadonlySet<string> | null;
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Check one entry against the installed provider schema.
|
|
247
|
+
*
|
|
248
|
+
* Only argument-level entries are checkable this way — a removed RESOURCE type
|
|
249
|
+
* cannot be corroborated by asking the schema about it (its absence is equally
|
|
250
|
+
* consistent with "removed in v4" and "this provider isn't installed"), so those
|
|
251
|
+
* return `unverified` and lean on the deterministic type match instead.
|
|
252
|
+
*/
|
|
253
|
+
export function verifyEntry(
|
|
254
|
+
entry: TransformEntry,
|
|
255
|
+
lookup: SchemaLookup,
|
|
256
|
+
): SchemaAgreement {
|
|
257
|
+
if (entry.kind !== "argument_renamed" && entry.kind !== "argument_removed")
|
|
258
|
+
return "unverified";
|
|
259
|
+
if (!entry.resource_type) return "unverified";
|
|
260
|
+
const known = lookup(entry.resource_type);
|
|
261
|
+
if (!known) return "unverified";
|
|
262
|
+
const hasFrom = known.has(leafOf(entry.from));
|
|
263
|
+
// A pure deletion has no replacement name to look for, so the ONLY signal is
|
|
264
|
+
// the old name's absence — which is equally consistent with "v4 is installed"
|
|
265
|
+
// and "this entry names the wrong argument". Treating absence as
|
|
266
|
+
// `post-upgrade` made the verdict unfalsifiable and, worse, made a
|
|
267
|
+
// misattributed entry read as MORE confirmed, not less. Deletions therefore
|
|
268
|
+
// corroborate in one direction only.
|
|
269
|
+
if (entry.to === null) return hasFrom ? "pre-upgrade" : "unverified";
|
|
270
|
+
const hasTo = known.has(leafOf(entry.to));
|
|
271
|
+
if (hasFrom && !hasTo) return "pre-upgrade";
|
|
272
|
+
if (!hasFrom && hasTo) return "post-upgrade";
|
|
273
|
+
return "unverified";
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Select the packs that apply to what this repo actually pins.
|
|
278
|
+
*
|
|
279
|
+
* A pack applies when the provider is required AND the pinned lower-bound major
|
|
280
|
+
* equals the pack's `from_major`. An unconstrained provider (`major: null`)
|
|
281
|
+
* matches nothing: guessing which major an unpinned provider resolves to is how
|
|
282
|
+
* you hand someone a migration they don't need.
|
|
283
|
+
*/
|
|
284
|
+
export function packsForRequirements(
|
|
285
|
+
packs: readonly TransformPack[],
|
|
286
|
+
requirements: readonly ProviderRequirement[],
|
|
287
|
+
): TransformPack[] {
|
|
288
|
+
const pinned = new Map<string, number>();
|
|
289
|
+
for (const r of requirements) {
|
|
290
|
+
if (r.major !== null && !pinned.has(r.name)) pinned.set(r.name, r.major);
|
|
291
|
+
}
|
|
292
|
+
return packs.filter((p) => pinned.get(p.provider) === p.from_major);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Match a pack's entries against the parsed configuration. Pure.
|
|
297
|
+
*
|
|
298
|
+
* `resources` comes from `parseResourceArguments`, which reports TOP-LEVEL
|
|
299
|
+
* argument names only. That bound is honoured rather than papered over: a
|
|
300
|
+
* dotted entry produces a `nested` match (resource type present, argument not
|
|
301
|
+
* confirmed) so the agent knows to look inside the block itself.
|
|
302
|
+
*/
|
|
303
|
+
export function matchTransforms(
|
|
304
|
+
pack: TransformPack,
|
|
305
|
+
resources: readonly LocatedResource[],
|
|
306
|
+
lookup: SchemaLookup,
|
|
307
|
+
): TransformMatch[] {
|
|
308
|
+
const matches: TransformMatch[] = [];
|
|
309
|
+
for (const entry of pack.entries) {
|
|
310
|
+
const agreement = verifyEntry(entry, lookup);
|
|
311
|
+
const { needs, reason } = transformNeedsHuman(entry);
|
|
312
|
+
const base = {
|
|
313
|
+
entry,
|
|
314
|
+
provider: pack.provider,
|
|
315
|
+
from_major: pack.from_major,
|
|
316
|
+
to_major: pack.to_major,
|
|
317
|
+
schema_agreement: agreement,
|
|
318
|
+
needs_human: needs,
|
|
319
|
+
needs_human_reason: reason,
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
if (
|
|
323
|
+
entry.kind === "resource_renamed" ||
|
|
324
|
+
entry.kind === "resource_removed"
|
|
325
|
+
) {
|
|
326
|
+
for (const r of resources) {
|
|
327
|
+
if (r.resourceType !== entry.from) continue;
|
|
328
|
+
matches.push({
|
|
329
|
+
...base,
|
|
330
|
+
file: r.file,
|
|
331
|
+
resource_name: r.name,
|
|
332
|
+
confidence: "confirmed",
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
if (entry.kind === "provider_setting") {
|
|
338
|
+
// Provider-block settings aren't resources; they are reported once, without
|
|
339
|
+
// a location, because `parseResourceArguments` doesn't see provider blocks.
|
|
340
|
+
matches.push({
|
|
341
|
+
...base,
|
|
342
|
+
file: "",
|
|
343
|
+
resource_name: "",
|
|
344
|
+
confidence: "nested",
|
|
345
|
+
});
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
// argument-level
|
|
349
|
+
for (const r of resources) {
|
|
350
|
+
if (r.resourceType !== entry.resource_type) continue;
|
|
351
|
+
if (isNestedPath(entry.from)) {
|
|
352
|
+
matches.push({
|
|
353
|
+
...base,
|
|
354
|
+
file: r.file,
|
|
355
|
+
resource_name: r.name,
|
|
356
|
+
confidence: "nested",
|
|
357
|
+
});
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
// `argument_required` is the one entry kind whose trigger is ABSENCE: the
|
|
361
|
+
// argument became mandatory, so the resources that need work are the ones
|
|
362
|
+
// NOT carrying it. Matching on presence here (as every other kind does)
|
|
363
|
+
// would report exactly the resources that are already correct.
|
|
364
|
+
const present = r.args.includes(entry.from);
|
|
365
|
+
const requiredAndMissing = entry.kind === "argument_required" && !present;
|
|
366
|
+
if (requiredAndMissing) {
|
|
367
|
+
matches.push({
|
|
368
|
+
...base,
|
|
369
|
+
file: r.file,
|
|
370
|
+
resource_name: r.name,
|
|
371
|
+
confidence: "absent",
|
|
372
|
+
});
|
|
373
|
+
} else if (present && entry.kind !== "argument_required") {
|
|
374
|
+
matches.push({
|
|
375
|
+
...base,
|
|
376
|
+
file: r.file,
|
|
377
|
+
resource_name: r.name,
|
|
378
|
+
confidence: "confirmed",
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
return matches;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Fleet reuse stats for a transform id — the §5.12-shaped half.
|
|
388
|
+
*
|
|
389
|
+
* Notice what is NOT here: no config, no snippet, no repo name. A transform is
|
|
390
|
+
* already fully described by the pack every engine ships; the only thing worth
|
|
391
|
+
* sharing across an org is *whether it has been proven to plan cleanly, and how
|
|
392
|
+
* widely*. That keeps the fleet payload a set of counters, so there is no path
|
|
393
|
+
* by which one repo's configuration reaches another.
|
|
394
|
+
*/
|
|
395
|
+
export interface ProvenTransform {
|
|
396
|
+
/** matches `TransformEntry.id`. */
|
|
397
|
+
transform_id: string;
|
|
398
|
+
provider: string;
|
|
399
|
+
from_major: number;
|
|
400
|
+
to_major: number;
|
|
401
|
+
/** how many times this transform's upgrade planned cleanly. */
|
|
402
|
+
times_proven?: number;
|
|
403
|
+
/** distinct repos it has been proven on. */
|
|
404
|
+
repos_count?: number;
|
|
405
|
+
last_proven?: string;
|
|
406
|
+
/** operator retired it in the dashboard — never offered as proven. */
|
|
407
|
+
disabled?: boolean;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
export function isProvenTransform(value: unknown): value is ProvenTransform {
|
|
411
|
+
if (!value || typeof value !== "object") return false;
|
|
412
|
+
const p = value as Record<string, unknown>;
|
|
413
|
+
return (
|
|
414
|
+
typeof p.transform_id === "string" &&
|
|
415
|
+
p.transform_id.length > 0 &&
|
|
416
|
+
typeof p.provider === "string" &&
|
|
417
|
+
typeof p.from_major === "number" &&
|
|
418
|
+
typeof p.to_major === "number"
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/** Coerce the untrusted Cloud `provenTransforms` blob. Pure — the wire boundary
|
|
423
|
+
* can't be typechecked across repos (same reasoning as `coerceLibrary`). */
|
|
424
|
+
export function coerceProvenTransforms(raw: unknown): ProvenTransform[] {
|
|
425
|
+
if (!Array.isArray(raw)) return [];
|
|
426
|
+
return raw.filter(isProvenTransform).filter((p) => !p.disabled);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* What `terraform_provider_upgrade` detected this run, parked on the session so
|
|
431
|
+
* the evidence builder can bind it to the plan that came after.
|
|
432
|
+
*/
|
|
433
|
+
export interface UpgradeIntent {
|
|
434
|
+
provider: string;
|
|
435
|
+
from_major: number;
|
|
436
|
+
to_major: number;
|
|
437
|
+
pack_version: string;
|
|
438
|
+
pack_source: string;
|
|
439
|
+
pack_exhaustive: boolean;
|
|
440
|
+
/** ids of every transform matched in this config, deduped, sorted. */
|
|
441
|
+
transform_ids: string[];
|
|
442
|
+
/** how many of those must not be applied autonomously. */
|
|
443
|
+
needing_human: number;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/** The plan facts the proof rests on. Supplied by the caller from the session so
|
|
447
|
+
* this stays pure and testable. */
|
|
448
|
+
export interface UpgradePlanFacts {
|
|
449
|
+
to_add: number;
|
|
450
|
+
to_change: number;
|
|
451
|
+
to_destroy: number;
|
|
452
|
+
/** count of destroy/replace actions across all roots. */
|
|
453
|
+
destructive: number;
|
|
454
|
+
/** count of those that hit a data-bearing resource type. */
|
|
455
|
+
stateful_destructive: number;
|
|
456
|
+
/** false when a second plan disagreed with the first. */
|
|
457
|
+
idempotent: boolean;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* The signed-evidence statement for a provider upgrade (TC-2.2's "carrying the
|
|
462
|
+
* passing plan as proof").
|
|
463
|
+
*
|
|
464
|
+
* The verdict is computed from the plan, never asserted by the agent, and — per
|
|
465
|
+
* §8 — the statement carries what it does NOT claim. A clean plan proves that
|
|
466
|
+
* Terraform intends no destructive change to the resources it can see. It does
|
|
467
|
+
* not prove the upgrade is behaviourally correct, and it says so.
|
|
468
|
+
*/
|
|
469
|
+
export interface UpgradeEvidenceStatement {
|
|
470
|
+
provider: string;
|
|
471
|
+
from_major: number;
|
|
472
|
+
to_major: number;
|
|
473
|
+
pack_version: string;
|
|
474
|
+
pack_source: string;
|
|
475
|
+
/** always false, carried into the signed bytes so a reader cannot mistake the
|
|
476
|
+
* transform list for a complete migration. */
|
|
477
|
+
pack_exhaustive: boolean;
|
|
478
|
+
verdict: "plan-proven" | "plan-unclean" | "no-plan";
|
|
479
|
+
transforms_detected: number;
|
|
480
|
+
transforms_needing_human: number;
|
|
481
|
+
transform_ids: string[];
|
|
482
|
+
plan?: UpgradePlanFacts | undefined;
|
|
483
|
+
asserts: string;
|
|
484
|
+
does_not_assert: string;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
const UPGRADE_DOES_NOT_ASSERT =
|
|
488
|
+
"Does NOT assert that the upgraded configuration is behaviourally equivalent to the previous " +
|
|
489
|
+
"major, that the transform list was complete, or that unlisted breaking changes were handled. " +
|
|
490
|
+
"A plan reflects only what Terraform can see from the configuration and state it was given.";
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Build the upgrade statement. Pure. `facts` is undefined when no plan ran —
|
|
494
|
+
* which is itself recorded as a verdict rather than omitted, because an upgrade
|
|
495
|
+
* shipped without a plan is precisely the case a reader must be able to spot.
|
|
496
|
+
*/
|
|
497
|
+
export function buildUpgradeStatement(
|
|
498
|
+
intent: UpgradeIntent | undefined,
|
|
499
|
+
facts: UpgradePlanFacts | undefined,
|
|
500
|
+
): UpgradeEvidenceStatement | undefined {
|
|
501
|
+
if (!intent) return undefined;
|
|
502
|
+
// ⚠️ `destructive`, not just `stateful_destructive`. A migration's entire
|
|
503
|
+
// premise is that state survives it, so ANY destroy/replace refutes it —
|
|
504
|
+
// including on resource types `STATEFUL_RESOURCE_TYPES` has never heard of.
|
|
505
|
+
// The first cut gated on stateful-ness alone, which meant 200 renamed
|
|
506
|
+
// `cloudflare_record`s missing their `moved {}` blocks planned as 200
|
|
507
|
+
// destroy+create, agreed with themselves across both runs, and signed as
|
|
508
|
+
// `plan-proven` — a clean bill of health for a plan that erases a DNS zone.
|
|
509
|
+
const verdict: UpgradeEvidenceStatement["verdict"] = !facts
|
|
510
|
+
? "no-plan"
|
|
511
|
+
: facts.destructive === 0 &&
|
|
512
|
+
facts.to_destroy === 0 &&
|
|
513
|
+
facts.stateful_destructive === 0 &&
|
|
514
|
+
facts.idempotent
|
|
515
|
+
? "plan-proven"
|
|
516
|
+
: "plan-unclean";
|
|
517
|
+
const asserts =
|
|
518
|
+
verdict === "plan-proven"
|
|
519
|
+
? `A \`terraform plan\` after the ${intent.provider} v${intent.from_major}→v${intent.to_major} upgrade was stable across two runs and destroys or replaces NOTHING.`
|
|
520
|
+
: verdict === "plan-unclean"
|
|
521
|
+
? `A \`terraform plan\` ran after the ${intent.provider} v${intent.from_major}→v${intent.to_major} upgrade and was NOT clean — it is recorded here as evidence, not as a pass.`
|
|
522
|
+
: `The ${intent.provider} v${intent.from_major}→v${intent.to_major} transforms below were detected in the configuration. NO plan backs this run, so nothing is proven about runtime behaviour.`;
|
|
523
|
+
return {
|
|
524
|
+
provider: intent.provider,
|
|
525
|
+
from_major: intent.from_major,
|
|
526
|
+
to_major: intent.to_major,
|
|
527
|
+
pack_version: intent.pack_version,
|
|
528
|
+
pack_source: intent.pack_source,
|
|
529
|
+
pack_exhaustive: intent.pack_exhaustive,
|
|
530
|
+
verdict,
|
|
531
|
+
transforms_detected: intent.transform_ids.length,
|
|
532
|
+
transforms_needing_human: intent.needing_human,
|
|
533
|
+
transform_ids: intent.transform_ids,
|
|
534
|
+
...(facts ? { plan: facts } : {}),
|
|
535
|
+
asserts,
|
|
536
|
+
does_not_assert: UPGRADE_DOES_NOT_ASSERT,
|
|
537
|
+
};
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
/**
|
|
541
|
+
* The transforms this run may report to the org's fleet library as PROVEN.
|
|
542
|
+
*
|
|
543
|
+
* Only on a `plan-proven` verdict, and only transforms that did not need a
|
|
544
|
+
* human — a transform a person had to intervene on is not evidence that the
|
|
545
|
+
* transform is safe to apply unattended, which is the only claim the fleet
|
|
546
|
+
* counter is allowed to make.
|
|
547
|
+
*/
|
|
548
|
+
export function captureProvenTransforms(
|
|
549
|
+
statement: UpgradeEvidenceStatement | undefined,
|
|
550
|
+
matches: readonly TransformMatch[],
|
|
551
|
+
): ProvenTransform[] {
|
|
552
|
+
if (statement?.verdict !== "plan-proven") return [];
|
|
553
|
+
const seen = new Set<string>();
|
|
554
|
+
const out: ProvenTransform[] = [];
|
|
555
|
+
for (const m of matches) {
|
|
556
|
+
if (m.needs_human) continue;
|
|
557
|
+
// A provider-block setting matches unconditionally — there is no config to
|
|
558
|
+
// confirm it against — so counting it as proven would inflate its fleet
|
|
559
|
+
// counter with every repo that never used the setting at all.
|
|
560
|
+
if (m.entry.kind === "provider_setting") continue;
|
|
561
|
+
// An entry the installed schema did not corroborate must not become fleet
|
|
562
|
+
// evidence. `unverified` is the honest "we could not check this"; promoting
|
|
563
|
+
// it to a proven counter would launder the doubt away.
|
|
564
|
+
if (
|
|
565
|
+
m.schema_agreement === "unverified" &&
|
|
566
|
+
m.entry.kind !== "resource_renamed"
|
|
567
|
+
)
|
|
568
|
+
continue;
|
|
569
|
+
if (seen.has(m.entry.id)) continue;
|
|
570
|
+
seen.add(m.entry.id);
|
|
571
|
+
// Coordinates come from the match's OWN pack, not the statement's. A repo
|
|
572
|
+
// mid-upgrade on two providers records the intent for the primary pack
|
|
573
|
+
// only, so stamping every match with those majors filed cloudflare
|
|
574
|
+
// migrations in the org's table as `azurerm` 3→4.
|
|
575
|
+
out.push({
|
|
576
|
+
transform_id: m.entry.id,
|
|
577
|
+
provider: m.provider,
|
|
578
|
+
from_major: m.from_major,
|
|
579
|
+
to_major: m.to_major,
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
return out;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/** Index a fleet library by transform id for O(1) lookup while rendering. */
|
|
586
|
+
export function indexProvenTransforms(
|
|
587
|
+
library: readonly ProvenTransform[],
|
|
588
|
+
): Map<string, ProvenTransform> {
|
|
589
|
+
const byId = new Map<string, ProvenTransform>();
|
|
590
|
+
for (const p of library) {
|
|
591
|
+
if (!byId.has(p.transform_id)) byId.set(p.transform_id, p);
|
|
592
|
+
}
|
|
593
|
+
return byId;
|
|
594
|
+
}
|