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,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-language IaC support for the READ-ONLY surfaces (Assess / SARIF /
|
|
3
|
+
* evidence). One honest principle throughout: **breadth never dilutes the moat**
|
|
4
|
+
* — trivy and checkov already parse these formats, so Assess widens to them, but
|
|
5
|
+
* Remediate stays Terraform-first (the `✗→✓` proof + equivalence machinery is
|
|
6
|
+
* Terraform-specific and is never faked for other formats; `terraform_scan` and
|
|
7
|
+
* the fix loop keep their Terraform-only filter).
|
|
8
|
+
*
|
|
9
|
+
* Everything here is verified against the scanners' actual support matrices
|
|
10
|
+
* (checkov 3.3.x `--framework` values; trivy 0.7x `--misconfig-scanners`), and
|
|
11
|
+
* the matrix below records per-language coverage HONESTLY — including what is
|
|
12
|
+
* NOT scannable (Pulumi programs have no credible static scanner: checkov never
|
|
13
|
+
* shipped one, trivy has none, and `pulumi preview` requires the engine + a
|
|
14
|
+
* backend). A detected-but-unscannable language is REPORTED as such, never
|
|
15
|
+
* silently dropped and never given fabricated findings.
|
|
16
|
+
*/
|
|
17
|
+
export declare const IAC_LANGUAGES: readonly ["terraform", "cloudformation", "kubernetes", "helm", "kustomize", "dockerfile", "arm", "bicep", "serverless", "ansible", "pulumi"];
|
|
18
|
+
export type IacLanguage = (typeof IAC_LANGUAGES)[number];
|
|
19
|
+
export declare const LANGUAGE_LABEL: Record<IacLanguage, string>;
|
|
20
|
+
/**
|
|
21
|
+
* Which of the two multi-format scanners genuinely covers each language, with
|
|
22
|
+
* the caveat an operator must know. This is the single source of the honesty
|
|
23
|
+
* notes the scorecard prints — a language whose only covering scanner didn't
|
|
24
|
+
* run is a COVERAGE GAP, not a pass, and a language neither covers is reported
|
|
25
|
+
* `unsupported`, never scanned-and-silent.
|
|
26
|
+
*/
|
|
27
|
+
export declare const LANGUAGE_COVERAGE: Record<IacLanguage, {
|
|
28
|
+
trivy: boolean;
|
|
29
|
+
checkov: boolean;
|
|
30
|
+
note?: string;
|
|
31
|
+
}>;
|
|
32
|
+
/** The checkov `--framework` list for a scanned-language set (sorted, deduped).
|
|
33
|
+
* Always includes terraform so the scanner invocation can never regress the
|
|
34
|
+
* core product even on an empty/odd scope. Pure. */
|
|
35
|
+
export declare function checkovFrameworksFor(scanned: readonly IacLanguage[]): string[];
|
|
36
|
+
/** Map a trivy result `Type` to a language; null for types we don't model. Pure. */
|
|
37
|
+
export declare function trivyTypeToLanguage(type: string | undefined): IacLanguage | null;
|
|
38
|
+
/** Map a checkov block `check_type` to a language; null for types we don't model. Pure. */
|
|
39
|
+
export declare function checkovTypeToLanguage(checkType: string | undefined): IacLanguage | null;
|
|
40
|
+
/**
|
|
41
|
+
* Classify a file by path alone (no content). Returns the language, or
|
|
42
|
+
* "needs-content" for yaml/json whose kind is only knowable by sniffing, or null
|
|
43
|
+
* for a file that is no IaC we model. Pure.
|
|
44
|
+
*/
|
|
45
|
+
export declare function classifyByPath(path: string): IacLanguage | "needs-content" | null;
|
|
46
|
+
/**
|
|
47
|
+
* Classify a yaml/json file by its content (first few KB). Conservative: only
|
|
48
|
+
* unmistakable markers classify; anything ambiguous returns null (better to
|
|
49
|
+
* under-detect than to claim coverage of a file no scanner will read). Pure.
|
|
50
|
+
*/
|
|
51
|
+
export declare function classifyByContent(path: string, content: string): IacLanguage | null;
|
|
52
|
+
/**
|
|
53
|
+
* The language a concern belongs to, for scope filtering: the scanner-reported
|
|
54
|
+
* language when present, else a path-only classification (fmt/validate/tflint
|
|
55
|
+
* only ever fire on Terraform), else terraform (the historical default — a
|
|
56
|
+
* reviewer-loaded concern with an unknowable file stays in the core scope
|
|
57
|
+
* rather than vanishing). Pure.
|
|
58
|
+
*/
|
|
59
|
+
export declare function languageOfConcern(c: {
|
|
60
|
+
language?: IacLanguage | undefined;
|
|
61
|
+
location: {
|
|
62
|
+
file: string;
|
|
63
|
+
};
|
|
64
|
+
}): IacLanguage;
|
|
65
|
+
export interface DetectedLanguages {
|
|
66
|
+
/** every language present in the tree, most files first. */
|
|
67
|
+
detected: IacLanguage[];
|
|
68
|
+
/** file count per detected language (the scorecard's breadth line). */
|
|
69
|
+
fileCounts: Partial<Record<IacLanguage, number>>;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Walk the workspace and detect which IaC languages are present. Bounded (depth
|
|
73
|
+
* + file cap + skip dirs) and read-only; yaml/json files are sniffed from their
|
|
74
|
+
* first bytes only. Terraform is detected by extension; everything else by
|
|
75
|
+
* basename or unmistakable content markers. Pure-ish (read-only I/O).
|
|
76
|
+
*/
|
|
77
|
+
export declare function detectIacLanguages(cwd: string): DetectedLanguages;
|
|
78
|
+
export interface LanguageScope {
|
|
79
|
+
/** the languages this run's read-only surfaces report on (scope ∩ scannable). */
|
|
80
|
+
scanned: IacLanguage[];
|
|
81
|
+
/** every language detected in the tree (superset of scanned + unsupported). */
|
|
82
|
+
detected: IacLanguage[];
|
|
83
|
+
fileCounts: Partial<Record<IacLanguage, number>>;
|
|
84
|
+
/** detected languages NO installed scanner can statically assess — surfaced,
|
|
85
|
+
* never silently dropped (e.g. pulumi). */
|
|
86
|
+
unsupported: {
|
|
87
|
+
language: IacLanguage;
|
|
88
|
+
reason: string;
|
|
89
|
+
}[];
|
|
90
|
+
/** iac_languages tokens that matched no known language (operator typo). */
|
|
91
|
+
unknown_tokens: string[];
|
|
92
|
+
}
|
|
93
|
+
/** membership test for the scope filter (terraform is always in scope). */
|
|
94
|
+
export declare function inLanguageScope(scope: Pick<LanguageScope, "scanned">): (c: {
|
|
95
|
+
language?: IacLanguage | undefined;
|
|
96
|
+
location: {
|
|
97
|
+
file: string;
|
|
98
|
+
};
|
|
99
|
+
}) => boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Resolve the operator's `iac_languages` setting against what the tree actually
|
|
102
|
+
* contains. `auto` (the default) scans every detected language a scanner can
|
|
103
|
+
* read; `terraform` restores the historical Terraform-only behaviour; a comma
|
|
104
|
+
* list pins an explicit set (terraform is always included — the core product is
|
|
105
|
+
* never configured away). Detected-but-unscannable languages land in
|
|
106
|
+
* `unsupported` with the honest reason. Pure given the detection result.
|
|
107
|
+
*/
|
|
108
|
+
export declare function resolveLanguageScope(raw: string | undefined, detection: DetectedLanguages): LanguageScope;
|
|
109
|
+
/**
|
|
110
|
+
* Enforce the matrix's own honesty rule AGAINST the run's actual scanner
|
|
111
|
+
* outcomes: a language whose every covering scanner was skipped/disabled this
|
|
112
|
+
* run (e.g. `tools_enabled: "-checkov"` on a Bicep repo — Bicep is checkov-only)
|
|
113
|
+
* moves from `scanned` to `unsupported` with the reason, instead of being
|
|
114
|
+
* reported as scanned-clean-with-zero-findings. Terraform always stays: the
|
|
115
|
+
* native toolchain (fmt/validate/tflint) covers it regardless of trivy/checkov.
|
|
116
|
+
*/
|
|
117
|
+
export declare function applyScannerAvailability(scope: LanguageScope, ran: {
|
|
118
|
+
trivy: boolean;
|
|
119
|
+
checkov: boolean;
|
|
120
|
+
}): LanguageScope;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { TfResourceEntry } from "#app/mcp/terraform/cspm";
|
|
2
|
+
/**
|
|
3
|
+
* Idle-floor detection (§5.19) — the resources that cost money at ZERO traffic.
|
|
4
|
+
*
|
|
5
|
+
* WHY THIS AND NOT A TOTAL. The hard part of plan-based cost estimation is not
|
|
6
|
+
* the pricing API, it is that usage-dependent lines (GB, requests, egress) are
|
|
7
|
+
* simply NOT derivable from Terraform. Any tool publishing a precise monthly
|
|
8
|
+
* total from a plan is guessing at the usage half. The idle floor is the portion
|
|
9
|
+
* that is deterministic — true regardless of traffic — so it is both the most
|
|
10
|
+
* defensible number we can publish and the most actionable one: an App Service
|
|
11
|
+
* Premium plan or an Azure Firewall bills the same whether or not anyone calls it.
|
|
12
|
+
*
|
|
13
|
+
* CREDENTIAL-FREE AND OFFLINE. Prices come from the bundled snapshot
|
|
14
|
+
* (`azurePrices.ts`, public Azure list prices captured at build time), so a scan
|
|
15
|
+
* makes no network call and needs no cloud credentials or pricing API key.
|
|
16
|
+
*
|
|
17
|
+
* FLOOR SEMANTICS — WE UNDER-CLAIM ON PURPOSE, AND NEVER GUESS A TIER. A
|
|
18
|
+
* resource is priced ONLY when its tier is identifiable from source AND is one
|
|
19
|
+
* this catalog carries. There is deliberately NO cheapest-tier fallback: every
|
|
20
|
+
* one of these resource types has a cheap or free tier (App Service `F1`/`B1`,
|
|
21
|
+
* Bastion `Developer`, a Basic VPN gateway, Basic Redis), so falling back would
|
|
22
|
+
* invent a charge for a resource that may cost nothing — the single failure mode
|
|
23
|
+
* that discredits the whole number. An unidentifiable tier is reported as an
|
|
24
|
+
* explicit coverage gap instead. A floor that is too low is honest; one that is
|
|
25
|
+
* too high is a number the customer can disprove.
|
|
26
|
+
*/
|
|
27
|
+
/** Billable hours per month — the 365×24/12 convention list prices assume. */
|
|
28
|
+
export declare const HOURS_PER_MONTH = 730;
|
|
29
|
+
/** One resource billing at zero traffic. */
|
|
30
|
+
export interface IdleFloorItem {
|
|
31
|
+
/** `type.name` of the Terraform resource. */
|
|
32
|
+
address: string;
|
|
33
|
+
resourceType: string;
|
|
34
|
+
file: string;
|
|
35
|
+
line: number;
|
|
36
|
+
/** The rule that fired. */
|
|
37
|
+
rule_id: string;
|
|
38
|
+
why: string;
|
|
39
|
+
/** Meter key resolved from the bundled snapshot. */
|
|
40
|
+
meter: string;
|
|
41
|
+
monthly_cost: number;
|
|
42
|
+
}
|
|
43
|
+
/** A catalogued resource type whose tier could not be identified, so it was not
|
|
44
|
+
* priced. Reported so the floor states exactly what it left out. */
|
|
45
|
+
export interface UnpricedResource {
|
|
46
|
+
address: string;
|
|
47
|
+
resourceType: string;
|
|
48
|
+
file: string;
|
|
49
|
+
line: number;
|
|
50
|
+
reason: string;
|
|
51
|
+
}
|
|
52
|
+
export interface IdleFloorReport {
|
|
53
|
+
currency: string;
|
|
54
|
+
region: string;
|
|
55
|
+
/** ISO date the bundled price snapshot was captured. */
|
|
56
|
+
priced_at: string;
|
|
57
|
+
items: IdleFloorItem[];
|
|
58
|
+
/** Sum of every item's monthly cost, rounded to cents. */
|
|
59
|
+
monthly_floor: number;
|
|
60
|
+
/** Catalogued resources left unpriced because their tier wasn't identifiable —
|
|
61
|
+
* the floor is a lower bound by exactly these. */
|
|
62
|
+
unpriced: UnpricedResource[];
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Detect every resource that bills at zero traffic, priced from the bundled
|
|
66
|
+
* snapshot. Pure and deterministic — no fs, no network, no credentials. Items
|
|
67
|
+
* come back in source order (file, then line) so `cost.md` is diff-stable.
|
|
68
|
+
*/
|
|
69
|
+
export declare function detectIdleFloor(resources: ReadonlyArray<TfResourceEntry>): IdleFloorReport;
|
|
70
|
+
/** What the idle-floor number does and does not assert — carried verbatim into
|
|
71
|
+
* `cost.md` and the signed evidence bundle so the claim can never drift. */
|
|
72
|
+
export declare const IDLE_FLOOR_ASSERTS: string;
|
|
73
|
+
export declare const IDLE_FLOOR_DOES_NOT_ASSERT: string;
|
|
74
|
+
/**
|
|
75
|
+
* Render the `cost.md` artifact. Pure and deterministic — the same report always
|
|
76
|
+
* produces the same bytes, so re-running on an unchanged plan yields no diff.
|
|
77
|
+
*/
|
|
78
|
+
export declare function renderCostMarkdown(report: IdleFloorReport, toolVersion: string): string;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KEYLESS (Sigstore) signing — the SECOND evidence tier, alongside the Ed25519
|
|
3
|
+
* detached signature in [[signing]].
|
|
4
|
+
*
|
|
5
|
+
* Where the Ed25519 tier proves "signed by whoever holds INFRAWEAVER_SIGNING_KEY"
|
|
6
|
+
* (and needs that key distributed to verifiers), the keyless tier signs with the
|
|
7
|
+
* workflow's ephemeral GitHub Actions OIDC identity: Fulcio issues a short-lived
|
|
8
|
+
* X.509 cert bound to "this repo, this workflow, this run", the signature +
|
|
9
|
+
* cert + an inclusion proof go into a Sigstore **bundle**, and the signing event
|
|
10
|
+
* is recorded in the public **Rekor** transparency log. There is no key to
|
|
11
|
+
* distribute — a verifier checks the CERTIFICATE IDENTITY (the workflow ref +
|
|
12
|
+
* the GitHub OIDC issuer), not a pinned fingerprint. That converts the
|
|
13
|
+
* fingerprint-pinning problem into a certificate-identity check.
|
|
14
|
+
*
|
|
15
|
+
* The signed payload is an in-toto v1 attestation whose `subject` is the evidence
|
|
16
|
+
* artifact (by sha256 digest) and whose `predicate` is a compact summary — the
|
|
17
|
+
* same shape that slots into a CycloneDX/VEX attestation pipeline.
|
|
18
|
+
*
|
|
19
|
+
* OPT-IN + best-effort: enabled by `INFRAWEAVER_KEYLESS_SIGNING=true` and only when
|
|
20
|
+
* an ambient OIDC identity was captured (CI with `id-token: write`). It performs
|
|
21
|
+
* live network calls to Fulcio + Rekor, so a failure is logged and the emit still
|
|
22
|
+
* succeeds with the deterministic bundle + optional Ed25519 `.sig` — a transient
|
|
23
|
+
* Rekor outage must not block emitting evidence.
|
|
24
|
+
*/
|
|
25
|
+
import { type SerializedBundle } from "@sigstore/bundle";
|
|
26
|
+
export declare const KEYLESS_SIGNING_ENV = "INFRAWEAVER_KEYLESS_SIGNING";
|
|
27
|
+
/** The in-toto predicateType for a Infraweaver evidence attestation. */
|
|
28
|
+
export declare const INFRAWEAVER_ATTESTATION_PREDICATE_TYPE: "https://infraweaver.dev/attestations/evidence/v1";
|
|
29
|
+
/** in-toto Statement v1 — what actually gets DSSE-signed. */
|
|
30
|
+
export interface InTotoStatement {
|
|
31
|
+
_type: "https://in-toto.io/Statement/v1";
|
|
32
|
+
subject: Array<{
|
|
33
|
+
name: string;
|
|
34
|
+
digest: {
|
|
35
|
+
sha256: string;
|
|
36
|
+
};
|
|
37
|
+
}>;
|
|
38
|
+
predicateType: string;
|
|
39
|
+
predicate: Record<string, unknown>;
|
|
40
|
+
}
|
|
41
|
+
/** Opt-in check — keyless signing performs live Fulcio/Rekor calls, so it never
|
|
42
|
+
* runs unless explicitly enabled. Distinct from {@link keylessSigningPossible}. */
|
|
43
|
+
export declare function keylessSigningEnabled(env?: NodeJS.ProcessEnv): boolean;
|
|
44
|
+
/** True when keyless signing is both enabled AND an ambient OIDC identity was
|
|
45
|
+
* captured (running in CI with id-token:write). The emit tools gate on this. */
|
|
46
|
+
export declare function keylessSigningPossible(env?: NodeJS.ProcessEnv): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Build the in-toto v1 Statement that attests `artifactBytes` by sha256 digest.
|
|
49
|
+
* Pure — the signable payload, independent of any network. The predicate carries
|
|
50
|
+
* a compact, non-authoritative summary (the artifact itself is the authority; the
|
|
51
|
+
* attestation binds it to the workflow identity).
|
|
52
|
+
*/
|
|
53
|
+
export declare function buildInTotoStatement(args: {
|
|
54
|
+
subjectName: string;
|
|
55
|
+
artifactBytes: string | Buffer;
|
|
56
|
+
predicate: Record<string, unknown>;
|
|
57
|
+
predicateType?: string;
|
|
58
|
+
}): InTotoStatement;
|
|
59
|
+
/** The sibling filename the Sigstore bundle is written to, next to `artifactPath`. */
|
|
60
|
+
export declare function keylessBundlePath(artifactPath: string): string;
|
|
61
|
+
/**
|
|
62
|
+
* Keyless-sign an in-toto statement: mint a `sigstore`-audience OIDC token, get a
|
|
63
|
+
* short-lived Fulcio signing cert for it, DSSE-sign the statement, and record the
|
|
64
|
+
* entry in Rekor. Returns the serialized Sigstore bundle (write it as
|
|
65
|
+
* `<artifact>.sigstore.json`). NETWORK — Fulcio + Rekor. Throws on any failure;
|
|
66
|
+
* callers treat keyless as best-effort and log rather than abort the emit.
|
|
67
|
+
*/
|
|
68
|
+
export declare function keylessSignStatement(statement: InTotoStatement): Promise<SerializedBundle>;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { LocalToolContext } from "#app/mcp/localContext";
|
|
2
|
+
import { type ModuleInterface } from "#app/mcp/modules";
|
|
3
|
+
export type ModuleDocsVerdict = "equivalence-proven" | "equivalence-failed" | "proposed-unproven";
|
|
4
|
+
export interface ModuleDocsRefactorInput {
|
|
5
|
+
/** every relocated address, `from → to` — from terraform_generate_moved. */
|
|
6
|
+
moves: {
|
|
7
|
+
from: string;
|
|
8
|
+
to: string;
|
|
9
|
+
}[];
|
|
10
|
+
/** worded exactly as the evidence layer's refactor statement. */
|
|
11
|
+
verdict: ModuleDocsVerdict;
|
|
12
|
+
}
|
|
13
|
+
export interface ModuleDocsInput {
|
|
14
|
+
/** repo-relative module dir, e.g. `modules/logging`. */
|
|
15
|
+
moduleDir: string;
|
|
16
|
+
iface: ModuleInterface;
|
|
17
|
+
/** present only for a refactor run (omits the section entirely otherwise). */
|
|
18
|
+
refactor?: ModuleDocsRefactorInput | undefined;
|
|
19
|
+
version?: string;
|
|
20
|
+
/** the repo HEAD the doc was generated at (footer metadata; drives the
|
|
21
|
+
* incremental refresh). null when git is unavailable. */
|
|
22
|
+
gitHead: string | null;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Build the README from tool outputs only (pure — same inputs, same bytes).
|
|
26
|
+
* No prose is invented: descriptions come verbatim from the HCL or stay empty.
|
|
27
|
+
*/
|
|
28
|
+
export declare function buildModuleReadme(input: ModuleDocsInput): string;
|
|
29
|
+
/** the `git-head` recorded in an existing generated README's footer, or null
|
|
30
|
+
* (no README / not infraweaver-generated / no head recorded). */
|
|
31
|
+
export declare function readFooterGitHead(readme: string | null): string | null;
|
|
32
|
+
export declare const TerraformModuleDocsParams: import("arktype/internal/variants/object.ts").ObjectType<{
|
|
33
|
+
module_dir: string;
|
|
34
|
+
moves?: {
|
|
35
|
+
from: string;
|
|
36
|
+
to: string;
|
|
37
|
+
}[];
|
|
38
|
+
proposed_unproven?: boolean;
|
|
39
|
+
}, {}>;
|
|
40
|
+
export declare function TerraformModuleDocsTool(ctx: LocalToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<{
|
|
41
|
+
module_dir: string;
|
|
42
|
+
moves?: {
|
|
43
|
+
from: string;
|
|
44
|
+
to: string;
|
|
45
|
+
}[];
|
|
46
|
+
proposed_unproven?: boolean;
|
|
47
|
+
}, {
|
|
48
|
+
module_dir: string;
|
|
49
|
+
moves?: {
|
|
50
|
+
from: string;
|
|
51
|
+
to: string;
|
|
52
|
+
}[];
|
|
53
|
+
proposed_unproven?: boolean;
|
|
54
|
+
}>> & {
|
|
55
|
+
mutates?: boolean;
|
|
56
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Concern, Severity } from "#app/mcp/terraform/types";
|
|
2
|
+
/** The `Concern.source` every native rule carries. Equal to the emitted-artifact
|
|
3
|
+
* wordmark, so a SARIF report we produce round-trips back through
|
|
4
|
+
* `read_findings` as native (not `reviewer`) and stays ✗→✓ verifiable. */
|
|
5
|
+
export declare const NATIVE_SOURCE = "infraweaver";
|
|
6
|
+
/** What a rule's finding is allowed to claim. See the module note. */
|
|
7
|
+
export type NativeBand = "verified" | "review-required" | "advisory";
|
|
8
|
+
export interface NativeRule {
|
|
9
|
+
/** bare rule id — the `rule_id` is `infraweaver:<id>` and the content hash uses
|
|
10
|
+
* this bare form (see `buildConcern`). */
|
|
11
|
+
id: string;
|
|
12
|
+
title: string;
|
|
13
|
+
band: NativeBand;
|
|
14
|
+
category: Concern["category"];
|
|
15
|
+
/** the precise claim the finding makes. Copied into evidence/docs verbatim so
|
|
16
|
+
* the report and the code can never drift apart. */
|
|
17
|
+
asserts: string;
|
|
18
|
+
/** the claim a reader might infer that this rule explicitly does NOT make. */
|
|
19
|
+
doesNotAssert: string;
|
|
20
|
+
}
|
|
21
|
+
export declare const SECRET_PERSISTED_TO_STATE = "secret-persisted-to-state";
|
|
22
|
+
export declare const IMPERATIVE_ACTION_TRIGGER = "imperative-action-trigger";
|
|
23
|
+
export declare const DYNAMIC_DESTROY_PROTECTION = "dynamic-destroy-protection";
|
|
24
|
+
export declare const DEPRECATED_STATE_LOCKING = "deprecated-state-locking";
|
|
25
|
+
export declare const NATIVE_RULES: readonly NativeRule[];
|
|
26
|
+
/**
|
|
27
|
+
* The native rule a concern belongs to, or null when it isn't one of ours.
|
|
28
|
+
* Accepts both the namespaced `infraweaver:<id>` and the bare `<id>` form so it
|
|
29
|
+
* works on a concern before and after `buildConcern` namespaces it.
|
|
30
|
+
*/
|
|
31
|
+
export declare function nativeRuleOf(ruleId: string): NativeRule | null;
|
|
32
|
+
/** The severity floor a band implies. A rule may report HIGHER than its floor for
|
|
33
|
+
* a worse instance (a hardcoded literal secret beats a referenced one), but a
|
|
34
|
+
* non-`verified` band can never present as a critical/high violation — that is
|
|
35
|
+
* the loudness a code-verified `fail` has earned and these have not. */
|
|
36
|
+
export declare const BAND_SEVERITY: Record<NativeBand, Severity>;
|
|
37
|
+
/** The reason text a non-`verified` band carries into the five-status verdict. */
|
|
38
|
+
export declare function bandVerdictReason(rule: NativeRule): string | null;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ScannerOutcome } from "#app/mcp/terraform/types";
|
|
2
|
+
/**
|
|
3
|
+
* Run the native pack over `cwd`.
|
|
4
|
+
*
|
|
5
|
+
* `ran` is always true: the governance rules need nothing but the source text, so
|
|
6
|
+
* the pack itself never fails to run. When the persisted-secret half could not
|
|
7
|
+
* run (no provider schema) that is reported through `partial` — a coverage gap
|
|
8
|
+
* the verification summary surfaces as INCONCLUSIVE, rather than being folded
|
|
9
|
+
* into a silent "the native pack found nothing".
|
|
10
|
+
*/
|
|
11
|
+
export declare function scanNative(cwd: string): ScannerOutcome;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* G7 — the noise-reduction learning loop.
|
|
3
|
+
*
|
|
4
|
+
* WHAT IT LEARNS FROM. Every time an org waives a rule it records a decision: a
|
|
5
|
+
* `rule`, a human `reason`, and (since the two-person gate) who proposed and who
|
|
6
|
+
* ratified it. When the SAME rule has been waived independently across several
|
|
7
|
+
* repos in a fleet, that is no longer a per-repo judgement — it is the org
|
|
8
|
+
* telling us, in writing and with reasons, that this finding type is noise for
|
|
9
|
+
* them. This module turns that record into a **surfacing** signal.
|
|
10
|
+
*
|
|
11
|
+
* WHAT IT IS NOT. Not suppression, and the distinction is the whole design:
|
|
12
|
+
*
|
|
13
|
+
* - A down-ranked finding is still **reported**, still **gates CI**, still
|
|
14
|
+
* appears in the **signed evidence** with an unchanged verdict. Only its
|
|
15
|
+
* position in "the top N that matter" moves.
|
|
16
|
+
* - The concern's `severity`, `category`, band and assessability are never
|
|
17
|
+
* touched. Nothing derived from a scanner's judgement is rewritten.
|
|
18
|
+
* - It applies to nothing at `critical` or `high`. A repeatedly-waived
|
|
19
|
+
* critical is a governance problem that should get LOUDER, not quieter, and
|
|
20
|
+
* an attacker who can get a rule waived across a fleet must not thereby be
|
|
21
|
+
* able to bury it.
|
|
22
|
+
*
|
|
23
|
+
* A ranking model that could hide a finding would be a liability in an evidence
|
|
24
|
+
* product; one that can only reorder the low-severity tail is a genuine
|
|
25
|
+
* ergonomic win with no honesty cost.
|
|
26
|
+
*
|
|
27
|
+
* WHY A THRESHOLD. One waiver is a decision, not a pattern — a single repo
|
|
28
|
+
* silencing a rule says nothing about the fleet. The signal needs
|
|
29
|
+
* {@link MIN_DISMISSAL_REPOS} *distinct repos*, counted per repo rather than
|
|
30
|
+
* per policy so that one repo with five overlapping path-scoped waivers cannot
|
|
31
|
+
* masquerade as five repos agreeing.
|
|
32
|
+
*
|
|
33
|
+
* ALWAYS REASON-LOGGED. An adjustment carries the repo count and the actual
|
|
34
|
+
* human reasons, and the scan output surfaces them next to the finding. A
|
|
35
|
+
* ranking that quietly demotes things is indistinguishable from a bug; one that
|
|
36
|
+
* says "ranked lower: 4 repos waived this — 'managed by the platform team'" is
|
|
37
|
+
* reviewable, and can be argued with.
|
|
38
|
+
*
|
|
39
|
+
* Pure. The profile arrives from Cloud over run-context as an untrusted blob
|
|
40
|
+
* (same shape and trust posture as §5.12's proven-fix library) and is coerced
|
|
41
|
+
* here before anything reads it.
|
|
42
|
+
*/
|
|
43
|
+
import type { Concern } from "#app/mcp/terraform/types";
|
|
44
|
+
/** Distinct repos that must have waived a rule before it is treated as fleet
|
|
45
|
+
* noise rather than one team's decision. */
|
|
46
|
+
export declare const MIN_DISMISSAL_REPOS = 3;
|
|
47
|
+
/** The largest amount a score may be reduced, and the floor it may not cross.
|
|
48
|
+
* Bounded so a down-rank reorders the tail rather than deleting a finding from
|
|
49
|
+
* practical view: a heavily-waived medium still outranks an untouched info. */
|
|
50
|
+
export declare const MAX_NOISE_PENALTY = 1.5;
|
|
51
|
+
export declare const NOISE_SCORE_FLOOR = 1;
|
|
52
|
+
/** One rule's dismissal history across an org's fleet. */
|
|
53
|
+
export interface NoiseEntry {
|
|
54
|
+
/** the waived rule id, exactly as the org recorded it. */
|
|
55
|
+
rule: string;
|
|
56
|
+
/** DISTINCT repos that have waived it — never a raw policy count. */
|
|
57
|
+
repos: number;
|
|
58
|
+
/** the human reasons given, deduped, in the order Cloud returned them. */
|
|
59
|
+
reasons: string[];
|
|
60
|
+
}
|
|
61
|
+
/** The org's fleet-wide dismissal record, keyed by rule id. */
|
|
62
|
+
export type NoiseProfile = ReadonlyMap<string, NoiseEntry>;
|
|
63
|
+
export declare const EMPTY_NOISE_PROFILE: NoiseProfile;
|
|
64
|
+
/**
|
|
65
|
+
* Coerce the untrusted run-context blob into a {@link NoiseProfile}.
|
|
66
|
+
*
|
|
67
|
+
* Every field is validated and anything malformed is dropped rather than
|
|
68
|
+
* defaulted: this data reorders a security report, so a blob that is not
|
|
69
|
+
* recognisably a dismissal record must produce NO adjustment instead of a
|
|
70
|
+
* plausible-looking one. Mirrors `fixMemory.coerceLibrary`.
|
|
71
|
+
*/
|
|
72
|
+
export declare function coerceNoiseProfile(raw: unknown): NoiseProfile;
|
|
73
|
+
/** A ranking adjustment, with the evidence for it. Never produced silently. */
|
|
74
|
+
export interface NoiseAdjustment {
|
|
75
|
+
/** how much the risk score was reduced (positive, ≤ {@link MAX_NOISE_PENALTY}). */
|
|
76
|
+
penalty: number;
|
|
77
|
+
/** distinct repos in the org that waived this rule. */
|
|
78
|
+
repos: number;
|
|
79
|
+
/** the human reasons they gave, truncated to {@link MAX_REASONS_SURFACED}. */
|
|
80
|
+
reasons: string[];
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* The adjustment for one concern, or null when none applies.
|
|
84
|
+
*
|
|
85
|
+
* Returns null — rather than a zero penalty — when the rule is unknown, below
|
|
86
|
+
* the threshold, or protected by severity, so a caller cannot accidentally
|
|
87
|
+
* report "adjusted by 0" as if a judgement had been made.
|
|
88
|
+
*/
|
|
89
|
+
export declare function noiseAdjustmentFor(concern: Pick<Concern, "rule_id" | "severity">, profile: NoiseProfile): NoiseAdjustment | null;
|
|
90
|
+
/**
|
|
91
|
+
* Apply an adjustment to a risk score, clamped to {@link NOISE_SCORE_FLOOR}.
|
|
92
|
+
*
|
|
93
|
+
* The floor is what keeps this a re-ordering rather than a disappearance: a
|
|
94
|
+
* finding can be pushed down the list but never to zero, because zero reads as
|
|
95
|
+
* "nothing here" and something is definitely here.
|
|
96
|
+
*/
|
|
97
|
+
export declare function applyNoisePenalty(score: number, adjustment: NoiseAdjustment | null): number;
|
|
98
|
+
/** One line explaining an adjustment, for the report. Deliberately states the
|
|
99
|
+
* bound as well as the reason — a reader must not infer that we hid anything. */
|
|
100
|
+
export declare function explainNoiseAdjustment(adjustment: NoiseAdjustment): string;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Idiomatic-normalisation DETECTION — the Refactor verb's companion to
|
|
3
|
+
* moduleExtraction.ts. Module extraction lifts raw resources behind a boundary;
|
|
4
|
+
* this finds the OTHER provably-equivalent refactor: in-place idiomatic cleanup of
|
|
5
|
+
* legacy HCL that changes STRUCTURE/SYNTAX but not behaviour, so a repo that is
|
|
6
|
+
* already modular but stylistically dated still has a real refactor to ship.
|
|
7
|
+
*
|
|
8
|
+
* Every kind here is a no-op the keys-free equivalence check proves: the resource
|
|
9
|
+
* set and per-resource argument NAMES are untouched, addresses don't move (zero
|
|
10
|
+
* `moved {}` needed), and `terraform validate` + `fmt` stay clean. That is the hard
|
|
11
|
+
* boundary — anything that changes a resource TYPE or the managed-resource set
|
|
12
|
+
* (e.g. `aws_launch_configuration`→`aws_launch_template`, `aws_elb`→`aws_lb`) is
|
|
13
|
+
* behaviour-ALTERING modernisation and belongs to Remediate, NOT here; the
|
|
14
|
+
* equivalence check would reject it as a resource-set diff anyway.
|
|
15
|
+
*
|
|
16
|
+
* Pure parsing over files already on disk — no subprocess, no network — mirroring
|
|
17
|
+
* moduleExtraction.ts.
|
|
18
|
+
*/
|
|
19
|
+
import type { LocalToolContext } from "#app/mcp/localContext";
|
|
20
|
+
export type NormalizationKind = "redundant_interpolation" | "legacy_block_assignment";
|
|
21
|
+
export interface NormalizationSite {
|
|
22
|
+
kind: NormalizationKind;
|
|
23
|
+
/** 1-based line of the offending snippet. */
|
|
24
|
+
line: number;
|
|
25
|
+
/** the snippet as written. */
|
|
26
|
+
before: string;
|
|
27
|
+
/** the idiomatic, behaviour-identical rewrite (advisory — the agent writes the edit). */
|
|
28
|
+
after: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Find every string literal that is EXACTLY one full-span interpolation
|
|
32
|
+
* (`"${ expr }"`), where dropping the wrapper to a bare `expr` is a behaviour-
|
|
33
|
+
* identical HCL2 rewrite (the canonical 0.11→0.12 cleanup). Skips comments and
|
|
34
|
+
* heredocs, and naturally excludes `"$${literal}"` (an escaped, non-interpolated
|
|
35
|
+
* `${`) and partial templates like `"${a}-${b}"` (where the quotes are load-bearing).
|
|
36
|
+
*/
|
|
37
|
+
export declare function findRedundantInterpolations(hcl: string): NormalizationSite[];
|
|
38
|
+
export declare function findLegacyBlockAssignments(hcl: string): NormalizationSite[];
|
|
39
|
+
/** every normalisation site in one file, in line order. */
|
|
40
|
+
export declare function scanNormalizations(hcl: string): NormalizationSite[];
|
|
41
|
+
export interface NormalizationFile {
|
|
42
|
+
file: string;
|
|
43
|
+
count: number;
|
|
44
|
+
kind_counts: Record<NormalizationKind, number>;
|
|
45
|
+
/** a capped sample of the actual sites, for the agent to anchor its edits. */
|
|
46
|
+
sites: NormalizationSite[];
|
|
47
|
+
}
|
|
48
|
+
export declare function findNormalizationCandidates(cwd: string): NormalizationFile[];
|
|
49
|
+
export declare const NormalizationCandidatesParams: import("arktype/internal/variants/object.ts").ObjectType<object, {}>;
|
|
50
|
+
export declare function NormalizationCandidatesTool(ctx: LocalToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<object, object>> & {
|
|
51
|
+
mutates?: boolean;
|
|
52
|
+
};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { type AssessmentScorecard } from "#app/mcp/assess";
|
|
2
|
+
import type { CrosswalkReport } from "#app/mcp/crosswalk";
|
|
3
|
+
import type { LocalToolContext } from "#app/mcp/localContext";
|
|
4
|
+
import type { EvidenceSubject } from "#app/mcp/terraform/evidence";
|
|
5
|
+
export declare const OSCAL_VERSION: "1.1.2";
|
|
6
|
+
interface OscalProp {
|
|
7
|
+
name: string;
|
|
8
|
+
value: string;
|
|
9
|
+
ns?: string;
|
|
10
|
+
}
|
|
11
|
+
interface OscalObservation {
|
|
12
|
+
uuid: string;
|
|
13
|
+
title: string;
|
|
14
|
+
description: string;
|
|
15
|
+
methods: string[];
|
|
16
|
+
collected: string;
|
|
17
|
+
"relevant-evidence"?: {
|
|
18
|
+
description: string;
|
|
19
|
+
}[];
|
|
20
|
+
}
|
|
21
|
+
interface OscalFinding {
|
|
22
|
+
uuid: string;
|
|
23
|
+
title: string;
|
|
24
|
+
description: string;
|
|
25
|
+
target: {
|
|
26
|
+
type: "objective-id";
|
|
27
|
+
"target-id": string;
|
|
28
|
+
status: {
|
|
29
|
+
state: "satisfied" | "not-satisfied";
|
|
30
|
+
reason?: string;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
"related-observations"?: {
|
|
34
|
+
"observation-uuid": string;
|
|
35
|
+
}[];
|
|
36
|
+
props?: OscalProp[];
|
|
37
|
+
}
|
|
38
|
+
export interface OscalAssessmentResults {
|
|
39
|
+
"assessment-results": {
|
|
40
|
+
uuid: string;
|
|
41
|
+
metadata: {
|
|
42
|
+
title: string;
|
|
43
|
+
"last-modified": string;
|
|
44
|
+
version: string;
|
|
45
|
+
"oscal-version": typeof OSCAL_VERSION;
|
|
46
|
+
props: OscalProp[];
|
|
47
|
+
remarks: string;
|
|
48
|
+
};
|
|
49
|
+
"import-ap": {
|
|
50
|
+
href: string;
|
|
51
|
+
remarks: string;
|
|
52
|
+
};
|
|
53
|
+
results: Array<{
|
|
54
|
+
uuid: string;
|
|
55
|
+
title: string;
|
|
56
|
+
description: string;
|
|
57
|
+
start: string;
|
|
58
|
+
"reviewed-controls": {
|
|
59
|
+
"control-selections": Array<{
|
|
60
|
+
"include-controls"?: {
|
|
61
|
+
"control-id": string;
|
|
62
|
+
}[];
|
|
63
|
+
"include-all"?: Record<string, never>;
|
|
64
|
+
}>;
|
|
65
|
+
};
|
|
66
|
+
observations: OscalObservation[];
|
|
67
|
+
findings: OscalFinding[];
|
|
68
|
+
}>;
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/** name-based (v5-shaped) UUID from a seed, so output is reproducible.
|
|
72
|
+
* Shared with the CycloneDX VEX emitter ([[vex]]) — both artefacts keep the
|
|
73
|
+
* pure/deterministic stance of the evidence builder. */
|
|
74
|
+
export declare function deterministicUuid(seed: string): string;
|
|
75
|
+
/**
|
|
76
|
+
* Build a strict OSCAL 1.1.2 Assessment Results document from an assessment's
|
|
77
|
+
* scorecard + crosswalk. Pure (clock/identity passed in). Each crosswalk entry
|
|
78
|
+
* (an open concern) yields one observation and one `not-satisfied` finding per
|
|
79
|
+
* control objective it maps to; the finding's verification status + severity ride
|
|
80
|
+
* as props so an OSCAL consumer keeps the five-status nuance.
|
|
81
|
+
*/
|
|
82
|
+
export declare function buildOscalAssessmentResults(args: {
|
|
83
|
+
scorecard: AssessmentScorecard;
|
|
84
|
+
crosswalk: CrosswalkReport;
|
|
85
|
+
subject: EvidenceSubject;
|
|
86
|
+
generatedAt: string;
|
|
87
|
+
version?: string;
|
|
88
|
+
}): OscalAssessmentResults;
|
|
89
|
+
export declare const DEFAULT_OSCAL_PATH = "compliance/infraweaver-oscal.json";
|
|
90
|
+
export declare const TerraformEmitOscalParams: import("arktype/internal/variants/object.ts").ObjectType<{
|
|
91
|
+
output_path?: string;
|
|
92
|
+
severity_threshold?: "critical" | "high" | "info" | "low" | "medium";
|
|
93
|
+
}, {}>;
|
|
94
|
+
export declare function TerraformEmitOscalTool(ctx: LocalToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<{
|
|
95
|
+
output_path?: string;
|
|
96
|
+
severity_threshold?: "critical" | "high" | "info" | "low" | "medium";
|
|
97
|
+
}, {
|
|
98
|
+
output_path?: string;
|
|
99
|
+
severity_threshold?: "critical" | "high" | "info" | "low" | "medium";
|
|
100
|
+
}>> & {
|
|
101
|
+
mutates?: boolean;
|
|
102
|
+
};
|
|
103
|
+
export {};
|