Skip to content

fix(typecheck): type Doctor screen state#1522

Merged
kevincodex1 merged 8 commits into
Gitlawb:mainfrom
chioarub:fix/typecheck-doctor-screen
Jun 9, 2026
Merged

fix(typecheck): type Doctor screen state#1522
kevincodex1 merged 8 commits into
Gitlawb:mainfrom
chioarub:fix/typecheck-doctor-screen

Conversation

@chioarub

@chioarub chioarub commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Type the Doctor screen props, dist-tag promise, and nullable async state so Doctor diagnostics no longer collapse to never/null during typecheck.
  • Accept the repo's readonly Tools alias in Doctor context-warning helpers instead of requiring mutable Tool[].
  • Add Doctor screen render coverage for resolved dist tags and version-fetch failure fallback.

Impact

  • user-facing impact: none expected; this is a type-surface cleanup with Doctor render coverage.
  • developer/maintainer impact: removes the Doctor screen/context-warning helper diagnostics from the repo-wide typecheck backlog tracked in fix: (All-call) TypeScript cleanup PRs needed #1486.

Testing

  • bun test src/screens/Doctor.test.tsx src/services/mcp/doctor.test.ts src/commands/mcp/doctorCommand.test.ts src/__tests__/doctorContextWarnings.test.ts src/__tests__/statusNoticeLocalModel.test.ts
  • env -u CLAUDE_CODE_USE_OPENAI -u OPENAI_API_KEY -u OPENAI_BASE_URL -u OPENAI_MODEL -u CLAUDE_CODE_MAX_RETRIES -u CLAUDE_CODE_UNATTENDED_RETRY bun run check
  • bun run test:provider
  • env -u CLAUDE_CODE_USE_OPENAI -u OPENAI_API_KEY -u OPENAI_BASE_URL -u OPENAI_MODEL -u CLAUDE_CODE_MAX_RETRIES -u CLAUDE_CODE_UNATTENDED_RETRY npm run test:provider-recommendation
  • bun run web:typecheck
  • git diff --check

Notes

  • Part of fix: (All-call) TypeScript cleanup PRs needed #1486.
  • bun run typecheck still exits 2 because of the existing repo-wide baseline; the post-change log has 1639 TypeScript diagnostics and no diagnostics for src/screens/Doctor.tsx, src/screens/Doctor.test.tsx, or src/utils/doctorContextWarnings.ts.
  • provider/model path tested: neutral CI-style environment with local provider override variables unset.
  • screenshots attached: n/a, no intended UI behavior change.
  • follow-up work or known limitations: remaining unrelated typecheck backlog in fix: (All-call) TypeScript cleanup PRs needed #1486.

Summary by CodeRabbit

  • Refactor

    • Improved code organization and stronger typing around diagnostics and tools
    • Extracted distribution-tag resolution into a dedicated resolver with clearer dependency wiring
  • New Features

    • Added a loader utility for diagnostic retrieval with explicit success/failure signaling
  • Bug Fixes

    • More robust fallback and error handling when dist-tag or diagnostic fetching fails
  • Tests

    • Added tests covering diagnostic loading and dist-tag resolution behaviors

@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Doctor screen gains explicit TypeScript annotations, extracts dist-tag resolution into resolveDoctorDistTags, extracts diagnostic loading into loadDoctorDiagnostic, updates Doctor state/effect wiring to use those modules, and adds tests for both resolver and loader behaviors.

Changes

Doctor Screen Refactoring

Layer / File(s) Summary
Type imports and prop signatures
src/utils/doctorContextWarnings.ts, src/screens/Doctor.tsx
Switch Tool[]Tools in doctorContextWarnings; add Tools import to Doctor; change DistTagsDisplay prop to { promise: Promise<NpmDistTags> }; annotate Doctor parameter as Props.
Doctor state wiring and rendering changes
src/screens/Doctor.tsx
Memoize tools with Tools, compute distTagsPromise via useMemo calling resolveDoctorDistTags, refactor main useEffect to call loadDoctorDiagnostic and run async IIFE to set agent info/context warnings/lock state, add early diagnostic-load-failed return, and adjust Updates section JSX to render DistTagsDisplay inside Suspense.
Dist-tag resolver implementation
src/screens/doctorDistTags.ts
New resolveDoctorDistTags accepts injected deps (getDoctorDiagnostic, getNpmDistTags, getGcsDistTags), selects provider by installationType, and returns FAILED_DIST_TAGS ({ latest: null, stable: null }) on errors.
Dist-tag resolver tests
src/screens/doctorDistTags.test.ts
Tests verify selection for npm-global vs native, fallback when selected provider throws, and behavior when getDoctorDiagnostic throws.
Diagnostic loader and tests
src/screens/doctorDiagnosticLoad.ts, src/screens/doctorDiagnosticLoad.test.ts
New loadDoctorDiagnostic calls getDoctorDiagnostic and updates handlers (setDiagnostic, setDiagnosticLoadFailed); tests cover success and failure paths.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • jatmn
  • kevincodex1
🚥 Pre-merge checks | ✅ 5 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Risk Surface Disclosed ⚠️ Warning PR touches MCP and network (dist-tags fetching), but review comment does not call out risk surface or confirm type-only refactoring nature despite sensitive areas affected. Review should document that MCP/network/async changes are type-only refactoring, not behavioral changes, and confirm no new outbound calls or permission logic.
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed Title accurately summarizes the main change: explicit typing of Doctor screen state to resolve typecheck diagnostics.
Description check ✅ Passed Description includes all required sections with sufficient detail: clear summary of changes, explicit user/maintainer impact, comprehensive testing evidence, and relevant notes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
No Hidden Policy Change ✅ Passed PR contains only type-surface refactoring with no hidden policy changes. No new routing, telemetry, trust-model, permission policy, or product decisions detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@src/screens/Doctor.test.tsx`:
- Around line 98-108: The teardown function restoreActualModules currently
re-registers mocks via mock.module(...) which leaks module-mock state across
tests; instead remove the mock.module(...) calls from restoreActualModules and
ensure teardown only restores original modules by stopping or clearing mocks
(e.g., call the test runner's mock stop/reset APIs or restore the saved actual*
variables without re-registering hooks). Update restoreActualModules and any
afterEach cleanup so they do not call mock.module('../utils/doctorDiagnostic.js'
/ '../utils/autoUpdater.js' / '../utils/nativeInstaller/pidLock.js') and use
proper mock stop/reset (or jest.resetModules()/mock.restore equivalents) to
fully isolate tests.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 909a4226-acf7-4a6f-8dc5-3f428ea1eb48

📥 Commits

Reviewing files that changed from the base of the PR and between e357d59 and cf97ee2.

📒 Files selected for processing (3)
  • src/screens/Doctor.test.tsx
  • src/screens/Doctor.tsx
  • src/utils/doctorContextWarnings.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: smoke-and-tests
🧰 Additional context used
📓 Path-based instructions (2)
**/*

⚙️ CodeRabbit configuration file

**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.

Files:

  • src/screens/Doctor.tsx
  • src/utils/doctorContextWarnings.ts
  • src/screens/Doctor.test.tsx
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}

⚙️ CodeRabbit configuration file

{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.

Files:

  • src/screens/Doctor.test.tsx
🔇 Additional comments (2)
src/screens/Doctor.tsx (1)

22-22: LGTM!

Also applies to: 60-62, 105-105, 115-115, 119-122

src/utils/doctorContextWarnings.ts (1)

2-2: LGTM!

Also applies to: 146-146, 269-269, 350-350

Comment thread src/screens/Doctor.test.tsx Outdated
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 4, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 4, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/screens/Doctor.test.tsx (1)

200-263: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add a native-install dist-tag source regression test.

Both tests keep installationType: 'npm-global', so the native -> getGcsDistTags branch introduced in Doctor remains unverified. Please add a focused case that sets installationType: 'native' and asserts GCS tags are rendered (and npm tags are not used).

As per coding guidelines, "Review tests for meaningful coverage of the changed behavior ... Block when risky runtime changes lack focused regression coverage."

🤖 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/screens/Doctor.test.tsx` around lines 200 - 263, Add a focused regression
test in Doctor.test.tsx that covers the native-install branch by rendering
<Doctor ... deps={doctorDeps} /> with installationType set to 'native' (override
doctorDeps or construct a new deps object) and mock getGcsDistTags to return
deterministic dist-tags while ensuring getNpmDistTags is not used; then assert
the output contains the GCS/`native` tags (e.g., "Latest version" / "Stable
version" from the GCS mock) and that npm tag strings are not present. Locate the
test block near the existing Doctor tests, reference the Doctor component and
the helper mocks getGcsDistTags and getNpmDistTags, and clean up streams exactly
as the other tests do (root.unmount, stdin.end, stdout.end, await Bun.sleep(0)).
🤖 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.

Outside diff comments:
In `@src/screens/Doctor.test.tsx`:
- Around line 200-263: Add a focused regression test in Doctor.test.tsx that
covers the native-install branch by rendering <Doctor ... deps={doctorDeps} />
with installationType set to 'native' (override doctorDeps or construct a new
deps object) and mock getGcsDistTags to return deterministic dist-tags while
ensuring getNpmDistTags is not used; then assert the output contains the
GCS/`native` tags (e.g., "Latest version" / "Stable version" from the GCS mock)
and that npm tag strings are not present. Locate the test block near the
existing Doctor tests, reference the Doctor component and the helper mocks
getGcsDistTags and getNpmDistTags, and clean up streams exactly as the other
tests do (root.unmount, stdin.end, stdout.end, await Bun.sleep(0)).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 7d98571a-bfeb-411a-acf2-b1272db9fb61

📥 Commits

Reviewing files that changed from the base of the PR and between cf1e39f and 6c17091.

📒 Files selected for processing (2)
  • src/screens/Doctor.test.tsx
  • src/screens/Doctor.tsx
📜 Review details
🧰 Additional context used
📓 Path-based instructions (2)
**/*

⚙️ CodeRabbit configuration file

**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.

Files:

  • src/screens/Doctor.test.tsx
  • src/screens/Doctor.tsx
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}

⚙️ CodeRabbit configuration file

{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.

Files:

  • src/screens/Doctor.test.tsx
🔇 Additional comments (1)
src/screens/Doctor.tsx (1)

39-56: LGTM!

Also applies to: 125-129, 143-146, 177-223

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 4, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 4, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@src/screens/Doctor.tsx`:
- Around line 125-129: The diagnostic promise can reject and leave the Doctor
screen stuck; update the places where getDoctorDiagnostic is invoked (both the
direct call around lines 160-162 and the useMemo that creates distTagsPromise
via resolveDoctorDistTags) to catch errors and return a safe fallback so no
promise remains unhandled: wrap the getDoctorDiagnostic call in a try/catch or
append .catch(() => fallbackDiagnostic) and ensure resolveDoctorDistTags is
called with a diagnostic-resolving function that never throws (or returns a
resolved fallback), and propagate a sensible default from distTagsPromise so the
UI switches out of loading even when diagnostics fail.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 989d0960-230e-4e2e-8a5a-ff8f87799cc5

📥 Commits

Reviewing files that changed from the base of the PR and between df2f73b and a368e70.

📒 Files selected for processing (3)
  • src/screens/Doctor.tsx
  • src/screens/doctorDistTags.test.ts
  • src/screens/doctorDistTags.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (2)
**/*

⚙️ CodeRabbit configuration file

**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.

Files:

  • src/screens/doctorDistTags.ts
  • src/screens/doctorDistTags.test.ts
  • src/screens/Doctor.tsx
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}

⚙️ CodeRabbit configuration file

{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.

Files:

  • src/screens/doctorDistTags.test.ts
🔇 Additional comments (3)
src/screens/Doctor.tsx (1)

35-35: LGTM!

Also applies to: 106-118, 170-170, 180-180, 186-189, 205-205

src/screens/doctorDistTags.ts (1)

4-27: LGTM!

src/screens/doctorDistTags.test.ts (1)

1-88: LGTM!

Comment thread src/screens/Doctor.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@src/screens/Doctor.tsx`:
- Around line 163-166: The PR currently implies it is fully merge-ready despite
repo-wide typecheck failures; update any status text or logic around the
diagnostic load in this file so it doesn't claim readiness when checks are
failing: ensure loadDoctorDiagnostic is invoked normally (keep the call using
loadDoctorDiagnostic with getDoctorDiagnostic) but change the post-call handling
to explicitly surface CI/typecheck failure state instead of marking success—use
setDiagnosticLoadFailed(true) when the repo-wide typecheck baseline or CI checks
are failing and avoid calling setDiagnostic in that case; also update any
user-visible "merge-ready" or success messaging in this file to mention required
GitHub Checks and human review must pass before merge.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 567319f2-f411-4d01-8551-611fed1f10f1

📥 Commits

Reviewing files that changed from the base of the PR and between a368e70 and 89c90e0.

📒 Files selected for processing (5)
  • src/screens/Doctor.tsx
  • src/screens/doctorDiagnosticLoad.test.ts
  • src/screens/doctorDiagnosticLoad.ts
  • src/screens/doctorDistTags.test.ts
  • src/screens/doctorDistTags.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: smoke-and-tests
🧰 Additional context used
📓 Path-based instructions (2)
**/*

⚙️ CodeRabbit configuration file

**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.

Files:

  • src/screens/doctorDiagnosticLoad.ts
  • src/screens/doctorDistTags.ts
  • src/screens/doctorDistTags.test.ts
  • src/screens/doctorDiagnosticLoad.test.ts
  • src/screens/Doctor.tsx
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}

⚙️ CodeRabbit configuration file

{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.

Files:

  • src/screens/doctorDistTags.test.ts
  • src/screens/doctorDiagnosticLoad.test.ts
🔇 Additional comments (5)
src/screens/doctorDistTags.ts (1)

20-30: LGTM!

src/screens/doctorDistTags.test.ts (1)

78-85: LGTM!

src/screens/Doctor.tsx (1)

35-35: LGTM!

Also applies to: 122-122, 163-166, 245-247

src/screens/doctorDiagnosticLoad.ts (1)

1-23: LGTM!

src/screens/doctorDiagnosticLoad.test.ts (1)

1-59: LGTM!

Comment thread src/screens/Doctor.tsx

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the contribution. I do not see any actionable issues from my review.

@kevincodex1

@kevincodex1 kevincodex1 merged commit 6cb3493 into Gitlawb:main Jun 9, 2026
3 checks passed
@chioarub chioarub deleted the fix/typecheck-doctor-screen branch June 9, 2026 05:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants