From e3be656f868d84d9863c34d5093ad4e7dd5b92e8 Mon Sep 17 00:00:00 2001 From: Sisyphus Date: Sun, 28 Dec 2025 16:02:04 +0900 Subject: [PATCH] fix: disable todo-continuation for plan mode agents (#303) * fix: disable todo-continuation for plan mode agents Plan mode agents (e.g., 'plan', 'Planner-Sisyphus') only analyze and plan, they don't implement. The todo-continuation hook was incorrectly triggering for these agents because the existing write permission check only looked at the stored message's tools field, not the agent's permission configuration. This fix adds an explicit check for plan mode agents by name to skip the todo continuation prompt injection. Fixes #293 * chore: changes by sisyphus-dev-ai * fix: address review comments for plan mode agent check - Use exact match for plan mode agents instead of substring match to prevent false positives on agents like 'deployment-planner' - Add plan mode agent check to preemptive injection path (non-interactive mode) which was missing from the initial fix --------- Co-authored-by: sisyphus-dev-ai --- assets/oh-my-opencode.schema.json | 2 +- bun.lock | 4 ++-- src/hooks/todo-continuation-enforcer.ts | 15 +++++++++++++-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/assets/oh-my-opencode.schema.json b/assets/oh-my-opencode.schema.json index 200889ce4..308d53aa2 100644 --- a/assets/oh-my-opencode.schema.json +++ b/assets/oh-my-opencode.schema.json @@ -1487,7 +1487,7 @@ } } }, - "dcp_on_compaction_failure": { + "dcp_for_compaction": { "type": "boolean" } } diff --git a/bun.lock b/bun.lock index ea24f0a59..3b580719b 100644 --- a/bun.lock +++ b/bun.lock @@ -8,7 +8,7 @@ "@ast-grep/cli": "^0.40.0", "@ast-grep/napi": "^0.40.0", "@clack/prompts": "^0.11.0", - "@code-yeongyu/comment-checker": "^0.6.0", + "@code-yeongyu/comment-checker": "^0.6.1", "@openauthjs/openauth": "^0.4.3", "@opencode-ai/plugin": "^1.0.162", "@opencode-ai/sdk": "^1.0.162", @@ -73,7 +73,7 @@ "@clack/prompts": ["@clack/prompts@0.11.0", "", { "dependencies": { "@clack/core": "0.5.0", "picocolors": "^1.0.0", "sisteransi": "^1.0.5" } }, "sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw=="], - "@code-yeongyu/comment-checker": ["@code-yeongyu/comment-checker@0.6.0", "", { "os": [ "linux", "win32", "darwin", ], "cpu": [ "x64", "arm64", ], "bin": { "comment-checker": "bin/comment-checker" } }, "sha512-VtDPrhbUJcb5BIS18VMcY/N/xSLbMr6dpU9MO1NYQyEDhI4pSIx07K4gOlCutG/nHVCjO+HEarn8rttODP+5UA=="], + "@code-yeongyu/comment-checker": ["@code-yeongyu/comment-checker@0.6.1", "", { "os": [ "linux", "win32", "darwin", ], "cpu": [ "x64", "arm64", ], "bin": { "comment-checker": "bin/comment-checker" } }, "sha512-BBremX+Y5aW8sTzlhHrLsKParupYkPOVUYmq9STrlWvBvfAme6w5IWuZCLl6nHIQScRDdvGdrAjPycJC86EZFA=="], "@openauthjs/openauth": ["@openauthjs/openauth@0.4.3", "", { "dependencies": { "@standard-schema/spec": "1.0.0-beta.3", "aws4fetch": "1.0.20", "jose": "5.9.6" }, "peerDependencies": { "arctic": "^2.2.2", "hono": "^4.0.0" } }, "sha512-RlnjqvHzqcbFVymEwhlUEuac4utA5h4nhSK/i2szZuQmxTIqbGUxZ+nM+avM+VV4Ing+/ZaNLKILoXS3yrkOOw=="], diff --git a/src/hooks/todo-continuation-enforcer.ts b/src/hooks/todo-continuation-enforcer.ts index 2ab3245f1..b9c2abd81 100644 --- a/src/hooks/todo-continuation-enforcer.ts +++ b/src/hooks/todo-continuation-enforcer.ts @@ -272,8 +272,19 @@ export function createTodoContinuationEnforcer( (prevMessage.tools.write !== false && prevMessage.tools.edit !== false) if (!agentHasWritePermission) { - log(`[${HOOK_NAME}] Skipped: agent lacks write permission`, { - sessionID, agent: prevMessage?.agent, tools: prevMessage?.tools + log(`[${HOOK_NAME}] Skipped: agent lacks write permission`, { + sessionID, agent: prevMessage?.agent, tools: prevMessage?.tools + }) + state.mode = "idle" + return + } + + // Plan mode agents only analyze and plan, not implement - skip todo continuation + const agentName = prevMessage?.agent?.toLowerCase() ?? "" + const isPlanModeAgent = agentName === "plan" || agentName === "planner-sisyphus" + if (isPlanModeAgent) { + log(`[${HOOK_NAME}] Skipped: plan mode agent detected`, { + sessionID, agent: prevMessage?.agent }) state.mode = "idle" return