fix(background-agent): clean tmux cancel bookkeeping

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
YeonGyu-Kim
2026-04-04 15:40:21 +09:00
parent fd476fe9a1
commit b31dfa6928
2 changed files with 13 additions and 0 deletions
@@ -15,6 +15,7 @@ afterAll(() => { mock.restore() })
import { getSessionPromptParams, clearSessionPromptParams } from "../../shared/session-prompt-params-state"
import { tmpdir } from "node:os"
import type { PluginInput } from "@opencode-ai/plugin"
import { _resetForTesting as resetClaudeCodeSessionState, subagentSessions } from "../claude-code-session-state"
import type { BackgroundTask, ResumeInput } from "./types"
import { MIN_IDLE_TIME_MS } from "./constants"
import { BackgroundManager } from "./manager"
@@ -213,6 +214,10 @@ function getCompletionTimers(manager: BackgroundManager): Map<string, ReturnType
return (manager as unknown as { completionTimers: Map<string, ReturnType<typeof setTimeout>> }).completionTimers
}
function getRootDescendantCounts(manager: BackgroundManager): Map<string, number> {
return (manager as unknown as { rootDescendantCounts: Map<string, number> }).rootDescendantCounts
}
function getQueuesByKey(
manager: BackgroundManager
): Map<string, Array<{ task: BackgroundTask; input: import("./types").LaunchInput }>> {
@@ -2585,6 +2590,7 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => {
test("should keep task cancelled when cancelled during tmux callback before running state is assigned", async () => {
// given
resetClaudeCodeSessionState()
const originalTmuxEnvironment = process.env.TMUX
process.env.TMUX = "test-session"
@@ -2674,7 +2680,10 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => {
expect(promptAsyncSessionIDs).not.toContain(createdSessionID)
expect(abortCalls).toEqual([createdSessionID])
expect(getConcurrencyManager(manager).getCount("test-agent")).toBe(0)
expect(getRootDescendantCounts(manager).has("parent-session")).toBe(false)
expect(subagentSessions.has(createdSessionID)).toBe(false)
} finally {
resetClaudeCodeSessionState()
if (originalTmuxEnvironment === undefined) {
delete process.env.TMUX
} else {
+4
View File
@@ -493,6 +493,10 @@ export class BackgroundManager {
if (this.tasks.get(task.id)?.status === "cancelled") {
await this.abortSessionWithLogging(sessionID, "cancelled during tmux setup")
subagentSessions.delete(sessionID)
if (task.rootSessionID) {
this.unregisterRootDescendant(task.rootSessionID)
}
this.concurrencyManager.release(concurrencyKey)
return
}