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,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The path-decision half of the write-time gates, emitted as source text that
|
|
3
|
+
* both agent runtimes embed into the standalone scripts they drop in the run
|
|
4
|
+
* tmpdir (see action/agents/claudePretoolGate.ts and
|
|
5
|
+
* action/agents/opencodePlugin.ts).
|
|
6
|
+
*
|
|
7
|
+
* It lives in one place because the two runtimes previously derived their base
|
|
8
|
+
* directory differently (the hook payload's `cwd` vs `process.cwd()`), which
|
|
9
|
+
* would silently misalign every glob the moment one of them changed. Sharing
|
|
10
|
+
* the source keeps a single definition of "is this write allowed", and keeps it
|
|
11
|
+
* aligned with the push-time gates in action/mcp/guardrails.ts that re-check
|
|
12
|
+
* the same globs.
|
|
13
|
+
*
|
|
14
|
+
* The emitted code is dependency-free (node builtins only) because the scripts
|
|
15
|
+
* run outside the bundle, with no module resolution available to them.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { globToRegex } from "#app/mcp/guardrails";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Shared helper source. Defines `refuseWrite(policy, rawPath, root)` returning
|
|
22
|
+
* a refusal string or null, plus the primitives it needs. Callers supply their
|
|
23
|
+
* own `targetPathOf` because the two runtimes name tool arguments differently.
|
|
24
|
+
*/
|
|
25
|
+
export const WRITE_GATE_HELPERS_SOURCE = `
|
|
26
|
+
import { readFileSync, realpathSync } from "node:fs";
|
|
27
|
+
import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
28
|
+
|
|
29
|
+
// embedded verbatim from globToRegex in action/mcp/guardrails.ts via
|
|
30
|
+
// Function.prototype.toString, so these gates and the push-time guardrails
|
|
31
|
+
// share one definition of glob membership rather than a copy that can drift.
|
|
32
|
+
// The function is a self-contained named declaration, which is what keeps this
|
|
33
|
+
// valid through esbuild bundling and minification.
|
|
34
|
+
const globToRegex = ${globToRegex.toString()};
|
|
35
|
+
|
|
36
|
+
function matchesAny(path, globs) {
|
|
37
|
+
if (!Array.isArray(globs)) return false;
|
|
38
|
+
return globs.some((g) => globToRegex(g).test(path));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Deny-list membership. Matches case-insensitively IN ADDITION to exactly:
|
|
43
|
+
* macOS and Windows resolve \`PROD/main.tf\` and \`prod/main.tf\` to the same
|
|
44
|
+
* file, so a case variant must not slip past protected_paths. The allow-list
|
|
45
|
+
* deliberately stays case-sensitive — failing closed there is an inconvenience,
|
|
46
|
+
* whereas failing open on a deny-list is a security hole.
|
|
47
|
+
*/
|
|
48
|
+
function denyMatches(path, globs) {
|
|
49
|
+
if (matchesAny(path, globs)) return true;
|
|
50
|
+
if (!Array.isArray(globs)) return false;
|
|
51
|
+
const lower = path.toLowerCase();
|
|
52
|
+
return globs.some((g) => globToRegex(String(g).toLowerCase()).test(lower));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Resolve to a real path, following symlinks on the deepest EXISTING ancestor.
|
|
57
|
+
* resolve() alone is purely lexical, so a symlink planted inside the checkout
|
|
58
|
+
* ("link" -> "../outside") would produce a repo-relative path that passes every
|
|
59
|
+
* glob while the write itself lands outside the work tree — where the push-time
|
|
60
|
+
* guardrails can never see it, because \`git diff\` does not report it.
|
|
61
|
+
*/
|
|
62
|
+
function realDeepest(p) {
|
|
63
|
+
let current = resolve(p);
|
|
64
|
+
const trailing = [];
|
|
65
|
+
for (;;) {
|
|
66
|
+
try {
|
|
67
|
+
const real = realpathSync(current);
|
|
68
|
+
return trailing.length === 0 ? real : join(real, ...trailing.slice().reverse());
|
|
69
|
+
} catch {
|
|
70
|
+
const parent = dirname(current);
|
|
71
|
+
// reached the filesystem root without finding anything that exists —
|
|
72
|
+
// fall back to the lexical resolution rather than looping forever.
|
|
73
|
+
if (parent === current) return resolve(p);
|
|
74
|
+
trailing.push(basename(current));
|
|
75
|
+
current = parent;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Repo-root-relative POSIX path, matching what \`git diff --name-only\` yields
|
|
82
|
+
* for the push-time gates, or null when the write escapes the workspace.
|
|
83
|
+
*
|
|
84
|
+
* The base is the REPO ROOT, never the process cwd: main.ts chdir()s into the
|
|
85
|
+
* \`cwd\` input for monorepo subdirectories, and the push-time globs are always
|
|
86
|
+
* repo-root-relative, so resolving against cwd would misalign every glob in
|
|
87
|
+
* exactly the runs that configure one.
|
|
88
|
+
*/
|
|
89
|
+
function repoRelativePath(rawPath, root) {
|
|
90
|
+
const realRoot = realDeepest(root);
|
|
91
|
+
const absolute = isAbsolute(rawPath) ? rawPath : resolve(realRoot, rawPath);
|
|
92
|
+
const rel = relative(realRoot, realDeepest(absolute)).replace(/\\\\/g, "/");
|
|
93
|
+
if (rel === "" || rel === ".." || rel.startsWith("../")) return null;
|
|
94
|
+
// on Windows, path.relative returns an ABSOLUTE path when the two roots
|
|
95
|
+
// differ (another drive letter, or a UNC share). Such a path must be a
|
|
96
|
+
// refusal, not something that happens to match \`**/*.tf\`.
|
|
97
|
+
if (isAbsolute(rel) || rel.startsWith("//")) return null;
|
|
98
|
+
return rel;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Refusal string when the write must be blocked, or null to allow. Deny-lists
|
|
103
|
+
* are checked BEFORE the allow-list: a .tf file inside protected_paths matches
|
|
104
|
+
* the allow-list too, and must still be refused. A policy whose arrays are
|
|
105
|
+
* missing or malformed fails CLOSED — an unusable policy must not silently
|
|
106
|
+
* become a pass.
|
|
107
|
+
*/
|
|
108
|
+
function refuseWrite(policy, rawPath, root) {
|
|
109
|
+
const rel = repoRelativePath(rawPath, root);
|
|
110
|
+
if (rel === null) {
|
|
111
|
+
return "write blocked (protected-paths guardrail): '" + rawPath +
|
|
112
|
+
"' resolves outside the repository workspace. Write only inside the checkout.";
|
|
113
|
+
}
|
|
114
|
+
if (denyMatches(rel, policy.protected)) {
|
|
115
|
+
return "write blocked (protected-paths guardrail): '" + rel +
|
|
116
|
+
"' matches the protected_paths globs [" + (policy.protected || []).join(", ") +
|
|
117
|
+
"], which are marked never-auto-modify. Leave this file for a human and fix the concern elsewhere.";
|
|
118
|
+
}
|
|
119
|
+
if (denyMatches(rel, policy.vendored)) {
|
|
120
|
+
return "write blocked (read-only module guardrail): '" + rel +
|
|
121
|
+
"' is FETCHED module code under the local module cache, which is read-only. " +
|
|
122
|
+
"Fix a module-internal concern at the CALL SITE via the module's inputs, never by editing the vendored copy.";
|
|
123
|
+
}
|
|
124
|
+
if (!Array.isArray(policy.allowed) || !matchesAny(rel, policy.allowed)) {
|
|
125
|
+
return "write blocked (Terraform-only guardrail): '" + rel +
|
|
126
|
+
"' is outside the allowed paths [" + (policy.allowed || []).join(", ") +
|
|
127
|
+
"]. " + policy.mode + " must only touch Terraform files — keep the change to those.";
|
|
128
|
+
}
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function readWritePolicy(policyPath) {
|
|
133
|
+
try {
|
|
134
|
+
const parsed = JSON.parse(readFileSync(policyPath, "utf8"));
|
|
135
|
+
// an absent/empty mode is the "no guarded mode selected" signal — the
|
|
136
|
+
// policy file exists for the whole run but only restricts once a guarded
|
|
137
|
+
// mode is chosen, mirroring the push-time gates' isGuardedMode() no-op.
|
|
138
|
+
if (!parsed || typeof parsed.mode !== "string" || parsed.mode === "") return null;
|
|
139
|
+
if (typeof parsed.root !== "string" || parsed.root === "") return null;
|
|
140
|
+
return parsed;
|
|
141
|
+
} catch {
|
|
142
|
+
// no policy published yet (or unreadable). the push-time guardrails remain
|
|
143
|
+
// the fail-closed backstop, so allowing here cannot let a bad change reach
|
|
144
|
+
// a PR — it only defers the refusal to push time.
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
`;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The write-time counterpart to the push-time path guardrails in
|
|
3
|
+
* `action/mcp/guardrails.ts`.
|
|
4
|
+
*
|
|
5
|
+
* Those gates (`enforceRemediationPaths`, `enforceProtectedPaths`,
|
|
6
|
+
* `assertNoVendoredModuleEdits`) all read `git diff <run-start> HEAD` — so they
|
|
7
|
+
* only fire once a change is already committed and heading for a push. That is
|
|
8
|
+
* fail-safe but LATE: between the write and the push the modified tree is what
|
|
9
|
+
* every subsequent subprocess sees, so a `terraform plan` or a re-scan can run
|
|
10
|
+
* against a file the guardrails would ultimately refuse. This module moves the
|
|
11
|
+
* same allow/deny decision to the moment of the write itself.
|
|
12
|
+
*
|
|
13
|
+
* SCOPE — this covers the agent's file-writing TOOLS, not every possible write.
|
|
14
|
+
* It deliberately does not cover:
|
|
15
|
+
* - the MCP `shell` tool (`cat > f`, `tee`, `sed -i`), which is bounded by
|
|
16
|
+
* the OS sandbox in `action/mcp/shell.ts` rather than by these globs;
|
|
17
|
+
* - the file-emitting MCP tools (`terraform_emit_sarif`, `_emit_evidence`,
|
|
18
|
+
* `_emit_oscal`, `_emit_vex`, `terraform_module_docs`), whose output paths
|
|
19
|
+
* are confined to the workspace by `resolveWithinCwd` but not to
|
|
20
|
+
* `allowed_paths`.
|
|
21
|
+
* Both remain covered by the push-time gates, which still fail closed, so
|
|
22
|
+
* neither is a route to a merged PR — but neither is stopped at write time.
|
|
23
|
+
*
|
|
24
|
+
* The policy is published as a small JSON file in the run's tmpdir rather than
|
|
25
|
+
* baked into the agent's gate script, because `select_mode` sets
|
|
26
|
+
* `toolState.selectedMode` DURING the run (see action/mcp/selectMode.ts) while
|
|
27
|
+
* the gate script is written before the agent launches. The gate re-reads this
|
|
28
|
+
* file on every tool call, so an auto-selected mode is picked up without
|
|
29
|
+
* restarting the agent. No file (or a non-guarded mode) means no restriction —
|
|
30
|
+
* exactly matching the push-time gates, which no-op outside a guarded mode.
|
|
31
|
+
*
|
|
32
|
+
* Both agent runtimes consume it: action/agents/claudePretoolGate.ts (Claude
|
|
33
|
+
* Code `PreToolUse`) and action/agents/opencodePlugin.ts
|
|
34
|
+
* (`tool.execute.before`).
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
import { renameSync, writeFileSync } from "node:fs";
|
|
38
|
+
import { join } from "node:path";
|
|
39
|
+
import {
|
|
40
|
+
type GuardrailContext,
|
|
41
|
+
isGuardedModeName,
|
|
42
|
+
resolveAllowedPaths,
|
|
43
|
+
resolveProtectedPaths,
|
|
44
|
+
VENDORED_MODULE_PATHS,
|
|
45
|
+
} from "#app/mcp/guardrails";
|
|
46
|
+
import { resolveRepoRoot } from "#app/mcp/shell";
|
|
47
|
+
import { log } from "#app/utils/cli";
|
|
48
|
+
|
|
49
|
+
export const WRITE_POLICY_FILENAME = "infraweaver-write-policy.json" as const;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* What the gate scripts read. Deliberately a flat, dependency-free shape: the
|
|
53
|
+
* gates are plain `.mjs` with no imports, so anything richer would have to be
|
|
54
|
+
* re-modelled on the other side.
|
|
55
|
+
*/
|
|
56
|
+
export interface WritePolicy {
|
|
57
|
+
/** the guarded mode in force — surfaced in the refusal so the model can reason about it. */
|
|
58
|
+
mode: string;
|
|
59
|
+
/**
|
|
60
|
+
* The repo root every glob is resolved against. Carried in the policy rather
|
|
61
|
+
* than derived inside the gates because `main.ts` chdir()s into the `cwd`
|
|
62
|
+
* input for monorepo subdirectories, so neither gate's own process cwd is a
|
|
63
|
+
* safe base — and the push-time globs are always repo-root-relative.
|
|
64
|
+
*/
|
|
65
|
+
root: string;
|
|
66
|
+
/** globs a write MUST match (the `allowed_paths` allow-list). */
|
|
67
|
+
allowed: string[];
|
|
68
|
+
/** globs a write must NOT match (the `protected_paths` deny-list). */
|
|
69
|
+
protected: string[];
|
|
70
|
+
/** fetched/vendored module code, which is read-only by the refactor contract. */
|
|
71
|
+
vendored: string[];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Derive the policy for the current run, or `null` when no restriction applies
|
|
76
|
+
* (no mode selected yet, or a mode outside the guarded set — Review, Plan,
|
|
77
|
+
* Assess and friends legitimately write files the Terraform-only allow-list
|
|
78
|
+
* would reject, so gating them would break them).
|
|
79
|
+
*/
|
|
80
|
+
export function buildWritePolicy(ctx: GuardrailContext): WritePolicy | null {
|
|
81
|
+
const mode = ctx.toolState.selectedMode;
|
|
82
|
+
if (!mode || !isGuardedModeName(mode)) return null;
|
|
83
|
+
return {
|
|
84
|
+
mode,
|
|
85
|
+
root: resolveRepoRoot(),
|
|
86
|
+
allowed: resolveAllowedPaths(ctx),
|
|
87
|
+
protected: resolveProtectedPaths(ctx),
|
|
88
|
+
vendored: [...VENDORED_MODULE_PATHS],
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function writePolicyPath(tmpdir: string): string {
|
|
93
|
+
return join(tmpdir, WRITE_POLICY_FILENAME);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Publish (or clear) the policy for the gates to read.
|
|
98
|
+
*
|
|
99
|
+
* Written via a temp file + `rename` so a gate that reads concurrently sees
|
|
100
|
+
* either the old policy or the new one, never a half-written file — `rename` is
|
|
101
|
+
* atomic within a filesystem, and the temp file is created in the same tmpdir.
|
|
102
|
+
*
|
|
103
|
+
* Best-effort by design: the push-time guardrails remain the authoritative,
|
|
104
|
+
* fail-closed backstop, so a failure to publish must not abort a run that would
|
|
105
|
+
* otherwise be blocked correctly a few steps later. It is logged, not thrown.
|
|
106
|
+
*/
|
|
107
|
+
export function refreshWritePolicy(ctx: GuardrailContext): void {
|
|
108
|
+
// everything, including resolving the path, sits inside the try: this is
|
|
109
|
+
// called from the select_mode hot path and must never be able to fail a run.
|
|
110
|
+
// A context without a tmpdir (or an unwritable one) degrades to "no policy
|
|
111
|
+
// published", which the gates read as "no restriction" — the same posture as
|
|
112
|
+
// before this gate existed, with the push-time guardrails still fail-closed.
|
|
113
|
+
try {
|
|
114
|
+
const policy = buildWritePolicy(ctx);
|
|
115
|
+
const target = writePolicyPath(ctx.tmpdir);
|
|
116
|
+
const staging = `${target}.${process.pid}.tmp`;
|
|
117
|
+
// an absent `mode` is the "no restriction" signal the gates already handle,
|
|
118
|
+
// so clearing is just publishing a policy with no mode rather than deleting
|
|
119
|
+
// the file (which would race with a concurrent read).
|
|
120
|
+
writeFileSync(staging, JSON.stringify(policy ?? { mode: "" }), "utf8");
|
|
121
|
+
renameSync(staging, target);
|
|
122
|
+
} catch (err) {
|
|
123
|
+
// warning, not debug: this silently disables write-time enforcement for the
|
|
124
|
+
// whole run, and the only remaining signal would be a push-time refusal
|
|
125
|
+
// much later. The run is still safe (push-time gates fail closed) but the
|
|
126
|
+
// operator should see that a layer went missing.
|
|
127
|
+
log.warning(
|
|
128
|
+
`could not publish the write policy — write-time path enforcement is disabled for this run ` +
|
|
129
|
+
`(push-time guardrails still apply): ${err instanceof Error ? err.message : String(err)}`,
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
}
|
package/src/brand.ts
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for the product brand on the engine side.
|
|
3
|
+
*
|
|
4
|
+
* Every user-visible product name, slug, prefix, and brand-derived filename
|
|
5
|
+
* must come from this module — a rebrand (or a white-label build) is then a
|
|
6
|
+
* handful of one-line edits here. The one permitted exception is `action.yml`,
|
|
7
|
+
* which is static YAML and cannot import; src/brand.test.ts asserts it stays
|
|
8
|
+
* in sync with these values.
|
|
9
|
+
*
|
|
10
|
+
* The reviewer subagent name is NOT defined here — it is a separate sub-brand
|
|
11
|
+
* owned by `REVIEWER_AGENT_NAME` in src/agents/reviewer.ts.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/** Display name — PR bodies, review comments, run summaries, agent labels. */
|
|
15
|
+
export const PRODUCT_NAME = "Infraweaver";
|
|
16
|
+
|
|
17
|
+
/** Lowercase wordmark — package/dir names, CLI usage strings, slugs. */
|
|
18
|
+
export const PRODUCT_SLUG = "infraweaver";
|
|
19
|
+
|
|
20
|
+
/** PR comment trigger, e.g. `@infraweaver fix`. */
|
|
21
|
+
export const COMMENT_COMMAND = `@${PRODUCT_SLUG}`;
|
|
22
|
+
|
|
23
|
+
/** SARIF `driver.name`, CycloneDX VEX tool component, evidence `tool.name` —
|
|
24
|
+
* the emitted artifacts all use the lowercase wordmark. */
|
|
25
|
+
export const TOOL_NAME = PRODUCT_SLUG;
|
|
26
|
+
|
|
27
|
+
/** Cloud API token prefix — must match the Cloud UI's `TOKEN_PREFIX`. */
|
|
28
|
+
export const TOKEN_PREFIX = "tmnd_";
|
|
29
|
+
|
|
30
|
+
/** Prefix for all brand-scoped environment variables. */
|
|
31
|
+
export const ENV_PREFIX = "INFRAWEAVER_";
|
|
32
|
+
|
|
33
|
+
/** Primary domain — the Cloud API's default host and bearer-credential allowlist root. */
|
|
34
|
+
export const PRIMARY_DOMAIN = "infraweaver.dev";
|
|
35
|
+
/** Default Cloud API base URL. */
|
|
36
|
+
export const DEFAULT_API_URL = `https://${PRIMARY_DOMAIN}`;
|
|
37
|
+
/** Docs subdomain, used in in-product setup links. */
|
|
38
|
+
export const DOCS_URL = `https://docs.${PRIMARY_DOMAIN}`;
|
|
39
|
+
/** Status-page subdomain, linked from transient-error messages. */
|
|
40
|
+
export const STATUS_URL = `https://status.${PRIMARY_DOMAIN}`;
|
|
41
|
+
/** Asset-hosting subdomain, used for static images embedded in PR/issue markdown. */
|
|
42
|
+
export const UPLOADS_URL = `https://uploads.${PRIMARY_DOMAIN}`;
|
|
43
|
+
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// Brand-derived filenames (repo config, state, and emitted artifacts).
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
|
|
48
|
+
/** Repo config file (YAML). */
|
|
49
|
+
export const CONFIG_FILE = `.${PRODUCT_SLUG}.yml`;
|
|
50
|
+
/** Repo config file (`.yaml` spelling variant). */
|
|
51
|
+
export const CONFIG_FILE_YAML = `.${PRODUCT_SLUG}.yaml`;
|
|
52
|
+
/** Repo config file (JSON variant). */
|
|
53
|
+
export const CONFIG_FILE_JSON = `.${PRODUCT_SLUG}.json`;
|
|
54
|
+
/** Committed baseline of accepted pre-existing findings. */
|
|
55
|
+
export const BASELINE_FILE = `.${PRODUCT_SLUG}.baseline.json`;
|
|
56
|
+
/** Committed fix-memory (proven-fix recall) file. */
|
|
57
|
+
export const FIX_MEMORY_FILE = `.${PRODUCT_SLUG}.fix-memory.json`;
|
|
58
|
+
/** Repo-committed reviewer learnings file seeded by the server. */
|
|
59
|
+
export const LEARNINGS_FILE = `${PRODUCT_SLUG}-learnings.md`;
|
|
60
|
+
/** Rolling PR summary snapshot file. */
|
|
61
|
+
export const SUMMARY_FILE = `${PRODUCT_SLUG}-summary.md`;
|
|
62
|
+
/** Signed evidence bundle. */
|
|
63
|
+
export const EVIDENCE_FILE = `${PRODUCT_SLUG}-evidence.json`;
|
|
64
|
+
/** Detached signature for the evidence bundle. */
|
|
65
|
+
export const EVIDENCE_SIG_FILE = `${EVIDENCE_FILE}.sig`;
|
|
66
|
+
/** SARIF report. */
|
|
67
|
+
export const SARIF_FILE = `${PRODUCT_SLUG}.sarif`;
|
|
68
|
+
/** CycloneDX VEX document. */
|
|
69
|
+
export const VEX_FILE = `${PRODUCT_SLUG}-vex.cdx.json`;
|
|
70
|
+
/** OSCAL Assessment Results document. */
|
|
71
|
+
export const OSCAL_FILE = `${PRODUCT_SLUG}-oscal.json`;
|
|
72
|
+
/** Credential-free cost-analysis artifact committed to the PR (§5.19). */
|
|
73
|
+
export const COST_FILE = "cost.md";
|
|
74
|
+
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
// Brand-derived identities.
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
|
|
79
|
+
/** The product's GitHub App bot login. */
|
|
80
|
+
export const BOT_LOGIN = `${PRODUCT_SLUG}[bot]`;
|
|
81
|
+
/** The bot's GitHub noreply commit-author email. */
|
|
82
|
+
export const BOT_EMAIL = `${BOT_LOGIN}@users.noreply.github.com`;
|
|
83
|
+
/** Default GitHub Actions OIDC audience for the product API. */
|
|
84
|
+
export const OIDC_AUDIENCE = `${PRODUCT_SLUG}-api`;
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { basename } from "node:path";
|
|
2
|
+
import arg from "arg";
|
|
3
|
+
import pc from "picocolors";
|
|
4
|
+
import { PRODUCT_SLUG } from "#app/brand";
|
|
5
|
+
import { runCli as runGhaCli } from "#app/commands/gha";
|
|
6
|
+
import { runMcpCli } from "#app/commands/mcp";
|
|
7
|
+
import { runVerifyEvidenceCli } from "#app/commands/verifyEvidence";
|
|
8
|
+
|
|
9
|
+
const VERSION = process.env.CLI_VERSION ?? "0.0.0";
|
|
10
|
+
const bin = basename(process.argv[1] || "");
|
|
11
|
+
const PROG = bin === "pf" || bin === PRODUCT_SLUG ? bin : PRODUCT_SLUG;
|
|
12
|
+
const rawArgs = process.argv.slice(2);
|
|
13
|
+
|
|
14
|
+
function printMainUsage(stream: typeof console.log): void {
|
|
15
|
+
stream(`usage: ${PROG} <command>\n`);
|
|
16
|
+
stream("commands:");
|
|
17
|
+
stream(" gha run the github action runtime flow (used by action.yml)");
|
|
18
|
+
stream(" mcp start the local MCP server (stdio) with read-only terraform tools");
|
|
19
|
+
stream(" verify-evidence verify a signed evidence bundle's detached Ed25519 signature");
|
|
20
|
+
stream("");
|
|
21
|
+
stream("global options:");
|
|
22
|
+
stream(" -h, --help show help");
|
|
23
|
+
stream(" -v, --version show version");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function parseGlobalArgs(args: string[]) {
|
|
27
|
+
return arg(
|
|
28
|
+
{
|
|
29
|
+
"--help": Boolean,
|
|
30
|
+
"--version": Boolean,
|
|
31
|
+
"-h": "--help",
|
|
32
|
+
"-v": "--version",
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
argv: args,
|
|
36
|
+
stopAtPositional: true,
|
|
37
|
+
},
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function exitWithUsageError(message: string): never {
|
|
42
|
+
console.error(`${message}\n`);
|
|
43
|
+
printMainUsage(console.error);
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function run(): Promise<void> {
|
|
48
|
+
let globalParsed: ReturnType<typeof parseGlobalArgs>;
|
|
49
|
+
try {
|
|
50
|
+
globalParsed = parseGlobalArgs(rawArgs);
|
|
51
|
+
} catch (error) {
|
|
52
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
53
|
+
exitWithUsageError(message);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (globalParsed["--version"]) {
|
|
57
|
+
console.log(VERSION);
|
|
58
|
+
process.exit(0);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const command = globalParsed._[0];
|
|
62
|
+
const commandArgs = globalParsed._.slice(1);
|
|
63
|
+
|
|
64
|
+
if (!command) {
|
|
65
|
+
if (globalParsed["--help"]) {
|
|
66
|
+
console.log(`${pc.bold(PRODUCT_SLUG)} v${VERSION}\n`);
|
|
67
|
+
printMainUsage(console.log);
|
|
68
|
+
process.exit(0);
|
|
69
|
+
}
|
|
70
|
+
printMainUsage(console.log);
|
|
71
|
+
process.exit(0);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (command === "gha") {
|
|
75
|
+
await runGhaCli({
|
|
76
|
+
args: commandArgs,
|
|
77
|
+
prog: PROG,
|
|
78
|
+
showHelp: globalParsed["--help"] === true,
|
|
79
|
+
});
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (command === "mcp") {
|
|
84
|
+
await runMcpCli({
|
|
85
|
+
args: commandArgs,
|
|
86
|
+
prog: PROG,
|
|
87
|
+
showHelp: globalParsed["--help"] === true,
|
|
88
|
+
});
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (command === "verify-evidence") {
|
|
93
|
+
await runVerifyEvidenceCli({
|
|
94
|
+
args: commandArgs,
|
|
95
|
+
prog: PROG,
|
|
96
|
+
showHelp: globalParsed["--help"] === true,
|
|
97
|
+
});
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (globalParsed["--help"]) {
|
|
102
|
+
printMainUsage(console.log);
|
|
103
|
+
process.exit(0);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
console.error(`unknown command: ${pc.bold(command)}\n`);
|
|
107
|
+
printMainUsage(console.error);
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
await run();
|
|
113
|
+
} catch (error) {
|
|
114
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
115
|
+
console.error(pc.red(message));
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { dirname } from "node:path";
|
|
2
|
+
import * as core from "@actions/core";
|
|
3
|
+
import arg from "arg";
|
|
4
|
+
import { main } from "#app/main";
|
|
5
|
+
import { acquireInstallationToken, revokeInstallationToken } from "#app/utils/token";
|
|
6
|
+
|
|
7
|
+
// GitHub Actions runs the action entry point with the node24 binary specified
|
|
8
|
+
// in action.yml, but doesn't add that binary's directory to PATH. Without this,
|
|
9
|
+
// spawned processes (pnpm, npm, etc.) resolve to the runner's default node (v20).
|
|
10
|
+
process.env.PATH = `${dirname(process.execPath)}:${process.env.PATH}`;
|
|
11
|
+
|
|
12
|
+
const STATE_TOKEN = "token";
|
|
13
|
+
|
|
14
|
+
interface GhaCliParams {
|
|
15
|
+
args: string[];
|
|
16
|
+
prog: string;
|
|
17
|
+
showHelp?: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function runMain(): Promise<void> {
|
|
21
|
+
try {
|
|
22
|
+
const result = await main();
|
|
23
|
+
if (!result.success) {
|
|
24
|
+
throw new Error(result.error || "agent execution failed");
|
|
25
|
+
}
|
|
26
|
+
} catch (error) {
|
|
27
|
+
const errorMessage = error instanceof Error ? error.message : "unknown error occurred";
|
|
28
|
+
core.setFailed(`action failed: ${errorMessage}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function tokenMain(): Promise<void> {
|
|
33
|
+
const reposInput = core.getInput("repos");
|
|
34
|
+
const additionalRepos = reposInput
|
|
35
|
+
? reposInput
|
|
36
|
+
.split(",")
|
|
37
|
+
.map((r) => r.trim())
|
|
38
|
+
.filter(Boolean)
|
|
39
|
+
: [];
|
|
40
|
+
|
|
41
|
+
const token = await acquireInstallationToken({ repos: additionalRepos });
|
|
42
|
+
|
|
43
|
+
core.setSecret(token);
|
|
44
|
+
core.saveState(STATE_TOKEN, token);
|
|
45
|
+
core.setOutput("token", token);
|
|
46
|
+
|
|
47
|
+
const scope = additionalRepos.length
|
|
48
|
+
? `current repo + ${additionalRepos.join(", ")}`
|
|
49
|
+
: "current repo only";
|
|
50
|
+
core.info(`» installation token acquired (${scope})`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function tokenPost(): Promise<void> {
|
|
54
|
+
const token = core.getState(STATE_TOKEN);
|
|
55
|
+
if (!token) {
|
|
56
|
+
core.debug("no token found in state, skipping revocation");
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
await revokeInstallationToken(token);
|
|
60
|
+
core.info("» installation token revoked");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function printGhaUsage(params: { stream: typeof console.log; prog: string }): void {
|
|
64
|
+
params.stream(`usage: ${params.prog} gha [subcommand]\n`);
|
|
65
|
+
params.stream("run the github action runtime flow.");
|
|
66
|
+
params.stream("");
|
|
67
|
+
params.stream("subcommands:");
|
|
68
|
+
params.stream(" token acquire a github app installation token");
|
|
69
|
+
params.stream("");
|
|
70
|
+
params.stream("options:");
|
|
71
|
+
params.stream(" -h, --help show help");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function printGhaTokenUsage(params: { stream: typeof console.log; prog: string }): void {
|
|
75
|
+
params.stream(`usage: ${params.prog} gha token [--post]\n`);
|
|
76
|
+
params.stream("acquire a github app installation token, or revoke it in the post step.");
|
|
77
|
+
params.stream("");
|
|
78
|
+
params.stream("options:");
|
|
79
|
+
params.stream(" -h, --help show help");
|
|
80
|
+
params.stream(" --post revoke the previously-acquired token (post-step usage only)");
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function parseGhaArgs(args: string[]) {
|
|
84
|
+
return arg(
|
|
85
|
+
{
|
|
86
|
+
"--help": Boolean,
|
|
87
|
+
"-h": "--help",
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
argv: args,
|
|
91
|
+
stopAtPositional: true,
|
|
92
|
+
},
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function parseGhaTokenArgs(args: string[]) {
|
|
97
|
+
return arg(
|
|
98
|
+
{
|
|
99
|
+
"--help": Boolean,
|
|
100
|
+
"--post": Boolean,
|
|
101
|
+
"-h": "--help",
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
argv: args,
|
|
105
|
+
},
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export async function runCli(params: GhaCliParams): Promise<void> {
|
|
110
|
+
if (params.showHelp) {
|
|
111
|
+
printGhaUsage({ stream: console.log, prog: params.prog });
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
let parsed: ReturnType<typeof parseGhaArgs>;
|
|
116
|
+
try {
|
|
117
|
+
parsed = parseGhaArgs(params.args);
|
|
118
|
+
} catch (error) {
|
|
119
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
120
|
+
console.error(`${message}\n`);
|
|
121
|
+
printGhaUsage({ stream: console.error, prog: params.prog });
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (parsed["--help"]) {
|
|
126
|
+
printGhaUsage({ stream: console.log, prog: params.prog });
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const positional = parsed._;
|
|
131
|
+
const subcommand = positional[0];
|
|
132
|
+
|
|
133
|
+
if (!subcommand) {
|
|
134
|
+
await run(["gha"]);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (subcommand !== "token") {
|
|
139
|
+
console.error(`unknown gha subcommand: ${subcommand}\n`);
|
|
140
|
+
printGhaUsage({ stream: console.error, prog: params.prog });
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// gha token [--post]
|
|
145
|
+
let tokenParsed: ReturnType<typeof parseGhaTokenArgs>;
|
|
146
|
+
try {
|
|
147
|
+
tokenParsed = parseGhaTokenArgs(positional.slice(1));
|
|
148
|
+
} catch (error) {
|
|
149
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
150
|
+
console.error(`${message}\n`);
|
|
151
|
+
printGhaTokenUsage({ stream: console.error, prog: params.prog });
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (tokenParsed["--help"]) {
|
|
156
|
+
printGhaTokenUsage({ stream: console.log, prog: params.prog });
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (tokenParsed._.length > 0) {
|
|
161
|
+
console.error(`unexpected positional arguments for gha token: ${tokenParsed._.join(" ")}\n`);
|
|
162
|
+
printGhaTokenUsage({ stream: console.error, prog: params.prog });
|
|
163
|
+
process.exit(1);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const normalizedArgs = ["gha", "token"];
|
|
167
|
+
if (tokenParsed["--post"]) {
|
|
168
|
+
normalizedArgs.push("--post");
|
|
169
|
+
}
|
|
170
|
+
await run(normalizedArgs);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export async function run(args: string[]) {
|
|
174
|
+
try {
|
|
175
|
+
if (args.includes("token")) {
|
|
176
|
+
if (args.includes("--post")) {
|
|
177
|
+
await tokenPost();
|
|
178
|
+
} else {
|
|
179
|
+
await tokenMain();
|
|
180
|
+
}
|
|
181
|
+
} else {
|
|
182
|
+
await runMain();
|
|
183
|
+
}
|
|
184
|
+
} catch (error) {
|
|
185
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
186
|
+
core.setFailed(message);
|
|
187
|
+
}
|
|
188
|
+
}
|