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,360 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* End-of-run cleanup phases extracted out of `main.ts`. Three shapes:
|
|
3
|
+
*
|
|
4
|
+
* - `persistRunArtifacts`: best-effort post-review cleanup + summary +
|
|
5
|
+
* learnings persistence. Shared by both the success path and the
|
|
6
|
+
* error-catch path; idempotent (each step has its own guard against
|
|
7
|
+
* double-execution).
|
|
8
|
+
*
|
|
9
|
+
* - `finalizeSuccessRun`: success-only — calls `persistRunArtifacts`
|
|
10
|
+
* first, then surfaces harness-side failures in the progress comment,
|
|
11
|
+
* deletes stranded progress comments, writes the GitHub Actions job
|
|
12
|
+
* summary, and emits the structured output marker.
|
|
13
|
+
*
|
|
14
|
+
* - `writeRunErrorOutputs`: error-only — writes the rendered error
|
|
15
|
+
* summary to the Actions summary tab and mirrors it to the PR
|
|
16
|
+
* progress comment. The catch path calls this and then
|
|
17
|
+
* `persistRunArtifacts` separately so the rendered error lands before
|
|
18
|
+
* the persistence calls, in case the latter throw.
|
|
19
|
+
*
|
|
20
|
+
* All three swallow their own non-fatal errors (`log.debug` or empty
|
|
21
|
+
* `catch {}`) so a cleanup failure can't flip an already-decided run
|
|
22
|
+
* outcome.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import { writeFile } from "node:fs/promises";
|
|
26
|
+
import { join } from "node:path";
|
|
27
|
+
import * as core from "@actions/core";
|
|
28
|
+
import type { AgentResult } from "#app/agents/shared";
|
|
29
|
+
import { SARIF_FILE } from "#app/brand";
|
|
30
|
+
import { deleteProgressComment } from "#app/mcp/comment";
|
|
31
|
+
import { requiredControlViolations } from "#app/mcp/crosswalk";
|
|
32
|
+
import type { ToolContext } from "#app/mcp/server";
|
|
33
|
+
import { evaluateGate, loadBaseline } from "#app/mcp/terraform/baseline";
|
|
34
|
+
import { buildSarifReport } from "#app/mcp/terraform/findings";
|
|
35
|
+
import { scanSessionOf } from "#app/mcp/terraform/scanSession";
|
|
36
|
+
import type { ToolState } from "#app/toolState";
|
|
37
|
+
import { buildFindingAnnotations } from "#app/utils/annotations";
|
|
38
|
+
import {
|
|
39
|
+
describeDispatchTally,
|
|
40
|
+
formatDispatchSummary,
|
|
41
|
+
} from "#app/agents/dispatchMetrics";
|
|
42
|
+
import { formatUsageSummary, log, writeSummary } from "#app/utils/cli";
|
|
43
|
+
import { reportToCloud } from "#app/utils/cloudReport";
|
|
44
|
+
import { reportErrorToComment } from "#app/utils/errorReport";
|
|
45
|
+
import { persistLearnings } from "#app/utils/learnings";
|
|
46
|
+
import { persistSummary } from "#app/utils/prSummary";
|
|
47
|
+
import { postReviewCleanup } from "#app/utils/reviewCleanup";
|
|
48
|
+
import {
|
|
49
|
+
type RenderedRunError,
|
|
50
|
+
renderRunError,
|
|
51
|
+
} from "#app/utils/runErrorRenderer";
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Best-effort cleanup shared by both run-end paths:
|
|
55
|
+
* 1. post-review cleanup (dispatch follow-up re-review on submitted reviews)
|
|
56
|
+
* 2. persist the agent-edited PR summary tmpfile
|
|
57
|
+
* 3. persist the agent-edited repo-level learnings tmpfile
|
|
58
|
+
*
|
|
59
|
+
* Each step is idempotent and swallows its own errors. Safe to call from
|
|
60
|
+
* both `main()`'s success path and its catch path.
|
|
61
|
+
*/
|
|
62
|
+
export async function persistRunArtifacts(
|
|
63
|
+
toolContext: ToolContext,
|
|
64
|
+
): Promise<void> {
|
|
65
|
+
await postReviewCleanup(toolContext).catch((error) => {
|
|
66
|
+
log.debug(`post-review cleanup failed: ${error}`);
|
|
67
|
+
});
|
|
68
|
+
await persistSummary(toolContext);
|
|
69
|
+
await persistLearnings(toolContext);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Run the success-path cleanup waterfall:
|
|
74
|
+
*
|
|
75
|
+
* 1. shared best-effort cleanup via `persistRunArtifacts`
|
|
76
|
+
* 2. when the harness returned `success=false` (e.g. unsubmitted-review
|
|
77
|
+
* gate exhausted retries, stop-hook persistently failing), render via
|
|
78
|
+
* `renderRunError` and surface the error in BOTH the progress comment
|
|
79
|
+
* (rendered.comment) and the Actions job summary (rendered.summary,
|
|
80
|
+
* prepended below in step 4) — same classifier as the catch path so
|
|
81
|
+
* the user sees it instead of a deleted-comment void / empty summary
|
|
82
|
+
* tab
|
|
83
|
+
* 3. when the run succeeded, some write landed (`wasUpdated`), but the
|
|
84
|
+
* progress comment was never finalized via `report_progress`, delete
|
|
85
|
+
* the stranded comment (abandoned checklist, or a substantive artifact
|
|
86
|
+
* written via another MCP write tool that skipped report_progress). a
|
|
87
|
+
* run where NO write landed keeps its comment for handleAgentResult to
|
|
88
|
+
* salvage into — see the `wasUpdated` guard below and #868
|
|
89
|
+
* 4. write the GitHub Actions step summary (best-effort — a write
|
|
90
|
+
* failure must not throw past this point because we'd hit the outer
|
|
91
|
+
* catch and clobber any progress comment we just wrote)
|
|
92
|
+
* 5. emit the structured output marker for tests + workflow consumers
|
|
93
|
+
*/
|
|
94
|
+
export async function finalizeSuccessRun(input: {
|
|
95
|
+
toolContext: ToolContext;
|
|
96
|
+
toolState: ToolState;
|
|
97
|
+
result: AgentResult;
|
|
98
|
+
repo: { owner: string; name: string };
|
|
99
|
+
/** Infraweaver Cloud org token (the `api_token` input). When set, the run's
|
|
100
|
+
* findings/posture are reported to Cloud (best-effort). */
|
|
101
|
+
cloudApiToken?: string | undefined;
|
|
102
|
+
}): Promise<void> {
|
|
103
|
+
await persistRunArtifacts(input.toolContext);
|
|
104
|
+
|
|
105
|
+
// shared rendering for the !success branch — same classifier as the
|
|
106
|
+
// outer catch path (BillingError reclassify → hang → BYOK billing →
|
|
107
|
+
// api-key → generic), so a harness-returned `{success: false}` lands an
|
|
108
|
+
// actionable error block in the job summary alongside the matching body
|
|
109
|
+
// in the progress comment. hang and generic get the `### ❌ Infraweaver
|
|
110
|
+
// failed` H3 banner; BillingError, BYOK billing, and api-key render
|
|
111
|
+
// their own provider-specific framing (no banner). renders once; reused
|
|
112
|
+
// for both surfaces below.
|
|
113
|
+
const rendered = !input.result.success
|
|
114
|
+
? renderRunError({
|
|
115
|
+
errorMessage: input.result.error || "agent run failed",
|
|
116
|
+
repo: input.repo,
|
|
117
|
+
agentDiagnostic: input.toolState.agentDiagnostic,
|
|
118
|
+
})
|
|
119
|
+
: null;
|
|
120
|
+
|
|
121
|
+
// `createIfMissing: true` is load-bearing for silent triggers
|
|
122
|
+
// (IncrementalReview / pull_request_synchronize / auto-label) that have
|
|
123
|
+
// no progress comment to update — without it, terminal failures like
|
|
124
|
+
// BYOK billing exhaustion land only in the GH job summary, which most
|
|
125
|
+
// users never open. `reportErrorToComment` no-ops when both progress
|
|
126
|
+
// comment AND issue context are absent. see #835.
|
|
127
|
+
if (rendered) {
|
|
128
|
+
await reportErrorToComment({
|
|
129
|
+
toolState: input.toolState,
|
|
130
|
+
error: rendered.comment,
|
|
131
|
+
createIfMissing: true,
|
|
132
|
+
}).catch((error) => {
|
|
133
|
+
log.debug(`failure error report failed: ${error}`);
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// create_pull_request_review owns its own deletion (see mcp/review.ts), so
|
|
138
|
+
// progressComment is already null by the time we get here for that path.
|
|
139
|
+
// uses finalSummaryWritten (not todoTracker.enabled or wasUpdated) so
|
|
140
|
+
// cleanup survives API failures in report_progress where cancel() ran but
|
|
141
|
+
// the write didn't succeed, and isn't fooled by writes to *other* artifacts.
|
|
142
|
+
//
|
|
143
|
+
// the extra `wasUpdated` guard preserves the comment when NO write landed at
|
|
144
|
+
// all: that's the case handleAgentResult salvages (raw-text answer / failed
|
|
145
|
+
// report_progress) by writing the agent's result into this very comment, or
|
|
146
|
+
// — when there's nothing to salvage — reports the failure into it. deleting
|
|
147
|
+
// here would strand the user with a vanished "Leaping into action" comment
|
|
148
|
+
// and a no-op error report (see #868).
|
|
149
|
+
//
|
|
150
|
+
// the `answerCommentPosted` clause handles the inverse: when the agent posted a
|
|
151
|
+
// standalone answer comment on the run's OWN target (create_issue_comment) AND
|
|
152
|
+
// finalized report_progress, the progress comment is redundant chrome duplicating
|
|
153
|
+
// the answer — delete it so the run leaves a single clean comment (the answer also
|
|
154
|
+
// notifies subscribers, which an in-place edit would not).
|
|
155
|
+
if (
|
|
156
|
+
input.result.success &&
|
|
157
|
+
input.toolState.progressComment &&
|
|
158
|
+
input.toolState.wasUpdated &&
|
|
159
|
+
(!input.toolState.finalSummaryWritten ||
|
|
160
|
+
input.toolState.answerCommentPosted)
|
|
161
|
+
) {
|
|
162
|
+
await deleteProgressComment(input.toolContext).catch((error) => {
|
|
163
|
+
log.debug(`stranded progress comment cleanup failed: ${error}`);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
try {
|
|
168
|
+
const usageSummary = formatUsageSummary(input.toolState.usageEntries);
|
|
169
|
+
// the specialist-routing watch (agents/dispatchMetrics.ts). rendered beside
|
|
170
|
+
// the usage table because the question it answers — "did hypothesis-coverage
|
|
171
|
+
// routing change what a run costs?" — is only answerable by comparing two
|
|
172
|
+
// runs, and this is where a human already looks to compare them.
|
|
173
|
+
const dispatchTally = input.toolState.dispatchMetrics.tally();
|
|
174
|
+
const dispatchLine = describeDispatchTally(dispatchTally);
|
|
175
|
+
if (dispatchLine) log.info(dispatchLine);
|
|
176
|
+
const dispatchSummary = formatDispatchSummary(dispatchTally);
|
|
177
|
+
const body = input.toolState.lastProgressBody || input.result.output;
|
|
178
|
+
const parts = [
|
|
179
|
+
rendered?.summary,
|
|
180
|
+
body,
|
|
181
|
+
usageSummary,
|
|
182
|
+
dispatchSummary,
|
|
183
|
+
].filter(Boolean);
|
|
184
|
+
if (parts.length > 0) {
|
|
185
|
+
await writeSummary(parts.join("\n\n"));
|
|
186
|
+
}
|
|
187
|
+
} catch (error) {
|
|
188
|
+
log.debug(`job summary write failed: ${error}`);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (input.toolState.output) {
|
|
192
|
+
log.info(
|
|
193
|
+
`::infraweaver-output::${Buffer.from(input.toolState.output).toString("base64")}`,
|
|
194
|
+
);
|
|
195
|
+
core.setOutput("result", input.toolState.output);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
await emitFindingsOutputs(
|
|
199
|
+
input.toolState,
|
|
200
|
+
input.toolContext.payload.requiredControls ?? [],
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
// best-effort report to Infraweaver Cloud (no-ops without an org token /
|
|
204
|
+
// configured backend / a scan). reportToCloud swallows its own errors; the
|
|
205
|
+
// extra catch is belt-and-suspenders so a finalize step can't flip the run.
|
|
206
|
+
await reportToCloud({
|
|
207
|
+
toolState: input.toolState,
|
|
208
|
+
repo: input.repo,
|
|
209
|
+
apiToken: input.cloudApiToken,
|
|
210
|
+
}).catch((error) => {
|
|
211
|
+
log.debug(`cloud report failed: ${error}`);
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* when a deterministic scan ran this run (`terraform_scan` populated
|
|
217
|
+
* `lastScanConcerns`), expose its reported concern set to downstream workflow
|
|
218
|
+
* steps: the `findings-count` / `findings-sarif-path` action outputs, plus a
|
|
219
|
+
* safety-net SARIF write so modes that don't prompt the agent to call
|
|
220
|
+
* `terraform_emit_sarif` (Review) — or a Remediate run where the agent skipped
|
|
221
|
+
* that optional step — still surface a Code-Scanning artifact.
|
|
222
|
+
*
|
|
223
|
+
* When the agent already emitted a SARIF via `terraform_emit_sarif`
|
|
224
|
+
* (`scanSession.emittedSarifPath` set), this defers to that file — points the
|
|
225
|
+
* output at it, does not rewrite — so an agent report at a lower threshold or
|
|
226
|
+
* custom path is never clobbered. Otherwise it writes the safety-net file using
|
|
227
|
+
* the canonical `buildSarifReport` (the same builder the tool uses), so there is
|
|
228
|
+
* only ever one SARIF format.
|
|
229
|
+
*
|
|
230
|
+
* Unset outputs when no scan ran; `0` + a results-free SARIF when the scan was
|
|
231
|
+
* clean — so a workflow gate can distinguish "clean scan" from "not scanned".
|
|
232
|
+
* Best-effort like every other finalize step: an emit failure must not flip the
|
|
233
|
+
* run outcome.
|
|
234
|
+
*/
|
|
235
|
+
async function emitFindingsOutputs(
|
|
236
|
+
toolState: ToolState,
|
|
237
|
+
requiredControls: string[],
|
|
238
|
+
): Promise<void> {
|
|
239
|
+
const session = scanSessionOf(toolState);
|
|
240
|
+
const concerns = session.lastScanConcerns;
|
|
241
|
+
if (!concerns) return;
|
|
242
|
+
const active = concerns.filter((c) => !c.suppression);
|
|
243
|
+
const suppressed = concerns.length - active.length;
|
|
244
|
+
const tail = suppressed ? ` (${suppressed} suppressed)` : "";
|
|
245
|
+
const workspace = process.env.GITHUB_WORKSPACE ?? process.cwd();
|
|
246
|
+
try {
|
|
247
|
+
core.setOutput("findings-count", String(active.length));
|
|
248
|
+
|
|
249
|
+
// 2c gate: fail the check only on NEW findings (vs a committed baseline) at or
|
|
250
|
+
// above High. With no baseline file present, every active concern is "new", so
|
|
251
|
+
// this is a plain High/Critical gate. Suppressed concerns are already excluded.
|
|
252
|
+
const gate = evaluateGate(active, loadBaseline(workspace));
|
|
253
|
+
|
|
254
|
+
// Required-controls policy: any OPEN finding mapping to a control the operator
|
|
255
|
+
// marked required fails the gate REGARDLESS of severity (binds the compliance
|
|
256
|
+
// crosswalk to the gate). Empty list → no-op.
|
|
257
|
+
const requiredViolations = requiredControlViolations(
|
|
258
|
+
active,
|
|
259
|
+
requiredControls,
|
|
260
|
+
);
|
|
261
|
+
const pass = gate.pass && requiredViolations.length === 0;
|
|
262
|
+
|
|
263
|
+
core.setOutput("findings-new-count", String(gate.newConcerns.length));
|
|
264
|
+
core.setOutput(
|
|
265
|
+
"findings-required-count",
|
|
266
|
+
String(requiredViolations.length),
|
|
267
|
+
);
|
|
268
|
+
core.setOutput("findings-gate", pass ? "pass" : "fail");
|
|
269
|
+
if (!gate.pass) {
|
|
270
|
+
const base = gate.hasBaseline ? " above the baseline" : "";
|
|
271
|
+
log.info(
|
|
272
|
+
`» gate: FAIL — ${gate.gating.length} new high/critical finding(s)${base}`,
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
if (requiredViolations.length > 0) {
|
|
276
|
+
log.info(
|
|
277
|
+
`» gate: FAIL — ${requiredViolations.length} open finding(s) on a required control (any severity)`,
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// PR inline annotations: a new high/critical OR a required-control violation →
|
|
282
|
+
// error, everything else active → warning. Surfaces findings on the "Files
|
|
283
|
+
// changed" view + the check summary.
|
|
284
|
+
const gatingIds = new Set(
|
|
285
|
+
[...gate.gating, ...requiredViolations].map((c) => c.id),
|
|
286
|
+
);
|
|
287
|
+
for (const a of buildFindingAnnotations(active, gatingIds)) {
|
|
288
|
+
const props = { title: a.title, file: a.file, startLine: a.startLine };
|
|
289
|
+
if (a.level === "error") core.error(a.message, props);
|
|
290
|
+
else core.warning(a.message, props);
|
|
291
|
+
}
|
|
292
|
+
if (session.emittedSarifPath) {
|
|
293
|
+
core.setOutput("findings-sarif-path", session.emittedSarifPath);
|
|
294
|
+
log.info(
|
|
295
|
+
`» findings output: ${active.length} concern(s)${tail}, SARIF at ${session.emittedSarifPath} (agent-emitted)`,
|
|
296
|
+
);
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
const sarifPath = join(
|
|
300
|
+
process.env.GITHUB_WORKSPACE ?? process.cwd(),
|
|
301
|
+
SARIF_FILE,
|
|
302
|
+
);
|
|
303
|
+
await writeFile(
|
|
304
|
+
sarifPath,
|
|
305
|
+
`${JSON.stringify(buildSarifReport(concerns), null, 2)}\n`,
|
|
306
|
+
);
|
|
307
|
+
core.setOutput("findings-sarif-path", sarifPath);
|
|
308
|
+
log.info(
|
|
309
|
+
`» findings output: ${active.length} concern(s)${tail}, SARIF at ${sarifPath}`,
|
|
310
|
+
);
|
|
311
|
+
} catch (error) {
|
|
312
|
+
log.debug(`findings output emit failed: ${error}`);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Write the rendered error to the GitHub Actions job summary tab + mirror
|
|
318
|
+
* to the PR progress comment when one exists. Catch path only.
|
|
319
|
+
*
|
|
320
|
+
* `lastProgressBody` and the usage table are appended to the summary so the
|
|
321
|
+
* partial work the agent did before failing isn't lost.
|
|
322
|
+
*
|
|
323
|
+
* `createIfMissing: true` is symmetric with `finalizeSuccessRun` — silent
|
|
324
|
+
* triggers (IncrementalReview / pull_request_synchronize / auto-label) that
|
|
325
|
+
* throw past `finalizeSuccessRun` (e.g. timeout race kills the agent
|
|
326
|
+
* mid-billing-exhausted-retry) reach this catch path with no progress
|
|
327
|
+
* comment to update, and without `createIfMissing` the terminal error
|
|
328
|
+
* lands only in the GH job summary that most users never open. see #835.
|
|
329
|
+
*/
|
|
330
|
+
export async function writeRunErrorOutputs(input: {
|
|
331
|
+
rendered: RenderedRunError;
|
|
332
|
+
toolState: ToolState;
|
|
333
|
+
}): Promise<void> {
|
|
334
|
+
try {
|
|
335
|
+
const usageSummary = formatUsageSummary(input.toolState.usageEntries);
|
|
336
|
+
// a failed run's dispatch cost is exactly as informative as a successful
|
|
337
|
+
// one's — arguably more, since over-dispatch is a plausible cause of the
|
|
338
|
+
// timeout that got it here.
|
|
339
|
+
const dispatchSummary = formatDispatchSummary(
|
|
340
|
+
input.toolState.dispatchMetrics.tally(),
|
|
341
|
+
);
|
|
342
|
+
const parts = [
|
|
343
|
+
input.rendered.summary,
|
|
344
|
+
input.toolState.lastProgressBody,
|
|
345
|
+
usageSummary,
|
|
346
|
+
dispatchSummary,
|
|
347
|
+
].filter(Boolean);
|
|
348
|
+
await writeSummary(parts.join("\n\n"));
|
|
349
|
+
} catch {}
|
|
350
|
+
|
|
351
|
+
try {
|
|
352
|
+
await reportErrorToComment({
|
|
353
|
+
toolState: input.toolState,
|
|
354
|
+
error: input.rendered.comment,
|
|
355
|
+
createIfMissing: true,
|
|
356
|
+
});
|
|
357
|
+
} catch {
|
|
358
|
+
// error reporting failed, but don't let it mask the original error
|
|
359
|
+
}
|
|
360
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Startup log formatting for the resolver pipeline. Computes the
|
|
3
|
+
* "model / agent / push / shell / timeout" block that main.ts prints
|
|
4
|
+
* after resolving the agent + model + payload.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { log } from "#app/utils/cli";
|
|
8
|
+
import type { ResolvedPayload } from "#app/utils/payload";
|
|
9
|
+
import { TIMEOUT_DISABLED } from "#app/utils/time";
|
|
10
|
+
|
|
11
|
+
function resolveTimeoutForLog(timeout: string | undefined): string {
|
|
12
|
+
if (!timeout) return "1h (default)";
|
|
13
|
+
if (timeout === TIMEOUT_DISABLED) return "none (disabled)";
|
|
14
|
+
return timeout;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function resolveModelForLog(ctx: {
|
|
18
|
+
payload: ResolvedPayload;
|
|
19
|
+
resolvedModel: string | undefined;
|
|
20
|
+
}): string {
|
|
21
|
+
const envModel = process.env.INFRAWEAVER_MODEL?.trim();
|
|
22
|
+
if (envModel) return `${envModel} (override via INFRAWEAVER_MODEL)`;
|
|
23
|
+
if (
|
|
24
|
+
ctx.resolvedModel &&
|
|
25
|
+
ctx.payload.model &&
|
|
26
|
+
ctx.payload.model !== ctx.resolvedModel
|
|
27
|
+
) {
|
|
28
|
+
return `${ctx.resolvedModel} (resolved from ${ctx.payload.model})`;
|
|
29
|
+
}
|
|
30
|
+
if (ctx.resolvedModel) return ctx.resolvedModel;
|
|
31
|
+
if (ctx.payload.model) return `${ctx.payload.model} (unresolved)`;
|
|
32
|
+
return "auto";
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function resolveAgentForLog(ctx: {
|
|
36
|
+
agentName: string;
|
|
37
|
+
resolvedModel: string | undefined;
|
|
38
|
+
}): string {
|
|
39
|
+
const envAgent = process.env.INFRAWEAVER_AGENT?.trim();
|
|
40
|
+
if (envAgent && envAgent === ctx.agentName) {
|
|
41
|
+
return `${ctx.agentName} (override via INFRAWEAVER_AGENT)`;
|
|
42
|
+
}
|
|
43
|
+
if (ctx.agentName === "claude" && ctx.resolvedModel) {
|
|
44
|
+
return `${ctx.agentName} (auto-selected for ${ctx.resolvedModel})`;
|
|
45
|
+
}
|
|
46
|
+
return ctx.agentName;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Emit the startup block ("» model / agent / push / shell / timeout") after
|
|
51
|
+
* the agent and model are resolved. Single side-effect; no return.
|
|
52
|
+
*/
|
|
53
|
+
export function logRunStartup(ctx: {
|
|
54
|
+
payload: ResolvedPayload;
|
|
55
|
+
resolvedModel: string | undefined;
|
|
56
|
+
agentName: string;
|
|
57
|
+
}): void {
|
|
58
|
+
log.info(
|
|
59
|
+
`» model: ${resolveModelForLog({ payload: ctx.payload, resolvedModel: ctx.resolvedModel })}`,
|
|
60
|
+
);
|
|
61
|
+
log.info(
|
|
62
|
+
`» agent: ${resolveAgentForLog({ agentName: ctx.agentName, resolvedModel: ctx.resolvedModel })}`,
|
|
63
|
+
);
|
|
64
|
+
log.info(`» push: ${ctx.payload.push}`);
|
|
65
|
+
log.info(`» shell: ${ctx.payload.shell}`);
|
|
66
|
+
log.info(`» timeout: ${resolveTimeoutForLog(ctx.payload.timeout)}`);
|
|
67
|
+
}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret detection and env filtering utilities
|
|
3
|
+
*
|
|
4
|
+
* subprocess env filtering: default-deny allowlist model.
|
|
5
|
+
* only vars in the safe set or user allowlist are passed to child processes.
|
|
6
|
+
*
|
|
7
|
+
* log redaction: SENSITIVE_PATTERNS are used to identify secret values
|
|
8
|
+
* for redaction in logs and GHA masking (independent of subprocess filtering).
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// --- log redaction (unchanged, independent of subprocess filtering) ---
|
|
12
|
+
|
|
13
|
+
// patterns for sensitive env var names (used by normalizeEnv)
|
|
14
|
+
export const SENSITIVE_PATTERNS = [
|
|
15
|
+
/_KEY$/i,
|
|
16
|
+
/_SECRET$/i,
|
|
17
|
+
/_TOKEN$/i,
|
|
18
|
+
/_PASSWORD$/i,
|
|
19
|
+
/_CREDENTIAL$/i,
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
// secret-bearing names the suffix patterns miss, because the credential sits in
|
|
23
|
+
// the middle or the var is a host-suffixed family:
|
|
24
|
+
// - ACTIONS_ID_TOKEN_REQUEST_URL ends in _URL, but with its sibling _TOKEN it
|
|
25
|
+
// mints OIDC tokens, so the pair is treated as one credential.
|
|
26
|
+
// - TF_TOKEN_<host> is Terraform's per-host registry credential.
|
|
27
|
+
// - GIT_CONFIG_VALUE_<n> can carry an http.<host>.extraheader Basic auth value.
|
|
28
|
+
const SENSITIVE_ENV_PREFIXES = ["ACTIONS_ID_TOKEN_REQUEST_", "TF_TOKEN_", "GIT_CONFIG_VALUE_"];
|
|
29
|
+
|
|
30
|
+
export function isSensitiveEnvName(key: string): boolean {
|
|
31
|
+
if (SENSITIVE_ENV_PREFIXES.some((p) => key.toUpperCase().startsWith(p))) return true;
|
|
32
|
+
return SENSITIVE_PATTERNS.some((p) => p.test(key));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// --- subprocess env filtering ---
|
|
36
|
+
|
|
37
|
+
// prefixes whose vars are safe to pass through (runner metadata, toolchain).
|
|
38
|
+
const SAFE_ENV_PREFIXES = ["RUNNER_", "JAVA_HOME_", "GOROOT_"];
|
|
39
|
+
|
|
40
|
+
// GITHUB_* is an EXACT allowlist rather than a prefix: the set of context vars
|
|
41
|
+
// the runner injects is well-known and closed, so listing them explicitly fails
|
|
42
|
+
// closed on any unknown/future GITHUB_* var (e.g. a sensitive one that doesn't
|
|
43
|
+
// end in _TOKEN/_KEY/_SECRET and would otherwise slip through the prefix).
|
|
44
|
+
// GITHUB_TOKEN/GH_TOKEN are intentionally absent; isSensitiveEnvName() also
|
|
45
|
+
// catches them via the _TOKEN suffix. Users can opt any var in via the allowlist.
|
|
46
|
+
const SAFE_GITHUB_ENV_NAMES = new Set([
|
|
47
|
+
"GITHUB_ACTION",
|
|
48
|
+
"GITHUB_ACTION_PATH",
|
|
49
|
+
"GITHUB_ACTION_REPOSITORY",
|
|
50
|
+
"GITHUB_ACTIONS",
|
|
51
|
+
"GITHUB_ACTOR",
|
|
52
|
+
"GITHUB_ACTOR_ID",
|
|
53
|
+
"GITHUB_API_URL",
|
|
54
|
+
"GITHUB_BASE_REF",
|
|
55
|
+
"GITHUB_ENV",
|
|
56
|
+
"GITHUB_EVENT_NAME",
|
|
57
|
+
"GITHUB_EVENT_PATH",
|
|
58
|
+
"GITHUB_GRAPHQL_URL",
|
|
59
|
+
"GITHUB_HEAD_REF",
|
|
60
|
+
"GITHUB_JOB",
|
|
61
|
+
"GITHUB_OUTPUT",
|
|
62
|
+
"GITHUB_PATH",
|
|
63
|
+
"GITHUB_REF",
|
|
64
|
+
"GITHUB_REF_NAME",
|
|
65
|
+
"GITHUB_REF_PROTECTED",
|
|
66
|
+
"GITHUB_REF_TYPE",
|
|
67
|
+
"GITHUB_REPOSITORY",
|
|
68
|
+
"GITHUB_REPOSITORY_ID",
|
|
69
|
+
"GITHUB_REPOSITORY_OWNER",
|
|
70
|
+
"GITHUB_REPOSITORY_OWNER_ID",
|
|
71
|
+
"GITHUB_RETENTION_DAYS",
|
|
72
|
+
"GITHUB_RUN_ATTEMPT",
|
|
73
|
+
"GITHUB_RUN_ID",
|
|
74
|
+
"GITHUB_RUN_NUMBER",
|
|
75
|
+
"GITHUB_SERVER_URL",
|
|
76
|
+
"GITHUB_SHA",
|
|
77
|
+
"GITHUB_STEP_SUMMARY",
|
|
78
|
+
"GITHUB_TRIGGERING_ACTOR",
|
|
79
|
+
"GITHUB_WORKFLOW",
|
|
80
|
+
"GITHUB_WORKFLOW_REF",
|
|
81
|
+
"GITHUB_WORKFLOW_SHA",
|
|
82
|
+
"GITHUB_WORKSPACE",
|
|
83
|
+
]);
|
|
84
|
+
|
|
85
|
+
// exact var names safe to pass through (system + runner image toolchain)
|
|
86
|
+
const SAFE_ENV_NAMES = new Set([
|
|
87
|
+
// system
|
|
88
|
+
"CI",
|
|
89
|
+
"HOME",
|
|
90
|
+
"LANG",
|
|
91
|
+
"LOGNAME",
|
|
92
|
+
"PATH",
|
|
93
|
+
"SHELL",
|
|
94
|
+
"SHLVL",
|
|
95
|
+
"TERM",
|
|
96
|
+
"TMPDIR",
|
|
97
|
+
"TZ",
|
|
98
|
+
"USER",
|
|
99
|
+
"XDG_CONFIG_HOME",
|
|
100
|
+
"XDG_RUNTIME_DIR",
|
|
101
|
+
"DEBIAN_FRONTEND",
|
|
102
|
+
// runner image toolchain
|
|
103
|
+
"ACCEPT_EULA",
|
|
104
|
+
"AGENT_TOOLSDIRECTORY",
|
|
105
|
+
"ANDROID_HOME",
|
|
106
|
+
"ANDROID_NDK",
|
|
107
|
+
"ANDROID_NDK_HOME",
|
|
108
|
+
"ANDROID_NDK_LATEST_HOME",
|
|
109
|
+
"ANDROID_NDK_ROOT",
|
|
110
|
+
"ANDROID_SDK_ROOT",
|
|
111
|
+
"ANT_HOME",
|
|
112
|
+
"AZURE_EXTENSION_DIR",
|
|
113
|
+
"BOOTSTRAP_HASKELL_NONINTERACTIVE",
|
|
114
|
+
"CHROME_BIN",
|
|
115
|
+
"CHROMEWEBDRIVER",
|
|
116
|
+
"CONDA",
|
|
117
|
+
"DOTNET_MULTILEVEL_LOOKUP",
|
|
118
|
+
"DOTNET_NOLOGO",
|
|
119
|
+
"DOTNET_SKIP_FIRST_TIME_EXPERIENCE",
|
|
120
|
+
"EDGEWEBDRIVER",
|
|
121
|
+
"GECKOWEBDRIVER",
|
|
122
|
+
"GHCUP_INSTALL_BASE_PREFIX",
|
|
123
|
+
"GRADLE_HOME",
|
|
124
|
+
"JAVA_HOME",
|
|
125
|
+
"HOMEBREW_CLEANUP_PERIODIC_FULL_DAYS",
|
|
126
|
+
"HOMEBREW_NO_AUTO_UPDATE",
|
|
127
|
+
"ImageOS",
|
|
128
|
+
"ImageVersion",
|
|
129
|
+
"NVM_DIR",
|
|
130
|
+
"PIPX_BIN_DIR",
|
|
131
|
+
"PIPX_HOME",
|
|
132
|
+
"PSModulePath",
|
|
133
|
+
"SELENIUM_JAR_PATH",
|
|
134
|
+
"SGX_AESM_ADDR",
|
|
135
|
+
"SWIFT_PATH",
|
|
136
|
+
"VCPKG_INSTALLATION_ROOT",
|
|
137
|
+
]);
|
|
138
|
+
|
|
139
|
+
let _userAllowlist: Set<string> | null = null;
|
|
140
|
+
|
|
141
|
+
export function setEnvAllowlist(raw: string): void {
|
|
142
|
+
const names = raw
|
|
143
|
+
.split("\n")
|
|
144
|
+
.map((line) => line.trim())
|
|
145
|
+
.filter(Boolean);
|
|
146
|
+
_userAllowlist = new Set(names);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function isSafeEnvVar(key: string): boolean {
|
|
150
|
+
if (SAFE_ENV_NAMES.has(key)) return true;
|
|
151
|
+
if (SAFE_GITHUB_ENV_NAMES.has(key)) return true;
|
|
152
|
+
return SAFE_ENV_PREFIXES.some((p) => key.startsWith(p));
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** filter env vars using default-deny allowlist: safe set + user allowlist */
|
|
156
|
+
export function filterEnv(): Record<string, string> {
|
|
157
|
+
const filtered: Record<string, string> = {};
|
|
158
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
159
|
+
if (value === undefined) continue;
|
|
160
|
+
const userAllowed = _userAllowlist?.has(key) ?? false;
|
|
161
|
+
if (isSensitiveEnvName(key) && !userAllowed) continue;
|
|
162
|
+
if (isSafeEnvVar(key) || userAllowed) {
|
|
163
|
+
filtered[key] = value;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return filtered;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* env for "inherit" mode: everything in process.env EXCEPT secret-bearing names.
|
|
171
|
+
*
|
|
172
|
+
* inherit exists to widen the *command* surface (arbitrary toolchain vars the
|
|
173
|
+
* restricted allowlist can't enumerate), not to hand the agent credentials — so
|
|
174
|
+
* this is a denylist over the full env rather than the restricted allowlist. A
|
|
175
|
+
* specific var can still be opted back in explicitly via the user allowlist.
|
|
176
|
+
*
|
|
177
|
+
* Without this, `shell: "enabled"` would let the agent read INPUT_*_TOKEN, a BYO
|
|
178
|
+
* model key, or the OIDC minting creds straight out of `env`.
|
|
179
|
+
*/
|
|
180
|
+
export function inheritEnv(): Record<string, string> {
|
|
181
|
+
const inherited: Record<string, string> = {};
|
|
182
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
183
|
+
if (value === undefined) continue;
|
|
184
|
+
const userAllowed = _userAllowlist?.has(key) ?? false;
|
|
185
|
+
if (isSensitiveEnvName(key) && !userAllowed) continue;
|
|
186
|
+
inherited[key] = value;
|
|
187
|
+
}
|
|
188
|
+
return inherited;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export type EnvMode = "restricted" | "inherit" | Record<string, string>;
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* resolve env mode to actual env object
|
|
195
|
+
* - "restricted" (default): filterEnv() — only safe set + user allowlist
|
|
196
|
+
* - "inherit": full process.env minus secret-bearing names
|
|
197
|
+
* - object: custom env merged with restricted base
|
|
198
|
+
*/
|
|
199
|
+
export function resolveEnv(mode: EnvMode | undefined): Record<string, string | undefined> {
|
|
200
|
+
if (mode === "inherit") {
|
|
201
|
+
return inheritEnv();
|
|
202
|
+
}
|
|
203
|
+
if (mode === "restricted" || mode === undefined) {
|
|
204
|
+
return filterEnv();
|
|
205
|
+
}
|
|
206
|
+
// custom env object - merge with restricted base
|
|
207
|
+
return { ...filterEnv(), ...mode };
|
|
208
|
+
}
|