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