fix(todo-continuation-enforcer): allow background task sessions to receive todo-continuation
Background task sessions registered in subagentSessions were not receiving
todo-continuation prompts, causing a deadlock: background tasks waited for
continuation that never came.
Changes:
- Allow both main session and background task sessions to receive continuation
- Add test for background task session continuation behavior
- Cleanup subagentSessions in test setup/teardown
This fixes the deadlock introduced in commit 116a90d which added todo waiting
logic to background-agent/manager.ts.
🤖 Generated with assistance of OhMyOpenCode
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import { describe, expect, test, beforeEach, afterEach, mock } from "bun:test"
|
import { describe, expect, test, beforeEach, afterEach, mock } from "bun:test"
|
||||||
|
|
||||||
import { createTodoContinuationEnforcer } from "./todo-continuation-enforcer"
|
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"
|
import type { BackgroundManager } from "../features/background-agent"
|
||||||
|
|
||||||
describe("todo-continuation-enforcer", () => {
|
describe("todo-continuation-enforcer", () => {
|
||||||
@@ -51,10 +51,12 @@ describe("todo-continuation-enforcer", () => {
|
|||||||
promptCalls = []
|
promptCalls = []
|
||||||
toastCalls = []
|
toastCalls = []
|
||||||
setMainSession(undefined)
|
setMainSession(undefined)
|
||||||
|
subagentSessions.clear()
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
setMainSession(undefined)
|
setMainSession(undefined)
|
||||||
|
subagentSessions.clear()
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should inject continuation when idle with incomplete todos", async () => {
|
test("should inject continuation when idle with incomplete todos", async () => {
|
||||||
@@ -143,6 +145,25 @@ describe("todo-continuation-enforcer", () => {
|
|||||||
expect(promptCalls).toHaveLength(0)
|
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 () => {
|
test("should skip injection after recent error", async () => {
|
||||||
// #given - session that just had an error
|
// #given - session that just had an error
|
||||||
const sessionID = "main-error"
|
const sessionID = "main-error"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { existsSync, readdirSync } from "node:fs"
|
import { existsSync, readdirSync } from "node:fs"
|
||||||
import { join } from "node:path"
|
import { join } from "node:path"
|
||||||
import type { PluginInput } from "@opencode-ai/plugin"
|
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 {
|
import {
|
||||||
findNearestMessageWithFields,
|
findNearestMessageWithFields,
|
||||||
MESSAGE_STORAGE,
|
MESSAGE_STORAGE,
|
||||||
@@ -265,8 +265,11 @@ export function createTodoContinuationEnforcer(
|
|||||||
log(`[${HOOK_NAME}] session.idle`, { sessionID })
|
log(`[${HOOK_NAME}] session.idle`, { sessionID })
|
||||||
|
|
||||||
const mainSessionID = getMainSessionID()
|
const mainSessionID = getMainSessionID()
|
||||||
if (mainSessionID && sessionID !== mainSessionID) {
|
const isMainSession = sessionID === mainSessionID
|
||||||
log(`[${HOOK_NAME}] Skipped: not main session`, { sessionID })
|
const isBackgroundTaskSession = subagentSessions.has(sessionID)
|
||||||
|
|
||||||
|
if (mainSessionID && !isMainSession && !isBackgroundTaskSession) {
|
||||||
|
log(`[${HOOK_NAME}] Skipped: not main or background task session`, { sessionID })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user