Skip to content

[issues/529] Add Gemini Code Assist as built-in AI assistant destination#538

Open
couimet wants to merge 9 commits into
mainfrom
issues/529
Open

[issues/529] Add Gemini Code Assist as built-in AI assistant destination#538
couimet wants to merge 9 commits into
mainfrom
issues/529

Conversation

@couimet
Copy link
Copy Markdown
Owner

@couimet couimet commented May 4, 2026

Summary

Adds Google Gemini Code Assist (google.geminicodeassist) as a fourth built-in AI assistant destination alongside Claude Code, Cursor AI, and GitHub Copilot Chat. The integration follows the established pattern for built-in AI assistants: a typed destination kind, focus command wiring, availability detection, picker ordering, and a dedicated bind command. Gemini is inserted between Claude Code and Cursor AI in picker order, matching the product's stated ordering priority.

Changes

  • New destination kind'gemini-code-assist' added to DESTINATION_KINDS and AI_ASSISTANT_KINDS in DestinationKind.ts; GeminiCodeAssistBindOptions interface added to BindOptions.ts union
  • Five new message codes — display name, error, info-not-available, user-instructions, and status-bar jump success added to MessageCode.ts and wired into messages.en.ts
  • Detection utilityisGeminiCodeAssistAvailable.ts created under src/utils/aiAssistants/, checking command availability first then falling back to extension presence; exported from index.ts; 191-line unit test suite with 100% coverage
  • Focus command + builderGEMINI_CODE_ASSIST_FOCUS_COMMANDS registered in aiAssistantFocusCommands.ts; BUILTIN_AI_ASSISTANTS entry added in destinationBuilders.ts keyed by 'google.geminicodeassist'; display-name map entry added to DestinationRegistry.ts
  • Availability & routing — not-available info map and send-path switch updated in DestinationAvailabilityService.ts and PasteDestinationManager.ts
  • Picker ordering'gemini-code-assist' inserted between 'claude-code' and 'cursor-ai' in DESTINATION_PICKER_SEQUENCE; group map entry added in buildDestinationQuickPickItems.ts
  • Command wiringCMD_BIND_TO_GEMINI_CODE_ASSIST = 'rangelink.bindToGeminiCodeAssist' added to commandIds.ts; registered in wireSubscriptions.ts; "Bind to Gemini Code Assist" command contributed in package.json
  • Test updates — all exhaustive kind/sequence assertions updated across 7 test files; integration test coverage updated in bindToDestination.test.ts
  • QA — 10 new test cases appended to qa-test-cases-v1.1.0-003.yaml covering bind, availability, focus, and picker ordering scenarios
  • Documentation — CHANGELOG [Unreleased] entry added; README updated with Gemini entry in assistant list, commands table, and inline prose sequences; all new entries marked <sup>Unreleased</sup>

Test Plan

  • All existing tests pass (108 suites, 1887 tests)
  • New unit tests added for isGeminiCodeAssistAvailable.ts (100% coverage)
  • QA YAML updated with 10 new test cases (IDs bind-to-destination-029 through bind-to-destination-038)
  • Manual testing: bind to Gemini Code Assist and verify auto-send behavior with the extension installed

Related

Closes #529

Summary by CodeRabbit

  • New Features

    • Gemini Code Assist added as a built-in AI assistant with a "Bind to Gemini Code Assist" command, focus-and-paste integration, and cold-start/refocus behavior.
  • Documentation

    • README and changelog updated with Gemini usage, binding instructions, and new destination settings for cold-start and refocus timing.
  • Tests

    • Unit, integration, and QA tests extended to cover Gemini scenarios, ordering, and focus/refocus/clipboard behaviors.
  • Chores

    • Test runner, fixtures, and scripts updated to support running integration tests with companion extensions.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 4, 2026

Warning

Rate limit exceeded

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

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ 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: cb158ac6-7c29-4e3b-b1a3-06286dc5e645

📥 Commits

Reviewing files that changed from the base of the PR and between d82b25d and 6eba3e2.

📒 Files selected for processing (1)
  • packages/rangelink-vscode-extension/src/utils/__tests__/aiAssistants/isGitHubCopilotChatAvailable.test.ts

Walkthrough

Adds Gemini Code Assist as a built-in AI assistant destination across types, availability detection, focus/paste cold-start/refocus, picker ordering, clipboard/paste flow, commands/wiring, tests, QA, README/CHANGELOG, and test-run support for running with marketplace extensions.

Changes

Gemini Code Assist Integration

Layer / File(s) Summary
Data Shape / Types
packages/rangelink-vscode-extension/src/types/DestinationKind.ts, .../src/types/MessageCode.ts, .../src/types/BindOptions.ts
Adds 'gemini-code-assist' to destination and AI assistant kind arrays, new MessageCode enum members, and GeminiCodeAssistBindOptions union entry.
Core Destination & Focus Capability
.../src/destinations/destinationBuilders.ts, .../src/destinations/capabilities/AIAssistantFocusCapability.ts, .../src/destinations/capabilities/ColdRefocusConfig.ts, .../src/destinations/capabilities/FocusCapabilityFactory.ts
Registers Gemini built-in assistant, forwards getColdRefocus to builders, adds ColdRefocusConfig, and implements cold/warm focus refocus loop behavior.
Focus Commands / Insert Factory
.../src/destinations/aiAssistantFocusCommands.ts, .../src/destinations/capabilities/insertFactories/aiAssistantInsertFactory.ts
Exports GEMINI_CODE_ASSIST_FOCUS_COMMANDS and removes explicit focus-to-paste delay in insert factory flow.
Clipboard & Send Flow
.../src/services/ClipboardRouter.ts, .../src/constants/chatPasteConstants.ts
ClipboardRouter now records sendSucceeded and returns boolean from executeCopyAndSend; chat-paste delay docs adjusted and insert factory no longer waits an explicit delay.
Availability Detection
.../src/utils/aiAssistants/builtInAiAssistants.ts, .../src/utils/aiAssistants/isGeminiCodeAssistAvailable.ts, .../src/utils/aiAssistants/index.ts
Adds built-in extension ID constants and isGeminiCodeAssistAvailable (extension active check) and re-exports it from the aiAssistants index.
Registry / Binding / Availability Service
.../src/destinations/DestinationRegistry.ts, .../src/destinations/DestinationAvailabilityService.ts, .../src/destinations/PasteDestinationManager.ts
Injects ConfigReader into DestinationRegistry context, adds Gemini display name mapping, includes Gemini in unavailable-message codes, and routes gemini binds via generic AI-assistant path.
Picker Ordering / UI Grouping
.../src/destinations/utils/buildDestinationQuickPickItems.ts
Inserts gemini-code-assist into DESTINATION_PICKER_SEQUENCE, maps it to ai group, and introduces BUILTIN_AI_COUNT for ordering.
Manifest, Commands & Scripts
package.json, packages/rangelink-vscode-extension/package.json, packages/rangelink-vscode-extension/src/constants/commandIds.ts, packages/rangelink-vscode-extension/src/wireSubscriptions.ts, root package.json
Adds root and package scripts for test-with-extensions, new contribution rangelink.bindToGeminiCodeAssist, exports CMD_BIND_TO_GEMINI_CODE_ASSIST, and wires registration on activation.
Docs / Changelog / QA / Test-run
packages/rangelink-vscode-extension/README.md, .../CHANGELOG.md, .../qa/qa-test-cases-v1.1.0-003.yaml, .../.vscode-test.with-extensions.mjs, .../scripts/test-release-run.sh, .../scripts/setup-integration-test-settings-with-extensions.js
README and CHANGELOG updated to mention Gemini; QA YAML adds Gemini scenarios; test-run config and scripts updated to run integration tests with marketplace extensions and inject custom assistant settings.
Tests / Mocks / Fixtures
.../__tests__/*, .../__integration-tests__/*, .../__tests__/helpers/*, test-fixtures/dummy-ai-extension/*
Adds/updates many unit and integration tests: availability, focus/refocus, insert factory, builders, registry, quick-pick ordering, PasteDestinationManager bind/unbind, clipboard-preservation assisted test (focus-fail), mock Gemini helpers, and dummy fixture command dummyAi.focusFail.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Wire as wireSubscriptions
  participant Manager as PasteDestinationManager
  participant Availability as isGeminiCodeAssistAvailable
  participant Gemini as Gemini Extension / Chat View

  User->>Wire: invoke "Bind to Gemini Code Assist" command
  Wire->>Manager: bind(kind: 'gemini-code-assist')
  Manager->>Availability: isGeminiCodeAssistAvailable(ideAdapter, logger)
  Availability->>Gemini: check extension presence/active
  alt available
    Manager->>Gemini: execute focus command(s)
    Manager->>Gemini: paste payload into chat view
    Gemini-->>User: chat receives pasted RangeLink + selection
  else not available
    Manager-->>User: show not-available/info message
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

  • #529: Add support for Gemini Code Assist as built-in AI assistant — this PR implements the Gemini built-in integration, README/CHANGELOG sequencing, and ordering requested by the issue.

Possibly related PRs

"🐰 I hopped through code with eager paws,
Gemini joins the assistant clause.
Commands align, mocks spring to life,
Tests cheer loud — no build-time strife.
Paste and focus, partners in cause."

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

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 4, 2026

⚠️ QA Coverage Gap Detected

The PR introduces new integrations with Gemini Code Assist and Claude Code, along with new configurable settings for cold-start timing. These changes require additional test cases to verify their functionality.

Suggested test cases:

  • Gemini Code Assist Integration: Verify that links and selected text are correctly inserted into Gemini Code Assist (manual — Requires verification of paste behavior in the Gemini Code Assist UI.)
  • Claude Code Cold-Start Timing: Check that the configurable cold-start settings for Claude Code are respected and function correctly (manual — Requires testing of timing behavior in the Claude Code UI.)
  • Custom AI Assistants: Ensure that custom AI assistants can be configured and appear in the destination picker (automatable)

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

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: 6

Caution

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

⚠️ Outside diff range comments (1)
packages/rangelink-vscode-extension/src/destinations/utils/buildDestinationQuickPickItems.ts (1)

36-45: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Adding gemini-code-assist shifts github-copilot-chat past the slice(0, 3) boundary — it now appears after custom AI assistants in the picker.

The custom-AI insertion at lines 93–97 (unchanged) splits DESTINATION_PICKER_SEQUENCE using a hardcoded index of 3. With the previous 3-item AI block this was correct; now that there are 4 built-in AI assistants the split falls between cursor-ai (index 2) and github-copilot-chat (index 3), placing Copilot Chat after any configured custom AI assistants in fullSequence.

For a user with custom AI assistants and GitHub Copilot Chat installed the picker renders:

Claude Code  ← slice(0,3)
Gemini Code Assist
Cursor AI
[custom AI assistants]
GitHub Copilot Chat  ← WRONG: slice(3) now starts here
🐛 Proposed fix — update magic index from 3 → 4
// buildDestinationQuickPickItems.ts  (lines 93-97, unchanged in this PR)
   const fullSequence: PickerSequenceKey[] = [
-    ...DESTINATION_PICKER_SEQUENCE.slice(0, 3),
+    ...DESTINATION_PICKER_SEQUENCE.slice(0, 4),
     ...(customAiKinds as PickerSequenceKey[]),
-    ...DESTINATION_PICKER_SEQUENCE.slice(3),
+    ...DESTINATION_PICKER_SEQUENCE.slice(4),
   ];

A more future-proof alternative imports AI_ASSISTANT_KINDS and derives the count:

 import {
   type BindableQuickPickItem,
   DESTINATION_KINDS,
+  AI_ASSISTANT_KINDS,
   ...
 } from '../../types';

+const BUILTIN_AI_COUNT = AI_ASSISTANT_KINDS.length;

   const fullSequence: PickerSequenceKey[] = [
-    ...DESTINATION_PICKER_SEQUENCE.slice(0, 3),
+    ...DESTINATION_PICKER_SEQUENCE.slice(0, BUILTIN_AI_COUNT),
     ...(customAiKinds as PickerSequenceKey[]),
-    ...DESTINATION_PICKER_SEQUENCE.slice(3),
+    ...DESTINATION_PICKER_SEQUENCE.slice(BUILTIN_AI_COUNT),
   ];

This automatically stays in sync with AI_ASSISTANT_KINDS for any future built-in additions.

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

In
`@packages/rangelink-vscode-extension/src/destinations/utils/buildDestinationQuickPickItems.ts`
around lines 36 - 45, The hardcoded split index (slice(0, 3) / slice(3)) that
partitions DESTINATION_PICKER_SEQUENCE must be replaced with a derived count so
built-in AI assistants stay grouped; import AI_ASSISTANT_KINDS (or otherwise
compute the number of built-in AI assistants) in
buildDestinationQuickPickItems.ts and replace the magic 3 with const aiCount =
AI_ASSISTANT_KINDS.length (or the computed count) and use slice(0, aiCount) and
slice(aiCount) when inserting custom AI assistants into fullSequence (update any
references to the old slices around DESTINATION_PICKER_SEQUENCE and the
custom-AI insertion block).
🧹 Nitpick comments (1)
packages/rangelink-vscode-extension/src/__tests__/helpers/createMockDestinationRegistry.ts (1)

21-27: 💤 Low value

Consider adding 'gemini-code-assist' to mock destinations for consistency.

The DEFAULT_DISPLAY_NAMES includes 'gemini-code-assist', but MockDestinationRegistryOptions.destinations and the default destinations object don't include it. Tests that call create({ kind: 'gemini-code-assist' }) on this mock will receive undefined.

If this is intentional (tests should provide custom createImpl), the current state is fine. Otherwise, consider adding the missing entry for completeness.

Also applies to: 63-73

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

In
`@packages/rangelink-vscode-extension/src/__tests__/helpers/createMockDestinationRegistry.ts`
around lines 21 - 27, The mock destination registry is missing a
'gemini-code-assist' entry causing create({ kind: 'gemini-code-assist' }) to
return undefined; update the MockDestinationRegistryOptions.destinations type
and the default destinations object in createMockDestinationRegistry to include
'gemini-code-assist' as a jest.Mocked<PasteDestination> (match the shape used
for 'claude-code'/'cursor-ai'), and add a default mock implementation in the
same defaults block so DEFAULT_DISPLAY_NAMES and the mock registry remain
consistent with each other.
🤖 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/qa/qa-test-cases-v1.1.0-003.yaml`:
- Around line 2992-2995: Update the QA test cases that assert "link + selected
code snippet" for the Cmd/Ctrl+R Cmd/Ctrl+L shortcut so they instead verify only
that the Claude Code chat opens and contains a RangeLink payload for the
selected range (not the pasted snippet); specifically change the expected_result
value from 'Claude Code chat opens and contains the RangeLink and selected code
snippet' to something like 'Claude Code chat opens and contains the RangeLink
payload for the selected range' for the test block containing the shortcut
string 'Cmd+R Cmd+L (Mac) / Ctrl+R Ctrl+L (Win/Linux)' and apply the same edit
to the other analogous test cases in this file that use that shortcut.

In `@packages/rangelink-vscode-extension/README.md`:
- Around line 148-151: Reorder the built-in assistants and any command rows in
the README so they follow the canonical sequence "Claude Code → Gemini Code
Assist → Cursor AI → GitHub Copilot Chat"; update the list items that currently
show "Cursor AI" before "Gemini Code Assist" (the lines containing the text for
Claude Code Extension, Gemini Code Assist, Cursor AI, and GitHub Copilot Chat)
and also apply the same corrected order to the corresponding command rows
mentioned around the other occurrence (lines referenced as also applies to
286-289).

In
`@packages/rangelink-vscode-extension/src/__tests__/constants/packageJsonContracts.test.ts`:
- Around line 480-482: Add a dedicated test for the
rangelink.bindToGeminiCodeAssist entry in the "destination binding commands"
suite: locate the tests referencing the commands array (in
packageJsonContracts.test.ts) and add an it() that finds the command object with
command === 'rangelink.bindToGeminiCodeAssist' and asserts its shape equals the
expected { command, title, category, icon } values (matching the other bind
tests like rangelink.bindToCursorAI, rangelink.bindToClaudeCode,
rangelink.bindToGitHubCopilotChat). Ensure the test uses the same assertion
style (e.g., expect(found).toEqual({...})) so future accidental
title/icon/category changes are caught.

In `@packages/rangelink-vscode-extension/src/types/MessageCode.ts`:
- Around line 68-69: The enum entry
MessageCode.ERROR_GEMINI_CODE_ASSIST_NOT_AVAILABLE is out of alphabetical order
relative to MessageCode.ERROR_FILE_PATH_NAVIGATION_FAILED; move the
ERROR_GEMINI_CODE_ASSIST_NOT_AVAILABLE line so it appears after
ERROR_FILE_PATH_NAVIGATION_FAILED in MessageCode.ts, and apply the same
transposition in messages.en.ts by moving the
[MessageCode.ERROR_GEMINI_CODE_ASSIST_NOT_AVAILABLE] message block to follow the
[MessageCode.ERROR_FILE_PATH_NAVIGATION_FAILED] block so both files maintain
consistent alphabetical ordering.

In
`@packages/rangelink-vscode-extension/src/utils/__tests__/aiAssistants/isGeminiCodeAssistAvailable.test.ts`:
- Around line 71-74: The test currently uses loose matchers for the logger
assertion; update the assertion in isGeminiCodeAssistAvailable.test.ts to assert
exact values: replace expect.objectContaining({ detectionMethod: 'command' })
with the exact object literal { detectionMethod: 'command' } and replace
expect.any(String) with the exact string literal that the code logs (the second
argument passed to mockLogger.debug). Modify the mockLogger.debug expectation to
use toHaveBeenCalledWith({ detectionMethod: 'command' }, '<exact log message>')
so the test asserts precise values.
- Around line 55-58: Replace the loose Jest matchers in the test assertion for
mockLogger.debug with an exact equality check: instead of
expect.objectContaining({ detectionMethod: 'command' }) and expect.any(String),
call expect(mockLogger.debug).toHaveBeenCalledWith(<exactExpectedMetaObject>,
'<exactExpectedMessage>'); locate the existing full expected meta object used
earlier in this test (the one asserted in lines ~31-38) and reuse that exact
object as the first argument and the exact expected log string as the second
argument so the assertion uses precise values for mockLogger.debug.

---

Outside diff comments:
In
`@packages/rangelink-vscode-extension/src/destinations/utils/buildDestinationQuickPickItems.ts`:
- Around line 36-45: The hardcoded split index (slice(0, 3) / slice(3)) that
partitions DESTINATION_PICKER_SEQUENCE must be replaced with a derived count so
built-in AI assistants stay grouped; import AI_ASSISTANT_KINDS (or otherwise
compute the number of built-in AI assistants) in
buildDestinationQuickPickItems.ts and replace the magic 3 with const aiCount =
AI_ASSISTANT_KINDS.length (or the computed count) and use slice(0, aiCount) and
slice(aiCount) when inserting custom AI assistants into fullSequence (update any
references to the old slices around DESTINATION_PICKER_SEQUENCE and the
custom-AI insertion block).

---

Nitpick comments:
In
`@packages/rangelink-vscode-extension/src/__tests__/helpers/createMockDestinationRegistry.ts`:
- Around line 21-27: The mock destination registry is missing a
'gemini-code-assist' entry causing create({ kind: 'gemini-code-assist' }) to
return undefined; update the MockDestinationRegistryOptions.destinations type
and the default destinations object in createMockDestinationRegistry to include
'gemini-code-assist' as a jest.Mocked<PasteDestination> (match the shape used
for 'claude-code'/'cursor-ai'), and add a default mock implementation in the
same defaults block so DEFAULT_DISPLAY_NAMES and the mock registry remain
consistent with each other.
🪄 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: CHILL

Plan: Pro

Run ID: 7d9508af-c448-43e3-8037-beb39163ee99

📥 Commits

Reviewing files that changed from the base of the PR and between 673405d and 467a925.

📒 Files selected for processing (28)
  • 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-003.yaml
  • packages/rangelink-vscode-extension/src/__integration-tests__/suite/bindToDestination.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/constants/packageJsonContracts.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/destinations/DestinationRegistry.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/destinations/destinationBuilders.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/destinations/utils/buildDestinationQuickPickItems.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/extension.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/helpers/createMockBindableQuickPickItem.ts
  • packages/rangelink-vscode-extension/src/__tests__/helpers/createMockDestinationRegistry.ts
  • packages/rangelink-vscode-extension/src/__tests__/wireSubscriptions.test.ts
  • packages/rangelink-vscode-extension/src/constants/commandIds.ts
  • packages/rangelink-vscode-extension/src/destinations/DestinationAvailabilityService.ts
  • packages/rangelink-vscode-extension/src/destinations/DestinationRegistry.ts
  • packages/rangelink-vscode-extension/src/destinations/PasteDestinationManager.ts
  • packages/rangelink-vscode-extension/src/destinations/aiAssistantFocusCommands.ts
  • packages/rangelink-vscode-extension/src/destinations/destinationBuilders.ts
  • packages/rangelink-vscode-extension/src/destinations/utils/buildDestinationQuickPickItems.ts
  • packages/rangelink-vscode-extension/src/i18n/messages.en.ts
  • packages/rangelink-vscode-extension/src/types/BindOptions.ts
  • packages/rangelink-vscode-extension/src/types/DestinationKind.ts
  • packages/rangelink-vscode-extension/src/types/MessageCode.ts
  • packages/rangelink-vscode-extension/src/utils/__tests__/aiAssistants/isGeminiCodeAssistAvailable.test.ts
  • packages/rangelink-vscode-extension/src/utils/aiAssistants/index.ts
  • packages/rangelink-vscode-extension/src/utils/aiAssistants/isGeminiCodeAssistAvailable.ts
  • packages/rangelink-vscode-extension/src/wireSubscriptions.ts

Comment thread packages/rangelink-vscode-extension/README.md
Comment thread packages/rangelink-vscode-extension/src/types/MessageCode.ts Outdated
couimet added a commit that referenced this pull request May 4, 2026
…eview

The most critical finding was a real user-visible bug: the hardcoded `slice(0, 3)` / `slice(3)` split in `buildDestinationQuickPickItems` placed GitHub Copilot Chat after any configured custom AI assistants once Gemini was added as the fourth built-in. The fix derives the split index from `AI_ASSISTANT_KINDS.length` and adds a behavioral guard test so the same regression can't recur silently on the next built-in addition.

The remaining items close gaps that the original implementation left open: alphabetical ordering violations in `MessageCode` and `messages.en.ts`, loose matchers that violated rule T004, a QA expected-result that misrepresented what `Cmd+R Cmd+L` actually sends (link only, not code), README ordering inconsistency, a missing `package.json` contract test for the new bind command, and missing Gemini mock helpers / `PasteDestinationManager` test scenarios that every other AI assistant already had.

Also adds `--with-extensions` mode to `test-release-run.sh` via a new `.vscode-test.with-extensions.mjs` config that installs `google.geminicodeassist` and `anthropic.claude-code` from the marketplace before running integration tests, enabling future graduation of Gemini/Claude Code QA tests from `automated: false` to `automated: assisted`.

Benefits:
- Picker ordering is now correct for users with custom AI assistants and GitHub Copilot Chat installed simultaneously
- `BUILTIN_AI_COUNT` and the exhaustive `packageJsonContracts` guard both break loudly when a fifth built-in AI assistant is added without updating the corresponding tests and commands
- Gemini mock helpers (`Paradigm A` + `Paradigm B`) and `PasteDestinationManager` scenarios bring Gemini to the same test coverage depth as Claude Code, Cursor AI, and GitHub Copilot Chat
- Extension-install infrastructure is opt-in and isolated to a separate VS Code test config, so the default `test:release` run is unaffected

Ref: #538 (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/__tests__/destinations/PasteDestinationManager.test.ts (1)

421-441: ⚡ Quick win

Missing mockLogger.info assertion in the bind success test.

The should bind to gemini-code-assist when available test omits the mockLogger.info assertion that commitBind emits on success. The should bind to github-copilot-chat when available test at lines 483–490 includes this assertion and serves as the correct reference. As per coding guidelines, "include logger assertions in tests that verify method behavior."

🛠️ Proposed addition
   expectContextKeys(mockAdapter.__getVscodeInstance(), { 'rangelink.isBound': true });
+  expect(mockLogger.info).toHaveBeenCalledWith(
+    {
+      fn: 'PasteDestinationManager.commitBind',
+      kind: 'gemini-code-assist',
+      displayName: 'Gemini Code Assist',
+    },
+    'Successfully bound to "Gemini Code Assist"',
+  );
 });

As per coding guidelines: "Include logger assertions in tests that verify method behavior - consolidate logging checks with behavior tests, never create separate logging-only tests."

🤖 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
`@packages/rangelink-vscode-extension/src/__tests__/destinations/PasteDestinationManager.test.ts`
around lines 421 - 441, The test "should bind to gemini-code-assist when
available" is missing the logger assertion; after calling manager.bind({ kind:
'gemini-code-assist' }) add an assertion that mockLogger.info was called once
for the successful bind (the same check used in the github-copilot-chat test).
Specifically, locate the test that uses createMockGeminiCodeAssistDestination
and mockRegistry.create, and add an expectation on mockLogger.info (the
commitBind/info call emitted by the bind flow) verifying it was invoked with the
bind success message/details (include destination name 'Gemini Code Assist' and
kind 'gemini-code-assist' or use an assertion consistent with the existing
github-copilot-chat test).
🤖 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
`@packages/rangelink-vscode-extension/src/__tests__/destinations/PasteDestinationManager.test.ts`:
- Around line 421-441: The test "should bind to gemini-code-assist when
available" is missing the logger assertion; after calling manager.bind({ kind:
'gemini-code-assist' }) add an assertion that mockLogger.info was called once
for the successful bind (the same check used in the github-copilot-chat test).
Specifically, locate the test that uses createMockGeminiCodeAssistDestination
and mockRegistry.create, and add an expectation on mockLogger.info (the
commitBind/info call emitted by the bind flow) verifying it was invoked with the
bind success message/details (include destination name 'Gemini Code Assist' and
kind 'gemini-code-assist' or use an assertion consistent with the existing
github-copilot-chat test).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6e271deb-42f7-4acf-b601-08f61b72f741

📥 Commits

Reviewing files that changed from the base of the PR and between 467a925 and f325f7b.

📒 Files selected for processing (17)
  • package.json
  • packages/rangelink-vscode-extension/.vscode-test.with-extensions.mjs
  • packages/rangelink-vscode-extension/README.md
  • packages/rangelink-vscode-extension/package.json
  • packages/rangelink-vscode-extension/qa/qa-test-cases-v1.1.0-003.yaml
  • packages/rangelink-vscode-extension/scripts/test-release-run.sh
  • packages/rangelink-vscode-extension/src/__tests__/constants/packageJsonContracts.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/destinations/PasteDestinationManager.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/destinations/utils/buildDestinationQuickPickItems.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/helpers/createMockDestinationRegistry.ts
  • packages/rangelink-vscode-extension/src/__tests__/helpers/createMockGeminiCodeAssistComposableDestination.ts
  • packages/rangelink-vscode-extension/src/__tests__/helpers/createMockGeminiCodeAssistDestination.ts
  • packages/rangelink-vscode-extension/src/__tests__/helpers/index.ts
  • packages/rangelink-vscode-extension/src/destinations/utils/buildDestinationQuickPickItems.ts
  • packages/rangelink-vscode-extension/src/i18n/messages.en.ts
  • packages/rangelink-vscode-extension/src/types/MessageCode.ts
  • packages/rangelink-vscode-extension/src/utils/__tests__/aiAssistants/isGeminiCodeAssistAvailable.test.ts
✅ Files skipped from review due to trivial changes (6)
  • packages/rangelink-vscode-extension/src/tests/helpers/index.ts
  • packages/rangelink-vscode-extension/src/tests/helpers/createMockGeminiCodeAssistDestination.ts
  • packages/rangelink-vscode-extension/README.md
  • packages/rangelink-vscode-extension/src/i18n/messages.en.ts
  • packages/rangelink-vscode-extension/qa/qa-test-cases-v1.1.0-003.yaml
  • packages/rangelink-vscode-extension/src/types/MessageCode.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/rangelink-vscode-extension/src/utils/tests/aiAssistants/isGeminiCodeAssistAvailable.test.ts
  • packages/rangelink-vscode-extension/package.json
  • packages/rangelink-vscode-extension/src/destinations/utils/buildDestinationQuickPickItems.ts

couimet added a commit that referenced this pull request May 4, 2026
@couimet
Copy link
Copy Markdown
Owner Author

couimet commented May 4, 2026

@coderabbitai Is the rate-limited comment in #538 (comment) still accurate ? Did you fully review 9958b14 (my latest push on this PR) ?

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 4, 2026

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Fetch the specific comment
gh api repos/couimet/rangeLink/issues/comments/4371851034 --jq '.body'

echo "---COMMIT DETAILS---"
# Fetch the commit details
gh api repos/couimet/rangeLink/commits/9958b142a64d889ce697f8195208031c13ce44aa --jq '{sha: .sha, message: .commit.message, files: [.files[] | {filename: .filename, status: .status, additions: .additions, deletions: .deletions, patch: .patch}]}'

Length of output: 46190


@couimet: Here's a summary of both questions:

Is the rate-limited comment still accurate?
No — it is stale. That comment was purely a rate-limit notice (no code review feedback was ever posted). The ~42-minute timeout referenced in that comment has long since passed.

Was commit 9958b142a64d889ce697f8195208031c13ce44aa fully reviewed?
No — the review was blocked by the rate limit before any inline comments could be emitted. The only file queued for processing at that point was packages/rangelink-vscode-extension/src/__tests__/destinations/PasteDestinationManager.test.ts.

From what I can see in the commit diff, the change is clean test-hardening: it adds symmetric expect(mockLogger.info).toHaveBeenCalledWith(...) assertions to the bind-success test cases for cursor-ai, claude-code, and gemini-code-assist, verifying the structured log payload (fn, kind, displayName) and the "Successfully bound to …" message string. This is consistent with the review suggestion referenced in the commit message.

Would you like me to trigger a full review of the PR now?

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@couimet
Copy link
Copy Markdown
Owner Author

couimet commented May 4, 2026

@coderabbitai Yes, trigger a full review of the PR now

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 4, 2026

Tip

For best results, initiate chat on the files or code changes.

@couimet: Triggering a full review of PR #538 now — this will re-examine all changes across the entire PR, including the latest commit.

[full_review]

couimet added 4 commits May 6, 2026 13:38
## Summary

Adds Google Gemini Code Assist (`google.geminicodeassist`) as a fourth built-in AI assistant destination alongside Claude Code, Cursor AI, and GitHub Copilot Chat. The integration follows the established pattern for built-in AI assistants: a typed destination kind, focus command wiring, availability detection, picker ordering, and a dedicated bind command. Gemini is inserted between Claude Code and Cursor AI in picker order, matching the product's stated ordering priority.

## Changes

- **New destination kind** — `'gemini-code-assist'` added to `DESTINATION_KINDS` and `AI_ASSISTANT_KINDS` in `DestinationKind.ts`; `GeminiCodeAssistBindOptions` interface added to `BindOptions.ts` union
- **Five new message codes** — display name, error, info-not-available, user-instructions, and status-bar jump success added to `MessageCode.ts` and wired into `messages.en.ts`
- **Detection utility** — `isGeminiCodeAssistAvailable.ts` created under `src/utils/aiAssistants/`, checking command availability first then falling back to extension presence; exported from `index.ts`; 191-line unit test suite with 100% coverage
- **Focus command + builder** — `GEMINI_CODE_ASSIST_FOCUS_COMMANDS` registered in `aiAssistantFocusCommands.ts`; `BUILTIN_AI_ASSISTANTS` entry added in `destinationBuilders.ts` keyed by `'google.geminicodeassist'`; display-name map entry added to `DestinationRegistry.ts`
- **Availability & routing** — not-available info map and send-path switch updated in `DestinationAvailabilityService.ts` and `PasteDestinationManager.ts`
- **Picker ordering** — `'gemini-code-assist'` inserted between `'claude-code'` and `'cursor-ai'` in `DESTINATION_PICKER_SEQUENCE`; group map entry added in `buildDestinationQuickPickItems.ts`
- **Command wiring** — `CMD_BIND_TO_GEMINI_CODE_ASSIST = 'rangelink.bindToGeminiCodeAssist'` added to `commandIds.ts`; registered in `wireSubscriptions.ts`; `"Bind to Gemini Code Assist"` command contributed in `package.json`
- **Test updates** — all exhaustive kind/sequence assertions updated across 7 test files; integration test coverage updated in `bindToDestination.test.ts`
- **QA** — 10 new test cases appended to `qa-test-cases-v1.1.0-003.yaml` covering bind, availability, focus, and picker ordering scenarios
- **Documentation** — CHANGELOG `[Unreleased]` entry added; README updated with Gemini entry in assistant list, commands table, and inline prose sequences; all new entries marked `<sup>Unreleased</sup>`

## Test Plan

- [x] All existing tests pass (108 suites, 1887 tests)
- [x] New unit tests added for `isGeminiCodeAssistAvailable.ts` (100% coverage)
- [x] QA YAML updated with 10 new test cases (IDs `bind-to-destination-029` through `bind-to-destination-038`)
- [ ] Manual testing: bind to Gemini Code Assist and verify auto-send behavior with the extension installed

## Related

Closes #529
…eview

The most critical finding was a real user-visible bug: the hardcoded `slice(0, 3)` / `slice(3)` split in `buildDestinationQuickPickItems` placed GitHub Copilot Chat after any configured custom AI assistants once Gemini was added as the fourth built-in. The fix derives the split index from `AI_ASSISTANT_KINDS.length` and adds a behavioral guard test so the same regression can't recur silently on the next built-in addition.

The remaining items close gaps that the original implementation left open: alphabetical ordering violations in `MessageCode` and `messages.en.ts`, loose matchers that violated rule T004, a QA expected-result that misrepresented what `Cmd+R Cmd+L` actually sends (link only, not code), README ordering inconsistency, a missing `package.json` contract test for the new bind command, and missing Gemini mock helpers / `PasteDestinationManager` test scenarios that every other AI assistant already had.

Also adds `--with-extensions` mode to `test-release-run.sh` via a new `.vscode-test.with-extensions.mjs` config that installs `google.geminicodeassist` and `anthropic.claude-code` from the marketplace before running integration tests, enabling future graduation of Gemini/Claude Code QA tests from `automated: false` to `automated: assisted`.

Benefits:
- Picker ordering is now correct for users with custom AI assistants and GitHub Copilot Chat installed simultaneously
- `BUILTIN_AI_COUNT` and the exhaustive `packageJsonContracts` guard both break loudly when a fifth built-in AI assistant is added without updating the corresponding tests and commands
- Gemini mock helpers (`Paradigm A` + `Paradigm B`) and `PasteDestinationManager` scenarios bring Gemini to the same test coverage depth as Claude Code, Cursor AI, and GitHub Copilot Chat
- Extension-install infrastructure is opt-in and isolated to a separate VS Code test config, so the default `test:release` run is unaffected

Ref: #538 (review)
…hitecture cleanup

Gemini Code Assist's webview panel needs time to initialise on first use — and the right duration varies by machine speed. The hardcoded 2500ms/300ms defaults work for most setups but leave slower machines without recourse. Two new user-facing settings (`rangelink.destinations.gemini.*`) let users tune the cold-start window without restarting VS Code, and runtime validation prevents misconfiguration.
The architecture was reworked so cold-start config is read fresh on every focus() call — no more stale values after a settings change — and ConfigReader was encapsulated into DestinationBuilderContext instead of being threaded through three function layers as a separate parameter.

Benefits:
- Users on slow machines can increase coldStartDelayMs without editing code or restarting
- Settings read at bind time, no restart required to apply changes
- Cross-field validation (delayMs > intervalMs) prevents silent refocus-loop failure
- ConfigReader on DestinationBuilderContext eliminates threaded param through registerAllDestinationBuilders → createBuiltinAiAssistantBuilder → buildBuiltinAiAssistantDestination
- getColdRefocus hook mirrors isAvailable signature for API symmetry
- ColdRefocusConfig and LazyResolvedFocusCapability added to capabilities barrel
couimet added 2 commits May 7, 2026 15:35
Claude Code Extension's chat panel has the same cold-start initialization behavior as Gemini Code Assist — the panel needs time to become ready on first use. Two new settings (`rangelink.destinations.claudeCode.coldStartDelayMs` and `coldRefocusIntervalMs`) let users tune the cold-start window, with runtime validation ensuring delayMs > intervalMs.

Follows the exact same architecture established for Gemini: setting keys and defaults in the single-source-of-truth files, getColdRefocus hook on the BuiltinAiAssistantDef, fresh config read on every focus() call, and full contract test coverage for package.json schema and default values.
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: 6

Caution

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

⚠️ Outside diff range comments (1)
packages/rangelink-vscode-extension/README.md (1)

373-373: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Stale count: "three built-in AI tools" should now be "four".

With Gemini Code Assist added, this sentence undercounts the built-in assistants.

📝 Proposed fix
-Define custom AI assistants to extend RangeLink beyond the three built-in AI tools.
+Define custom AI assistants to extend RangeLink beyond the four built-in AI tools.
🤖 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 `@packages/rangelink-vscode-extension/README.md` at line 373, Update the README
sentence that undercounts built-in assistants: locate the line containing
"Define custom AI assistants to extend RangeLink beyond the three built-in AI
tools." and change "three" to "four" so it reads "four built-in AI tools" to
account for the added Gemini Code Assist.
🧹 Nitpick comments (4)
packages/rangelink-vscode-extension/src/__tests__/extension.test.ts (1)

624-629: ⚡ Quick win

Avoid hardcoded command count drift in subscription assertions.

COMMAND_COUNT = 51 is brittle and already required manual updates in this PR. Consider deriving it from a shared expected command list constant (or centralized command-id source) to prevent future false negatives/positives.

🤖 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 `@packages/rangelink-vscode-extension/src/__tests__/extension.test.ts` around
lines 624 - 629, The test hardcodes COMMAND_COUNT = 51 which is brittle; change
the test to derive the command count from the authoritative command list instead
of a magic number: import or reference the shared expected commands
array/constant used by the extension (e.g., the exported command IDs list or
COMMANDS constant) and set COMMAND_COUNT = sharedCommands.length, then recompute
EXPECTED_SUBSCRIPTION_COUNT using that derived value along with
INFRASTRUCTURE_COUNT, PROVIDER_COUNT, and DESTINATION_MANAGER_LISTENERS so the
assertion stays correct when commands change.
packages/rangelink-vscode-extension/src/utils/__tests__/aiAssistants/isGeminiCodeAssistAvailable.test.ts (1)

79-111: ⚡ Quick win

Add logger assertions to behavior-verifying edge case tests.

The three edge-case tests verify method behavior (return value) but omit mockLogger.debug assertions. All three code paths log a debug message, and the guideline requires logger assertions to be consolidated with behavior tests.

📝 Proposed additions
   it('should not match other Google extensions', async () => {
     mockAdapter = createMockVscodeAdapter({
       extensionsOptions: [{ id: 'GoogleCloudTools.cloudcode', isActive: true }],
     });

     const result = await isGeminiCodeAssistAvailable(mockAdapter, mockLogger);

     expect(result).toBe(false);
+    expect(mockLogger.debug).toHaveBeenCalledWith(
+      {
+        fn: 'isGeminiCodeAssistAvailable',
+        extensionId: 'google.geminicodeassist',
+        extensionFound: false,
+        extensionActive: false,
+      },
+      'Gemini Code Assist not available (not installed or not active)',
+    );
   });

   it('should handle mixed extensions list', async () => {
     ...
     expect(result).toBe(true);
+    expect(mockLogger.debug).toHaveBeenCalledWith(
+      {
+        fn: 'isGeminiCodeAssistAvailable',
+        extensionId: 'google.geminicodeassist',
+        extensionFound: true,
+        extensionActive: true,
+      },
+      'Gemini Code Assist detected and active',
+    );
   });

   it('should use exact extension ID match', async () => {
     ...
     expect(result).toBe(false);
+    expect(mockLogger.debug).toHaveBeenCalledWith(
+      {
+        fn: 'isGeminiCodeAssistAvailable',
+        extensionId: 'google.geminicodeassist',
+        extensionFound: false,
+        extensionActive: false,
+      },
+      'Gemini Code Assist not available (not installed or not active)',
+    );
   });

As per coding guidelines: "Include logger assertions in tests that verify method behavior - consolidate logging checks with behavior tests, never create separate logging-only tests".

🤖 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
`@packages/rangelink-vscode-extension/src/utils/__tests__/aiAssistants/isGeminiCodeAssistAvailable.test.ts`
around lines 79 - 111, Update the three edge-case tests for
isGeminiCodeAssistAvailable to also assert the logger calls: in the "should not
match other Google extensions", "should handle mixed extensions list", and
"should use exact extension ID match" tests add expectations that
mockLogger.debug was invoked (or invoked with the expected diagnostic message)
appropriate to the code path after calling isGeminiCodeAssistAvailable;
reference the isGeminiCodeAssistAvailable function and the existing mockAdapter
configurations (extensionsOptions / EXTENSION_ID_GEMINI_CODE_ASSIST) to locate
where to add mockLogger.debug assertions so logging checks are consolidated with
the behavior assertions.
packages/rangelink-vscode-extension/src/destinations/utils/buildDestinationQuickPickItems.ts (1)

21-21: ⚡ Quick win

Consider deriving BUILTIN_AI_COUNT from AI_ASSISTANT_KINDS.length to eliminate manual sync.

The test already asserts BUILTIN_AI_COUNT === AI_ASSISTANT_KINDS.length, meaning they must stay in sync. If a future AI destination is added to AI_ASSISTANT_KINDS but BUILTIN_AI_COUNT isn't updated, fullSequence will incorrectly split the built-in AI block — silently inserting custom AI kinds in the wrong position.

♻️ Proposed refactor
+import { AI_ASSISTANT_KINDS } from '../../types';
 
-export const BUILTIN_AI_COUNT = 4;
+export const BUILTIN_AI_COUNT = AI_ASSISTANT_KINDS.length;

This makes BUILTIN_AI_COUNT a derived constant, keeps the test assertion valid as documentation, and removes the synchronization burden entirely.

🤖 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
`@packages/rangelink-vscode-extension/src/destinations/utils/buildDestinationQuickPickItems.ts`
at line 21, BUILTIN_AI_COUNT is a brittle hard-coded value that must match
AI_ASSISTANT_KINDS.length; change the code to derive the count from the array
instead of a manual constant — replace the exported constant BUILTIN_AI_COUNT
with a derived value using AI_ASSISTANT_KINDS.length (or remove the constant and
use AI_ASSISTANT_KINDS.length where fullSequence and related logic reference
BUILTIN_AI_COUNT) so the built-in AI block splitting in fullSequence stays
correct and the test asserting equality remains valid.
packages/rangelink-vscode-extension/src/__integration-tests__/suite/clipboardPreservation.test.ts (1)

382-397: ⚡ Quick win

Also assert the warning toast path in TC-010.

The test verifies the failure log and clipboard outcome, but not the user-facing warning mentioned in the scenario steps. Adding a toast-log assertion would protect UX regressions.

Suggested patch
     const focusFailLog = lines010.find((line) => line.includes('Focus failed, cannot paste link'));
     assert.ok(
       focusFailLog,
       'Expected "Focus failed, cannot paste link" log — the focus command should have thrown',
     );
+    const warningToastLog = lines010.find(
+      (line) =>
+        line.includes('VscodeAdapter.showWarningMessage') &&
+        line.toLowerCase().includes('paste'),
+    );
+    assert.ok(
+      warningToastLog,
+      'Expected warning toast log instructing manual paste after focus failure',
+    );
🤖 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
`@packages/rangelink-vscode-extension/src/__integration-tests__/suite/clipboardPreservation.test.ts`
around lines 382 - 397, After confirming focus failure (using lines010 and
focusFailLog) add an assertion that the user-facing warning toast was shown by
searching the same lines010 for a toast/warning log entry (e.g., find a line
that includes both "toast" and "warning" or the exact scenario message text),
failing the test if it's not present; place this new assertion after the
focusFailLog check and before the clipboard assertion so the test verifies the
UX toast path as well (use the existing logCapture.getLinesSince('before-010')
and lines010.find(...) pattern and keep the assertion style consistent with the
surrounding asserts and assertClipboardChanged call).
🤖 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
`@packages/rangelink-vscode-extension/scripts/setup-integration-test-settings-with-extensions.js`:
- Around line 59-66: The inline comment incorrectly names the property as
focusPasteCommands while the actual key used is focusAndPasteCommands; update
the comment to reference focusAndPasteCommands (or otherwise match the settings
schema) so it accurately describes the bogus property for the Gemini entry
(extensionId: 'google.geminicodeassist', focusAndPasteCommands:
['nonexistent.gemini.focusPaste']).
- Around line 7-9: Update the two comment occurrences of the old test ID
"TC-011" in the setup-integration-test-settings-with-extensions.js script to the
canonical "clipboard-preservation-010"; locate the comment that describes the
Gemini Code Assist override using a bogus focusPasteCommands (and the other
comment referencing the clipboard preservation test) and replace "TC-011" with
"clipboard-preservation-010" so the script's comments match the QA/integration
test identifiers.
- Around line 13-16: Update the incorrect test ID comments from "TC-011" to
"clipboard-preservation-010" where referenced and correct the comment that
mentions "bogus focusPasteCommands" to match the actual property name
focusAndPasteCommands; in addition, resolve the os.tmpdir() portability mismatch
around SETTINGS_DIR (the constant SETTINGS_DIR using os.tmpdir()) by either
hardcoding the path to "/tmp/rl-vscode-test-with-ext/User" to match the
documented test host or by adding a short runtime verification/coordination step
so the test runner and this script use the same temp directory (choose one
approach and apply consistently); make these edits around the SETTINGS_DIR
declaration and the comments that reference the test ID and
focusAndPasteCommands.

In
`@packages/rangelink-vscode-extension/src/__integration-tests__/suite/bindToDestination.test.ts`:
- Around line 335-337: The numbered steps in the test's instruction array are
duplicated (two "1." entries) which breaks the manual flow; update the three
strings so they read sequentially ("1. Press Cmd+R Cmd+D and select any built-in
AI assistant (e.g., Claude Code Chat)", "2. Press Cmd+R Cmd+D and select any
built-in AI assistant (e.g., Gemini Code Assist)", "3. Press Cmd+R Cmd+D again")
— locate the instruction array in the bindToDestination.test.ts integration test
(the test/suite or variable holding the steps) and change the second and third
string prefixes from "1." and "2." to "2." and "3." respectively.

In
`@packages/rangelink-vscode-extension/src/destinations/capabilities/AIAssistantFocusCapability.ts`:
- Around line 65-68: The loop in AIAssistantFocusCapability that uses
refocus.intervalMs can hang if intervalMs is zero or negative because waitMs
becomes non-positive and elapsed doesn't advance; update the refocus handling
(where elapsed, waitMs and refocus.totalMs are used) to guard intervalMs by
validating or normalizing it before the loop (e.g., require intervalMs > 0 and
throw or clamp to a sensible minimum like 1ms), or compute waitMs as Math.max(1,
Math.min(refocus.intervalMs, refocus.totalMs - elapsed)) so elapsed always
progresses and the loop terminates.

In
`@packages/rangelink-vscode-extension/src/utils/aiAssistants/isGitHubCopilotChatAvailable.ts`:
- Around line 15-16: The code currently only checks the first entry
(chatCommand) of GITHUB_COPILOT_CHAT_FOCUS_COMMANDS which can miss the fallback;
update isGitHubCopilotChatAvailable to test the entire
GITHUB_COPILOT_CHAT_FOCUS_COMMANDS array (e.g., use Array.prototype.some or
equivalent) against the registered commands list instead of only using
GITHUB_COPILOT_CHAT_FOCUS_COMMANDS[0], so commandExists reflects any matching
focus command.

---

Outside diff comments:
In `@packages/rangelink-vscode-extension/README.md`:
- Line 373: Update the README sentence that undercounts built-in assistants:
locate the line containing "Define custom AI assistants to extend RangeLink
beyond the three built-in AI tools." and change "three" to "four" so it reads
"four built-in AI tools" to account for the added Gemini Code Assist.

---

Nitpick comments:
In
`@packages/rangelink-vscode-extension/src/__integration-tests__/suite/clipboardPreservation.test.ts`:
- Around line 382-397: After confirming focus failure (using lines010 and
focusFailLog) add an assertion that the user-facing warning toast was shown by
searching the same lines010 for a toast/warning log entry (e.g., find a line
that includes both "toast" and "warning" or the exact scenario message text),
failing the test if it's not present; place this new assertion after the
focusFailLog check and before the clipboard assertion so the test verifies the
UX toast path as well (use the existing logCapture.getLinesSince('before-010')
and lines010.find(...) pattern and keep the assertion style consistent with the
surrounding asserts and assertClipboardChanged call).

In `@packages/rangelink-vscode-extension/src/__tests__/extension.test.ts`:
- Around line 624-629: The test hardcodes COMMAND_COUNT = 51 which is brittle;
change the test to derive the command count from the authoritative command list
instead of a magic number: import or reference the shared expected commands
array/constant used by the extension (e.g., the exported command IDs list or
COMMANDS constant) and set COMMAND_COUNT = sharedCommands.length, then recompute
EXPECTED_SUBSCRIPTION_COUNT using that derived value along with
INFRASTRUCTURE_COUNT, PROVIDER_COUNT, and DESTINATION_MANAGER_LISTENERS so the
assertion stays correct when commands change.

In
`@packages/rangelink-vscode-extension/src/destinations/utils/buildDestinationQuickPickItems.ts`:
- Line 21: BUILTIN_AI_COUNT is a brittle hard-coded value that must match
AI_ASSISTANT_KINDS.length; change the code to derive the count from the array
instead of a manual constant — replace the exported constant BUILTIN_AI_COUNT
with a derived value using AI_ASSISTANT_KINDS.length (or remove the constant and
use AI_ASSISTANT_KINDS.length where fullSequence and related logic reference
BUILTIN_AI_COUNT) so the built-in AI block splitting in fullSequence stays
correct and the test asserting equality remains valid.

In
`@packages/rangelink-vscode-extension/src/utils/__tests__/aiAssistants/isGeminiCodeAssistAvailable.test.ts`:
- Around line 79-111: Update the three edge-case tests for
isGeminiCodeAssistAvailable to also assert the logger calls: in the "should not
match other Google extensions", "should handle mixed extensions list", and
"should use exact extension ID match" tests add expectations that
mockLogger.debug was invoked (or invoked with the expected diagnostic message)
appropriate to the code path after calling isGeminiCodeAssistAvailable;
reference the isGeminiCodeAssistAvailable function and the existing mockAdapter
configurations (extensionsOptions / EXTENSION_ID_GEMINI_CODE_ASSIST) to locate
where to add mockLogger.debug assertions so logging checks are consolidated with
the behavior assertions.
🪄 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: CHILL

Plan: Pro

Run ID: 9e11cbaf-0c0a-470e-bf2a-cd8364610f5a

📥 Commits

Reviewing files that changed from the base of the PR and between f325f7b and 946eed1.

📒 Files selected for processing (67)
  • package.json
  • packages/rangelink-vscode-extension/.vscode-test.with-extensions.mjs
  • 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-003.yaml
  • packages/rangelink-vscode-extension/scripts/setup-integration-test-settings-with-extensions.js
  • packages/rangelink-vscode-extension/scripts/setup-integration-test-settings.js
  • packages/rangelink-vscode-extension/scripts/test-release-run.sh
  • packages/rangelink-vscode-extension/src/__integration-tests__/suite/bindToDestination.test.ts
  • packages/rangelink-vscode-extension/src/__integration-tests__/suite/clipboardPreservation.test.ts
  • packages/rangelink-vscode-extension/src/__integration-tests__/suite/commandRegistration.test.ts
  • packages/rangelink-vscode-extension/src/__integration-tests__/suite/customAiAssistants.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/constants/packageJsonContracts.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/constants/settingDefaults.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/destinations/ComposablePasteDestination.integration.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/destinations/DestinationRegistry.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/destinations/PasteDestinationManager.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/destinations/capabilities/AIAssistantFocusCapability.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/destinations/capabilities/FocusCapabilityFactory.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/destinations/capabilities/insertFactories/aiAssistantInsertFactory.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/destinations/destinationBuilders.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/destinations/utils/buildDestinationQuickPickItems.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/extension.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/helpers/createMockBindableQuickPickItem.ts
  • packages/rangelink-vscode-extension/src/__tests__/helpers/createMockDestinationRegistry.ts
  • packages/rangelink-vscode-extension/src/__tests__/helpers/createMockFocusCapabilityFactory.ts
  • packages/rangelink-vscode-extension/src/__tests__/helpers/createMockGeminiCodeAssistComposableDestination.ts
  • packages/rangelink-vscode-extension/src/__tests__/helpers/createMockGeminiCodeAssistDestination.ts
  • packages/rangelink-vscode-extension/src/__tests__/helpers/index.ts
  • packages/rangelink-vscode-extension/src/__tests__/helpers/spyOnIsGeminiCodeAssistAvailable.ts
  • packages/rangelink-vscode-extension/src/__tests__/services/ClipboardRouter.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/wireSubscriptions.test.ts
  • packages/rangelink-vscode-extension/src/constants/chatPasteConstants.ts
  • packages/rangelink-vscode-extension/src/constants/commandIds.ts
  • packages/rangelink-vscode-extension/src/constants/settingDefaults.ts
  • packages/rangelink-vscode-extension/src/constants/settingKeys.ts
  • packages/rangelink-vscode-extension/src/createWiringServices.ts
  • packages/rangelink-vscode-extension/src/destinations/DestinationAvailabilityService.ts
  • packages/rangelink-vscode-extension/src/destinations/DestinationRegistry.ts
  • packages/rangelink-vscode-extension/src/destinations/PasteDestinationManager.ts
  • packages/rangelink-vscode-extension/src/destinations/aiAssistantFocusCommands.ts
  • packages/rangelink-vscode-extension/src/destinations/capabilities/AIAssistantFocusCapability.ts
  • packages/rangelink-vscode-extension/src/destinations/capabilities/ColdRefocusConfig.ts
  • packages/rangelink-vscode-extension/src/destinations/capabilities/FocusCapabilityFactory.ts
  • packages/rangelink-vscode-extension/src/destinations/capabilities/index.ts
  • packages/rangelink-vscode-extension/src/destinations/capabilities/insertFactories/aiAssistantInsertFactory.ts
  • packages/rangelink-vscode-extension/src/destinations/destinationBuilders.ts
  • packages/rangelink-vscode-extension/src/destinations/index.ts
  • packages/rangelink-vscode-extension/src/destinations/utils/buildDestinationQuickPickItems.ts
  • packages/rangelink-vscode-extension/src/i18n/messages.en.ts
  • packages/rangelink-vscode-extension/src/services/ClipboardRouter.ts
  • packages/rangelink-vscode-extension/src/types/BindOptions.ts
  • packages/rangelink-vscode-extension/src/types/DestinationKind.ts
  • packages/rangelink-vscode-extension/src/types/MessageCode.ts
  • packages/rangelink-vscode-extension/src/utils/__tests__/aiAssistants/isClaudeCodeAvailable.test.ts
  • packages/rangelink-vscode-extension/src/utils/__tests__/aiAssistants/isCursorIDEDetected.test.ts
  • packages/rangelink-vscode-extension/src/utils/__tests__/aiAssistants/isGeminiCodeAssistAvailable.test.ts
  • packages/rangelink-vscode-extension/src/utils/__tests__/aiAssistants/isGitHubCopilotChatAvailable.test.ts
  • packages/rangelink-vscode-extension/src/utils/aiAssistants/builtInAiAssistants.ts
  • packages/rangelink-vscode-extension/src/utils/aiAssistants/index.ts
  • packages/rangelink-vscode-extension/src/utils/aiAssistants/isClaudeCodeAvailable.ts
  • packages/rangelink-vscode-extension/src/utils/aiAssistants/isGeminiCodeAssistAvailable.ts
  • packages/rangelink-vscode-extension/src/utils/aiAssistants/isGitHubCopilotChatAvailable.ts
  • packages/rangelink-vscode-extension/src/wireSubscriptions.ts
  • packages/rangelink-vscode-extension/test-fixtures/dummy-ai-extension/extension.js
  • packages/rangelink-vscode-extension/test-fixtures/dummy-ai-extension/package.json
💤 Files with no reviewable changes (1)
  • packages/rangelink-vscode-extension/src/destinations/capabilities/insertFactories/aiAssistantInsertFactory.ts
✅ Files skipped from review due to trivial changes (14)
  • packages/rangelink-vscode-extension/src/integration-tests/suite/commandRegistration.test.ts
  • packages/rangelink-vscode-extension/src/constants/commandIds.ts
  • packages/rangelink-vscode-extension/src/destinations/capabilities/ColdRefocusConfig.ts
  • packages/rangelink-vscode-extension/src/tests/helpers/spyOnIsGeminiCodeAssistAvailable.ts
  • packages/rangelink-vscode-extension/src/destinations/index.ts
  • packages/rangelink-vscode-extension/src/tests/helpers/createMockFocusCapabilityFactory.ts
  • packages/rangelink-vscode-extension/src/utils/aiAssistants/index.ts
  • packages/rangelink-vscode-extension/src/constants/chatPasteConstants.ts
  • packages/rangelink-vscode-extension/src/utils/tests/aiAssistants/isCursorIDEDetected.test.ts
  • packages/rangelink-vscode-extension/src/utils/aiAssistants/builtInAiAssistants.ts
  • packages/rangelink-vscode-extension/src/tests/helpers/createMockBindableQuickPickItem.ts
  • packages/rangelink-vscode-extension/src/constants/settingDefaults.ts
  • packages/rangelink-vscode-extension/src/types/MessageCode.ts
  • packages/rangelink-vscode-extension/src/tests/destinations/capabilities/AIAssistantFocusCapability.test.ts
🚧 Files skipped from review as they are similar to previous changes (25)
  • package.json
  • packages/rangelink-vscode-extension/src/destinations/aiAssistantFocusCommands.ts
  • packages/rangelink-vscode-extension/src/tests/helpers/index.ts
  • packages/rangelink-vscode-extension/src/wireSubscriptions.ts
  • packages/rangelink-vscode-extension/src/tests/wireSubscriptions.test.ts
  • packages/rangelink-vscode-extension/src/types/BindOptions.ts
  • packages/rangelink-vscode-extension/CHANGELOG.md
  • packages/rangelink-vscode-extension/src/destinations/DestinationAvailabilityService.ts
  • packages/rangelink-vscode-extension/src/tests/helpers/createMockGeminiCodeAssistComposableDestination.ts
  • packages/rangelink-vscode-extension/src/destinations/PasteDestinationManager.ts
  • packages/rangelink-vscode-extension/src/i18n/messages.en.ts
  • packages/rangelink-vscode-extension/.vscode-test.with-extensions.mjs
  • packages/rangelink-vscode-extension/src/tests/destinations/DestinationRegistry.test.ts
  • packages/rangelink-vscode-extension/src/tests/destinations/utils/buildDestinationQuickPickItems.test.ts
  • packages/rangelink-vscode-extension/qa/qa-test-cases-v1.1.0-003.yaml
  • packages/rangelink-vscode-extension/src/tests/helpers/createMockDestinationRegistry.ts
  • packages/rangelink-vscode-extension/package.json
  • packages/rangelink-vscode-extension/src/tests/destinations/destinationBuilders.test.ts
  • packages/rangelink-vscode-extension/src/tests/helpers/createMockGeminiCodeAssistDestination.ts
  • packages/rangelink-vscode-extension/src/destinations/destinationBuilders.ts
  • packages/rangelink-vscode-extension/scripts/test-release-run.sh
  • packages/rangelink-vscode-extension/src/tests/constants/packageJsonContracts.test.ts
  • packages/rangelink-vscode-extension/src/tests/destinations/PasteDestinationManager.test.ts
  • packages/rangelink-vscode-extension/src/utils/aiAssistants/isGeminiCodeAssistAvailable.ts
  • packages/rangelink-vscode-extension/src/types/DestinationKind.ts

couimet added 2 commits May 8, 2026 08:39
Fixes across four categories:

- Doc: update README built-in AI tool count from three to four (A)
- Defensive: guard intervalMs <= 0 in AIAssistantFocusCapability to prevent
  infinite loops (H); check all focus commands in isGitHubCopilotChatAvailable
  instead of only index 0 (I)
- Correctness: derive BUILTIN_AI_COUNT from AI_ASSISTANT_KINDS.length (C);
  derive COMMAND_COUNT from the command list instead of hardcoding 51 (E);
  fix stale TC-011 IDs, rename focusPasteCommands->focusAndPasteCommands, and
  replace os.tmpdir() with /tmp in integration-test setup script (F)
- Test hygiene: add logger assertions to 3 edge-case tests in
  isGeminiCodeAssistAvailable.test.ts (B); add toast assertion in TC-010
  clipboardPreservation.test.ts (D); fix duplicated step numbering in
  bindToDestination.test.ts (G)

Ref: #538 (review)
@couimet
Copy link
Copy Markdown
Owner Author

couimet commented May 8, 2026

@coderabbitai review -- I was rate-limited in #538 (comment) . I don't believe you reviewed since my last push

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 8, 2026

@couimet: Understood — I'll trigger a fresh review of PR #538 now, including all changes since your last push.

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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/utils/__tests__/aiAssistants/isGitHubCopilotChatAvailable.test.ts (1)

194-207: ⚡ Quick win

Add logger assertion in this behavior test for consistency.

This case asserts availability but not the emitted log payload, unlike the other behavior tests in this suite.

Suggested test addition
   it('should handle multiple extensions when Copilot Chat is active', async () => {
     mockAdapter = createMockVscodeAdapter({
       commandsOptions: { availableCommands: [] },
       extensionsOptions: [
         { id: 'other.extension', isActive: true },
         { id: EXTENSION_ID_GITHUB_COPILOT_CHAT, isActive: true },
         { id: 'another.extension', isActive: false },
       ],
     });

     const result = await isGitHubCopilotChatAvailable(mockAdapter, mockLogger);

     expect(result).toBe(true);
+    expect(mockLogger.debug).toHaveBeenCalledWith(
+      {
+        fn: 'isGitHubCopilotChatAvailable',
+        extensionId: 'github.copilot-chat',
+        extensionFound: true,
+        extensionActive: true,
+        detectionMethod: 'extension',
+      },
+      'GitHub Copilot Chat detected via extension',
+    );
   });

As per coding guidelines, "Include logger assertions in tests that verify method behavior - consolidate logging checks with behavior tests, never create separate logging-only tests".

🤖 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
`@packages/rangelink-vscode-extension/src/utils/__tests__/aiAssistants/isGitHubCopilotChatAvailable.test.ts`
around lines 194 - 207, Add the logger assertion to this behavior test: after
calling isGitHubCopilotChatAvailable(mockAdapter, mockLogger) assert that
mockLogger.info was invoked with the same payload/format used in the other
availability tests (i.e., the same message/structure used to indicate GitHub
Copilot Chat is available). Locate the test "should handle multiple extensions
when Copilot Chat is active" and add an expectation against mockLogger
(mockLogger.info) consistent with the other tests in this suite so the logging
check is consolidated with the behavior assertion for
isGitHubCopilotChatAvailable.
🤖 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
`@packages/rangelink-vscode-extension/src/utils/__tests__/aiAssistants/isGitHubCopilotChatAvailable.test.ts`:
- Around line 194-207: Add the logger assertion to this behavior test: after
calling isGitHubCopilotChatAvailable(mockAdapter, mockLogger) assert that
mockLogger.info was invoked with the same payload/format used in the other
availability tests (i.e., the same message/structure used to indicate GitHub
Copilot Chat is available). Locate the test "should handle multiple extensions
when Copilot Chat is active" and add an expectation against mockLogger
(mockLogger.info) consistent with the other tests in this suite so the logging
check is consolidated with the behavior assertion for
isGitHubCopilotChatAvailable.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2b237d31-a20a-40ac-a8cd-4d8d5e69ed67

📥 Commits

Reviewing files that changed from the base of the PR and between 946eed1 and d82b25d.

📒 Files selected for processing (11)
  • packages/rangelink-vscode-extension/README.md
  • packages/rangelink-vscode-extension/scripts/setup-integration-test-settings-with-extensions.js
  • packages/rangelink-vscode-extension/src/__integration-tests__/suite/bindToDestination.test.ts
  • packages/rangelink-vscode-extension/src/__integration-tests__/suite/clipboardPreservation.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/destinations/capabilities/AIAssistantFocusCapability.test.ts
  • packages/rangelink-vscode-extension/src/__tests__/extension.test.ts
  • packages/rangelink-vscode-extension/src/destinations/capabilities/AIAssistantFocusCapability.ts
  • packages/rangelink-vscode-extension/src/destinations/utils/buildDestinationQuickPickItems.ts
  • packages/rangelink-vscode-extension/src/utils/__tests__/aiAssistants/isGeminiCodeAssistAvailable.test.ts
  • packages/rangelink-vscode-extension/src/utils/__tests__/aiAssistants/isGitHubCopilotChatAvailable.test.ts
  • packages/rangelink-vscode-extension/src/utils/aiAssistants/isGitHubCopilotChatAvailable.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/rangelink-vscode-extension/README.md
🚧 Files skipped from review as they are similar to previous changes (8)
  • packages/rangelink-vscode-extension/src/destinations/utils/buildDestinationQuickPickItems.ts
  • packages/rangelink-vscode-extension/scripts/setup-integration-test-settings-with-extensions.js
  • packages/rangelink-vscode-extension/src/tests/destinations/capabilities/AIAssistantFocusCapability.test.ts
  • packages/rangelink-vscode-extension/src/integration-tests/suite/clipboardPreservation.test.ts
  • packages/rangelink-vscode-extension/src/utils/tests/aiAssistants/isGeminiCodeAssistAvailable.test.ts
  • packages/rangelink-vscode-extension/src/destinations/capabilities/AIAssistantFocusCapability.ts
  • packages/rangelink-vscode-extension/src/utils/aiAssistants/isGitHubCopilotChatAvailable.ts
  • packages/rangelink-vscode-extension/src/integration-tests/suite/bindToDestination.test.ts

…nsion test

The test "should handle multiple extensions when Copilot Chat is active" was the only behavior test in the suite without a mockLogger.debug assertion. All other tests in the same describe block already verify the log payload per T007.

Benefits:
- Consistent logging assertions across all isGitHubCopilotChatAvailable tests
- Prevents regression where the log payload silently breaks

Ref: #538 (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.

Add support for Gemini Code Assist as built-in AI assistant

1 participant