diff --git a/src/hooks/todo-continuation-enforcer.test.ts b/src/hooks/todo-continuation-enforcer.test.ts index b79ad4c..f330e10 100644 --- a/src/hooks/todo-continuation-enforcer.test.ts +++ b/src/hooks/todo-continuation-enforcer.test.ts @@ -1,7 +1,7 @@ import { describe, expect, test, beforeEach, afterEach, mock } from "bun:test" import { createTodoContinuationEnforcer } from "./todo-continuation-enforcer" -import { setMainSession } from "../features/claude-code-session-state" +import { setMainSession, subagentSessions } from "../features/claude-code-session-state" import type { BackgroundManager } from "../features/background-agent" describe("todo-continuation-enforcer", () => { @@ -51,10 +51,12 @@ describe("todo-continuation-enforcer", () => { promptCalls = [] toastCalls = [] setMainSession(undefined) + subagentSessions.clear() }) afterEach(() => { setMainSession(undefined) + subagentSessions.clear() }) test("should inject continuation when idle with incomplete todos", async () => { @@ -143,6 +145,25 @@ describe("todo-continuation-enforcer", () => { expect(promptCalls).toHaveLength(0) }) + test("should inject for background task session (subagent)", async () => { + // #given - main session set, background task session registered + setMainSession("main-session") + const bgTaskSession = "bg-task-session" + subagentSessions.add(bgTaskSession) + + const hook = createTodoContinuationEnforcer(createMockPluginInput(), {}) + + // #when - background task session goes idle + await hook.handler({ + event: { type: "session.idle", properties: { sessionID: bgTaskSession } }, + }) + + // #then - continuation injected for background task session + await new Promise(r => setTimeout(r, 2500)) + expect(promptCalls.length).toBe(1) + expect(promptCalls[0].sessionID).toBe(bgTaskSession) + }) + test("should skip injection after recent error", async () => { // #given - session that just had an error const sessionID = "main-error" diff --git a/src/hooks/todo-continuation-enforcer.ts b/src/hooks/todo-continuation-enforcer.ts index f3b204f..14aa4c5 100644 --- a/src/hooks/todo-continuation-enforcer.ts +++ b/src/hooks/todo-continuation-enforcer.ts @@ -1,7 +1,7 @@ import { existsSync, readdirSync } from "node:fs" import { join } from "node:path" import type { PluginInput } from "@opencode-ai/plugin" -import { getMainSessionID } from "../features/claude-code-session-state" +import { getMainSessionID, subagentSessions } from "../features/claude-code-session-state" import { findNearestMessageWithFields, MESSAGE_STORAGE, @@ -265,8 +265,11 @@ export function createTodoContinuationEnforcer( log(`[${HOOK_NAME}] session.idle`, { sessionID }) const mainSessionID = getMainSessionID() - if (mainSessionID && sessionID !== mainSessionID) { - log(`[${HOOK_NAME}] Skipped: not main session`, { sessionID }) + const isMainSession = sessionID === mainSessionID + const isBackgroundTaskSession = subagentSessions.has(sessionID) + + if (mainSessionID && !isMainSession && !isBackgroundTaskSession) { + log(`[${HOOK_NAME}] Skipped: not main or background task session`, { sessionID }) return }