Skip to content

[issues/54] Phase 3: Navigation toast settings#491

Merged
couimet merged 7 commits into
mainfrom
issues/54
Mar 23, 2026
Merged

[issues/54] Phase 3: Navigation toast settings#491
couimet merged 7 commits into
mainfrom
issues/54

Conversation

@couimet
Copy link
Copy Markdown
Owner

@couimet couimet commented Mar 22, 2026

Summary

Adds two user-configurable settings that let power users control which toasts appear after clicking a RangeLink. This completes Phase 3 of the Enhanced Navigation Feedback epic (#47), following Phase 1 (clamping detection) and Phase 2 (toast classification).

The issue's proposed toastDelay setting was dropped because VS Code's showInformationMessage/showWarningMessage API does not support duration parameters — toasts remain until dismissed by the user.

Changes

  • Added rangelink.navigation.showNavigatedToast (boolean, default: true) — controls the info toast after successful navigation
  • Added rangelink.navigation.showClampingWarning (boolean, default: true) — controls the warning toast when navigation is clamped to file boundaries
  • Injected ConfigReader into RangeLinkNavigationHandler to read settings, following the same pattern as RangeLinkService
  • Error toasts remain always-on — errors need visibility regardless of user preference
  • Default behavior is unchanged (both settings default to true)
  • Named defaults in settingDefaults.ts for consistency with other settings

Test Plan

  • All existing unit tests pass (1655 tests, 91 suites)
  • test:release passes — 110 integration tests in VS Code host, 0 failures
  • QA validator: 55/55 automated TCs matched
  • New unit tests: suppress info toast, suppress clamping warning, default behavior (3 tests)
  • New integration tests: setting-controlled toast suppression with log-based assertions (3 tests)
  • New QA TCs: navigation-toast-settings-001 through 003 (all automated)
  • Contract tests updated: 2 new setting entries verified, property count 12 → 14

Related

Summary by CodeRabbit

  • New Features

    • Added two navigation settings to control feedback toasts: showNavigatedToast and showClampingWarning (both default true). Disable to suppress the respective notification; navigation behavior unchanged.
  • Documentation

    • Documented the new Navigation Settings and added changelog entry.
  • Tests

    • Added unit, integration, and QA tests validating the configurable toast behavior.

Charles Ouimet added 4 commits March 22, 2026 17:15
Added two user-configurable settings that allow power users to mute navigation toasts without losing the navigation functionality itself:

- `rangelink.navigation.showNavigatedToast` (default: true) — controls the info toast shown after successful exact navigation
- `rangelink.navigation.showClampingWarning` (default: true) — controls the warning toast shown when navigation is clamped to file boundaries

Injected `ConfigReader` into `RangeLinkNavigationHandler` as a 4th constructor parameter, following the same pattern used in `RangeLinkService`. Error toasts remain always-on — errors need visibility regardless of user preference.

The issue's proposed `toastDelay` setting was dropped because VS Code's `showInformationMessage`/`showWarningMessage` API does not support duration parameters.

Benefits:
- Power users can silence navigated/clamping toasts for a quieter workflow
- Error toasts always shown for visibility
- Default behavior unchanged (both settings default to true)
…tings

Added 3 integration tests that verify setting-controlled toast suppression in a real VS Code host:
- showNavigatedToast=false: navigation succeeds silently (no info toast)
- showClampingWarning=false: clamped navigation succeeds silently (no warning toast)
- Default settings: info toast shown after successful navigation (baseline)

Each test uses log-based toast assertions and verifies navigation still works (correct selection position) even when toasts are suppressed.
Added CHANGELOG entry under [Unreleased] Added for the two navigation toast settings with descriptions of what each controls.

Added "Navigation Settings" section to README Configuration with a table documenting both settings, defaults, and a note that error toasts always appear. Section has <sup>Unreleased</sup> marker per trunk-based documentation convention.
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 22, 2026

QA Coverage OK

New settings for controlling navigation toast notifications were introduced, allowing users to suppress specific toasts after navigation actions.


Generated by QA Gap Check (GPT-4o-mini via GitHub Models)

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 22, 2026

Warning

Rate limit exceeded

@couimet has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 10 minutes and 1 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b2420e9f-c241-4d45-a570-461cfedb5c1d

📥 Commits

Reviewing files that changed from the base of the PR and between c22d488 and 900edad.

📒 Files selected for processing (1)
  • packages/rangelink-vscode-extension/src/__integration-tests__/helpers/logBasedUiAssertions.ts

Walkthrough

This PR adds two new boolean settings—rangelink.navigation.showNavigatedToast and rangelink.navigation.showClampingWarning (both default true)—and makes the navigation handler consult these settings (via an injected ConfigReader) before showing post-navigation info or clamping warning toasts. Docs, package manifest, defaults, keys, tests, and integration QA were updated accordingly.

Changes

Cohort / File(s) Summary
Configuration & Docs
packages/rangelink-vscode-extension/CHANGELOG.md, packages/rangelink-vscode-extension/README.md, packages/rangelink-vscode-extension/package.json
Added two new configuration properties and documentation describing their behavior and defaults.
Setting Keys & Defaults
packages/rangelink-vscode-extension/src/constants/settingKeys.ts, packages/rangelink-vscode-extension/src/constants/settingDefaults.ts
Introduced new exported keys SETTING_NAVIGATION_SHOW_CLAMPING_WARNING, SETTING_NAVIGATION_SHOW_NAVIGATED_TOAST and matching defaults set to true.
Extension Wiring
packages/rangelink-vscode-extension/src/extension.ts, packages/rangelink-vscode-extension/src/navigation/RangeLinkNavigationHandler.ts
Injected ConfigReader into handler; conditionally call showInformationMessage / showWarningMessage based on config booleans, or emit debug suppression logs.
Unit Tests
packages/rangelink-vscode-extension/src/__tests__/navigation/RangeLinkNavigationHandler.test.ts, packages/rangelink-vscode-extension/src/__tests__/constants/packageJsonContracts.test.ts
Updated handler construction to include mockConfigReader; added test suite asserting toast suppression behavior; bumped configuration property count assertions.
Integration & QA Tests / Helpers
packages/rangelink-vscode-extension/src/__integration-tests__/suite/navigationToastSettings.test.ts, packages/rangelink-vscode-extension/src/__integration-tests__/helpers/logBasedUiAssertions.ts, packages/rangelink-vscode-extension/src/__integration-tests__/helpers/index.ts, packages/rangelink-vscode-extension/qa/qa-test-cases-v1.1.0-2026-03-18.yaml
Added integration tests and QA cases validating suppression behavior; added assertSuppressionLogged helper and re-exported it for integration tests.

Sequence Diagram(s)

sequenceDiagram
  participant User as "User (click link)"
  participant Cmd as "handleDocumentLinkClick"
  participant Handler as "RangeLinkNavigationHandler"
  participant Config as "ConfigReader"
  participant IDE as "IDE Adapter (show message)"
  participant Logger as "Logger"

  User->>Cmd: trigger link click
  Cmd->>Handler: navigateTo(target)
  Handler->>Config: getBoolean(showClampingWarning / showNavigatedToast)
  Handler->>IDE: apply navigation (open editor / set selection)
  alt clamping occurred
    Handler->>Config: getBoolean(showClampingWarning, default:true)
    alt true
      Handler->>IDE: showWarningMessage("clamped...")
    else false
      Handler->>Logger: debug("suppressed clamping warning")
    end
  else exact navigation
    Handler->>Config: getBoolean(showNavigatedToast, default:true)
    alt true
      Handler->>IDE: showInformationMessage("Navigated to ...")
    else false
      Handler->>Logger: debug("suppressed navigated toast")
    end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 I hopped to a link and peeked at the coast,
Two tiny switches now quiet the toast.
Clicks still jump true, clamps still make sense,
But silence or cheeps are now your expense.
🥕 Hooray — configurable nibble of peace!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title clearly references issue #54 and describes the main change as adding configurable navigation toast settings, which aligns with the primary changeset content.
Linked Issues check ✅ Passed Implementation covers all coding requirements from #54 and #47: two configurable boolean settings (showNavigatedToast, showClampingWarning) added to package.json, defaults centralized in settingDefaults.ts, settings respected in RangeLinkNavigationHandler, and comprehensive unit/integration tests verify setting-controlled behavior.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing navigation toast settings from #54 and #47; no unrelated modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issues/54

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 and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@packages/rangelink-vscode-extension/src/__integration-tests__/suite/navigationToastSettings.test.ts`:
- Around line 128-132: The test uses assertNoToastLogged with a partial message
'RangeLink: Navigated to' which will never equal the actual toast string and
makes the check ineffective; update the test to pass the exact expected message
into assertNoToastLogged (or derive it using the same message-formatting helper
used when toasts are created) so the assertion compares the full toast text
produced by the extension (e.g., the fully formatted "RangeLink: Navigated to
<filename> @ <line>" string), referencing the assertNoToastLogged call and the
logCapture.getLinesSince usage to locate and correct the expected message.
- Around line 154-159: The current negative assertion uses the partial string
'clamped' which won't detect the actual toast text format; update the check that
calls assertNoToastLogged(lines, { type: 'warning', message: 'clamped' }) to use
the exact expected warning string produced by the code (e.g. "RangeLink:
Navigated to ${filename} @ 50 (clamped: line exceeded file length)") — locate
the test around the variables lastLine and sel.anchor.line and the log capture
call logCapture.getLinesSince('before-toast-settings-002') and replace the
partial message with the precise formatted message (using the test's filename
variable) so the assertion accurately fails when the clamping warning is
emitted.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c5029e05-1b7a-4e08-ba8f-d5dd1a842615

📥 Commits

Reviewing files that changed from the base of the PR and between 3b8e75e and afa0c82.

📒 Files selected for processing (11)
  • packages/rangelink-vscode-extension/CHANGELOG.md
  • packages/rangelink-vscode-extension/README.md
  • packages/rangelink-vscode-extension/package.json
  • packages/rangelink-vscode-extension/qa/qa-test-cases-v1.1.0-2026-03-18.yaml
  • packages/rangelink-vscode-extension/src/__integration-tests__/suite/navigationToastSettings.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/constants/packageJsonContracts.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/navigation/RangeLinkNavigationHandler.test.ts
  • packages/rangelink-vscode-extension/src/constants/settingDefaults.ts
  • packages/rangelink-vscode-extension/src/constants/settingKeys.ts
  • packages/rangelink-vscode-extension/src/extension.ts
  • packages/rangelink-vscode-extension/src/navigation/RangeLinkNavigationHandler.ts

Charles Ouimet added 2 commits March 22, 2026 21:48
The negative toast assertions used partial strings that could never match via `findLogEntry`'s exact `===` comparison, making both assertions no-ops. Fixing the message strings alone still leaves a fragile single-point-of-failure — if `assertNoToastLogged` has a bug, the test silently passes.

The suppression debug logs now include a `suppressedMessage` attribute carrying the exact formatted message that *would* have been shown. A new `assertSuppressionLogged` helper matches on `fn` + `suppressedMessage` in the log JSON context. Integration tests now have a two-sided proof: the suppression log IS present with the exact constructed message AND the toast is NOT present.

Changes:
- `RangeLinkNavigationHandler`: build toast/clamping message before the setting branch; log it as `suppressedMessage` attribute in else-branch
- `logBasedUiAssertions`: added `parseLogContextFull` (extracts arbitrary JSON attrs) and `assertSuppressionLogged` helper
- Integration tests (TC 001, TC 002): use `assertSuppressionLogged` with exact `suppressedMessage` + `assertNoToastLogged`
- Unit tests: verify `suppressedMessage` attribute in both suppression debug log assertions

Ref: #491 (review)
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/rangelink-vscode-extension/src/__integration-tests__/helpers/logBasedUiAssertions.ts (1)

46-61: Minor observation: shared JSON extraction logic.

There's some duplication between parseLogContext and parseLogContextFull for the JSON extraction. Given this is test infrastructure with minimal duplication and slightly different validation requirements, the current approach is acceptable. No action needed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/rangelink-vscode-extension/src/__integration-tests__/helpers/logBasedUiAssertions.ts`
around lines 46 - 61, No code change required: the duplication between
parseLogContext and parseLogContextFull is acceptable for test infra, so leave
both functions (parseLogContextFull and parseLogContext) as-is and do not
consolidate their JSON extraction logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@packages/rangelink-vscode-extension/src/__integration-tests__/helpers/logBasedUiAssertions.ts`:
- Around line 46-61: No code change required: the duplication between
parseLogContext and parseLogContextFull is acceptable for test infra, so leave
both functions (parseLogContextFull and parseLogContext) as-is and do not
consolidate their JSON extraction logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 530e658a-af39-4803-9eed-559f4fd0077c

📥 Commits

Reviewing files that changed from the base of the PR and between afa0c82 and c22d488.

📒 Files selected for processing (5)
  • packages/rangelink-vscode-extension/src/__integration-tests__/helpers/index.ts
  • packages/rangelink-vscode-extension/src/__integration-tests__/helpers/logBasedUiAssertions.ts
  • packages/rangelink-vscode-extension/src/__integration-tests__/suite/navigationToastSettings.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/navigation/RangeLinkNavigationHandler.test.ts
  • packages/rangelink-vscode-extension/src/navigation/RangeLinkNavigationHandler.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/rangelink-vscode-extension/src/integration-tests/helpers/index.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/rangelink-vscode-extension/src/integration-tests/suite/navigationToastSettings.test.ts
  • packages/rangelink-vscode-extension/src/tests/navigation/RangeLinkNavigationHandler.test.ts

@couimet couimet merged commit e818771 into main Mar 23, 2026
3 checks passed
@couimet couimet deleted the issues/54 branch March 23, 2026 02:45
couimet pushed a commit that referenced this pull request Mar 24, 2026
…s for logBasedUiAssertions

`getLogCapture.ts` depends on `vscode.extensions` (VS Code host only) and was dragging down Jest coverage metrics with 0% across all metrics. Excluded it from `collectCoverageFrom` — targeted exclusion, not the entire `__integration-tests__/` directory.

`logBasedUiAssertions.ts` is the assertion safety net for all log-based integration tests. Extended the existing test file with tests for `assertSuppressionLogged` (new function from PR #491 feedback) and `parseLogContext` edge cases (invalid JSON, missing fn, non-string fn, non-object parse results). The file is now at 100% coverage across all metrics.
couimet added a commit that referenced this pull request Mar 24, 2026
…extension` (#495)

* [issues/488] Exclude getLogCapture.ts from coverage and add full tests for logBasedUiAssertions

`getLogCapture.ts` depends on `vscode.extensions` (VS Code host only) and was dragging down Jest coverage metrics with 0% across all metrics. Excluded it from `collectCoverageFrom` — targeted exclusion, not the entire `__integration-tests__/` directory.

`logBasedUiAssertions.ts` is the assertion safety net for all log-based integration tests. Extended the existing test file with tests for `assertSuppressionLogged` (new function from PR #491 feedback) and `parseLogContext` edge cases (invalid JSON, missing fn, non-string fn, non-object parse results). The file is now at 100% coverage across all metrics.

* [test] Cover uncovered callbacks in destinationBuilders

The builder functions passed `compareWith`, `isAvailable`, and `getUserInstruction` callbacks into `ComposablePasteDestination` but no test ever invoked them — leaving 6 branches and 7 functions uncovered despite high line coverage.

Added tests that invoke each callback through the built destination's public interface: `equals()` for compareWith, `isAvailable()` for availability delegation, and `getUserInstruction()` for both Success (returns undefined) and Failure (returns instruction string) branches. All three AI assistant builders (Cursor, Claude Code, GitHub Copilot) now have availability spy tests verifying delegation to the detection utilities.

`destinationBuilders.ts` is now at 100% across all coverage metrics.

* [test] Cover BookmarksStore error handling branches

BookmarksStore had 65.78% branch coverage — all the `catch` branches for save failures and unexpected errors were untested. These branches are the safety net that prevents unhandled rejections from propagating to the extension host.

Added tests for both error paths: `globalState.update` rejection (triggers the `save()` catch which wraps as `BOOKMARK_SAVE_FAILED` with operation details and cause), and non-`RangeLinkExtensionError` throws (triggers the generic catch in each CRUD method). Also covered the `error instanceof Error` ternary edge case where a non-Error value is thrown.

BookmarksStore is now at 100/92/100/100 (branches at 92.1%, up from 65.78%).

* [test] Cover BindToTextEditorCommand executeWithUri and getPlaceholder paths

The entire `executeWithUri` path (explorer context menu "Bind Here") was untested — the tab group scanning loop, multi-group picker, and single-group focus were all uncovered. The `getPlaceholder` callback in the file picker was also never invoked.

Added 5 tests covering all `executeWithUri` branches (no matching groups, single group, multi-group picker selection, picker cancellation) and the `getPlaceholder` callback invocation.

`BindToTextEditorCommand.ts` is now at 100/93.75/100/100 (up from 76.78/62.5/75/78.18).

* [test] Cover focus capability resolution branches and factory methods

`FocusCapabilityFactory` had 25% function coverage (only `createAIAssistantCapability` called), `TerminalFocusCapability` had no test for its error catch branch, and `EditorFocusCapability.resolveViewColumn` had an untested fallback when `editor.viewColumn` is undefined.

Added `FocusCapabilityFactory.test.ts` (verifies all 3 factory methods return correct capability types), `TerminalFocusCapability.test.ts` (success + error catch branch), and the undefined-viewColumn fallback test in `EditorFocusCapability.test.ts`.

All capabilities files now at 100% across all individual coverage metrics.

* [test] Add unit tests for SelectionValidator

`SelectionValidator` was extracted from `RangeLinkService` in #493 but had no dedicated test file — 0% branches, 16.66% functions. Added tests covering all three public methods: `validateSelectionsAndShowError` (valid selections, no editor, empty selections), `mapSelectionsForLogging` (populated and empty arrays), and `getLineContentAtSelectionBoundaries` (in-bounds, out-of-bounds, lineAt throws, negative line numbers).

`SelectionValidator.ts` is now at 100% across all coverage metrics.

* [test] Cover getPlaceholder() callbacks in StatusBar and DestinationPicker overflow pickers

The `getPlaceholder` callbacks in secondary terminal/file pickers were never invoked during tests — they were passed to `showTerminalPicker`/`showFilePicker` but the mock implementations only called `onSelected`. Added `getPlaceholder()` invocation and literal placeholder assertions to existing overflow picker tests in both `RangeLinkStatusBar` and `DestinationPicker`.

Both files now at 100% function coverage. Only the exhaustive `never` type guards remain uncovered (unreachable by design).

* [refactor] Move inline command object construction to bootstrap section

Preparation for extracting registration wiring into a separate file. Command objects (ShowVersionCommand, BindToDestinationCommand, JumpToDestinationCommand, GoToRangeLinkCommand, ListBookmarksCommand, ManageBookmarksCommand) were created inline within the registration block — moved them to the bootstrap section so the registration block contains only `context.subscriptions.push(...)` calls.

* [refactor] Extract registration wiring from extension.ts into wireSubscriptions.ts

extension.ts was 649 lines mixing bootstrap, dependency construction, and registration wiring. This made it hard to navigate and impossible to unit test without mocking the full activation lifecycle.

Moved the entire object graph (config, services, commands, providers) and all `context.subscriptions.push(...)` calls into `wireSubscriptions()`. The `ExtensionDependencies` interface has only 3 fields — `ideAdapter`, `logger`, `versionInfo` — everything else is built internally. extension.ts is now 67 lines: logger init, version info, adapter creation, locale setup, and the single `wireSubscriptions()` call.

Benefits:
- extension.ts is a minimal bootstrap file — reads top to bottom in seconds
- wireSubscriptions.ts is independently unit-testable with just 3 mock dependencies
- New commands/services are added in one place without touching bootstrap

* [test] Add unit tests for wireSubscriptions command and provider registration

Verifies that `wireSubscriptions` registers the complete set of 50 commands and 4 link providers. Uses a real `VscodeAdapter` backed by mock VSCode — calls `wireSubscriptions` with the 3-field `ExtensionDependencies` and asserts against spy calls.

Provider tests go beyond counts: they verify exact provider types via `instanceof` (FilePathTerminalProvider, RangeLinkTerminalProvider, FilePathDocumentProvider, RangeLinkDocumentProvider) and document selectors (`file` + `untitled` schemes). Command count is frozen as a literal to catch accidental deletions from the EXPECTED_COMMANDS array.

* Raise thresholds — pass #1

* [refactor] Introduce SubscriptionRegistrar and WiringServices factory for testable wiring

`wireSubscriptions` built the entire object graph and registered closures in one function — making closures untestable (services constructed internally, registrations coupled to `context`). This kept function coverage at 85% with no path to 90%.

Separated concerns into three layers following the VscodeAdapter pattern:
- `SubscriptionRegistrar`: wraps `context.subscriptions.push(ideAdapter.registerCommand(...))` behind a testable interface
- `createWiringServices`: factory that builds the full service object graph from 3 foundational deps
- `wireSubscriptions`: pure wiring — receives a registrar and pre-built services, registers closures

Tests inject a mock registrar (captures handlers for invocation) and mock services (verifiable delegation). Added 30 closure delegation tests covering all service methods, URI ternary branches, and representative commands from each pattern. Functions coverage crossed the 90% target.

Coverage thresholds raised to 97/95/90/97 — all acceptance criteria met.

Benefits:
- Every command closure is independently testable via `registrar.getHandler(CMD_X)()`
- `wireSubscriptions` is now 100% branches (pure wiring, no construction logic)
- `extension.ts` stays 67 lines — unchanged from the previous extraction

* [test] Cover all wireSubscriptions closures and exclude barrel files from coverage

Added the remaining 13 closure delegation tests — every command handler now verifies the correct service method is called with the correct arguments. `wireSubscriptions.ts` is at 100% across all metrics.

Excluded barrel `index.ts` re-export files from coverage collection — Istanbul counts each `export {}` as a function, inflating the denominator with phantom uncovered functions despite 100% line coverage. This removed ~85 false-negative functions from the count.

Coverage thresholds raised to 98/95/95/98 (up from 97/95/90/97).

* Ran `fix`

* [PR feedback] Address CodeRabbit review — test isolation, spy typing, logger assertions, exact matchers

Addressed 4 accepted items from the CodeRabbit review:
- FocusCapabilityFactory.test.ts: moved mock creation into `beforeEach` for test isolation
- spyOnIsGitHubCopilotChatAvailable.ts: added generic type params (`jest.SpyInstance<Promise<boolean>, [VscodeAdapter, Logger]>`) so `mockResolvedValue` infers correctly — removed `as never` cast from destinationBuilders.test.ts
- BookmarksStore.test.ts: added `mockLogger.error` assertions to update, remove, and recordAccess save failure tests (T007 compliance)
- SelectionValidator.test.ts: replaced 3 `expect.objectContaining()` calls with exact object literals (T004 compliance)

Ignored Feedback:
- spyOnIsCursorIDEDetected interception concern: false positive — CommonJS module identity ensures the spy intercepts calls through barrel re-exports. All 3 spy tests pass and verify `toHaveBeenCalledTimes(1)`.

Ref: #495 (review)
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.

Phase 3: Settings & Configuration Enhanced Navigation Feedback

1 participant