overhaul git setup

This commit is contained in:
Colin McDonnell
2025-12-16 18:00:22 -08:00
parent f6ac916e22
commit 1bff21f7fb
19 changed files with 514 additions and 195 deletions
+202 -86
View File
@@ -80489,6 +80489,9 @@ function formatIndentedField(label, content) {
return formatted;
}
// agents/instructions.ts
import { execSync } from "node:child_process";
// ../node_modules/.pnpm/@toon-format+toon@1.0.0/node_modules/@toon-format/toon/dist/index.js
var LIST_ITEM_MARKER = "-";
var LIST_ITEM_PREFIX = "- ";
@@ -89416,10 +89419,11 @@ function getModes({
name: "Address Reviews",
description: "Address PR review feedback; respond to reviewer comments; make requested changes to an existing PR",
prompt: `Follow these steps:
1. Get PR info with ${ghPullfrogMcpName}/get_pull_request (this automatically fetches and checks out the PR branch)
1. Checkout the PR using ${ghPullfrogMcpName}/checkout_pr with the PR number. This fetches the PR branch and configures push settings (including for fork PRs).
2. Review the feedback provided. Understand each review comment and what changes are being requested.
- **EVENT DATA may contain review comment details**: If available, \`approved_comments\` are comments to address, \`unapproved_comments\` are for context only. The \`triggerer\` field indicates who initiated this action - prioritize their replies when deciding how to implement fixes.
- You can use ${ghPullfrogMcpName}/get_pull_request to get PR metadata if needed.
3. If the request requires understanding the codebase structure, dependencies, or conventions, gather relevant context. Read AGENTS.md if it exists.
@@ -89429,7 +89433,7 @@ function getModes({
6. Test your changes to ensure they work correctly.
7. When done, commit and push your changes to the existing PR branch. Do not create a new branch or PR - you are updating an existing one.
7. When done, commit your changes with ${ghPullfrogMcpName}/commit_files, then push with ${ghPullfrogMcpName}/push_branch. The push will automatically go to the correct remote (including fork repos). Do not create a new branch or PR - you are updating an existing one.
${disableProgressComment ? "" : `
8. ${reportProgressInstruction}
@@ -89439,9 +89443,9 @@ ${disableProgressComment ? "" : `
name: "Review",
description: "Review code, PRs, or implementations; provide feedback or suggestions; identify issues; or check code quality, style, and correctness",
prompt: `Follow these steps:
1. Get PR info with ${ghPullfrogMcpName}/get_pull_request (this automatically prepares the repository by fetching and checking out the PR branch)
1. Checkout the PR using ${ghPullfrogMcpName}/checkout_pr with the PR number. This fetches the PR branch and base branch, preparing the repo for review.
2. **IMPORTANT**: After calling ${ghPullfrogMcpName}/get_pull_request, the PR branch is already checked out locally. View diff using: \`git diff origin/<base>...HEAD\` (replace <base> with 'base' from PR info). Do NOT use \`origin/<head>\` - the branch is checked out locally, not as a remote tracking branch.
2. **IMPORTANT**: After calling checkout_pr, the PR branch is checked out locally. View diff using: \`git diff origin/<base>..HEAD\` (replace <base> with 'base' from checkout_pr result, e.g., \`git diff origin/main..HEAD\`). Use two dots (..) not three dots (...) for reliable diffs. Do NOT use \`origin/<head>\` - the branch is checked out locally, not as a remote tracking branch. This works for both same-repo and fork PRs.
3. Read files from the checked-out PR branch to understand the implementation. Always use **relative paths** from repo root (e.g., \`src/index.ts\`), never absolute paths.
@@ -89449,7 +89453,8 @@ ${disableProgressComment ? "" : `
**GENERAL GUIDANCE**
- *CRITICAL* \u2014\xA0Use **relative paths** from repo root (e.g., \`packages/core/src/utils.ts\`)
- Do not leave any comments that are not potentially actionable. Do not leave complimentary comments just to be nice.
- *CRITICAL* \u2014 Use **relative paths** from repo root (e.g., \`packages/core/src/utils.ts\`)
- For line numbers, use the NEW file line number from the diff (shown after \`+\` in hunk headers like \`@@ -10,5 +12,8 @@\` means new file starts at line 12)
- Only comment on lines that appear in the diff. GitHub will reject comments on unchanged lines.
- **CRITICAL: Prioritize per-line feedback over summary text.**
@@ -89459,7 +89464,6 @@ ${disableProgressComment ? "" : `
- 95%+ of review content should be in per-line comments; the body should be just a couple sentences
- The review body will include quick action links for addressing feedback, so keep it concise
- Do not nitpick unless instructed explicity to do so by the user's additional instructions. This includes: requesting documentation/docstrings/JSDoc.
- Do not leave any comments that are not potentially actionable.
- The review should be thoughtful. When evaluating complex changes, consider the following conceptual approach:
- 1) conceptualize the changes made. make sure you understand it.
- 2) evaluate conceptual approach. leave feedback as needed.
@@ -89554,20 +89558,47 @@ function formatPrepResults(results) {
if (lines.length === 0) {
return "";
}
return `************* ENVIRONMENT SETUP *************
${lines.join("\n")}
`;
return lines.join("\n");
}
var addInstructions = ({ payload, prepResults }) => {
function buildRuntimeContext({ repo, prepResults }) {
const lines = [];
lines.push(`working_directory: ${process.cwd()}`);
try {
const gitStatus = execSync("git status --short", { encoding: "utf-8", stdio: "pipe" }).trim();
lines.push(`git_status: ${gitStatus || "(clean)"}`);
} catch {
}
lines.push(`repo: ${repo.owner}/${repo.name}`);
lines.push(`default_branch: ${repo.defaultBranch}`);
const ghVars = {
github_event_name: process.env.GITHUB_EVENT_NAME,
github_ref: process.env.GITHUB_REF,
github_sha: process.env.GITHUB_SHA?.slice(0, 7),
github_actor: process.env.GITHUB_ACTOR,
github_run_id: process.env.GITHUB_RUN_ID,
github_workflow: process.env.GITHUB_WORKFLOW
};
for (const [key, value2] of Object.entries(ghVars)) {
if (value2) {
lines.push(`${key}: ${value2}`);
}
}
const envSetup = formatPrepResults(prepResults);
if (envSetup) {
lines.push("");
lines.push("environment_setup:");
lines.push(envSetup);
}
return lines.join("\n");
}
var addInstructions = ({ payload, prepResults, repo }) => {
let encodedEvent = "";
const eventKeys = Object.keys(payload.event);
if (eventKeys.length === 1 && eventKeys[0] === "trigger") {
} else {
encodedEvent = encode(payload.event);
}
const envSetup = formatPrepResults(prepResults);
const runtimeContext = buildRuntimeContext({ repo, prepResults });
const dependenciesPreinstalled = prepResults.every((r) => r.dependenciesInstalled) || void 0;
return `
***********************************************
@@ -89643,14 +89674,21 @@ Tool names may be formatted as \`(server name)/(tool name)\`, for example: \`${g
**Git operations**: All git operations must use ${ghPullfrogMcpName} MCP tools to ensure proper authentication and commit attribution. Do NOT use git commands directly (e.g., \`git commit\`, \`git push\`, \`git checkout\`, \`git branch\`) - these will use incorrect credentials and attribute commits to the wrong author.
**Available git MCP tools**:
- \`${ghPullfrogMcpName}/checkout_pr\` - Checkout an existing PR branch locally (handles fork PRs automatically)
- \`${ghPullfrogMcpName}/create_branch\` - Create a new branch from a base branch
- \`${ghPullfrogMcpName}/commit_files\` - Stage and commit files with proper authentication
- \`${ghPullfrogMcpName}/push_branch\` - Push a branch to the remote repository
- \`${ghPullfrogMcpName}/push_branch\` - Push a branch to the remote (automatically uses correct remote for fork PRs)
- \`${ghPullfrogMcpName}/create_pull_request\` - Create a PR from the current branch
**Workflow for making code changes**:
1. Use file operations to create/modify files
2. Use \`${ghPullfrogMcpName}/create_branch\` to create a new branch
**Workflow for working on an existing PR**:
1. Use \`${ghPullfrogMcpName}/checkout_pr\` to checkout the PR branch
2. Make your changes using file operations
3. Use \`${ghPullfrogMcpName}/commit_files\` to commit your changes
4. Use \`${ghPullfrogMcpName}/push_branch\` to push (automatically pushes to fork for fork PRs)
**Workflow for creating new changes**:
1. Use \`${ghPullfrogMcpName}/create_branch\` to create a new branch
2. Make your changes using file operations
3. Use \`${ghPullfrogMcpName}/commit_files\` to commit your changes
4. Use \`${ghPullfrogMcpName}/push_branch\` to push the branch
5. Use \`${ghPullfrogMcpName}/create_pull_request\` to create a PR
@@ -89694,9 +89732,7 @@ ${encodedEvent}` : ""}
************* RUNTIME CONTEXT *************
working_directory: ${process.cwd()}
${envSetup}`;
${runtimeContext}`;
};
// agents/shared.ts
@@ -90117,9 +90153,9 @@ var claude = agent({
executablePath: "cli.js"
});
},
run: async ({ payload, mcpServers, apiKey, cliPath, prepResults }) => {
run: async ({ payload, mcpServers, apiKey, cliPath, prepResults, repo }) => {
delete process.env.ANTHROPIC_API_KEY;
const prompt = addInstructions({ payload, prepResults });
const prompt = addInstructions({ payload, prepResults, repo });
console.log(prompt);
const sandboxOptions = payload.sandbox ? {
permissionMode: "default",
@@ -90575,7 +90611,7 @@ var codex = agent({
executablePath: "bin/codex.js"
});
},
run: async ({ payload, mcpServers, apiKey, cliPath, prepResults }) => {
run: async ({ payload, mcpServers, apiKey, cliPath, prepResults, repo }) => {
const tempHome = process.env.PULLFROG_TEMP_DIR;
const configDir = join5(tempHome, ".config", "codex");
mkdirSync2(configDir, { recursive: true });
@@ -90605,7 +90641,7 @@ var codex = agent({
}
);
try {
const streamedTurn = await thread.runStreamed(addInstructions({ payload, prepResults }));
const streamedTurn = await thread.runStreamed(addInstructions({ payload, prepResults, repo }));
let finalOutput2 = "";
for await (const event of streamedTurn.events) {
const handler2 = messageHandlers2[event.type];
@@ -90747,7 +90783,7 @@ var cursor = agent({
executableName: "cursor-agent"
});
},
run: async ({ payload, apiKey, cliPath, mcpServers, prepResults }) => {
run: async ({ payload, apiKey, cliPath, mcpServers, prepResults, repo }) => {
configureCursorMcpServers({ mcpServers, cliPath });
configureCursorSandbox({ sandbox: payload.sandbox ?? false });
const loggedModelCallIds = /* @__PURE__ */ new Set();
@@ -90800,7 +90836,7 @@ var cursor = agent({
}
};
try {
const fullPrompt = addInstructions({ payload, prepResults });
const fullPrompt = addInstructions({ payload, prepResults, repo });
const cursorArgs = payload.sandbox ? [
"--print",
fullPrompt,
@@ -91104,12 +91140,12 @@ var gemini = agent({
...githubInstallationToken2 && { githubInstallationToken: githubInstallationToken2 }
});
},
run: async ({ payload, apiKey, mcpServers, cliPath, prepResults }) => {
run: async ({ payload, apiKey, mcpServers, cliPath, prepResults, repo }) => {
configureGeminiMcpServers({ mcpServers, cliPath });
if (!apiKey) {
throw new Error("google_api_key or gemini_api_key is required for gemini agent");
}
const sessionPrompt = addInstructions({ payload, prepResults });
const sessionPrompt = addInstructions({ payload, prepResults, repo });
log.info(`Starting Gemini CLI with prompt: ${payload.prompt.substring(0, 100)}...`);
const args3 = payload.sandbox ? [
"--allowed-tools",
@@ -91365,13 +91401,13 @@ var opencode = agent({
installDependencies: true
});
},
run: async ({ payload, apiKey: _apiKey, apiKeys, mcpServers, cliPath, prepResults }) => {
run: async ({ payload, apiKey: _apiKey, apiKeys, mcpServers, cliPath, prepResults, repo }) => {
const tempHome = process.env.PULLFROG_TEMP_DIR;
const configDir = join7(tempHome, ".config", "opencode");
mkdirSync4(configDir, { recursive: true });
configureOpenCodeMcpServers({ mcpServers });
configureOpenCodeSandbox({ sandbox: payload.sandbox ?? false });
const prompt = addInstructions({ payload, prepResults });
const prompt = addInstructions({ payload, prepResults, repo });
const args3 = ["run", "--format", "json", prompt];
if (payload.sandbox) {
log.info("\u{1F512} sandbox mode enabled: restricting to read-only operations");
@@ -95064,7 +95100,8 @@ function buildPullfrogFooter(params) {
parts.push(`Using [${params.agent.displayName}](${params.agent.url})`);
}
if (params.workflowRun) {
const url2 = params.workflowRun.htmlUrl ?? `https://github.com/${params.workflowRun.owner}/${params.workflowRun.repo}/actions/runs/${params.workflowRun.runId}`;
const baseUrl = `https://github.com/${params.workflowRun.owner}/${params.workflowRun.repo}/actions/runs/${params.workflowRun.runId}`;
const url2 = params.workflowRun.jobId ? `${baseUrl}/job/${params.workflowRun.jobId}` : baseUrl;
parts.push(`[View workflow run](${url2})`);
}
if (params.customParts) {
@@ -123934,6 +123971,70 @@ function $(cmd, args3, options) {
return stdout.trim();
}
// mcp/checkout.ts
var CheckoutPr = type({
pull_number: type.number.describe("the pull request number to checkout")
});
function CheckoutPrTool(ctx) {
return tool({
name: "checkout_pr",
description: "Checkout a pull request branch locally. This fetches the PR branch and sets up push configuration for fork PRs. Use this when you need to work on an existing PR.",
parameters: CheckoutPr,
execute: execute(ctx, async ({ pull_number }) => {
log.info(`\u{1F500} checking out PR #${pull_number}...`);
const pr = await ctx.octokit.rest.pulls.get({
owner: ctx.owner,
repo: ctx.name,
pull_number
});
const headRepo = pr.data.head.repo;
if (!headRepo) {
throw new Error(`PR #${pull_number} source repository was deleted`);
}
const isFork = headRepo.full_name !== pr.data.base.repo.full_name;
const baseBranch = pr.data.base.ref;
const headBranch = pr.data.head.ref;
log.info(`\u{1F4E5} fetching base branch (${baseBranch})...`);
$("git", ["fetch", "--no-tags", "origin", baseBranch]);
log.info(`\u{1F33F} fetching PR #${pull_number} (${headBranch})...`);
$("git", ["fetch", "--no-tags", "origin", `pull/${pull_number}/head:${headBranch}`]);
$("git", ["checkout", headBranch]);
log.info(`\u2713 checked out PR #${pull_number}`);
if (isFork) {
const remoteName = `pr-${pull_number}`;
const forkUrl = `https://x-access-token:${ctx.githubInstallationToken}@github.com/${headRepo.full_name}.git`;
try {
$("git", ["remote", "add", remoteName, forkUrl]);
log.info(`\u{1F4CC} added remote '${remoteName}' for fork ${headRepo.full_name}`);
} catch {
$("git", ["remote", "set-url", remoteName, forkUrl]);
log.info(`\u{1F4CC} updated remote '${remoteName}' for fork ${headRepo.full_name}`);
}
$("git", ["config", `branch.${headBranch}.pushRemote`, remoteName]);
log.info(`\u{1F4CC} configured branch '${headBranch}' to push to '${remoteName}'`);
if (!pr.data.maintainer_can_modify) {
log.warning(
`\u26A0\uFE0F fork PR has maintainer_can_modify=false - push operations will fail. ask the PR author to enable "Allow edits from maintainers" or the fork may be owned by an organization.`
);
}
} else {
$("git", ["config", `branch.${headBranch}.pushRemote`, "origin"]);
}
return {
success: true,
number: pr.data.number,
title: pr.data.title,
base: baseBranch,
head: headBranch,
isFork,
maintainerCanModify: pr.data.maintainer_can_modify,
url: pr.data.html_url,
headRepo: headRepo.full_name
};
})
});
}
// mcp/debug.ts
var DebugShellCommand = type({});
var DebugShellCommandTool = tool({
@@ -124079,27 +124180,30 @@ var PushBranch = type({
branchName: type.string.describe("The branch name to push (defaults to current branch)").optional(),
force: type.boolean.describe("Force push (use with caution)").default(false)
});
function PushBranchTool(ctx) {
const remote = ctx.pushRemote;
function PushBranchTool(_ctx) {
return tool({
name: "push_branch",
description: "Push the current branch (or specified branch) to the remote repository. Never force push unless explicitly requested.",
description: "Push the current branch (or specified branch) to the remote repository. Git automatically determines the correct remote based on branch config (set by checkout_pr for fork PRs). Never force push unless explicitly requested.",
parameters: PushBranch,
execute: execute(ctx, async ({ branchName, force }) => {
execute: execute(_ctx, async ({ branchName, force }) => {
const branch = branchName || $("git", ["rev-parse", "--abbrev-ref", "HEAD"], { log: false });
const isUrl = remote.startsWith("https://");
const args3 = force ? ["push", "--force", ...isUrl ? [] : ["-u"], remote, branch] : ["push", ...isUrl ? [] : ["-u"], remote, branch];
log.info(`Pushing branch ${branch} to ${isUrl ? "(fork URL)" : remote}`);
let remote = "origin";
try {
remote = $("git", ["config", `branch.${branch}.pushRemote`], { log: false }).trim();
} catch {
}
const args3 = force ? ["push", "--force", "-u", remote, branch] : ["push", "-u", remote, branch];
log.info(`pushing branch ${branch} to ${remote}`);
if (force) {
log.warning(`Force pushing - this will overwrite remote history`);
log.warning(`force pushing - this will overwrite remote history`);
}
$("git", args3);
return {
success: true,
branch,
remote: isUrl ? "(fork URL)" : remote,
remote,
force,
message: `Successfully pushed branch ${branch}`
message: `successfully pushed branch ${branch}`
};
})
});
@@ -124325,6 +124429,19 @@ var PullRequest = type({
body: type.string.describe("the body content of the pull request"),
base: type.string.describe("the base branch to merge into (e.g., 'main')")
});
function buildPrBodyWithFooter(ctx, body) {
const repoContext = parseRepoContext();
const runId = process.env.GITHUB_RUN_ID;
const agentName = ctx.payload.agent;
const agentInfo = agentName ? agentsManifest[agentName] : null;
const footer = buildPullfrogFooter({
triggeredBy: true,
agent: agentInfo ? { displayName: agentInfo.displayName, url: agentInfo.url } : void 0,
workflowRun: runId ? { owner: repoContext.owner, repo: repoContext.name, runId } : void 0
});
const bodyWithoutFooter = stripExistingFooter(body);
return `${bodyWithoutFooter}${footer}`;
}
function PullRequestTool(ctx) {
return tool({
name: "create_pull_request",
@@ -124338,17 +124455,18 @@ function PullRequestTool(ctx) {
"PR creation blocked: secrets detected in PR title or body. Please remove any sensitive information (API keys, tokens, passwords) before creating a PR."
);
}
const diff = $("git", ["diff", `origin/${base}...HEAD`], { log: false });
const diff = $("git", ["diff", `origin/${base}..HEAD`], { log: false });
if (containsSecrets(diff)) {
throw new Error(
"PR creation blocked: secrets detected in changes. Please remove any sensitive information (API keys, tokens, passwords) before creating a PR."
);
}
const bodyWithFooter = buildPrBodyWithFooter(ctx, body);
const result = await ctx.octokit.rest.pulls.create({
owner: ctx.owner,
repo: ctx.name,
title,
body,
body: bodyWithFooter,
head: currentBranch,
base
});
@@ -124372,7 +124490,7 @@ var PullRequestInfo = type({
function PullRequestInfoTool(ctx) {
return tool({
name: "get_pull_request",
description: "Retrieve PR information (metadata only). PR branch is already checked out during setup.",
description: "Retrieve PR metadata (number, title, state, base/head branches, fork status). To checkout a PR branch locally, use checkout_pr instead.",
parameters: PullRequestInfo,
execute: execute(ctx, async ({ pull_number }) => {
const pr = await ctx.octokit.rest.pulls.get({
@@ -124417,7 +124535,9 @@ var Review = type({
),
start_line: type.number.describe("Start line for multi-line comments (optional, for commenting on ranges)").optional()
}).array().describe(
"PRIMARY location for ALL feedback. 95%+ of review content should be here. Use 'git diff origin/<base>...origin/<head>' to find correct line numbers (RIGHT side for new code, LEFT for old)."
// FORK PR NOTE: use HEAD not origin/<head> - for fork PRs, origin/<head> doesn't exist
// because the head branch is in a different repo (the fork). HEAD is the locally checked out PR branch.
"PRIMARY location for ALL feedback. 95%+ of review content should be here. Use 'git diff origin/<base>..HEAD' to find correct line numbers (RIGHT side for new code, LEFT for old). Works for both fork and same-repo PRs."
).optional()
});
function ReviewTool(ctx) {
@@ -124462,6 +124582,7 @@ function ReviewTool(ctx) {
const fixAllUrl = `${apiUrl}/trigger/${ctx.owner}/${ctx.name}/${pull_number}?action=fix&review_id=${reviewId}`;
const fixApprovedUrl = `${apiUrl}/trigger/${ctx.owner}/${ctx.name}/${pull_number}?action=fix-approved&review_id=${reviewId}`;
const footer = buildPullfrogFooter({
workflowRun: { owner: ctx.owner, repo: ctx.name, runId: ctx.runId, jobId: ctx.jobId },
customParts: [`[Fix all \u2794](${fixAllUrl})`, `[Fix \u{1F44D}s \u2794](${fixApprovedUrl})`]
});
const updatedBody = (body || "") + footer;
@@ -124695,6 +124816,7 @@ async function startMcpHttpServer(ctx) {
PullRequestTool(ctx),
ReviewTool(ctx),
PullRequestInfoTool(ctx),
CheckoutPrTool(ctx),
GetReviewCommentsTool(ctx),
ListPullRequestReviewsTool(ctx),
GetCheckSuiteLogsTool(ctx),
@@ -125328,16 +125450,16 @@ ${error42}` : `\u274C ${error42}`;
}
// utils/setup.ts
import { execSync } from "node:child_process";
import { execSync as execSync2 } from "node:child_process";
function setupGitConfig() {
const repoDir = process.cwd();
log.info("\u{1F527} Setting up git configuration...");
try {
execSync('git config --local user.email "team@pullfrog.com"', {
execSync2('git config --local user.email "team@pullfrog.com"', {
cwd: repoDir,
stdio: "pipe"
});
execSync('git config --local user.name "pullfrog"', {
execSync2('git config --local user.name "pullfrog"', {
cwd: repoDir,
stdio: "pipe"
});
@@ -125350,44 +125472,19 @@ function setupGitConfig() {
}
async function setupGit(ctx) {
const repoDir = process.cwd();
log.info("\u{1F527} Setting up git authentication...");
log.info("\u{1F527} setting up git authentication...");
try {
execSync("git config --local --unset-all http.https://github.com/.extraheader", {
execSync2("git config --local --unset-all http.https://github.com/.extraheader", {
cwd: repoDir,
stdio: "pipe"
});
log.info("\u2713 Removed existing authentication headers");
log.info("\u2713 removed existing authentication headers");
} catch {
log.debug("No existing authentication headers to remove");
log.debug("no existing authentication headers to remove");
}
const originUrl = `https://x-access-token:${ctx.githubInstallationToken}@github.com/${ctx.owner}/${ctx.name}.git`;
$("git", ["remote", "set-url", "origin", originUrl], { cwd: repoDir });
log.info("\u2713 Updated origin URL with authentication token");
if (ctx.payload.event.is_pr !== true || !ctx.payload.event.issue_number) {
return { pushRemote: "origin" };
}
const prNumber = ctx.payload.event.issue_number;
const pr = await ctx.octokit.rest.pulls.get({
owner: ctx.owner,
repo: ctx.name,
pull_number: prNumber
});
const headRepo = pr.data.head.repo;
if (!headRepo) {
throw new Error(`PR #${prNumber} source repository was deleted`);
}
const branch = pr.data.head.ref;
log.info(`\u{1F33F} Checking out PR #${prNumber} (${branch})...`);
$("git", ["fetch", "origin", `pull/${prNumber}/head:${branch}`], { cwd: repoDir });
$("git", ["checkout", branch], { cwd: repoDir });
log.info(`\u2713 Successfully checked out PR #${prNumber}`);
const token = process.env.GITHUB_TOKEN || ctx.githubInstallationToken;
const pushUrl = `https://x-access-token:${token}@github.com/${headRepo.full_name}.git`;
const isFork = headRepo.full_name !== pr.data.base.repo.full_name;
if (isFork) {
log.info(`\u{1F374} Fork PR detected, will push to: ${headRepo.full_name}`);
}
return { pushRemote: pushUrl };
log.info("\u2713 updated origin URL with authentication token");
}
// utils/timer.ts
@@ -125426,8 +125523,7 @@ async function main(inputs) {
const partialCtx = await initializeContext(inputs, payload);
const ctx = partialCtx;
timer.checkpoint("initializeContext");
const { pushRemote } = await setupGit(ctx);
ctx.pushRemote = pushRemote;
await setupGit(ctx);
timer.checkpoint("setupGit");
await setupTempDirectory(ctx);
timer.checkpoint("setupTempDirectory");
@@ -125636,11 +125732,26 @@ function parsePayload(inputs) {
}
async function startMcpServer(ctx) {
const runId = process.env.GITHUB_RUN_ID;
if (runId) {
const workflowRunInfo = await fetchWorkflowRunInfo(runId);
if (workflowRunInfo.progressCommentId) {
process.env.PULLFROG_PROGRESS_COMMENT_ID = workflowRunInfo.progressCommentId;
log.info(`\u{1F4DD} Using pre-created progress comment: ${workflowRunInfo.progressCommentId}`);
if (!runId) {
throw new Error("GITHUB_RUN_ID environment variable is required");
}
ctx.runId = runId;
const workflowRunInfo = await fetchWorkflowRunInfo(ctx.runId);
if (workflowRunInfo.progressCommentId) {
process.env.PULLFROG_PROGRESS_COMMENT_ID = workflowRunInfo.progressCommentId;
log.info(`\u{1F4DD} Using pre-created progress comment: ${workflowRunInfo.progressCommentId}`);
}
const jobName = process.env.GITHUB_JOB;
if (jobName) {
const jobs = await ctx.octokit.rest.actions.listJobsForWorkflowRun({
owner: ctx.owner,
repo: ctx.name,
run_id: parseInt(ctx.runId, 10)
});
const matchingJob = jobs.data.jobs.find((job) => job.name === jobName);
if (matchingJob) {
ctx.jobId = String(matchingJob.id);
log.info(`\u{1F4CB} Found job ID: ${ctx.jobId}`);
}
}
const { url: url2, close } = await startMcpHttpServer(ctx);
@@ -125695,7 +125806,12 @@ ${encode(eventWithoutContext)}`;
apiKey: ctx.apiKey,
apiKeys: ctx.apiKeys,
cliPath: ctx.cliPath,
prepResults: ctx.prepResults
prepResults: ctx.prepResults,
repo: {
owner: ctx.owner,
name: ctx.name,
defaultBranch: ctx.repo.default_branch
}
});
}
async function handleAgentResult(result) {