diff --git a/agents/instructions.ts b/agents/instructions.ts index 83cabdf..d97da94 100644 --- a/agents/instructions.ts +++ b/agents/instructions.ts @@ -17,6 +17,7 @@ You adapt your writing style to the style of your coworkers, while never being u You run in a non-interactive environment: complete tasks autonomously without asking follow-up questions. You make reasonable assumptions when details are missing, but fail with an explicit error if critical information is missing (e.g. user asks to review a PR but does not provide a link or ID). Never push commits directly to protected branches: main, master, production. Always create a feature branch. All created branches must be prefixed with "pullfrog/" and have VERY specific names in order to avoid collisions. +Never add co-author trailers (e.g., "Co-authored-by" or "Co-Authored-By") to commit messages. Commits should only include the commit message itself, without any co-author attribution. ## SECURITY diff --git a/fixtures/basic.txt b/fixtures/basic.txt index 789260c..117d20a 100644 --- a/fixtures/basic.txt +++ b/fixtures/basic.txt @@ -1 +1,3 @@ -create a comment on https://github.com/pullfrogai/scratch/pull/29 that says ribbit \ No newline at end of file +Print the MCP tools available to you. +Try to call select_mode with the name "Plan". +Then tell me a joke \ No newline at end of file diff --git a/mcp/comment.ts b/mcp/comment.ts index 45f82ac..3cc630e 100644 --- a/mcp/comment.ts +++ b/mcp/comment.ts @@ -4,6 +4,8 @@ import { agentsManifest } from "../external.ts"; import { parseRepoContext } from "../utils/github.ts"; import { contextualize, tool } from "./shared.ts"; +const PULLFROG_DIVIDER = ""; + function buildCommentFooter(payload: Payload): string { const repoContext = parseRepoContext(); const runId = process.env.GITHUB_RUN_ID; @@ -19,10 +21,24 @@ function buildCommentFooter(payload: Payload): string { : `https://github.com/${repoContext.owner}/${repoContext.name}`; return ` - +${PULLFROG_DIVIDER} --- -Triggered by [Pullfrog](https://pullfrog.ai) | Using [${agentDisplayName}](${agentUrl}) | [View workflow run](${workflowRunUrl}) | [𝕏](https://x.com/pullfrogai)`; +🐸 Triggered by [Pullfrog](https://pullfrog.ai) | 🤖 [${agentDisplayName}](${agentUrl}) | [View workflow run](${workflowRunUrl}) | [𝕏](https://x.com/pullfrogai)`; +} + +function stripExistingFooter(body: string): string { + const dividerIndex = body.indexOf(PULLFROG_DIVIDER); + if (dividerIndex === -1) { + return body; + } + return body.substring(0, dividerIndex).trimEnd(); +} + +function addFooter(body: string, payload: Payload): string { + const bodyWithoutFooter = stripExistingFooter(body); + const footer = buildCommentFooter(payload); + return `${bodyWithoutFooter}${footer}`; } export const Comment = type({ @@ -35,11 +51,13 @@ export const CreateCommentTool = tool({ description: "Create a comment on a GitHub issue", parameters: Comment, execute: contextualize(async ({ issueNumber, body }, ctx) => { + const bodyWithFooter = addFooter(body, ctx.payload); + const result = await ctx.octokit.rest.issues.createComment({ owner: ctx.owner, repo: ctx.name, issue_number: issueNumber, - body: body, + body: bodyWithFooter, }); return { @@ -61,11 +79,13 @@ export const EditCommentTool = tool({ description: "Edit a GitHub issue comment by its ID", parameters: EditComment, execute: contextualize(async ({ commentId, body }, ctx) => { + const bodyWithFooter = addFooter(body, ctx.payload); + const result = await ctx.octokit.rest.issues.updateComment({ owner: ctx.owner, repo: ctx.name, comment_id: commentId, - body: body, + body: bodyWithFooter, }); return { @@ -97,14 +117,14 @@ export const CreateWorkingCommentTool = tool({ throw new Error("create_working_comment may not be called multiple times"); } - const footer = buildCommentFooter(ctx.payload); - const body = `${intent} ${footer}`; + const body = `${intent} `; + const bodyWithFooter = addFooter(body, ctx.payload); const result = await ctx.octokit.rest.issues.createComment({ owner: ctx.owner, repo: ctx.name, issue_number: issueNumber, - body, + body: bodyWithFooter, }); workingCommentId = result.data.id; @@ -131,8 +151,7 @@ export const UpdateWorkingCommentTool = tool({ throw new Error("create_working_comment must be called before update_working_comment"); } - const footer = buildCommentFooter(ctx.payload); - const bodyWithFooter = `${body}${footer}`; + const bodyWithFooter = addFooter(body, ctx.payload); const result = await ctx.octokit.rest.issues.updateComment({ owner: ctx.owner, diff --git a/play.ts b/play.ts index 7926fe0..3d12db4 100644 --- a/play.ts +++ b/play.ts @@ -12,6 +12,7 @@ import { log } from "./utils/cli.ts"; import { setupTestRepo } from "./utils/setup.ts"; config(); +config({ path: join(process.cwd(), "../.env") }); export async function run(prompt: string): Promise { try { @@ -26,7 +27,7 @@ export async function run(prompt: string): Promise { // we don't need to extract it here since main() will parse the payload const inputs: Required = { prompt, - defaultAgent: undefined, + defaultAgent: "cursor", ...flatMorph(agents, (_, agent) => agent.apiKeyNames.map((inputKey) => [inputKey, process.env[inputKey.toUpperCase()]]) ), diff --git a/utils/api.ts b/utils/api.ts index b9b95f5..cd6c7ff 100644 --- a/utils/api.ts +++ b/utils/api.ts @@ -36,9 +36,7 @@ export async function fetchRepoSettings({ token: string; repoContext: RepoContext; }): Promise { - log.info("Fetching repository settings..."); const settings = await getRepoSettings(token, repoContext); - log.info("Repository settings fetched"); return settings; } diff --git a/utils/setup.ts b/utils/setup.ts index 985d38a..fd332a9 100644 --- a/utils/setup.ts +++ b/utils/setup.ts @@ -98,12 +98,6 @@ export function setupGitAuth(githubToken: string, repoContext: RepoContext): voi * Automatically checks out the appropriate branch before agent execution */ export function setupGitBranch(payload: Payload): void { - // Only set up git branch in GitHub Actions environment - // In local testing, this might interfere with local git state - if (!process.env.GITHUB_ACTIONS) { - return; - } - const branch = payload.event.branch; if (!branch) {