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.
Files changed (524) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +244 -0
  3. package/dist/agents/claude.d.ts +113 -0
  4. package/dist/agents/claudePretoolGate.d.ts +137 -0
  5. package/dist/agents/dispatchMetrics.d.ts +77 -0
  6. package/dist/agents/gateServer.d.ts +7 -0
  7. package/dist/agents/index.d.ts +6 -0
  8. package/dist/agents/nativeFsDenies.d.ts +46 -0
  9. package/dist/agents/opencode.d.ts +284 -0
  10. package/dist/agents/opencodePlugin.d.ts +96 -0
  11. package/dist/agents/opencodeShared.d.ts +40 -0
  12. package/dist/agents/postRun.d.ts +126 -0
  13. package/dist/agents/reviewer.d.ts +41 -0
  14. package/dist/agents/sessionLabeler.d.ts +97 -0
  15. package/dist/agents/shared.d.ts +246 -0
  16. package/dist/agents/subagentModels.d.ts +19 -0
  17. package/dist/agents/tokenQuota.d.ts +118 -0
  18. package/dist/agents/writeGateSource.d.ts +22 -0
  19. package/dist/agents/writePolicy.d.ts +79 -0
  20. package/dist/brand.d.ts +67 -0
  21. package/dist/cli.mjs +247846 -0
  22. package/dist/external.d.ts +227 -0
  23. package/dist/i18n/scaffolding.d.ts +59 -0
  24. package/dist/index.d.ts +6 -0
  25. package/dist/index.js +247061 -0
  26. package/dist/internal/index.d.ts +18 -0
  27. package/dist/internal.js +2398 -0
  28. package/dist/lifecycle.d.ts +2 -0
  29. package/dist/main.d.ts +8 -0
  30. package/dist/mcp/arkConfig.d.ts +1 -0
  31. package/dist/mcp/assess.d.ts +157 -0
  32. package/dist/mcp/capabilityContext.d.ts +71 -0
  33. package/dist/mcp/changeSummary.d.ts +52 -0
  34. package/dist/mcp/checkSuite.d.ts +27 -0
  35. package/dist/mcp/checkout.d.ts +92 -0
  36. package/dist/mcp/comment.d.ts +127 -0
  37. package/dist/mcp/commitInfo.d.ts +11 -0
  38. package/dist/mcp/crosswalk.d.ts +178 -0
  39. package/dist/mcp/crosswalkDigest.d.ts +1 -0
  40. package/dist/mcp/cyberEssentials.d.ts +24 -0
  41. package/dist/mcp/dashboard.d.ts +125 -0
  42. package/dist/mcp/dependencies.d.ts +12 -0
  43. package/dist/mcp/frameworks.d.ts +74 -0
  44. package/dist/mcp/geminiSanitizer.d.ts +28 -0
  45. package/dist/mcp/git.d.ts +60 -0
  46. package/dist/mcp/guardrails.d.ts +222 -0
  47. package/dist/mcp/issue.d.ts +20 -0
  48. package/dist/mcp/issueComments.d.ts +11 -0
  49. package/dist/mcp/issueEvents.d.ts +11 -0
  50. package/dist/mcp/issueInfo.d.ts +11 -0
  51. package/dist/mcp/labels.d.ts +14 -0
  52. package/dist/mcp/localContext.d.ts +26 -0
  53. package/dist/mcp/moduleExtraction.d.ts +79 -0
  54. package/dist/mcp/moduleTests.d.ts +106 -0
  55. package/dist/mcp/modules.d.ts +198 -0
  56. package/dist/mcp/output.d.ts +16 -0
  57. package/dist/mcp/pathSafety.d.ts +14 -0
  58. package/dist/mcp/policy.d.ts +50 -0
  59. package/dist/mcp/pr.d.ts +64 -0
  60. package/dist/mcp/prInfo.d.ts +11 -0
  61. package/dist/mcp/providerSchema.d.ts +52 -0
  62. package/dist/mcp/review.d.ts +212 -0
  63. package/dist/mcp/reviewComments.d.ts +245 -0
  64. package/dist/mcp/roots.d.ts +60 -0
  65. package/dist/mcp/scope.d.ts +26 -0
  66. package/dist/mcp/selectMode.d.ts +20 -0
  67. package/dist/mcp/server.d.ts +61 -0
  68. package/dist/mcp/shared.d.ts +62 -0
  69. package/dist/mcp/shell.d.ts +58 -0
  70. package/dist/mcp/staleFix.d.ts +138 -0
  71. package/dist/mcp/terraform/azurePrices.d.ts +8 -0
  72. package/dist/mcp/terraform/baseline.d.ts +57 -0
  73. package/dist/mcp/terraform/concernResult.d.ts +38 -0
  74. package/dist/mcp/terraform/cost.d.ts +55 -0
  75. package/dist/mcp/terraform/cspm.d.ts +80 -0
  76. package/dist/mcp/terraform/currency.d.ts +110 -0
  77. package/dist/mcp/terraform/decisions.d.ts +178 -0
  78. package/dist/mcp/terraform/eidas.d.ts +100 -0
  79. package/dist/mcp/terraform/evidence.d.ts +343 -0
  80. package/dist/mcp/terraform/findings.d.ts +76 -0
  81. package/dist/mcp/terraform/fixMemory.d.ts +81 -0
  82. package/dist/mcp/terraform/governance.d.ts +56 -0
  83. package/dist/mcp/terraform/hcl.d.ts +115 -0
  84. package/dist/mcp/terraform/iacLanguages.d.ts +120 -0
  85. package/dist/mcp/terraform/idleFloor.d.ts +78 -0
  86. package/dist/mcp/terraform/keyless.d.ts +68 -0
  87. package/dist/mcp/terraform/moduleDocs.d.ts +56 -0
  88. package/dist/mcp/terraform/nativeRules.d.ts +38 -0
  89. package/dist/mcp/terraform/nativeScan.d.ts +11 -0
  90. package/dist/mcp/terraform/noiseProfile.d.ts +100 -0
  91. package/dist/mcp/terraform/normalization.d.ts +52 -0
  92. package/dist/mcp/terraform/oscal.d.ts +103 -0
  93. package/dist/mcp/terraform/packs/azurerm-3-4.d.ts +2 -0
  94. package/dist/mcp/terraform/packs/cloudflare-4-5.d.ts +2 -0
  95. package/dist/mcp/terraform/paths.d.ts +28 -0
  96. package/dist/mcp/terraform/plan.d.ts +157 -0
  97. package/dist/mcp/terraform/planDrift.d.ts +199 -0
  98. package/dist/mcp/terraform/policyAuthor.d.ts +191 -0
  99. package/dist/mcp/terraform/prowlerOcsf.d.ts +136 -0
  100. package/dist/mcp/terraform/refactor.d.ts +183 -0
  101. package/dist/mcp/terraform/registry.d.ts +108 -0
  102. package/dist/mcp/terraform/risk.d.ts +41 -0
  103. package/dist/mcp/terraform/scanSession.d.ts +116 -0
  104. package/dist/mcp/terraform/scannerCache.d.ts +15 -0
  105. package/dist/mcp/terraform/scannerEgress.d.ts +72 -0
  106. package/dist/mcp/terraform/scannerJson.d.ts +13 -0
  107. package/dist/mcp/terraform/scanners.d.ts +205 -0
  108. package/dist/mcp/terraform/signing.d.ts +61 -0
  109. package/dist/mcp/terraform/stateLocking.d.ts +18 -0
  110. package/dist/mcp/terraform/subprocess.d.ts +43 -0
  111. package/dist/mcp/terraform/suppressions.d.ts +90 -0
  112. package/dist/mcp/terraform/taxonomy.d.ts +39 -0
  113. package/dist/mcp/terraform/tfquery.d.ts +47 -0
  114. package/dist/mcp/terraform/toolchainIntegrity.d.ts +82 -0
  115. package/dist/mcp/terraform/tools/authorPolicy.d.ts +59 -0
  116. package/dist/mcp/terraform/tools/detectPlanDrift.d.ts +20 -0
  117. package/dist/mcp/terraform/tools/emitCost.d.ts +11 -0
  118. package/dist/mcp/terraform/tools/emitSarif.d.ts +14 -0
  119. package/dist/mcp/terraform/tools/fixMemory.d.ts +19 -0
  120. package/dist/mcp/terraform/tools/infracostDiff.d.ts +22 -0
  121. package/dist/mcp/terraform/tools/ingestExternalFindings.d.ts +21 -0
  122. package/dist/mcp/terraform/tools/moduleLookup.d.ts +14 -0
  123. package/dist/mcp/terraform/tools/moduleSearch.d.ts +23 -0
  124. package/dist/mcp/terraform/tools/plan.d.ts +59 -0
  125. package/dist/mcp/terraform/tools/providerUpgrade.d.ts +55 -0
  126. package/dist/mcp/terraform/tools/readFindings.d.ts +17 -0
  127. package/dist/mcp/terraform/tools/scan.d.ts +114 -0
  128. package/dist/mcp/terraform/tools/validate.d.ts +31 -0
  129. package/dist/mcp/terraform/tools/verifyRemediation.d.ts +31 -0
  130. package/dist/mcp/terraform/tools/versionCurrency.d.ts +5 -0
  131. package/dist/mcp/terraform/tools.d.ts +16 -0
  132. package/dist/mcp/terraform/transformPacks.d.ts +267 -0
  133. package/dist/mcp/terraform/types.d.ts +226 -0
  134. package/dist/mcp/terraform/verification.d.ts +81 -0
  135. package/dist/mcp/terraform/vex.d.ts +115 -0
  136. package/dist/mcp/terraform/writeOnly.d.ts +67 -0
  137. package/dist/mcp/terraform.d.ts +51 -0
  138. package/dist/mcp/terratest.d.ts +85 -0
  139. package/dist/mcp/untrustedContent.d.ts +76 -0
  140. package/dist/mcp/upload.d.ts +8 -0
  141. package/dist/models.d.ts +181 -0
  142. package/dist/modes/address-reviews.d.ts +2 -0
  143. package/dist/modes/assess.d.ts +2 -0
  144. package/dist/modes/build.d.ts +2 -0
  145. package/dist/modes/compliance-audit.d.ts +2 -0
  146. package/dist/modes/cost-optimization.d.ts +2 -0
  147. package/dist/modes/drift-detect.d.ts +2 -0
  148. package/dist/modes/fix.d.ts +2 -0
  149. package/dist/modes/incremental-review.d.ts +2 -0
  150. package/dist/modes/index.d.ts +24 -0
  151. package/dist/modes/modernize-deprecated.d.ts +2 -0
  152. package/dist/modes/plan.d.ts +2 -0
  153. package/dist/modes/policy-gate.d.ts +2 -0
  154. package/dist/modes/prFormats.d.ts +3 -0
  155. package/dist/modes/refactor.d.ts +2 -0
  156. package/dist/modes/refresh-remediation.d.ts +2 -0
  157. package/dist/modes/remediate-and-refactor.d.ts +2 -0
  158. package/dist/modes/remediate.d.ts +2 -0
  159. package/dist/modes/resolve-conflicts.d.ts +2 -0
  160. package/dist/modes/review.d.ts +2 -0
  161. package/dist/modes/summarize-pr.d.ts +2 -0
  162. package/dist/modes/task.d.ts +2 -0
  163. package/dist/modes/terraform-code-review.d.ts +2 -0
  164. package/dist/modes/types.d.ts +9 -0
  165. package/dist/modes/update-dependencies.d.ts +2 -0
  166. package/dist/prep/index.d.ts +7 -0
  167. package/dist/prep/installNodeDependencies.d.ts +2 -0
  168. package/dist/prep/installPythonDependencies.d.ts +2 -0
  169. package/dist/prep/types.d.ts +31 -0
  170. package/dist/reviewQuality.d.ts +107 -0
  171. package/dist/skills/terraform-best-practices/SKILL.md +379 -0
  172. package/dist/toolState.d.ts +123 -0
  173. package/dist/utils/activity.d.ts +40 -0
  174. package/dist/utils/agent.d.ts +47 -0
  175. package/dist/utils/agentHangReport.d.ts +38 -0
  176. package/dist/utils/annotations.d.ts +17 -0
  177. package/dist/utils/apiFetch.d.ts +11 -0
  178. package/dist/utils/apiKeys.d.ts +48 -0
  179. package/dist/utils/apiUrl.d.ts +28 -0
  180. package/dist/utils/assets.d.ts +8 -0
  181. package/dist/utils/baseRefConfig.d.ts +121 -0
  182. package/dist/utils/billingErrors.d.ts +85 -0
  183. package/dist/utils/body.d.ts +34 -0
  184. package/dist/utils/buildInfraweaverFooter.d.ts +29 -0
  185. package/dist/utils/byokFallback.d.ts +85 -0
  186. package/dist/utils/changeImpact.d.ts +101 -0
  187. package/dist/utils/claudeSubscription.d.ts +30 -0
  188. package/dist/utils/cli.d.ts +10 -0
  189. package/dist/utils/cloudClient.d.ts +33 -0
  190. package/dist/utils/cloudFetchCore.d.ts +42 -0
  191. package/dist/utils/cloudReport.d.ts +114 -0
  192. package/dist/utils/codexHome.d.ts +29 -0
  193. package/dist/utils/codexOAuth.d.ts +60 -0
  194. package/dist/utils/diffCoverage.d.ts +63 -0
  195. package/dist/utils/env.d.ts +46 -0
  196. package/dist/utils/errorReport.d.ts +17 -0
  197. package/dist/utils/exitHandler.d.ts +8 -0
  198. package/dist/utils/fixDoubleEscapedString.d.ts +1 -0
  199. package/dist/utils/gitAuth.d.ts +84 -0
  200. package/dist/utils/gitAuthServer.d.ts +24 -0
  201. package/dist/utils/github.d.ts +104 -0
  202. package/dist/utils/globals.d.ts +3 -0
  203. package/dist/utils/infraweaverConfig.d.ts +56 -0
  204. package/dist/utils/install.d.ts +37 -0
  205. package/dist/utils/instructions.d.ts +48 -0
  206. package/dist/utils/keylessOidc.d.ts +28 -0
  207. package/dist/utils/leapingComment.d.ts +11 -0
  208. package/dist/utils/learnings.d.ts +62 -0
  209. package/dist/utils/learningsTruncate.d.ts +25 -0
  210. package/dist/utils/lifecycle.d.ts +57 -0
  211. package/dist/utils/log.d.ts +111 -0
  212. package/dist/utils/modelResolver.d.ts +63 -0
  213. package/dist/utils/moduleFetch.d.ts +39 -0
  214. package/dist/utils/normalizeEnv.d.ts +30 -0
  215. package/dist/utils/openCodeModels.d.ts +11 -0
  216. package/dist/utils/openaiCompatible.d.ts +26 -0
  217. package/dist/utils/opentofuMcp.d.ts +50 -0
  218. package/dist/utils/overrides.d.ts +40 -0
  219. package/dist/utils/packageManager.d.ts +49 -0
  220. package/dist/utils/patchWorkflowRunFields.d.ts +29 -0
  221. package/dist/utils/payload.d.ts +249 -0
  222. package/dist/utils/prSummary.d.ts +61 -0
  223. package/dist/utils/presets.d.ts +36 -0
  224. package/dist/utils/progressComment.d.ts +146 -0
  225. package/dist/utils/providerErrors.d.ts +31 -0
  226. package/dist/utils/proxyModel.d.ts +76 -0
  227. package/dist/utils/rangeDiff.d.ts +51 -0
  228. package/dist/utils/redact.d.ts +33 -0
  229. package/dist/utils/registryAuth.d.ts +52 -0
  230. package/dist/utils/remediationCommand.d.ts +58 -0
  231. package/dist/utils/retry.d.ts +38 -0
  232. package/dist/utils/reviewCleanup.d.ts +14 -0
  233. package/dist/utils/run.d.ts +9 -0
  234. package/dist/utils/runContext.d.ts +112 -0
  235. package/dist/utils/runContextData.d.ts +42 -0
  236. package/dist/utils/runErrorRenderer.d.ts +64 -0
  237. package/dist/utils/runLifecycle.d.ts +89 -0
  238. package/dist/utils/runStartupLog.d.ts +15 -0
  239. package/dist/utils/secrets.d.ts +34 -0
  240. package/dist/utils/setup.d.ts +90 -0
  241. package/dist/utils/shell.d.ts +44 -0
  242. package/dist/utils/skills.d.ts +10 -0
  243. package/dist/utils/subprocess.d.ts +81 -0
  244. package/dist/utils/terraformMcp.d.ts +46 -0
  245. package/dist/utils/time.d.ts +15 -0
  246. package/dist/utils/timer.d.ts +23 -0
  247. package/dist/utils/todoTracking.d.ts +16 -0
  248. package/dist/utils/token.d.ts +52 -0
  249. package/dist/utils/toolLicensing.d.ts +56 -0
  250. package/dist/utils/toolSelection.d.ts +73 -0
  251. package/dist/utils/toon.d.ts +16 -0
  252. package/dist/utils/version.d.ts +2 -0
  253. package/dist/utils/versioning.d.ts +7 -0
  254. package/dist/utils/vertex.d.ts +16 -0
  255. package/dist/utils/workflow.d.ts +13 -0
  256. package/package.json +132 -0
  257. package/src/agents/claude.ts +1588 -0
  258. package/src/agents/claudePretoolGate.ts +286 -0
  259. package/src/agents/dispatchMetrics.ts +162 -0
  260. package/src/agents/gateServer.ts +178 -0
  261. package/src/agents/index.ts +10 -0
  262. package/src/agents/nativeFsDenies.ts +164 -0
  263. package/src/agents/opencode.ts +1600 -0
  264. package/src/agents/opencodePlugin.ts +304 -0
  265. package/src/agents/opencodeShared.ts +134 -0
  266. package/src/agents/postRun.ts +615 -0
  267. package/src/agents/reviewer.ts +134 -0
  268. package/src/agents/sessionLabeler.ts +185 -0
  269. package/src/agents/shared.ts +377 -0
  270. package/src/agents/subagentModels.ts +40 -0
  271. package/src/agents/tokenQuota.ts +203 -0
  272. package/src/agents/writeGateSource.ts +148 -0
  273. package/src/agents/writePolicy.ts +132 -0
  274. package/src/brand.ts +84 -0
  275. package/src/cli.ts +117 -0
  276. package/src/commands/gha.ts +188 -0
  277. package/src/commands/mcp.ts +126 -0
  278. package/src/commands/verifyEvidence.ts +100 -0
  279. package/src/entry.ts +7 -0
  280. package/src/entryPost.ts +109 -0
  281. package/src/external.ts +308 -0
  282. package/src/i18n/scaffolding.ts +191 -0
  283. package/src/index.ts +7 -0
  284. package/src/internal/index.ts +74 -0
  285. package/src/lifecycle.ts +2 -0
  286. package/src/main.ts +815 -0
  287. package/src/mcp/__fixtures__/infraweaver-scratch-pr-49-review-3485940013.json +110 -0
  288. package/src/mcp/__fixtures__/infraweaver-scratch-pr-64-review-3531000326.json +14 -0
  289. package/src/mcp/__fixtures__/infraweaver-test-repo-pr-1.diff.json +67 -0
  290. package/src/mcp/__snapshots__/checkout.test.ts.snap +109 -0
  291. package/src/mcp/__snapshots__/reviewComments.test.ts.snap +71 -0
  292. package/src/mcp/arkConfig.ts +7 -0
  293. package/src/mcp/assess.ts +723 -0
  294. package/src/mcp/capabilityContext.ts +80 -0
  295. package/src/mcp/changeSummary.ts +145 -0
  296. package/src/mcp/checkSuite.ts +261 -0
  297. package/src/mcp/checkout.ts +1015 -0
  298. package/src/mcp/comment.ts +683 -0
  299. package/src/mcp/commitInfo.ts +57 -0
  300. package/src/mcp/crosswalk.ts +1253 -0
  301. package/src/mcp/crosswalkDigest.ts +5 -0
  302. package/src/mcp/cyberEssentials.ts +60 -0
  303. package/src/mcp/dashboard.ts +232 -0
  304. package/src/mcp/dependencies.ts +190 -0
  305. package/src/mcp/frameworks.ts +236 -0
  306. package/src/mcp/geminiSanitizer.ts +212 -0
  307. package/src/mcp/git.ts +1116 -0
  308. package/src/mcp/guardrails.ts +771 -0
  309. package/src/mcp/issue.ts +74 -0
  310. package/src/mcp/issueComments.ts +48 -0
  311. package/src/mcp/issueEvents.ts +100 -0
  312. package/src/mcp/issueInfo.ts +72 -0
  313. package/src/mcp/labels.ts +35 -0
  314. package/src/mcp/localContext.ts +65 -0
  315. package/src/mcp/localServer.ts +217 -0
  316. package/src/mcp/moduleExtraction.ts +368 -0
  317. package/src/mcp/moduleTests.ts +421 -0
  318. package/src/mcp/modules.ts +752 -0
  319. package/src/mcp/output.ts +71 -0
  320. package/src/mcp/pathSafety.ts +28 -0
  321. package/src/mcp/policy.ts +226 -0
  322. package/src/mcp/pr.ts +238 -0
  323. package/src/mcp/prInfo.ts +91 -0
  324. package/src/mcp/providerSchema.ts +175 -0
  325. package/src/mcp/review.ts +1081 -0
  326. package/src/mcp/reviewComments.ts +1137 -0
  327. package/src/mcp/roots.ts +217 -0
  328. package/src/mcp/scope.ts +82 -0
  329. package/src/mcp/selectMode.ts +207 -0
  330. package/src/mcp/server.ts +498 -0
  331. package/src/mcp/shared.ts +120 -0
  332. package/src/mcp/shell.ts +631 -0
  333. package/src/mcp/staleFix.ts +557 -0
  334. package/src/mcp/terraform/__snapshots__/moduleDocs.test.ts.snap +40 -0
  335. package/src/mcp/terraform/azurePrices.ts +38 -0
  336. package/src/mcp/terraform/baseline.ts +172 -0
  337. package/src/mcp/terraform/concernResult.ts +111 -0
  338. package/src/mcp/terraform/cost.ts +175 -0
  339. package/src/mcp/terraform/cspm.ts +326 -0
  340. package/src/mcp/terraform/currency.ts +354 -0
  341. package/src/mcp/terraform/decisions.ts +590 -0
  342. package/src/mcp/terraform/eidas.ts +134 -0
  343. package/src/mcp/terraform/evidence.ts +771 -0
  344. package/src/mcp/terraform/findings.ts +383 -0
  345. package/src/mcp/terraform/fixMemory.ts +253 -0
  346. package/src/mcp/terraform/governance.ts +231 -0
  347. package/src/mcp/terraform/hcl.ts +273 -0
  348. package/src/mcp/terraform/iacLanguages.ts +431 -0
  349. package/src/mcp/terraform/idleFloor.ts +304 -0
  350. package/src/mcp/terraform/keyless.ts +123 -0
  351. package/src/mcp/terraform/moduleDocs.ts +303 -0
  352. package/src/mcp/terraform/nativeRules.ts +152 -0
  353. package/src/mcp/terraform/nativeScan.ts +67 -0
  354. package/src/mcp/terraform/noiseProfile.ts +183 -0
  355. package/src/mcp/terraform/normalization.ts +265 -0
  356. package/src/mcp/terraform/oscal.ts +283 -0
  357. package/src/mcp/terraform/packs/azurerm-3-4.ts +382 -0
  358. package/src/mcp/terraform/packs/cloudflare-4-5.ts +114 -0
  359. package/src/mcp/terraform/paths.ts +59 -0
  360. package/src/mcp/terraform/plan.ts +377 -0
  361. package/src/mcp/terraform/planDrift.ts +520 -0
  362. package/src/mcp/terraform/policyAuthor.ts +886 -0
  363. package/src/mcp/terraform/prowlerOcsf.ts +380 -0
  364. package/src/mcp/terraform/refactor.ts +879 -0
  365. package/src/mcp/terraform/registry.ts +317 -0
  366. package/src/mcp/terraform/risk.ts +99 -0
  367. package/src/mcp/terraform/scanSession.ts +242 -0
  368. package/src/mcp/terraform/scannerCache.ts +86 -0
  369. package/src/mcp/terraform/scannerEgress.ts +141 -0
  370. package/src/mcp/terraform/scannerJson.ts +22 -0
  371. package/src/mcp/terraform/scanners.ts +1134 -0
  372. package/src/mcp/terraform/signing.ts +151 -0
  373. package/src/mcp/terraform/stateLocking.ts +106 -0
  374. package/src/mcp/terraform/subprocess.ts +102 -0
  375. package/src/mcp/terraform/suppressions.ts +551 -0
  376. package/src/mcp/terraform/taxonomy.ts +0 -0
  377. package/src/mcp/terraform/tfquery.ts +159 -0
  378. package/src/mcp/terraform/toolchainIntegrity.ts +151 -0
  379. package/src/mcp/terraform/tools/authorPolicy.ts +185 -0
  380. package/src/mcp/terraform/tools/detectPlanDrift.ts +279 -0
  381. package/src/mcp/terraform/tools/emitCost.ts +130 -0
  382. package/src/mcp/terraform/tools/emitSarif.ts +108 -0
  383. package/src/mcp/terraform/tools/fixMemory.ts +82 -0
  384. package/src/mcp/terraform/tools/infracostDiff.ts +110 -0
  385. package/src/mcp/terraform/tools/ingestExternalFindings.ts +259 -0
  386. package/src/mcp/terraform/tools/moduleLookup.ts +86 -0
  387. package/src/mcp/terraform/tools/moduleSearch.ts +46 -0
  388. package/src/mcp/terraform/tools/plan.ts +384 -0
  389. package/src/mcp/terraform/tools/providerUpgrade.ts +217 -0
  390. package/src/mcp/terraform/tools/readFindings.ts +138 -0
  391. package/src/mcp/terraform/tools/scan.ts +303 -0
  392. package/src/mcp/terraform/tools/validate.ts +160 -0
  393. package/src/mcp/terraform/tools/verifyRemediation.ts +190 -0
  394. package/src/mcp/terraform/tools/versionCurrency.ts +64 -0
  395. package/src/mcp/terraform/tools.ts +62 -0
  396. package/src/mcp/terraform/transformPacks.ts +594 -0
  397. package/src/mcp/terraform/types.ts +382 -0
  398. package/src/mcp/terraform/verification.ts +150 -0
  399. package/src/mcp/terraform/vex.ts +367 -0
  400. package/src/mcp/terraform/writeOnly.ts +252 -0
  401. package/src/mcp/terraform.ts +52 -0
  402. package/src/mcp/terratest.ts +215 -0
  403. package/src/mcp/untrustedContent.ts +126 -0
  404. package/src/mcp/upload.ts +123 -0
  405. package/src/models.ts +753 -0
  406. package/src/modes/address-reviews.ts +35 -0
  407. package/src/modes/assess.ts +27 -0
  408. package/src/modes/build.ts +86 -0
  409. package/src/modes/compliance-audit.ts +25 -0
  410. package/src/modes/cost-optimization.ts +36 -0
  411. package/src/modes/drift-detect.ts +31 -0
  412. package/src/modes/fix.ts +29 -0
  413. package/src/modes/incremental-review.ts +103 -0
  414. package/src/modes/index.ts +94 -0
  415. package/src/modes/modernize-deprecated.ts +36 -0
  416. package/src/modes/plan.ts +21 -0
  417. package/src/modes/policy-gate.ts +27 -0
  418. package/src/modes/prFormats.ts +325 -0
  419. package/src/modes/refactor.ts +74 -0
  420. package/src/modes/refresh-remediation.ts +40 -0
  421. package/src/modes/remediate-and-refactor.ts +42 -0
  422. package/src/modes/remediate.ts +78 -0
  423. package/src/modes/resolve-conflicts.ts +32 -0
  424. package/src/modes/review.ts +135 -0
  425. package/src/modes/summarize-pr.ts +42 -0
  426. package/src/modes/task.ts +26 -0
  427. package/src/modes/terraform-code-review.ts +68 -0
  428. package/src/modes/types.ts +17 -0
  429. package/src/modes/update-dependencies.ts +44 -0
  430. package/src/prep/index.ts +96 -0
  431. package/src/prep/installNodeDependencies.ts +251 -0
  432. package/src/prep/installPythonDependencies.ts +235 -0
  433. package/src/prep/types.ts +38 -0
  434. package/src/reviewQuality.ts +237 -0
  435. package/src/runCli.ts +335 -0
  436. package/src/skills/terraform-best-practices/SKILL.md +379 -0
  437. package/src/toolState.ts +241 -0
  438. package/src/utils/activity.ts +210 -0
  439. package/src/utils/agent.ts +245 -0
  440. package/src/utils/agentHangReport.ts +180 -0
  441. package/src/utils/annotations.ts +56 -0
  442. package/src/utils/apiFetch.ts +19 -0
  443. package/src/utils/apiKeys.ts +305 -0
  444. package/src/utils/apiUrl.ts +42 -0
  445. package/src/utils/assets.ts +123 -0
  446. package/src/utils/baseRefConfig.ts +254 -0
  447. package/src/utils/billingErrors.ts +210 -0
  448. package/src/utils/body.ts +168 -0
  449. package/src/utils/buildInfraweaverFooter.ts +104 -0
  450. package/src/utils/byokFallback.ts +137 -0
  451. package/src/utils/changeImpact.ts +330 -0
  452. package/src/utils/claudeSubscription.ts +93 -0
  453. package/src/utils/cli.ts +36 -0
  454. package/src/utils/cloudClient.ts +57 -0
  455. package/src/utils/cloudFetchCore.ts +139 -0
  456. package/src/utils/cloudReport.ts +316 -0
  457. package/src/utils/codexHome.ts +204 -0
  458. package/src/utils/codexOAuth.ts +154 -0
  459. package/src/utils/codexRefreshDetect.ts +36 -0
  460. package/src/utils/diffCoverage.ts +404 -0
  461. package/src/utils/env.ts +84 -0
  462. package/src/utils/errorReport.ts +94 -0
  463. package/src/utils/exitHandler.ts +35 -0
  464. package/src/utils/fixDoubleEscapedString.ts +9 -0
  465. package/src/utils/ghaCore.ts +13 -0
  466. package/src/utils/gitAuth.ts +268 -0
  467. package/src/utils/gitAuthServer.ts +186 -0
  468. package/src/utils/github.ts +676 -0
  469. package/src/utils/globals.ts +9 -0
  470. package/src/utils/humanEditCapture.ts +198 -0
  471. package/src/utils/infraweaverConfig.ts +202 -0
  472. package/src/utils/install.ts +279 -0
  473. package/src/utils/instructions.ts +640 -0
  474. package/src/utils/keylessOidc.ts +47 -0
  475. package/src/utils/leapingComment.ts +20 -0
  476. package/src/utils/learnings.ts +145 -0
  477. package/src/utils/learningsTruncate.ts +42 -0
  478. package/src/utils/lifecycle.ts +198 -0
  479. package/src/utils/log.ts +452 -0
  480. package/src/utils/modelResolver.ts +105 -0
  481. package/src/utils/moduleFetch.ts +138 -0
  482. package/src/utils/normalizeEnv.ts +106 -0
  483. package/src/utils/openCodeModels.ts +86 -0
  484. package/src/utils/openaiCompatible.ts +52 -0
  485. package/src/utils/opentofuMcp.ts +61 -0
  486. package/src/utils/overrides.ts +100 -0
  487. package/src/utils/packageManager.ts +257 -0
  488. package/src/utils/patchWorkflowRunFields.ts +173 -0
  489. package/src/utils/payload.ts +1206 -0
  490. package/src/utils/prSummary.ts +148 -0
  491. package/src/utils/presets.ts +105 -0
  492. package/src/utils/progressComment.ts +266 -0
  493. package/src/utils/providerErrors.ts +189 -0
  494. package/src/utils/proxyModel.ts +239 -0
  495. package/src/utils/rangeDiff.ts +182 -0
  496. package/src/utils/redact.ts +86 -0
  497. package/src/utils/registryAuth.ts +115 -0
  498. package/src/utils/remediationCommand.ts +144 -0
  499. package/src/utils/retry.ts +180 -0
  500. package/src/utils/reviewCleanup.ts +116 -0
  501. package/src/utils/run.ts +100 -0
  502. package/src/utils/runContext.ts +276 -0
  503. package/src/utils/runContextData.ts +121 -0
  504. package/src/utils/runErrorRenderer.ts +282 -0
  505. package/src/utils/runFixture.ts +91 -0
  506. package/src/utils/runLifecycle.ts +360 -0
  507. package/src/utils/runStartupLog.ts +67 -0
  508. package/src/utils/secrets.ts +208 -0
  509. package/src/utils/setup.ts +368 -0
  510. package/src/utils/shell.ts +132 -0
  511. package/src/utils/skills.ts +67 -0
  512. package/src/utils/subprocess.ts +474 -0
  513. package/src/utils/terraformMcp.ts +99 -0
  514. package/src/utils/time.ts +59 -0
  515. package/src/utils/timer.ts +72 -0
  516. package/src/utils/todoTracking.ts +168 -0
  517. package/src/utils/token.ts +294 -0
  518. package/src/utils/toolLicensing.ts +152 -0
  519. package/src/utils/toolSelection.ts +239 -0
  520. package/src/utils/toon.ts +76 -0
  521. package/src/utils/version.ts +10 -0
  522. package/src/utils/versioning.ts +44 -0
  523. package/src/utils/vertex.ts +94 -0
  524. package/src/utils/workflow.ts +25 -0
@@ -0,0 +1,498 @@
1
+ // this must be imported first
2
+ import "#app/mcp/arkConfig";
3
+ import { randomUUID } from "node:crypto";
4
+ import { createServer } from "node:net";
5
+ import { setTimeout as sleep } from "node:timers/promises";
6
+ import { FastMCP } from "fastmcp";
7
+ import { type AgentId, infraweaverMcpName } from "#app/external";
8
+ import { TerraformAssessTool } from "#app/mcp/assess";
9
+ import { TerraformChangeSummaryTool } from "#app/mcp/changeSummary";
10
+ import { CheckoutPrTool } from "#app/mcp/checkout";
11
+ import { GetCheckSuiteLogsTool } from "#app/mcp/checkSuite";
12
+ import {
13
+ CreateCommentTool,
14
+ EditCommentTool,
15
+ ReplyToReviewCommentTool,
16
+ ReportProgressTool,
17
+ } from "#app/mcp/comment";
18
+ import { CommitInfoTool } from "#app/mcp/commitInfo";
19
+ import { ComplianceCrosswalkTool } from "#app/mcp/crosswalk";
20
+ import { UpsertRemediationDashboardTool } from "#app/mcp/dashboard";
21
+ import {
22
+ AwaitDependencyInstallationTool,
23
+ StartDependencyInstallationTool,
24
+ } from "#app/mcp/dependencies";
25
+ import {
26
+ DeleteBranchTool,
27
+ GitFetchTool,
28
+ GitTool,
29
+ PushBranchTool,
30
+ PushTagsTool,
31
+ } from "#app/mcp/git";
32
+ import { IssueTool } from "#app/mcp/issue";
33
+ import { GetIssueCommentsTool } from "#app/mcp/issueComments";
34
+ import { GetIssueEventsTool } from "#app/mcp/issueEvents";
35
+ import { IssueInfoTool } from "#app/mcp/issueInfo";
36
+ import { AddLabelsTool } from "#app/mcp/labels";
37
+ import { ModuleExtractionCandidatesTool } from "#app/mcp/moduleExtraction";
38
+ import {
39
+ ListModulesTool,
40
+ TerraformModuleGraphTool,
41
+ TerraformModuleInterfaceTool,
42
+ } from "#app/mcp/modules";
43
+ import { TerraformModuleTestsTool } from "#app/mcp/moduleTests";
44
+ import { SetOutputTool } from "#app/mcp/output";
45
+ import { PolicyCheckTool } from "#app/mcp/policy";
46
+ import { CreatePullRequestTool, UpdatePullRequestBodyTool } from "#app/mcp/pr";
47
+ import { PullRequestInfoTool } from "#app/mcp/prInfo";
48
+ import { TerraformProviderSchemaTool } from "#app/mcp/providerSchema";
49
+ import { CreatePullRequestReviewTool } from "#app/mcp/review";
50
+ import {
51
+ GetReviewCommentsTool,
52
+ ListPullRequestReviewsTool,
53
+ ResolveReviewThreadTool,
54
+ } from "#app/mcp/reviewComments";
55
+ import { TerraformRootsTool } from "#app/mcp/roots";
56
+ import { SelectModeTool } from "#app/mcp/selectMode";
57
+ import { addTools, type InfraweaverTool } from "#app/mcp/shared";
58
+ import { KillBackgroundTool, ShellTool } from "#app/mcp/shell";
59
+ import {
60
+ ClosePullRequestTool,
61
+ ListRemediationPrsTool,
62
+ } from "#app/mcp/staleFix";
63
+ import {
64
+ DetectPlanDriftTool,
65
+ InfracostDiffTool,
66
+ IngestExternalFindingsTool,
67
+ NormalizationCandidatesTool,
68
+ PolicyAuthorTool,
69
+ ReadFindingsTool,
70
+ TerraformEmitCostTool,
71
+ TerraformEmitEvidenceTool,
72
+ TerraformEmitOscalTool,
73
+ TerraformEmitSarifTool,
74
+ TerraformEmitVexTool,
75
+ TerraformEquivalenceCheckTool,
76
+ TerraformFixMemoryTool,
77
+ TerraformGenerateMovedTool,
78
+ TerraformModuleDocsTool,
79
+ TerraformModuleLookupTool,
80
+ TerraformModuleSearchTool,
81
+ TerraformPlanTool,
82
+ TerraformProviderUpgradeTool,
83
+ TerraformQueryInventoryTool,
84
+ TerraformScanTool,
85
+ TerraformValidateTool,
86
+ TerraformVerifyRemediationTool,
87
+ TerraformVersionCurrencyTool,
88
+ } from "#app/mcp/terraform";
89
+ import { ScaffoldTerratestTool } from "#app/mcp/terratest";
90
+ import { UploadFileTool } from "#app/mcp/upload";
91
+ import type { Mode } from "#app/modes";
92
+ import type { ToolState } from "#app/toolState";
93
+ import type { OctokitWithPlugins } from "#app/utils/github";
94
+ import type { ResolvedPayload } from "#app/utils/payload";
95
+ import type { AccountPlan } from "#app/utils/runContext";
96
+ import type { RunContextData } from "#app/utils/runContextData";
97
+ import packageJson from "#package.json" with { type: "json" };
98
+
99
+ export interface ToolContext {
100
+ agentId: AgentId;
101
+ repo: RunContextData["repo"];
102
+ payload: ResolvedPayload;
103
+ octokit: OctokitWithPlugins;
104
+ githubInstallationToken: string;
105
+ gitToken: string;
106
+ // single-flight git-token re-minter (pullfrog #972), or undefined when
107
+ // re-minting isn't possible (off-CI / external GH_TOKEN). pushWithRetry calls
108
+ // it to recover from an auth-class push 401 with a fresh installation token.
109
+ refreshGitToken?: ((stale: string) => Promise<string>) | undefined;
110
+ apiToken: string;
111
+ modes: Mode[];
112
+ postCheckoutScript: string | null;
113
+ prepushScript: string | null;
114
+ prApproveEnabled: boolean;
115
+ modeInstructions: Record<string, string>;
116
+ toolState: ToolState;
117
+ runId: number | undefined;
118
+ mcpServerUrl: string;
119
+ // per-run bearer token the agent's MCP client must present (Authorization:
120
+ // Bearer <token>) to reach this server. Closes the unauthenticated-localhost
121
+ // side door: a co-located process on the runner (e.g. a malicious dependency
122
+ // postinstall) that scans the loopback port range can no longer drive
123
+ // privileged tools without the token. Minted in startMcpHttpServer; delivered
124
+ // to each agent's MCP config out-of-band (env-expanded header for Claude,
125
+ // OPENCODE_CONFIG_CONTENT for opencode) so it never lands in a readable file.
126
+ mcpServerToken: string;
127
+ tmpdir: string;
128
+ // repo-level OSS flag + account-level billing plan. together they decide
129
+ // whether infraweaver is paying for marginal infra — see `isInfraCovered` in
130
+ // the server's `utils/billing.ts`. plan gating for endpoints like the
131
+ // learnings PATCH is enforced server-side via 402, so we pass plan along
132
+ // mostly for future use / observability. see wiki/pricing.md.
133
+ oss: boolean;
134
+ plan: AccountPlan;
135
+ // resolved upstream model specifier (e.g. "google/gemini-3.1-pro-preview").
136
+ // undefined when the alias is unresolvable (agent auto-selects).
137
+ // used by the schema sanitizer to detect Gemini-routed traffic.
138
+ resolvedModel: string | undefined;
139
+ }
140
+
141
+ const mcpPortStart = 3764;
142
+ const mcpPortAttempts = 100;
143
+ const mcpHost = "127.0.0.1";
144
+ const mcpEndpoint = "/mcp";
145
+
146
+ function readEnvPort(): number | null {
147
+ const rawPort = process.env.INFRAWEAVER_MCP_PORT;
148
+ if (!rawPort) return null;
149
+ const parsed = Number.parseInt(rawPort, 10);
150
+ if (!Number.isInteger(parsed) || parsed <= 0 || parsed > 65535) {
151
+ throw new Error(`invalid INFRAWEAVER_MCP_PORT: ${rawPort}`);
152
+ }
153
+ return parsed;
154
+ }
155
+
156
+ function isPortAvailable(port: number): Promise<boolean> {
157
+ return new Promise((resolve) => {
158
+ const server = createServer();
159
+ server.unref();
160
+ server.once("error", () => resolve(false));
161
+ server.once("listening", () => {
162
+ server.close(() => resolve(true));
163
+ });
164
+ server.listen(port, mcpHost);
165
+ });
166
+ }
167
+
168
+ function getErrorMessage(error: unknown): string {
169
+ if (error instanceof Error) return error.message;
170
+ return String(error);
171
+ }
172
+
173
+ function isAddressInUse(error: unknown): boolean {
174
+ const message = getErrorMessage(error).toLowerCase();
175
+ return (
176
+ message.includes("eaddrinuse") || message.includes("address already in use")
177
+ );
178
+ }
179
+
180
+ type JsonSchema = Record<string, unknown>;
181
+
182
+ function buildCommonTools(
183
+ ctx: ToolContext,
184
+ outputSchema?: JsonSchema,
185
+ ): InfraweaverTool[] {
186
+ const tools: InfraweaverTool[] = [
187
+ StartDependencyInstallationTool(ctx),
188
+ AwaitDependencyInstallationTool(ctx),
189
+ CreateCommentTool(ctx),
190
+ EditCommentTool(ctx),
191
+ ReplyToReviewCommentTool(ctx),
192
+ IssueTool(ctx),
193
+ IssueInfoTool(ctx),
194
+ GetIssueCommentsTool(ctx),
195
+ GetIssueEventsTool(ctx),
196
+ CreatePullRequestReviewTool(ctx),
197
+ PullRequestInfoTool(ctx),
198
+ CommitInfoTool(ctx),
199
+ CheckoutPrTool(ctx),
200
+ TerraformChangeSummaryTool(ctx),
201
+ GetReviewCommentsTool(ctx),
202
+ ListPullRequestReviewsTool(ctx),
203
+ ResolveReviewThreadTool(ctx),
204
+ GetCheckSuiteLogsTool(ctx),
205
+ AddLabelsTool(ctx),
206
+ GitTool(ctx),
207
+ GitFetchTool(ctx),
208
+ UploadFileTool(ctx),
209
+ // Terraform best-practice check tools (read-only). Always available so the
210
+ // Remediate mode can scan + gate without extra perms.
211
+ TerraformScanTool(ctx),
212
+ TerraformAssessTool(ctx),
213
+ TerraformValidateTool(ctx),
214
+ TerraformVerifyRemediationTool(ctx),
215
+ TerraformFixMemoryTool(ctx),
216
+ InfracostDiffTool(ctx),
217
+ ReadFindingsTool(ctx),
218
+ IngestExternalFindingsTool(ctx),
219
+ DetectPlanDriftTool(ctx),
220
+ TerraformPlanTool(ctx),
221
+ TerraformProviderUpgradeTool(ctx),
222
+ TerraformVersionCurrencyTool(ctx),
223
+ TerraformModuleLookupTool(ctx),
224
+ TerraformModuleSearchTool(ctx),
225
+ ListModulesTool(ctx),
226
+ TerraformModuleGraphTool(ctx),
227
+ TerraformModuleInterfaceTool(ctx),
228
+ TerraformModuleTestsTool(ctx),
229
+ ModuleExtractionCandidatesTool(ctx),
230
+ NormalizationCandidatesTool(ctx),
231
+ TerraformQueryInventoryTool(ctx),
232
+ TerraformEquivalenceCheckTool(ctx),
233
+ TerraformGenerateMovedTool(ctx),
234
+ TerraformModuleDocsTool(ctx),
235
+ TerraformProviderSchemaTool(ctx),
236
+ TerraformRootsTool(ctx),
237
+ ScaffoldTerratestTool(ctx),
238
+ TerraformEmitSarifTool(ctx),
239
+ TerraformEmitEvidenceTool(ctx),
240
+ TerraformEmitOscalTool(ctx),
241
+ TerraformEmitVexTool(ctx),
242
+ TerraformEmitCostTool(ctx),
243
+ PolicyCheckTool(ctx),
244
+ // §5.2 authoring: prose → reviewed Rego / .policy.hcl. Pairs with the
245
+ // PolicyCheckTool above — author here, enforce there.
246
+ PolicyAuthorTool(),
247
+ ComplianceCrosswalkTool(ctx),
248
+ ];
249
+
250
+ const isStandalone = ctx.payload.event.trigger === "unknown";
251
+ if (isStandalone || outputSchema) {
252
+ tools.push(SetOutputTool(ctx, outputSchema));
253
+ }
254
+
255
+ // MCP shell with filtered env (no secrets leaked to child processes)
256
+ if (ctx.payload.shell === "restricted") {
257
+ tools.push(ShellTool(ctx));
258
+ tools.push(KillBackgroundTool(ctx));
259
+ }
260
+
261
+ return tools;
262
+ }
263
+
264
+ function buildOrchestratorTools(
265
+ ctx: ToolContext,
266
+ outputSchema?: JsonSchema,
267
+ ): InfraweaverTool[] {
268
+ return [
269
+ ...buildCommonTools(ctx, outputSchema),
270
+ ReportProgressTool(ctx),
271
+ SelectModeTool(ctx),
272
+ PushBranchTool(ctx),
273
+ PushTagsTool(ctx),
274
+ DeleteBranchTool(ctx),
275
+ CreatePullRequestTool(ctx),
276
+ UpdatePullRequestBodyTool(ctx),
277
+ // stale-fix self-healing — list open remediation PRs + close a redundant
278
+ // one. Orchestrator-only (close is a write; the sweep is an orchestrator job).
279
+ ListRemediationPrsTool(ctx),
280
+ ClosePullRequestTool(ctx),
281
+ // the single per-repo Remediation Dashboard issue (open PRs / waiting
282
+ // groups with on-demand checkboxes / suppressed). Upsert, so one issue total.
283
+ UpsertRemediationDashboardTool(ctx),
284
+ ];
285
+ }
286
+
287
+ /**
288
+ * The per-run subagent deny set: the canonical bare names of every registered
289
+ * orchestrator tool marked `mutates: true`. Derived here (not from a static list)
290
+ * so a newly-added mutating tool is fenced the moment it's tagged — there is no
291
+ * separate list to drift. Embedded into the claude/opencode subagent gates
292
+ * (`buildClaudePretoolGateSource` / `buildOpencodeSubagentGateSource`).
293
+ *
294
+ * Throws when the derived set is empty: that means the `mutates` tagging
295
+ * regressed, and we refuse to start with the gate silently disabled rather than
296
+ * let subagents reach state-changing tools.
297
+ */
298
+ export function subagentDeniedToolNames(
299
+ ctx: ToolContext,
300
+ outputSchema?: JsonSchema,
301
+ ): string[] {
302
+ const names = buildOrchestratorTools(ctx, outputSchema)
303
+ .filter((t) => t.mutates)
304
+ .map((t) => t.name);
305
+ if (names.length === 0) {
306
+ throw new Error(
307
+ "subagent deny list derived empty — no MCP tool is marked `mutates: true`. " +
308
+ "refusing to start with the subagent gate disabled.",
309
+ );
310
+ }
311
+ return names;
312
+ }
313
+
314
+ type McpStartResult = {
315
+ server: FastMCP;
316
+ url: string;
317
+ port: number;
318
+ };
319
+
320
+ /**
321
+ * Build the FastMCP `authenticate` hook that enforces the per-run bearer token.
322
+ *
323
+ * The streamable-HTTP transport invokes this at session creation, so a caller
324
+ * without the token can't even open a session (let alone call a tool). On a
325
+ * valid token it returns a truthy session object; otherwise it throws and the
326
+ * transport rejects the connection. The token is compared with a
327
+ * length-then-constant-time check to avoid leaking it via timing.
328
+ */
329
+ function buildAuthenticate(token: string) {
330
+ const expected = `Bearer ${token}`;
331
+ return async (
332
+ request: import("node:http").IncomingMessage,
333
+ ): Promise<{ authorized: true }> => {
334
+ const header = request.headers.authorization;
335
+ const provided = Array.isArray(header) ? header[0] : header;
336
+ if (!provided || !timingSafeEqualStr(provided, expected)) {
337
+ throw new Error("Unauthorized: missing or invalid MCP bearer token");
338
+ }
339
+ return { authorized: true };
340
+ };
341
+ }
342
+
343
+ /** constant-time string compare (length-guarded) so a wrong token can't be
344
+ * recovered byte-by-byte via response timing. */
345
+ function timingSafeEqualStr(a: string, b: string): boolean {
346
+ if (a.length !== b.length) return false;
347
+ let diff = 0;
348
+ for (let i = 0; i < a.length; i++) {
349
+ diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
350
+ }
351
+ return diff === 0;
352
+ }
353
+
354
+ async function tryStartMcpServer(
355
+ ctx: ToolContext,
356
+ tools: InfraweaverTool[],
357
+ port: number,
358
+ token: string,
359
+ ): Promise<McpStartResult | null> {
360
+ const server = new FastMCP({
361
+ name: infraweaverMcpName,
362
+ version: packageJson.version as `${number}.${number}.${number}`,
363
+ authenticate: buildAuthenticate(token),
364
+ });
365
+ addTools(ctx, server, tools);
366
+
367
+ try {
368
+ await server.start({
369
+ transportType: "httpStream",
370
+ httpStream: {
371
+ port,
372
+ host: mcpHost,
373
+ endpoint: mcpEndpoint,
374
+ },
375
+ });
376
+ const url = `http://${mcpHost}:${port}${mcpEndpoint}`;
377
+ return { server, url, port };
378
+ } catch (error) {
379
+ if (!isAddressInUse(error)) {
380
+ throw error;
381
+ }
382
+ try {
383
+ await server.stop();
384
+ } catch {
385
+ // ignore cleanup errors on failed start
386
+ }
387
+ return null;
388
+ }
389
+ }
390
+
391
+ async function selectMcpPort(
392
+ ctx: ToolContext,
393
+ tools: InfraweaverTool[],
394
+ token: string,
395
+ ): Promise<McpStartResult> {
396
+ let lastError: unknown = null;
397
+
398
+ const requestedPort = readEnvPort();
399
+ if (requestedPort !== null) {
400
+ if (await isPortAvailable(requestedPort)) {
401
+ const requestedResult = await tryStartMcpServer(
402
+ ctx,
403
+ tools,
404
+ requestedPort,
405
+ token,
406
+ );
407
+ if (requestedResult) {
408
+ return requestedResult;
409
+ }
410
+ }
411
+ }
412
+
413
+ // randomize start offset to reduce collision chance in parallel runs
414
+ const randomOffset = Math.floor(Math.random() * 50);
415
+
416
+ for (let offset = 0; offset < mcpPortAttempts; offset++) {
417
+ const port = mcpPortStart + randomOffset + offset;
418
+ try {
419
+ if (!(await isPortAvailable(port))) {
420
+ continue;
421
+ }
422
+ const result = await tryStartMcpServer(ctx, tools, port, token);
423
+ if (result) {
424
+ return result;
425
+ }
426
+ } catch (error) {
427
+ lastError = error;
428
+ if (!isAddressInUse(error)) {
429
+ throw error;
430
+ }
431
+ }
432
+ }
433
+
434
+ const message = getErrorMessage(lastError);
435
+ throw new Error(
436
+ `could not find available mcp port starting at ${mcpPortStart} (last error: ${message})`,
437
+ );
438
+ }
439
+
440
+ async function killBackgroundProcesses(toolState: ToolState): Promise<void> {
441
+ const backgroundProcesses = toolState.backgroundProcesses;
442
+ if (backgroundProcesses.size === 0) return;
443
+ for (const proc of backgroundProcesses.values()) {
444
+ try {
445
+ process.kill(-proc.pid, "SIGTERM");
446
+ } catch {
447
+ // already dead
448
+ }
449
+ }
450
+ await sleep(200);
451
+ for (const proc of backgroundProcesses.values()) {
452
+ try {
453
+ process.kill(-proc.pid, "SIGKILL");
454
+ } catch {
455
+ // already dead
456
+ }
457
+ }
458
+ backgroundProcesses.clear();
459
+ }
460
+
461
+ type McpHttpServerOptions = {
462
+ outputSchema?: JsonSchema | undefined;
463
+ };
464
+
465
+ /**
466
+ * Start the MCP HTTP server.
467
+ *
468
+ * The returned disposer is idempotent — safe to call multiple times.
469
+ * Callers (e.g. the inner activity-timeout handler in main.ts) may need to
470
+ * stop the server before the `await using` block exits; a subsequent
471
+ * automatic dispose is then a no-op.
472
+ */
473
+ export async function startMcpHttpServer(
474
+ ctx: ToolContext,
475
+ options?: McpHttpServerOptions,
476
+ ): Promise<{
477
+ url: string;
478
+ token: string;
479
+ [Symbol.asyncDispose]: () => Promise<void>;
480
+ }> {
481
+ // per-run bearer token. minted here (not in process.env) and returned so the
482
+ // caller can hand it to the agent's MCP client out-of-band; see ToolContext.
483
+ const token = randomUUID();
484
+ const tools = buildOrchestratorTools(ctx, options?.outputSchema);
485
+ const startResult = await selectMcpPort(ctx, tools, token);
486
+
487
+ let disposed = false;
488
+ return {
489
+ url: startResult.url,
490
+ token,
491
+ [Symbol.asyncDispose]: async () => {
492
+ if (disposed) return;
493
+ disposed = true;
494
+ await killBackgroundProcesses(ctx.toolState);
495
+ await startResult.server.stop();
496
+ },
497
+ };
498
+ }
@@ -0,0 +1,120 @@
1
+ import type { StandardSchemaV1 } from "@standard-schema/spec";
2
+ import type { FastMCP, Tool } from "fastmcp";
3
+ import {
4
+ isGeminiRouted,
5
+ sanitizeToolForGemini,
6
+ } from "#app/mcp/geminiSanitizer";
7
+ import type { ToolContext } from "#app/mcp/server";
8
+ import { formatJsonValue, log } from "#app/utils/cli";
9
+ import { toonEncode } from "#app/utils/toon";
10
+
11
+ /**
12
+ * A FastMCP tool augmented with infraweaver's `mutates` flag: `true` marks a
13
+ * state-changing tool (working tree, remote, GitHub state, run state, fs/process)
14
+ * that subagents must not call. The subagent deny list is derived from this flag
15
+ * at runtime (see `subagentDeniedToolNames`) rather than a hand-maintained list,
16
+ * so a new mutating tool is gated the moment it's tagged — no separate list to
17
+ * drift out of sync.
18
+ */
19
+ export type InfraweaverTool = Tool<any, any> & { mutates?: boolean };
20
+
21
+ export const tool = <const params>(
22
+ toolDef: Tool<any, StandardSchemaV1<params>> & { mutates?: boolean },
23
+ ): Tool<any, StandardSchemaV1<params>> & { mutates?: boolean } => toolDef;
24
+
25
+ export interface ToolResult {
26
+ content: {
27
+ type: "text";
28
+ text: string;
29
+ }[];
30
+ isError?: boolean;
31
+ }
32
+
33
+ /**
34
+ * Structured tool-outcome envelope ("Structured tool errors"). Every tool
35
+ * that can be unavailable, skipped, or degrade green returns the SAME shape so a
36
+ * caller (the agent, or a downstream parser) can branch deterministically:
37
+ * - success: `{ ok: true, … }`
38
+ * - skip / unavailable / soft failure: `{ ok: false, code, detail }`
39
+ * where `code` is a stable machine token (snake_case) and `detail` a human
40
+ * sentence. The newer tools (terraform_roots / terraform_module_interface /
41
+ * terraform_provider_schema / policy_check) emit this natively; the older
42
+ * degrade-green tools historically returned `{ ran|found: false,
43
+ * skipped_reason|reason }`. Those keep their legacy aliases ALONGSIDE the new
44
+ * fields (the call site spreads `toolSkip(...)` into its existing object) so
45
+ * prompt + test contracts keep working while the surface converges — additive,
46
+ * never breaking.
47
+ */
48
+ export type ToolOk<T extends Record<string, any>> = T & { ok: true };
49
+
50
+ /** wrap a success payload with `ok: true`. */
51
+ export const toolOk = <T extends Record<string, any>>(data: T): ToolOk<T> => ({
52
+ ok: true,
53
+ ...data,
54
+ });
55
+
56
+ /** the structured skip/unavailable envelope: `{ ok: false, code, detail }`. */
57
+ export const toolSkip = (
58
+ code: string,
59
+ detail: string,
60
+ ): { ok: false; code: string; detail: string } => ({ ok: false, code, detail });
61
+
62
+ export const handleToolSuccess = (
63
+ data: Record<string, any> | string,
64
+ ): ToolResult => {
65
+ const text = typeof data === "string" ? data : toonEncode(data);
66
+ return {
67
+ content: [{ type: "text", text }],
68
+ };
69
+ };
70
+
71
+ export const handleToolError = (error: unknown): ToolResult => {
72
+ const errorMessage = error instanceof Error ? error.message : String(error);
73
+ return {
74
+ content: [
75
+ {
76
+ type: "text",
77
+ text: `Error: ${errorMessage}`,
78
+ },
79
+ ],
80
+ isError: true,
81
+ };
82
+ };
83
+
84
+ /**
85
+ * Helper to wrap a tool execute function with error handling.
86
+ * Captures ctx in closure so tools don't need to handle try/catch.
87
+ * @param fn - the function to execute
88
+ * @param toolName - optional tool name for error logging
89
+ */
90
+ export const execute = <T, R extends Record<string, any> | string>(
91
+ fn: (params: T) => Promise<R>,
92
+ toolName?: string,
93
+ ) => {
94
+ const _fn = async (params: T): Promise<ToolResult> => {
95
+ try {
96
+ const result = await fn(params);
97
+ return handleToolSuccess(result);
98
+ } catch (error) {
99
+ const errorMessage =
100
+ error instanceof Error ? error.message : String(error);
101
+ const prefix = toolName ? `[${toolName}]` : "tool";
102
+ log.info(`${prefix} error: ${errorMessage}`);
103
+ log.debug(`${prefix} params: ${formatJsonValue(params)}`);
104
+ return handleToolError(error);
105
+ }
106
+ };
107
+ return _fn;
108
+ };
109
+
110
+ export const addTools = (
111
+ ctx: ToolContext,
112
+ server: FastMCP<any>,
113
+ tools: InfraweaverTool[],
114
+ ) => {
115
+ const shouldSanitize = isGeminiRouted(ctx);
116
+ for (const tool of tools) {
117
+ server.addTool(shouldSanitize ? sanitizeToolForGemini(tool) : tool);
118
+ }
119
+ return server;
120
+ };