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) {