From 9fa9dace2c772e41fedef7ef51fa6ac0d121ed75 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 19 Feb 2026 14:07:52 +0900 Subject: [PATCH] fix(todo-continuation-enforcer): check isContinuationStopped in injectContinuation to close race window When /stop-continuation is invoked during the 2s countdown, the stop flag was never checked inside injectContinuation, so the injection would still fire after the countdown elapsed. Propagate isContinuationStopped from handleSessionIdle through startCountdown into injectContinuation, where it is now re-checked before any API call. --- .../todo-continuation-enforcer/continuation-injection.ts | 7 +++++++ src/hooks/todo-continuation-enforcer/countdown.ts | 3 +++ src/hooks/todo-continuation-enforcer/idle-event.ts | 1 + 3 files changed, 11 insertions(+) diff --git a/src/hooks/todo-continuation-enforcer/continuation-injection.ts b/src/hooks/todo-continuation-enforcer/continuation-injection.ts index b48770ab7..ba60d23b0 100644 --- a/src/hooks/todo-continuation-enforcer/continuation-injection.ts +++ b/src/hooks/todo-continuation-enforcer/continuation-injection.ts @@ -37,6 +37,7 @@ export async function injectContinuation(args: { skipAgents?: string[] resolvedInfo?: ResolvedMessageInfo sessionStateStore: SessionStateStore + isContinuationStopped?: (sessionID: string) => boolean }): Promise { const { ctx, @@ -45,6 +46,7 @@ export async function injectContinuation(args: { skipAgents = DEFAULT_SKIP_AGENTS, resolvedInfo, sessionStateStore, + isContinuationStopped, } = args const state = sessionStateStore.getExistingState(sessionID) @@ -53,6 +55,11 @@ export async function injectContinuation(args: { return } + if (isContinuationStopped?.(sessionID)) { + log(`[${HOOK_NAME}] Skipped injection: continuation stopped for session`, { sessionID }) + return + } + const hasRunningBgTasks = backgroundManager ? backgroundManager.getTasksByParentSession(sessionID).some((task: { status: string }) => task.status === "running") : false diff --git a/src/hooks/todo-continuation-enforcer/countdown.ts b/src/hooks/todo-continuation-enforcer/countdown.ts index 7404d32d1..007e7dc3f 100644 --- a/src/hooks/todo-continuation-enforcer/countdown.ts +++ b/src/hooks/todo-continuation-enforcer/countdown.ts @@ -38,6 +38,7 @@ export function startCountdown(args: { backgroundManager?: BackgroundManager skipAgents: string[] sessionStateStore: SessionStateStore + isContinuationStopped?: (sessionID: string) => boolean }): void { const { ctx, @@ -47,6 +48,7 @@ export function startCountdown(args: { backgroundManager, skipAgents, sessionStateStore, + isContinuationStopped, } = args const state = sessionStateStore.getState(sessionID) @@ -72,6 +74,7 @@ export function startCountdown(args: { skipAgents, resolvedInfo, sessionStateStore, + isContinuationStopped, }) }, COUNTDOWN_SECONDS * 1000) diff --git a/src/hooks/todo-continuation-enforcer/idle-event.ts b/src/hooks/todo-continuation-enforcer/idle-event.ts index 689672c01..10708d1a3 100644 --- a/src/hooks/todo-continuation-enforcer/idle-event.ts +++ b/src/hooks/todo-continuation-enforcer/idle-event.ts @@ -187,5 +187,6 @@ export async function handleSessionIdle(args: { backgroundManager, skipAgents, sessionStateStore, + isContinuationStopped, }) }