Score: 73/100 · 2 errors · 178 warnings
Copy as prompt
Fix the following React Review diagnostics in my codebase.
## Errors (2)
1. [error] effect-needs-cleanup — src/lib/hooks/use-has-primary-touch.tsx:6
useEffect subscribes via `addEventListener(...)` but never returns a cleanup — leaks the registration on every re-run and on unmount. Return a cleanup function that calls the matching remove/unsubscribe call
2. [error] effect-needs-cleanup — src/components/ui/scroll-area.tsx:75
useEffect subscribes via `addEventListener(...)` but never returns a cleanup — leaks the registration on every re-run and on unmount. Return a cleanup function that calls the matching remove/unsubscribe call
## Warnings (178)
3. [warning] no-react19-deprecated-apis — src/components/spinner.tsx:7
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
4. [warning] use-lazy-motion — src/components/spaces/settings-dialog.tsx:11
Import "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size
5. [warning] no-prevent-default — src/components/spaces/settings-dialog.tsx:116
preventDefault() on <form> onSubmit — form won't work without JavaScript. Consider using a server action for progressive enhancement
6. [warning] react-compiler-destructure-method — src/components/spaces/settings-dialog.tsx:360
Destructure for clarity: `const { push } = useRouter()` then call `push(...)` directly — easier for React Compiler to memoize and clearer about which methods this component depends on
7. [warning] design-no-redundant-padding-axes — src/app/(auth)/sign-in/page.tsx:50
px-4 py-4 → use the shorthand p-4
8. [warning] design-no-three-period-ellipsis — src/components/chat/tools/knowledge-search-tool.tsx:170
Three-period ellipsis ("...") in JSX text — use the actual ellipsis character "…" (or `…`)
9. [warning] no-prevent-default — src/components/spaces/knowledge-table.tsx:172
preventDefault() on <form> onSubmit — form won't work without JavaScript. Consider using a server action for progressive enhancement
10. [warning] design-no-redundant-size-axes — src/components/spaces/knowledge-table.tsx:515
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
11. [warning] design-no-redundant-size-axes — src/components/spaces/knowledge-table.tsx:532
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
12. [warning] design-no-redundant-size-axes — src/components/spaces/knowledge-table.tsx:552
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
13. [warning] design-no-redundant-size-axes — src/components/spaces/knowledge-table.tsx:565
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
14. [warning] design-no-three-period-ellipsis — src/components/chat/tools/finance-search-tool.tsx:154
Three-period ellipsis ("...") in JSX text — use the actual ellipsis character "…" (or `…`)
15. [warning] no-react19-deprecated-apis — src/components/ui/form.tsx:45
useContext is superseded by `use()` on React 19+ — `use()` reads context conditionally inside hooks, branches, and loops; switch to `import { use } from 'react'`
16. [warning] no-react19-deprecated-apis — src/components/ui/form.tsx:46
useContext is superseded by `use()` on React 19+ — `use()` reads context conditionally inside hooks, branches, and loops; switch to `import { use } from 'react'`
17. [warning] no-react19-deprecated-apis — src/components/ui/form.tsx:75
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
18. [warning] no-react19-deprecated-apis — src/components/ui/form.tsx:89
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
19. [warning] no-react19-deprecated-apis — src/components/ui/form.tsx:106
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
20. [warning] no-react19-deprecated-apis — src/components/ui/form.tsx:129
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
21. [warning] no-react19-deprecated-apis — src/components/ui/form.tsx:146
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
22. [warning] use-lazy-motion — src/components/spaces/knowledge-dialog.tsx:5
Import "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size
23. [warning] async-await-in-loop — src/components/spaces/knowledge-dialog.tsx:129
await inside a for…of loop runs the calls sequentially — for independent operations, collect them and use `await Promise.all(items.map(...))` to run them concurrently
24. [warning] no-pure-black-background — src/components/spaces/knowledge-dialog.tsx:249
Pure black background (bg-black) looks harsh — use a near-black tinted toward your brand hue (e.g. bg-gray-950)
25. [warning] design-no-space-on-flex-children — src/components/spaces/knowledge-dialog.tsx:254
space-y-6 on a flex/grid parent — use gap-y-6 instead. Per-sibling margins phantom-gap on conditional render and don't mirror in RTL
26. [warning] design-no-space-on-flex-children — src/components/spaces/knowledge-dialog.tsx:268
space-y-6 on a flex/grid parent — use gap-y-6 instead. Per-sibling margins phantom-gap on conditional render and don't mirror in RTL
27. [warning] use-lazy-motion — src/components/spaces/header.tsx:9
Import "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size
28. [warning] async-parallel — src/workflows/knowledge-process.ts:51
3 sequential await statements that appear independent — use Promise.all() for parallel execution
29. [warning] design-no-three-period-ellipsis — src/components/chat/tools/academic-search-tool.tsx:178
Three-period ellipsis ("...") in JSX text — use the actual ellipsis character "…" (or `…`)
30. [warning] use-lazy-motion — src/components/spaces/cards.tsx:4
Import "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size
31. [warning] rerender-memo-with-default-value — src/components/chat/space-intro.tsx:22
Default prop value [] creates a new array reference every render — extract to a module-level constant
32. [warning] design-no-bold-heading — src/components/chat/space-intro.tsx:35
font-bold on <h1> crushes counter shapes at display sizes — use font-semibold (600) or font-medium (500)
33. [warning] use-lazy-motion — src/components/ui/disclosure.tsx:3
Import "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size
34. [warning] no-react19-deprecated-apis — src/components/ui/disclosure.tsx:12
useContext is superseded by `use()` on React 19+ — `use()` reads context conditionally inside hooks, branches, and loops; switch to `import { use } from 'react'`
35. [warning] no-derived-useState — src/components/ui/disclosure.tsx:38
useState initialized from prop "openProp" — if this value should stay in sync with the prop, derive it during render instead
36. [warning] no-many-boolean-props — src/components/sidebar/chats-list.tsx:45
Component "ChatItem" takes 4 boolean-like props (isActive, isConfirming, isPending…) — consider compound components or explicit variants instead of stacking flags
37. [warning] react-compiler-destructure-method — src/components/sidebar/chats-list.tsx:216
Destructure for clarity: `const { replace } = useRouter()` then call `replace(...)` directly — easier for React Compiler to memoize and clearer about which methods this component depends on
38. [warning] design-no-redundant-padding-axes — src/components/sidebar/chats-list.tsx:320
px-1 py-1 → use the shorthand p-1
39. [warning] design-no-redundant-padding-axes — src/components/sidebar/chats-list.tsx:334
px-1 py-1 → use the shorthand p-1
40. [warning] design-no-redundant-padding-axes — src/components/sidebar/chats-list.tsx:336
px-1 py-1 → use the shorthand p-1
41. [warning] design-no-three-period-ellipsis — src/components/sidebar/chats-list.tsx:338
Three-period ellipsis ("...") in JSX text — use the actual ellipsis character "…" (or `…`)
42. [warning] design-no-three-period-ellipsis — src/components/sidebar/chats-list.tsx:370
Three-period ellipsis ("...") in JSX text — use the actual ellipsis character "…" (or `…`)
43. [warning] use-lazy-motion — src/components/sidebar.tsx:11
Import "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size
44. [warning] use-lazy-motion — src/components/chat/message.tsx:5
Import "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size
45. [warning] no-array-index-as-key — src/components/chat/message.tsx:452
Array index "index" used as key — causes bugs when list is reordered or filtered
46. [warning] no-array-index-as-key — src/components/chat/message.tsx:497
Array index "index" used as key — causes bugs when list is reordered or filtered
47. [warning] no-array-index-as-key — src/components/chat/message.tsx:523
Array index "index" used as key — causes bugs when list is reordered or filtered
48. [warning] no-array-index-as-key — src/components/chat/message.tsx:545
Array index "index" used as key — causes bugs when list is reordered or filtered
49. [warning] no-render-in-render — src/components/chat/message.tsx:601
Inline render function "renderAttachments()" — extract to a separate component for proper reconciliation
50. [warning] use-lazy-motion — src/components/chat/header.tsx:4
Import "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size
51. [warning] use-lazy-motion — src/components/chat/display-chats.tsx:10
Import "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size
52. [warning] design-no-redundant-size-axes — src/components/chat/display-chats.tsx:264
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
53. [warning] use-lazy-motion — src/components/profile.tsx:5
Import "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size
54. [warning] design-no-redundant-size-axes — src/components/profile.tsx:48
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
55. [warning] rerender-state-only-in-handlers — src/components/profile.tsx:222
useState "isHydrated" is updated but never read in the component's return — use useRef so updates don't trigger re-renders
56. [warning] rendering-hydration-no-flicker — src/components/profile.tsx:224
useEffect(setState, []) on mount causes a flash — consider useSyncExternalStore or suppressHydrationWarning
57. [warning] react-compiler-destructure-method — src/components/profile.tsx:235
Destructure for clarity: `const { push } = useRouter()` then call `push(...)` directly — easier for React Compiler to memoize and clearer about which methods this component depends on
58. [warning] react-compiler-destructure-method — src/components/profile.tsx:247
Destructure for clarity: `const { push } = useRouter()` then call `push(...)` directly — easier for React Compiler to memoize and clearer about which methods this component depends on
59. [warning] react-compiler-destructure-method — src/components/profile.tsx:252
Destructure for clarity: `const { push } = useRouter()` then call `push(...)` directly — easier for React Compiler to memoize and clearer about which methods this component depends on
60. [warning] no-react19-deprecated-apis — src/components/chat/code-block.tsx:5
useContext is superseded by `use()` on React 19+ — `use()` reads context conditionally inside hooks, branches, and loops; switch to `import { use } from 'react'`
61. [warning] no-react19-deprecated-apis — src/components/ui/carousel.tsx:36
useContext is superseded by `use()` on React 19+ — `use()` reads context conditionally inside hooks, branches, and loops; switch to `import { use } from 'react'`
62. [warning] no-prop-callback-in-effect — src/components/ui/carousel.tsx:97
useEffect calls prop callback "setApi" with local state in deps — this is the "lift state via callback" anti-pattern; lift state into a shared Provider so both sides read the same source
63. [warning] advanced-event-handler-refs — src/components/ui/carousel.tsx:100
useEffect re-subscribes a "onSelect" listener every time the handler identity changes — store the handler in a ref and have the listener read `handlerRef.current()`, then drop it from the deps
64. [warning] design-no-redundant-padding-axes — src/components/model-selector.tsx:272
px-2 py-2 → use the shorthand p-2
65. [warning] rerender-state-only-in-handlers — src/components/chat.tsx:164
useState "_hasOptimisticallyAdded" is updated but never read in the component's return — use useRef so updates don't trigger re-renders
66. [warning] no-giant-component — src/components/chat.tsx:53
Component "Chat" is 355 lines — consider breaking it into smaller focused components
67. [warning] use-lazy-motion — src/components/mode-selector.tsx:4
Import "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size
68. [warning] no-autofocus — src/components/chat-input.tsx:515
The `autoFocus` attribute is found here, which can cause usability issues for sighted and non-sighted users.
69. [warning] use-lazy-motion — src/components/chat-input.tsx:13
Import "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size
70. [warning] no-giant-component — src/components/chat-input.tsx:106
Component "PureInput" is 513 lines — consider breaking it into smaller focused components
71. [warning] js-batch-dom-css — src/components/chat-input.tsx:147
Multiple sequential element.style assignments — batch with cssText or classList for fewer reflows
72. [warning] no-prop-callback-in-effect — src/components/chat-input.tsx:165
useEffect calls prop callback "setInput" with local state in deps — this is the "lift state via callback" anti-pattern; lift state into a shared Provider so both sides read the same source
73. [warning] no-array-index-as-key — src/components/chat-input.tsx:481
Array index "index" used as key — causes bugs when list is reordered or filtered
74. [warning] rendering-usetransition-loading — src/components/auth/sign-out-button.tsx:17
useState for "isLoading" — if this guards a state transition (not an async fetch), consider useTransition instead
75. [warning] react-compiler-destructure-method — src/components/auth/sign-out-button.tsx:25
Destructure for clarity: `const { push } = useRouter()` then call `push(...)` directly — easier for React Compiler to memoize and clearer about which methods this component depends on
76. [warning] use-lazy-motion — src/components/ui/border-trail.tsx:2
Import "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size
77. [warning] no-permanent-will-change — src/components/ui/border-trail.tsx:40
Permanent will-change wastes GPU memory — apply only during active animation and remove after
78. [warning] rendering-usetransition-loading — src/components/auth/sign-in-button.tsx:21
useState for "isLoading" — if this guards a state transition (not an async fetch), consider useTransition instead
79. [warning] no-react19-deprecated-apis — src/components/ui/avatar.tsx:8
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
80. [warning] no-render-in-render — src/components/mcp-server-config.tsx:236
Inline render function "renderStatusBadge()" — extract to a separate component for proper reconciliation
81. [warning] design-no-space-on-flex-children — src/components/mcp-server-config.tsx:239
space-x-2 on a flex/grid parent — use gap-x-2 instead. Per-sibling margins phantom-gap on conditional render and don't mirror in RTL
82. [warning] no-prevent-default — src/components/mcp-server-config.tsx:429
preventDefault() on <form> onSubmit — form won't work without JavaScript. Consider using a server action for progressive enhancement
83. [warning] design-no-space-on-flex-children — src/components/display-memories.tsx:125
space-x-2 on a flex/grid parent — use gap-x-2 instead. Per-sibling margins phantom-gap on conditional render and don't mirror in RTL
84. [warning] design-no-redundant-size-axes — src/components/display-memories.tsx:127
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
85. [warning] design-no-space-on-flex-children — src/components/display-memories.tsx:280
space-x-2 on a flex/grid parent — use gap-x-2 instead. Per-sibling margins phantom-gap on conditional render and don't mirror in RTL
86. [warning] use-lazy-motion — src/components/ui/accordion.tsx:2
Import "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size
87. [warning] no-react19-deprecated-apis — src/components/ui/accordion.tsx:13
useContext is superseded by `use()` on React 19+ — `use()` reads context conditionally inside hooks, branches, and loops; switch to `import { use } from 'react'`
88. [warning] no-react19-deprecated-apis — src/components/ai-elements/inline-citation.tsx:8
useContext is superseded by `use()` on React 19+ — `use()` reads context conditionally inside hooks, branches, and loops; switch to `import { use } from 'react'`
89. [warning] no-cascading-set-state — src/components/ai-elements/inline-citation.tsx:180
3 setState calls in a single useEffect — consider using useReducer or deriving state
90. [warning] no-generic-handler-names — src/components/ai-elements/inline-citation.tsx:230
Non-descriptive handler name "handleClick" — name should describe what it does, not when it runs
91. [warning] no-generic-handler-names — src/components/ai-elements/inline-citation.tsx:257
Non-descriptive handler name "handleClick" — name should describe what it does, not when it runs
92. [warning] no-react19-deprecated-apis — src/components/data-stream-provider.tsx:5
useContext is superseded by `use()` on React 19+ — `use()` reads context conditionally inside hooks, branches, and loops; switch to `import { use } from 'react'`
93. [warning] js-combine-iterations — src/components/ai-elements/conversation.tsx:131
.filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of
94. [warning] no-react19-deprecated-apis — src/components/copy-button.tsx:6
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
95. [warning] no-react19-deprecated-apis — src/components/ai-elements/attachments.tsx:6
useContext is superseded by `use()` on React 19+ — `use()` reads context conditionally inside hooks, branches, and loops; switch to `import { use } from 'react'`
96. [warning] js-combine-iterations — src/components/chat/tools/web-search-tool.tsx:61
.filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of
97. [warning] js-combine-iterations — src/components/chat/tools/web-search-tool.tsx:61
.flatMap().filter() iterates the array twice — combine into a single loop with .reduce() or for...of
98. [warning] design-no-three-period-ellipsis — src/components/chat/tools/web-search-tool.tsx:241
Three-period ellipsis ("...") in JSX text — use the actual ellipsis character "…" (or `…`)
99. [warning] design-no-three-period-ellipsis — src/components/chat/tools/save-to-memories.tsx:35
Three-period ellipsis ("...") in JSX text — use the actual ellipsis character "…" (or `…`)
100. [warning] nextjs-missing-metadata — src/app/(main)/(chat)/c/page.tsx:1
Page without metadata or generateMetadata export — hurts SEO
101. [warning] js-combine-iterations — src/app/api/chat/_lib/tools.ts:53
.filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of
102. [warning] no-react19-deprecated-apis — src/lib/mobile-header-context.tsx:8
useContext is superseded by `use()` on React 19+ — `use()` reads context conditionally inside hooks, branches, and loops; switch to `import { use } from 'react'`
103. [warning] no-derived-state-effect — src/lib/mobile-header-context.tsx:51
Derived state in useEffect — compute during render instead
104. [warning] nextjs-missing-metadata — src/app/(main)/(chat)/c/[id]/page.tsx:1
Page without metadata or generateMetadata export — hurts SEO
105. [warning] server-sequential-independent-await — src/app/(main)/(chat)/c/[id]/page.tsx:15
Sequential `await` without a data dependency on the previous result — wrap the independent calls in `Promise.all([...])` so they race instead of waterfalling
106. [warning] server-sequential-independent-await — src/app/(main)/(chat)/c/[id]/page.tsx:20
Sequential `await` without a data dependency on the previous result — wrap the independent calls in `Promise.all([...])` so they race instead of waterfalling
107. [warning] async-parallel — src/app/(main)/(chat)/c/[id]/page.tsx:13
4 sequential await statements that appear independent — use Promise.all() for parallel execution
108. [warning] js-combine-iterations — src/lib/ai/utils.ts:44
.filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of
109. [warning] nextjs-missing-metadata — src/app/(main)/page.tsx:1
Page without metadata or generateMetadata export — hurts SEO
110. [warning] async-parallel — src/app/api/chat/_lib/resumable-stream.ts:28
3 sequential await statements that appear independent — use Promise.all() for parallel execution
111. [warning] js-combine-iterations — src/app/api/chat/_lib/request-logger.ts:42
.filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of
112. [warning] async-await-in-loop — src/lib/ai/tools/web-search.ts:69
Async callback in .map — sequential awaits inside the callback waterfall. Use `await Promise.all(items.map(async (item) => {...}))` to run them concurrently
113. [warning] async-await-in-loop — src/lib/mcp/client.ts:135
await inside a for…of loop runs the calls sequentially — for independent operations, collect them and use `await Promise.all(items.map(...))` to run them concurrently
114. [warning] async-await-in-loop — src/lib/mcp/client.ts:178
await inside a for…of loop runs the calls sequentially — for independent operations, collect them and use `await Promise.all(items.map(...))` to run them concurrently
115. [warning] async-await-in-loop — src/lib/mcp/client.ts:196
await inside a for…of loop runs the calls sequentially — for independent operations, collect them and use `await Promise.all(items.map(...))` to run them concurrently
116. [warning] async-await-in-loop — src/lib/mcp/client.ts:225
await inside a for…of loop runs the calls sequentially — for independent operations, collect them and use `await Promise.all(items.map(...))` to run them concurrently
117. [warning] nextjs-missing-metadata — src/app/(main)/(spaces)/s/page.tsx:1
Page without metadata or generateMetadata export — hurts SEO
118. [warning] server-sequential-independent-await — src/app/(main)/(spaces)/s/page.tsx:9
Sequential `await` without a data dependency on the previous result — wrap the independent calls in `Promise.all([...])` so they race instead of waterfalling
119. [warning] async-await-in-loop — src/lib/ai/tools/save-to-memories.ts:53
await inside a for-loop runs the calls sequentially — for independent operations, collect them and use `await Promise.all(items.map(...))` to run them concurrently
120. [warning] nextjs-missing-metadata — src/app/(main)/(spaces)/s/[id]/page.tsx:1
Page without metadata or generateMetadata export — hurts SEO
121. [warning] server-sequential-independent-await — src/app/(main)/(spaces)/s/[id]/page.tsx:13
Sequential `await` without a data dependency on the previous result — wrap the independent calls in `Promise.all([...])` so they race instead of waterfalling
122. [warning] server-sequential-independent-await — src/app/(main)/(spaces)/s/[id]/page.tsx:19
Sequential `await` without a data dependency on the previous result — wrap the independent calls in `Promise.all([...])` so they race instead of waterfalling
123. [warning] async-await-in-loop — src/lib/ai/embedding.ts:68
await inside a for-loop runs the calls sequentially — for independent operations, collect them and use `await Promise.all(items.map(...))` to run them concurrently
124. [warning] async-await-in-loop — src/lib/ai/tools/knowledge-search.ts:57
Async callback in .map — sequential awaits inside the callback waterfall. Use `await Promise.all(items.map(async (item) => {...}))` to run them concurrently
125. [warning] async-await-in-loop — src/lib/ai/tools/finance-search.ts:41
Async callback in .map — sequential awaits inside the callback waterfall. Use `await Promise.all(items.map(async (item) => {...}))` to run them concurrently
126. [warning] no-react19-deprecated-apis — src/components/ui/tooltip.tsx:15
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
127. [warning] client-passive-event-listeners — src/lib/hooks/use-click-outside.ts:17
"touchstart" listener without { passive: true } — blocks scrolling performance. Only add { passive: true } if the handler does NOT call event.preventDefault() (passive listeners silently ignore preventDefault())
128. [warning] no-react19-deprecated-apis — src/components/ui/toggle-group.tsx:51
useContext is superseded by `use()` on React 19+ — `use()` reads context conditionally inside hooks, branches, and loops; switch to `import { use } from 'react'`
129. [warning] use-lazy-motion — src/components/ui/theme-toggle.tsx:6
Import "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size
130. [warning] rendering-hydration-no-flicker — src/components/ui/theme-toggle.tsx:32
useEffect(setState, []) on mount causes a flash — consider useSyncExternalStore or suppressHydrationWarning
131. [warning] js-combine-iterations — src/lib/ai/mistral-ocr.ts:36
.map().filter() iterates the array twice — combine into a single loop with .reduce() or for...of
132. [warning] use-lazy-motion — src/components/ui/text-loop.tsx:2
Import "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size
133. [warning] no-permanent-will-change — src/components/ui/text-loop.tsx:68
Permanent will-change wastes GPU memory — apply only during active animation and remove after
134. [warning] use-lazy-motion — src/components/ui/text-shimmer.tsx:2
Import "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size
135. [warning] use-lazy-motion — src/components/ui/text-effect.tsx:3
Import "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size
136. [warning] no-array-index-as-key — src/components/ui/text-effect.tsx:315
Array index "index" used as key — causes bugs when list is reordered or filtered
137. [warning] no-react19-deprecated-apis — src/components/ui/sidebar.tsx:48
useContext is superseded by `use()` on React 19+ — `use()` reads context conditionally inside hooks, branches, and loops; switch to `import { use } from 'react'`
138. [warning] no-react19-deprecated-apis — src/components/ui/sidebar.tsx:56
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
139. [warning] no-react19-deprecated-apis — src/components/ui/sidebar.tsx:166
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
140. [warning] no-react19-deprecated-apis — src/components/ui/sidebar.tsx:279
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
141. [warning] no-react19-deprecated-apis — src/components/ui/sidebar.tsx:305
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
142. [warning] no-react19-deprecated-apis — src/components/ui/sidebar.tsx:334
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
143. [warning] no-react19-deprecated-apis — src/components/ui/sidebar.tsx:352
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
144. [warning] no-react19-deprecated-apis — src/components/ui/sidebar.tsx:370
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
145. [warning] no-react19-deprecated-apis — src/components/ui/sidebar.tsx:385
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
146. [warning] no-react19-deprecated-apis — src/components/ui/sidebar.tsx:400
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
147. [warning] no-react19-deprecated-apis — src/components/ui/sidebar.tsx:418
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
148. [warning] no-react19-deprecated-apis — src/components/ui/sidebar.tsx:436
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
149. [warning] no-react19-deprecated-apis — src/components/ui/sidebar.tsx:454
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
150. [warning] no-react19-deprecated-apis — src/components/ui/sidebar.tsx:475
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
151. [warning] no-react19-deprecated-apis — src/components/ui/sidebar.tsx:498
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
152. [warning] no-react19-deprecated-apis — src/components/ui/sidebar.tsx:511
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
153. [warning] no-react19-deprecated-apis — src/components/ui/sidebar.tsx:524
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
154. [warning] no-react19-deprecated-apis — src/components/ui/sidebar.tsx:560
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
155. [warning] no-react19-deprecated-apis — src/components/ui/sidebar.tsx:622
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
156. [warning] no-react19-deprecated-apis — src/components/ui/sidebar.tsx:653
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
157. [warning] no-react19-deprecated-apis — src/components/ui/sidebar.tsx:674
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
158. [warning] no-react19-deprecated-apis — src/components/ui/sidebar.tsx:715
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
159. [warning] no-react19-deprecated-apis — src/components/ui/sidebar.tsx:732
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
160. [warning] no-react19-deprecated-apis — src/components/ui/sidebar.tsx:738
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
161. [warning] async-parallel — src/lib/db/queries.ts:181
3 sequential await statements that appear independent — use Promise.all() for parallel execution
162. [warning] no-react19-deprecated-apis — src/components/ui/popover.tsx:15
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
163. [warning] no-react19-deprecated-apis — src/components/ui/sheet.tsx:19
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
164. [warning] no-react19-deprecated-apis — src/components/ui/sheet.tsx:55
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
165. [warning] design-no-redundant-size-axes — src/components/ui/sheet.tsx:67
w-4 h-4 → use the shorthand size-4 (Tailwind v3.4+)
166. [warning] no-react19-deprecated-apis — src/components/ui/sheet.tsx:104
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
167. [warning] no-react19-deprecated-apis — src/components/ui/sheet.tsx:116
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
168. [warning] use-lazy-motion — src/components/ui/morphing-dialog.tsx:7
Import "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size
169. [warning] no-react19-deprecated-apis — src/components/ui/morphing-dialog.tsx:16
useContext is superseded by `use()` on React 19+ — `use()` reads context conditionally inside hooks, branches, and loops; switch to `import { use } from 'react'`
170. [warning] no-generic-handler-names — src/components/ui/morphing-dialog.tsx:131
Non-descriptive handler name "handleClick" — name should describe what it does, not when it runs
171. [warning] no-effect-event-handler — src/components/ui/morphing-dialog.tsx:196
useEffect simulating an event handler — move logic to an actual event handler instead
172. [warning] no-permanent-will-change — src/components/ui/morphing-dialog.tsx:234
Permanent will-change wastes GPU memory — apply only during active animation and remove after
173. [warning] no-permanent-will-change — src/components/ui/morphing-dialog.tsx:301
Permanent will-change wastes GPU memory — apply only during active animation and remove after
174. [warning] no-permanent-will-change — src/components/ui/morphing-dialog.tsx:334
Permanent will-change wastes GPU memory — apply only during active animation and remove after
175. [warning] no-permanent-will-change — src/components/ui/morphing-dialog.tsx:388
Permanent will-change wastes GPU memory — apply only during active animation and remove after
176. [warning] no-react19-deprecated-apis — src/components/ui/scroll-area.tsx:18
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
177. [warning] advanced-event-handler-refs — src/components/ui/scroll-area.tsx:75
useEffect re-subscribes a "checkScrollability" listener every time the handler identity changes — store the handler in a ref and have the listener read `handlerRef.current()`, then drop it from the deps
178. [warning] client-passive-event-listeners — src/components/ui/scroll-area.tsx:91
"scroll" listener without { passive: true } — blocks scrolling performance. Only add { passive: true } if the handler does NOT call event.preventDefault() (passive listeners silently ignore preventDefault())
179. [warning] no-react19-deprecated-apis — src/components/ui/scroll-area.tsx:170
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
180. [warning] no-react19-deprecated-apis — src/components/ui/scroll-area.tsx:176
useContext is superseded by `use()` on React 19+ — `use()` reads context conditionally inside hooks, branches, and loops; switch to `import { use } from 'react'`
❌ Errors (2)
effect-needs-cleanup
useEffect subscribes via addEventListener(...) but never returns a cleanup — leaks the registration on every re-run and on unmount. Return a cleanup function that calls the matching remove/unsubscribe call
Return a cleanup function that releases the subscription / timer: return () => target.removeEventListener(name, handler) for listeners, return () => clearInterval(id) / clearTimeout(id) for timers, or return unsubscribe if the subscribe call already returned one
src/lib/hooks/use-has-primary-touch.tsx:6
src/components/ui/scroll-area.tsx:75
⚠️ Warnings (178)
no-react19-deprecated-apis
forwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
Pass ref as a regular prop on function components — forwardRef is no longer needed in React 19+. Replace useContext(X) with use(X) for branch-aware context reads. Only enabled on projects detected as React 19+.
src/components/spinner.tsx:7
src/components/ui/form.tsx:45
src/components/ui/form.tsx:46
src/components/ui/form.tsx:75
src/components/ui/form.tsx:89
src/components/ui/form.tsx:106
src/components/ui/form.tsx:129
src/components/ui/form.tsx:146
src/components/ui/disclosure.tsx:12
src/components/chat/code-block.tsx:5
src/components/ui/carousel.tsx:36
src/components/ui/avatar.tsx:8
src/components/ui/accordion.tsx:13
src/components/ai-elements/inline-citation.tsx:8
src/components/data-stream-provider.tsx:5
src/components/copy-button.tsx:6
src/components/ai-elements/attachments.tsx:6
src/lib/mobile-header-context.tsx:8
src/components/ui/tooltip.tsx:15
src/components/ui/toggle-group.tsx:51
src/components/ui/sidebar.tsx:48
src/components/ui/sidebar.tsx:56
src/components/ui/sidebar.tsx:166
src/components/ui/sidebar.tsx:279
src/components/ui/sidebar.tsx:305
src/components/ui/sidebar.tsx:334
src/components/ui/sidebar.tsx:352
src/components/ui/sidebar.tsx:370
src/components/ui/sidebar.tsx:385
src/components/ui/sidebar.tsx:400
src/components/ui/sidebar.tsx:418
src/components/ui/sidebar.tsx:436
src/components/ui/sidebar.tsx:454
src/components/ui/sidebar.tsx:475
src/components/ui/sidebar.tsx:498
src/components/ui/sidebar.tsx:511
src/components/ui/sidebar.tsx:524
src/components/ui/sidebar.tsx:560
src/components/ui/sidebar.tsx:622
src/components/ui/sidebar.tsx:653
src/components/ui/sidebar.tsx:674
src/components/ui/sidebar.tsx:715
src/components/ui/sidebar.tsx:732
src/components/ui/sidebar.tsx:738
src/components/ui/popover.tsx:15
src/components/ui/sheet.tsx:19
src/components/ui/sheet.tsx:55
src/components/ui/sheet.tsx:104
src/components/ui/sheet.tsx:116
src/components/ui/morphing-dialog.tsx:16
src/components/ui/scroll-area.tsx:18
src/components/ui/scroll-area.tsx:170
src/components/ui/scroll-area.tsx:176
use-lazy-motion
Import "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size
Use import { LazyMotion, m } from "framer-motion" with domAnimation features — saves ~30kb
src/components/spaces/settings-dialog.tsx:11
src/components/spaces/knowledge-dialog.tsx:5
src/components/spaces/header.tsx:9
src/components/spaces/cards.tsx:4
src/components/ui/disclosure.tsx:3
src/components/sidebar.tsx:11
src/components/chat/message.tsx:5
src/components/chat/header.tsx:4
src/components/chat/display-chats.tsx:10
src/components/profile.tsx:5
src/components/mode-selector.tsx:4
src/components/chat-input.tsx:13
src/components/ui/border-trail.tsx:2
src/components/ui/accordion.tsx:2
src/components/ui/theme-toggle.tsx:6
src/components/ui/text-loop.tsx:2
src/components/ui/text-shimmer.tsx:2
src/components/ui/text-effect.tsx:3
src/components/ui/morphing-dialog.tsx:7
async-await-in-loop
await inside a for…of loop runs the calls sequentially — for independent operations, collect them and use await Promise.all(items.map(...)) to run them concurrently
Collect the items and use await Promise.all(items.map(...)) to run independent operations concurrently
src/components/spaces/knowledge-dialog.tsx:129
src/lib/ai/tools/web-search.ts:69
src/lib/mcp/client.ts:135
src/lib/mcp/client.ts:178
src/lib/mcp/client.ts:196
src/lib/mcp/client.ts:225
src/lib/ai/tools/save-to-memories.ts:53
src/lib/ai/embedding.ts:68
src/lib/ai/tools/knowledge-search.ts:57
src/lib/ai/tools/finance-search.ts:41
design-no-redundant-size-axes
w-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
Collapse w-N h-N to size-N (Tailwind v3.4+) when both axes match
src/components/spaces/knowledge-table.tsx:515
src/components/spaces/knowledge-table.tsx:532
src/components/spaces/knowledge-table.tsx:552
src/components/spaces/knowledge-table.tsx:565
src/components/chat/display-chats.tsx:264
src/components/profile.tsx:48
src/components/display-memories.tsx:127
src/components/ui/sheet.tsx:67
design-no-three-period-ellipsis
Three-period ellipsis ("...") in JSX text — use the actual ellipsis character "…" (or …)
Use the typographic ellipsis "…" (or …) instead of three periods — pairs with action-with-followup labels ("Rename…", "Loading…")
src/components/chat/tools/knowledge-search-tool.tsx:170
src/components/chat/tools/finance-search-tool.tsx:154
src/components/chat/tools/academic-search-tool.tsx:178
src/components/sidebar/chats-list.tsx:338
src/components/sidebar/chats-list.tsx:370
src/components/chat/tools/web-search-tool.tsx:241
src/components/chat/tools/save-to-memories.tsx:35
js-combine-iterations
.filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of
Combine .map().filter() (or similar chains) into a single pass with .reduce() or a for...of loop to avoid iterating the array twice
src/components/ai-elements/conversation.tsx:131
src/components/chat/tools/web-search-tool.tsx:61
src/components/chat/tools/web-search-tool.tsx:61
src/app/api/chat/_lib/tools.ts:53
src/lib/ai/utils.ts:44
src/app/api/chat/_lib/request-logger.ts:42
src/lib/ai/mistral-ocr.ts:36
react-compiler-destructure-method
Destructure for clarity: const { push } = useRouter() then call push(...) directly — easier for React Compiler to memoize and clearer about which methods this component depends on
Destructure the method up front: const { push } = useRouter() then call push(...) directly — clearer dependency graph and easier for React Compiler to memoize
src/components/spaces/settings-dialog.tsx:360
src/components/sidebar/chats-list.tsx:216
src/components/profile.tsx:235
src/components/profile.tsx:247
src/components/profile.tsx:252
src/components/auth/sign-out-button.tsx:25
no-array-index-as-key
Array index "index" used as key — causes bugs when list is reordered or filtered
Use a stable unique identifier: key={item.id} or key={item.slug} — index keys break on reorder/filter
src/components/chat/message.tsx:452
src/components/chat/message.tsx:497
src/components/chat/message.tsx:523
src/components/chat/message.tsx:545
src/components/chat-input.tsx:481
src/components/ui/text-effect.tsx:315
no-permanent-will-change
Permanent will-change wastes GPU memory — apply only during active animation and remove after
Add will-change on animation start (onMouseEnter) and remove on end (onAnimationEnd). Permanent promotion wastes GPU memory and can degrade performance
src/components/ui/border-trail.tsx:40
src/components/ui/text-loop.tsx:68
src/components/ui/morphing-dialog.tsx:234
src/components/ui/morphing-dialog.tsx:301
src/components/ui/morphing-dialog.tsx:334
src/components/ui/morphing-dialog.tsx:388
design-no-redundant-padding-axes
px-4 py-4 → use the shorthand p-4
Collapse px-N py-N to p-N when both axes match. Keep them split only when one axis varies at a breakpoint (py-2 md:py-3)
src/app/(auth)/sign-in/page.tsx:50
src/components/sidebar/chats-list.tsx:320
src/components/sidebar/chats-list.tsx:334
src/components/sidebar/chats-list.tsx:336
src/components/model-selector.tsx:272
design-no-space-on-flex-children
space-y-6 on a flex/grid parent — use gap-y-6 instead. Per-sibling margins phantom-gap on conditional render and don't mirror in RTL
Use gap-* on the flex/grid parent. space-x-* / space-y-* produce phantom gaps when a sibling is conditionally rendered, lose vertical spacing on wrapped lines, and don't mirror in RTL
src/components/spaces/knowledge-dialog.tsx:254
src/components/spaces/knowledge-dialog.tsx:268
src/components/mcp-server-config.tsx:239
src/components/display-memories.tsx:125
src/components/display-memories.tsx:280
nextjs-missing-metadata
Page without metadata or generateMetadata export — hurts SEO
Add export const metadata = { title: '...', description: '...' } or export async function generateMetadata()
src/app/(main)/(chat)/c/page.tsx:1
src/app/(main)/(chat)/c/[id]/page.tsx:1
src/app/(main)/page.tsx:1
src/app/(main)/(spaces)/s/page.tsx:1
src/app/(main)/(spaces)/s/[id]/page.tsx:1
server-sequential-independent-await
Sequential await without a data dependency on the previous result — wrap the independent calls in Promise.all([...]) so they race instead of waterfalling
Wrap independent awaits in Promise.all([...]) so they race instead of waterfalling — second call doesn't depend on the first
src/app/(main)/(chat)/c/[id]/page.tsx:15
src/app/(main)/(chat)/c/[id]/page.tsx:20
src/app/(main)/(spaces)/s/page.tsx:9
src/app/(main)/(spaces)/s/[id]/page.tsx:13
src/app/(main)/(spaces)/s/[id]/page.tsx:19
async-parallel
3 sequential await statements that appear independent — use Promise.all() for parallel execution
Use `const [a, b] = await Promise.all([fetchA(), fet
Issue body truncated. See the full report at react.review/dashboard.
Score: 73/100 · 2 errors · 178 warnings
Copy as prompt
❌ Errors (2)
effect-needs-cleanupuseEffect subscribes via
addEventListener(...)but never returns a cleanup — leaks the registration on every re-run and on unmount. Return a cleanup function that calls the matching remove/unsubscribe callsrc/lib/hooks/use-has-primary-touch.tsx:6src/components/ui/scroll-area.tsx:75no-react19-deprecated-apisforwardRef is no longer needed on React 19+ — refs are regular props on function components; remove forwardRef and pass ref directly
src/components/spinner.tsx:7src/components/ui/form.tsx:45src/components/ui/form.tsx:46src/components/ui/form.tsx:75src/components/ui/form.tsx:89src/components/ui/form.tsx:106src/components/ui/form.tsx:129src/components/ui/form.tsx:146src/components/ui/disclosure.tsx:12src/components/chat/code-block.tsx:5src/components/ui/carousel.tsx:36src/components/ui/avatar.tsx:8src/components/ui/accordion.tsx:13src/components/ai-elements/inline-citation.tsx:8src/components/data-stream-provider.tsx:5src/components/copy-button.tsx:6src/components/ai-elements/attachments.tsx:6src/lib/mobile-header-context.tsx:8src/components/ui/tooltip.tsx:15src/components/ui/toggle-group.tsx:51src/components/ui/sidebar.tsx:48src/components/ui/sidebar.tsx:56src/components/ui/sidebar.tsx:166src/components/ui/sidebar.tsx:279src/components/ui/sidebar.tsx:305src/components/ui/sidebar.tsx:334src/components/ui/sidebar.tsx:352src/components/ui/sidebar.tsx:370src/components/ui/sidebar.tsx:385src/components/ui/sidebar.tsx:400src/components/ui/sidebar.tsx:418src/components/ui/sidebar.tsx:436src/components/ui/sidebar.tsx:454src/components/ui/sidebar.tsx:475src/components/ui/sidebar.tsx:498src/components/ui/sidebar.tsx:511src/components/ui/sidebar.tsx:524src/components/ui/sidebar.tsx:560src/components/ui/sidebar.tsx:622src/components/ui/sidebar.tsx:653src/components/ui/sidebar.tsx:674src/components/ui/sidebar.tsx:715src/components/ui/sidebar.tsx:732src/components/ui/sidebar.tsx:738src/components/ui/popover.tsx:15src/components/ui/sheet.tsx:19src/components/ui/sheet.tsx:55src/components/ui/sheet.tsx:104src/components/ui/sheet.tsx:116src/components/ui/morphing-dialog.tsx:16src/components/ui/scroll-area.tsx:18src/components/ui/scroll-area.tsx:170src/components/ui/scroll-area.tsx:176use-lazy-motionImport "m" with LazyMotion instead of "motion" — saves ~30kb in bundle size
src/components/spaces/settings-dialog.tsx:11src/components/spaces/knowledge-dialog.tsx:5src/components/spaces/header.tsx:9src/components/spaces/cards.tsx:4src/components/ui/disclosure.tsx:3src/components/sidebar.tsx:11src/components/chat/message.tsx:5src/components/chat/header.tsx:4src/components/chat/display-chats.tsx:10src/components/profile.tsx:5src/components/mode-selector.tsx:4src/components/chat-input.tsx:13src/components/ui/border-trail.tsx:2src/components/ui/accordion.tsx:2src/components/ui/theme-toggle.tsx:6src/components/ui/text-loop.tsx:2src/components/ui/text-shimmer.tsx:2src/components/ui/text-effect.tsx:3src/components/ui/morphing-dialog.tsx:7async-await-in-loopawait inside a for…of loop runs the calls sequentially — for independent operations, collect them and use
await Promise.all(items.map(...))to run them concurrentlysrc/components/spaces/knowledge-dialog.tsx:129src/lib/ai/tools/web-search.ts:69src/lib/mcp/client.ts:135src/lib/mcp/client.ts:178src/lib/mcp/client.ts:196src/lib/mcp/client.ts:225src/lib/ai/tools/save-to-memories.ts:53src/lib/ai/embedding.ts:68src/lib/ai/tools/knowledge-search.ts:57src/lib/ai/tools/finance-search.ts:41design-no-redundant-size-axesw-8 h-8 → use the shorthand size-8 (Tailwind v3.4+)
src/components/spaces/knowledge-table.tsx:515src/components/spaces/knowledge-table.tsx:532src/components/spaces/knowledge-table.tsx:552src/components/spaces/knowledge-table.tsx:565src/components/chat/display-chats.tsx:264src/components/profile.tsx:48src/components/display-memories.tsx:127src/components/ui/sheet.tsx:67design-no-three-period-ellipsisThree-period ellipsis ("...") in JSX text — use the actual ellipsis character "…" (or
…)src/components/chat/tools/knowledge-search-tool.tsx:170src/components/chat/tools/finance-search-tool.tsx:154src/components/chat/tools/academic-search-tool.tsx:178src/components/sidebar/chats-list.tsx:338src/components/sidebar/chats-list.tsx:370src/components/chat/tools/web-search-tool.tsx:241src/components/chat/tools/save-to-memories.tsx:35js-combine-iterations.filter().map() iterates the array twice — combine into a single loop with .reduce() or for...of
src/components/ai-elements/conversation.tsx:131src/components/chat/tools/web-search-tool.tsx:61src/components/chat/tools/web-search-tool.tsx:61src/app/api/chat/_lib/tools.ts:53src/lib/ai/utils.ts:44src/app/api/chat/_lib/request-logger.ts:42src/lib/ai/mistral-ocr.ts:36react-compiler-destructure-methodDestructure for clarity:
const { push } = useRouter()then callpush(...)directly — easier for React Compiler to memoize and clearer about which methods this component depends onsrc/components/spaces/settings-dialog.tsx:360src/components/sidebar/chats-list.tsx:216src/components/profile.tsx:235src/components/profile.tsx:247src/components/profile.tsx:252src/components/auth/sign-out-button.tsx:25no-array-index-as-keyArray index "index" used as key — causes bugs when list is reordered or filtered
src/components/chat/message.tsx:452src/components/chat/message.tsx:497src/components/chat/message.tsx:523src/components/chat/message.tsx:545src/components/chat-input.tsx:481src/components/ui/text-effect.tsx:315no-permanent-will-changePermanent will-change wastes GPU memory — apply only during active animation and remove after
src/components/ui/border-trail.tsx:40src/components/ui/text-loop.tsx:68src/components/ui/morphing-dialog.tsx:234src/components/ui/morphing-dialog.tsx:301src/components/ui/morphing-dialog.tsx:334src/components/ui/morphing-dialog.tsx:388design-no-redundant-padding-axespx-4 py-4 → use the shorthand p-4
src/app/(auth)/sign-in/page.tsx:50src/components/sidebar/chats-list.tsx:320src/components/sidebar/chats-list.tsx:334src/components/sidebar/chats-list.tsx:336src/components/model-selector.tsx:272design-no-space-on-flex-childrenspace-y-6 on a flex/grid parent — use gap-y-6 instead. Per-sibling margins phantom-gap on conditional render and don't mirror in RTL
src/components/spaces/knowledge-dialog.tsx:254src/components/spaces/knowledge-dialog.tsx:268src/components/mcp-server-config.tsx:239src/components/display-memories.tsx:125src/components/display-memories.tsx:280nextjs-missing-metadataPage without metadata or generateMetadata export — hurts SEO
src/app/(main)/(chat)/c/page.tsx:1src/app/(main)/(chat)/c/[id]/page.tsx:1src/app/(main)/page.tsx:1src/app/(main)/(spaces)/s/page.tsx:1src/app/(main)/(spaces)/s/[id]/page.tsx:1server-sequential-independent-awaitSequential
awaitwithout a data dependency on the previous result — wrap the independent calls inPromise.all([...])so they race instead of waterfallingsrc/app/(main)/(chat)/c/[id]/page.tsx:15src/app/(main)/(chat)/c/[id]/page.tsx:20src/app/(main)/(spaces)/s/page.tsx:9src/app/(main)/(spaces)/s/[id]/page.tsx:13src/app/(main)/(spaces)/s/[id]/page.tsx:19async-parallel3 sequential await statements that appear independent — use Promise.all() for parallel execution
Issue body truncated. See the full report at react.review/dashboard.