diff --git a/main.ts b/main.ts index 3463ea2..3960f0d 100644 --- a/main.ts +++ b/main.ts @@ -705,20 +705,21 @@ export async function main(): Promise { }); } - // clean up stranded progress comments. two cases: - // 1. wasUpdated=false: nothing wrote to the comment ("Leaping into action" orphan) - // 2. tracker published a checklist but the agent never wrote a final summary - // (hasPublished=true, finalSummaryWritten=false). - // in both cases, delete the comment so it doesn't linger with stale content. - // wasUpdated is intentionally NOT set here — cleanup is not a real progress update. - // uses finalSummaryWritten (not todoTracker.enabled) so cleanup survives API failures - // in report_progress where cancel() ran but the write didn't succeed. - const trackerWasLastWriter = todoTracker?.hasPublished && !toolState.finalSummaryWritten; - if ( - toolContext && - toolState.progressComment && - (!toolState.wasUpdated || trackerWasLastWriter) - ) { + // clean up stranded progress comments. the comment is stale unless + // report_progress wrote a final summary to it — three sub-cases all reduce + // to !finalSummaryWritten: + // 1. nothing wrote to the comment ("Leaping into action" orphan) + // 2. tracker published a checklist but the agent never finalized it + // 3. the agent produced a substantive artifact via another MCP write tool + // (create_issue_comment, update_pull_request_body, reply_to_review_comment) + // and skipped report_progress — wasUpdated is true, but the progress + // comment itself was never touched. + // create_pull_request_review owns its own deletion (see action/mcp/review.ts), + // so progressComment is already null by the time we get here for that path. + // uses finalSummaryWritten (not todoTracker.enabled or wasUpdated) so cleanup + // survives API failures in report_progress where cancel() ran but the write + // didn't succeed, and isn't fooled by writes to *other* artifacts. + if (toolContext && toolState.progressComment && !toolState.finalSummaryWritten) { await deleteProgressComment(toolContext).catch((error) => { log.debug(`stranded progress comment cleanup failed: ${error}`); }); diff --git a/mcp/comment.ts b/mcp/comment.ts index c70a07f..a797375 100644 --- a/mcp/comment.ts +++ b/mcp/comment.ts @@ -91,6 +91,8 @@ export function CreateCommentTool(ctx: ToolContext) { body: bodyWithFooter, }); + ctx.toolState.wasUpdated = true; + if (result.data.node_id) { await patchWorkflowRunFields(ctx, { summaryCommentNodeId: result.data.node_id }); } @@ -110,6 +112,8 @@ export function CreateCommentTool(ctx: ToolContext) { body: bodyWithFooter, }); + ctx.toolState.wasUpdated = true; + if (commentType === "Plan") { if (result.data.node_id) { await patchWorkflowRunFields(ctx, { planCommentNodeId: result.data.node_id }); @@ -366,10 +370,6 @@ export function ReportProgressTool(ctx: ToolContext) { } const result = await reportProgress(ctx, reportParams); - if (!params.target_plan_comment) { - ctx.toolState.finalSummaryWritten = true; - } - if (result.action === "skipped") { return { success: true, @@ -378,6 +378,10 @@ export function ReportProgressTool(ctx: ToolContext) { }; } + if (!params.target_plan_comment) { + ctx.toolState.finalSummaryWritten = true; + } + return { success: true, ...result, diff --git a/mcp/pr.ts b/mcp/pr.ts index 841b21e..9110914 100644 --- a/mcp/pr.ts +++ b/mcp/pr.ts @@ -49,6 +49,8 @@ export function UpdatePullRequestBodyTool(ctx: ToolContext) { body: bodyWithFooter, }); + ctx.toolState.wasUpdated = true; + return { success: true, number: result.data.number, diff --git a/mcp/review.ts b/mcp/review.ts index dedbf71..3b10cb8 100644 --- a/mcp/review.ts +++ b/mcp/review.ts @@ -537,6 +537,8 @@ export function CreatePullRequestReviewTool(ctx: ToolContext) { reviewedSha: actuallyReviewedSha, }; + ctx.toolState.wasUpdated = true; + // a submitted review obsoletes the progress comment — the review IS the // durable artifact. owned here (not in main.ts) so cleanup is atomic with // submission and survives any path out of the run (success, timeout, diff --git a/utils/run.ts b/utils/run.ts index b1cc201..6397cbb 100644 --- a/utils/run.ts +++ b/utils/run.ts @@ -19,14 +19,14 @@ export async function handleAgentResult(ctx: HandleAgentResultParams): Promise