From 11b363849366db64a5f8a4faced58bc6ddf68b85 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Tue, 12 May 2026 14:21:46 +0900 Subject: [PATCH] test(features): remove unsafe test assertions Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- ...kground-task-notification-template.test.ts | 8 ++--- .../compaction-aware-message-resolver.test.ts | 2 +- .../manager-circuit-breaker.test.ts | 8 ++--- .../manager-session-permission.test.ts | 4 +-- .../session-existence.test.ts | 4 +-- .../subagent-spawn-limits.test.ts | 32 +++++++++---------- .../context-injector/injector.test.ts | 8 ++--- src/features/context-injector/injector.ts | 15 ++++++--- .../hook-message-injector/injector.test.ts | 32 +++++++++---------- .../skill-mcp-manager/manager.test.ts | 10 +++--- .../task-toast-manager/manager.test.ts | 18 +++++------ .../cleanup-team-run-resources.test.ts | 4 +-- .../tmux-subagent/polling-manager.test.ts | 22 ++++++------- 13 files changed, 87 insertions(+), 80 deletions(-) diff --git a/src/features/background-agent/background-task-notification-template.test.ts b/src/features/background-agent/background-task-notification-template.test.ts index 7001aef12..80cbb93f5 100644 --- a/src/features/background-agent/background-task-notification-template.test.ts +++ b/src/features/background-agent/background-task-notification-template.test.ts @@ -134,7 +134,7 @@ Use \`background_output(task_id="")\` to retrieve each result. const notification = buildBackgroundTaskNotificationText({ task: { id: "bg_abc123", - description: undefined as unknown as string, + description: testCoerce(undefined), status: "completed", }, duration: "5s", @@ -142,8 +142,8 @@ Use \`background_output(task_id="")\` to retrieve each result. allComplete: true, remainingCount: 0, completedTasks: [ - { id: "bg_abc123", description: undefined as unknown as string, status: "completed" }, - { id: "bg_def456", description: undefined as unknown as string, status: "completed" }, + { id: "bg_abc123", description: testCoerce(undefined), status: "completed" }, + { id: "bg_def456", description: testCoerce(undefined), status: "completed" }, ], }) @@ -230,7 +230,7 @@ Use \`background_output(task_id="")\` to retrieve each result. const notification = buildBackgroundTaskNotificationText({ task: { id: "bg_xyz789", - description: undefined as unknown as string, + description: testCoerce(undefined), status: "completed", }, duration: "3s", diff --git a/src/features/background-agent/compaction-aware-message-resolver.test.ts b/src/features/background-agent/compaction-aware-message-resolver.test.ts index 4ad9a33cf..191b5152f 100644 --- a/src/features/background-agent/compaction-aware-message-resolver.test.ts +++ b/src/features/background-agent/compaction-aware-message-resolver.test.ts @@ -49,7 +49,7 @@ describe("isCompactionAgent", () => { test("returns false for null", () => { // when - const result = isCompactionAgent(null as unknown as string) + const result = isCompactionAgent(testCoerce(null)) // then expect(result).toBe(false) diff --git a/src/features/background-agent/manager-circuit-breaker.test.ts b/src/features/background-agent/manager-circuit-breaker.test.ts index 8adef0618..0e5308400 100644 --- a/src/features/background-agent/manager-circuit-breaker.test.ts +++ b/src/features/background-agent/manager-circuit-breaker.test.ts @@ -16,12 +16,12 @@ function createManager(config?: BackgroundTaskConfig): BackgroundManager { }, } - const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput, config: config }) - const testManager = manager as unknown as { + const manager = new BackgroundManager({ pluginContext: testCoerce({ client, directory: tmpdir() }), config: config }) + const testManager = testCoerce<{ enqueueNotificationForParent: (sessionId: string, fn: () => Promise) => Promise notifyParentSession: (task: BackgroundTask) => Promise tasks: Map - } + }>(manager) testManager.enqueueNotificationForParent = async (_sessionId: string, fn) => { await fn() @@ -32,7 +32,7 @@ function createManager(config?: BackgroundTaskConfig): BackgroundManager { } function getTaskMap(manager: BackgroundManager): Map { - return (manager as unknown as { tasks: Map }).tasks + return (testCoerce<{ tasks: Map }>(manager)).tasks } async function flushAsyncWork() { diff --git a/src/features/background-agent/manager-session-permission.test.ts b/src/features/background-agent/manager-session-permission.test.ts index a9f4a1756..29f68ba20 100644 --- a/src/features/background-agent/manager-session-permission.test.ts +++ b/src/features/background-agent/manager-session-permission.test.ts @@ -21,7 +21,7 @@ describe("BackgroundManager session permission", () => { }, } const directory = tmpdir() - const manager = new BackgroundManager({ pluginContext: { client, directory } as unknown as PluginInput }) + const manager = new BackgroundManager({ pluginContext: testCoerce({ client, directory }) }) // when await manager.launch({ @@ -62,7 +62,7 @@ describe("BackgroundManager session permission", () => { abort: async () => ({}), }, } - const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput }) + const manager = new BackgroundManager({ pluginContext: testCoerce({ client, directory: tmpdir() }) }) // when await manager.launch({ diff --git a/src/features/background-agent/session-existence.test.ts b/src/features/background-agent/session-existence.test.ts index 9b59a4816..09eb7eeee 100644 --- a/src/features/background-agent/session-existence.test.ts +++ b/src/features/background-agent/session-existence.test.ts @@ -7,11 +7,11 @@ describe("verifySessionExists", () => { test("passes query directory to session lookup when provided", async () => { // given const get = mock(async () => ({ data: { id: "session-123" } })) - const client = { + const client = testCoerce({ session: { get, }, - } as unknown as OpencodeClient + }) // when const result = await verifySessionExists(client, "session-123", "/project/root") diff --git a/src/features/background-agent/subagent-spawn-limits.test.ts b/src/features/background-agent/subagent-spawn-limits.test.ts index e3094c551..c43bd8727 100644 --- a/src/features/background-agent/subagent-spawn-limits.test.ts +++ b/src/features/background-agent/subagent-spawn-limits.test.ts @@ -20,14 +20,14 @@ describe("resolveSubagentSpawnContext", () => { test("passes query.directory to each session.get call", async () => { // given const sessionGetCalls: Array> = [] - const client = createMockClient((async (input) => { + const client = createMockClient(testCoerce((async (input) => { sessionGetCalls.push(input as Record) if (input.path.id === "child-session") { return { data: { id: "child-session", parentID: "root-session" } } } return { data: { id: "root-session", parentID: undefined } } - }) as unknown as OpencodeClient["session"]["get"]) + }))) // when const result = await resolveSubagentSpawnContext(client, "child-session", "/project/root") @@ -50,10 +50,10 @@ describe("resolveSubagentSpawnContext", () => { describe("#given session.get returns an SDK error response", () => { test("throws a fail-closed spawn blocked error", async () => { // given - const client = createMockClient((async () => ({ + const client = createMockClient(testCoerce((async () => ({ error: "lookup failed", data: undefined, - })) as unknown as OpencodeClient["session"]["get"]) + })))) // when const result = resolveSubagentSpawnContext(client, "parent-session") @@ -66,9 +66,9 @@ describe("resolveSubagentSpawnContext", () => { describe("#given session.get returns no session data", () => { test("throws a fail-closed spawn blocked error", async () => { // given - const client = createMockClient((async () => ({ + const client = createMockClient(testCoerce((async () => ({ data: undefined, - })) as unknown as OpencodeClient["session"]["get"]) + })))) // when const result = resolveSubagentSpawnContext(client, "parent-session") @@ -81,12 +81,12 @@ describe("resolveSubagentSpawnContext", () => { describe("depth calculation smoke tests (regression guard)", () => { test("root session (no parentID) reports depth 0 and childDepth 1", async () => { // given - a root session with no parent - const client = createMockClient((async (opts) => { + const client = createMockClient(testCoerce((async (opts) => { if (opts.path.id === "root-session") { return { data: { id: "root-session", parentID: undefined } } } return { error: "not found", data: undefined } - }) as unknown as OpencodeClient["session"]["get"]) + }))) // when const result = await resolveSubagentSpawnContext(client, "root-session") @@ -99,7 +99,7 @@ describe("resolveSubagentSpawnContext", () => { test("depth-1 child reports childDepth 2", async () => { // given - child -> root chain - const client = createMockClient((async (opts) => { + const client = createMockClient(testCoerce((async (opts) => { if (opts.path.id === "child-1") { return { data: { id: "child-1", parentID: "root-session" } } } @@ -107,7 +107,7 @@ describe("resolveSubagentSpawnContext", () => { return { data: { id: "root-session", parentID: undefined } } } return { error: "not found", data: undefined } - }) as unknown as OpencodeClient["session"]["get"]) + }))) // when const result = await resolveSubagentSpawnContext(client, "child-1") @@ -120,7 +120,7 @@ describe("resolveSubagentSpawnContext", () => { test("depth-2 grandchild reports childDepth 3", async () => { // given - grandchild -> child -> root chain - const client = createMockClient((async (opts) => { + const client = createMockClient(testCoerce((async (opts) => { const sessions: Record = { "grandchild": { id: "grandchild", parentID: "child" }, "child": { id: "child", parentID: "root" }, @@ -129,7 +129,7 @@ describe("resolveSubagentSpawnContext", () => { const session = sessions[opts.path.id] if (session) return { data: session } return { error: "not found", data: undefined } - }) as unknown as OpencodeClient["session"]["get"]) + }))) // when const result = await resolveSubagentSpawnContext(client, "grandchild") @@ -153,11 +153,11 @@ describe("resolveSubagentSpawnContext", () => { } } - const client = createMockClient((async (opts) => { + const client = createMockClient(testCoerce((async (opts) => { const session = sessions[opts.path.id] if (session) return { data: session } return { error: "not found", data: undefined } - }) as unknown as OpencodeClient["session"]["get"]) + }))) // when - resolve from the deepest session const deepest = `session-${DEFAULT_MAX_SUBAGENT_DEPTH}` @@ -170,7 +170,7 @@ describe("resolveSubagentSpawnContext", () => { test("detects parent cycle and throws", async () => { // given - A -> B -> A (cycle) - const client = createMockClient((async (opts) => { + const client = createMockClient(testCoerce((async (opts) => { const sessions: Record = { "session-a": { id: "session-a", parentID: "session-b" }, "session-b": { id: "session-b", parentID: "session-a" }, @@ -178,7 +178,7 @@ describe("resolveSubagentSpawnContext", () => { const session = sessions[opts.path.id] if (session) return { data: session } return { error: "not found", data: undefined } - }) as unknown as OpencodeClient["session"]["get"]) + }))) // when const result = resolveSubagentSpawnContext(client, "session-a") diff --git a/src/features/context-injector/injector.test.ts b/src/features/context-injector/injector.test.ts index 09de376fe..4a4f1d0ec 100644 --- a/src/features/context-injector/injector.test.ts +++ b/src/features/context-injector/injector.test.ts @@ -51,7 +51,7 @@ describe("createContextInjectorMessagesTransformHook", () => { createMockMessage("user", "Second message", sessionID), ] // eslint-disable-next-line @typescript-eslint/no-explicit-any - const output = { messages } as any + const output = testCoerce({ messages }) // when await hook["experimental.chat.messages.transform"]!({}, output) @@ -115,7 +115,7 @@ describe("createContextInjectorMessagesTransformHook", () => { const sessionID = "ses_transform2" const messages = [createMockMessage("user", "Hello world", sessionID)] // eslint-disable-next-line @typescript-eslint/no-explicit-any - const output = { messages } as any + const output = testCoerce({ messages }) // when await hook["experimental.chat.messages.transform"]!({}, output) @@ -135,7 +135,7 @@ describe("createContextInjectorMessagesTransformHook", () => { }) const messages = [createMockMessage("assistant", "Response", sessionID)] // eslint-disable-next-line @typescript-eslint/no-explicit-any - const output = { messages } as any + const output = testCoerce({ messages }) // when await hook["experimental.chat.messages.transform"]!({}, output) @@ -156,7 +156,7 @@ describe("createContextInjectorMessagesTransformHook", () => { }) const messages = [createMockMessage("user", "Message", sessionID)] // eslint-disable-next-line @typescript-eslint/no-explicit-any - const output = { messages } as any + const output = testCoerce({ messages }) // when await hook["experimental.chat.messages.transform"]!({}, output) diff --git a/src/features/context-injector/injector.ts b/src/features/context-injector/injector.ts index 8a52de914..eff4faaec 100644 --- a/src/features/context-injector/injector.ts +++ b/src/features/context-injector/injector.ts @@ -79,6 +79,14 @@ type MessagesTransformHook = { ) => Promise } +function getSessionIDFromMessageInfo(info: Message): string | undefined { + return "sessionID" in info && typeof info.sessionID === "string" ? info.sessionID : undefined +} + +function hasText(part: Part): boolean { + return "text" in part && typeof part.text === "string" && part.text.length > 0 +} + export function createContextInjectorMessagesTransformHook( collector: ContextCollector ): MessagesTransformHook { @@ -106,8 +114,7 @@ export function createContextInjectorMessagesTransformHook( } const lastUserMessage = messages[lastUserMessageIndex] - // Try message.info.sessionID first, fallback to mainSessionID - const messageSessionID = (lastUserMessage.info as unknown as { sessionID?: string }).sessionID + const messageSessionID = getSessionIDFromMessageInfo(lastUserMessage.info) const sessionID = messageSessionID ?? getMainSessionID() log("[DEBUG] Extracted sessionID", { messageSessionID, @@ -135,7 +142,7 @@ export function createContextInjectorMessagesTransformHook( } const textPartIndex = lastUserMessage.parts.findIndex( - (p) => p.type === "text" && (p as { text?: string }).text + (p) => p.type === "text" && hasText(p) ) if (textPartIndex === -1) { @@ -150,7 +157,7 @@ export function createContextInjectorMessagesTransformHook( const syntheticPart = { id: `synthetic_hook_${sessionID}`, messageID: lastUserMessage.info.id, - sessionID: (lastUserMessage.info as { sessionID?: string }).sessionID ?? "", + sessionID: messageSessionID ?? "", type: "text" as const, text: pending.merged, synthetic: true, // hidden in UI diff --git a/src/features/hook-message-injector/injector.test.ts b/src/features/hook-message-injector/injector.test.ts index a50aefa95..af63bffc6 100644 --- a/src/features/hook-message-injector/injector.test.ts +++ b/src/features/hook-message-injector/injector.test.ts @@ -73,7 +73,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => { { info: { agent: "sisyphus", model: { providerID: "anthropic", modelID: "claude-opus-4" } } }, ]) - const result = await findNearestMessageWithFieldsFromSDK(mockClient as any, "ses_123") + const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123") expect(result).toEqual({ agent: "sisyphus", @@ -87,7 +87,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => { { info: { agent: "sisyphus", providerID: "openai", modelID: "gpt-5" } }, ]) - const result = await findNearestMessageWithFieldsFromSDK(mockClient as any, "ses_123") + const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123") expect(result).toEqual({ agent: "sisyphus", @@ -102,7 +102,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => { { id: "msg_new", info: { agent: "new-agent", model: { providerID: "new", modelID: "model" }, time: { created: 20 } } }, ]) - const result = await findNearestMessageWithFieldsFromSDK(mockClient as any, "ses_123") + const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123") expect(result?.agent).toBe("new-agent") }) @@ -112,7 +112,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => { { info: { agent: "partial-agent" } }, ]) - const result = await findNearestMessageWithFieldsFromSDK(mockClient as any, "ses_123") + const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123") expect(result?.agent).toBe("partial-agent") }) @@ -123,7 +123,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => { { info: {} }, ]) - const result = await findNearestMessageWithFieldsFromSDK(mockClient as any, "ses_123") + const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123") expect(result).toBeNull() }) @@ -131,7 +131,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => { it("returns null when messages array is empty", async () => { const mockClient = createMockClient([]) - const result = await findNearestMessageWithFieldsFromSDK(mockClient as any, "ses_123") + const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123") expect(result).toBeNull() }) @@ -145,7 +145,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => { }, } - const result = await findNearestMessageWithFieldsFromSDK(mockClient as any, "ses_123") + const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123") expect(result).toBeNull() }) @@ -161,7 +161,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => { }, ]) - const result = await findNearestMessageWithFieldsFromSDK(mockClient as any, "ses_123") + const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123") expect(result?.tools).toEqual({ edit: true, write: false }) }) @@ -172,7 +172,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => { { id: "msg_older", info: { agent: "newest-by-time", model: { providerID: "openai", modelID: "gpt-5" }, time: { created: 100 } } }, ]) - const result = await findNearestMessageWithFieldsFromSDK(mockClient as any, "ses_123") + const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123") expect(result?.agent).toBe("newest-by-time") }) @@ -190,7 +190,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => { }, ]) - const result = await findNearestMessageWithFieldsFromSDK(mockClient as any, "ses_123") + const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123") expect(result?.agent).toBe("sisyphus") }) @@ -252,7 +252,7 @@ describe("findFirstMessageWithAgentFromSDK", () => { { info: { agent: "second-agent" } }, ]) - const result = await findFirstMessageWithAgentFromSDK(mockClient as any, "ses_123") + const result = await findFirstMessageWithAgentFromSDK(testCoerce(mockClient), "ses_123") expect(result).toBe("first-agent") }) @@ -263,7 +263,7 @@ describe("findFirstMessageWithAgentFromSDK", () => { { id: "msg_early", info: { agent: "earliest-agent", time: { created: 10 } } }, ]) - const result = await findFirstMessageWithAgentFromSDK(mockClient as any, "ses_123") + const result = await findFirstMessageWithAgentFromSDK(testCoerce(mockClient), "ses_123") expect(result).toBe("earliest-agent") }) @@ -274,7 +274,7 @@ describe("findFirstMessageWithAgentFromSDK", () => { { id: "msg_real", info: { agent: "sisyphus", time: { created: 20 } } }, ]) - const result = await findFirstMessageWithAgentFromSDK(mockClient as any, "ses_123") + const result = await findFirstMessageWithAgentFromSDK(testCoerce(mockClient), "ses_123") expect(result).toBe("sisyphus") }) @@ -285,7 +285,7 @@ describe("findFirstMessageWithAgentFromSDK", () => { { info: { agent: "first-real-agent" } }, ]) - const result = await findFirstMessageWithAgentFromSDK(mockClient as any, "ses_123") + const result = await findFirstMessageWithAgentFromSDK(testCoerce(mockClient), "ses_123") expect(result).toBe("first-real-agent") }) @@ -296,7 +296,7 @@ describe("findFirstMessageWithAgentFromSDK", () => { { info: {} }, ]) - const result = await findFirstMessageWithAgentFromSDK(mockClient as any, "ses_123") + const result = await findFirstMessageWithAgentFromSDK(testCoerce(mockClient), "ses_123") expect(result).toBeNull() }) @@ -310,7 +310,7 @@ describe("findFirstMessageWithAgentFromSDK", () => { }, } - const result = await findFirstMessageWithAgentFromSDK(mockClient as any, "ses_123") + const result = await findFirstMessageWithAgentFromSDK(testCoerce(mockClient), "ses_123") expect(result).toBeNull() }) diff --git a/src/features/skill-mcp-manager/manager.test.ts b/src/features/skill-mcp-manager/manager.test.ts index f3ef6f51e..17a4cb2c6 100644 --- a/src/features/skill-mcp-manager/manager.test.ts +++ b/src/features/skill-mcp-manager/manager.test.ts @@ -634,7 +634,7 @@ describe("SkillMcpManager", () => { close: mock(() => Promise.resolve()), } - const getOrCreateSpy = spyOn(manager as any, "getOrCreateClientWithRetry") + const getOrCreateSpy = spyOn(testCoerce(manager), "getOrCreateClientWithRetry") getOrCreateSpy.mockResolvedValue(mockClient) // when @@ -668,7 +668,7 @@ describe("SkillMcpManager", () => { close: mock(() => Promise.resolve()), } - const getOrCreateSpy = spyOn(manager as any, "getOrCreateClientWithRetry") + const getOrCreateSpy = spyOn(testCoerce(manager), "getOrCreateClientWithRetry") getOrCreateSpy.mockResolvedValue(mockClient) // when / #then @@ -700,7 +700,7 @@ describe("SkillMcpManager", () => { close: mock(() => Promise.resolve()), } - const getOrCreateSpy = spyOn(manager as any, "getOrCreateClientWithRetry") + const getOrCreateSpy = spyOn(testCoerce(manager), "getOrCreateClientWithRetry") getOrCreateSpy.mockResolvedValue(mockClient) // when / #then @@ -929,7 +929,7 @@ describe("SkillMcpManager", () => { close: mock(() => Promise.resolve()), } - const getOrCreateSpy = spyOn(manager as any, "getOrCreateClientWithRetry") + const getOrCreateSpy = spyOn(testCoerce(manager), "getOrCreateClientWithRetry") getOrCreateSpy.mockResolvedValue(mockClient) // when @@ -962,7 +962,7 @@ describe("SkillMcpManager", () => { close: mock(() => Promise.resolve()), } - const getOrCreateSpy = spyOn(manager as any, "getOrCreateClientWithRetry") + const getOrCreateSpy = spyOn(testCoerce(manager), "getOrCreateClientWithRetry") getOrCreateSpy.mockResolvedValue(mockClient) // when / #then diff --git a/src/features/task-toast-manager/manager.test.ts b/src/features/task-toast-manager/manager.test.ts index 92ab524a0..23a2f276c 100644 --- a/src/features/task-toast-manager/manager.test.ts +++ b/src/features/task-toast-manager/manager.test.ts @@ -20,15 +20,15 @@ describe("TaskToastManager", () => { showToast: mock(() => Promise.resolve()), }, } - mockConcurrencyManager = { + mockConcurrencyManager = testCoerce({ getConcurrencyLimit: mock(() => 5), - } as unknown as ConcurrencyManager + }) const mod = await import("./manager") TaskToastManager = mod.TaskToastManager // eslint-disable-next-line @typescript-eslint/no-explicit-any - toastManager = new TaskToastManager(mockClient as any, mockConcurrencyManager) + toastManager = new TaskToastManager(testCoerce(mockClient), mockConcurrencyManager) }) afterEach(() => { @@ -108,14 +108,14 @@ describe("TaskToastManager", () => { test("should display concurrency limit info when available", () => { // given - a concurrency manager with known limit - const mockConcurrencyWithCounts = { + const mockConcurrencyWithCounts = testCoerce({ getConcurrencyLimit: mock(() => 5), getRunningCount: mock(() => 2), getQueuedCount: mock(() => 1), - } as unknown as ConcurrencyManager + }) // eslint-disable-next-line @typescript-eslint/no-explicit-any - const managerWithConcurrency = new TaskToastManager(mockClient as any, mockConcurrencyWithCounts) + const managerWithConcurrency = new TaskToastManager(testCoerce(mockClient), mockConcurrencyWithCounts) // when - a task is added managerWithConcurrency.addTask({ @@ -357,11 +357,11 @@ describe("TaskToastManager", () => { test("should show model name in queued tasks too", () => { // given - a concurrency manager that limits to 1 - const limitedConcurrency = { + const limitedConcurrency = testCoerce({ getConcurrencyLimit: mock(() => 1), - } as unknown as ConcurrencyManager + }) // eslint-disable-next-line @typescript-eslint/no-explicit-any - const limitedManager = new TaskToastManager(mockClient as any, limitedConcurrency) + const limitedManager = new TaskToastManager(testCoerce(mockClient), limitedConcurrency) limitedManager.addTask({ id: "task_running", diff --git a/src/features/team-mode/team-runtime/cleanup-team-run-resources.test.ts b/src/features/team-mode/team-runtime/cleanup-team-run-resources.test.ts index 22ee7d53d..af916c6b3 100644 --- a/src/features/team-mode/team-runtime/cleanup-team-run-resources.test.ts +++ b/src/features/team-mode/team-runtime/cleanup-team-run-resources.test.ts @@ -41,9 +41,9 @@ function createRuntimeState(teamRunId: string): RuntimeState { } function createStubBgMgr(): BackgroundManager { - return { + return testCoerce({ cancelTask: async () => undefined, - } as unknown as BackgroundManager + }) } describe("cleanupTeamRunResources", () => { diff --git a/src/features/tmux-subagent/polling-manager.test.ts b/src/features/tmux-subagent/polling-manager.test.ts index 38b32797f..87b5b5297 100644 --- a/src/features/tmux-subagent/polling-manager.test.ts +++ b/src/features/tmux-subagent/polling-manager.test.ts @@ -39,15 +39,15 @@ describe("TmuxPollingManager overlap", () => { } const manager = new TmuxPollingManager( - client as unknown as import("../../tools/delegate-task/types").OpencodeClient, + testCoerce(client), sessions, async () => {}, ) //#when - const firstPoll = (manager as unknown as { pollSessions: () => Promise }).pollSessions() + const firstPoll = (testCoerce<{ pollSessions: () => Promise }>(manager)).pollSessions() await Promise.resolve() - const secondPoll = (manager as unknown as { pollSessions: () => Promise }).pollSessions() + const secondPoll = (testCoerce<{ pollSessions: () => Promise }>(manager)).pollSessions() releaseStatus?.() await Promise.all([firstPoll, secondPoll]) @@ -85,7 +85,7 @@ describe("TmuxPollingManager overlap", () => { } const manager = new TmuxPollingManager( - client as unknown as import("../../tools/delegate-task/types").OpencodeClient, + testCoerce(client), sessions, async (sessionId) => { closedSessionIds.push(sessionId) @@ -98,7 +98,7 @@ describe("TmuxPollingManager overlap", () => { }) //#when - const pollSessions = (manager as unknown as { pollSessions: () => Promise }).pollSessions + const pollSessions = (testCoerce<{ pollSessions: () => Promise }>(manager)).pollSessions await pollSessions.call(manager) await pollSessions.call(manager) await pollSessions.call(manager) @@ -132,7 +132,7 @@ describe("TmuxPollingManager overlap", () => { } const manager = new TmuxPollingManager( - client as unknown as import("../../tools/delegate-task/types").OpencodeClient, + testCoerce(client), sessions, async (sessionId) => { closedSessionIds.push(sessionId) @@ -140,7 +140,7 @@ describe("TmuxPollingManager overlap", () => { ) // when - const pollSessions = (manager as unknown as { pollSessions: () => Promise }).pollSessions + const pollSessions = (testCoerce<{ pollSessions: () => Promise }>(manager)).pollSessions await pollSessions.call(manager) // then @@ -171,7 +171,7 @@ describe("TmuxPollingManager overlap", () => { } const manager = new TmuxPollingManager( - client as unknown as import("../../tools/delegate-task/types").OpencodeClient, + testCoerce(client), sessions, async (sessionId) => { closedSessionIds.push(sessionId) @@ -179,7 +179,7 @@ describe("TmuxPollingManager overlap", () => { ) // when - const pollSessions = (manager as unknown as { pollSessions: () => Promise }).pollSessions + const pollSessions = (testCoerce<{ pollSessions: () => Promise }>(manager)).pollSessions await pollSessions.call(manager) // then @@ -222,13 +222,13 @@ describe("TmuxPollingManager overlap", () => { } manager = new TmuxPollingManager( - client as unknown as import("../../tools/delegate-task/types").OpencodeClient, + testCoerce(client), sessions, async (sessionId) => { closedSessionIds.push(sessionId) }, ) - const pollSessions = (manager as unknown as { pollSessions: () => Promise }).pollSessions + const pollSessions = (testCoerce<{ pollSessions: () => Promise }>(manager)).pollSessions // when await pollSessions.call(manager)