From eb6d19969dd85a5d8cf3b834ca5fc666e0afa0d9 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Tue, 5 May 2026 16:27:26 +0800 Subject: [PATCH] refactor: explicit returns + void floating promises (T3.a typeaware sweep) (#756) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cluster T3.a — mechanical fixes for consistent-return and no-floating-promises. Files touched (15): - server/shared/tool-call-display.ts — default throw in buildCanonicalDetailDisplay switch - server/agent/prompt-attachments.ts — default throw in renderPromptAttachmentAsText switch - server/workspace-directory.ts — default throw in getSortValue switch - server/agent/mcp-server.ts — default throw in mcpCreateWorktreeInput switch - server/terminal/terminal-session-controller.ts — default return in dispatch switch - server/daemon-e2e/agent-configs.ts — default return false in isProviderAvailable switch - server/agent/agent-manager.ts — void dispatchSessionEvent fire-and-forget call - server/agent/mcp-shared.ts — void 4 notify() floating calls - app/agent-status-bar.utils.ts — default throw in getStatusSelectorHint switch - app/keyboard-shortcuts.ts — default throw in resolvePayload switch - app/resolve-agent-form.ts — default throw in resolveAgentForm switch - app/ui/dropdown-menu.tsx — void .then() + return undefined for promise/always-return - app/use-agent-form-state.ts — void refreshSnapshot() floating call - cli/worktree/create.ts — default throw in toDaemonCreateInput switch - cli/onboard.ts — return process.exit(1) to satisfy consistent-return in catch Deferred (outside 15-file cap or in EXCLUDE list): - server/worktree-session.ts — getSortValue (same pattern, cap reached) - Multiple files with other errors (unbound-method, unsafe-type-assertion) are separate clusters --- packages/app/src/components/agent-status-bar.utils.ts | 2 ++ packages/app/src/components/ui/dropdown-menu.tsx | 8 ++++---- packages/app/src/hooks/resolve-agent-form.ts | 2 ++ packages/app/src/hooks/use-agent-form-state.ts | 2 +- packages/app/src/keyboard/keyboard-shortcuts.ts | 2 ++ packages/cli/src/commands/onboard.ts | 2 +- packages/cli/src/commands/worktree/create.ts | 2 ++ packages/server/src/server/agent/agent-manager.ts | 2 +- packages/server/src/server/agent/mcp-server.ts | 2 ++ packages/server/src/server/agent/mcp-shared.ts | 8 ++++---- packages/server/src/server/agent/prompt-attachments.ts | 2 ++ packages/server/src/server/daemon-e2e/agent-configs.ts | 2 ++ packages/server/src/server/workspace-directory.ts | 2 ++ packages/server/src/shared/tool-call-display.ts | 2 ++ .../server/src/terminal/terminal-session-controller.ts | 2 ++ 15 files changed, 31 insertions(+), 11 deletions(-) diff --git a/packages/app/src/components/agent-status-bar.utils.ts b/packages/app/src/components/agent-status-bar.utils.ts index bbf0243ff..0cb7dd904 100644 --- a/packages/app/src/components/agent-status-bar.utils.ts +++ b/packages/app/src/components/agent-status-bar.utils.ts @@ -11,6 +11,8 @@ export function getStatusSelectorHint(selector: ExplainedStatusSelector): string return "Change model"; case "mode": return "Change permission mode"; + default: + throw new Error("unreachable"); } } diff --git a/packages/app/src/components/ui/dropdown-menu.tsx b/packages/app/src/components/ui/dropdown-menu.tsx index a83434379..49c80e7e7 100644 --- a/packages/app/src/components/ui/dropdown-menu.tsx +++ b/packages/app/src/components/ui/dropdown-menu.tsx @@ -445,7 +445,7 @@ export function DropdownMenuContent({ setTriggerRect(null); setContentSize(null); setPosition(null); - return; + return undefined; } // Capture status bar height synchronously before async measurement. @@ -454,8 +454,8 @@ export function DropdownMenuContent({ const statusBarHeight = Platform.OS === "android" ? (StatusBar.currentHeight ?? 0) : 0; let cancelled = false; - measureElement(triggerRef.current).then((rect) => { - if (cancelled) return; + void measureElement(triggerRef.current).then((rect) => { + if (cancelled) return undefined; // On Android with statusBarTranslucent, measureInWindow returns coordinates // relative to below the status bar, but Modal content starts from screen top. // Add status bar height to align coordinate systems (same as react-native-popover-view). @@ -463,7 +463,7 @@ export function DropdownMenuContent({ ...rect, y: rect.y + statusBarHeight, }); - return; + return undefined; }); return () => { diff --git a/packages/app/src/hooks/resolve-agent-form.ts b/packages/app/src/hooks/resolve-agent-form.ts index adb73f34a..a54f9ae8c 100644 --- a/packages/app/src/hooks/resolve-agent-form.ts +++ b/packages/app/src/hooks/resolve-agent-form.ts @@ -553,5 +553,7 @@ export function resolveAgentForm( case "RESET": return { ...state, userModified: INITIAL_USER_MODIFIED }; + default: + throw new Error("unreachable"); } } diff --git a/packages/app/src/hooks/use-agent-form-state.ts b/packages/app/src/hooks/use-agent-form-state.ts index 052d58b7f..989dfbeff 100644 --- a/packages/app/src/hooks/use-agent-form-state.ts +++ b/packages/app/src/hooks/use-agent-form-state.ts @@ -459,7 +459,7 @@ export function useAgentFormState(options: UseAgentFormStateOptions = {}): UseAg }, []); const refreshProviderModels = useCallback(() => { - refreshSnapshot(); + void refreshSnapshot(); }, [refreshSnapshot]); const refetchProviderModelsIfStale = useCallback(() => { diff --git a/packages/app/src/keyboard/keyboard-shortcuts.ts b/packages/app/src/keyboard/keyboard-shortcuts.ts index 6c48662d8..8141128cd 100644 --- a/packages/app/src/keyboard/keyboard-shortcuts.ts +++ b/packages/app/src/keyboard/keyboard-shortcuts.ts @@ -1055,6 +1055,8 @@ function resolvePayload( return { delta: def.delta }; case "message-input": return { kind: def.kind }; + default: + throw new Error("unreachable"); } } diff --git a/packages/cli/src/commands/onboard.ts b/packages/cli/src/commands/onboard.ts index 7fee4b03c..59fd2b5fb 100644 --- a/packages/cli/src/commands/onboard.ts +++ b/packages/cli/src/commands/onboard.ts @@ -432,7 +432,7 @@ async function waitForDaemonReadyWithUi(args: { } else { log.error(message); } - process.exit(1); + return process.exit(1); } } diff --git a/packages/cli/src/commands/worktree/create.ts b/packages/cli/src/commands/worktree/create.ts index 689723ed4..7e8f183b4 100644 --- a/packages/cli/src/commands/worktree/create.ts +++ b/packages/cli/src/commands/worktree/create.ts @@ -123,6 +123,8 @@ export function toDaemonCreateInput(parsed: ParsedWorktreeCreateInput) { action: "checkout" as const, githubPrNumber: parsed.target.prNumber, }; + default: + throw new Error("unreachable"); } } diff --git a/packages/server/src/server/agent/agent-manager.ts b/packages/server/src/server/agent/agent-manager.ts index 14da6eb92..74e4d37e9 100644 --- a/packages/server/src/server/agent/agent-manager.ts +++ b/packages/server/src/server/agent/agent-manager.ts @@ -1647,7 +1647,7 @@ export class AgentManager { { agentId, foregroundTurnId }, "cancelAgentRun: foreground turn still active after timeout, force-canceling", ); - this.dispatchSessionEvent(agent, { + void this.dispatchSessionEvent(agent, { type: "turn_canceled", provider: agent.provider, reason: "interrupted", diff --git a/packages/server/src/server/agent/mcp-server.ts b/packages/server/src/server/agent/mcp-server.ts index a381385b3..5ba6a6d4a 100644 --- a/packages/server/src/server/agent/mcp-server.ts +++ b/packages/server/src/server/agent/mcp-server.ts @@ -2104,6 +2104,8 @@ function mcpCreateWorktreeInput( return { input: { ...base, action: "checkout", githubPrNumber: target.prNumber }, }; + default: + throw new Error("unreachable"); } } diff --git a/packages/server/src/server/agent/mcp-shared.ts b/packages/server/src/server/agent/mcp-shared.ts index 420a58ce7..4890dd0cd 100644 --- a/packages/server/src/server/agent/mcp-shared.ts +++ b/packages/server/src/server/agent/mcp-shared.ts @@ -327,11 +327,11 @@ export function setupFinishNotification(params: SetupFinishNotificationParams): return; } if (event.agent.lifecycle === "error") { - notify("errored"); + void notify("errored"); return; } if (event.agent.lifecycle === "idle" && hasSeenRunning) { - notify("finished"); + void notify("finished"); return; } if (event.agent.lifecycle === "closed") { @@ -343,7 +343,7 @@ export function setupFinishNotification(params: SetupFinishNotificationParams): } if (event.event.type === "permission_requested") { - notify("needs permission"); + void notify("needs permission"); } }, { agentId: childAgentId, replayState: false }, @@ -362,7 +362,7 @@ export function setupFinishNotification(params: SetupFinishNotificationParams): if (childSnapshot.lifecycle === "running") { hasSeenRunning = true; } else if (childSnapshot.lifecycle === "error") { - notify("errored"); + void notify("errored"); } } diff --git a/packages/server/src/server/agent/prompt-attachments.ts b/packages/server/src/server/agent/prompt-attachments.ts index ea432edfe..049239bcc 100644 --- a/packages/server/src/server/agent/prompt-attachments.ts +++ b/packages/server/src/server/agent/prompt-attachments.ts @@ -54,6 +54,8 @@ export function renderPromptAttachmentAsText(attachment: AgentAttachment): strin }); return lines.join("\n"); } + default: + throw new Error("unreachable"); } } diff --git a/packages/server/src/server/daemon-e2e/agent-configs.ts b/packages/server/src/server/daemon-e2e/agent-configs.ts index ead0551cb..7068af84d 100644 --- a/packages/server/src/server/daemon-e2e/agent-configs.ts +++ b/packages/server/src/server/daemon-e2e/agent-configs.ts @@ -134,6 +134,8 @@ export function isProviderAvailable(provider: AgentProvider): Promise { Boolean(process.env.OPENROUTER_API_KEY) || existsSync(join(homedir(), ".pi", "agent", "auth.json"))) ); + default: + return false; } })(); diff --git a/packages/server/src/server/workspace-directory.ts b/packages/server/src/server/workspace-directory.ts index 3cfc2cc43..229adac5e 100644 --- a/packages/server/src/server/workspace-directory.ts +++ b/packages/server/src/server/workspace-directory.ts @@ -116,6 +116,8 @@ export class WorkspaceDirectory { return workspace.name.toLocaleLowerCase(); case "project_id": return workspace.projectId.toLocaleLowerCase(); + default: + throw new Error("unreachable"); } }, }); diff --git a/packages/server/src/shared/tool-call-display.ts b/packages/server/src/shared/tool-call-display.ts index 2cadd2d65..3f6527632 100644 --- a/packages/server/src/shared/tool-call-display.ts +++ b/packages/server/src/shared/tool-call-display.ts @@ -122,6 +122,8 @@ function buildCanonicalDetailDisplay(input: ToolCallDisplayInput): DetailDisplay }; case "unknown": return {}; + default: + throw new Error("unreachable"); } } diff --git a/packages/server/src/terminal/terminal-session-controller.ts b/packages/server/src/terminal/terminal-session-controller.ts index 269b41724..f2d4aa6a8 100644 --- a/packages/server/src/terminal/terminal-session-controller.ts +++ b/packages/server/src/terminal/terminal-session-controller.ts @@ -145,6 +145,8 @@ export class TerminalSessionController { return this.handleKillTerminalRequest(msg); case "capture_terminal_request": return this.handleCaptureTerminalRequest(msg); + default: + return undefined; } }