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,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure-stdlib (fetch + Buffer) Codex OAuth refresh + JWT exp decoding.
|
|
3
|
+
*
|
|
4
|
+
* Lives here (not in codexAuth.ts) so the Next.js server side can import it
|
|
5
|
+
* via terramend/internal without dragging in node:child_process / spawn /
|
|
6
|
+
* mkdtemp from the rest of codexAuth.ts. Used by:
|
|
7
|
+
* - action/utils/codexAuth.ts (re-exports refreshCodexAuthBody)
|
|
8
|
+
* - utils/codexSecretRotation.ts (server-side maybeRotate at run-context)
|
|
9
|
+
*
|
|
10
|
+
* See wiki/codex-auth.md for the end-to-end refresh lifecycle.
|
|
11
|
+
*/
|
|
12
|
+
export interface CodexAuthBody {
|
|
13
|
+
auth_mode: "chatgpt";
|
|
14
|
+
tokens: {
|
|
15
|
+
access_token: string;
|
|
16
|
+
refresh_token: string;
|
|
17
|
+
id_token?: string;
|
|
18
|
+
account_id?: string;
|
|
19
|
+
};
|
|
20
|
+
last_refresh?: string;
|
|
21
|
+
}
|
|
22
|
+
/** OAuth client id Codex CLI and OpenCode both use against `auth.openai.com`.
|
|
23
|
+
* Same chain — a refresh token minted via `codex login --device-auth` can be
|
|
24
|
+
* refreshed against this client_id. */
|
|
25
|
+
export declare const CODEX_OAUTH_CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
|
|
26
|
+
export declare const CODEX_OAUTH_TOKEN_URL = "https://auth.openai.com/oauth/token";
|
|
27
|
+
/** thrown when the OAuth provider rejects the refresh token (4xx). callers
|
|
28
|
+
* can distinguish "race-lost / token revoked" from network errors via
|
|
29
|
+
* `instanceof OAuthInvalidGrantError`. */
|
|
30
|
+
export declare class OAuthInvalidGrantError extends Error {
|
|
31
|
+
readonly status: number;
|
|
32
|
+
constructor(status: number, body: string);
|
|
33
|
+
}
|
|
34
|
+
/** force one refresh round-trip against the OAuth provider. returns the
|
|
35
|
+
* rotated Codex-shaped blob (the auth.json body verbatim). does NOT persist
|
|
36
|
+
* — caller is responsible for writing back to wherever the token lives.
|
|
37
|
+
*
|
|
38
|
+
* server-side callers (maybeRotateCodexSecret) hold a DB row lock around
|
|
39
|
+
* this call so concurrent runs serialize: first one rotates, subsequent
|
|
40
|
+
* ones see the fresh value and skip. The 10s timeout is critical for that
|
|
41
|
+
* use: it caps how long a stalled auth.openai.com holds the row lock,
|
|
42
|
+
* keeping us well under the enclosing 30s transaction budget so the lock
|
|
43
|
+
* always releases and queued callers get a turn instead of timing out on
|
|
44
|
+
* the tx wrapper. Real OAuth latency is sub-second; 10s is generous. */
|
|
45
|
+
export declare function refreshCodexAuthBody(body: CodexAuthBody): Promise<CodexAuthBody>;
|
|
46
|
+
/** decode the access_token's JWT payload and return its `exp` claim in ms
|
|
47
|
+
* since epoch. returns null if the token isn't a parseable JWT or has no
|
|
48
|
+
* `exp` claim — caller falls back to "treat as expired".
|
|
49
|
+
*
|
|
50
|
+
* We don't verify the JWT signature (we'd need OpenAI's JWKS); we're only
|
|
51
|
+
* using the claim as a freshness hint. The actual auth check happens
|
|
52
|
+
* server-side at OpenAI when the token is used — trusting a fake JWT here
|
|
53
|
+
* would just delay the inevitable 401 from OpenAI. No security boundary
|
|
54
|
+
* at this decode step. */
|
|
55
|
+
export declare function decodeJwtExpMs(token: string): number | null;
|
|
56
|
+
/** parse + validate a Codex auth.json body from its JSON-string form.
|
|
57
|
+
* returns null on any shape mismatch — caller treats as "no codex auth". */
|
|
58
|
+
export declare function parseCodexAuthBody(raw: string): CodexAuthBody | null;
|
|
59
|
+
/** serialize a CodexAuthBody to its canonical on-disk form. */
|
|
60
|
+
export declare function stringifyCodexAuthBody(body: CodexAuthBody): string;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export type DiffLineRange = {
|
|
2
|
+
startLine: number;
|
|
3
|
+
endLine: number;
|
|
4
|
+
};
|
|
5
|
+
export type DiffTocEntry = {
|
|
6
|
+
filename: string;
|
|
7
|
+
startLine: number;
|
|
8
|
+
endLine: number;
|
|
9
|
+
};
|
|
10
|
+
export type DiffCoverageFileBreakdown = {
|
|
11
|
+
filename: string;
|
|
12
|
+
startLine: number;
|
|
13
|
+
endLine: number;
|
|
14
|
+
totalLines: number;
|
|
15
|
+
coveredLines: number;
|
|
16
|
+
coveredRanges: DiffLineRange[];
|
|
17
|
+
unreadRanges: DiffLineRange[];
|
|
18
|
+
};
|
|
19
|
+
export type DiffCoverageBreakdown = {
|
|
20
|
+
totalLines: number;
|
|
21
|
+
coveredLines: number;
|
|
22
|
+
unreadLines: number;
|
|
23
|
+
coveragePercent: number;
|
|
24
|
+
coveredRanges: DiffLineRange[];
|
|
25
|
+
unreadRanges: DiffLineRange[];
|
|
26
|
+
files: DiffCoverageFileBreakdown[];
|
|
27
|
+
};
|
|
28
|
+
export type DiffCoverageState = {
|
|
29
|
+
diffPath: string;
|
|
30
|
+
totalLines: number;
|
|
31
|
+
tocEntries: DiffTocEntry[];
|
|
32
|
+
coveredRanges: DiffLineRange[];
|
|
33
|
+
coveragePreflightRan: boolean;
|
|
34
|
+
lastBreakdown?: string | undefined;
|
|
35
|
+
};
|
|
36
|
+
export declare function countLines(params: {
|
|
37
|
+
content: string;
|
|
38
|
+
}): number;
|
|
39
|
+
export declare function parseDiffTocEntries(params: {
|
|
40
|
+
toc: string;
|
|
41
|
+
}): DiffTocEntry[];
|
|
42
|
+
export declare function createDiffCoverageState(params: {
|
|
43
|
+
diffPath: string;
|
|
44
|
+
totalLines: number;
|
|
45
|
+
toc: string;
|
|
46
|
+
previous?: DiffCoverageState | undefined;
|
|
47
|
+
}): DiffCoverageState;
|
|
48
|
+
export declare function recordDiffReadFromToolUse(params: {
|
|
49
|
+
state: DiffCoverageState | undefined;
|
|
50
|
+
toolName: string;
|
|
51
|
+
input: unknown;
|
|
52
|
+
cwd: string;
|
|
53
|
+
}): boolean;
|
|
54
|
+
export declare function getDiffCoverageBreakdown(params: {
|
|
55
|
+
state: DiffCoverageState;
|
|
56
|
+
}): DiffCoverageBreakdown;
|
|
57
|
+
export declare function renderDiffCoverageBreakdown(params: {
|
|
58
|
+
diffPath: string;
|
|
59
|
+
breakdown: DiffCoverageBreakdown;
|
|
60
|
+
}): string;
|
|
61
|
+
export declare function countLinesInRanges(params: {
|
|
62
|
+
ranges: DiffLineRange[];
|
|
63
|
+
}): number;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ToolState } from "#app/toolState";
|
|
2
|
+
interface ReportErrorParams {
|
|
3
|
+
toolState: ToolState;
|
|
4
|
+
error: string;
|
|
5
|
+
title?: string;
|
|
6
|
+
/**
|
|
7
|
+
* When the run has no pre-existing progress comment to update (silent
|
|
8
|
+
* IncrementalReview / pull_request_synchronize, mode-less polls), create
|
|
9
|
+
* a fresh issue comment on `toolState.issueNumber` instead of returning
|
|
10
|
+
* silently. Used for terminal errors (BillingError, TransientError) where
|
|
11
|
+
* the GH job summary is the only other surface and most users never open
|
|
12
|
+
* it. see #775.
|
|
13
|
+
*/
|
|
14
|
+
createIfMissing?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare function reportErrorToComment(ctx: ReportErrorParams): Promise<void>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type ExitSignalHandler = (signal: "SIGINT" | "SIGTERM") => void | Promise<void>;
|
|
2
|
+
/**
|
|
3
|
+
* Register a handler to run when the process receives SIGINT or SIGTERM.
|
|
4
|
+
* Returns a dispose function that removes the handler.
|
|
5
|
+
*/
|
|
6
|
+
export declare function onExitSignal(handler: ExitSignalHandler): () => void;
|
|
7
|
+
export declare function exitWithSignal(signal: "SIGINT" | "SIGTERM"): void;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function fixDoubleEscapedString(str: string): string;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* git authentication via GIT_ASKPASS.
|
|
3
|
+
*
|
|
4
|
+
* a localhost HTTP server serves tokens via UUID codes whose lifetime is
|
|
5
|
+
* bounded by the parent $git() invocation: register() makes the code active,
|
|
6
|
+
* the script (and any sibling subprocess — e.g. git-lfs pre-push) can fetch
|
|
7
|
+
* the token any number of times, and $git()'s finally calls revoke() to
|
|
8
|
+
* close the window. each $git() call writes a unique askpass script with
|
|
9
|
+
* the server port+code baked into the file body — no secrets in subprocess
|
|
10
|
+
* env. a replay of a revoked code trips a 409 and revokes the underlying
|
|
11
|
+
* github installation token.
|
|
12
|
+
*
|
|
13
|
+
* see wiki/askpass.md for full security documentation.
|
|
14
|
+
*/
|
|
15
|
+
import type { GitAuthServer } from "#app/utils/gitAuthServer";
|
|
16
|
+
type SafeGitSubcommand = "fetch" | "push";
|
|
17
|
+
type GitAuthOptions = {
|
|
18
|
+
token: string;
|
|
19
|
+
cwd?: string;
|
|
20
|
+
disableHooks?: boolean;
|
|
21
|
+
};
|
|
22
|
+
type GitResult = {
|
|
23
|
+
stdout: string;
|
|
24
|
+
stderr: string;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* resolve and fingerprint the git binary. must be called once at startup
|
|
28
|
+
* (in main()) before any agent code runs, so the path and hash reflect
|
|
29
|
+
* the untampered binary.
|
|
30
|
+
*
|
|
31
|
+
* resolves symlinks via realpath so the hash is of the actual binary.
|
|
32
|
+
* a malicious agent with sudo could replace the binary later, which is
|
|
33
|
+
* caught by verifyGitBinary() before each authenticated call.
|
|
34
|
+
*/
|
|
35
|
+
export declare function resolveGit(): void;
|
|
36
|
+
export declare function setGitAuthServer(server: GitAuthServer): void;
|
|
37
|
+
/**
|
|
38
|
+
* execute authenticated git command via ASKPASS.
|
|
39
|
+
*
|
|
40
|
+
* subcommand is restricted to "fetch" | "push" — operations that talk to
|
|
41
|
+
* a remote and need credentials. working-tree operations (checkout, merge)
|
|
42
|
+
* use $() from shell.ts which has no token.
|
|
43
|
+
*
|
|
44
|
+
* per call: registers a code with the auth server (valid for the lifetime
|
|
45
|
+
* of this invocation), writes a unique askpass script with port+code baked
|
|
46
|
+
* in, spawns git with GIT_ASKPASS pointing to the script. on completion,
|
|
47
|
+
* revokes the code and deletes the script in finally. multiple sibling
|
|
48
|
+
* askpass calls within one invocation (e.g. git itself + git-lfs pre-push)
|
|
49
|
+
* all see a valid code; replay attempts after finally trip a 409 and the
|
|
50
|
+
* server revokes the underlying github token as a tamper signal.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* await $git("fetch", ["origin", "main"], { token });
|
|
54
|
+
* await $git("push", ["-u", "origin", "feature"], { token });
|
|
55
|
+
*/
|
|
56
|
+
export declare function $git(subcommand: SafeGitSubcommand, args: string[], options: GitAuthOptions): Promise<GitResult>;
|
|
57
|
+
/**
|
|
58
|
+
* shallow-clone unreachable: when an existing local depth is too shallow for
|
|
59
|
+
* git to traverse to the requested ref's ancestry, the remote walk fails with
|
|
60
|
+
* one of these wordings (git emits the full OID via oid_to_hex, so the bound
|
|
61
|
+
* is 40 for SHA-1 or 64 for SHA-256). detecting both lets a single deepen
|
|
62
|
+
* retry recover before the error reaches the agent — see issue #564 for the
|
|
63
|
+
* original `git_fetch` precedent and #656 for the `checkout_pr` follow-up.
|
|
64
|
+
*/
|
|
65
|
+
export declare const SHALLOW_UNREACHABLE_PATTERNS: RegExp[];
|
|
66
|
+
/**
|
|
67
|
+
* large enough to clear the merge base on most real-world PRs without
|
|
68
|
+
* downloading the full history; matches the fallback used by
|
|
69
|
+
* `checkoutPrBranch` when the GitHub compare API is unavailable.
|
|
70
|
+
*/
|
|
71
|
+
export declare const DEEPEN_RETRY_DEPTH = 1000;
|
|
72
|
+
/**
|
|
73
|
+
* authenticated `git fetch` that recovers from shallow-unreachable errors
|
|
74
|
+
* by retrying once with `--deepen=1000`. callers pass the same args they
|
|
75
|
+
* would to `$git("fetch", ...)`; on shallow-unreachable failures in a
|
|
76
|
+
* shallow repo, the second attempt prepends `--deepen=N` and strips any
|
|
77
|
+
* caller-supplied `--depth=` (the two flags are mutually exclusive, and
|
|
78
|
+
* the caller's depth is what got us into this mess).
|
|
79
|
+
*
|
|
80
|
+
* non-shallow-unreachable errors and non-shallow repos rethrow unchanged,
|
|
81
|
+
* so this is safe to wrap any fetch without changing fast-path behavior.
|
|
82
|
+
*/
|
|
83
|
+
export declare function $gitFetchWithDeepen(args: string[], options: GitAuthOptions, label?: string): Promise<GitResult>;
|
|
84
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ASKPASS-based git authentication server.
|
|
3
|
+
*
|
|
4
|
+
* serves tokens via a localhost HTTP server with per-$git()-call UUID codes.
|
|
5
|
+
* each $git() call gets a unique askpass script with the port+code baked in.
|
|
6
|
+
* the token never appears in subprocess env — only the script file path.
|
|
7
|
+
*
|
|
8
|
+
* lifetime: the code is valid for as long as the $git() invocation is
|
|
9
|
+
* running. multiple askpass calls within one invocation (e.g. git's own
|
|
10
|
+
* fetch/push + a git-lfs pre-push hook that also authenticates) all
|
|
11
|
+
* succeed. $git() calls revoke(code) in finally; subsequent requests for
|
|
12
|
+
* a revoked code trigger immediate token revocation via the GitHub API
|
|
13
|
+
* as a tamper-evidence precaution (an agent replaying the code after the
|
|
14
|
+
* legitimate window has closed is the realistic attack we still catch).
|
|
15
|
+
*/
|
|
16
|
+
export type GitAuthServer = {
|
|
17
|
+
port: number;
|
|
18
|
+
register: (token: string) => string;
|
|
19
|
+
revoke: (code: string) => void;
|
|
20
|
+
writeAskpassScript: (code: string) => string;
|
|
21
|
+
close: () => Promise<void>;
|
|
22
|
+
[Symbol.asyncDispose]: () => Promise<void>;
|
|
23
|
+
};
|
|
24
|
+
export declare function startGitAuthServer(tmpdir: string): Promise<GitAuthServer>;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { throttling } from "@octokit/plugin-throttling";
|
|
2
|
+
import { Octokit } from "@octokit/rest";
|
|
3
|
+
export interface InstallationToken {
|
|
4
|
+
token: string;
|
|
5
|
+
expires_at: string;
|
|
6
|
+
installation_id: number;
|
|
7
|
+
repository: string;
|
|
8
|
+
ref: string;
|
|
9
|
+
runner_environment: string;
|
|
10
|
+
owner?: string;
|
|
11
|
+
}
|
|
12
|
+
type ReadWrite = "read" | "write";
|
|
13
|
+
type WriteOnly = "write";
|
|
14
|
+
/**
|
|
15
|
+
* GitHub App installation access token permissions.
|
|
16
|
+
* passed to `POST /app/installations/{id}/access_tokens` to scope the token.
|
|
17
|
+
* fields and allowed values come from the `app-permissions` OpenAPI schema.
|
|
18
|
+
* @see https://docs.github.com/en/rest/apps/installations#create-an-installation-access-token-for-an-app
|
|
19
|
+
* @see https://github.com/github/rest-api-description — components.schemas.app-permissions
|
|
20
|
+
*/
|
|
21
|
+
type GitHubAppPermissions = {
|
|
22
|
+
actions?: ReadWrite;
|
|
23
|
+
artifact_metadata?: ReadWrite;
|
|
24
|
+
attestations?: ReadWrite;
|
|
25
|
+
checks?: ReadWrite;
|
|
26
|
+
contents?: ReadWrite;
|
|
27
|
+
deployments?: ReadWrite;
|
|
28
|
+
discussions?: ReadWrite;
|
|
29
|
+
issues?: ReadWrite;
|
|
30
|
+
packages?: ReadWrite;
|
|
31
|
+
pages?: ReadWrite;
|
|
32
|
+
pull_requests?: ReadWrite;
|
|
33
|
+
security_events?: ReadWrite;
|
|
34
|
+
statuses?: ReadWrite;
|
|
35
|
+
workflows?: WriteOnly;
|
|
36
|
+
};
|
|
37
|
+
type AcquireTokenOptions = {
|
|
38
|
+
repos?: string[];
|
|
39
|
+
permissions?: GitHubAppPermissions;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* ensure a GitHub token is available in the environment.
|
|
43
|
+
*
|
|
44
|
+
* when OIDC is available (CI), always mints a fresh token scoped to
|
|
45
|
+
* GITHUB_REPOSITORY — overriding any inherited GITHUB_TOKEN that may
|
|
46
|
+
* be scoped to the wrong repo.
|
|
47
|
+
*
|
|
48
|
+
* otherwise falls back to GitHub App credentials for local development.
|
|
49
|
+
*
|
|
50
|
+
* only called from dev-run.ts (test/dev path) — the live action calls
|
|
51
|
+
* main() directly and never calls this.
|
|
52
|
+
*/
|
|
53
|
+
export declare function ensureGitHubToken(): Promise<void>;
|
|
54
|
+
export declare function acquireNewToken(opts?: AcquireTokenOptions): Promise<string>;
|
|
55
|
+
export interface RepoContext {
|
|
56
|
+
owner: string;
|
|
57
|
+
name: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Parse repository context from GITHUB_REPOSITORY environment variable.
|
|
61
|
+
*/
|
|
62
|
+
export declare function parseRepoContext(): RepoContext;
|
|
63
|
+
export type OctokitWithPlugins = InstanceType<ReturnType<typeof Octokit.plugin<typeof Octokit, [typeof throttling]>>>;
|
|
64
|
+
export interface ResourceUsage {
|
|
65
|
+
requestCount: number;
|
|
66
|
+
rateLimitRemaining: number | null;
|
|
67
|
+
rateLimitResetMs: number | null;
|
|
68
|
+
}
|
|
69
|
+
export interface UsageSummary {
|
|
70
|
+
version: 1;
|
|
71
|
+
github: {
|
|
72
|
+
core: ResourceUsage;
|
|
73
|
+
graphql: ResourceUsage;
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
export declare function writeGitHubUsageSummaryToFile(path: string): Promise<void>;
|
|
77
|
+
export declare function createOctokit(token: string): OctokitWithPlugins;
|
|
78
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export interface InstallFromNpmTarballParams {
|
|
2
|
+
packageName: string;
|
|
3
|
+
version: string;
|
|
4
|
+
executablePath: string;
|
|
5
|
+
installDependencies?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface InstallFromCurlParams {
|
|
8
|
+
installUrl: string;
|
|
9
|
+
executableName: string;
|
|
10
|
+
}
|
|
11
|
+
export interface InstallFromDirectTarballParams {
|
|
12
|
+
url: string;
|
|
13
|
+
executablePath: string;
|
|
14
|
+
stripComponents?: number;
|
|
15
|
+
}
|
|
16
|
+
export interface InstallFromGithubParams {
|
|
17
|
+
owner: string;
|
|
18
|
+
repo: string;
|
|
19
|
+
tag?: string;
|
|
20
|
+
assetName?: string;
|
|
21
|
+
executablePath?: string;
|
|
22
|
+
githubInstallationToken?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface InstallFromGithubTarballParams {
|
|
25
|
+
owner: string;
|
|
26
|
+
repo: string;
|
|
27
|
+
tag?: string;
|
|
28
|
+
assetNamePattern: string;
|
|
29
|
+
executablePath: string;
|
|
30
|
+
githubInstallationToken?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Install a CLI tool from an npm package tarball
|
|
34
|
+
* Downloads the tarball, extracts it to a temp directory, and returns the path to the CLI executable
|
|
35
|
+
* The temp directory will be cleaned up by the OS automatically
|
|
36
|
+
*/
|
|
37
|
+
export declare function installFromNpmTarball(params: InstallFromNpmTarballParams): Promise<string>;
|
|
38
|
+
/**
|
|
39
|
+
* Install a CLI tool from GitHub releases
|
|
40
|
+
* Downloads the latest release asset from GitHub and returns the path to the executable
|
|
41
|
+
* The temp directory will be cleaned up by the OS automatically
|
|
42
|
+
*/
|
|
43
|
+
export declare function installFromGithub(params: InstallFromGithubParams): Promise<string>;
|
|
44
|
+
/**
|
|
45
|
+
* Install a CLI tool from a GitHub release tarball
|
|
46
|
+
* Downloads the tar.gz from GitHub releases, extracts it, and returns the path to the CLI executable
|
|
47
|
+
* The temp directory will be cleaned up by the OS automatically
|
|
48
|
+
*/
|
|
49
|
+
export declare function installFromGithubTarball(params: InstallFromGithubTarballParams): Promise<string>;
|
|
50
|
+
/**
|
|
51
|
+
* Install a CLI tool from a direct tarball URL.
|
|
52
|
+
* Downloads the tarball, extracts it to a temp directory, and returns the path to the CLI executable.
|
|
53
|
+
*/
|
|
54
|
+
export declare function installFromDirectTarball(params: InstallFromDirectTarballParams): Promise<string>;
|
|
55
|
+
/**
|
|
56
|
+
* Install a CLI tool from a curl-based install script
|
|
57
|
+
* Downloads the install script, runs it with HOME set to temp directory, and returns the path to the CLI executable
|
|
58
|
+
* The temp directory will be cleaned up by the OS automatically
|
|
59
|
+
*/
|
|
60
|
+
export declare function installFromCurl(params: InstallFromCurlParams): Promise<string>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type AgentId } from "#app/external";
|
|
2
|
+
import type { Mode } from "#app/modes";
|
|
3
|
+
import type { ResolvedPayload } from "#app/utils/payload";
|
|
4
|
+
import type { LearningsHeading } from "#app/utils/runContext";
|
|
5
|
+
import type { RunContextData } from "#app/utils/runContextData";
|
|
6
|
+
interface InstructionsContext {
|
|
7
|
+
payload: ResolvedPayload;
|
|
8
|
+
repo: RunContextData["repo"];
|
|
9
|
+
modes: Mode[];
|
|
10
|
+
agentId: AgentId;
|
|
11
|
+
outputSchema?: Record<string, unknown> | undefined;
|
|
12
|
+
/** absolute path to the seeded learnings tmpfile, or null when the file
|
|
13
|
+
* couldn't be seeded for some reason. main.ts always seeds, so in
|
|
14
|
+
* practice this is always set; the null case keeps the type honest. */
|
|
15
|
+
learningsFilePath: string | null;
|
|
16
|
+
/** server-parsed TOC for the body of the learnings tmpfile. rendered
|
|
17
|
+
* inline into the LEARNINGS prompt section so the agent can `read_file`
|
|
18
|
+
* targeted line ranges instead of pulling the whole file into context. */
|
|
19
|
+
learningsHeadings: LearningsHeading[];
|
|
20
|
+
/** agent-facing description of a setup lifecycle hook failure (see
|
|
21
|
+
* `describeSetupFailure`), rendered as a SETUP HOOK FAILED banner. empty
|
|
22
|
+
* string when the hook succeeded, was skipped, or wasn't configured. */
|
|
23
|
+
setupHookFailure: string;
|
|
24
|
+
}
|
|
25
|
+
export interface ResolvedInstructions {
|
|
26
|
+
full: string;
|
|
27
|
+
system: string;
|
|
28
|
+
user: string;
|
|
29
|
+
eventInstructions: string;
|
|
30
|
+
event: string;
|
|
31
|
+
runtime: string;
|
|
32
|
+
}
|
|
33
|
+
/** render the heading list as an indented bullet TOC. ranges shown in
|
|
34
|
+
* parentheses (`(L3-L18)`); the start line is always the heading line
|
|
35
|
+
* itself, so reading the listed range gives the agent the heading +
|
|
36
|
+
* body together. shallowest heading depth in the body sits at the root
|
|
37
|
+
* column; deeper levels indent by `(depth - rootDepth) * 2` spaces. */
|
|
38
|
+
export declare function renderLearningsToc(headings: LearningsHeading[]): string;
|
|
39
|
+
/** assemble the LEARNINGS prompt section: file path + intro + either
|
|
40
|
+
* the rendered heading TOC (when the body has structure) or a no-headings
|
|
41
|
+
* affordance pointing the agent at the reflection turn for restructuring.
|
|
42
|
+
* empty string when the seed step failed and there's no path to surface. */
|
|
43
|
+
export declare function buildLearningsSection(ctx: {
|
|
44
|
+
filePath: string | null;
|
|
45
|
+
headings: LearningsHeading[];
|
|
46
|
+
}): string;
|
|
47
|
+
export declare function resolveInstructions(ctx: InstructionsContext): ResolvedInstructions;
|
|
48
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The prefix text for the initial "leaping into action" comment.
|
|
3
|
+
* Used to detect whether a progress comment is still in its initial state
|
|
4
|
+
* and hasn't been updated with real progress or error messages.
|
|
5
|
+
*
|
|
6
|
+
* Lives in `utils/` (not `mcp/`) so it can be re-exported via `terramend/internal`
|
|
7
|
+
* without dragging the MCP server's transitive imports into the Next.js app's
|
|
8
|
+
* type-check graph.
|
|
9
|
+
*/
|
|
10
|
+
export declare const LEAPING_INTO_ACTION_PREFIX = "Leaping into action";
|
|
11
|
+
export declare function isLeapingIntoActionCommentBody(body: string): boolean;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { ToolContext } from "#app/mcp/server";
|
|
2
|
+
import { MAX_LEARNINGS_LENGTH, truncateAtLineBoundary } from "#app/utils/learningsTruncate";
|
|
3
|
+
export { MAX_LEARNINGS_LENGTH, truncateAtLineBoundary };
|
|
4
|
+
/**
|
|
5
|
+
* Repo-level learnings — operational facts about a repo (setup steps, test
|
|
6
|
+
* commands, conventions, gotchas) that accumulate across agent runs and feed
|
|
7
|
+
* back into future runs as durable context. Modeled on the PR-summary tmpfile
|
|
8
|
+
* pattern (see action/utils/prSummary.ts):
|
|
9
|
+
*
|
|
10
|
+
* 1. server seeds `terramend-learnings.md` with the verbatim body of
|
|
11
|
+
* `Repo.learnings` (or empty for fresh repos), and parses headings
|
|
12
|
+
* server-side (`utils/learningsToc.ts`) — the parsed TOC is rendered
|
|
13
|
+
* into the LEARNINGS prompt section, not into the file
|
|
14
|
+
* 2. the agent reads the TOC in the prompt and uses listed line ranges
|
|
15
|
+
* to read just the sections relevant to the current task — file can
|
|
16
|
+
* grow large, but only targeted ranges hit the agent's context
|
|
17
|
+
* 3. agent edits the file in place at end-of-run during the reflection
|
|
18
|
+
* turn (see action/agents/postRun.ts buildLearningsReflectionPrompt)
|
|
19
|
+
* 4. main.ts reads the file back at end-of-run and PATCHes
|
|
20
|
+
* `/api/repo/[owner]/[repo]/learnings` if the body changed
|
|
21
|
+
*
|
|
22
|
+
* Edit-in-place avoids stuffing the entire learnings list into both the
|
|
23
|
+
* prompt context and an `update_learnings` MCP tool call (which previously
|
|
24
|
+
* required passing the FULL merged list as a string parameter — an
|
|
25
|
+
* output-token tax that grew linearly with the learnings size).
|
|
26
|
+
*
|
|
27
|
+
* Section structure is agent-curated. The reflection prompt teaches
|
|
28
|
+
* hierarchy + a soft 300-line-per-section cap to keep TOC ranges
|
|
29
|
+
* agent-targetable on long-lived repos; there is no fixed taxonomy.
|
|
30
|
+
*/
|
|
31
|
+
export declare const LEARNINGS_FILE_NAME = "terramend-learnings.md";
|
|
32
|
+
export declare function learningsFilePath(tmpdir: string): string;
|
|
33
|
+
/** seed the rolling learnings tmpfile with the verbatim DB body (or empty
|
|
34
|
+
* string for fresh repos). returns the absolute path. the parsed TOC is
|
|
35
|
+
* carried separately via `RepoSettings.learningsHeadings` and rendered
|
|
36
|
+
* into the prompt by `resolveInstructions`, so the file on disk is just
|
|
37
|
+
* the body — no markers, no scaffold, no in-file TOC. */
|
|
38
|
+
export declare function seedLearningsFile(params: {
|
|
39
|
+
tmpdir: string;
|
|
40
|
+
current: string | null;
|
|
41
|
+
}): Promise<string>;
|
|
42
|
+
/** read the agent-edited learnings file. returns null when the file is
|
|
43
|
+
* missing or unreadable (treated as "no change"). caps content at the
|
|
44
|
+
* server's max length to avoid a 400 round-trip. */
|
|
45
|
+
export declare function readLearningsFile(path: string): Promise<string | null>;
|
|
46
|
+
/**
|
|
47
|
+
* Read the agent-edited repo-level learnings tmpfile and PATCH it to
|
|
48
|
+
* `Repo.learnings`.
|
|
49
|
+
*
|
|
50
|
+
* Best-effort: any failure is logged and does not affect the run's success
|
|
51
|
+
* status. Skips the PATCH when the file is byte-trim-identical to its seed —
|
|
52
|
+
* the agent didn't touch it, so writing the same content back would just
|
|
53
|
+
* burn a `LearningsRevision` row and an API round-trip.
|
|
54
|
+
*
|
|
55
|
+
* `ctx.toolState.model` is forwarded so `LearningsRevision.model` keeps
|
|
56
|
+
* populating; it powers the per-revision attribution badge in the UI
|
|
57
|
+
* history view.
|
|
58
|
+
*
|
|
59
|
+
* `learningsPersistAttempted` guards against double-execution between the
|
|
60
|
+
* normal end-of-run path and the SIGINT/SIGTERM handler.
|
|
61
|
+
*/
|
|
62
|
+
export declare function persistLearnings(ctx: ToolContext): Promise<void>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pure string helpers for capping and line-boundary-truncating the
|
|
3
|
+
* `Repo.learnings` body. lives in its own module (vs alongside
|
|
4
|
+
* `learnings.ts`) so the proprietary root app can re-export it through
|
|
5
|
+
* `action/internal/index.ts` without dragging the entire MCP type graph
|
|
6
|
+
* along — `learnings.ts` imports `ToolContext` for its runtime helpers,
|
|
7
|
+
* and pulling that into the SDK-facing `internal` barrel expands the
|
|
8
|
+
* type graph reachable from root `tsc` and `cf-worker-indexing` to every
|
|
9
|
+
* tool module under `action/mcp/`. keeping these helpers MCP-free is the
|
|
10
|
+
* cheap structural fix.
|
|
11
|
+
*
|
|
12
|
+
* see `action/utils/learnings.ts` for the full learnings-file lifecycle.
|
|
13
|
+
*/
|
|
14
|
+
/** maximum size of `Repo.learnings` body in chars. action truncates the
|
|
15
|
+
* read-back BEFORE the PATCH to avoid sending an oversized payload; the
|
|
16
|
+
* server applies the same truncation as a defense-in-depth backstop (any
|
|
17
|
+
* caller that misses the client-side step would otherwise persist a
|
|
18
|
+
* mid-line tail, breaking the next-run TOC parse).
|
|
19
|
+
*
|
|
20
|
+
* raised from 10k → 100k once the TOC affordance landed: with line-range
|
|
21
|
+
* reads via the server-parsed TOC the agent doesn't ingest the whole
|
|
22
|
+
* file, so the cap is governed by curation discipline rather than a
|
|
23
|
+
* tight byte ceiling. 100k holds ~400-500 short bullets. */
|
|
24
|
+
export declare const MAX_LEARNINGS_LENGTH = 100000;
|
|
25
|
+
export declare function truncateAtLineBoundary(body: string, cap: number): string;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export interface ExecuteLifecycleHookParams {
|
|
2
|
+
event: string;
|
|
3
|
+
script: string | null;
|
|
4
|
+
/**
|
|
5
|
+
* when true, after the hook runs (success or failure), discard tracked-file
|
|
6
|
+
* mods so the agent doesn't see hook-generated drift (e.g. `pnpm install`
|
|
7
|
+
* rewriting a lockfile). untracked files are preserved — hooks that
|
|
8
|
+
* intentionally materialize files (e.g. a `.env` from a template) stay
|
|
9
|
+
* visible to the agent. skipped (with a warning) if the tree had
|
|
10
|
+
* pre-existing tracked changes before the hook ran, so we never clobber
|
|
11
|
+
* pre-existing work; pre-existing untracked files are ignored for this
|
|
12
|
+
* gate because `git restore --staged --worktree .` doesn't touch them
|
|
13
|
+
* anyway. no-op when no script was configured.
|
|
14
|
+
*/
|
|
15
|
+
normalizeWorkingTreeAfter?: boolean;
|
|
16
|
+
}
|
|
17
|
+
/** structured failure info — `output` on the `exit` variant is trimmed
|
|
18
|
+
* stderr, falling back to stdout when stderr is empty. */
|
|
19
|
+
export type LifecycleHookFailure = {
|
|
20
|
+
kind: "exit";
|
|
21
|
+
exitCode: number;
|
|
22
|
+
output: string;
|
|
23
|
+
} | {
|
|
24
|
+
kind: "timeout";
|
|
25
|
+
} | {
|
|
26
|
+
kind: "spawn";
|
|
27
|
+
spawnError: string;
|
|
28
|
+
};
|
|
29
|
+
/** one-line, agent-facing description of a hook failure. empty string when
|
|
30
|
+
* there was no failure, so callers can pass the result straight through to a
|
|
31
|
+
* prompt section that omits itself on empty. */
|
|
32
|
+
export declare function describeSetupFailure(failure: LifecycleHookFailure | undefined): string;
|
|
33
|
+
export interface LifecycleHookResult {
|
|
34
|
+
/**
|
|
35
|
+
* human-readable warning when the hook failed. includes retry guidance:
|
|
36
|
+
* transient spawn/exit errors are worth retrying, timeouts and
|
|
37
|
+
* persistent failures are not. absent when the hook succeeded or was
|
|
38
|
+
* skipped. setup/post-checkout callers surface this verbatim; prepush
|
|
39
|
+
* builds its own message from `failure` instead.
|
|
40
|
+
*/
|
|
41
|
+
warning?: string;
|
|
42
|
+
/**
|
|
43
|
+
* structured failure info — undefined when the hook succeeded or was
|
|
44
|
+
* skipped. lets callers compose their own messaging without parsing the
|
|
45
|
+
* `warning` string.
|
|
46
|
+
*/
|
|
47
|
+
failure?: LifecycleHookFailure;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* execute a lifecycle hook script if one is configured.
|
|
51
|
+
*
|
|
52
|
+
* soft-fails: instead of throwing on hook errors, returns a warning string
|
|
53
|
+
* (and structured failure info) so callers can choose how to surface it
|
|
54
|
+
* (mcp tools relay it to the agent; setup logs it and adds a prompt banner).
|
|
55
|
+
* timeouts are flagged as non-retryable in the warning text.
|
|
56
|
+
*/
|
|
57
|
+
export declare function executeLifecycleHook(params: ExecuteLifecycleHookParams): Promise<LifecycleHookResult>;
|