terramend 0.2.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 (406) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +145 -0
  3. package/dist/agents/claude.d.ts +73 -0
  4. package/dist/agents/claudePretoolGate.d.ts +99 -0
  5. package/dist/agents/gateServer.d.ts +7 -0
  6. package/dist/agents/index.d.ts +6 -0
  7. package/dist/agents/nativeFsDenies.d.ts +28 -0
  8. package/dist/agents/opencode.d.ts +231 -0
  9. package/dist/agents/opencodePlugin.d.ts +85 -0
  10. package/dist/agents/opencodeShared.d.ts +40 -0
  11. package/dist/agents/postRun.d.ts +132 -0
  12. package/dist/agents/reviewer.d.ts +38 -0
  13. package/dist/agents/sessionLabeler.d.ts +97 -0
  14. package/dist/agents/shared.d.ts +189 -0
  15. package/dist/agents/subagentModels.d.ts +19 -0
  16. package/dist/agents/subagentToolGates.d.ts +55 -0
  17. package/dist/cli.mjs +197426 -0
  18. package/dist/external.d.ts +227 -0
  19. package/dist/index.d.ts +6 -0
  20. package/dist/index.js +196783 -0
  21. package/dist/internal/index.d.ts +18 -0
  22. package/dist/internal.js +1714 -0
  23. package/dist/lifecycle.d.ts +2 -0
  24. package/dist/main.d.ts +8 -0
  25. package/dist/mcp/arkConfig.d.ts +1 -0
  26. package/dist/mcp/checkSuite.d.ts +25 -0
  27. package/dist/mcp/checkout.d.ts +77 -0
  28. package/dist/mcp/comment.d.ts +119 -0
  29. package/dist/mcp/commitInfo.d.ts +9 -0
  30. package/dist/mcp/crosswalk.d.ts +105 -0
  31. package/dist/mcp/dependencies.d.ts +8 -0
  32. package/dist/mcp/geminiSanitizer.d.ts +28 -0
  33. package/dist/mcp/git.d.ts +46 -0
  34. package/dist/mcp/guardrails.d.ts +104 -0
  35. package/dist/mcp/issue.d.ts +18 -0
  36. package/dist/mcp/issueComments.d.ts +9 -0
  37. package/dist/mcp/issueEvents.d.ts +9 -0
  38. package/dist/mcp/issueInfo.d.ts +9 -0
  39. package/dist/mcp/labels.d.ts +12 -0
  40. package/dist/mcp/localContext.d.ts +19 -0
  41. package/dist/mcp/moduleExtraction.d.ts +71 -0
  42. package/dist/mcp/moduleTests.d.ts +104 -0
  43. package/dist/mcp/modules.d.ts +179 -0
  44. package/dist/mcp/output.d.ts +12 -0
  45. package/dist/mcp/pathSafety.d.ts +14 -0
  46. package/dist/mcp/policy.d.ts +48 -0
  47. package/dist/mcp/pr.d.ts +49 -0
  48. package/dist/mcp/prInfo.d.ts +9 -0
  49. package/dist/mcp/providerSchema.d.ts +50 -0
  50. package/dist/mcp/review.d.ts +199 -0
  51. package/dist/mcp/reviewComments.d.ts +178 -0
  52. package/dist/mcp/roots.d.ts +58 -0
  53. package/dist/mcp/scope.d.ts +15 -0
  54. package/dist/mcp/selectMode.d.ts +18 -0
  55. package/dist/mcp/server.d.ts +48 -0
  56. package/dist/mcp/shared.d.ts +47 -0
  57. package/dist/mcp/shell.d.ts +37 -0
  58. package/dist/mcp/staleFix.d.ts +51 -0
  59. package/dist/mcp/terraform/cost.d.ts +55 -0
  60. package/dist/mcp/terraform/currency.d.ts +94 -0
  61. package/dist/mcp/terraform/decisions.d.ts +178 -0
  62. package/dist/mcp/terraform/findings.d.ts +75 -0
  63. package/dist/mcp/terraform/plan.d.ts +157 -0
  64. package/dist/mcp/terraform/scanners.d.ts +131 -0
  65. package/dist/mcp/terraform/tools.d.ts +63 -0
  66. package/dist/mcp/terraform/types.d.ts +172 -0
  67. package/dist/mcp/terraform.d.ts +22 -0
  68. package/dist/mcp/terratest.d.ts +83 -0
  69. package/dist/mcp/upload.d.ts +6 -0
  70. package/dist/models.d.ts +171 -0
  71. package/dist/modes.d.ts +26 -0
  72. package/dist/prep/index.d.ts +7 -0
  73. package/dist/prep/installNodeDependencies.d.ts +2 -0
  74. package/dist/prep/installPythonDependencies.d.ts +2 -0
  75. package/dist/prep/types.d.ts +31 -0
  76. package/dist/reviewQuality.d.ts +64 -0
  77. package/dist/skills/terraform-best-practices/SKILL.md +369 -0
  78. package/dist/toolState.d.ts +135 -0
  79. package/dist/utils/activity.d.ts +40 -0
  80. package/dist/utils/agent.d.ts +20 -0
  81. package/dist/utils/agentHangReport.d.ts +38 -0
  82. package/dist/utils/apiFetch.d.ts +19 -0
  83. package/dist/utils/apiKeys.d.ts +41 -0
  84. package/dist/utils/apiUrl.d.ts +20 -0
  85. package/dist/utils/assets.d.ts +8 -0
  86. package/dist/utils/billingErrors.d.ts +85 -0
  87. package/dist/utils/body.d.ts +34 -0
  88. package/dist/utils/buildTerramendFooter.d.ts +25 -0
  89. package/dist/utils/byokFallback.d.ts +85 -0
  90. package/dist/utils/claudeSubscription.d.ts +30 -0
  91. package/dist/utils/cli.d.ts +10 -0
  92. package/dist/utils/codexHome.d.ts +29 -0
  93. package/dist/utils/codexOAuth.d.ts +60 -0
  94. package/dist/utils/diffCoverage.d.ts +63 -0
  95. package/dist/utils/errorReport.d.ts +17 -0
  96. package/dist/utils/exitHandler.d.ts +8 -0
  97. package/dist/utils/fixDoubleEscapedString.d.ts +1 -0
  98. package/dist/utils/gitAuth.d.ts +84 -0
  99. package/dist/utils/gitAuthServer.d.ts +24 -0
  100. package/dist/utils/github.d.ts +78 -0
  101. package/dist/utils/globals.d.ts +3 -0
  102. package/dist/utils/install.d.ts +60 -0
  103. package/dist/utils/instructions.d.ts +48 -0
  104. package/dist/utils/leapingComment.d.ts +11 -0
  105. package/dist/utils/learnings.d.ts +62 -0
  106. package/dist/utils/learningsTruncate.d.ts +25 -0
  107. package/dist/utils/lifecycle.d.ts +57 -0
  108. package/dist/utils/log.d.ts +111 -0
  109. package/dist/utils/normalizeEnv.d.ts +30 -0
  110. package/dist/utils/openCodeModels.d.ts +11 -0
  111. package/dist/utils/overrides.d.ts +40 -0
  112. package/dist/utils/packageManager.d.ts +49 -0
  113. package/dist/utils/patchWorkflowRunFields.d.ts +29 -0
  114. package/dist/utils/payload.d.ts +105 -0
  115. package/dist/utils/prSummary.d.ts +61 -0
  116. package/dist/utils/progressComment.d.ts +146 -0
  117. package/dist/utils/providerErrors.d.ts +31 -0
  118. package/dist/utils/rangeDiff.d.ts +51 -0
  119. package/dist/utils/remediationCommand.d.ts +55 -0
  120. package/dist/utils/retry.d.ts +13 -0
  121. package/dist/utils/reviewCleanup.d.ts +14 -0
  122. package/dist/utils/run.d.ts +9 -0
  123. package/dist/utils/runContext.d.ts +60 -0
  124. package/dist/utils/runContextData.d.ts +23 -0
  125. package/dist/utils/runErrorRenderer.d.ts +64 -0
  126. package/dist/utils/runLifecycle.d.ts +86 -0
  127. package/dist/utils/runStartupLog.d.ts +15 -0
  128. package/dist/utils/secrets.d.ts +22 -0
  129. package/dist/utils/setup.d.ts +90 -0
  130. package/dist/utils/shell.d.ts +32 -0
  131. package/dist/utils/skills.d.ts +10 -0
  132. package/dist/utils/subprocess.d.ts +80 -0
  133. package/dist/utils/terraformMcp.d.ts +42 -0
  134. package/dist/utils/time.d.ts +15 -0
  135. package/dist/utils/timer.d.ts +23 -0
  136. package/dist/utils/todoTracking.d.ts +16 -0
  137. package/dist/utils/token.d.ts +39 -0
  138. package/dist/utils/version.d.ts +2 -0
  139. package/dist/utils/versioning.d.ts +7 -0
  140. package/dist/utils/vertex.d.ts +16 -0
  141. package/dist/utils/workflow.d.ts +13 -0
  142. package/package.json +119 -0
  143. package/src/agents/claude.test.ts +1016 -0
  144. package/src/agents/claude.ts +1246 -0
  145. package/src/agents/claudePretoolGate.test.ts +28 -0
  146. package/src/agents/claudePretoolGate.ts +173 -0
  147. package/src/agents/gateServer.test.ts +204 -0
  148. package/src/agents/gateServer.ts +124 -0
  149. package/src/agents/index.ts +10 -0
  150. package/src/agents/nativeFsDenies.ts +82 -0
  151. package/src/agents/opencode.test.ts +1440 -0
  152. package/src/agents/opencode.ts +1312 -0
  153. package/src/agents/opencodePlugin.ts +222 -0
  154. package/src/agents/opencodeShared.test.ts +34 -0
  155. package/src/agents/opencodeShared.ts +121 -0
  156. package/src/agents/postRun.test.ts +549 -0
  157. package/src/agents/postRun.ts +535 -0
  158. package/src/agents/reviewer.ts +104 -0
  159. package/src/agents/sessionLabeler.test.ts +247 -0
  160. package/src/agents/sessionLabeler.ts +178 -0
  161. package/src/agents/shared.test.ts +76 -0
  162. package/src/agents/shared.ts +292 -0
  163. package/src/agents/subagentModels.test.ts +113 -0
  164. package/src/agents/subagentModels.ts +40 -0
  165. package/src/agents/subagentRegistration.test.ts +41 -0
  166. package/src/agents/subagentToolGates.ts +114 -0
  167. package/src/cli.test.ts +129 -0
  168. package/src/cli.ts +105 -0
  169. package/src/commands/gha.test.ts +192 -0
  170. package/src/commands/gha.ts +188 -0
  171. package/src/commands/mcp.ts +122 -0
  172. package/src/config.ts +1 -0
  173. package/src/entry.ts +7 -0
  174. package/src/entryPost.stdlibOnly.test.ts +109 -0
  175. package/src/entryPost.ts +99 -0
  176. package/src/external.test.ts +16 -0
  177. package/src/external.ts +302 -0
  178. package/src/index.ts +11 -0
  179. package/src/internal/index.ts +71 -0
  180. package/src/lifecycle.ts +2 -0
  181. package/src/main.test.ts +873 -0
  182. package/src/main.ts +712 -0
  183. package/src/mcp/__fixtures__/terramend-scratch-pr-49-review-3485940013.json +110 -0
  184. package/src/mcp/__fixtures__/terramend-scratch-pr-64-review-3531000326.json +14 -0
  185. package/src/mcp/__fixtures__/terramend-test-repo-pr-1.diff.json +67 -0
  186. package/src/mcp/__snapshots__/checkout.test.ts.snap +109 -0
  187. package/src/mcp/__snapshots__/reviewComments.test.ts.snap +71 -0
  188. package/src/mcp/arkConfig.ts +7 -0
  189. package/src/mcp/checkSuite.test.ts +245 -0
  190. package/src/mcp/checkSuite.ts +255 -0
  191. package/src/mcp/checkout.test.ts +752 -0
  192. package/src/mcp/checkout.ts +886 -0
  193. package/src/mcp/comment.test.ts +772 -0
  194. package/src/mcp/comment.ts +582 -0
  195. package/src/mcp/commitInfo.test.ts +127 -0
  196. package/src/mcp/commitInfo.ts +61 -0
  197. package/src/mcp/crosswalk.test.ts +106 -0
  198. package/src/mcp/crosswalk.ts +339 -0
  199. package/src/mcp/dependencies.test.ts +309 -0
  200. package/src/mcp/dependencies.ts +189 -0
  201. package/src/mcp/geminiSanitizer.test.ts +287 -0
  202. package/src/mcp/geminiSanitizer.ts +207 -0
  203. package/src/mcp/git.test.ts +1083 -0
  204. package/src/mcp/git.ts +890 -0
  205. package/src/mcp/guardrails.test.ts +705 -0
  206. package/src/mcp/guardrails.ts +465 -0
  207. package/src/mcp/issue.test.ts +113 -0
  208. package/src/mcp/issue.ts +73 -0
  209. package/src/mcp/issueComments.test.ts +69 -0
  210. package/src/mcp/issueComments.ts +48 -0
  211. package/src/mcp/issueEvents.test.ts +134 -0
  212. package/src/mcp/issueEvents.ts +100 -0
  213. package/src/mcp/issueInfo.test.ts +104 -0
  214. package/src/mcp/issueInfo.ts +72 -0
  215. package/src/mcp/labels.test.ts +52 -0
  216. package/src/mcp/labels.ts +34 -0
  217. package/src/mcp/localContext.ts +28 -0
  218. package/src/mcp/localServer.test.ts +75 -0
  219. package/src/mcp/localServer.ts +131 -0
  220. package/src/mcp/moduleExtraction.test.ts +261 -0
  221. package/src/mcp/moduleExtraction.ts +313 -0
  222. package/src/mcp/moduleTests.test.ts +269 -0
  223. package/src/mcp/moduleTests.ts +421 -0
  224. package/src/mcp/modules.test.ts +640 -0
  225. package/src/mcp/modules.ts +696 -0
  226. package/src/mcp/output.test.ts +96 -0
  227. package/src/mcp/output.ts +70 -0
  228. package/src/mcp/pathSafety.test.ts +44 -0
  229. package/src/mcp/pathSafety.ts +28 -0
  230. package/src/mcp/policy.test.ts +282 -0
  231. package/src/mcp/policy.ts +199 -0
  232. package/src/mcp/pr.test.ts +387 -0
  233. package/src/mcp/pr.ts +194 -0
  234. package/src/mcp/prInfo.test.ts +96 -0
  235. package/src/mcp/prInfo.ts +91 -0
  236. package/src/mcp/providerSchema.test.ts +85 -0
  237. package/src/mcp/providerSchema.ts +175 -0
  238. package/src/mcp/review.test.ts +936 -0
  239. package/src/mcp/review.ts +923 -0
  240. package/src/mcp/reviewComments.test.ts +549 -0
  241. package/src/mcp/reviewComments.ts +896 -0
  242. package/src/mcp/roots.test.ts +175 -0
  243. package/src/mcp/roots.ts +217 -0
  244. package/src/mcp/scope.test.ts +59 -0
  245. package/src/mcp/scope.ts +65 -0
  246. package/src/mcp/security.test.ts +720 -0
  247. package/src/mcp/selectMode.test.ts +210 -0
  248. package/src/mcp/selectMode.ts +181 -0
  249. package/src/mcp/server.test.ts +292 -0
  250. package/src/mcp/server.ts +403 -0
  251. package/src/mcp/shared.ts +100 -0
  252. package/src/mcp/shell.test.ts +520 -0
  253. package/src/mcp/shell.ts +505 -0
  254. package/src/mcp/staleFix.test.ts +237 -0
  255. package/src/mcp/staleFix.ts +277 -0
  256. package/src/mcp/terraform/cost.ts +163 -0
  257. package/src/mcp/terraform/currency.test.ts +338 -0
  258. package/src/mcp/terraform/currency.ts +336 -0
  259. package/src/mcp/terraform/decisions.ts +527 -0
  260. package/src/mcp/terraform/findings.ts +333 -0
  261. package/src/mcp/terraform/plan.ts +348 -0
  262. package/src/mcp/terraform/scanners.ts +809 -0
  263. package/src/mcp/terraform/tools.test.ts +1071 -0
  264. package/src/mcp/terraform/tools.ts +908 -0
  265. package/src/mcp/terraform/types.ts +305 -0
  266. package/src/mcp/terraform.test.ts +1957 -0
  267. package/src/mcp/terraform.ts +23 -0
  268. package/src/mcp/terratest.test.ts +105 -0
  269. package/src/mcp/terratest.ts +196 -0
  270. package/src/mcp/toolFiltering.test.ts +85 -0
  271. package/src/mcp/upload.test.ts +180 -0
  272. package/src/mcp/upload.ts +112 -0
  273. package/src/models.test.ts +300 -0
  274. package/src/models.ts +708 -0
  275. package/src/modes.test.ts +107 -0
  276. package/src/modes.ts +880 -0
  277. package/src/prep/index.ts +43 -0
  278. package/src/prep/installNodeDependencies.test.ts +298 -0
  279. package/src/prep/installNodeDependencies.ts +196 -0
  280. package/src/prep/installPythonDependencies.test.ts +268 -0
  281. package/src/prep/installPythonDependencies.ts +199 -0
  282. package/src/prep/types.ts +38 -0
  283. package/src/reviewQuality.test.ts +63 -0
  284. package/src/reviewQuality.ts +134 -0
  285. package/src/runCli.test.ts +214 -0
  286. package/src/runCli.ts +282 -0
  287. package/src/skills/terraform-best-practices/SKILL.md +369 -0
  288. package/src/toolState.test.ts +45 -0
  289. package/src/toolState.ts +252 -0
  290. package/src/utils/activity.test.ts +188 -0
  291. package/src/utils/activity.ts +210 -0
  292. package/src/utils/agent.test.ts +251 -0
  293. package/src/utils/agent.ts +139 -0
  294. package/src/utils/agentHangReport.test.ts +203 -0
  295. package/src/utils/agentHangReport.ts +170 -0
  296. package/src/utils/apiFetch.test.ts +115 -0
  297. package/src/utils/apiFetch.ts +62 -0
  298. package/src/utils/apiKeys.test.ts +344 -0
  299. package/src/utils/apiKeys.ts +206 -0
  300. package/src/utils/apiUrl.test.ts +30 -0
  301. package/src/utils/apiUrl.ts +59 -0
  302. package/src/utils/assets.test.ts +153 -0
  303. package/src/utils/assets.ts +107 -0
  304. package/src/utils/billingErrors.test.ts +121 -0
  305. package/src/utils/billingErrors.ts +189 -0
  306. package/src/utils/body.test.ts +217 -0
  307. package/src/utils/body.ts +168 -0
  308. package/src/utils/buildTerramendFooter.test.ts +38 -0
  309. package/src/utils/buildTerramendFooter.ts +82 -0
  310. package/src/utils/byokFallback.test.ts +205 -0
  311. package/src/utils/byokFallback.ts +128 -0
  312. package/src/utils/claudeSubscription.test.ts +179 -0
  313. package/src/utils/claudeSubscription.ts +93 -0
  314. package/src/utils/cli.ts +31 -0
  315. package/src/utils/codexHome.test.ts +190 -0
  316. package/src/utils/codexHome.ts +191 -0
  317. package/src/utils/codexOAuth.ts +147 -0
  318. package/src/utils/codexRefreshDetect.test.ts +85 -0
  319. package/src/utils/codexRefreshDetect.ts +35 -0
  320. package/src/utils/diffCoverage.test.ts +468 -0
  321. package/src/utils/diffCoverage.ts +404 -0
  322. package/src/utils/errorReport.test.ts +135 -0
  323. package/src/utils/errorReport.ts +83 -0
  324. package/src/utils/exitHandler.ts +35 -0
  325. package/src/utils/fixDoubleEscapedString.ts +9 -0
  326. package/src/utils/ghaCore.ts +13 -0
  327. package/src/utils/gitAuth.test.ts +322 -0
  328. package/src/utils/gitAuth.ts +263 -0
  329. package/src/utils/gitAuthServer.test.ts +260 -0
  330. package/src/utils/gitAuthServer.ts +182 -0
  331. package/src/utils/github.test.ts +615 -0
  332. package/src/utils/github.ts +538 -0
  333. package/src/utils/globals.ts +9 -0
  334. package/src/utils/humanEditCapture.test.ts +100 -0
  335. package/src/utils/humanEditCapture.ts +193 -0
  336. package/src/utils/install.test.ts +768 -0
  337. package/src/utils/install.ts +492 -0
  338. package/src/utils/instructions.test.ts +240 -0
  339. package/src/utils/instructions.ts +543 -0
  340. package/src/utils/leapingComment.test.ts +51 -0
  341. package/src/utils/leapingComment.ts +18 -0
  342. package/src/utils/learnings.test.ts +87 -0
  343. package/src/utils/learnings.ts +138 -0
  344. package/src/utils/learningsTocRender.test.ts +116 -0
  345. package/src/utils/learningsTruncate.test.ts +39 -0
  346. package/src/utils/learningsTruncate.ts +42 -0
  347. package/src/utils/lifecycle.test.ts +195 -0
  348. package/src/utils/lifecycle.ts +198 -0
  349. package/src/utils/log.test.ts +402 -0
  350. package/src/utils/log.ts +432 -0
  351. package/src/utils/normalizeEnv.test.ts +91 -0
  352. package/src/utils/normalizeEnv.ts +106 -0
  353. package/src/utils/openCodeModels.ts +82 -0
  354. package/src/utils/overrides.test.ts +89 -0
  355. package/src/utils/overrides.ts +98 -0
  356. package/src/utils/packageManager.test.ts +321 -0
  357. package/src/utils/packageManager.ts +257 -0
  358. package/src/utils/patchWorkflowRunFields.test.ts +92 -0
  359. package/src/utils/patchWorkflowRunFields.ts +150 -0
  360. package/src/utils/payload.test.ts +497 -0
  361. package/src/utils/payload.ts +371 -0
  362. package/src/utils/postApiFetch.ts +51 -0
  363. package/src/utils/prSummary.test.ts +224 -0
  364. package/src/utils/prSummary.ts +147 -0
  365. package/src/utils/progressComment.ts +261 -0
  366. package/src/utils/providerErrors.test.ts +315 -0
  367. package/src/utils/providerErrors.ts +172 -0
  368. package/src/utils/rangeDiff.test.ts +236 -0
  369. package/src/utils/rangeDiff.ts +182 -0
  370. package/src/utils/remediationCommand.test.ts +163 -0
  371. package/src/utils/remediationCommand.ts +119 -0
  372. package/src/utils/retry.test.ts +153 -0
  373. package/src/utils/retry.ts +58 -0
  374. package/src/utils/reviewCleanup.ts +106 -0
  375. package/src/utils/run.ts +99 -0
  376. package/src/utils/runContext.ts +145 -0
  377. package/src/utils/runContextData.ts +58 -0
  378. package/src/utils/runErrorRenderer.test.ts +95 -0
  379. package/src/utils/runErrorRenderer.ts +259 -0
  380. package/src/utils/runFixture.ts +76 -0
  381. package/src/utils/runLifecycle.ts +237 -0
  382. package/src/utils/runStartupLog.ts +60 -0
  383. package/src/utils/secrets.test.ts +103 -0
  384. package/src/utils/secrets.ts +177 -0
  385. package/src/utils/setup.test.ts +509 -0
  386. package/src/utils/setup.ts +352 -0
  387. package/src/utils/shell.ts +103 -0
  388. package/src/utils/skills.test.ts +46 -0
  389. package/src/utils/skills.ts +67 -0
  390. package/src/utils/subprocess.test.ts +170 -0
  391. package/src/utils/subprocess.ts +438 -0
  392. package/src/utils/terraformMcp.test.ts +63 -0
  393. package/src/utils/terraformMcp.ts +83 -0
  394. package/src/utils/time.test.ts +105 -0
  395. package/src/utils/time.ts +59 -0
  396. package/src/utils/timer.test.ts +91 -0
  397. package/src/utils/timer.ts +72 -0
  398. package/src/utils/todoTracking.test.ts +223 -0
  399. package/src/utils/todoTracking.ts +167 -0
  400. package/src/utils/token.test.ts +239 -0
  401. package/src/utils/token.ts +186 -0
  402. package/src/utils/version.ts +10 -0
  403. package/src/utils/versioning.test.ts +34 -0
  404. package/src/utils/versioning.ts +44 -0
  405. package/src/utils/vertex.ts +85 -0
  406. package/src/utils/workflow.ts +25 -0
@@ -0,0 +1,199 @@
1
+ import type { RestEndpointMethodTypes } from "@octokit/rest";
2
+ import type { ToolContext } from "#app/mcp/server";
3
+ import type { CommentableLines } from "#app/toolState";
4
+ export type { CommentableLines };
5
+ /**
6
+ * detect GitHub's generic server-side 422 ("An internal error occurred,
7
+ * please try again.") that sometimes fires on `POST /pulls/{n}/reviews`.
8
+ *
9
+ * the body is stable across occurrences and distinct from every other 422
10
+ * cause we care about (anchor validation, body length, malformed suggestion
11
+ * blocks) — those all cite the specific problem. treating this as a
12
+ * transient server error unlocks bounded in-tool retry instead of surfacing
13
+ * it to the agent with the generic "likely causes (1)(2)(3)" prompt, which
14
+ * induces whack-a-mole comment dropping on content that was never the issue.
15
+ */
16
+ export declare function isTransientReviewError(err: unknown): boolean;
17
+ export declare const TRANSIENT_REVIEW_RETRY_DELAYS_MS: number[];
18
+ /**
19
+ * parse a PR file's patch to determine which line numbers on each side are
20
+ * valid anchors for inline comments. GitHub only accepts comments on lines
21
+ * inside a diff hunk: added/context lines on RIGHT, removed/context lines
22
+ * on LEFT.
23
+ */
24
+ export declare function commentableLinesForFile(patch: string | undefined): CommentableLines;
25
+ export declare function buildCommentableMap(ctx: ToolContext, pullNumber: number): Promise<Map<string, CommentableLines>>;
26
+ export type ReviewCommentInput = NonNullable<RestEndpointMethodTypes["pulls"]["createReview"]["parameters"]["comments"]>[number];
27
+ export interface DroppedComment {
28
+ path: string;
29
+ line: number;
30
+ startLine?: number | undefined;
31
+ side: "LEFT" | "RIGHT";
32
+ reason: string;
33
+ }
34
+ export declare function validateInlineComments(comments: ReviewCommentInput[], map: Map<string, CommentableLines>): {
35
+ valid: ReviewCommentInput[];
36
+ dropped: DroppedComment[];
37
+ };
38
+ export declare const MAX_DROPPED_COMMENT_LINES = 50;
39
+ /**
40
+ * reason a create_pull_request_review call should be skipped without hitting
41
+ * GitHub. returned by reviewSkipDecision; null means submit normally.
42
+ */
43
+ export type ReviewSkipDecision = {
44
+ kind: "no-issues";
45
+ reason: string;
46
+ } | {
47
+ kind: "empty-downgraded-approve";
48
+ reason: string;
49
+ };
50
+ /**
51
+ * decision returned by duplicateReviewDecision when a session has already
52
+ * submitted a review and the current call would be a duplicate.
53
+ */
54
+ export type DuplicateReviewDecision = {
55
+ kind: "already-submitted";
56
+ reviewId: number;
57
+ reason: string;
58
+ };
59
+ /**
60
+ * decide whether a second create_pull_request_review call in the same session
61
+ * is a duplicate of an earlier submission.
62
+ *
63
+ * the agent is instructed to call create_pull_request_review exactly once per
64
+ * Review-mode session (see action/modes.ts), but in practice it sometimes
65
+ * submits twice — once with substantive feedback, then again with the
66
+ * canonical "No new issues found." body when the prompt's branch logic
67
+ * re-classifies non-blocking observations. the second submission is
68
+ * always redundant: the first review is the record, and the duplicate just
69
+ * adds noise to the PR.
70
+ *
71
+ * legitimate follow-up reviews after new commits ARE allowed: the
72
+ * new-commits-mid-review path advances toolState.checkoutSha past the
73
+ * previously reviewed sha, and a subsequent checkout_pr advances it again.
74
+ * any call where checkoutSha has moved past the prior reviewedSha is a real
75
+ * follow-up and goes through. anything else — same sha, or no checkoutSha
76
+ * to compare against — is a duplicate.
77
+ */
78
+ export declare function duplicateReviewDecision(params: {
79
+ existing: {
80
+ id: number;
81
+ reviewedSha: string | undefined;
82
+ } | undefined;
83
+ currentCheckoutSha: string | undefined;
84
+ }): DuplicateReviewDecision | null;
85
+ /**
86
+ * decide whether to skip a review submission before any network call.
87
+ *
88
+ * GitHub rejects `event: "COMMENT"` reviews with no body and no inline comments
89
+ * with HTTP 422 "Unprocessable Entity". two paths produce that shape:
90
+ *
91
+ * 1. `!approved` + empty body/comments: agent's "no issues found" result.
92
+ * skipping preserves the agent's intent (nothing to post is a fine
93
+ * outcome for a review run) without a spurious 422.
94
+ * 2. `approved` + `!prApproveEnabled` + empty body/comments: the runtime
95
+ * downgrades APPROVE to COMMENT when prApproveEnabled is off, and the
96
+ * resulting empty-COMMENT is exactly the shape GitHub 422s. skipping
97
+ * here surfaces the cause (downgrade + nothing to say) instead of an
98
+ * opaque 422 the agent can't recover from.
99
+ *
100
+ * legitimate bare approvals (`approved` + `prApproveEnabled`, no body/comments)
101
+ * are never skipped — GitHub accepts empty APPROVE reviews and the approval
102
+ * stamp itself is the review's content.
103
+ */
104
+ export declare function reviewSkipDecision(params: {
105
+ approved: boolean;
106
+ body: string | null | undefined;
107
+ hasComments: boolean;
108
+ prApproveEnabled: boolean;
109
+ }): ReviewSkipDecision | null;
110
+ export declare function formatDroppedCommentsNote(dropped: DroppedComment[]): string;
111
+ export declare const CreatePullRequestReview: import("arktype/internal/variants/object.ts").ObjectType<{
112
+ pull_number: number;
113
+ body?: string;
114
+ approved?: boolean;
115
+ commit_id?: string;
116
+ comments?: {
117
+ path: string;
118
+ line: number;
119
+ side?: "LEFT" | "RIGHT";
120
+ body?: string;
121
+ suggestion?: string;
122
+ start_line?: number;
123
+ }[];
124
+ }, {}>;
125
+ export declare function CreatePullRequestReviewTool(ctx: ToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<{
126
+ pull_number: number;
127
+ body?: string;
128
+ approved?: boolean;
129
+ commit_id?: string;
130
+ comments?: {
131
+ path: string;
132
+ line: number;
133
+ side?: "LEFT" | "RIGHT";
134
+ body?: string;
135
+ suggestion?: string;
136
+ start_line?: number;
137
+ }[];
138
+ }, {
139
+ pull_number: number;
140
+ body?: string;
141
+ approved?: boolean;
142
+ commit_id?: string;
143
+ comments?: {
144
+ path: string;
145
+ line: number;
146
+ side?: "LEFT" | "RIGHT";
147
+ body?: string;
148
+ suggestion?: string;
149
+ start_line?: number;
150
+ }[];
151
+ }>>;
152
+ /**
153
+ * clear a pending review draft stranded on the PR by a prior hard-killed run
154
+ * (workflow timeout, OOM) so the next createReview can succeed.
155
+ *
156
+ * GitHub enforces one-pending-review-per-user-per-PR. if the previous process
157
+ * died between createReview(PENDING) and submitReview, the draft remains and
158
+ * the next run's createReview 422s with "already has a pending review".
159
+ * listReviews only exposes PENDING reviews to their author, so filtering on
160
+ * state === "PENDING" is already scoped to the authed token's own draft.
161
+ *
162
+ * if `originalErr` is not a pending-review 422, or no leftover is found, this
163
+ * function rethrows `originalErr` so the caller surfaces the original failure.
164
+ * delete failures with 404 (draft already gone) or 422 (draft submitted by a
165
+ * concurrent caller) are swallowed — the caller's retry will succeed in both
166
+ * cases. any other delete error is rethrown unchanged.
167
+ *
168
+ * known limitation: if two runs on the SAME PR share the authed token and
169
+ * overlap in time, the loser's createReview 422s on the winner's still-active
170
+ * draft. recovery would then delete the winner's active draft and the
171
+ * winner's submitReview would 404. this is not distinguishable from a
172
+ * genuinely-stranded draft via the review object alone (PENDING reviews
173
+ * expose no created_at timestamp, and both reviews are authored by the same
174
+ * bot user). rely on workflow-level concurrency controls (e.g. a concurrency
175
+ * key keyed to the PR number) to prevent overlap.
176
+ */
177
+ export declare function clearStrandedPendingReview(ctx: ToolContext, params: {
178
+ owner: string;
179
+ repo: string;
180
+ pull_number: number;
181
+ originalErr: unknown;
182
+ }): Promise<void>;
183
+ /**
184
+ * single-step createReview (event != PENDING) with stranded-draft recovery.
185
+ * the body path goes through createAndSubmitWithFooter which already recovers
186
+ * from a stranded PENDING draft at its own createReview call. the no-body path
187
+ * used to call createReview directly with no recovery — so a PR whose previous
188
+ * body-path run crashed between createReview(PENDING) and submitReview would
189
+ * permanently 422 any subsequent no-body review (approve-with-no-feedback or
190
+ * comments-only) until a body-path run happened to clear the draft.
191
+ */
192
+ export declare function createReviewWithStrandedRecovery(ctx: ToolContext, params: RestEndpointMethodTypes["pulls"]["createReview"]["parameters"]): Promise<Awaited<ReturnType<typeof ctx.octokit.rest.pulls.createReview>>>;
193
+ /**
194
+ * report the review node ID so the WorkflowRun is marked as "review submitted".
195
+ * exported for use in main.ts post-agent cleanup.
196
+ */
197
+ export declare function reportReviewNodeId(ctx: ToolContext, params: {
198
+ nodeId: string;
199
+ }): Promise<void>;
@@ -0,0 +1,178 @@
1
+ import type { Octokit } from "@octokit/rest";
2
+ import type { ToolContext } from "#app/mcp/server";
3
+ export declare const REVIEW_THREADS_QUERY = "\nquery ($owner: String!, $name: String!, $prNumber: Int!) {\n repository(owner: $owner, name: $name) {\n pullRequest(number: $prNumber) {\n reviewThreads(first: 100) {\n nodes {\n id\n path\n line\n startLine\n diffSide\n isResolved\n isOutdated\n comments(first: 50) {\n nodes {\n fullDatabaseId\n body\n bodyHTML\n createdAt\n diffHunk\n line\n startLine\n originalLine\n originalStartLine\n author { login }\n pullRequestReview {\n databaseId\n author { login }\n }\n reactionGroups {\n content\n reactors(first: 10) {\n totalCount\n nodes {\n ... on Actor { login }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n}\n";
4
+ export type ReviewThreadComment = {
5
+ fullDatabaseId: string | null;
6
+ body: string;
7
+ bodyHTML: string;
8
+ createdAt: string;
9
+ diffHunk: string;
10
+ line: number | null;
11
+ startLine: number | null;
12
+ originalLine: number | null;
13
+ originalStartLine: number | null;
14
+ author: {
15
+ login: string;
16
+ } | null;
17
+ pullRequestReview: {
18
+ databaseId: number | null;
19
+ author: {
20
+ login: string;
21
+ } | null;
22
+ } | null;
23
+ reactionGroups: Array<{
24
+ content: string;
25
+ reactors: {
26
+ totalCount?: number;
27
+ nodes: Array<{
28
+ login: string;
29
+ } | null> | null;
30
+ } | null;
31
+ }> | null;
32
+ };
33
+ export type ReviewThread = {
34
+ id: string;
35
+ path: string;
36
+ line: number | null;
37
+ startLine: number | null;
38
+ diffSide: "LEFT" | "RIGHT";
39
+ isResolved: boolean;
40
+ isOutdated: boolean;
41
+ comments: {
42
+ nodes: (ReviewThreadComment | null)[] | null;
43
+ } | null;
44
+ };
45
+ export type ReviewThreadsQueryResponse = {
46
+ repository: {
47
+ pullRequest: {
48
+ reviewThreads: {
49
+ nodes: (ReviewThread | null)[] | null;
50
+ } | null;
51
+ } | null;
52
+ } | null;
53
+ };
54
+ export declare function countLines(str: string): number;
55
+ export type ParsedHunk = {
56
+ header: string;
57
+ oldStart: number;
58
+ oldCount: number;
59
+ newStart: number;
60
+ newCount: number;
61
+ content: string[];
62
+ };
63
+ export declare function parseFilePatches(patch: string): ParsedHunk[];
64
+ export declare const GetReviewComments: import("arktype/internal/variants/object.ts").ObjectType<{
65
+ pull_number: number;
66
+ review_id: number;
67
+ }, {}>;
68
+ /**
69
+ * §5.7 — render 👍/👎 totals as a `reactions=` tag attribute so the agent sees
70
+ * human feedback on its findings inline with the thread (a 👎 on a terramend
71
+ * root comment is false-positive signal; see the IncrementalReview prompt).
72
+ * Only the thumbs contents — the other six reaction types carry no
73
+ * accept/reject semantics — and only when at least one is nonzero, so the
74
+ * common no-reaction case adds zero tokens.
75
+ */
76
+ export declare function formatReactionCounts(comment: ReviewThreadComment): string;
77
+ /**
78
+ * formats thread blocks into markdown with TOC and line numbers.
79
+ * extracted for testability.
80
+ */
81
+ export declare function formatReviewThreads(threadBlocks: Array<{
82
+ path: string;
83
+ lineRange: string;
84
+ content: string[];
85
+ }>, header: {
86
+ pullNumber: number;
87
+ reviewId: number;
88
+ reviewer: string;
89
+ reviewBody?: string;
90
+ }): {
91
+ toc: string;
92
+ content: string;
93
+ };
94
+ /**
95
+ * builds thread blocks from review threads and file patches.
96
+ * extracted for testability.
97
+ */
98
+ export declare function buildThreadBlocks(threads: ReviewThread[], filePatchMap: Map<string, ParsedHunk[]>, reviewId: number): {
99
+ path: string;
100
+ lineRange: string;
101
+ content: string[];
102
+ }[];
103
+ interface GetReviewDataInput {
104
+ octokit: Octokit;
105
+ owner: string;
106
+ name: string;
107
+ pullNumber: number;
108
+ reviewId: number;
109
+ approvedBy?: string | undefined;
110
+ tmpdir: string;
111
+ githubToken: string;
112
+ }
113
+ export interface FormatReviewDataInput {
114
+ review: ReviewResponse;
115
+ threads: ReviewThread[];
116
+ prFiles: ReviewPrFile[];
117
+ pullNumber: number;
118
+ reviewId: number;
119
+ }
120
+ export type ReviewResponse = {
121
+ body: string | null | undefined;
122
+ user: {
123
+ login: string;
124
+ } | null | undefined;
125
+ };
126
+ export type ReviewPrFile = {
127
+ filename: string;
128
+ patch?: string | undefined;
129
+ };
130
+ export declare function formatReviewData(input: FormatReviewDataInput): {
131
+ threadBlocks: Array<{
132
+ path: string;
133
+ lineRange: string;
134
+ content: string[];
135
+ }>;
136
+ reviewer: string;
137
+ formatted: {
138
+ toc: string;
139
+ content: string;
140
+ };
141
+ } | undefined;
142
+ export declare function getReviewData(input: GetReviewDataInput): Promise<{
143
+ threadBlocks: Array<{
144
+ path: string;
145
+ lineRange: string;
146
+ content: string[];
147
+ }>;
148
+ reviewer: string;
149
+ formatted: {
150
+ toc: string;
151
+ content: string;
152
+ };
153
+ truncated: boolean;
154
+ } | undefined>;
155
+ export declare function GetReviewCommentsTool(ctx: ToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<{
156
+ pull_number: number;
157
+ review_id: number;
158
+ }, {
159
+ pull_number: number;
160
+ review_id: number;
161
+ }>>;
162
+ export declare const ListPullRequestReviews: import("arktype/internal/variants/object.ts").ObjectType<{
163
+ pull_number: number;
164
+ }, {}>;
165
+ export declare function ListPullRequestReviewsTool(ctx: ToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<{
166
+ pull_number: number;
167
+ }, {
168
+ pull_number: number;
169
+ }>>;
170
+ export declare const ResolveReviewThread: import("arktype/internal/variants/object.ts").ObjectType<{
171
+ thread_id: string;
172
+ }, {}>;
173
+ export declare function ResolveReviewThreadTool(ctx: ToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<{
174
+ thread_id: string;
175
+ }, {
176
+ thread_id: string;
177
+ }>>;
178
+ export {};
@@ -0,0 +1,58 @@
1
+ import type { LocalToolContext } from "#app/mcp/localContext";
2
+ /**
3
+ * Multi-root awareness. A repo can hold SEVERAL Terraform root modules — the
4
+ * dirs you'd run `terraform init/plan/apply` in — not one. hepcare, for example,
5
+ * has `terraform/` AND `terraform/core/`, plus a child module under
6
+ * `terraform/modules/`. The scanners run recursively, but plan/validate assume a
7
+ * single `cwd`; this surfaces the roots so a run can act per-root.
8
+ *
9
+ * Heuristic (validated against real repos): a ROOT is a dir whose `*.tf`
10
+ * declares a PROVIDER CONFIGURATION (`provider "<name>" { … }`) or a BACKEND
11
+ * (`backend "<type>" { … }`). A CHILD MODULE never configures a provider or a
12
+ * backend (it only declares `required_providers`), so this cleanly separates the
13
+ * two. Pure parsing + a single fs walk; no subprocess.
14
+ */
15
+ export interface TerraformRoot {
16
+ /** repo-relative dir (POSIX); "" for the top-level. */
17
+ dir: string;
18
+ hasBackend: boolean;
19
+ hasProviderConfig: boolean;
20
+ tfFileCount: number;
21
+ }
22
+ /** detect whether some concatenated HCL marks a root module. */
23
+ export declare function isRootModuleHcl(hcl: string): {
24
+ hasBackend: boolean;
25
+ hasProviderConfig: boolean;
26
+ };
27
+ /**
28
+ * Discover the Terraform root modules under `cwd`. Walks `*.tf` recursively
29
+ * (skipping cache/VCS dirs via walkTfFiles), groups by directory, and keeps the
30
+ * dirs that configure a provider or a backend. Sorted by dir. An empty result
31
+ * means no obvious root was found — the caller falls back to scanning `cwd`
32
+ * itself as a single root.
33
+ */
34
+ export declare function discoverTerraformRoots(cwd: string): TerraformRoot[];
35
+ export interface EnvironmentTwinGroup {
36
+ /** the shared path shape with the env/region segment replaced by `{env}`. */
37
+ pattern: string;
38
+ /** the matched twins: each a dir + the environment/region token it carries. */
39
+ members: {
40
+ dir: string;
41
+ environment: string;
42
+ }[];
43
+ }
44
+ /**
45
+ * Detect environment/region TWINS among a set of repo-relative paths (root dirs
46
+ * and/or `*.tfvars` files): parallel stacks that differ only by an environment
47
+ * (`dev`/`staging`/`prod`/…) or region (`eu-west-2`) segment. A fix applied to
48
+ * one should usually be offered for its twins too (§22 — backport / fan-out).
49
+ *
50
+ * For each path, finds the LAST segment that is an env token or a region (a
51
+ * `<env>.tfvars` file counts via its basename), replaces it with `{env}` to form
52
+ * a pattern, and groups by that pattern. Only groups with ≥2 DISTINCT
53
+ * environments are returned (a single match isn't a twin set). Pure +
54
+ * deterministic (sorted).
55
+ */
56
+ export declare function detectEnvironmentTwins(paths: string[]): EnvironmentTwinGroup[];
57
+ export declare const TerraformRootsParams: import("arktype/internal/variants/object.ts").ObjectType<object, {}>;
58
+ export declare function TerraformRootsTool(ctx: LocalToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<object, object>>;
@@ -0,0 +1,15 @@
1
+ import type { ToolContext } from "#app/mcp/server";
2
+ /**
3
+ * Record a PR/issue this run created so later body edits / comments / reviews on
4
+ * it pass {@link assertTargetInScope}. Call after a successful
5
+ * `create_pull_request` / `create_issue`.
6
+ */
7
+ export declare function recordCreatedTarget(ctx: ToolContext, target: number): void;
8
+ /** true when `target` is the run's triggering issue/PR or one it created. */
9
+ export declare function isTargetInScope(ctx: ToolContext, target: number): boolean;
10
+ /**
11
+ * Throw if `target` is neither the run's triggering issue/PR nor one it created.
12
+ * `action` is a short verb phrase used in the error (e.g. "comment on",
13
+ * "submit a review on", "add labels to").
14
+ */
15
+ export declare function assertTargetInScope(ctx: ToolContext, target: number, action: string): void;
@@ -0,0 +1,18 @@
1
+ import type { ToolContext } from "#app/mcp/server";
2
+ export declare const SelectModeParams: import("arktype/internal/variants/object.ts").ObjectType<{
3
+ mode: string;
4
+ issue_number?: number;
5
+ }, {}>;
6
+ export type PlanCommentResponsePayload = {
7
+ error: string;
8
+ } | {
9
+ commentId: number;
10
+ body: string;
11
+ };
12
+ export declare function SelectModeTool(ctx: ToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<{
13
+ mode: string;
14
+ issue_number?: number;
15
+ }, {
16
+ mode: string;
17
+ issue_number?: number;
18
+ }>>;
@@ -0,0 +1,48 @@
1
+ import "#app/mcp/arkConfig";
2
+ import { type AgentId } from "#app/external";
3
+ import type { Mode } from "#app/modes";
4
+ import type { ToolState } from "#app/toolState";
5
+ import type { OctokitWithPlugins } from "#app/utils/github";
6
+ import type { ResolvedPayload } from "#app/utils/payload";
7
+ import type { AccountPlan } from "#app/utils/runContext";
8
+ import type { RunContextData } from "#app/utils/runContextData";
9
+ export interface ToolContext {
10
+ agentId: AgentId;
11
+ repo: RunContextData["repo"];
12
+ payload: ResolvedPayload;
13
+ octokit: OctokitWithPlugins;
14
+ githubInstallationToken: string;
15
+ gitToken: string;
16
+ apiToken: string;
17
+ modes: Mode[];
18
+ postCheckoutScript: string | null;
19
+ prepushScript: string | null;
20
+ prApproveEnabled: boolean;
21
+ modeInstructions: Record<string, string>;
22
+ toolState: ToolState;
23
+ runId: number | undefined;
24
+ mcpServerUrl: string;
25
+ mcpServerToken: string;
26
+ tmpdir: string;
27
+ oss: boolean;
28
+ plan: AccountPlan;
29
+ resolvedModel: string | undefined;
30
+ }
31
+ type JsonSchema = Record<string, unknown>;
32
+ type McpHttpServerOptions = {
33
+ outputSchema?: JsonSchema | undefined;
34
+ };
35
+ /**
36
+ * Start the MCP HTTP server.
37
+ *
38
+ * The returned disposer is idempotent — safe to call multiple times.
39
+ * Callers (e.g. the inner activity-timeout handler in main.ts) may need to
40
+ * stop the server before the `await using` block exits; a subsequent
41
+ * automatic dispose is then a no-op.
42
+ */
43
+ export declare function startMcpHttpServer(ctx: ToolContext, options?: McpHttpServerOptions): Promise<{
44
+ url: string;
45
+ token: string;
46
+ [Symbol.asyncDispose]: () => Promise<void>;
47
+ }>;
48
+ export {};
@@ -0,0 +1,47 @@
1
+ import type { StandardSchemaV1 } from "@standard-schema/spec";
2
+ import type { FastMCP, Tool } from "fastmcp";
3
+ import type { ToolContext } from "#app/mcp/server";
4
+ export declare const tool: <const params>(toolDef: Tool<any, StandardSchemaV1<params>>) => Tool<any, StandardSchemaV1<params>>;
5
+ export interface ToolResult {
6
+ content: {
7
+ type: "text";
8
+ text: string;
9
+ }[];
10
+ isError?: boolean;
11
+ }
12
+ /**
13
+ * Structured tool-outcome envelope (§3.5 "Structured tool errors"). Every tool
14
+ * that can be unavailable, skipped, or degrade green returns the SAME shape so a
15
+ * caller (the agent, or a downstream parser) can branch deterministically:
16
+ * - success: `{ ok: true, … }`
17
+ * - skip / unavailable / soft failure: `{ ok: false, code, detail }`
18
+ * where `code` is a stable machine token (snake_case) and `detail` a human
19
+ * sentence. The newer tools (terraform_roots / terraform_module_interface /
20
+ * terraform_provider_schema / policy_check) emit this natively; the older
21
+ * degrade-green tools historically returned `{ ran|found: false,
22
+ * skipped_reason|reason }`. Those keep their legacy aliases ALONGSIDE the new
23
+ * fields (the call site spreads `toolSkip(...)` into its existing object) so
24
+ * prompt + test contracts keep working while the surface converges — additive,
25
+ * never breaking.
26
+ */
27
+ export type ToolOk<T extends Record<string, any>> = T & {
28
+ ok: true;
29
+ };
30
+ /** wrap a success payload with `ok: true`. */
31
+ export declare const toolOk: <T extends Record<string, any>>(data: T) => ToolOk<T>;
32
+ /** the structured skip/unavailable envelope: `{ ok: false, code, detail }`. */
33
+ export declare const toolSkip: (code: string, detail: string) => {
34
+ ok: false;
35
+ code: string;
36
+ detail: string;
37
+ };
38
+ export declare const handleToolSuccess: (data: Record<string, any> | string) => ToolResult;
39
+ export declare const handleToolError: (error: unknown) => ToolResult;
40
+ /**
41
+ * Helper to wrap a tool execute function with error handling.
42
+ * Captures ctx in closure so tools don't need to handle try/catch.
43
+ * @param fn - the function to execute
44
+ * @param toolName - optional tool name for error logging
45
+ */
46
+ export declare const execute: <T, R extends Record<string, any> | string>(fn: (params: T) => Promise<R>, toolName?: string) => (params: T) => Promise<ToolResult>;
47
+ export declare const addTools: (ctx: ToolContext, server: FastMCP<any>, tools: Tool<any, any>[]) => FastMCP<any>;
@@ -0,0 +1,37 @@
1
+ import type { ToolContext } from "#app/mcp/server";
2
+ export declare const ShellParams: import("arktype/internal/variants/object.ts").ObjectType<{
3
+ command: string;
4
+ description: string;
5
+ timeout?: number;
6
+ working_directory?: string;
7
+ background?: boolean;
8
+ }, {}>;
9
+ export type SandboxMethod = "unshare" | "sudo-unshare" | "none";
10
+ /** get the current sandbox method (for testing/diagnostics) */
11
+ export declare function getSandboxMethod(): SandboxMethod;
12
+ /** chars of shell output kept inline in the agent reply. anything past this
13
+ * blows the agent's context budget on commands that dump big logs (test
14
+ * runners, build tools, grep on large trees), so the overflow is spilled
15
+ * to a tempfile the agent can re-read selectively (cat/tail/grep). */
16
+ export declare const MAX_OUTPUT_CHARS = 5000;
17
+ export declare function ShellTool(ctx: ToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<{
18
+ command: string;
19
+ description: string;
20
+ timeout?: number;
21
+ working_directory?: string;
22
+ background?: boolean;
23
+ }, {
24
+ command: string;
25
+ description: string;
26
+ timeout?: number;
27
+ working_directory?: string;
28
+ background?: boolean;
29
+ }>>;
30
+ export declare const KillBackgroundParams: import("arktype/internal/variants/object.ts").ObjectType<{
31
+ handle: string;
32
+ }, {}>;
33
+ export declare function KillBackgroundTool(ctx: ToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<{
34
+ handle: string;
35
+ }, {
36
+ handle: string;
37
+ }>>;
@@ -0,0 +1,51 @@
1
+ import type { ToolContext } from "#app/mcp/server";
2
+ /** true when `branch` is a Terramend remediation/generation branch. */
3
+ export declare function isRemediationBranch(branch: string): boolean;
4
+ /** the `<group-id>` of a `remediate/<group-id>` branch (the scan group id that
5
+ * keys the fix), or null for a generation branch / non-remediation branch. */
6
+ export declare function groupIdFromBranch(branch: string): string | null;
7
+ /** true when a commit-author login is Terramend's bot (so a commit by it is NOT
8
+ * a human edit). A null/absent login is treated as non-human: Terramend pushes
9
+ * with a git identity that often doesn't map to a GitHub user, so requiring a
10
+ * positive bot match would make every PR look human-touched and never refresh. */
11
+ export declare function isBotActor(login: string | null | undefined): boolean;
12
+ export type StaleFixStatus = "current" | "stale" | "human_touched";
13
+ export type StaleFixAction = "skip" | "refresh" | "escalate";
14
+ export interface StaleFixAssessment {
15
+ status: StaleFixStatus;
16
+ action: StaleFixAction;
17
+ reason: string;
18
+ }
19
+ /**
20
+ * Decide what a refresh sweep should do with one open remediation PR, from git
21
+ * facts alone. Pure.
22
+ * - a branch carrying NON-bot commits is `human_touched` → `escalate` (never
23
+ * force-overwrite a human's work; leave it for review).
24
+ * - a branch whose base has NOT advanced is `current` → `skip` (the fix is still
25
+ * derived against the live base).
26
+ * - otherwise the base moved → `stale` → `refresh`: re-derive the fix on the
27
+ * current base, then close it if the concern is already resolved or update it.
28
+ */
29
+ export declare function assessStaleFix(input: {
30
+ baseBehindBy: number;
31
+ hasNonBotCommits: boolean;
32
+ }): StaleFixAssessment;
33
+ export declare const ListRemediationPrsParams: import("arktype/internal/variants/object.ts").ObjectType<{
34
+ limit?: number;
35
+ }, {}>;
36
+ export declare function ListRemediationPrsTool(ctx: ToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<{
37
+ limit?: number;
38
+ }, {
39
+ limit?: number;
40
+ }>>;
41
+ export declare const ClosePullRequest: import("arktype/internal/variants/object.ts").ObjectType<{
42
+ pull_number: number;
43
+ comment?: string;
44
+ }, {}>;
45
+ export declare function ClosePullRequestTool(ctx: ToolContext): import("fastmcp").Tool<any, import("@standard-schema/spec").StandardSchemaV1<{
46
+ pull_number: number;
47
+ comment?: string;
48
+ }, {
49
+ pull_number: number;
50
+ comment?: string;
51
+ }>>;