Skip to content

Conversation

@brendan-kellam
Copy link
Contributor

@brendan-kellam brendan-kellam commented Dec 1, 2025

We were seeing that on large deployments, code navigation queries were sometimes taking several seconds to resolve. This was because we were searching across all repositories to resolve references / definitions.

This PR changes the default behaviour to only search in the current repository where the user is. I've also added a toggle button to allow searching across all repositories as well:

image

The rationale / intuition here is that, most of the time, symbol are only referenced within the repository they are defined in. There are exceptions of course (e.g., methods exported from a shared library), but most of the time this will be the case. Besides speed, the other benefit of scoping to the current repository as it reduces the false-positive rate inherent with search-based code navigation (e.g., if function doSomething is declared in multiple function).

Summary by CodeRabbit

  • New Features

    • Added cross-repository search toggle in the explore menu with Shift+A keyboard shortcut support.
    • Code navigation now displays keyboard shortcut hints for improved discoverability.
  • Bug Fixes

    • Fixed search query handling for repository names containing special characters.
  • Documentation

    • Updated feature documentation to reflect cross-repository navigation capabilities.
  • Chores

    • Enhanced analytics event tracking for code navigation and search interactions.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 1, 2025

Important

Review skipped

Auto reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This PR introduces cross-repository search scoping to the code navigation system. It adds a toggle UI in the explore menu to enable/disable cross-repository search, refactors the SymbolHoverPopup component from callback-based navigation to data-driven props (fileName, repoName, source), threads a repoName parameter through code navigation APIs for search filtering, and adds telemetry events for code navigation interactions.

Changes

Cohort / File(s) Summary
Documentation Updates
CHANGELOG.md, docs/docs/features/code-navigation.mdx
Added changelog entry and documentation for cross-repository navigation feature with globe-icon toggle and default repository scoping.
Code Navigation API Layer
packages/web/src/features/codeNav/types.ts, packages/web/src/features/codeNav/api.ts
Extended FindRelatedSymbolsRequest schema with optional repoName field; updated API functions to accept and propagate repoName parameter through search queries with escaped regex filtering.
SymbolHoverPopup Component & Hooks
packages/web/src/ee/features/codeNav/components/symbolHoverPopup/index.tsx, packages/web/src/ee/features/codeNav/components/symbolHoverPopup/useHoveredOverSymbolInfo.ts
Changed SymbolHoverPopup public API from callback-based (onFindReferences, onGotoDefinition) to data-driven props (repoName, fileName, source); introduced repository-scoped symbol definition selection and highlight range computation.
Explore Menu Component
packages/web/src/ee/features/codeNav/components/exploreMenu/index.tsx
Added toggle UI for global search (Shift+A hotkey), refactored query keys to include isGlobalSearchEnabled state, added event measurement and capture for load events with duration and global search context.
Browse & Preview Components
packages/web/src/app/[domain]/browse/layout.tsx, packages/web/src/app/[domain]/browse/[...path]/components/pureCodePreviewPanel.tsx, packages/web/src/app/[domain]/search/components/codePreviewPanel/codePreview.tsx
Simplified preview panel by removing navigation callbacks and hooks; added repoName/fileName props to SymbolHoverPopup; escaped repository names in search queries for exact matches.
Chat Features
packages/web/src/features/chat/components/chatThread/referencedFileSourceListItem.tsx, packages/web/src/features/chat/tools.ts
Updated SymbolHoverPopup usage with source="chat" and repo context; added optional repository parameter to chat tools for search scoping.
Search API
packages/web/src/features/search/fileSourceApi.ts
Updated repository regex matching to escape repository strings for safe interpolation.
UI Components
packages/web/src/components/ui/toggle.tsx, packages/web/src/app/components/keyboardShortcutHint.tsx
Adjusted Toggle default size to compact (h-7 w-7) and added cursor styling; added optional className prop to KeyboardShortcutHint for custom styling.
Telemetry
packages/web/src/lib/posthogEvents.ts
Added new events: wa_goto_definition_pressed, wa_find_references_pressed (both with source field), wa_explore_menu_reference_clicked, wa_symbol_hover_popup_definitions_loaded, wa_explore_menu_references_loaded, wa_explore_menu_definitions_loaded.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

  • SymbolHoverPopup API contract changes: Public props signature modified to remove onFindReferences/onGotoDefinition callbacks and add repoName/fileName/source props; requires verification all callers (CodePreview, ReferencedFileSourceListItem, etc.) are updated consistently.
  • Navigation logic refactoring: Navigation and audit actions moved from component callbacks into SymbolHoverPopup internals; ensure previewedSymbolDefinition selection logic correctly handles single vs. multiple definitions and fallback cases.
  • useHoveredOverSymbolInfo hook extension: New repoName parameter threading and highlightRange computation via CodeMirror view; verify viewport detection logic and range fallbacks are correct.
  • ExploreMenu search toggle implementation: Complex state management with isGlobalSearchEnabled affecting query keys and API calls; check that query refetching and conditional repoName propagation work as intended.
  • API contract changes: FindRelatedSymbolsRequest now accepts optional repoName; verify all query paths (search, definitions, references) handle both scoped and unscoped searches correctly with escaped regex filtering.
  • Telemetry event additions: Six new events added with varying structures; ensure all emit sites are correctly capturing source context and duration measurements.

Possibly related PRs

  • V4 #311: Both PRs make overlapping changes to SymbolHoverPopup's public props (removing callbacks, adding repoName/fileName/source), update code preview/preview-panel usage with source="preview" context, and extend find-related-symbols APIs to accept repoName filters.
  • fix(web): Fix loading issues with references / definitions list #617: Both PRs modify code navigation API signatures (findSearchBasedSymbolDefinitions/findSearchBasedSymbolReferences) and wire repoName parameters through callers like useHoveredOverSymbolInfo, ExploreMenu, and SymbolHoverPopup.
  • fix(ask_sb): Various improvements to the references system #396: Both PRs modify symbol navigation/hover behavior, telemetry tracking with source field, and related preview/hover components and their interaction patterns.

Suggested labels

sourcebot-team

Suggested reviewers

  • msukkari

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 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 change: scoping code navigation to the current repository by default, which directly addresses the performance issue mentioned in the PR objectives.

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.

@github-actions

This comment has been minimized.

@brendan-kellam
Copy link
Contributor Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Dec 1, 2025

✅ 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

@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

🧹 Nitpick comments (4)
packages/web/src/features/chat/tools.ts (2)

24-55: Repository scoping for references tool is wired correctly

Optional repository input and forwarding it as repoName into the references API cleanly enable per-repo scoping while preserving the previous behavior when omitted. Only minor nit: you define const revision = "HEAD"; but still inline "HEAD" in the request; could reuse revision for consistency, but not required.


63-95: Definitions tool mirrors references tool behavior appropriately

Adding the optional repository field and passing it through as repoName to the definitions API keeps the two tools symmetric and supports repo-scoped lookups without breaking existing callers.

packages/web/src/app/[domain]/browse/[...path]/components/pureCodePreviewPanel.tsx (1)

110-132: Nice improvement to scroll behavior.

The viewport check to determine scroll strategy (nearest vs center) prevents jarring scroll jumps when the highlight is already visible. This is a good UX consideration.

Minor nit: Line 128 uses optional chaining (editorRef.view?.dispatch) but the guard at line 110 already ensures editorRef.view is defined.

-        editorRef.view?.dispatch({
+        editorRef.view.dispatch({
packages/web/src/ee/features/codeNav/components/symbolHoverPopup/index.tsx (1)

122-127: Consider adding error handling for audit actions.

The fire-and-forget pattern is appropriate for audit/telemetry to avoid blocking user interactions. However, errors are currently silently swallowed. Consider adding a .catch() handler to log failures for observability:

-        createAuditAction({
+        createAuditAction({
             action: "user.performed_goto_definition",
             metadata: {
                 message: symbolInfo.symbolName,
             },
-        });
+        }).catch((error) => console.error('Audit action failed:', error));

The same applies to the onFindReferences callback at lines 175-180.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 28986f4 and f58d468.

📒 Files selected for processing (16)
  • CHANGELOG.md (1 hunks)
  • docs/docs/features/code-navigation.mdx (1 hunks)
  • packages/web/src/app/[domain]/browse/[...path]/components/pureCodePreviewPanel.tsx (3 hunks)
  • packages/web/src/app/[domain]/browse/layout.tsx (2 hunks)
  • packages/web/src/app/[domain]/search/components/codePreviewPanel/codePreview.tsx (2 hunks)
  • packages/web/src/app/components/keyboardShortcutHint.tsx (1 hunks)
  • packages/web/src/components/ui/toggle.tsx (2 hunks)
  • packages/web/src/ee/features/codeNav/components/exploreMenu/index.tsx (4 hunks)
  • packages/web/src/ee/features/codeNav/components/symbolHoverPopup/index.tsx (6 hunks)
  • packages/web/src/ee/features/codeNav/components/symbolHoverPopup/useHoveredOverSymbolInfo.ts (7 hunks)
  • packages/web/src/features/chat/components/chatThread/referencedFileSourceListItem.tsx (2 hunks)
  • packages/web/src/features/chat/tools.ts (2 hunks)
  • packages/web/src/features/codeNav/api.ts (5 hunks)
  • packages/web/src/features/codeNav/types.ts (1 hunks)
  • packages/web/src/features/search/fileSourceApi.ts (2 hunks)
  • packages/web/src/lib/posthogEvents.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
packages/web/src/app/components/keyboardShortcutHint.tsx (1)
packages/web/src/lib/utils.ts (1)
  • cn (24-26)
packages/web/src/ee/features/codeNav/components/symbolHoverPopup/useHoveredOverSymbolInfo.ts (4)
packages/web/src/features/search/types.ts (1)
  • SourceRange (16-16)
packages/web/src/lib/utils.ts (2)
  • measure (511-529)
  • unwrapServiceError (539-546)
packages/web/src/features/codeNav/api.ts (1)
  • findSearchBasedSymbolDefinitions (71-127)
packages/web/src/app/api/(client)/client.ts (1)
  • findSearchBasedSymbolDefinitions (82-88)
packages/web/src/ee/features/codeNav/components/symbolHoverPopup/index.tsx (4)
packages/web/src/app/[domain]/browse/hooks/useBrowseNavigation.ts (1)
  • useBrowseNavigation (8-36)
packages/web/src/ee/features/codeNav/components/symbolHoverPopup/useHoveredOverSymbolInfo.ts (1)
  • useHoveredOverSymbolInfo (39-203)
packages/web/src/ee/features/audit/actions.ts (1)
  • createAuditAction (17-26)
packages/web/src/ee/features/codeNav/components/symbolHoverPopup/symbolDefinitionPreview.tsx (1)
  • SymbolDefinitionPreview (17-57)
packages/web/src/features/chat/tools.ts (2)
packages/web/src/features/codeNav/api.ts (2)
  • findSearchBasedSymbolReferences (16-68)
  • findSearchBasedSymbolDefinitions (71-127)
packages/web/src/app/api/(client)/client.ts (2)
  • findSearchBasedSymbolReferences (74-80)
  • findSearchBasedSymbolDefinitions (82-88)
🔇 Additional comments (19)
CHANGELOG.md (1)

12-21: Changelog entry accurately documents new default and UI toggle

The new “Added” and “Changed” entries clearly describe the explore menu toggle and repo-scoped default for code nav, consistent with the PR intent. No changes needed.

packages/web/src/features/search/fileSourceApi.ts (1)

9-23: Escaping repository in repo filter regex is a solid hardening

Anchoring the repo filter and escaping the repository string before interpolating into the regexp is correct and consistent with the code nav API usage; it avoids partial matches and issues with special characters in repo names.

packages/web/src/lib/posthogEvents.ts (1)

296-316: New code‑nav telemetry events are well‑structured

The added event payloads (source, durationMs, isGlobalSearchEnabled) give good observability into code‑nav usage and the explore menu toggle. As long as all emitters are updated to provide these fields, this looks solid.

docs/docs/features/code-navigation.mdx (1)

24-42: Docs row clearly explains cross‑repo toggle and default scope

The “Cross-repository navigation” entry accurately captures the new globe toggle and default repo‑scoped behavior for references/definitions. Reads clearly and aligns with the implementation.

packages/web/src/app/[domain]/browse/layout.tsx (1)

13-35: Default browse search now safely scopes to the current repo

Escaping the repo name and anchoring it in repo:^…$ for the default SearchBar query correctly constrains searches to the active repository and avoids regex issues with special characters. The optional rev:${revisionName} suffix keeps existing revision scoping behavior.

packages/web/src/features/codeNav/api.ts (1)

11-52: Repository filter in code‑nav queries is correctly parameterized and escaped

Adding optional repoName to the request and conditionally appending an anchored, escaped repo regexp to the IR query cleanly enables repository‑scoped references/definitions. Existing callers that don’t pass repoName retain the previous cross‑repo behavior, which is ideal for a gradual rollout.

Also applies to: 71-111

packages/web/src/app/components/keyboardShortcutHint.tsx (1)

1-13: className support makes the shortcut hint more reusable

Allowing an optional className and merging it with the base styles via cn improves composability while preserving existing layout and aria-label behavior. Looks good.

packages/web/src/features/codeNav/types.ts (1)

7-16: LGTM!

The JSDoc comments clearly document the optional behavior, and the schema correctly models the repository-scoped vs. global search distinction. The repoName field being optional aligns well with the PR objective.

packages/web/src/ee/features/codeNav/components/exploreMenu/index.tsx (2)

49-66: LGTM!

The query implementation correctly:

  • Includes isGlobalSearchEnabled in the query key for proper cache invalidation
  • Conditionally passes repoName based on the toggle state
  • Wraps the fetch with measurement and captures telemetry events

161-179: LGTM!

The global search toggle UI is well-implemented with proper accessibility via the tooltip and keyboard shortcut hint. The Toggle state binding is correct.

packages/web/src/ee/features/codeNav/components/symbolHoverPopup/useHoveredOverSymbolInfo.ts (2)

59-76: LGTM!

The query implementation correctly threads repoName for repository-scoped search, includes it in the query key, and captures telemetry with duration measurement.


142-186: Solid implementation for highlight range extraction.

The coordinate-to-position conversion handles null cases correctly and the column computation properly converts to 1-based indexing. The dependency array is appropriate.

One consideration: using rect.top + rect.height / 2 for the y-coordinate works well for single-line symbols. If multi-line symbols are possible, the end position calculation might not capture the full range accurately.

packages/web/src/app/[domain]/browse/[...path]/components/pureCodePreviewPanel.tsx (1)

156-165: LGTM!

The migration from callback-based navigation (onFindReferences/onGotoDefinition) to data-driven props (fileName, repoName, source) is cleaner and aligns with the PR's approach of threading repository context through the code navigation system.

packages/web/src/features/chat/components/chatThread/referencedFileSourceListItem.tsx (1)

259-267: LGTM!

The updated SymbolHoverPopup usage correctly passes the new data-driven props (source, repoName, fileName) instead of the removed callback props. This aligns well with the broader refactor to centralize navigation logic within the SymbolHoverPopup component itself.

packages/web/src/app/[domain]/search/components/codePreviewPanel/codePreview.tsx (1)

207-216: LGTM!

The SymbolHoverPopup integration is well-structured:

  • Properly gated by hasCodeNavEntitlement
  • Correctly passes source="preview" to identify this context
  • Uses file.filepath for fileName which is consistent with the file's content model
packages/web/src/ee/features/codeNav/components/symbolHoverPopup/index.tsx (4)

88-107: Well-designed definition prioritization.

The logic to prefer definitions within the current file/repo context before falling back to the first available definition is sound and aligns with the PR objective of scoping navigation to the current repository by default.


166-199: LGTM!

The onFindReferences implementation correctly uses the current file context (repoName, fileName, revisionName, language from props) for navigation and browse state, which ensures references are searched from the user's current position.


215-221: LGTM!

The hotkey handler correctly calls onFindReferences() without parameters since the callback now obtains symbolInfo via closure from the useHoveredOverSymbolInfo hook.


261-284: LGTM!

The UI consistently uses previewedSymbolDefinition for rendering the preview, disabling the button, and displaying appropriate labels. The state transitions are handled correctly.

@brendan-kellam brendan-kellam merged commit 9257888 into main Dec 1, 2025
10 checks passed
@brendan-kellam brendan-kellam deleted the bkellam/search-based-code-nav-SOU-120 branch December 1, 2025 02:53
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.

2 participants