Skip to content

chore(lint): add core/webview to no-floating-promises ratchet#950

Open
morgan-coded wants to merge 1 commit into
Zoo-Code-Org:mainfrom
morgan-coded:webview-floating-promises-949
Open

chore(lint): add core/webview to no-floating-promises ratchet#950
morgan-coded wants to merge 1 commit into
Zoo-Code-Org:mainfrom
morgan-coded:webview-floating-promises-949

Conversation

@morgan-coded

@morgan-coded morgan-coded commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Picked up #949 from the #912 review-thread invitation and triaged the live core/webview set: 75 calls are awaited and 14 are explicitly voided. Two of the voids are flagged for your review as genuinely ambiguous: the constructor updateGlobalState("codebaseIndexModels", ...) in ClineProvider.ts (constructors cannot await) and workspaceTracker?.initializeFilePaths() in the webviewDidLaunch case, where the existing "Don't await" comment is preserved because a workspace scan would sit on the launch path. Both keep baseline timing and rejection behavior exactly.

Added core/webview/**/*.ts to the existing ratchet. I ran the issue repro with zero warnings across all three ratcheted directories, the full suite with 6,785 passing, plus lint and typecheck.

Fixes #949

Summary by CodeRabbit

  • Bug Fixes
    • Improved reliability and ordering of webview updates across task, marketplace, terminal, file, and indexing workflows.
    • Fixed checkpoint restoration to wait for task cancellation before continuing.
    • Improved error handling when opening rule and skill files.
    • Added protection against reading files outside the workspace.
  • Chores
    • Strengthened checks for asynchronous operations to help prevent missed errors and inconsistent states.

Copilot AI review requested due to automatic review settings July 19, 2026 16:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Webview lifecycle, message handlers, file access, indexing, marketplace operations, and supporting handlers now explicitly await required asynchronous work or mark intentional fire-and-forget calls. ESLint enforcement now covers core/webview, and file reads validate workspace boundaries.

Changes

Webview asynchronous control

Layer / File(s) Summary
Provider lifecycle and state delivery
src/core/webview/ClineProvider.ts, src/core/webview/__tests__/ClineProvider.spec.ts
State and marketplace posts, cleanup, and test state updates are awaited; intentional background operations use void; webview resources and listeners are initialized explicitly.
Message dispatch and file flows
src/core/webview/webviewMessageHandler.ts
Task, model, media, file, prompt, mode, authentication, and command operations now await asynchronous work; file reads enforce workspace boundaries.
Indexing and marketplace flows
src/core/webview/webviewMessageHandler.ts
Indexing status, data clearing, marketplace results, and rate-limit responses await webview posts while indexing starts remain explicitly non-blocking.
Supporting handler and lint enforcement
src/core/webview/checkpointRestoreHandler.ts, src/core/webview/rulesMessageHandler.ts, src/core/webview/skillsMessageHandler.ts, src/core/webview/webviewMessageHandler.ts, src/eslint.config.mjs
Restore, rule, skill, and command handlers await file operations, and the no-floating-promises ratchet now covers webview TypeScript files.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

  • Zoo-Code-Org/Zoo-Code#251: Applies similar explicit promise handling and ESLint scoping changes in activation command handlers.

Suggested labels: awaiting-review

Suggested reviewers: taltas, navedmerchant, hannesrudolph, edelauna, jamesrobert20

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately describes the main change: extending the no-floating-promises ratchet to core/webview.
Description check ✅ Passed The PR description includes the linked issue, a change summary, and testing details, which covers the template's key sections.
Linked Issues check ✅ Passed The changes triage the core/webview floating-promise violations and add the new ESLint glob, matching issue #949.
Out of Scope Changes check ✅ Passed The modified files and test updates are all directly related to the no-floating-promises ratchet in core/webview.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Jul 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 37.23404% with 59 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/core/webview/webviewMessageHandler.ts 26.08% 51 Missing ⚠️
src/core/webview/ClineProvider.ts 57.89% 7 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (4)
src/core/webview/ClineProvider.ts (1)

845-871: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Prefer destructuring with await over .then().

Mixing await with .then() is less idiomatic than using standard async/await destructuring. Consider refactoring this initialization block to use standard destructuring for better readability.

♻️ Proposed refactor
-		await this.getState().then(
-			({
-				terminalShellIntegrationTimeout = Terminal.defaultShellIntegrationTimeout,
-				terminalShellIntegrationDisabled = false,
-				terminalCommandDelay = 0,
-				terminalZshClearEolMark = true,
-				terminalZshOhMy = false,
-				terminalZshP10k = false,
-				terminalPowershellCounter = false,
-				terminalZdotdir = false,
-				terminalProfile,
-				ttsEnabled,
-				ttsSpeed,
-			}) => {
-				Terminal.setShellIntegrationTimeout(terminalShellIntegrationTimeout)
-				Terminal.setShellIntegrationDisabled(terminalShellIntegrationDisabled)
-				Terminal.setCommandDelay(terminalCommandDelay)
-				Terminal.setTerminalZshClearEolMark(terminalZshClearEolMark)
-				Terminal.setTerminalZshOhMy(terminalZshOhMy)
-				Terminal.setTerminalZshP10k(terminalZshP10k)
-				Terminal.setPowershellCounter(terminalPowershellCounter)
-				Terminal.setTerminalZdotdir(terminalZdotdir)
-				Terminal.setTerminalProfile(terminalProfile)
-				setTtsEnabled(ttsEnabled ?? false)
-				setTtsSpeed(ttsSpeed ?? 1)
-			},
-		)
+		const {
+			terminalShellIntegrationTimeout = Terminal.defaultShellIntegrationTimeout,
+			terminalShellIntegrationDisabled = false,
+			terminalCommandDelay = 0,
+			terminalZshClearEolMark = true,
+			terminalZshOhMy = false,
+			terminalZshP10k = false,
+			terminalPowershellCounter = false,
+			terminalZdotdir = false,
+			terminalProfile,
+			ttsEnabled,
+			ttsSpeed,
+		} = await this.getState()
+
+		Terminal.setShellIntegrationTimeout(terminalShellIntegrationTimeout)
+		Terminal.setShellIntegrationDisabled(terminalShellIntegrationDisabled)
+		Terminal.setCommandDelay(terminalCommandDelay)
+		Terminal.setTerminalZshClearEolMark(terminalZshClearEolMark)
+		Terminal.setTerminalZshOhMy(terminalZshOhMy)
+		Terminal.setTerminalZshP10k(terminalZshP10k)
+		Terminal.setPowershellCounter(terminalPowershellCounter)
+		Terminal.setTerminalZdotdir(terminalZdotdir)
+		Terminal.setTerminalProfile(terminalProfile)
+		setTtsEnabled(ttsEnabled ?? false)
+		setTtsSpeed(ttsSpeed ?? 1)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/webview/ClineProvider.ts` around lines 845 - 871, Refactor the
initialization block in ClineProvider to await getState() directly and
destructure the returned state in the surrounding async method, then keep the
existing Terminal setters and TTS defaults unchanged.
src/core/webview/checkpointRestoreHandler.ts (1)

34-41: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Remove redundant polling loop.

Now that currentCline.abortTask() is explicitly awaited, the task is guaranteed to have completed its abort sequence (and this.abort is synchronously set to true within it). The subsequent pWaitFor polling loop is therefore redundant.

♻️ Proposed refactor
 			await currentCline.abortTask()
-			// Wait a bit for the abort to complete
-			await pWaitFor(() => currentCline.abort === true, {
-				timeout: 1000,
-				interval: 50,
-			}).catch(() => {
-				// Continue even if timeout - the abort flag should be set
-			})
 		}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/webview/checkpointRestoreHandler.ts` around lines 34 - 41, Remove
the redundant pWaitFor polling and its timeout catch after awaiting
currentCline.abortTask() in the checkpoint restore flow; rely on the awaited
abortTask completion and synchronous abort flag update before continuing.
src/core/webview/webviewMessageHandler.ts (2)

1298-1302: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Wrap the switch case in a block.

To prevent potential lexical scope pollution and resolve the noSwitchDeclarations static analysis warning, wrap the case logic in a block.

♻️ Proposed refactor
-		case "requestVsCodeLmModels":
+		case "requestVsCodeLmModels": {
 			const vsCodeLmModels = await getVsCodeLmModels()
 			// TODO: Cache like we do for OpenRouter, etc?
 			await provider.postMessageToWebview({ type: "vsCodeLmModels", vsCodeLmModels })
 			break
+		}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/webview/webviewMessageHandler.ts` around lines 1298 - 1302, Wrap the
"requestVsCodeLmModels" switch case body in a block so the declarations of
vsCodeLmModels remain scoped to that case and satisfy noSwitchDeclarations,
preserving the existing model retrieval and provider.postMessageToWebview
behavior.

Source: Linters/SAST tools


3006-3016: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Remove the redundant initialization block.

Since await manager.initialize(provider.contextProxy) is already called successfully a few lines above (on line 3004) before reaching this block, checking !manager.isInitialized and attempting to initialize and start indexing again is redundant.

♻️ Proposed refactor
 					const currentState = manager.state
 					if (currentState === "Standby" || currentState === "Error") {
 						void manager.startIndexing()
-
-						if (!manager.isInitialized) {
-							await manager.initialize(provider.contextProxy)
-							if (manager.state === "Standby" || manager.state === "Error") {
-								void manager.startIndexing()
-							}
-						}
 					}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/webview/webviewMessageHandler.ts` around lines 3006 - 3016, Remove
the redundant !manager.isInitialized check and its nested
manager.initialize(provider.contextProxy) and second manager.startIndexing()
call from the currentState handling block. Keep the initial
manager.startIndexing() behavior for Standby and Error states unchanged, relying
on the earlier successful initialization.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/core/webview/checkpointRestoreHandler.ts`:
- Around line 34-41: Remove the redundant pWaitFor polling and its timeout catch
after awaiting currentCline.abortTask() in the checkpoint restore flow; rely on
the awaited abortTask completion and synchronous abort flag update before
continuing.

In `@src/core/webview/ClineProvider.ts`:
- Around line 845-871: Refactor the initialization block in ClineProvider to
await getState() directly and destructure the returned state in the surrounding
async method, then keep the existing Terminal setters and TTS defaults
unchanged.

In `@src/core/webview/webviewMessageHandler.ts`:
- Around line 1298-1302: Wrap the "requestVsCodeLmModels" switch case body in a
block so the declarations of vsCodeLmModels remain scoped to that case and
satisfy noSwitchDeclarations, preserving the existing model retrieval and
provider.postMessageToWebview behavior.
- Around line 3006-3016: Remove the redundant !manager.isInitialized check and
its nested manager.initialize(provider.contextProxy) and second
manager.startIndexing() call from the currentState handling block. Keep the
initial manager.startIndexing() behavior for Standby and Error states unchanged,
relying on the earlier successful initialization.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 14b8e4b5-aae8-4335-ae15-adc5c60d0fe8

📥 Commits

Reviewing files that changed from the base of the PR and between 6e05ae9 and 3e17542.

📒 Files selected for processing (7)
  • src/core/webview/ClineProvider.ts
  • src/core/webview/__tests__/ClineProvider.spec.ts
  • src/core/webview/checkpointRestoreHandler.ts
  • src/core/webview/rulesMessageHandler.ts
  • src/core/webview/skillsMessageHandler.ts
  • src/core/webview/webviewMessageHandler.ts
  • src/eslint.config.mjs

@github-actions github-actions Bot added the awaiting-review PR changes are ready and waiting for maintainer re-review label Jul 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-review PR changes are ready and waiting for maintainer re-review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

chore(lint): add core/webview to no-floating-promises ratchet

2 participants