fix(router): make automerge comments fish friendly
This commit is contained in:
parent
99866c84da
commit
6c1fe749a3
@ -194,9 +194,9 @@ export function renderResponse(command, dispatched) {
|
||||
if (command.intent === "stop") {
|
||||
return [
|
||||
marker,
|
||||
"Got it. Clownfish will leave this item for human review.",
|
||||
"Got it. Clownfish is floating this back to human review. 🐠",
|
||||
"",
|
||||
"I kept the regular `clownfish` label on it and paused the automation trail until a maintainer asks again.",
|
||||
"I kept the regular `clownfish` label on it and paused the automation current until a maintainer calls me back in.",
|
||||
].join("\n");
|
||||
}
|
||||
if (command.intent === "automerge") {
|
||||
@ -204,14 +204,14 @@ export function renderResponse(command, dispatched) {
|
||||
return [
|
||||
marker,
|
||||
dispatched?.clawsweeper
|
||||
? "Clownfish automerge is enabled for this PR."
|
||||
: "Clownfish could not enable automerge for this PR.",
|
||||
? "Clownfish is on the reef for this PR. 🐠"
|
||||
: "Clownfish could not catch the automerge current for this PR.",
|
||||
"",
|
||||
dispatched?.clawsweeper
|
||||
? `I ${clearedHumanReview ? "cleared `clownfish:human-review`, " : ""}added \`clownfish:automerge\` and asked ClawSweeper to review this head. If ClawSweeper requests changes or returns \`needs-human\`, I will repair/rebase the branch and ask for another review, up to the configured round limit.`
|
||||
? `I ${clearedHumanReview ? "cleared \`clownfish:human-review\`, " : ""}tagged \`clownfish:automerge\` and sent ClawSweeper over this exact head. If the sweep finds rough coral, failing checks, or \`needs-human\`, I will take another bounded repair lap and ask for a fresh review.`
|
||||
: `Reason: ${command.reason ?? "automerge requires a pull request"}.`,
|
||||
"",
|
||||
"A maintainer can pause this with `/clownfish stop`.",
|
||||
"A maintainer can call `/clownfish stop` any time and I will drift this back to human review.",
|
||||
].join("\n");
|
||||
}
|
||||
if (command.intent === "autoclose") {
|
||||
@ -242,23 +242,23 @@ export function renderResponse(command, dispatched) {
|
||||
return [
|
||||
marker,
|
||||
fromNeedsHuman
|
||||
? "Thanks, ClawSweeper. Clownfish is continuing the automerge repair loop for this PR."
|
||||
: "Thanks, ClawSweeper. Clownfish picked up the repair feedback.",
|
||||
? "Thanks, ClawSweeper. Clownfish is swimming another guarded repair lap for this PR. 🐠"
|
||||
: "Thanks, ClawSweeper. Clownfish picked up the reef notes and is starting a guarded repair pass. 🐠",
|
||||
"",
|
||||
`Source: \`${command.trusted_bot_author ?? command.author ?? "trusted automation"}\``,
|
||||
`Feedback: ${command.repair_reason ?? "ClawSweeper requested another repair pass."}`,
|
||||
`Action: dispatched \`${dispatched.workflow}\` for \`${dispatched.job_path}\` in \`${dispatched.mode}\` mode.`,
|
||||
`Model: \`${dispatched.model}\``,
|
||||
"",
|
||||
"I will update this PR branch, or open a safe credited replacement, if the repair worker finds a narrow fix.",
|
||||
"I will update this PR branch when I can. If GitHub branch permissions block that swim lane, I will open a safe credited replacement instead and keep it narrow.",
|
||||
].join("\n");
|
||||
}
|
||||
if (command.intent === "clawsweeper_auto_merge") {
|
||||
return [
|
||||
marker,
|
||||
dispatched?.merge?.status === "executed"
|
||||
? "Thanks, ClawSweeper. Clownfish merged this PR after the passing review."
|
||||
: "Thanks, ClawSweeper. Clownfish saw the passing review, but did not merge yet.",
|
||||
? "Thanks, ClawSweeper. Clear water: Clownfish merged this PR after the passing review. 🐠"
|
||||
: "Thanks, ClawSweeper. Clownfish saw the passing review, but one reef gate still blocked the merge.",
|
||||
"",
|
||||
`Source: \`${command.trusted_bot_author ?? command.author ?? "trusted automation"}\``,
|
||||
`Feedback: ${command.repair_reason ?? "ClawSweeper reported a passing review."}`,
|
||||
@ -266,36 +266,36 @@ export function renderResponse(command, dispatched) {
|
||||
...(dispatched?.merge?.merged_at ? [`Merged at: ${dispatched.merge.merged_at}`] : []),
|
||||
"",
|
||||
dispatched?.merge?.status === "executed"
|
||||
? "The automerge loop is complete."
|
||||
: "I left the PR open for the remaining gate instead of bypassing it.",
|
||||
? "Automerge lap complete. no mystery bubbles."
|
||||
: "I left the PR open for the remaining gate instead of cutting around it.",
|
||||
].join("\n");
|
||||
}
|
||||
if (command.intent === "clawsweeper_needs_human") {
|
||||
return [
|
||||
marker,
|
||||
"Clownfish is pausing automerge for human review.",
|
||||
"Clownfish is floating this PR back to human review. 🐠",
|
||||
"",
|
||||
`Source: \`${command.trusted_bot_author ?? command.author ?? "trusted automation"}\``,
|
||||
`Reason: ${command.repair_reason ?? "ClawSweeper requested human review."}`,
|
||||
"",
|
||||
"I kept the regular `clownfish` label on it and left the final call with a maintainer.",
|
||||
"I kept the regular `clownfish` label on it and left the final call with a maintainer. no sneaky merge currents.",
|
||||
].join("\n");
|
||||
}
|
||||
if (!dispatched) {
|
||||
return [
|
||||
marker,
|
||||
"Clownfish did not dispatch a repair worker for this one.",
|
||||
"Clownfish did not send a repair worker into this current.",
|
||||
"",
|
||||
`Reason: ${command.reason ?? "unsupported command or target"}.`,
|
||||
"",
|
||||
"Supported repair commands work on existing Clownfish PRs and PRs opted into `clownfish:automerge`: `/clownfish fix ci`, `/clownfish address review`, `/clownfish rebase`.",
|
||||
"A maintainer can opt a PR in with `/clownfish automerge` and I can take another pass.",
|
||||
"A maintainer can opt a PR in with `/clownfish automerge`, and I can take another guarded swim.",
|
||||
"A maintainer can close unsupported or declined work with `/autoclose <reason>`.",
|
||||
].join("\n");
|
||||
}
|
||||
return [
|
||||
marker,
|
||||
"Clownfish picked this up.",
|
||||
"Clownfish picked this up and is swimming it through the narrow lane. 🐠",
|
||||
"",
|
||||
`Command: \`${command.command}\``,
|
||||
`Action: dispatched \`${dispatched.workflow}\` for \`${dispatched.job_path}\` in \`${dispatched.mode}\` mode.`,
|
||||
|
||||
@ -72,6 +72,22 @@ const sourceStaysOpenLines = [
|
||||
"This PR stays open for now, with the replacement linked as the current fix path.",
|
||||
];
|
||||
|
||||
const automergeNoChangeOpeners = [
|
||||
"This repair lap finished without changing the PR. Clownfish checked the reef and found no safe patch to push this time.",
|
||||
"Clownfish finished this automerge repair swim without changing the branch.",
|
||||
"No new branch changes from this lap. Clownfish kept the current tidy instead of splashing around.",
|
||||
"This pass ended as a no-op: no narrow repair surfaced, so Clownfish left the branch untouched.",
|
||||
"Clownfish took another look and did not find a safe branch change to make on this pass.",
|
||||
];
|
||||
|
||||
const automergeNoChangeClosers = [
|
||||
"No branch push, rebase, replacement PR, merge, or ClawSweeper re-review was started on this lap.",
|
||||
"No push, rebase, replacement PR, merge, or ClawSweeper re-review happened this swim.",
|
||||
"Clownfish left the PR as-is: no push, no rebase, no replacement PR, no merge, and no fresh ClawSweeper pass.",
|
||||
"Nothing moved downstream from this pass: no branch update, replacement PR, merge, or re-review.",
|
||||
"This lap stayed observational only. no branch push, no replacement, no merge, no mystery bubbles.",
|
||||
];
|
||||
|
||||
const carriedCreditLines = [
|
||||
"Contributor credit is carried into the replacement PR body and changelog plan.",
|
||||
"Contributor credit is copied into the replacement PR notes and changelog path.",
|
||||
@ -185,9 +201,9 @@ export function repairContributorBranchComment({ sourcePrUrl, validationCommands
|
||||
export function automergeRepairOutcomeComment({ marker, result, report, target, provenance }) {
|
||||
const lines = [
|
||||
marker,
|
||||
`${SIGNATURE} automerge status`,
|
||||
`${SIGNATURE} reef automerge status`,
|
||||
"",
|
||||
"Repair pass finished without changing this PR.",
|
||||
variant(automergeNoChangeOpeners),
|
||||
"",
|
||||
`Target: #${target}`,
|
||||
`Executor outcome: ${compactForComment(report?.reason ?? "no executable fix action", 260)}.`,
|
||||
@ -198,7 +214,7 @@ export function automergeRepairOutcomeComment({ marker, result, report, target,
|
||||
if (actionLines.length > 0) {
|
||||
lines.push("", "Worker actions:", ...actionLines);
|
||||
}
|
||||
lines.push("", "No branch push, rebase, replacement PR, merge, or ClawSweeper re-review was started by this pass.");
|
||||
lines.push("", variant(automergeNoChangeClosers));
|
||||
return withFishNotes(lines, provenance);
|
||||
}
|
||||
|
||||
|
||||
@ -229,7 +229,7 @@ test("renderResponse reports trusted repair dispatches without losing guardrails
|
||||
assert.match(body, /clownfish-command:456:2026-04-29T07:12:31Z:clawsweeper_auto_repair:def456/);
|
||||
assert.match(body, /cluster-worker\.yml/);
|
||||
assert.match(body, /safe credited replacement/);
|
||||
assert.match(body, /narrow fix/);
|
||||
assert.match(body, /keep it narrow/);
|
||||
assert.doesNotMatch(body, /ProjectClownfish/i);
|
||||
});
|
||||
|
||||
@ -250,7 +250,9 @@ test("renderResponse reports automerge resume actions", () => {
|
||||
);
|
||||
|
||||
assert.match(body, /cleared `clownfish:human-review`/);
|
||||
assert.match(body, /repair\/rebase/);
|
||||
assert.match(body, /tagged `clownfish:automerge`/);
|
||||
assert.match(body, /bounded repair lap/);
|
||||
assert.match(body, /\/clownfish stop/);
|
||||
});
|
||||
|
||||
test("renderResponse reports maintainer autoclose results", () => {
|
||||
@ -295,9 +297,11 @@ test("renderResponse reports needs-human automerge repair dispatches", () => {
|
||||
},
|
||||
);
|
||||
|
||||
assert.match(body, /continuing the automerge repair loop/);
|
||||
assert.match(body, /guarded repair lap/);
|
||||
assert.match(body, /cluster-worker\.yml/);
|
||||
assert.match(body, /automerge-openclaw-openclaw-74156/);
|
||||
assert.match(body, /safe credited replacement/);
|
||||
assert.match(body, /keep it narrow/);
|
||||
assert.doesNotMatch(body, /did not dispatch/);
|
||||
});
|
||||
|
||||
@ -313,7 +317,7 @@ test("renderResponse reports explicit human-review pause actions", () => {
|
||||
null,
|
||||
);
|
||||
|
||||
assert.match(body, /pausing automerge/);
|
||||
assert.match(body, /human review/);
|
||||
assert.match(body, /regular `clownfish` label/);
|
||||
assert.doesNotMatch(body, /clownfish:human-review/);
|
||||
assert.doesNotMatch(body, /did not dispatch/);
|
||||
@ -338,7 +342,7 @@ test("renderResponse reports automerge completion", () => {
|
||||
);
|
||||
|
||||
assert.match(body, /merged this PR/);
|
||||
assert.match(body, /automerge loop is complete/);
|
||||
assert.match(body, /Automerge lap complete/);
|
||||
assert.doesNotMatch(body, /ProjectClownfish/i);
|
||||
});
|
||||
|
||||
|
||||
@ -23,9 +23,10 @@ test("automergeRepairOutcomeComment explains no-op repair runs", () => {
|
||||
});
|
||||
|
||||
assert.match(body, /^<!-- marker -->/);
|
||||
assert.match(body, /Repair pass finished without changing this PR/);
|
||||
assert.match(body, /Clownfish 🐠 reef automerge status/);
|
||||
assert.match(body, /(without changing|without changing the branch|no-op|no new branch changes|no safe branch change)/i);
|
||||
assert.match(body, /Executor outcome: no planned fix actions\./);
|
||||
assert.match(body, /`route_security` on `#74156`: planned - central handling required/);
|
||||
assert.match(body, /No branch push, rebase, replacement PR, merge, or ClawSweeper re-review/);
|
||||
assert.match(body, /(No branch push|No push|left the PR as-is|Nothing moved downstream|observational only)/i);
|
||||
assert.match(body, /model gpt-test, reasoning medium; reviewed against 0123456789ab/);
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user