Clarify push, prepush, and progress errors in agent prompts (#521)

This commit is contained in:
David Blass
2026-04-06 20:47:43 +00:00
committed by pullfrog[bot]
parent ab3e339db0
commit 1c730300b6
6 changed files with 59 additions and 34 deletions
+26 -17
View File
@@ -144777,11 +144777,17 @@ var package_default = {
types: "./dist/index.d.cts",
exports: {
".": {
"@pullfrog/source": "./index.ts",
types: "./dist/index.d.cts",
import: "./dist/index.js",
require: "./dist/index.cjs"
},
"./internal": "./dist/internal.js",
"./internal": {
"@pullfrog/source": "./internal/index.ts",
types: "./dist/internal.d.cts",
import: "./dist/internal.js",
default: "./dist/internal.js"
},
"./package.json": "./package.json"
},
packageManager: "pnpm@10.27.0+sha512.72d699da16b1179c14ba9e64dc71c9a40988cbdc65c264cb0e489db7de917f20dcf4d64d8723625f2969ba52d4b7e2a1170682d9ac2a5dcaeaab732b7e16f04a"
@@ -146741,7 +146747,7 @@ function PushBranchTool(ctx) {
const pushPermission = ctx.payload.push;
return tool({
name: "push_branch",
description: "Push the current branch to the remote repository. Omit branchName to push the current branch (recommended). If specifying branchName, use the LOCAL branch name (e.g., 'pr-1'), not the remote branch name. The correct remote and remote branch are determined automatically from branch config set by checkout_pr. Never force push unless explicitly requested. Pushes to the default branch are blocked in restricted mode.",
description: "Push the current branch to the remote repository. Omit branchName to push the current branch (recommended). If specifying branchName, use the LOCAL branch name (e.g., 'pr-1'), not the remote branch name. The correct remote and remote branch are determined automatically from branch config set by checkout_pr. Requires a clean working tree. Runs the repository prepush hook (if configured) before the network push \u2014 hook failure means tests/lint or similar in that script failed, not necessarily a Pullfrog timeout. Never force push unless explicitly requested. Pushes to the default branch are blocked in restricted mode.",
parameters: PushBranch,
execute: execute(async ({ branchName, force }) => {
if (pushPermission === "disabled") {
@@ -146751,7 +146757,7 @@ function PushBranchTool(ctx) {
const status = $("git", ["status", "--porcelain"], { log: false });
if (status) {
throw new Error(
`push blocked: working tree has uncommitted changes. commit or discard them before pushing.
`push blocked: working tree is not clean (tracked changes and/or untracked files). commit, discard, or remove stray artifacts before pushing.
git status:
${status}`
@@ -148785,9 +148791,9 @@ function computeModes(agentId) {
- commit locally via shell (\`git add . && git commit -m "..."\`)
5. **finalize**:
- push the branch via \`${t("push_branch")}\`
- confirm a clean working tree, then push via \`${t("push_branch")}\` (see *SYSTEM* Git rules if this fails \u2014 prepush errors are usually the repo's tests/lint, not infra timeouts)
- create a PR via \`${t("create_pull_request")}\`
- call \`${t("report_progress")}\` with the final summary including PR link
- call \`${t("report_progress")}\` with the PR link or the exact error if push/PR failed
${learningsStep(t, 6)}
@@ -148814,10 +148820,10 @@ For simple, well-defined tasks, skip the plan phase and go straight to build.`
- commit locally via shell (\`git add . && git commit -m "..."\`)
5. Finalize:
- push changes via \`${t("push_branch")}\`
- confirm a clean working tree, then push via \`${t("push_branch")}\` (same push/prepush guidance as Build mode in *SYSTEM*)
- reply to each comment using \`${t("reply_to_review_comment")}\`
- resolve addressed threads via \`${t("resolve_review_thread")}\`
- call \`${t("report_progress")}\` with a brief summary
- call \`${t("report_progress")}\` with a brief summary (or the exact push error if push failed)
${learningsStep(t, 6)}`
},
@@ -148923,8 +148929,8 @@ ${learningsStep(t, 4)}`
- commit locally via shell (\`git add . && git commit -m "..."\`)
5. Finalize:
- push changes via \`${t("push_branch")}\`
- call \`${t("report_progress")}\` with the diagnosis and fix summary
- confirm a clean working tree, then push via \`${t("push_branch")}\` (same push/prepush guidance as Build mode in *SYSTEM*)
- call \`${t("report_progress")}\` with the diagnosis and fix summary (or the exact push error if push failed)
${learningsStep(t, 6)}`
},
@@ -148940,8 +148946,8 @@ ${learningsStep(t, 6)}`
2. **Merge Attempt**:
- Run \`git merge origin/<base_branch>\` via shell.
- If it succeeds automatically, push via \`${t("push_branch")}\` and report success.
- If it fails (conflicts), resolve them manually.
- If it succeeds automatically, confirm a clean working tree, push via \`${t("push_branch")}\` (same push/prepush guidance as Build mode in *SYSTEM*), and call \`${t("report_progress")}\` with a brief success note or the exact push error if push failed \u2014 **then stop; do not run steps 3\u20134.**
- If it fails (conflicts), resolve them manually (continue to steps 3\u20134).
3. **Resolve Conflicts**:
- Run \`git status\` or parse the merge output to find the list of conflicting files.
@@ -148951,8 +148957,8 @@ ${learningsStep(t, 6)}`
4. **Finalize**:
- Run a final verification (build/test) to ensure the resolution works.
- \`git add . && git commit -m "resolve merge conflicts"\`
- Push via \`${t("push_branch")}\`
- Call \`${t("report_progress")}\` with a summary of what was resolved`
- confirm a clean working tree, then push via \`${t("push_branch")}\` (same push/prepush guidance as Build mode in *SYSTEM*)
- Call \`${t("report_progress")}\` with a summary of what was resolved (or the exact push error if push failed)`
},
{
name: "Task",
@@ -148968,8 +148974,8 @@ ${learningsStep(t, 6)}`
- if code changes are needed: review your own diff before committing \u2014 verify only intended changes are present, no debug artifacts remain, and the changes are clean enough that a senior engineer would approve without hesitation
3. Finalize:
- if code changes were made, push all changes to a pull request (new or existing). \`git status\` must be clean before you finish.
- call \`${t("report_progress")}\` with results
- if code changes were made, push to a pull request (new or existing) using \`${t("push_branch")}\` and \`${t("create_pull_request")}\` as needed. \`git status\` must be clean before you finish (see *SYSTEM* Git rules if push fails).
- call \`${t("report_progress")}\` once with results \u2014 include exact tool errors if push or PR creation failed
- if the task involved labeling, commenting, or other GitHub operations, perform those directly
${learningsStep(t, 4)}`
@@ -150534,6 +150540,9 @@ Rules:
- Do not attempt to configure git credentials manually \u2014 the ${pullfrogMcpName} server handles all authentication internally.
- Never push commits directly to the default branch or any protected branch (commonly: main, master, production, develop, staging). Always create a feature branch following the pattern: \`pullfrog/<issue-number>-<kebab-case-description>\` (e.g., \`pullfrog/123-fix-login-bug\`).
- Never add co-author trailers (e.g., "Co-authored-by" or "Co-Authored-By") to commit messages.
- Untracked files from tests or tooling (e.g. \`coverage/\`) often remain *after* your last commit and still block \`${t("push_branch")}\` \u2014 delete them, extend \`.gitignore\`, or only add files that truly belong in the repo.
- \`${t("push_branch")}\` runs the repository's optional **prepush** hook before the network push. If the error includes \`lifecycle hook 'prepush' failed\` (with an exit code and script output after it), the hook script exited non-zero (commonly tests or lint). Fix that or change the hook \u2014 do not describe it as an infrastructure "timeout" unless the tool output or logs clearly show a timeout.
- If push or PR creation fails, \`${t("report_progress")}\` must summarize using the **actual** error from the tool. Do not substitute vague causes unless they match what failed.
### GitHub
@@ -150549,7 +150558,7 @@ ${getStandaloneModeInstructions(ctx.payload.event.trigger, t, ctx.outputSchema)}
### Efficiency
Trust the tools \u2014 do not repeatedly verify file contents or git status after operations. If a tool reports success, proceed to the next step. Only verify if you encounter an actual error.
Trust the tools \u2014 do not repeatedly verify file contents or git status after operations. If a tool reports success, proceed to the next step. Only verify if you encounter an actual error. Exception: right before \`${t("push_branch")}\`, ensure the working tree is clean \u2014 that tool rejects dirty trees, and tests you ran earlier often leave untracked output.
### Command execution
@@ -150563,7 +150572,7 @@ When posting comments via ${pullfrogMcpName}, write as a professional team membe
**Task list**: at the start of every run, create an internal task list based on the steps in your current mode. Update it as you complete each step. The system automatically renders this list to the progress comment \u2014 you do not need to call \`report_progress\` for this.
**\`report_progress\`**: call this exactly once at the end of every run with a brief final summary (1-3 sentences) unless the mode guidance instructs otherwise. Never call it for intermediate status updates (e.g., "Checking for changes...", "Starting review...") \u2014 the task list handles live progress automatically. Calling \`report_progress\` replaces the task list with your summary and preserves the current task list in a collapsible section. Keep the summary concise \u2014 do not repeat what the task list already shows. Focus on the outcome (what was accomplished, links to artifacts) rather than listing individual steps.
**\`report_progress\`**: call this exactly once at the end of every run with a brief final summary (1-3 sentences) unless the mode guidance instructs otherwise. Never call it for intermediate status updates (e.g., "Checking for changes...", "Starting review...") \u2014 the task list handles live progress automatically. Calling \`report_progress\` replaces the task list with your summary and preserves the current task list in a collapsible section. Keep the summary concise \u2014 do not repeat what the task list already shows. Focus on the outcome (what was accomplished, links to artifacts) rather than listing individual steps. If something failed, include the tool's error text even when that makes the summary longer.
Never use \`create_issue_comment\` for task progress \u2014 that creates duplicate comments and leaves the progress comment stuck in its initial state. \`create_issue_comment\` is only for standalone comments unrelated to your current task (e.g., Plan comments, PR Summary comments).
+2 -1
View File
@@ -96,6 +96,7 @@ export function PushBranchTool(ctx: ToolContext) {
"Push the current branch to the remote repository. Omit branchName to push the current branch (recommended). " +
"If specifying branchName, use the LOCAL branch name (e.g., 'pr-1'), not the remote branch name. " +
"The correct remote and remote branch are determined automatically from branch config set by checkout_pr. " +
"Requires a clean working tree. Runs the repository prepush hook (if configured) before the network push — hook failure means tests/lint or similar in that script failed, not necessarily a Pullfrog timeout. " +
"Never force push unless explicitly requested. Pushes to the default branch are blocked in restricted mode.",
parameters: PushBranch,
execute: execute(async ({ branchName, force }) => {
@@ -110,7 +111,7 @@ export function PushBranchTool(ctx: ToolContext) {
const status = $("git", ["status", "--porcelain"], { log: false });
if (status) {
throw new Error(
`push blocked: working tree has uncommitted changes. commit or discard them before pushing.\n\n` +
`push blocked: working tree is not clean (tracked changes and/or untracked files). commit, discard, or remove stray artifacts before pushing.\n\n` +
`git status:\n${status}`
);
}
+12 -12
View File
@@ -38,9 +38,9 @@ export function computeModes(agentId: AgentId): Mode[] {
- commit locally via shell (\`git add . && git commit -m "..."\`)
5. **finalize**:
- push the branch via \`${t("push_branch")}\`
- confirm a clean working tree, then push via \`${t("push_branch")}\` (see *SYSTEM* Git rules if this fails — prepush errors are usually the repo's tests/lint, not infra timeouts)
- create a PR via \`${t("create_pull_request")}\`
- call \`${t("report_progress")}\` with the final summary including PR link
- call \`${t("report_progress")}\` with the PR link or the exact error if push/PR failed
${learningsStep(t, 6)}
@@ -68,10 +68,10 @@ For simple, well-defined tasks, skip the plan phase and go straight to build.`,
- commit locally via shell (\`git add . && git commit -m "..."\`)
5. Finalize:
- push changes via \`${t("push_branch")}\`
- confirm a clean working tree, then push via \`${t("push_branch")}\` (same push/prepush guidance as Build mode in *SYSTEM*)
- reply to each comment using \`${t("reply_to_review_comment")}\`
- resolve addressed threads via \`${t("resolve_review_thread")}\`
- call \`${t("report_progress")}\` with a brief summary
- call \`${t("report_progress")}\` with a brief summary (or the exact push error if push failed)
${learningsStep(t, 6)}`,
},
@@ -181,8 +181,8 @@ ${learningsStep(t, 4)}`,
- commit locally via shell (\`git add . && git commit -m "..."\`)
5. Finalize:
- push changes via \`${t("push_branch")}\`
- call \`${t("report_progress")}\` with the diagnosis and fix summary
- confirm a clean working tree, then push via \`${t("push_branch")}\` (same push/prepush guidance as Build mode in *SYSTEM*)
- call \`${t("report_progress")}\` with the diagnosis and fix summary (or the exact push error if push failed)
${learningsStep(t, 6)}`,
},
@@ -198,8 +198,8 @@ ${learningsStep(t, 6)}`,
2. **Merge Attempt**:
- Run \`git merge origin/<base_branch>\` via shell.
- If it succeeds automatically, push via \`${t("push_branch")}\` and report success.
- If it fails (conflicts), resolve them manually.
- If it succeeds automatically, confirm a clean working tree, push via \`${t("push_branch")}\` (same push/prepush guidance as Build mode in *SYSTEM*), and call \`${t("report_progress")}\` with a brief success note or the exact push error if push failed — **then stop; do not run steps 34.**
- If it fails (conflicts), resolve them manually (continue to steps 34).
3. **Resolve Conflicts**:
- Run \`git status\` or parse the merge output to find the list of conflicting files.
@@ -209,8 +209,8 @@ ${learningsStep(t, 6)}`,
4. **Finalize**:
- Run a final verification (build/test) to ensure the resolution works.
- \`git add . && git commit -m "resolve merge conflicts"\`
- Push via \`${t("push_branch")}\`
- Call \`${t("report_progress")}\` with a summary of what was resolved`,
- confirm a clean working tree, then push via \`${t("push_branch")}\` (same push/prepush guidance as Build mode in *SYSTEM*)
- Call \`${t("report_progress")}\` with a summary of what was resolved (or the exact push error if push failed)`,
},
{
name: "Task",
@@ -227,8 +227,8 @@ ${learningsStep(t, 6)}`,
- if code changes are needed: review your own diff before committing — verify only intended changes are present, no debug artifacts remain, and the changes are clean enough that a senior engineer would approve without hesitation
3. Finalize:
- if code changes were made, push all changes to a pull request (new or existing). \`git status\` must be clean before you finish.
- call \`${t("report_progress")}\` with results
- if code changes were made, push to a pull request (new or existing) using \`${t("push_branch")}\` and \`${t("create_pull_request")}\` as needed. \`git status\` must be clean before you finish (see *SYSTEM* Git rules if push fails).
- call \`${t("report_progress")}\` once with results — include exact tool errors if push or PR creation failed
- if the task involved labeling, commenting, or other GitHub operations, perform those directly
${learningsStep(t, 4)}`,
+7 -1
View File
@@ -83,11 +83,17 @@
"types": "./dist/index.d.cts",
"exports": {
".": {
"@pullfrog/source": "./index.ts",
"types": "./dist/index.d.cts",
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
"./internal": "./dist/internal.js",
"./internal": {
"@pullfrog/source": "./internal/index.ts",
"types": "./dist/internal.d.cts",
"import": "./dist/internal.js",
"default": "./dist/internal.js"
},
"./package.json": "./package.json"
},
"packageManager": "pnpm@10.27.0+sha512.72d699da16b1179c14ba9e64dc71c9a40988cbdc65c264cb0e489db7de917f20dcf4d64d8723625f2969ba52d4b7e2a1170682d9ac2a5dcaeaab732b7e16f04a"
+7 -1
View File
@@ -41642,11 +41642,17 @@ var package_default = {
types: "./dist/index.d.cts",
exports: {
".": {
"@pullfrog/source": "./index.ts",
types: "./dist/index.d.cts",
import: "./dist/index.js",
require: "./dist/index.cjs"
},
"./internal": "./dist/internal.js",
"./internal": {
"@pullfrog/source": "./internal/index.ts",
types: "./dist/internal.d.cts",
import: "./dist/internal.js",
default: "./dist/internal.js"
},
"./package.json": "./package.json"
},
packageManager: "pnpm@10.27.0+sha512.72d699da16b1179c14ba9e64dc71c9a40988cbdc65c264cb0e489db7de917f20dcf4d64d8723625f2969ba52d4b7e2a1170682d9ac2a5dcaeaab732b7e16f04a"
+5 -2
View File
@@ -252,6 +252,9 @@ Rules:
- Do not attempt to configure git credentials manually — the ${pullfrogMcpName} server handles all authentication internally.
- Never push commits directly to the default branch or any protected branch (commonly: main, master, production, develop, staging). Always create a feature branch following the pattern: \`pullfrog/<issue-number>-<kebab-case-description>\` (e.g., \`pullfrog/123-fix-login-bug\`).
- Never add co-author trailers (e.g., "Co-authored-by" or "Co-Authored-By") to commit messages.
- Untracked files from tests or tooling (e.g. \`coverage/\`) often remain *after* your last commit and still block \`${t("push_branch")}\` — delete them, extend \`.gitignore\`, or only add files that truly belong in the repo.
- \`${t("push_branch")}\` runs the repository's optional **prepush** hook before the network push. If the error includes \`lifecycle hook 'prepush' failed\` (with an exit code and script output after it), the hook script exited non-zero (commonly tests or lint). Fix that or change the hook — do not describe it as an infrastructure "timeout" unless the tool output or logs clearly show a timeout.
- If push or PR creation fails, \`${t("report_progress")}\` must summarize using the **actual** error from the tool. Do not substitute vague causes unless they match what failed.
### GitHub
@@ -267,7 +270,7 @@ ${getStandaloneModeInstructions(ctx.payload.event.trigger, t, ctx.outputSchema)}
### Efficiency
Trust the tools — do not repeatedly verify file contents or git status after operations. If a tool reports success, proceed to the next step. Only verify if you encounter an actual error.
Trust the tools — do not repeatedly verify file contents or git status after operations. If a tool reports success, proceed to the next step. Only verify if you encounter an actual error. Exception: right before \`${t("push_branch")}\`, ensure the working tree is clean — that tool rejects dirty trees, and tests you ran earlier often leave untracked output.
### Command execution
@@ -281,7 +284,7 @@ When posting comments via ${pullfrogMcpName}, write as a professional team membe
**Task list**: at the start of every run, create an internal task list based on the steps in your current mode. Update it as you complete each step. The system automatically renders this list to the progress comment — you do not need to call \`report_progress\` for this.
**\`report_progress\`**: call this exactly once at the end of every run with a brief final summary (1-3 sentences) unless the mode guidance instructs otherwise. Never call it for intermediate status updates (e.g., "Checking for changes...", "Starting review...") — the task list handles live progress automatically. Calling \`report_progress\` replaces the task list with your summary and preserves the current task list in a collapsible section. Keep the summary concise — do not repeat what the task list already shows. Focus on the outcome (what was accomplished, links to artifacts) rather than listing individual steps.
**\`report_progress\`**: call this exactly once at the end of every run with a brief final summary (1-3 sentences) unless the mode guidance instructs otherwise. Never call it for intermediate status updates (e.g., "Checking for changes...", "Starting review...") — the task list handles live progress automatically. Calling \`report_progress\` replaces the task list with your summary and preserves the current task list in a collapsible section. Keep the summary concise — do not repeat what the task list already shows. Focus on the outcome (what was accomplished, links to artifacts) rather than listing individual steps. If something failed, include the tool's error text even when that makes the summary longer.
Never use \`create_issue_comment\` for task progress — that creates duplicate comments and leaves the progress comment stuck in its initial state. \`create_issue_comment\` is only for standalone comments unrelated to your current task (e.g., Plan comments, PR Summary comments).