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.
- package/LICENSE +661 -0
- package/README.md +145 -0
- package/dist/agents/claude.d.ts +73 -0
- package/dist/agents/claudePretoolGate.d.ts +99 -0
- package/dist/agents/gateServer.d.ts +7 -0
- package/dist/agents/index.d.ts +6 -0
- package/dist/agents/nativeFsDenies.d.ts +28 -0
- package/dist/agents/opencode.d.ts +231 -0
- package/dist/agents/opencodePlugin.d.ts +85 -0
- package/dist/agents/opencodeShared.d.ts +40 -0
- package/dist/agents/postRun.d.ts +132 -0
- package/dist/agents/reviewer.d.ts +38 -0
- package/dist/agents/sessionLabeler.d.ts +97 -0
- package/dist/agents/shared.d.ts +189 -0
- package/dist/agents/subagentModels.d.ts +19 -0
- package/dist/agents/subagentToolGates.d.ts +55 -0
- package/dist/cli.mjs +197426 -0
- package/dist/external.d.ts +227 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +196783 -0
- package/dist/internal/index.d.ts +18 -0
- package/dist/internal.js +1714 -0
- package/dist/lifecycle.d.ts +2 -0
- package/dist/main.d.ts +8 -0
- package/dist/mcp/arkConfig.d.ts +1 -0
- package/dist/mcp/checkSuite.d.ts +25 -0
- package/dist/mcp/checkout.d.ts +77 -0
- package/dist/mcp/comment.d.ts +119 -0
- package/dist/mcp/commitInfo.d.ts +9 -0
- package/dist/mcp/crosswalk.d.ts +105 -0
- package/dist/mcp/dependencies.d.ts +8 -0
- package/dist/mcp/geminiSanitizer.d.ts +28 -0
- package/dist/mcp/git.d.ts +46 -0
- package/dist/mcp/guardrails.d.ts +104 -0
- package/dist/mcp/issue.d.ts +18 -0
- package/dist/mcp/issueComments.d.ts +9 -0
- package/dist/mcp/issueEvents.d.ts +9 -0
- package/dist/mcp/issueInfo.d.ts +9 -0
- package/dist/mcp/labels.d.ts +12 -0
- package/dist/mcp/localContext.d.ts +19 -0
- package/dist/mcp/moduleExtraction.d.ts +71 -0
- package/dist/mcp/moduleTests.d.ts +104 -0
- package/dist/mcp/modules.d.ts +179 -0
- package/dist/mcp/output.d.ts +12 -0
- package/dist/mcp/pathSafety.d.ts +14 -0
- package/dist/mcp/policy.d.ts +48 -0
- package/dist/mcp/pr.d.ts +49 -0
- package/dist/mcp/prInfo.d.ts +9 -0
- package/dist/mcp/providerSchema.d.ts +50 -0
- package/dist/mcp/review.d.ts +199 -0
- package/dist/mcp/reviewComments.d.ts +178 -0
- package/dist/mcp/roots.d.ts +58 -0
- package/dist/mcp/scope.d.ts +15 -0
- package/dist/mcp/selectMode.d.ts +18 -0
- package/dist/mcp/server.d.ts +48 -0
- package/dist/mcp/shared.d.ts +47 -0
- package/dist/mcp/shell.d.ts +37 -0
- package/dist/mcp/staleFix.d.ts +51 -0
- package/dist/mcp/terraform/cost.d.ts +55 -0
- package/dist/mcp/terraform/currency.d.ts +94 -0
- package/dist/mcp/terraform/decisions.d.ts +178 -0
- package/dist/mcp/terraform/findings.d.ts +75 -0
- package/dist/mcp/terraform/plan.d.ts +157 -0
- package/dist/mcp/terraform/scanners.d.ts +131 -0
- package/dist/mcp/terraform/tools.d.ts +63 -0
- package/dist/mcp/terraform/types.d.ts +172 -0
- package/dist/mcp/terraform.d.ts +22 -0
- package/dist/mcp/terratest.d.ts +83 -0
- package/dist/mcp/upload.d.ts +6 -0
- package/dist/models.d.ts +171 -0
- package/dist/modes.d.ts +26 -0
- package/dist/prep/index.d.ts +7 -0
- package/dist/prep/installNodeDependencies.d.ts +2 -0
- package/dist/prep/installPythonDependencies.d.ts +2 -0
- package/dist/prep/types.d.ts +31 -0
- package/dist/reviewQuality.d.ts +64 -0
- package/dist/skills/terraform-best-practices/SKILL.md +369 -0
- package/dist/toolState.d.ts +135 -0
- package/dist/utils/activity.d.ts +40 -0
- package/dist/utils/agent.d.ts +20 -0
- package/dist/utils/agentHangReport.d.ts +38 -0
- package/dist/utils/apiFetch.d.ts +19 -0
- package/dist/utils/apiKeys.d.ts +41 -0
- package/dist/utils/apiUrl.d.ts +20 -0
- package/dist/utils/assets.d.ts +8 -0
- package/dist/utils/billingErrors.d.ts +85 -0
- package/dist/utils/body.d.ts +34 -0
- package/dist/utils/buildTerramendFooter.d.ts +25 -0
- package/dist/utils/byokFallback.d.ts +85 -0
- package/dist/utils/claudeSubscription.d.ts +30 -0
- package/dist/utils/cli.d.ts +10 -0
- package/dist/utils/codexHome.d.ts +29 -0
- package/dist/utils/codexOAuth.d.ts +60 -0
- package/dist/utils/diffCoverage.d.ts +63 -0
- package/dist/utils/errorReport.d.ts +17 -0
- package/dist/utils/exitHandler.d.ts +8 -0
- package/dist/utils/fixDoubleEscapedString.d.ts +1 -0
- package/dist/utils/gitAuth.d.ts +84 -0
- package/dist/utils/gitAuthServer.d.ts +24 -0
- package/dist/utils/github.d.ts +78 -0
- package/dist/utils/globals.d.ts +3 -0
- package/dist/utils/install.d.ts +60 -0
- package/dist/utils/instructions.d.ts +48 -0
- package/dist/utils/leapingComment.d.ts +11 -0
- package/dist/utils/learnings.d.ts +62 -0
- package/dist/utils/learningsTruncate.d.ts +25 -0
- package/dist/utils/lifecycle.d.ts +57 -0
- package/dist/utils/log.d.ts +111 -0
- package/dist/utils/normalizeEnv.d.ts +30 -0
- package/dist/utils/openCodeModels.d.ts +11 -0
- package/dist/utils/overrides.d.ts +40 -0
- package/dist/utils/packageManager.d.ts +49 -0
- package/dist/utils/patchWorkflowRunFields.d.ts +29 -0
- package/dist/utils/payload.d.ts +105 -0
- package/dist/utils/prSummary.d.ts +61 -0
- package/dist/utils/progressComment.d.ts +146 -0
- package/dist/utils/providerErrors.d.ts +31 -0
- package/dist/utils/rangeDiff.d.ts +51 -0
- package/dist/utils/remediationCommand.d.ts +55 -0
- package/dist/utils/retry.d.ts +13 -0
- package/dist/utils/reviewCleanup.d.ts +14 -0
- package/dist/utils/run.d.ts +9 -0
- package/dist/utils/runContext.d.ts +60 -0
- package/dist/utils/runContextData.d.ts +23 -0
- package/dist/utils/runErrorRenderer.d.ts +64 -0
- package/dist/utils/runLifecycle.d.ts +86 -0
- package/dist/utils/runStartupLog.d.ts +15 -0
- package/dist/utils/secrets.d.ts +22 -0
- package/dist/utils/setup.d.ts +90 -0
- package/dist/utils/shell.d.ts +32 -0
- package/dist/utils/skills.d.ts +10 -0
- package/dist/utils/subprocess.d.ts +80 -0
- package/dist/utils/terraformMcp.d.ts +42 -0
- package/dist/utils/time.d.ts +15 -0
- package/dist/utils/timer.d.ts +23 -0
- package/dist/utils/todoTracking.d.ts +16 -0
- package/dist/utils/token.d.ts +39 -0
- package/dist/utils/version.d.ts +2 -0
- package/dist/utils/versioning.d.ts +7 -0
- package/dist/utils/vertex.d.ts +16 -0
- package/dist/utils/workflow.d.ts +13 -0
- package/package.json +119 -0
- package/src/agents/claude.test.ts +1016 -0
- package/src/agents/claude.ts +1246 -0
- package/src/agents/claudePretoolGate.test.ts +28 -0
- package/src/agents/claudePretoolGate.ts +173 -0
- package/src/agents/gateServer.test.ts +204 -0
- package/src/agents/gateServer.ts +124 -0
- package/src/agents/index.ts +10 -0
- package/src/agents/nativeFsDenies.ts +82 -0
- package/src/agents/opencode.test.ts +1440 -0
- package/src/agents/opencode.ts +1312 -0
- package/src/agents/opencodePlugin.ts +222 -0
- package/src/agents/opencodeShared.test.ts +34 -0
- package/src/agents/opencodeShared.ts +121 -0
- package/src/agents/postRun.test.ts +549 -0
- package/src/agents/postRun.ts +535 -0
- package/src/agents/reviewer.ts +104 -0
- package/src/agents/sessionLabeler.test.ts +247 -0
- package/src/agents/sessionLabeler.ts +178 -0
- package/src/agents/shared.test.ts +76 -0
- package/src/agents/shared.ts +292 -0
- package/src/agents/subagentModels.test.ts +113 -0
- package/src/agents/subagentModels.ts +40 -0
- package/src/agents/subagentRegistration.test.ts +41 -0
- package/src/agents/subagentToolGates.ts +114 -0
- package/src/cli.test.ts +129 -0
- package/src/cli.ts +105 -0
- package/src/commands/gha.test.ts +192 -0
- package/src/commands/gha.ts +188 -0
- package/src/commands/mcp.ts +122 -0
- package/src/config.ts +1 -0
- package/src/entry.ts +7 -0
- package/src/entryPost.stdlibOnly.test.ts +109 -0
- package/src/entryPost.ts +99 -0
- package/src/external.test.ts +16 -0
- package/src/external.ts +302 -0
- package/src/index.ts +11 -0
- package/src/internal/index.ts +71 -0
- package/src/lifecycle.ts +2 -0
- package/src/main.test.ts +873 -0
- package/src/main.ts +712 -0
- package/src/mcp/__fixtures__/terramend-scratch-pr-49-review-3485940013.json +110 -0
- package/src/mcp/__fixtures__/terramend-scratch-pr-64-review-3531000326.json +14 -0
- package/src/mcp/__fixtures__/terramend-test-repo-pr-1.diff.json +67 -0
- package/src/mcp/__snapshots__/checkout.test.ts.snap +109 -0
- package/src/mcp/__snapshots__/reviewComments.test.ts.snap +71 -0
- package/src/mcp/arkConfig.ts +7 -0
- package/src/mcp/checkSuite.test.ts +245 -0
- package/src/mcp/checkSuite.ts +255 -0
- package/src/mcp/checkout.test.ts +752 -0
- package/src/mcp/checkout.ts +886 -0
- package/src/mcp/comment.test.ts +772 -0
- package/src/mcp/comment.ts +582 -0
- package/src/mcp/commitInfo.test.ts +127 -0
- package/src/mcp/commitInfo.ts +61 -0
- package/src/mcp/crosswalk.test.ts +106 -0
- package/src/mcp/crosswalk.ts +339 -0
- package/src/mcp/dependencies.test.ts +309 -0
- package/src/mcp/dependencies.ts +189 -0
- package/src/mcp/geminiSanitizer.test.ts +287 -0
- package/src/mcp/geminiSanitizer.ts +207 -0
- package/src/mcp/git.test.ts +1083 -0
- package/src/mcp/git.ts +890 -0
- package/src/mcp/guardrails.test.ts +705 -0
- package/src/mcp/guardrails.ts +465 -0
- package/src/mcp/issue.test.ts +113 -0
- package/src/mcp/issue.ts +73 -0
- package/src/mcp/issueComments.test.ts +69 -0
- package/src/mcp/issueComments.ts +48 -0
- package/src/mcp/issueEvents.test.ts +134 -0
- package/src/mcp/issueEvents.ts +100 -0
- package/src/mcp/issueInfo.test.ts +104 -0
- package/src/mcp/issueInfo.ts +72 -0
- package/src/mcp/labels.test.ts +52 -0
- package/src/mcp/labels.ts +34 -0
- package/src/mcp/localContext.ts +28 -0
- package/src/mcp/localServer.test.ts +75 -0
- package/src/mcp/localServer.ts +131 -0
- package/src/mcp/moduleExtraction.test.ts +261 -0
- package/src/mcp/moduleExtraction.ts +313 -0
- package/src/mcp/moduleTests.test.ts +269 -0
- package/src/mcp/moduleTests.ts +421 -0
- package/src/mcp/modules.test.ts +640 -0
- package/src/mcp/modules.ts +696 -0
- package/src/mcp/output.test.ts +96 -0
- package/src/mcp/output.ts +70 -0
- package/src/mcp/pathSafety.test.ts +44 -0
- package/src/mcp/pathSafety.ts +28 -0
- package/src/mcp/policy.test.ts +282 -0
- package/src/mcp/policy.ts +199 -0
- package/src/mcp/pr.test.ts +387 -0
- package/src/mcp/pr.ts +194 -0
- package/src/mcp/prInfo.test.ts +96 -0
- package/src/mcp/prInfo.ts +91 -0
- package/src/mcp/providerSchema.test.ts +85 -0
- package/src/mcp/providerSchema.ts +175 -0
- package/src/mcp/review.test.ts +936 -0
- package/src/mcp/review.ts +923 -0
- package/src/mcp/reviewComments.test.ts +549 -0
- package/src/mcp/reviewComments.ts +896 -0
- package/src/mcp/roots.test.ts +175 -0
- package/src/mcp/roots.ts +217 -0
- package/src/mcp/scope.test.ts +59 -0
- package/src/mcp/scope.ts +65 -0
- package/src/mcp/security.test.ts +720 -0
- package/src/mcp/selectMode.test.ts +210 -0
- package/src/mcp/selectMode.ts +181 -0
- package/src/mcp/server.test.ts +292 -0
- package/src/mcp/server.ts +403 -0
- package/src/mcp/shared.ts +100 -0
- package/src/mcp/shell.test.ts +520 -0
- package/src/mcp/shell.ts +505 -0
- package/src/mcp/staleFix.test.ts +237 -0
- package/src/mcp/staleFix.ts +277 -0
- package/src/mcp/terraform/cost.ts +163 -0
- package/src/mcp/terraform/currency.test.ts +338 -0
- package/src/mcp/terraform/currency.ts +336 -0
- package/src/mcp/terraform/decisions.ts +527 -0
- package/src/mcp/terraform/findings.ts +333 -0
- package/src/mcp/terraform/plan.ts +348 -0
- package/src/mcp/terraform/scanners.ts +809 -0
- package/src/mcp/terraform/tools.test.ts +1071 -0
- package/src/mcp/terraform/tools.ts +908 -0
- package/src/mcp/terraform/types.ts +305 -0
- package/src/mcp/terraform.test.ts +1957 -0
- package/src/mcp/terraform.ts +23 -0
- package/src/mcp/terratest.test.ts +105 -0
- package/src/mcp/terratest.ts +196 -0
- package/src/mcp/toolFiltering.test.ts +85 -0
- package/src/mcp/upload.test.ts +180 -0
- package/src/mcp/upload.ts +112 -0
- package/src/models.test.ts +300 -0
- package/src/models.ts +708 -0
- package/src/modes.test.ts +107 -0
- package/src/modes.ts +880 -0
- package/src/prep/index.ts +43 -0
- package/src/prep/installNodeDependencies.test.ts +298 -0
- package/src/prep/installNodeDependencies.ts +196 -0
- package/src/prep/installPythonDependencies.test.ts +268 -0
- package/src/prep/installPythonDependencies.ts +199 -0
- package/src/prep/types.ts +38 -0
- package/src/reviewQuality.test.ts +63 -0
- package/src/reviewQuality.ts +134 -0
- package/src/runCli.test.ts +214 -0
- package/src/runCli.ts +282 -0
- package/src/skills/terraform-best-practices/SKILL.md +369 -0
- package/src/toolState.test.ts +45 -0
- package/src/toolState.ts +252 -0
- package/src/utils/activity.test.ts +188 -0
- package/src/utils/activity.ts +210 -0
- package/src/utils/agent.test.ts +251 -0
- package/src/utils/agent.ts +139 -0
- package/src/utils/agentHangReport.test.ts +203 -0
- package/src/utils/agentHangReport.ts +170 -0
- package/src/utils/apiFetch.test.ts +115 -0
- package/src/utils/apiFetch.ts +62 -0
- package/src/utils/apiKeys.test.ts +344 -0
- package/src/utils/apiKeys.ts +206 -0
- package/src/utils/apiUrl.test.ts +30 -0
- package/src/utils/apiUrl.ts +59 -0
- package/src/utils/assets.test.ts +153 -0
- package/src/utils/assets.ts +107 -0
- package/src/utils/billingErrors.test.ts +121 -0
- package/src/utils/billingErrors.ts +189 -0
- package/src/utils/body.test.ts +217 -0
- package/src/utils/body.ts +168 -0
- package/src/utils/buildTerramendFooter.test.ts +38 -0
- package/src/utils/buildTerramendFooter.ts +82 -0
- package/src/utils/byokFallback.test.ts +205 -0
- package/src/utils/byokFallback.ts +128 -0
- package/src/utils/claudeSubscription.test.ts +179 -0
- package/src/utils/claudeSubscription.ts +93 -0
- package/src/utils/cli.ts +31 -0
- package/src/utils/codexHome.test.ts +190 -0
- package/src/utils/codexHome.ts +191 -0
- package/src/utils/codexOAuth.ts +147 -0
- package/src/utils/codexRefreshDetect.test.ts +85 -0
- package/src/utils/codexRefreshDetect.ts +35 -0
- package/src/utils/diffCoverage.test.ts +468 -0
- package/src/utils/diffCoverage.ts +404 -0
- package/src/utils/errorReport.test.ts +135 -0
- package/src/utils/errorReport.ts +83 -0
- package/src/utils/exitHandler.ts +35 -0
- package/src/utils/fixDoubleEscapedString.ts +9 -0
- package/src/utils/ghaCore.ts +13 -0
- package/src/utils/gitAuth.test.ts +322 -0
- package/src/utils/gitAuth.ts +263 -0
- package/src/utils/gitAuthServer.test.ts +260 -0
- package/src/utils/gitAuthServer.ts +182 -0
- package/src/utils/github.test.ts +615 -0
- package/src/utils/github.ts +538 -0
- package/src/utils/globals.ts +9 -0
- package/src/utils/humanEditCapture.test.ts +100 -0
- package/src/utils/humanEditCapture.ts +193 -0
- package/src/utils/install.test.ts +768 -0
- package/src/utils/install.ts +492 -0
- package/src/utils/instructions.test.ts +240 -0
- package/src/utils/instructions.ts +543 -0
- package/src/utils/leapingComment.test.ts +51 -0
- package/src/utils/leapingComment.ts +18 -0
- package/src/utils/learnings.test.ts +87 -0
- package/src/utils/learnings.ts +138 -0
- package/src/utils/learningsTocRender.test.ts +116 -0
- package/src/utils/learningsTruncate.test.ts +39 -0
- package/src/utils/learningsTruncate.ts +42 -0
- package/src/utils/lifecycle.test.ts +195 -0
- package/src/utils/lifecycle.ts +198 -0
- package/src/utils/log.test.ts +402 -0
- package/src/utils/log.ts +432 -0
- package/src/utils/normalizeEnv.test.ts +91 -0
- package/src/utils/normalizeEnv.ts +106 -0
- package/src/utils/openCodeModels.ts +82 -0
- package/src/utils/overrides.test.ts +89 -0
- package/src/utils/overrides.ts +98 -0
- package/src/utils/packageManager.test.ts +321 -0
- package/src/utils/packageManager.ts +257 -0
- package/src/utils/patchWorkflowRunFields.test.ts +92 -0
- package/src/utils/patchWorkflowRunFields.ts +150 -0
- package/src/utils/payload.test.ts +497 -0
- package/src/utils/payload.ts +371 -0
- package/src/utils/postApiFetch.ts +51 -0
- package/src/utils/prSummary.test.ts +224 -0
- package/src/utils/prSummary.ts +147 -0
- package/src/utils/progressComment.ts +261 -0
- package/src/utils/providerErrors.test.ts +315 -0
- package/src/utils/providerErrors.ts +172 -0
- package/src/utils/rangeDiff.test.ts +236 -0
- package/src/utils/rangeDiff.ts +182 -0
- package/src/utils/remediationCommand.test.ts +163 -0
- package/src/utils/remediationCommand.ts +119 -0
- package/src/utils/retry.test.ts +153 -0
- package/src/utils/retry.ts +58 -0
- package/src/utils/reviewCleanup.ts +106 -0
- package/src/utils/run.ts +99 -0
- package/src/utils/runContext.ts +145 -0
- package/src/utils/runContextData.ts +58 -0
- package/src/utils/runErrorRenderer.test.ts +95 -0
- package/src/utils/runErrorRenderer.ts +259 -0
- package/src/utils/runFixture.ts +76 -0
- package/src/utils/runLifecycle.ts +237 -0
- package/src/utils/runStartupLog.ts +60 -0
- package/src/utils/secrets.test.ts +103 -0
- package/src/utils/secrets.ts +177 -0
- package/src/utils/setup.test.ts +509 -0
- package/src/utils/setup.ts +352 -0
- package/src/utils/shell.ts +103 -0
- package/src/utils/skills.test.ts +46 -0
- package/src/utils/skills.ts +67 -0
- package/src/utils/subprocess.test.ts +170 -0
- package/src/utils/subprocess.ts +438 -0
- package/src/utils/terraformMcp.test.ts +63 -0
- package/src/utils/terraformMcp.ts +83 -0
- package/src/utils/time.test.ts +105 -0
- package/src/utils/time.ts +59 -0
- package/src/utils/timer.test.ts +91 -0
- package/src/utils/timer.ts +72 -0
- package/src/utils/todoTracking.test.ts +223 -0
- package/src/utils/todoTracking.ts +167 -0
- package/src/utils/token.test.ts +239 -0
- package/src/utils/token.ts +186 -0
- package/src/utils/version.ts +10 -0
- package/src/utils/versioning.test.ts +34 -0
- package/src/utils/versioning.ts +44 -0
- package/src/utils/vertex.ts +85 -0
- 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
|
+
}>>;
|