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
package/src/mcp/roots.ts
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { type } from "arktype";
|
|
4
|
+
import type { LocalToolContext } from "#app/mcp/localContext";
|
|
5
|
+
import { walkTfFiles } from "#app/mcp/modules";
|
|
6
|
+
import { execute, tool } from "#app/mcp/shared";
|
|
7
|
+
import { log } from "#app/utils/cli";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Multi-root awareness. A repo can hold SEVERAL Terraform root modules — the
|
|
11
|
+
* dirs you'd run `terraform init/plan/apply` in — not one. hepcare, for example,
|
|
12
|
+
* has `terraform/` AND `terraform/core/`, plus a child module under
|
|
13
|
+
* `terraform/modules/`. The scanners run recursively, but plan/validate assume a
|
|
14
|
+
* single `cwd`; this surfaces the roots so a run can act per-root.
|
|
15
|
+
*
|
|
16
|
+
* Heuristic (validated against real repos): a ROOT is a dir whose `*.tf`
|
|
17
|
+
* declares a PROVIDER CONFIGURATION (`provider "<name>" { … }`) or a BACKEND
|
|
18
|
+
* (`backend "<type>" { … }`). A CHILD MODULE never configures a provider or a
|
|
19
|
+
* backend (it only declares `required_providers`), so this cleanly separates the
|
|
20
|
+
* two. Pure parsing + a single fs walk; no subprocess.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
export interface TerraformRoot {
|
|
24
|
+
/** repo-relative dir (POSIX); "" for the top-level. */
|
|
25
|
+
dir: string;
|
|
26
|
+
hasBackend: boolean;
|
|
27
|
+
hasProviderConfig: boolean;
|
|
28
|
+
tfFileCount: number;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// a provider CONFIGURATION block — `provider "aws" {`. Distinct from a
|
|
32
|
+
// `required_providers` block (which child modules also have). The negative
|
|
33
|
+
// lookbehind avoids matching `required_providers`.
|
|
34
|
+
const PROVIDER_CONFIG = /(?:^|\n)\s*provider\s+"[^"]+"\s*\{/;
|
|
35
|
+
const BACKEND_BLOCK = /(?:^|\n)\s*backend\s+"[^"]+"\s*\{/;
|
|
36
|
+
|
|
37
|
+
/** detect whether some concatenated HCL marks a root module. */
|
|
38
|
+
export function isRootModuleHcl(hcl: string): { hasBackend: boolean; hasProviderConfig: boolean } {
|
|
39
|
+
return {
|
|
40
|
+
hasBackend: BACKEND_BLOCK.test(hcl),
|
|
41
|
+
hasProviderConfig: PROVIDER_CONFIG.test(hcl),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** the directory of a repo-relative file path ("" for a top-level file). */
|
|
46
|
+
function dirOf(file: string): string {
|
|
47
|
+
const i = file.lastIndexOf("/");
|
|
48
|
+
return i === -1 ? "" : file.slice(0, i);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Discover the Terraform root modules under `cwd`. Walks `*.tf` recursively
|
|
53
|
+
* (skipping cache/VCS dirs via walkTfFiles), groups by directory, and keeps the
|
|
54
|
+
* dirs that configure a provider or a backend. Sorted by dir. An empty result
|
|
55
|
+
* means no obvious root was found — the caller falls back to scanning `cwd`
|
|
56
|
+
* itself as a single root.
|
|
57
|
+
*/
|
|
58
|
+
export function discoverTerraformRoots(cwd: string): TerraformRoot[] {
|
|
59
|
+
const byDir = new Map<string, { files: string[]; hcl: string }>();
|
|
60
|
+
for (const f of walkTfFiles(cwd)) {
|
|
61
|
+
const dir = dirOf(f);
|
|
62
|
+
const entry = byDir.get(dir) ?? { files: [], hcl: "" };
|
|
63
|
+
entry.files.push(f);
|
|
64
|
+
try {
|
|
65
|
+
entry.hcl += `${readFileSync(join(cwd, f), "utf8")}\n`;
|
|
66
|
+
} catch {
|
|
67
|
+
/* skip unreadable */
|
|
68
|
+
}
|
|
69
|
+
byDir.set(dir, entry);
|
|
70
|
+
}
|
|
71
|
+
const roots: TerraformRoot[] = [];
|
|
72
|
+
for (const [dir, entry] of byDir) {
|
|
73
|
+
const { hasBackend, hasProviderConfig } = isRootModuleHcl(entry.hcl);
|
|
74
|
+
if (hasBackend || hasProviderConfig) {
|
|
75
|
+
roots.push({ dir, hasBackend, hasProviderConfig, tfFileCount: entry.files.length });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return roots.sort((a, b) => a.dir.localeCompare(b.dir));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// --- environment / region fan-out --------------------------------------
|
|
82
|
+
|
|
83
|
+
// tokens that mark an environment twin when they appear as a whole path segment
|
|
84
|
+
// or a `<token>.tfvars` filename. Lowercased; matched exactly against a segment.
|
|
85
|
+
const ENV_TOKENS = new Set([
|
|
86
|
+
"dev",
|
|
87
|
+
"develop",
|
|
88
|
+
"development",
|
|
89
|
+
"stg",
|
|
90
|
+
"stage",
|
|
91
|
+
"staging",
|
|
92
|
+
"prod",
|
|
93
|
+
"prd",
|
|
94
|
+
"production",
|
|
95
|
+
"test",
|
|
96
|
+
"testing",
|
|
97
|
+
"qa",
|
|
98
|
+
"uat",
|
|
99
|
+
"sandbox",
|
|
100
|
+
"sbx",
|
|
101
|
+
"preprod",
|
|
102
|
+
"pre-prod",
|
|
103
|
+
"preproduction",
|
|
104
|
+
"demo",
|
|
105
|
+
"nonprod",
|
|
106
|
+
"non-prod",
|
|
107
|
+
]);
|
|
108
|
+
|
|
109
|
+
// AWS-style region segment, e.g. `eu-west-2`, `eu-west-1` — the other common
|
|
110
|
+
// fan-out axis (the same stack replicated per region).
|
|
111
|
+
const REGION_RE = /^[a-z]{2}-[a-z]+-\d$/;
|
|
112
|
+
|
|
113
|
+
export interface EnvironmentTwinGroup {
|
|
114
|
+
/** the shared path shape with the env/region segment replaced by `{env}`. */
|
|
115
|
+
pattern: string;
|
|
116
|
+
/** the matched twins: each a dir + the environment/region token it carries. */
|
|
117
|
+
members: { dir: string; environment: string }[];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Detect environment/region TWINS among a set of repo-relative paths (root dirs
|
|
122
|
+
* and/or `*.tfvars` files): parallel stacks that differ only by an environment
|
|
123
|
+
* (`dev`/`staging`/`prod`/…) or region (`eu-west-2`) segment. A fix applied to
|
|
124
|
+
* one should usually be offered for its twins too (backport / fan-out).
|
|
125
|
+
*
|
|
126
|
+
* For each path, finds the LAST segment that is an env token or a region (a
|
|
127
|
+
* `<env>.tfvars` file counts via its basename), replaces it with `{env}` to form
|
|
128
|
+
* a pattern, and groups by that pattern. Only groups with ≥2 DISTINCT
|
|
129
|
+
* environments are returned (a single match isn't a twin set). Pure +
|
|
130
|
+
* deterministic (sorted).
|
|
131
|
+
*/
|
|
132
|
+
export function detectEnvironmentTwins(paths: string[]): EnvironmentTwinGroup[] {
|
|
133
|
+
const byPattern = new Map<string, Map<string, string>>(); // pattern → env → dir
|
|
134
|
+
for (const raw of paths) {
|
|
135
|
+
const path = raw.replace(/\\/g, "/").replace(/^\.\//, "");
|
|
136
|
+
const segments = path.split("/").filter(Boolean);
|
|
137
|
+
// a `<env>.tfvars` filename: treat the basename (sans .tfvars) as a segment.
|
|
138
|
+
const last = segments[segments.length - 1] ?? "";
|
|
139
|
+
if (last.endsWith(".tfvars")) {
|
|
140
|
+
segments[segments.length - 1] = last.slice(0, -".tfvars".length);
|
|
141
|
+
}
|
|
142
|
+
// find the LAST env/region segment (so `infra/prod/network` keys on `prod`).
|
|
143
|
+
let idx = -1;
|
|
144
|
+
let token = "";
|
|
145
|
+
for (let i = segments.length - 1; i >= 0; i--) {
|
|
146
|
+
const seg = segments[i]!.toLowerCase();
|
|
147
|
+
if (ENV_TOKENS.has(seg) || REGION_RE.test(seg)) {
|
|
148
|
+
idx = i;
|
|
149
|
+
token = seg;
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (idx === -1) continue;
|
|
154
|
+
const patternSegs = [...segments];
|
|
155
|
+
patternSegs[idx] = "{env}";
|
|
156
|
+
const pattern = patternSegs.join("/") + (last.endsWith(".tfvars") ? ".tfvars" : "");
|
|
157
|
+
const map = byPattern.get(pattern) ?? new Map<string, string>();
|
|
158
|
+
if (!map.has(token)) map.set(token, path);
|
|
159
|
+
byPattern.set(pattern, map);
|
|
160
|
+
}
|
|
161
|
+
const groups: EnvironmentTwinGroup[] = [];
|
|
162
|
+
for (const [pattern, envMap] of byPattern) {
|
|
163
|
+
if (envMap.size < 2) continue;
|
|
164
|
+
const members = [...envMap.entries()]
|
|
165
|
+
.map(([environment, dir]) => ({ dir, environment }))
|
|
166
|
+
.sort((a, b) => a.environment.localeCompare(b.environment));
|
|
167
|
+
groups.push({ pattern, members });
|
|
168
|
+
}
|
|
169
|
+
return groups.sort((a, b) => a.pattern.localeCompare(b.pattern));
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export const TerraformRootsParams = type({});
|
|
173
|
+
|
|
174
|
+
export function TerraformRootsTool(ctx: LocalToolContext) {
|
|
175
|
+
return tool({
|
|
176
|
+
name: "terraform_roots",
|
|
177
|
+
description:
|
|
178
|
+
"Discover the Terraform ROOT modules in the repo — the dirs you'd run `terraform init/plan/apply` in " +
|
|
179
|
+
"(they configure a `provider` or a `backend`), as opposed to child modules under `modules/`. A repo " +
|
|
180
|
+
"can have several (e.g. `terraform/` and `terraform/core/`). `terraform_scan` already scans the whole " +
|
|
181
|
+
"tree, but `terraform_plan`/`terraform_validate` act on one dir — run them once PER ROOT (set the " +
|
|
182
|
+
"`cwd` accordingly) when there is more than one, so each root's real-world effect is checked. Returns " +
|
|
183
|
+
"an empty list when no root is detected (then treat the scan `cwd` as the single root).",
|
|
184
|
+
parameters: TerraformRootsParams,
|
|
185
|
+
execute: execute(async () => {
|
|
186
|
+
const cwd = ctx.payload.cwd ?? process.cwd();
|
|
187
|
+
const roots = discoverTerraformRoots(cwd);
|
|
188
|
+
// parallel per-environment/region stacks among the roots; a fix to
|
|
189
|
+
// one twin should usually be offered for the others.
|
|
190
|
+
const twins = detectEnvironmentTwins(roots.map((r) => r.dir).filter(Boolean));
|
|
191
|
+
log.info(
|
|
192
|
+
`» terraform_roots: ${roots.length} root(s) [${roots.map((r) => r.dir || ".").join(", ")}]` +
|
|
193
|
+
(twins.length ? `, ${twins.length} env-twin group(s)` : ""),
|
|
194
|
+
);
|
|
195
|
+
return {
|
|
196
|
+
ok: true,
|
|
197
|
+
root_count: roots.length,
|
|
198
|
+
roots: roots.map((r) => ({
|
|
199
|
+
dir: r.dir || ".",
|
|
200
|
+
has_backend: r.hasBackend,
|
|
201
|
+
has_provider_config: r.hasProviderConfig,
|
|
202
|
+
tf_file_count: r.tfFileCount,
|
|
203
|
+
})),
|
|
204
|
+
// environment/region twin groups (≥2 stacks differing only by an
|
|
205
|
+
// env/region segment). Empty when there are none.
|
|
206
|
+
environment_twins: twins,
|
|
207
|
+
note:
|
|
208
|
+
roots.length > 1
|
|
209
|
+
? "Multiple roots — terraform_plan/terraform_validate run per root automatically. " +
|
|
210
|
+
(twins.length
|
|
211
|
+
? "Detected environment twins: a fix to one stack should usually be offered for its twins."
|
|
212
|
+
: "")
|
|
213
|
+
: "Single root (or none detected) — the scan cwd is the root.",
|
|
214
|
+
};
|
|
215
|
+
}),
|
|
216
|
+
});
|
|
217
|
+
}
|
package/src/mcp/scope.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { PRODUCT_SLUG } from "#app/brand";
|
|
2
|
+
import type { ToolState } from "#app/toolState";
|
|
3
|
+
import type { ResolvedPayload } from "#app/utils/payload";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The slice of the run these scope guards read: the triggering event (for the
|
|
7
|
+
* scoped issue/PR) and the created-target set. Both `GitHubToolContext` and the
|
|
8
|
+
* combined GitHub write context satisfy it — the guards need no octokit of their
|
|
9
|
+
* own.
|
|
10
|
+
*/
|
|
11
|
+
export interface ScopeContext {
|
|
12
|
+
payload: ResolvedPayload;
|
|
13
|
+
toolState: ToolState;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Bind the GitHub REST write tools to the issue/PR the run is scoped to.
|
|
18
|
+
*
|
|
19
|
+
* Infraweaver's threat model treats the agent as semi-trusted: attacker-controlled
|
|
20
|
+
* PR/issue content can prompt-inject it. The git tools already refuse to act on a
|
|
21
|
+
* PR the run was not triggered against (the cross-PR clobber guard in
|
|
22
|
+
* `mcp/git.ts`). These helpers extend the same scoping to the REST write tools
|
|
23
|
+
* (comment, review, labels, PR-body update, review reply, thread resolve) so an
|
|
24
|
+
* injected agent cannot comment on / approve / label an UNRELATED issue or PR in
|
|
25
|
+
* the same repo. The installation token already prevents cross-REPO writes; this
|
|
26
|
+
* closes the remaining cross-issue/PR-within-the-repo gap.
|
|
27
|
+
*
|
|
28
|
+
* In scope = the triggering issue/PR (`event.issue_number`) OR a PR/issue THIS
|
|
29
|
+
* run created (`create_pull_request` / `create_issue`, recorded via
|
|
30
|
+
* `recordCreatedTarget`). A merely checked-out PR is NOT in scope: `checkout_pr`
|
|
31
|
+
* is agent-controlled, so letting it widen write scope would defeat the guard.
|
|
32
|
+
*
|
|
33
|
+
* Standalone runs (workflow_dispatch / CLI: `event.trigger === "unknown"`) carry
|
|
34
|
+
* no triggering issue/PR and therefore no injection surface — there is nothing to
|
|
35
|
+
* bind to, so the guard is a no-op and the operator-supplied target is honored.
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
/** the PR/issue this run was triggered against, or undefined for standalone runs. */
|
|
39
|
+
function scopedTarget(ctx: ScopeContext): number | undefined {
|
|
40
|
+
// optional chain: production always sets `payload.event` (resolvePayload
|
|
41
|
+
// defaults event to {trigger:"unknown"}), but degrade to "no scope" if it's
|
|
42
|
+
// somehow absent rather than throwing from a guard.
|
|
43
|
+
return ctx.payload?.event?.issue_number;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Record a PR/issue this run created so later body edits / comments / reviews on
|
|
48
|
+
* it pass {@link assertTargetInScope}. Call after a successful
|
|
49
|
+
* `create_pull_request` / `create_issue`.
|
|
50
|
+
*/
|
|
51
|
+
export function recordCreatedTarget(ctx: ScopeContext, target: number): void {
|
|
52
|
+
ctx.toolState.createdTargets ??= new Set();
|
|
53
|
+
ctx.toolState.createdTargets.add(target);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** true when `target` is the run's triggering issue/PR or one it created. */
|
|
57
|
+
export function isTargetInScope(ctx: ScopeContext, target: number): boolean {
|
|
58
|
+
const scoped = scopedTarget(ctx);
|
|
59
|
+
// standalone run — no triggering issue/PR to bind to (no injection surface).
|
|
60
|
+
if (scoped === undefined) return true;
|
|
61
|
+
if (target === scoped) return true;
|
|
62
|
+
return ctx.toolState.createdTargets?.has(target) ?? false;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Throw if `target` is neither the run's triggering issue/PR nor one it created.
|
|
67
|
+
* `action` is a short verb phrase used in the error (e.g. "comment on",
|
|
68
|
+
* "submit a review on", "add labels to").
|
|
69
|
+
*/
|
|
70
|
+
export function assertTargetInScope(
|
|
71
|
+
ctx: ScopeContext,
|
|
72
|
+
target: number,
|
|
73
|
+
action: string,
|
|
74
|
+
): void {
|
|
75
|
+
if (isTargetInScope(ctx, target)) return;
|
|
76
|
+
const scoped = scopedTarget(ctx);
|
|
77
|
+
throw new Error(
|
|
78
|
+
`blocked: this run is scoped to #${scoped}; refusing to ${action} #${target}. ` +
|
|
79
|
+
`${PRODUCT_SLUG} only writes to the issue/PR that triggered the run (or one it opened during the run). ` +
|
|
80
|
+
`if acting on #${target} is intended, trigger a run against #${target}.`,
|
|
81
|
+
);
|
|
82
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { type } from "arktype";
|
|
2
|
+
import { refreshWritePolicy } from "#app/agents/writePolicy";
|
|
3
|
+
import { formatMcpToolRef } from "#app/external";
|
|
4
|
+
import type { ToolContext } from "#app/mcp/server";
|
|
5
|
+
import { execute, tool } from "#app/mcp/shared";
|
|
6
|
+
import type { Mode } from "#app/modes";
|
|
7
|
+
import { cloudRequest } from "#app/utils/cloudClient";
|
|
8
|
+
|
|
9
|
+
export const SelectModeParams = type({
|
|
10
|
+
mode: type.string.describe(
|
|
11
|
+
"the name of the mode to select (e.g., 'Build', 'Plan', 'Review', 'IncrementalReview', 'Fix', 'AddressReviews', 'Task', 'ResolveConflicts')",
|
|
12
|
+
),
|
|
13
|
+
"issue_number?": type("number").describe(
|
|
14
|
+
"optional issue number; when provided with Plan mode, used to look up an existing plan comment for this issue (edit vs create)",
|
|
15
|
+
),
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
function resolveMode(modes: Mode[], modeName: string): Mode | null {
|
|
19
|
+
return (
|
|
20
|
+
modes.find((m) => m.name.toLowerCase() === modeName.toLowerCase()) ?? null
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function buildModeOverrides(
|
|
25
|
+
t: (name: string) => string,
|
|
26
|
+
): Record<string, string> {
|
|
27
|
+
return {
|
|
28
|
+
PlanEdit: `### Checklist (editing existing plan)
|
|
29
|
+
|
|
30
|
+
An existing plan comment was found for this issue. Update that comment with the revised plan — do not create a new plan comment.
|
|
31
|
+
|
|
32
|
+
1. **task list**: create your task list for this run as your first action.
|
|
33
|
+
2. Use \`previousPlanBody\` from this response as the plan to revise; do not call \`get_issue\` or \`get_issue_comments\`.
|
|
34
|
+
3. Revise the plan based on the user's request:
|
|
35
|
+
- incorporate the current plan (\`previousPlanBody\`) and the user's revision request
|
|
36
|
+
- gather relevant codebase context (file paths, architecture notes from AGENTS.md)
|
|
37
|
+
- produce a structured plan with clear milestones
|
|
38
|
+
4. Call \`${t("report_progress")}\` with the full revised plan text and \`{ target_plan_comment: true }\` so it updates the existing plan comment (not the progress comment).
|
|
39
|
+
5. Then post a short note to the progress comment (e.g. "Plan has been updated in the comment above.") via \`${t("report_progress")}\` so it is not left as "Leaping...".`,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
type OrchestratorGuidance = {
|
|
44
|
+
modeName: string;
|
|
45
|
+
description: string;
|
|
46
|
+
orchestratorGuidance: string;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// IncrementalReview and TerraformCodeReview inherit Review's user instructions
|
|
50
|
+
// (the org review_instructions + fp_filtering_instructions land on the "Review"
|
|
51
|
+
// key), Fix inherits Build's. Without TerraformCodeReview here its FP addendum
|
|
52
|
+
// never reaches the mode, so its FINDING_VERIFICATION_PASS asks the orchestrator
|
|
53
|
+
// to include a `### Finding precedents — org addendum` section that doesn't exist.
|
|
54
|
+
const modeInstructionParent: Record<string, string> = {
|
|
55
|
+
IncrementalReview: "Review",
|
|
56
|
+
TerraformCodeReview: "Review",
|
|
57
|
+
Fix: "Build",
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
function buildOrchestratorGuidance(
|
|
61
|
+
ctx: ToolContext,
|
|
62
|
+
mode: Mode,
|
|
63
|
+
overrideGuidance?: string,
|
|
64
|
+
): OrchestratorGuidance {
|
|
65
|
+
const hardcoded = overrideGuidance ?? mode.prompt ?? "";
|
|
66
|
+
const lookupKey = modeInstructionParent[mode.name] ?? mode.name;
|
|
67
|
+
const userInstructions = ctx.modeInstructions[lookupKey] ?? "";
|
|
68
|
+
const guidance = [hardcoded, userInstructions].filter(Boolean).join("\n\n");
|
|
69
|
+
return {
|
|
70
|
+
modeName: mode.name,
|
|
71
|
+
description: mode.description,
|
|
72
|
+
orchestratorGuidance: guidance,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// matches the API response for /repo/[owner]/[repo]/issue/[issueNumber]/plan-comment
|
|
77
|
+
export type PlanCommentResponsePayload =
|
|
78
|
+
| { error: string }
|
|
79
|
+
| { commentId: number; body: string };
|
|
80
|
+
|
|
81
|
+
// IMPORTANT: this route authenticates via GitHub installation token (getEnrichedRepo),
|
|
82
|
+
// NOT the Infraweaver API JWT (ctx.apiToken). use ctx.githubInstallationToken here.
|
|
83
|
+
// see wiki/api-auth.md for the two auth patterns.
|
|
84
|
+
async function fetchExistingPlanComment(
|
|
85
|
+
ctx: ToolContext,
|
|
86
|
+
issueNumber: number,
|
|
87
|
+
): Promise<Extract<PlanCommentResponsePayload, { commentId: number }> | null> {
|
|
88
|
+
if (!ctx.githubInstallationToken) return null;
|
|
89
|
+
try {
|
|
90
|
+
const response = await cloudRequest({
|
|
91
|
+
path: `/api/repo/${ctx.repo.owner}/${ctx.repo.name}/issue/${issueNumber}/plan-comment`,
|
|
92
|
+
method: "GET",
|
|
93
|
+
credential: ctx.githubInstallationToken,
|
|
94
|
+
timeoutMs: 10_000,
|
|
95
|
+
});
|
|
96
|
+
const data = (await response.json()) as PlanCommentResponsePayload;
|
|
97
|
+
return response.ok && "commentId" in data ? data : null;
|
|
98
|
+
} catch {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const SUMMARY_MODES = new Set(["Review", "IncrementalReview", "Task"]);
|
|
104
|
+
|
|
105
|
+
/** modes that gain the PR summary edit step when toolState.summaryFilePath is set.
|
|
106
|
+
*
|
|
107
|
+
* NOTE: this snapshot is an internal artifact consumed by future agent runs. it is
|
|
108
|
+
* deliberately NOT shaped by user-supplied summary instructions — those would warp
|
|
109
|
+
* the durable agent context. user-facing summarization (e.g. the review body's
|
|
110
|
+
* "Reviewed changes" section) is governed by review-mode prompts and review
|
|
111
|
+
* instructions, separately from this snapshot. */
|
|
112
|
+
function buildSummaryAddendum(
|
|
113
|
+
t: (name: string) => string,
|
|
114
|
+
ctx: ToolContext,
|
|
115
|
+
): string {
|
|
116
|
+
const filePath = ctx.toolState.summaryFilePath;
|
|
117
|
+
if (!filePath) return "";
|
|
118
|
+
return `### PR summary snapshot — required step
|
|
119
|
+
|
|
120
|
+
A rolling PR summary lives at \`${filePath}\`. It is your durable cross-run agent context — a functional summary of what this PR does, the subsystems and files it touches, the material behavior of its changes, and any risks or open questions worth carrying forward. It is NOT a chronological log of past review runs; commit-level history can already be reconstructed from \`${t("list_pull_request_reviews")}\`.
|
|
121
|
+
|
|
122
|
+
How to use it:
|
|
123
|
+
|
|
124
|
+
- read \`${filePath}\` at the START of the run, alongside the diff. it represents what previous agent runs already understood about this PR — absorb it before picking lenses or crafting subagent dispatch prompts. if it's a fresh seed (file is one or two lines), this is a first review and you'll be filling it in from the diff.
|
|
125
|
+
- let the snapshot inform triage and dispatch. when it already tracks a risk, your lens prompts to subagents are stronger when they reference that context (e.g. "the JSDoc explicitly scopes to code points — do not flag grapheme-cluster issues" if the snapshot already documents that contract). when something the snapshot tracks is now resolved by new commits, note that. when new commits introduce something the snapshot doesn't yet describe, that's exactly where your fan-out should focus.
|
|
126
|
+
- update the file in place to reflect the PR's CURRENT state. revise stale claims, drop resolved risks, add new behavior or risks. accuracy over breadth — every claim must be grounded in the diff. write for the next agent run, not for a human.
|
|
127
|
+
- structure however serves THIS PR. there is no required section template. a refactor might organize by renamed export and call-site impact; a feature by capability; a billing change by money path. a compact note of which commit ranges have been reviewed should always be present so future runs scope correctly, but the rest is your call. when the structure works across runs, keep it stable so range-diffs are clean; when the PR's character changes (e.g. scope expands), reshape.
|
|
128
|
+
|
|
129
|
+
Do NOT call \`${t("create_issue_comment")}\` for the summary — the server reads this file at end-of-run and persists it. The file edit is mandatory regardless of whether a review is submitted; the snapshot feeds the next run.`;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function SelectModeTool(ctx: ToolContext) {
|
|
133
|
+
const t = (name: string) => formatMcpToolRef(ctx.agentId, name);
|
|
134
|
+
const overrides = buildModeOverrides(t);
|
|
135
|
+
|
|
136
|
+
return tool({
|
|
137
|
+
mutates: true,
|
|
138
|
+
name: "select_mode",
|
|
139
|
+
description:
|
|
140
|
+
"Select a mode and receive step-by-step guidance on how to handle the task. Call this to understand the best workflow for the current mode. " +
|
|
141
|
+
'Example: `select_mode({ mode: "Review" })` or `select_mode({ mode: "Plan", issue_number: 1234 })`.',
|
|
142
|
+
parameters: SelectModeParams,
|
|
143
|
+
execute: execute(async (params) => {
|
|
144
|
+
if (ctx.toolState.selectedMode) {
|
|
145
|
+
return {
|
|
146
|
+
error: `mode already selected: "${ctx.toolState.selectedMode}". mode selection is final and cannot be changed. complete your current workflow within this mode.`,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const modeName = params.mode;
|
|
151
|
+
|
|
152
|
+
const selectedMode = resolveMode(ctx.modes, modeName);
|
|
153
|
+
|
|
154
|
+
if (!selectedMode) {
|
|
155
|
+
const availableModes = ctx.modes.map((m) => m.name).join(", ");
|
|
156
|
+
return {
|
|
157
|
+
error: `mode "${modeName}" not found. available modes: ${availableModes}`,
|
|
158
|
+
availableModes: ctx.modes.map((m) => ({
|
|
159
|
+
name: m.name,
|
|
160
|
+
description: m.description,
|
|
161
|
+
})),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
ctx.toolState.selectedMode = selectedMode.name;
|
|
166
|
+
// publish the write-time path policy for the agent gates. mode selection
|
|
167
|
+
// is final (see the guard above), so this runs exactly once per run — and
|
|
168
|
+
// it must run HERE rather than at agent launch, because an auto-selected
|
|
169
|
+
// mode isn't known until this point.
|
|
170
|
+
refreshWritePolicy(ctx);
|
|
171
|
+
|
|
172
|
+
if (selectedMode.name === "Plan") {
|
|
173
|
+
const issueNumber =
|
|
174
|
+
params.issue_number ?? ctx.payload.event.issue_number;
|
|
175
|
+
if (issueNumber !== undefined) {
|
|
176
|
+
const existing = await fetchExistingPlanComment(ctx, issueNumber);
|
|
177
|
+
if (existing !== null) {
|
|
178
|
+
ctx.toolState.existingPlanCommentId = existing.commentId;
|
|
179
|
+
ctx.toolState.previousPlanBody = existing.body;
|
|
180
|
+
return {
|
|
181
|
+
...buildOrchestratorGuidance(
|
|
182
|
+
ctx,
|
|
183
|
+
selectedMode,
|
|
184
|
+
overrides.PlanEdit,
|
|
185
|
+
),
|
|
186
|
+
previousPlanBody: existing.body,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const summaryAddendum = SUMMARY_MODES.has(selectedMode.name)
|
|
193
|
+
? buildSummaryAddendum(t, ctx)
|
|
194
|
+
: "";
|
|
195
|
+
|
|
196
|
+
const base = buildOrchestratorGuidance(ctx, selectedMode);
|
|
197
|
+
if (summaryAddendum.length > 0) {
|
|
198
|
+
return {
|
|
199
|
+
...base,
|
|
200
|
+
orchestratorGuidance: `${base.orchestratorGuidance}\n\n${summaryAddendum}`,
|
|
201
|
+
summaryFilePath: ctx.toolState.summaryFilePath,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
return base;
|
|
205
|
+
}),
|
|
206
|
+
});
|
|
207
|
+
}
|