Skip to content

Conversation

@couimet
Copy link
Owner

@couimet couimet commented Feb 6, 2026

Summary

This side-quest addresses two related issues:

  1. Bug Fix: Terminal jump (R-J) was not actually moving focus to the terminal - it showed the terminal panel but kept focus in the editor
  2. Refactor: Renamed PasteExecutorFocusCapability with symmetric InsertFactory injection pattern

Changes

Bug Fix - For unreleased version

  • Changed terminal.show(true) (preserveFocus) to ideAdapter.showTerminal(terminal, StealFocus)
  • Now R-J properly moves focus to the terminal

Architecture Refactor

  • Renamed types for clarity:

    • PasteExecutorFocusCapability (emphasizes what it does: focus destinations)
    • FocusSuccessFocusedDestination (a handle to something focused)
    • CommandPasteExecutorAIAssistantFocusCapability (domain concept, not implementation)
  • Extracted InsertFactory<T> interface with class implementations:

    • TerminalInsertFactory - pastes via clipboard to terminal
    • EditorInsertFactory - inserts text at cursor
    • AIAssistantInsertFactory - clipboard paste with command execution
  • Made implementations symmetric:

    • Both Editor and Terminal capabilities now receive InsertFactory as constructor dependency
    • Both call factory.forTarget(target) to create insert functions
    • AI assistant uses forTarget() with no argument (void parameter)

File Structure

src/destinations/capabilities/
├── FocusCapability.ts              (interface + FocusedDestination + FocusResult)
├── TerminalFocusCapability.ts
├── EditorFocusCapability.ts
├── AIAssistantFocusCapability.ts
├── FocusCapabilityFactory.ts
├── insertFactories/
│   ├── InsertFactory.ts            (type definition)
│   ├── terminalInsertFactory.ts
│   ├── editorInsertFactory.ts
│   └── aiAssistantInsertFactory.ts
└── index.ts

Benefits

  1. Clear naming - Types describe what they do, not how they do it
  2. Symmetry - All implementations follow same pattern
  3. Testability - InsertFactory can be mocked in unit tests
  4. Decoupling - Focus logic separated from insert logic

Summary by CodeRabbit

  • Refactor

    • Enhanced internal architecture for text insertion handling to improve consistency and maintainability across editor, terminal, and AI assistant destinations.
  • Tests

    • Expanded test coverage with new test suites validating text insertion functionality across all supported destination types.

The R-J command (cmd+r cmd+j) was not actually jumping to the terminal - it showed
the terminal panel but kept focus in the editor. This was due to `terminal.show(true)`
which preserves focus instead of stealing it.

Changed to use `ideAdapter.showTerminal(terminal, TerminalFocusType.StealFocus)` for
consistency with other terminal operations and correct focus behavior.

Benefits:
- R-J command now actually moves focus to the bound terminal
- Consistent use of adapter pattern for terminal focus operations
- Uses existing TerminalFocusType enum for explicit intent
## Summary

This side-quest addresses two related issues:

1. **Bug Fix**: Terminal jump (R-J) was not actually moving focus to the terminal - it showed the terminal panel but kept focus in the editor
2. **Refactor**: Renamed `PasteExecutor` → `FocusCapability` with symmetric `InsertFactory` injection pattern

## Changes

### Bug Fix - For unreleased version
- Changed `terminal.show(true)` (preserveFocus) to `ideAdapter.showTerminal(terminal, StealFocus)`
- Now R-J properly moves focus to the terminal

### Architecture Refactor
- Renamed types for clarity:
  - `PasteExecutor` → `FocusCapability` (emphasizes what it does: focus destinations)
  - `FocusSuccess` → `FocusedDestination` (a handle to something focused)
  - `CommandPasteExecutor` → `AIAssistantFocusCapability` (domain concept, not implementation)

- Extracted `InsertFactory<T>` interface with class implementations:
  - `TerminalInsertFactory` - pastes via clipboard to terminal
  - `EditorInsertFactory` - inserts text at cursor
  - `AIAssistantInsertFactory` - clipboard paste with command execution

- Made implementations symmetric:
  - Both Editor and Terminal capabilities now receive `InsertFactory` as constructor dependency
  - Both call `factory.forTarget(target)` to create insert functions
  - AI assistant uses `forTarget()` with no argument (void parameter)

### File Structure
```
src/destinations/capabilities/
├── FocusCapability.ts              (interface + FocusedDestination + FocusResult)
├── TerminalFocusCapability.ts
├── EditorFocusCapability.ts
├── AIAssistantFocusCapability.ts
├── FocusCapabilityFactory.ts
├── insertFactories/
│   ├── InsertFactory.ts            (type definition)
│   ├── terminalInsertFactory.ts
│   ├── editorInsertFactory.ts
│   └── aiAssistantInsertFactory.ts
└── index.ts
```

## Benefits

1. **Clear naming** - Types describe what they do, not how they do it
2. **Symmetry** - All implementations follow same pattern
3. **Testability** - InsertFactory can be mocked in unit tests
4. **Decoupling** - Focus logic separated from insert logic
@coderabbitai
Copy link

coderabbitai bot commented Feb 6, 2026

Warning

Rate limit exceeded

@couimet has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 15 minutes and 45 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.

Walkthrough

This change refactors the VSCode extension's destination architecture by replacing the PasteExecutor-based pattern with a new FocusCapability and InsertFactory separation of concerns. Key transforms include renaming three executor classes to focus capabilities, introducing a dedicated FocusCapabilityFactory, and creating separate InsertFactory implementations for each target type. The insert function signature is simplified to remove the context parameter, which is now captured internally within the focused destination.

Changes

Cohort / File(s) Summary
FocusCapability Core Implementation
src/destinations/capabilities/FocusCapability.ts, src/destinations/capabilities/AIAssistantFocusCapability.ts, src/destinations/capabilities/EditorFocusCapability.ts, src/destinations/capabilities/TerminalFocusCapability.ts
New/renamed capability classes implementing FocusCapability interface; renames FocusSuccess to FocusedDestination and updates insert signature to remove context parameter; CommandPasteExecutor, EditorPasteExecutor, TerminalPasteExecutor removed and replaced with focus-based variants.
FocusCapabilityFactory
src/destinations/capabilities/FocusCapabilityFactory.ts
New factory class replacing PasteExecutorFactory, centralizes creation of all three FocusCapability implementations with injected InsertFactory instances. Removed: PasteExecutorFactory.ts.
InsertFactory Interface & Implementations
src/destinations/capabilities/insertFactories/InsertFactory.ts, src/destinations/capabilities/insertFactories/aiAssistantInsertFactory.ts, src/destinations/capabilities/insertFactories/editorInsertFactory.ts, src/destinations/capabilities/insertFactories/terminalInsertFactory.ts, src/destinations/capabilities/insertFactories/index.ts
New generic InsertFactory interface with three concrete implementations decoupling insert logic from focus concerns; each factory bound to a specific target type (void, TextEditor, Terminal).
Destination Core Configuration
src/destinations/ComposablePasteDestination.ts, src/destinations/DestinationRegistry.ts, src/destinations/destinationBuilders.ts, src/extension.ts
Updated to use FocusCapability instead of PasteExecutor; destination params and configurations renamed from pasteExecutor to focusCapability; destination creation methods wired to use new factory methods.
Public API Exports
src/destinations/capabilities/index.ts
Replaced PasteExecutor-related exports with FocusCapability types; added exports for new InsertFactory implementations and AIAssistantFocusCapability; removed EligibilityChecker exports.
Test Helpers & Mocks
src/__tests__/helpers/createMockComposablePasteDestination.ts, src/__tests__/helpers/createMockFocusCapabilityFactory.ts, src/__tests__/helpers/index.ts
Introduced new mock factory for FocusCapabilityFactory; replaced mock pasteExecutor with mock focusCapability in destination helpers; updated export index to expose new mocks.
Integration & Unit Tests (Destinations)
src/__tests__/destinations/ComposablePasteDestination.integration.test.ts, src/__tests__/destinations/ComposablePasteDestination.test.ts, src/__tests__/destinations/DestinationRegistry.test.ts, src/__tests__/destinations/PasteDestinationManager.test.ts, src/__tests__/destinations/destinationBuilders.test.ts
Updated test setup and assertions to use focusCapability mocks and verify new focus/insert patterns; replaced pasteExecutor references with focusCapability throughout; adjusted expectations to match new capability signatures.
Capability-Specific Tests (Removed & Added)
src/__tests__/destinations/capabilities/EditorPasteExecutor.test.ts (removed), src/__tests__/destinations/capabilities/insertFactories/aiAssistantInsertFactory.test.ts, src/__tests__/destinations/capabilities/insertFactories/editorInsertFactory.test.ts, src/__tests__/destinations/capabilities/insertFactories/terminalInsertFactory.test.ts (added)
Removed old EditorPasteExecutor test suite; added comprehensive tests for new InsertFactory implementations covering target binding, error handling, logging, and paste workflows.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐰 The executors once all stood apart,
But Focus and Insert now play their part!
Factories flourish with targets in hand,
A cleaner design across all the land!
With tests rewritten and logic refined,
A better architecture we've now aligned! 🎯✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: a terminal focus fix and a significant refactor of the focus/paste architecture.
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
  • Post copyable unit tests in a comment
  • Commit unit tests in branch side-quest/terminal-jump-focus-fix

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

@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

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/ComposablePasteDestination.ts (1)

538-540: ⚠️ Potential issue | 🟡 Minor

Stale JSDoc reference to TextInserter.

Line 539 mentions "Inject mocked capabilities (TextInserter, EligibilityChecker, etc.)" but TextInserter no longer exists — it should reference FocusCapability or InsertFactory.

📝 Suggested fix
    * This method is exposed for unit tests that need to:
-   * - Inject mocked capabilities (TextInserter, EligibilityChecker, etc.)
+   * - Inject mocked capabilities (FocusCapability, EligibilityChecker, etc.)
    * - Test specific orchestration scenarios
🤖 Fix all issues with AI agents
In
`@packages/rangelink-vscode-extension/src/destinations/capabilities/insertFactories/aiAssistantInsertFactory.ts`:
- Line 28: Replace the Node-specific global.setTimeout call in
aiAssistantInsertFactory.ts with the universal setTimeout to fix the no-undef CI
error: inside the async pause awaiting the paste delay (the line using
FOCUS_TO_PASTE_DELAY_MS), change the Promise constructor to call
setTimeout(resolve, FOCUS_TO_PASTE_DELAY_MS) instead of global.setTimeout so the
code runs in all JS environments.
- Around line 22-43: The forTarget() async function currently calls
this.ideAdapter.writeTextToClipboard(text) without handling exceptions, so a
clipboard write failure will throw and bypass the pasteCommands loop; wrap the
entire function body (inside the returned async (text) => { ... }) in a
try/catch so any error from writeTextToClipboard (and any other unexpected
error) is caught, log the error via this.logger (include fn and error) and
return false; keep the existing try/catch around
this.ideAdapter.executeCommand(command) intact and ensure you still await the
FOCUS_TO_PASTE_DELAY_MS before attempting pasteCommands.
🧹 Nitpick comments (8)
packages/rangelink-vscode-extension/src/__tests__/destinations/capabilities/insertFactories/terminalInsertFactory.test.ts (2)

9-37: Test at lines 26-37 is redundant with the first test.

The "returns true on successful paste" test (lines 26-37) is a subset of the first test (lines 9-24), which already asserts result === true and verifies the paste call. Consider removing it or consolidating into a single test.


54-85: Consolidate logging assertions into behavior tests instead of separate tests.

The "logs success on successful paste" and "logs warning on paste failure" tests are standalone logging-only tests. Per coding guidelines, logger assertions should be included in the tests that verify the corresponding behavior (e.g., the success path test and the failure path test). As per coding guidelines: "Include logger assertions in tests that verify method behavior - consolidate logging verification with behavior tests, never create separate tests just for logging."

♻️ Suggested consolidation
  it('creates an insert function that pastes text to terminal via clipboard', async () => {
    const mockAdapter = createMockVscodeAdapter();
-   const mockTerminal = createMockTerminal({ name: 'Test Terminal' });
+   const mockTerminal = createMockTerminal({ name: 'My Terminal' });
    const pasteTextSpy = jest
      .spyOn(mockAdapter, 'pasteTextToTerminalViaClipboard')
      .mockResolvedValue(undefined);

    const factory = new TerminalInsertFactory(mockAdapter, mockLogger);
    const insertFn = factory.forTarget(mockTerminal);

    const result = await insertFn('test content');

    expect(result).toBe(true);
    expect(pasteTextSpy).toHaveBeenCalledTimes(1);
    expect(pasteTextSpy).toHaveBeenCalledWith(mockTerminal, 'test content');
+   expect(mockLogger.info).toHaveBeenCalledWith(
+     { fn: 'TerminalInsertFactory.insert', terminalName: 'My Terminal' },
+     'Terminal paste succeeded',
+   );
  });

  it('returns false when paste throws an error', async () => {
    const mockAdapter = createMockVscodeAdapter();
-   const mockTerminal = createMockTerminal({ name: 'Test Terminal' });
-   jest
+   const mockTerminal = createMockTerminal({ name: 'My Terminal' });
+   const testError = new Error('Paste failed');
+   jest
      .spyOn(mockAdapter, 'pasteTextToTerminalViaClipboard')
-     .mockRejectedValue(new Error('Paste failed'));
+     .mockRejectedValue(testError);

    const factory = new TerminalInsertFactory(mockAdapter, mockLogger);
    const insertFn = factory.forTarget(mockTerminal);

    const result = await insertFn('content');

    expect(result).toBe(false);
+   expect(mockLogger.warn).toHaveBeenCalledWith(
+     { fn: 'TerminalInsertFactory.insert', terminalName: 'My Terminal', error: testError },
+     'Terminal paste failed',
+   );
  });

Then remove the standalone logging tests at lines 54-85.

packages/rangelink-vscode-extension/src/__tests__/destinations/capabilities/insertFactories/editorInsertFactory.test.ts (2)

21-47: Test at lines 36-47 is redundant with the first test.

"returns true when insertTextAtCursor succeeds" (lines 36-47) duplicates the assertion already in the first test (line 31). Consider removing it.


75-122: Consolidate logging assertions into behavior tests.

Same pattern as in terminalInsertFactory.test.ts — these three tests (lines 75-89, 91-105, 107-122) exist solely to verify logging. Per coding guidelines, fold logger assertions into the corresponding behavior tests (success, failure, and exception paths). As per coding guidelines: "Include logger assertions in tests that verify method behavior - consolidate logging verification with behavior tests, never create separate tests just for logging."

♻️ Suggested consolidation
  it('creates an insert function that inserts text at cursor', async () => {
    const mockAdapter = createMockVscodeAdapter();
    const mockEditor = createTestEditor('/path/to/file.ts');
    const insertSpy = jest.spyOn(mockAdapter, 'insertTextAtCursor').mockResolvedValue(true);

    const factory = new EditorInsertFactory(mockAdapter, mockLogger);
    const insertFn = factory.forTarget(mockEditor);

    const result = await insertFn('test content');

    expect(result).toBe(true);
    expect(insertSpy).toHaveBeenCalledTimes(1);
    expect(insertSpy).toHaveBeenCalledWith(mockEditor, 'test content');
+   expect(mockLogger.info).toHaveBeenCalledWith(
+     { fn: 'EditorInsertFactory.insert', editorUri: 'file:///path/to/file.ts' },
+     'Editor insert succeeded',
+   );
  });

  it('returns false when insertTextAtCursor returns false', async () => {
    const mockAdapter = createMockVscodeAdapter();
    const mockEditor = createTestEditor('/path/to/file.ts');
    jest.spyOn(mockAdapter, 'insertTextAtCursor').mockResolvedValue(false);

    const factory = new EditorInsertFactory(mockAdapter, mockLogger);
    const insertFn = factory.forTarget(mockEditor);

    const result = await insertFn('content');

    expect(result).toBe(false);
+   expect(mockLogger.info).toHaveBeenCalledWith(
+     { fn: 'EditorInsertFactory.insert', editorUri: 'file:///path/to/file.ts' },
+     'Editor insert failed',
+   );
  });

  it('returns false when insertTextAtCursor throws an error', async () => {
    const mockAdapter = createMockVscodeAdapter();
    const mockEditor = createTestEditor('/path/to/file.ts');
-   jest.spyOn(mockAdapter, 'insertTextAtCursor').mockRejectedValue(new Error('Insert failed'));
+   const testError = new Error('Insert threw');
+   jest.spyOn(mockAdapter, 'insertTextAtCursor').mockRejectedValue(testError);

    const factory = new EditorInsertFactory(mockAdapter, mockLogger);
    const insertFn = factory.forTarget(mockEditor);

    const result = await insertFn('content');

    expect(result).toBe(false);
+   expect(mockLogger.warn).toHaveBeenCalledWith(
+     { fn: 'EditorInsertFactory.insert', editorUri: 'file:///path/to/file.ts', error: testError },
+     'Editor insert threw exception',
+   );
  });

Then remove the standalone logging tests at lines 75-122.

packages/rangelink-vscode-extension/src/__tests__/destinations/capabilities/insertFactories/aiAssistantInsertFactory.test.ts (2)

114-174: Consolidate logging assertions into the corresponding behavior tests.

The guideline states to "never create separate tests just for logging." The clipboard-copy debug log (line 130), success info log (line 152), and all-fail info log (line 170) should be asserted within the existing behavior tests at lines 18, 67, and 92 respectively.

As per coding guidelines, **/*.test.{ts,tsx}: "Include logger assertions in tests that verify method behavior - consolidate logging verification with behavior tests, never create separate tests just for logging."


176-194: This test is redundant.

Every other test already calls factory.forTarget() with no arguments. This test doesn't exercise any unique path beyond what's covered in the first happy-path test (line 18).

packages/rangelink-vscode-extension/src/__tests__/destinations/ComposablePasteDestination.test.ts (1)

57-72: Dead _mockInsert assignment on Line 60.

Line 60 sets _mockInsert on the focusCapability object, but line 61 immediately overrides focus to return a different Result.ok({ insert: mockInsert }). The _mockInsert property is never read in this test — the assertion on line 71 checks mockInsert directly.

♻️ Suggested cleanup
     it('should not double-pad already padded text', async () => {
       const mockInsert = jest.fn().mockResolvedValue(true);
       const focusCapability = createMockFocusCapability();
-      (focusCapability as unknown as { _mockInsert: jest.Mock })._mockInsert = mockInsert;
       focusCapability.focus.mockResolvedValue(Result.ok({ insert: mockInsert }));
packages/rangelink-vscode-extension/src/destinations/destinationBuilders.ts (1)

212-221: Minor inconsistency: CURSOR_AI_FOCUS_COMMANDS and CLAUDE_CODE_FOCUS_COMMANDS are local constants, but GITHUB_COPILOT_CHAT_FOCUS_COMMANDS is imported from ../utils.

Consider colocating all three in the same place — either all local to this file or all in a shared constants module — to reduce surprise when maintaining these lists.

Comment on lines 22 to 43
forTarget(): (text: string) => Promise<boolean> {
return async (text: string): Promise<boolean> => {
const fn = 'AIAssistantInsertFactory.insert';
await this.ideAdapter.writeTextToClipboard(text);
this.logger.debug({ fn, textLength: text.length }, 'Copied text to clipboard');

await new Promise<void>((resolve) => global.setTimeout(resolve, FOCUS_TO_PASTE_DELAY_MS));

for (const command of this.pasteCommands) {
try {
await this.ideAdapter.executeCommand(command);
this.logger.info({ fn, command }, 'Clipboard paste succeeded');
return true;
} catch (error) {
this.logger.debug({ fn, command, error }, 'Paste command failed, trying next');
}
}

this.logger.info({ fn, allCommandsFailed: true }, 'All clipboard paste commands failed');
return false;
};
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Clipboard write failure is unhandled.

If writeTextToClipboard (line 25) throws, the promise rejects with an unhandled error. The paste-command loop has try/catch, but the clipboard write does not — a failure there will propagate as an unhandled rejection rather than returning false.

🛡️ Proposed fix — wrap the entire body in try/catch
   forTarget(): (text: string) => Promise<boolean> {
     return async (text: string): Promise<boolean> => {
       const fn = 'AIAssistantInsertFactory.insert';
-      await this.ideAdapter.writeTextToClipboard(text);
-      this.logger.debug({ fn, textLength: text.length }, 'Copied text to clipboard');
+      try {
+        await this.ideAdapter.writeTextToClipboard(text);
+      } catch (error) {
+        this.logger.warn({ fn, error }, 'Failed to write to clipboard');
+        return false;
+      }
+      this.logger.debug({ fn, textLength: text.length }, 'Copied text to clipboard');
 
-      await new Promise<void>((resolve) => global.setTimeout(resolve, FOCUS_TO_PASTE_DELAY_MS));
+      await new Promise<void>((resolve) => setTimeout(resolve, FOCUS_TO_PASTE_DELAY_MS));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
forTarget(): (text: string) => Promise<boolean> {
return async (text: string): Promise<boolean> => {
const fn = 'AIAssistantInsertFactory.insert';
await this.ideAdapter.writeTextToClipboard(text);
this.logger.debug({ fn, textLength: text.length }, 'Copied text to clipboard');
await new Promise<void>((resolve) => global.setTimeout(resolve, FOCUS_TO_PASTE_DELAY_MS));
for (const command of this.pasteCommands) {
try {
await this.ideAdapter.executeCommand(command);
this.logger.info({ fn, command }, 'Clipboard paste succeeded');
return true;
} catch (error) {
this.logger.debug({ fn, command, error }, 'Paste command failed, trying next');
}
}
this.logger.info({ fn, allCommandsFailed: true }, 'All clipboard paste commands failed');
return false;
};
}
forTarget(): (text: string) => Promise<boolean> {
return async (text: string): Promise<boolean> => {
const fn = 'AIAssistantInsertFactory.insert';
try {
await this.ideAdapter.writeTextToClipboard(text);
} catch (error) {
this.logger.warn({ fn, error }, 'Failed to write to clipboard');
return false;
}
this.logger.debug({ fn, textLength: text.length }, 'Copied text to clipboard');
await new Promise<void>((resolve) => setTimeout(resolve, FOCUS_TO_PASTE_DELAY_MS));
for (const command of this.pasteCommands) {
try {
await this.ideAdapter.executeCommand(command);
this.logger.info({ fn, command }, 'Clipboard paste succeeded');
return true;
} catch (error) {
this.logger.debug({ fn, command, error }, 'Paste command failed, trying next');
}
}
this.logger.info({ fn, allCommandsFailed: true }, 'All clipboard paste commands failed');
return false;
};
}
🧰 Tools
🪛 GitHub Actions: CI

[error] 28-28: ESLint: 'global' is not defined. (no-undef)

🪛 GitHub Check: Test & Validate

[failure] 28-28:
'global' is not defined

🤖 Prompt for AI Agents
In
`@packages/rangelink-vscode-extension/src/destinations/capabilities/insertFactories/aiAssistantInsertFactory.ts`
around lines 22 - 43, The forTarget() async function currently calls
this.ideAdapter.writeTextToClipboard(text) without handling exceptions, so a
clipboard write failure will throw and bypass the pasteCommands loop; wrap the
entire function body (inside the returned async (text) => { ... }) in a
try/catch so any error from writeTextToClipboard (and any other unexpected
error) is caught, log the error via this.logger (include fn and error) and
return false; keep the existing try/catch around
this.ideAdapter.executeCommand(command) intact and ensure you still await the
FOCUS_TO_PASTE_DELAY_MS before attempting pasteCommands.

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.

1 participant