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,189 @@
|
|
|
1
|
+
type ProviderErrorPattern = { regex: RegExp; label: string };
|
|
2
|
+
|
|
3
|
+
/** Stable label for the BYOK provider-billing-exhausted classification. */
|
|
4
|
+
export const PROVIDER_BILLING_EXHAUSTED_LABEL = "provider billing exhausted";
|
|
5
|
+
|
|
6
|
+
// status codes are only treated as provider errors when they are adjacent to
|
|
7
|
+
// a recognised status key. this rejects commit SHAs that happen to contain
|
|
8
|
+
// "429", version strings, file hashes, etc.
|
|
9
|
+
const statusKey = `\\b(?:status[_ ]?code|http[_ ]?status|status)["']?\\s*[:=]\\s*["']?`;
|
|
10
|
+
|
|
11
|
+
const PROVIDER_ERROR_PATTERNS: ProviderErrorPattern[] = [
|
|
12
|
+
// billing-payload patterns come BEFORE bare status-code patterns. providers
|
|
13
|
+
// commonly return 401 / 429 for billing/quota exhaustion (OpenCode Zen
|
|
14
|
+
// `CreditsError` / `FreeUsageLimitError`, Gemini `RESOURCE_EXHAUSTED` +
|
|
15
|
+
// "spending cap", Anthropic "Insufficient balance" / "credit balance is
|
|
16
|
+
// too low"). these are non-retryable and require user-billing action —
|
|
17
|
+
// distinct from a transient auth error or rate-limit. status-code patterns
|
|
18
|
+
// would otherwise win and surface "auth error (401)" / "rate limited (429)"
|
|
19
|
+
// with no billing hint. see #778, #835.
|
|
20
|
+
{ regex: /\bCreditsError\b/, label: PROVIDER_BILLING_EXHAUSTED_LABEL },
|
|
21
|
+
{ regex: /\bFreeUsageLimitError\b/, label: PROVIDER_BILLING_EXHAUSTED_LABEL },
|
|
22
|
+
{ regex: /Insufficient balance/i, label: PROVIDER_BILLING_EXHAUSTED_LABEL },
|
|
23
|
+
{
|
|
24
|
+
regex: /credit balance is too low/i,
|
|
25
|
+
label: PROVIDER_BILLING_EXHAUSTED_LABEL,
|
|
26
|
+
},
|
|
27
|
+
{ regex: /spending cap/i, label: PROVIDER_BILLING_EXHAUSTED_LABEL },
|
|
28
|
+
// auth patterns must come BEFORE rate-limit patterns. OpenRouter 401 error
|
|
29
|
+
// payloads carry `x-ratelimit-*` response headers in the dump, and the
|
|
30
|
+
// free-form rate-limit regex below would otherwise win on word-boundary
|
|
31
|
+
// matches inside header names. canonical 401 messages: OpenRouter returns
|
|
32
|
+
// `{"error":{"message":"User not found","code":401}}` for disabled or
|
|
33
|
+
// invalid keys (https://openai.luzhipeng.com/docs/api/reference/errors-and-debugging).
|
|
34
|
+
{ regex: new RegExp(`${statusKey}401\\b`, "i"), label: "auth error (401)" },
|
|
35
|
+
{ regex: new RegExp(`${statusKey}403\\b`, "i"), label: "auth error (403)" },
|
|
36
|
+
{ regex: /\bUser not found\b/i, label: "auth error (invalid/disabled key)" },
|
|
37
|
+
{
|
|
38
|
+
regex: /\bInvalid authentication\b/i,
|
|
39
|
+
label: "auth error (invalid credentials)",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
regex: /\bNo auth credentials found\b/i,
|
|
43
|
+
label: "auth error (missing credentials)",
|
|
44
|
+
},
|
|
45
|
+
{ regex: new RegExp(`${statusKey}429\\b`, "i"), label: "rate limited (429)" },
|
|
46
|
+
{ regex: new RegExp(`${statusKey}500\\b`, "i"), label: "provider 500 error" },
|
|
47
|
+
{
|
|
48
|
+
regex: new RegExp(`${statusKey}503\\b`, "i"),
|
|
49
|
+
label: "provider unavailable (503)",
|
|
50
|
+
},
|
|
51
|
+
// matches `rate limit`, `rate limited`, `rate limits exceeded`,
|
|
52
|
+
// `rate_limit_error`, `rate_limit_exceeded`. the leading `\b` + `[_ ]`
|
|
53
|
+
// separator rejects `x-ratelimit-*` / `anthropic-ratelimit-*` response
|
|
54
|
+
// headers (no separator between "rate" and "limit") which routinely
|
|
55
|
+
// appear in dumped 401 / 4xx error JSON.
|
|
56
|
+
{ regex: /\brate[_ ]limit/i, label: "rate limited" },
|
|
57
|
+
{ regex: /\bRESOURCE_EXHAUSTED\b/, label: "quota exhausted" },
|
|
58
|
+
// Google gRPC `INTERNAL` status. word-boundary anchors reject
|
|
59
|
+
// `INTERNAL_SERVER_ERROR` (HTTP 500 message that may appear in unrelated
|
|
60
|
+
// log lines) and identifiers like `INTERNALS`.
|
|
61
|
+
{ regex: /\bINTERNAL\b/, label: "provider internal error" },
|
|
62
|
+
{ regex: /\bUNAVAILABLE\b/, label: "provider unavailable" },
|
|
63
|
+
// matches `quota`, `insufficient_quota`, `quota_exceeded`, `quotaExceeded`.
|
|
64
|
+
// word-character lookarounds would reject `_quota` / `quotaX`; `quota` is
|
|
65
|
+
// specific enough that a plain substring match is safe.
|
|
66
|
+
{ regex: /quota/i, label: "quota error" },
|
|
67
|
+
// explicit zero-quota response, e.g. `{"limit": 0}`. the `\b` anchor
|
|
68
|
+
// around `limit` rejects keys like `time_limit` or `field_limit`.
|
|
69
|
+
{ regex: /["']?\blimit\b["']?\s*:\s*0\b/, label: "zero quota" },
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Result of a provider-error scan: the classification label plus a
|
|
74
|
+
* human-readable excerpt centered on the matched line. The excerpt is what
|
|
75
|
+
* gets surfaced in `» provider error detected (...)` log lines — see
|
|
76
|
+
* `extractExcerpt` for the windowing/byte-cap policy.
|
|
77
|
+
*/
|
|
78
|
+
export type ProviderErrorMatch = {
|
|
79
|
+
label: string;
|
|
80
|
+
excerpt: string;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// roughly half a wide terminal line by 4–5 lines of context; large enough
|
|
84
|
+
// to capture a structured error payload (request id, retry-after, model)
|
|
85
|
+
// plus its immediate stack/headers, small enough to not flood the log.
|
|
86
|
+
const EXCERPT_MAX_BYTES = 600;
|
|
87
|
+
const LINES_BEFORE = 1;
|
|
88
|
+
const LINES_AFTER = 2;
|
|
89
|
+
|
|
90
|
+
export function findProviderErrorMatch(
|
|
91
|
+
text: string,
|
|
92
|
+
): ProviderErrorMatch | null {
|
|
93
|
+
for (const entry of PROVIDER_ERROR_PATTERNS) {
|
|
94
|
+
const m = entry.regex.exec(text);
|
|
95
|
+
if (!m) continue;
|
|
96
|
+
return { label: entry.label, excerpt: extractExcerpt(text, m.index) };
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function detectProviderError(text: string): string | null {
|
|
102
|
+
return findProviderErrorMatch(text)?.label ?? null;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Slice a context window around `matchIndex`: the matched line plus
|
|
107
|
+
* `LINES_BEFORE`/`LINES_AFTER` neighbours. If the windowed slice exceeds
|
|
108
|
+
* `EXCERPT_MAX_BYTES` (giant adjacent lines, e.g. JSON tool-schema dumps),
|
|
109
|
+
* fall back to the matched line alone, head-truncated if still too long.
|
|
110
|
+
* Replaces the old `chunk.substring(0, 500)` head-anchored excerpt which
|
|
111
|
+
* surfaced whatever happened to be at the front of the stderr buffer
|
|
112
|
+
* instead of the error itself. See issue #703.
|
|
113
|
+
*/
|
|
114
|
+
function extractExcerpt(text: string, matchIndex: number): string {
|
|
115
|
+
const lineStart = text.lastIndexOf("\n", matchIndex - 1) + 1;
|
|
116
|
+
const lineEndRaw = text.indexOf("\n", matchIndex);
|
|
117
|
+
const lineEnd = lineEndRaw === -1 ? text.length : lineEndRaw;
|
|
118
|
+
|
|
119
|
+
let start = lineStart;
|
|
120
|
+
for (let i = 0; i < LINES_BEFORE && start > 0; i++) {
|
|
121
|
+
const prev = text.lastIndexOf("\n", start - 2);
|
|
122
|
+
start = prev < 0 ? 0 : prev + 1;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
let end = lineEnd;
|
|
126
|
+
for (let i = 0; i < LINES_AFTER && end < text.length; i++) {
|
|
127
|
+
const next = text.indexOf("\n", end + 1);
|
|
128
|
+
end = next < 0 ? text.length : next;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
let excerpt = text.slice(start, end);
|
|
132
|
+
if (excerpt.length > EXCERPT_MAX_BYTES) {
|
|
133
|
+
excerpt = text.slice(lineStart, lineEnd);
|
|
134
|
+
if (excerpt.length > EXCERPT_MAX_BYTES)
|
|
135
|
+
excerpt = excerpt.slice(0, EXCERPT_MAX_BYTES);
|
|
136
|
+
}
|
|
137
|
+
return excerpt.trim();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* OpenRouter's response when the per-run key's remaining budget can't cover
|
|
142
|
+
* the agent's `max_tokens` reservation. Distinct from a generic provider error
|
|
143
|
+
* because it's a Infraweaver billing concern, not an upstream outage — the user's
|
|
144
|
+
* Router wallet ran out (or the key budget was undersized at mint time and the
|
|
145
|
+
* agent ran out of headroom partway through).
|
|
146
|
+
*
|
|
147
|
+
* Match must be specific to this exact OpenRouter error class. Generic "credits"
|
|
148
|
+
* or "limit" text shows up in unrelated errors and would mis-classify them.
|
|
149
|
+
*
|
|
150
|
+
* Sample:
|
|
151
|
+
* `APIError: This request requires more credits, or fewer max_tokens.
|
|
152
|
+
* You requested up to 32000 tokens, but can only afford 22800.`
|
|
153
|
+
*/
|
|
154
|
+
// `/s` (dotAll) lets `.*?` cross newlines so we still detect the error if any
|
|
155
|
+
// upstream layer reformats the message onto multiple lines. Without it, a
|
|
156
|
+
// single inserted `\n` would silently bypass the BillingError reclassification
|
|
157
|
+
// and the user would see the generic `❌ Infraweaver failed` dump instead of the
|
|
158
|
+
// actionable top-up CTA.
|
|
159
|
+
const ROUTER_KEYLIMIT_EXHAUSTED_PATTERN =
|
|
160
|
+
/requires more credits.*?fewer max_tokens|requested up to \d+ tokens.*?can only afford/is;
|
|
161
|
+
|
|
162
|
+
export function isRouterKeylimitExhaustedError(text: string): boolean {
|
|
163
|
+
return ROUTER_KEYLIMIT_EXHAUSTED_PATTERN.test(text);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* BYOK billing-exhausted: provider rejected the request because the user's
|
|
168
|
+
* provider wallet is empty (DeepSeek "Insufficient Balance", Anthropic
|
|
169
|
+
* "credit balance is too low", OpenCode Zen `CreditsError` /
|
|
170
|
+
* `FreeUsageLimitError`, Gemini "spending cap"). Distinct from
|
|
171
|
+
* `isRouterKeylimitExhaustedError` — that's Infraweaver's Router wallet, this
|
|
172
|
+
* is the user's own provider account.
|
|
173
|
+
*/
|
|
174
|
+
export function isProviderBillingExhausted(text: string): boolean {
|
|
175
|
+
return (
|
|
176
|
+
findProviderErrorMatch(text)?.label === PROVIDER_BILLING_EXHAUSTED_LABEL
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Extract `providerID=foo` from agent error logs (OpenCode emits this on
|
|
182
|
+
* `provider error detected (...)` lines). Returns the lowercase provider
|
|
183
|
+
* slug, or null when absent. Used to render a provider-specific dashboard
|
|
184
|
+
* link in the BYOK billing-exhausted summary.
|
|
185
|
+
*/
|
|
186
|
+
export function extractProviderId(text: string): string | null {
|
|
187
|
+
const match = text.match(/\bproviderID=([a-z0-9_-]+)/i);
|
|
188
|
+
return match ? match[1]!.toLowerCase() : null;
|
|
189
|
+
}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import * as core from "@actions/core";
|
|
2
|
+
|
|
3
|
+
import type { Agent } from "#app/agents/index";
|
|
4
|
+
import type { ModelGateResult } from "#app/utils/agent";
|
|
5
|
+
import { apiFetch } from "#app/utils/apiFetch";
|
|
6
|
+
import { BillingError } from "#app/utils/billingErrors";
|
|
7
|
+
import { resolveModelSlug } from "#app/models";
|
|
8
|
+
import { registerSecret } from "#app/utils/redact";
|
|
9
|
+
import type { AccountPlan } from "#app/utils/runContext";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Managed-model routing (the engine half of Phase D). On a PAYG plan with no BYO
|
|
13
|
+
* provider key, instead of the free fallback the engine mints a short-lived proxy
|
|
14
|
+
* token from the Cloud (`POST /api/proxy-token`) and points the Anthropic-compatible
|
|
15
|
+
* harness at the returned EU Bedrock proxy endpoint. The proxy meters usage out of
|
|
16
|
+
* band (`/api/proxy-usage`) — the engine never bills.
|
|
17
|
+
*
|
|
18
|
+
* `applyManagedProxy` overlays this decision onto a BYOK model gate and returns a
|
|
19
|
+
* complete `RoutedModel` — including the env patch the caller must apply
|
|
20
|
+
* (`envToApply`) rather than mutating `process.env` from inside, so the routing
|
|
21
|
+
* decision is fully described by its return value. The composition with the gate
|
|
22
|
+
* and validation lives in modelResolver.ts (`resolveRunModel`).
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
// The Anthropic CLI / Claude Code harness reads these to route through a gateway:
|
|
26
|
+
// a base URL + a bearer token. NOT CLAUDE_CODE_USE_BEDROCK — the proxy speaks the
|
|
27
|
+
// Anthropic Messages API, not the Bedrock wire format.
|
|
28
|
+
const PROXY_BASE_URL_ENV = "ANTHROPIC_BASE_URL";
|
|
29
|
+
const PROXY_AUTH_TOKEN_ENV = "ANTHROPIC_AUTH_TOKEN";
|
|
30
|
+
|
|
31
|
+
/** A resolved model decision plus the env patch (if any) the caller must apply to
|
|
32
|
+
* route the run. `envToApply` is set only when the managed proxy engaged. */
|
|
33
|
+
export type RoutedModel = ModelGateResult & {
|
|
34
|
+
envToApply?: Record<string, string>;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export type ProxyMintResult =
|
|
38
|
+
| { ok: true; token: string; endpoint: string }
|
|
39
|
+
| {
|
|
40
|
+
ok: false;
|
|
41
|
+
reason:
|
|
42
|
+
| "requires_card"
|
|
43
|
+
| "requires_upgrade"
|
|
44
|
+
| "unconfigured"
|
|
45
|
+
| "transient";
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* The proxy `endpoint` becomes `ANTHROPIC_BASE_URL` and receives the bearer on every
|
|
50
|
+
* model call, so it must be a well-formed **https** URL — never cleartext. It comes
|
|
51
|
+
* from the authenticated Cloud (not directly attacker-controlled), but a
|
|
52
|
+
* compromised/misconfigured Cloud response could otherwise redirect the proxy token.
|
|
53
|
+
* Operators can additionally pin exact hosts via `INFRAWEAVER_MODEL_PROXY_ALLOWED_HOSTS`
|
|
54
|
+
* (comma-separated); unset = trust any https host the Cloud returns.
|
|
55
|
+
*/
|
|
56
|
+
export function isSafeProxyEndpoint(endpoint: string): boolean {
|
|
57
|
+
let url: URL;
|
|
58
|
+
try {
|
|
59
|
+
url = new URL(endpoint);
|
|
60
|
+
} catch {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
if (url.protocol !== "https:") return false;
|
|
64
|
+
const pinned = (process.env.INFRAWEAVER_MODEL_PROXY_ALLOWED_HOSTS ?? "")
|
|
65
|
+
.split(",")
|
|
66
|
+
.map((h) => h.trim().toLowerCase())
|
|
67
|
+
.filter(Boolean);
|
|
68
|
+
return pinned.length === 0 || pinned.includes(url.hostname.toLowerCase());
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Classify a `/api/proxy-token` response. Pure given the status + parsed body
|
|
72
|
+
* (aside from the optional `INFRAWEAVER_MODEL_PROXY_ALLOWED_HOSTS` host pin). */
|
|
73
|
+
export function classifyProxyMint(
|
|
74
|
+
status: number,
|
|
75
|
+
body: { token?: unknown; endpoint?: unknown } | null,
|
|
76
|
+
): ProxyMintResult {
|
|
77
|
+
if (
|
|
78
|
+
status === 200 &&
|
|
79
|
+
body &&
|
|
80
|
+
typeof body.token === "string" &&
|
|
81
|
+
typeof body.endpoint === "string" &&
|
|
82
|
+
// refuse to route the bearer to a cleartext / malformed / non-allowlisted host.
|
|
83
|
+
isSafeProxyEndpoint(body.endpoint)
|
|
84
|
+
) {
|
|
85
|
+
return { ok: true, token: body.token, endpoint: body.endpoint };
|
|
86
|
+
}
|
|
87
|
+
// 402 = router_requires_card (no payment method); 403 = the requested managed
|
|
88
|
+
// model needs a higher plan (Opus / Sonnet run on OSS + Team, Claude Fable is
|
|
89
|
+
// Enterprise); 501 = proxy not deployed yet.
|
|
90
|
+
if (status === 402) return { ok: false, reason: "requires_card" };
|
|
91
|
+
if (status === 403) return { ok: false, reason: "requires_upgrade" };
|
|
92
|
+
if (status === 501) return { ok: false, reason: "unconfigured" };
|
|
93
|
+
return { ok: false, reason: "transient" };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** The env that points the Anthropic-compatible harness at the managed proxy. Pure. */
|
|
97
|
+
export function managedProxyEnv(
|
|
98
|
+
token: string,
|
|
99
|
+
endpoint: string,
|
|
100
|
+
): Record<string, string> {
|
|
101
|
+
return { [PROXY_BASE_URL_ENV]: endpoint, [PROXY_AUTH_TOKEN_ENV]: token };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** Apply a model-routing env patch to the process. The one place env is mutated, and
|
|
105
|
+
* the caller does it explicitly with a value it can see (no hidden side effect). */
|
|
106
|
+
export function applyModelEnv(env: Record<string, string>): void {
|
|
107
|
+
for (const [key, value] of Object.entries(env)) process.env[key] = value;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Mint a managed-model proxy token from the Cloud. Never throws — network/parse
|
|
111
|
+
* failures classify as `transient` so the caller can fall back to the free model. */
|
|
112
|
+
export async function mintProxyToken(opts: {
|
|
113
|
+
credential: string;
|
|
114
|
+
model?: string | undefined;
|
|
115
|
+
fetchImpl?: typeof apiFetch;
|
|
116
|
+
}): Promise<ProxyMintResult> {
|
|
117
|
+
const doFetch = opts.fetchImpl ?? apiFetch;
|
|
118
|
+
try {
|
|
119
|
+
const res = await doFetch({
|
|
120
|
+
path: "/api/proxy-token",
|
|
121
|
+
method: "POST",
|
|
122
|
+
headers: {
|
|
123
|
+
Authorization: `Bearer ${opts.credential}`,
|
|
124
|
+
"content-type": "application/json",
|
|
125
|
+
},
|
|
126
|
+
body: JSON.stringify(opts.model ? { model: opts.model } : {}),
|
|
127
|
+
});
|
|
128
|
+
let body: { token?: unknown; endpoint?: unknown } | null = null;
|
|
129
|
+
try {
|
|
130
|
+
body = (await res.json()) as { token?: unknown; endpoint?: unknown };
|
|
131
|
+
} catch {
|
|
132
|
+
body = null;
|
|
133
|
+
}
|
|
134
|
+
const result = classifyProxyMint(res.status, body);
|
|
135
|
+
// register the minted `tmpx_` proxy token for log masking the moment we
|
|
136
|
+
// receive it — exactly like every other bearer the engine handles (gitAuth,
|
|
137
|
+
// token.ts, payload.ts). It is about to be placed in `ANTHROPIC_AUTH_TOKEN`
|
|
138
|
+
// (managedProxyEnv → applyModelEnv); GitHub only masks REGISTERED secrets, so
|
|
139
|
+
// without this any later env dump / error line would print it in cleartext.
|
|
140
|
+
// also register it with the sink-independent redactor so it's masked on the
|
|
141
|
+
// stderr / local sinks `core.setSecret` doesn't cover.
|
|
142
|
+
if (result.ok) {
|
|
143
|
+
core.setSecret(result.token);
|
|
144
|
+
registerSecret(result.token);
|
|
145
|
+
}
|
|
146
|
+
return result;
|
|
147
|
+
} catch {
|
|
148
|
+
return { ok: false, reason: "transient" };
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** The mint seam `applyManagedProxy` / `resolveRunModel` accept for tests. */
|
|
153
|
+
export type ProxyMint = typeof mintProxyToken;
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* The model the managed EU Bedrock proxy should serve for this run. The managed
|
|
157
|
+
* gateway is Anthropic-on-Bedrock, and unlike a BYOK key it can serve the whole
|
|
158
|
+
* Claude family — including Claude Fable, which the BYOK catalog deprecates to Opus
|
|
159
|
+
* (many BYOK Anthropic keys can't invoke Fable). So for an `anthropic/*` selection
|
|
160
|
+
* we mint for the slug's *undeprecated* resolve (e.g. `anthropic/claude-fable`
|
|
161
|
+
* stays Fable) rather than the fallback-collapsed model the BYOK gate produced.
|
|
162
|
+
* Non-Anthropic selections keep the gate's resolved model (the proxy maps anything
|
|
163
|
+
* else to its default Claude model anyway). Returns undefined when there is no
|
|
164
|
+
* usable Anthropic override, so the caller keeps `gate.fallback.from`.
|
|
165
|
+
*/
|
|
166
|
+
export function managedProxyModel(
|
|
167
|
+
slug: string | undefined,
|
|
168
|
+
): string | undefined {
|
|
169
|
+
if (!slug?.startsWith("anthropic/")) return undefined;
|
|
170
|
+
return resolveModelSlug(slug);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Overlay the managed proxy onto a model gate. A no-op (returns the gate unchanged)
|
|
175
|
+
* unless the free fallback engaged (no BYO key) AND the org is on PAYG. On a
|
|
176
|
+
* successful mint it routes the originally-requested model through the proxy and sets
|
|
177
|
+
* `envToApply`; a `requires_card` mint surfaces a `BillingError`;
|
|
178
|
+
* `unconfigured`/`transient` keep the free fallback the gate already chose.
|
|
179
|
+
*/
|
|
180
|
+
export async function applyManagedProxy(input: {
|
|
181
|
+
gate: ModelGateResult;
|
|
182
|
+
plan: AccountPlan;
|
|
183
|
+
credential: string;
|
|
184
|
+
resolveAgent: (ctx: { model?: string | undefined }) => Agent;
|
|
185
|
+
/** the originally-requested model slug (before BYOK fallback), when known */
|
|
186
|
+
slug?: string | undefined;
|
|
187
|
+
mint?: ProxyMint;
|
|
188
|
+
}): Promise<RoutedModel> {
|
|
189
|
+
const { gate } = input;
|
|
190
|
+
if (!gate.fallback || input.plan !== "payg" || !input.credential) return gate;
|
|
191
|
+
|
|
192
|
+
// Prefer the user's chosen managed Claude model (Fable survives here) over the
|
|
193
|
+
// BYOK fallback-collapsed model — see {@link managedProxyModel}.
|
|
194
|
+
const requested = managedProxyModel(input.slug) ?? gate.fallback.from;
|
|
195
|
+
const mintFn = input.mint ?? mintProxyToken;
|
|
196
|
+
const result = await mintFn({
|
|
197
|
+
credential: input.credential,
|
|
198
|
+
model: requested,
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
if (result.ok) {
|
|
202
|
+
const model = requested;
|
|
203
|
+
return {
|
|
204
|
+
model,
|
|
205
|
+
effectiveSlug: model,
|
|
206
|
+
agent: input.resolveAgent({ model }),
|
|
207
|
+
warnings: [
|
|
208
|
+
`» routing ${model} through the managed EU Bedrock proxy (no BYO key on a PAYG plan)`,
|
|
209
|
+
],
|
|
210
|
+
validate: false,
|
|
211
|
+
envToApply: managedProxyEnv(result.token, result.endpoint),
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (result.reason === "requires_card") {
|
|
216
|
+
throw new BillingError(
|
|
217
|
+
"Managed models require a payment method on this organisation.",
|
|
218
|
+
{
|
|
219
|
+
code: "router_requires_card",
|
|
220
|
+
},
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (result.reason === "requires_upgrade") {
|
|
225
|
+
throw new BillingError(
|
|
226
|
+
`The managed model ${requested} needs a higher plan — Claude Opus and Sonnet run on OSS + Team, ` +
|
|
227
|
+
`Claude Fable is on Enterprise. Upgrade, or pick a managed model your plan includes.`,
|
|
228
|
+
{ code: "router_requires_upgrade" },
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return {
|
|
233
|
+
...gate,
|
|
234
|
+
warnings: [
|
|
235
|
+
...gate.warnings,
|
|
236
|
+
`» managed-model proxy ${result.reason}; using the free fallback model`,
|
|
237
|
+
],
|
|
238
|
+
};
|
|
239
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { log } from "#app/utils/cli";
|
|
2
|
+
import { $ } from "#app/utils/shell";
|
|
3
|
+
|
|
4
|
+
type ComputeIncrementalDiffParams = {
|
|
5
|
+
baseBranch: string;
|
|
6
|
+
beforeSha: string;
|
|
7
|
+
headSha: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* computes the incremental diff between two versions of a PR using range-diff
|
|
12
|
+
* on virtual squash commits created via `git commit-tree`.
|
|
13
|
+
*
|
|
14
|
+
* each PR version is squashed into a single synthetic commit (merge-base → tip tree),
|
|
15
|
+
* then range-diff compares those two single-commit ranges. this:
|
|
16
|
+
* - isolates each version's net effect (base branch noise eliminated via per-version merge bases)
|
|
17
|
+
* - avoids commit-matching issues that raw range-diff has with rebases/squashes/reordering
|
|
18
|
+
* - creates only loose git objects, no branches or refs (unlike temp-branch squash approaches)
|
|
19
|
+
*
|
|
20
|
+
* unlike fetchAndFormatPrDiff/formatFilesWithLineNumbers, this output has no line numbers.
|
|
21
|
+
* range-diff compares *patches* (diffs-of-diffs), not file trees — its hunk headers are
|
|
22
|
+
* `@@ file.ts` breadcrumbs, not positional `@@ -X,Y +A,B @@` markers. reconstructing
|
|
23
|
+
* line numbers would require cross-referencing with the v2 diff or content-matching against
|
|
24
|
+
* file trees, both of which are fragile (duplicate lines, hunk boundary shifts after rebase).
|
|
25
|
+
* a structured interdiff approach (diff two parsed patches, compare only +/- keys via Myers)
|
|
26
|
+
* could approximate line numbers but loses semantic precision: range-diff understands patch
|
|
27
|
+
* structure natively (rename detection, hunk-aware matching, dual-prefix inner/outer changes),
|
|
28
|
+
* while flat key-sequence comparison can misalign duplicate lines and can't distinguish
|
|
29
|
+
* "new addition to the PR" from "existing code newly modified by the PR". range-diff is the
|
|
30
|
+
* right abstraction here — the incremental diff answers "how did the changeset evolve?",
|
|
31
|
+
* not "where in the file is this?", and forcing positional line numbers onto it would be
|
|
32
|
+
* semantically misleading.
|
|
33
|
+
*
|
|
34
|
+
* alternatives considered:
|
|
35
|
+
* - plain git diff (two-tree or three-dot): includes base branch changes, no PR isolation
|
|
36
|
+
* - patch-text diffing (interdiff / diff-of-diffs): fragile, hunk offset noise on rebase
|
|
37
|
+
* - range-diff on raw commit ranges: confused by commit reorganization across force-pushes
|
|
38
|
+
*/
|
|
39
|
+
export function computeIncrementalDiff(params: ComputeIncrementalDiffParams): string | null {
|
|
40
|
+
try {
|
|
41
|
+
// $1=beforeSha, $2=baseBranch, $3=headSha
|
|
42
|
+
const raw = $(
|
|
43
|
+
"sh",
|
|
44
|
+
[
|
|
45
|
+
"-c",
|
|
46
|
+
'old_base=$(git merge-base "$1" "origin/$2") && ' +
|
|
47
|
+
'new_base=$(git merge-base "$3" "origin/$2") && ' +
|
|
48
|
+
"git range-diff --no-color " +
|
|
49
|
+
'"$old_base..$(git commit-tree "$1^{tree}" -p "$old_base" -m x)" ' +
|
|
50
|
+
'"$new_base..$(git commit-tree "$3^{tree}" -p "$new_base" -m x)"',
|
|
51
|
+
"--",
|
|
52
|
+
params.beforeSha,
|
|
53
|
+
params.baseBranch,
|
|
54
|
+
params.headSha,
|
|
55
|
+
],
|
|
56
|
+
{ log: false },
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
return postProcessRangeDiff(raw);
|
|
60
|
+
} catch (e) {
|
|
61
|
+
log.debug(`» range-diff failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function isDiffPrefix(ch: string): boolean {
|
|
67
|
+
return ch === " " || ch === "+" || ch === "-";
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* transforms git range-diff output into a clean incremental diff.
|
|
72
|
+
*
|
|
73
|
+
* range-diff content lines have two prefix characters:
|
|
74
|
+
* 1st (outer): range-diff level — space (same in both), + (new only), - (old only)
|
|
75
|
+
* 2nd (inner): original diff level — space (context), + (added), - (removed)
|
|
76
|
+
*
|
|
77
|
+
* stripping the inner prefix produces a standard unified-diff-like output where
|
|
78
|
+
* +/- means "changed between PR versions" rather than "changed vs base branch".
|
|
79
|
+
*
|
|
80
|
+
* uses a streaming approach: a ring buffer of before-context lines is flushed when
|
|
81
|
+
* a change is hit, then afterCount lines of after-context are emitted directly.
|
|
82
|
+
* nearest preceding ## / @@ headers are force-included when outside the context window.
|
|
83
|
+
*/
|
|
84
|
+
export function postProcessRangeDiff(raw: string, contextLines = 3): string | null {
|
|
85
|
+
if (!raw.trim()) return null;
|
|
86
|
+
if (/^\d+:\s+\w+\s+=\s+\d+:/m.test(raw)) return null;
|
|
87
|
+
|
|
88
|
+
type Line = { prefix: string; from: number; to: number; seq: number };
|
|
89
|
+
|
|
90
|
+
const beforeBuf: Line[] = [];
|
|
91
|
+
let lastFileHdr: Line | null = null;
|
|
92
|
+
let lastHunkHdr: Line | null = null;
|
|
93
|
+
let fileHdrEmitted = true;
|
|
94
|
+
let hunkHdrEmitted = true;
|
|
95
|
+
|
|
96
|
+
let out = "";
|
|
97
|
+
let afterRemaining = 0;
|
|
98
|
+
let lastEmittedSeq = -2;
|
|
99
|
+
let seq = 0;
|
|
100
|
+
let hasChanges = false;
|
|
101
|
+
|
|
102
|
+
function emit(line: Line) {
|
|
103
|
+
if (lastEmittedSeq >= 0 && line.seq > lastEmittedSeq + 1) out += `${out ? "\n" : ""}...`;
|
|
104
|
+
out += (out ? "\n" : "") + line.prefix + raw.slice(line.from, line.to);
|
|
105
|
+
lastEmittedSeq = line.seq;
|
|
106
|
+
if (lastFileHdr?.seq === line.seq) fileHdrEmitted = true;
|
|
107
|
+
if (lastHunkHdr?.seq === line.seq) hunkHdrEmitted = true;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function flushBefore() {
|
|
111
|
+
if (lastFileHdr && !fileHdrEmitted) emit(lastFileHdr);
|
|
112
|
+
if (lastHunkHdr && !hunkHdrEmitted) emit(lastHunkHdr);
|
|
113
|
+
for (const line of beforeBuf) {
|
|
114
|
+
if (line.seq > lastEmittedSeq) emit(line);
|
|
115
|
+
}
|
|
116
|
+
beforeBuf.length = 0;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
let cursor = 0;
|
|
120
|
+
while (cursor < raw.length) {
|
|
121
|
+
const eol = raw.indexOf("\n", cursor);
|
|
122
|
+
const lineEnd = eol === -1 ? raw.length : eol;
|
|
123
|
+
|
|
124
|
+
if (raw.charCodeAt(cursor) >= 48 && raw.charCodeAt(cursor) <= 57) {
|
|
125
|
+
cursor = lineEnd + 1;
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (lineEnd - cursor >= 5 && raw.startsWith(" ", cursor)) {
|
|
130
|
+
const prefix = raw[cursor + 4]!;
|
|
131
|
+
if (isDiffPrefix(prefix)) {
|
|
132
|
+
const contentPos = cursor + 5;
|
|
133
|
+
const isOuterChange = prefix !== " ";
|
|
134
|
+
let line: Line;
|
|
135
|
+
let isChange = false;
|
|
136
|
+
|
|
137
|
+
if (contentPos >= lineEnd) {
|
|
138
|
+
line = { prefix, from: lineEnd, to: lineEnd, seq };
|
|
139
|
+
} else if (isDiffPrefix(raw[contentPos]!)) {
|
|
140
|
+
isChange = isOuterChange;
|
|
141
|
+
line = { prefix, from: contentPos + 1, to: lineEnd, seq };
|
|
142
|
+
} else {
|
|
143
|
+
line = { prefix, from: contentPos, to: lineEnd, seq };
|
|
144
|
+
if (
|
|
145
|
+
raw.startsWith("## ", contentPos) &&
|
|
146
|
+
!raw.startsWith("## Commit message", contentPos)
|
|
147
|
+
) {
|
|
148
|
+
lastFileHdr = line;
|
|
149
|
+
fileHdrEmitted = false;
|
|
150
|
+
lastHunkHdr = null;
|
|
151
|
+
hunkHdrEmitted = true;
|
|
152
|
+
} else if (
|
|
153
|
+
raw.startsWith("@@", contentPos) &&
|
|
154
|
+
!raw.startsWith("@@ Metadata", contentPos)
|
|
155
|
+
) {
|
|
156
|
+
lastHunkHdr = line;
|
|
157
|
+
hunkHdrEmitted = false;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (isChange) {
|
|
162
|
+
hasChanges = true;
|
|
163
|
+
flushBefore();
|
|
164
|
+
emit(line);
|
|
165
|
+
afterRemaining = contextLines;
|
|
166
|
+
} else if (afterRemaining > 0) {
|
|
167
|
+
emit(line);
|
|
168
|
+
afterRemaining--;
|
|
169
|
+
} else {
|
|
170
|
+
if (beforeBuf.length >= contextLines) beforeBuf.shift();
|
|
171
|
+
beforeBuf.push(line);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
seq++;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
cursor = lineEnd + 1;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return hasChanges ? out : null;
|
|
182
|
+
}
|