-
Notifications
You must be signed in to change notification settings - Fork 417
global-search result rendering on left-side-bar #1560
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Caution Review failedThe pull request is closed. 📝 WalkthroughWalkthroughAdds an in-app Orama-backed search system (context, types, indexing, multi-entity search), integrates search UI into sidebar and layout, adds search input enhancements and new result components, updates style guidance, adds dependencies, tweaks chat hotkey, adjusts timeline sizing, and removes a duplicate template. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant Input as SearchInput
participant Ctx as SearchProvider / useSearch
participant Index as Orama
participant Sidebar as SearchResults UI
participant Tabs as Tabs Store
User->>Input: Type / Hotkeys (mod+k, arrows, enter)
Input->>Ctx: setQuery / onFocus / onBlur
activate Ctx
Ctx-->>Ctx: Debounce & normalize query
Ctx->>Index: Search(query, filters, boosts)
Index-->>Ctx: Hits + scores + highlights
Ctx-->>Sidebar: grouped results { groups, totalResults, maxScore }
deactivate Ctx
Sidebar->>User: Render grouped results
User->>Sidebar: Click "Load more"
Sidebar->>Ctx: increase visible count (per-group)
Ctx-->>Sidebar: updated group view
User->>Sidebar: Click result item
Sidebar->>Tabs: openCurrent(target tab)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
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. Comment |
There was a problem hiding this 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 (2)
apps/desktop2/src/components/main/sidebar/search/empty.tsx (1)
1-14: Consider removing unnecessarycnusage.Since none of the classNames have conditional logic, using
cnadds unnecessary overhead. According to the style guidelines,cnshould be used when there are "many classNames and they have conditional logic."As per coding guidelines.
Apply this diff to simplify:
-import { cn } from "@hypr/ui/lib/utils"; - export function SearchNoResults() { return ( - <div className={cn(["h-full flex items-center justify-center"])}> - <div className={cn(["text-center px-4"])}> - <p className={cn(["text-sm text-gray-600"])}>No results found</p> - <p className={cn(["text-xs text-gray-400 mt-1"])}> + <div className="h-full flex items-center justify-center"> + <div className="text-center px-4"> + <p className="text-sm text-gray-600">No results found</p> + <p className="text-xs text-gray-400 mt-1"> Try a different search term </p> </div> </div> ); }apps/desktop2/src/components/main/sidebar/search/group.tsx (1)
1-47: Consider removing unnecessarycnusage.While the component structure is solid (early return, clean layout), none of the classNames have conditional logic. According to the style guidelines,
cnshould be used when there are "many classNames and they have conditional logic."As per coding guidelines.
Apply this diff to simplify:
-import { cn } from "@hypr/ui/lib/utils"; import { type SearchResult } from "../../../../contexts/search"; import { SearchResultItem } from "./item"; export function SearchResultGroup({ title, results, icon: Icon, }: { title: string; results: SearchResult[]; icon: React.ComponentType<{ className?: string }>; }) { if (results.length === 0) { return null; } return ( - <div className={cn(["mb-6"])}> + <div className="mb-6"> <div - className={cn([ - "sticky top-0 z-10", - "px-3 py-2 mb-2", - "flex items-center gap-2", - "bg-gray-50 rounded-lg", - "border-b border-gray-200", - ])} + className="sticky top-0 z-10 px-3 py-2 mb-2 flex items-center gap-2 bg-gray-50 rounded-lg border-b border-gray-200" > - <Icon className={cn(["h-4 w-4 text-gray-600"])} /> + <Icon className="h-4 w-4 text-gray-600" /> <h3 - className={cn([ - "text-xs font-semibold text-gray-700", - "uppercase tracking-wider", - ])} + className="text-xs font-semibold text-gray-700 uppercase tracking-wider" > {title} </h3> - <span className={cn(["text-xs text-gray-500 font-medium"])}> + <span className="text-xs text-gray-500 font-medium"> ({results.length}) </span> </div> - <div className={cn(["space-y-0.5 px-1"])}> + <div className="space-y-0.5 px-1"> {results.map((result) => <SearchResultItem key={result.id} result={result} />)} </div> </div> ); }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (13)
apps/desktop2/.cursor/rules/style.mdc(1 hunks)apps/desktop2/package.json(1 hunks)apps/desktop2/src/components/chat/index.tsx(1 hunks)apps/desktop2/src/components/main/body/search.tsx(1 hunks)apps/desktop2/src/components/main/body/sessions/floating-regenerate-button.tsx(0 hunks)apps/desktop2/src/components/main/sidebar/index.tsx(2 hunks)apps/desktop2/src/components/main/sidebar/search/empty.tsx(1 hunks)apps/desktop2/src/components/main/sidebar/search/group.tsx(1 hunks)apps/desktop2/src/components/main/sidebar/search/index.tsx(1 hunks)apps/desktop2/src/components/main/sidebar/search/item.tsx(1 hunks)apps/desktop2/src/components/main/sidebar/timeline.tsx(1 hunks)apps/desktop2/src/contexts/search.tsx(1 hunks)apps/desktop2/src/routes/app/main/_layout.tsx(2 hunks)
💤 Files with no reviewable changes (1)
- apps/desktop2/src/components/main/body/sessions/floating-regenerate-button.tsx
🧰 Additional context used
📓 Path-based instructions (2)
apps/desktop2/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (apps/desktop2/.cursor/rules/style.mdc)
apps/desktop2/**/*.{ts,tsx,js,jsx}: Use the cn utility for conditional Tailwind classNames, importing it as: import { cn } from "@hypr/ui/lib/utils"; avoid using clsx/classnames directly.
When calling cn, always pass an array of class segments (e.g., cn(["base", condition && "modifier"]))
Files:
apps/desktop2/src/components/main/sidebar/search/empty.tsxapps/desktop2/src/components/chat/index.tsxapps/desktop2/src/components/main/sidebar/timeline.tsxapps/desktop2/src/components/main/sidebar/index.tsxapps/desktop2/src/components/main/sidebar/search/item.tsxapps/desktop2/src/components/main/body/search.tsxapps/desktop2/src/components/main/sidebar/search/group.tsxapps/desktop2/src/components/main/sidebar/search/index.tsxapps/desktop2/src/contexts/search.tsxapps/desktop2/src/routes/app/main/_layout.tsx
**/*.{js,ts,tsx,rs}
⚙️ CodeRabbit configuration file
**/*.{js,ts,tsx,rs}: 1. Do not add any error handling. Keep the existing one.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".
Files:
apps/desktop2/src/components/main/sidebar/search/empty.tsxapps/desktop2/src/components/chat/index.tsxapps/desktop2/src/components/main/sidebar/timeline.tsxapps/desktop2/src/components/main/sidebar/index.tsxapps/desktop2/src/components/main/sidebar/search/item.tsxapps/desktop2/src/components/main/body/search.tsxapps/desktop2/src/components/main/sidebar/search/group.tsxapps/desktop2/src/components/main/sidebar/search/index.tsxapps/desktop2/src/contexts/search.tsxapps/desktop2/src/routes/app/main/_layout.tsx
🧠 Learnings (2)
📚 Learning: 2025-10-12T01:18:24.844Z
Learnt from: CR
PR: fastrepl/hyprnote#0
File: apps/desktop2/.cursor/rules/style.mdc:0-0
Timestamp: 2025-10-12T01:18:24.844Z
Learning: Applies to apps/desktop2/**/*.{ts,tsx,js,jsx} : Use the cn utility for conditional Tailwind classNames, importing it as: import { cn } from "hypr/ui/lib/utils"; avoid using clsx/classnames directly.
Applied to files:
apps/desktop2/.cursor/rules/style.mdc
📚 Learning: 2025-10-12T01:18:24.844Z
Learnt from: CR
PR: fastrepl/hyprnote#0
File: apps/desktop2/.cursor/rules/style.mdc:0-0
Timestamp: 2025-10-12T01:18:24.844Z
Learning: Applies to apps/desktop2/**/*.{ts,tsx,js,jsx} : When calling cn, always pass an array of class segments (e.g., cn(["base", condition && "modifier"]))
Applied to files:
apps/desktop2/.cursor/rules/style.mdc
🧬 Code graph analysis (8)
apps/desktop2/src/components/main/sidebar/search/empty.tsx (1)
packages/ui/src/lib/utils.ts (1)
cn(4-6)
apps/desktop2/src/components/main/sidebar/index.tsx (4)
apps/desktop2/src/contexts/search.tsx (1)
useSearch(312-318)apps/desktop2/src/components/main/sidebar/new-note-button.tsx (1)
NewNoteButton(8-34)apps/desktop2/src/components/main/sidebar/search/index.tsx (1)
SearchResults(8-52)apps/desktop2/src/components/main/sidebar/timeline.tsx (1)
TimelineView(15-35)
apps/desktop2/src/components/main/sidebar/search/item.tsx (3)
apps/desktop2/src/contexts/search.tsx (1)
SearchResult(7-14)apps/desktop2/src/store/zustand/tabs.ts (1)
useTabs(31-121)packages/ui/src/lib/utils.ts (1)
cn(4-6)
apps/desktop2/src/components/main/body/search.tsx (2)
apps/desktop2/src/contexts/search.tsx (1)
useSearch(312-318)packages/ui/src/lib/utils.ts (1)
cn(4-6)
apps/desktop2/src/components/main/sidebar/search/group.tsx (3)
apps/desktop2/src/contexts/search.tsx (1)
SearchResult(7-14)packages/ui/src/lib/utils.ts (1)
cn(4-6)apps/desktop2/src/components/main/sidebar/search/item.tsx (1)
SearchResultItem(8-54)
apps/desktop2/src/components/main/sidebar/search/index.tsx (4)
apps/desktop2/src/contexts/search.tsx (1)
useSearch(312-318)apps/desktop2/src/components/main/sidebar/search/empty.tsx (1)
SearchNoResults(3-14)packages/ui/src/lib/utils.ts (1)
cn(4-6)apps/desktop2/src/components/main/sidebar/search/group.tsx (1)
SearchResultGroup(5-47)
apps/desktop2/src/contexts/search.tsx (1)
crates/db-script/src/lib.rs (1)
transcript(10-21)
apps/desktop2/src/routes/app/main/_layout.tsx (1)
apps/desktop2/src/contexts/search.tsx (1)
SearchProvider(192-310)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: ci (windows, windows-latest)
- GitHub Check: ci (macos, macos-14)
🔇 Additional comments (7)
apps/desktop2/.cursor/rules/style.mdc (1)
5-7: LGTM!The updated guidance clarifies when to use
cnand adds helpful structure about splitting by logical grouping while preserving the array requirement.apps/desktop2/src/components/chat/index.tsx (1)
16-16: LGTM!Using
modinstead ofmetaensures cross-platform compatibility (Cmd on macOS, Ctrl on Windows/Linux).apps/desktop2/src/components/main/sidebar/timeline.tsx (1)
19-19: LGTM!The change to
h-fullaligns withSearchResultscomponent styling for consistent height behavior in the sidebar's conditional rendering.apps/desktop2/src/routes/app/main/_layout.tsx (1)
4-5: LGTM!The
SearchProvideris properly integrated into the provider hierarchy, enabling search context for all child components while maintaining the existing layout structure.Also applies to: 17-20
apps/desktop2/src/components/main/sidebar/index.tsx (2)
5-5: LGTM!The search integration is clean and straightforward. Conditional rendering based on
query.trim()appropriately switches between search results and timeline view.Also applies to: 8-8, 13-15
37-44: LGTM!The layout structure correctly accommodates both
SearchResultsandTimelineViewwith proper overflow handling. The addedgap-1improves spacing between sidebar sections.apps/desktop2/package.json (1)
25-25: @orama/orama is up-to-date (v3.1.15) with no known security advisories.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Nitpick comments (1)
apps/desktop2/src/contexts/search/index.tsx (1)
221-226: Rename helper to avoid shadowingtoString.Naming this helper
toStringshadows the global and is flagged by Biome. Rename it (e.g.,toNonEmptyString) and update the callers.Apply this diff:
-function toString(value: unknown): string | null { +function toNonEmptyString(value: unknown): string | null { if (typeof value === "string" && value.length > 0) { return value; } return null; }- folder_id: toString(row.folder_id), - event_id: toString(row.event_id), + folder_id: toNonEmptyString(row.folder_id), + event_id: toNonEmptyString(row.event_id),- org_id: toString(row.org_id), + org_id: toNonEmptyString(row.org_id),Also applies to: 257-260, 289-290
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (8)
apps/desktop2/.cursor/rules/style.mdc(1 hunks)apps/desktop2/package.json(1 hunks)apps/desktop2/src/components/main/body/search.tsx(1 hunks)apps/desktop2/src/components/main/sidebar/search/empty.tsx(1 hunks)apps/desktop2/src/components/main/sidebar/search/group.tsx(1 hunks)apps/desktop2/src/components/main/sidebar/search/index.tsx(1 hunks)apps/desktop2/src/components/main/sidebar/search/item.tsx(1 hunks)apps/desktop2/src/contexts/search/index.tsx(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- apps/desktop2/src/components/main/sidebar/search/index.tsx
- apps/desktop2/package.json
🧰 Additional context used
📓 Path-based instructions (2)
apps/desktop2/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (apps/desktop2/.cursor/rules/style.mdc)
apps/desktop2/**/*.{ts,tsx,js,jsx}: Use the cn utility for conditional Tailwind classNames, importing it as: import { cn } from "@hypr/ui/lib/utils"; avoid using clsx/classnames directly.
When calling cn, always pass an array of class segments (e.g., cn(["base", condition && "modifier"]))
Files:
apps/desktop2/src/components/main/sidebar/search/group.tsxapps/desktop2/src/contexts/search/index.tsxapps/desktop2/src/components/main/sidebar/search/item.tsxapps/desktop2/src/components/main/body/search.tsxapps/desktop2/src/components/main/sidebar/search/empty.tsx
**/*.{js,ts,tsx,rs}
⚙️ CodeRabbit configuration file
**/*.{js,ts,tsx,rs}: 1. Do not add any error handling. Keep the existing one.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".
Files:
apps/desktop2/src/components/main/sidebar/search/group.tsxapps/desktop2/src/contexts/search/index.tsxapps/desktop2/src/components/main/sidebar/search/item.tsxapps/desktop2/src/components/main/body/search.tsxapps/desktop2/src/components/main/sidebar/search/empty.tsx
🧠 Learnings (2)
📚 Learning: 2025-10-12T01:18:24.844Z
Learnt from: CR
PR: fastrepl/hyprnote#0
File: apps/desktop2/.cursor/rules/style.mdc:0-0
Timestamp: 2025-10-12T01:18:24.844Z
Learning: Applies to apps/desktop2/**/*.{ts,tsx,js,jsx} : Use the cn utility for conditional Tailwind classNames, importing it as: import { cn } from "hypr/ui/lib/utils"; avoid using clsx/classnames directly.
Applied to files:
apps/desktop2/.cursor/rules/style.mdc
📚 Learning: 2025-10-12T01:18:24.844Z
Learnt from: CR
PR: fastrepl/hyprnote#0
File: apps/desktop2/.cursor/rules/style.mdc:0-0
Timestamp: 2025-10-12T01:18:24.844Z
Learning: Applies to apps/desktop2/**/*.{ts,tsx,js,jsx} : When calling cn, always pass an array of class segments (e.g., cn(["base", condition && "modifier"]))
Applied to files:
apps/desktop2/.cursor/rules/style.mdc
🧬 Code graph analysis (5)
apps/desktop2/src/components/main/sidebar/search/group.tsx (3)
apps/desktop2/src/contexts/search/index.tsx (2)
SearchGroup(36-45)useSearch(619-625)packages/ui/src/lib/utils.ts (1)
cn(4-6)apps/desktop2/src/components/main/sidebar/search/item.tsx (1)
SearchResultItem(8-69)
apps/desktop2/src/contexts/search/index.tsx (1)
crates/db-script/src/lib.rs (1)
transcript(10-21)
apps/desktop2/src/components/main/sidebar/search/item.tsx (3)
apps/desktop2/src/contexts/search/index.tsx (1)
SearchResult(20-34)apps/desktop2/src/store/zustand/tabs.ts (1)
useTabs(31-121)packages/ui/src/lib/utils.ts (1)
cn(4-6)
apps/desktop2/src/components/main/body/search.tsx (2)
apps/desktop2/src/contexts/search/index.tsx (1)
useSearch(619-625)packages/ui/src/lib/utils.ts (1)
cn(4-6)
apps/desktop2/src/components/main/sidebar/search/empty.tsx (1)
packages/ui/src/lib/utils.ts (1)
cn(4-6)
🪛 ast-grep (0.39.6)
apps/desktop2/src/components/main/sidebar/search/item.tsx
[warning] 48-48: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html
(react-unsafe-html-injection)
[warning] 62-62: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html
(react-unsafe-html-injection)
🪛 Biome (2.1.2)
apps/desktop2/src/contexts/search/index.tsx
[error] 221-221: Do not shadow the global "toString" property.
Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.
(lint/suspicious/noShadowRestrictedNames)
apps/desktop2/src/components/main/sidebar/search/item.tsx
[error] 49-49: Avoid passing content using the dangerouslySetInnerHTML prop.
Setting content using code can expose users to cross-site scripting (XSS) attacks
(lint/security/noDangerouslySetInnerHtml)
[error] 63-63: Avoid passing content using the dangerouslySetInnerHTML prop.
Setting content using code can expose users to cross-site scripting (XSS) attacks
(lint/security/noDangerouslySetInnerHtml)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: ci (windows, windows-latest)
- GitHub Check: ci (macos, macos-14)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
apps/desktop2/src/contexts/search/index.tsx (1)
466-486: Critical issue already flagged: Await the create() call.This issue was previously identified in past review comments. The
create()function returns aPromise<Orama>, but it's not awaited here. This meansdb(and subsequentlyoramaInstance.current) will be a Promise object, causinginsert()andsearch()calls to fail when they attempt to access Orama internals.The
createIndexcallback should be async and await the create call:- const createIndex = useCallback(async () => { + const createIndex = useCallback(async () => { if (!persistedStore || isIndexing) { return; } setIsIndexing(true); try { - const db = create({ + const db = await create({ schema: {
🧹 Nitpick comments (2)
apps/desktop2/src/components/main/sidebar/search/group.tsx (1)
83-83: Use LOAD_MORE_STEP constant in button text.The button displays "Load 5 more" as hardcoded text while the onClick handler increments by
LOAD_MORE_STEP. IfLOAD_MORE_STEPchanges, the text will be stale.Apply this diff:
- <span>Load 5 more</span> + <span>Load {LOAD_MORE_STEP} more</span>apps/desktop2/src/contexts/search/index.tsx (1)
216-221: RenametoStringto avoid shadowing the global property.The function name
toStringshadows the globaltoStringproperty, which can cause confusion about variable origin and potential issues with tooling.Apply this diff:
-function toString(value: unknown): string { +function toStringValue(value: unknown): string { if (typeof value === "string" && value.length > 0) { return value; } return ""; }Then update all call sites at lines 252, 253, 284, and 308:
- folder_id: toString(row.folder_id), - event_id: toString(row.event_id), + folder_id: toStringValue(row.folder_id), + event_id: toStringValue(row.event_id),- org_id: toString(row.org_id), + org_id: toStringValue(row.org_id),Based on static analysis hints.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
apps/desktop2/src/components/main/sidebar/search/group.tsx(1 hunks)apps/desktop2/src/contexts/search/index.tsx(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
apps/desktop2/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (apps/desktop2/.cursor/rules/style.mdc)
apps/desktop2/**/*.{ts,tsx,js,jsx}: Use the cn utility for conditional Tailwind classNames, importing it as: import { cn } from "@hypr/ui/lib/utils"; avoid using clsx/classnames directly.
When calling cn, always pass an array of class segments (e.g., cn(["base", condition && "modifier"]))
Files:
apps/desktop2/src/components/main/sidebar/search/group.tsxapps/desktop2/src/contexts/search/index.tsx
**/*.{js,ts,tsx,rs}
⚙️ CodeRabbit configuration file
**/*.{js,ts,tsx,rs}: 1. Do not add any error handling. Keep the existing one.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".
Files:
apps/desktop2/src/components/main/sidebar/search/group.tsxapps/desktop2/src/contexts/search/index.tsx
🧬 Code graph analysis (2)
apps/desktop2/src/components/main/sidebar/search/group.tsx (3)
apps/desktop2/src/contexts/search/index.tsx (1)
SearchGroup(36-43)packages/ui/src/lib/utils.ts (1)
cn(4-6)apps/desktop2/src/components/main/sidebar/search/item.tsx (1)
SearchResultItem(8-69)
apps/desktop2/src/contexts/search/index.tsx (1)
crates/db-script/src/lib.rs (1)
transcript(10-21)
🪛 Biome (2.1.2)
apps/desktop2/src/contexts/search/index.tsx
[error] 216-216: Do not shadow the global "toString" property.
Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.
(lint/suspicious/noShadowRestrictedNames)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: ci (windows, windows-latest)
- GitHub Check: ci (macos, macos-14)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (2)
apps/desktop2/package.json(2 hunks)apps/desktop2/src/components/main/sidebar/search/item.tsx(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- apps/desktop2/package.json
🧰 Additional context used
📓 Path-based instructions (2)
apps/desktop2/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (apps/desktop2/.cursor/rules/style.mdc)
apps/desktop2/**/*.{ts,tsx,js,jsx}: Use the cn utility for conditional Tailwind classNames, importing it as: import { cn } from "@hypr/ui/lib/utils"; avoid using clsx/classnames directly.
When calling cn, always pass an array of class segments (e.g., cn(["base", condition && "modifier"]))
Files:
apps/desktop2/src/components/main/sidebar/search/item.tsx
**/*.{js,ts,tsx,rs}
⚙️ CodeRabbit configuration file
**/*.{js,ts,tsx,rs}: 1. Do not add any error handling. Keep the existing one.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".
Files:
apps/desktop2/src/components/main/sidebar/search/item.tsx
🧬 Code graph analysis (1)
apps/desktop2/src/components/main/sidebar/search/item.tsx (3)
apps/desktop2/src/contexts/search/index.tsx (1)
SearchResult(20-34)apps/desktop2/src/store/zustand/tabs.ts (1)
useTabs(31-121)packages/ui/src/lib/utils.ts (1)
cn(4-6)
🪛 ast-grep (0.39.6)
apps/desktop2/src/components/main/sidebar/search/item.tsx
[warning] 59-59: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html
(react-unsafe-html-injection)
[warning] 73-73: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html
(react-unsafe-html-injection)
🪛 Biome (2.1.2)
apps/desktop2/src/components/main/sidebar/search/item.tsx
[error] 60-60: Avoid passing content using the dangerouslySetInnerHTML prop.
Setting content using code can expose users to cross-site scripting (XSS) attacks
(lint/security/noDangerouslySetInnerHtml)
[error] 74-74: Avoid passing content using the dangerouslySetInnerHTML prop.
Setting content using code can expose users to cross-site scripting (XSS) attacks
(lint/security/noDangerouslySetInnerHtml)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: ci (windows, windows-latest)
- GitHub Check: ci (macos, macos-14)
🔇 Additional comments (1)
apps/desktop2/src/components/main/sidebar/search/item.tsx (1)
9-80: XSS mitigation implemented—good work!The component correctly sanitizes
result.titleHighlightedandresult.contentHighlightedbefore rendering withdangerouslySetInnerHTML, addressing the XSS concerns from previous reviews. The use ofuseMemoto cache sanitized values is appropriate, and the overall component structure (event handling, icon selection, confidence display) is clean and follows React best practices.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
There was a problem hiding this 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 (1)
apps/desktop2/src/components/main/sidebar/search/item.tsx (1)
29-31: Consider truncating text content instead of raw HTML.Slicing the HTML string at position 200 before sanitization can break tags mid-stream (e.g., cutting
</mark>to</mar). While DOMPurify safely cleans up broken tags, the visual result may truncate highlights unexpectedly or include fewer than 200 characters of visible text due to HTML overhead.A more display-friendly approach:
const sanitizedContent = useMemo( - () => DOMPurify.sanitize(result.contentHighlighted.slice(0, 200), { ALLOWED_TAGS: ['mark'], ALLOWED_ATTR: [] }), + () => { + const full = DOMPurify.sanitize(result.contentHighlighted, { ALLOWED_TAGS: ['mark'], ALLOWED_ATTR: [] }); + const temp = document.createElement('div'); + temp.innerHTML = full; + const text = temp.textContent || ''; + if (text.length <= 200) return full; + // Fallback: slice and re-sanitize + return DOMPurify.sanitize(result.contentHighlighted.slice(0, 200), { ALLOWED_TAGS: ['mark'], ALLOWED_ATTR: [] }); + }, [result.contentHighlighted], );Alternatively, use CSS
text-overflow: ellipsiswith a fixed height container instead of pre-truncating.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/desktop2/src/components/main/sidebar/search/item.tsx(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
apps/desktop2/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (apps/desktop2/.cursor/rules/style.mdc)
apps/desktop2/**/*.{ts,tsx,js,jsx}: Use the cn utility for conditional Tailwind classNames, importing it as: import { cn } from "@hypr/ui/lib/utils"; avoid using clsx/classnames directly.
When calling cn, always pass an array of class segments (e.g., cn(["base", condition && "modifier"]))
Files:
apps/desktop2/src/components/main/sidebar/search/item.tsx
**/*.{js,ts,tsx,rs}
⚙️ CodeRabbit configuration file
**/*.{js,ts,tsx,rs}: 1. Do not add any error handling. Keep the existing one.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".
Files:
apps/desktop2/src/components/main/sidebar/search/item.tsx
🧬 Code graph analysis (1)
apps/desktop2/src/components/main/sidebar/search/item.tsx (3)
apps/desktop2/src/contexts/search/index.tsx (1)
SearchResult(20-34)apps/desktop2/src/store/zustand/tabs.ts (1)
useTabs(31-121)packages/ui/src/lib/utils.ts (1)
cn(4-6)
🪛 ast-grep (0.39.6)
apps/desktop2/src/components/main/sidebar/search/item.tsx
[warning] 59-59: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html
(react-unsafe-html-injection)
[warning] 73-73: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html
(react-unsafe-html-injection)
🪛 Biome (2.1.2)
apps/desktop2/src/components/main/sidebar/search/item.tsx
[error] 60-60: Avoid passing content using the dangerouslySetInnerHTML prop.
Setting content using code can expose users to cross-site scripting (XSS) attacks
(lint/security/noDangerouslySetInnerHtml)
[error] 74-74: Avoid passing content using the dangerouslySetInnerHTML prop.
Setting content using code can expose users to cross-site scripting (XSS) attacks
(lint/security/noDangerouslySetInnerHtml)
🪛 GitHub Actions: .github/workflows/fmt.yaml
apps/desktop2/src/components/main/sidebar/search/item.tsx
[error] 1-1: dprint formatting check failed. Found 1 not formatted file. Run '~/.dprint/bin/dprint check --config dprint.json' to fix formatting.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: ci (windows, windows-latest)
- GitHub Check: ci (macos, macos-14)
🔇 Additional comments (1)
apps/desktop2/src/components/main/sidebar/search/item.tsx (1)
24-32: LGTM! Previous XSS concerns addressed.The sanitization implementation correctly addresses the previous security concerns by:
- Using DOMPurify with a restrictive allowlist (
ALLOWED_TAGS: ['mark'], ALLOWED_ATTR: [])- Sanitizing both title and content before rendering
- Memoizing sanitized values for performance
The configuration properly restricts allowed HTML to only
<mark>tags, minimizing XSS attack surface while preserving search highlights.Based on learnings
No description provided.