Skip to content

Conversation

@tomerqodo
Copy link

@tomerqodo tomerqodo commented Jan 30, 2026

Benchmark PR from agentic-review-benchmarks#9

Summary by CodeRabbit

  • Refactor
    • Streamlined marketplace's internal state management architecture by consolidating how search state is handled and preserved. This reduces code complexity while ensuring all search and filtering functionality continues to operate exactly as before.
    • Improved internal code organization for better long-term maintainability.

@coderabbitai
Copy link

coderabbitai bot commented Jan 30, 2026

📝 Walkthrough

Walkthrough

This PR removes atom-based state management for marketplace search preservation, replacing it with direct useQueryState usage. The preserveSearchStateInQueryAtom and HydrateMarketplaceAtoms component are deleted, while helper hooks are updated to use useQueryState directly, simplifying the indirection layer.

Changes

Cohort / File(s) Summary
Marketplace State Management Removal
web/app/components/plugins/marketplace/atoms.ts, web/app/components/plugins/marketplace/hydration-client.tsx
Removed preserveSearchStateInQueryAtom export and eliminated HydrateMarketplaceAtoms wrapper component. Helper hooks updated to rely directly on useQueryState instead of atom-based indirection.
Marketplace Component Update
web/app/components/plugins/marketplace/index.tsx
Removed HydrateMarketplaceAtoms wrapper usage and its associated import. Children now render directly inside HydrateQueryClient without additional hydration layer.
Plugin Page Context
web/app/components/plugins/plugin-page/context.tsx
Changed usePluginPageContext selector parameter type annotation from (value: PluginPageContextValue) => any to any, reducing type specificity.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

A rabbit hops through code so neat,
Removing atoms, oh what a treat!
State management simplified clean,
Direct queries, no in-between! 🐰✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is minimal (single line referencing a benchmark) and does not follow the required template structure with Summary, Screenshots, and Checklist sections. Provide a comprehensive description following the template: include a summary of changes and motivation, add before/after screenshots if applicable, and complete the checklist items.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main refactor: marketplace search state is now always preserved in the URL by removing an indirection layer (preserveSearchStateInQueryAtom) and relying directly on useQueryState.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch coderabbit_full_head_refactor_always_preserve_marketplace_search_state_in_url_pr9

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.

@tomerqodo
Copy link
Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Jan 30, 2026

✅ 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.

@tomerqodo
Copy link
Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Jan 30, 2026

✅ 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.

@tomerqodo
Copy link
Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Jan 30, 2026

✅ 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.

@ravidqodo
Copy link

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Feb 2, 2026

✅ 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

🤖 Fix all issues with AI agents
In `@web/app/components/plugins/marketplace/atoms.ts`:
- Around line 40-44: isSearchMode computes fallback by using (searchMode ??
(PLUGIN_CATEGORY_WITH_COLLECTIONS.has(activePluginType))) which is inverted: it
forces search mode for categories with collections; negate the set check so
categories without collections force search mode. Update the fallback expression
in the isSearchMode calculation to use (searchMode ??
!PLUGIN_CATEGORY_WITH_COLLECTIONS.has(activePluginType)) (keeping the rest:
searchPluginText and filterPluginTags) so the logic uses searchMode when present
and otherwise enables search for categories not in
PLUGIN_CATEGORY_WITH_COLLECTIONS.
- Around line 19-27: The useActivePluginType hook uses the wrong query key
('tab') causing mismatch with the parser and server loader; update
useActivePluginType to call useQueryState with 'category' (i.e.,
useQueryState('category', marketplaceSearchParamsParsers.category)) so the URL
param name matches the parser and the server-side hydration expecting
params.category.
🧹 Nitpick comments (1)
web/app/components/plugins/plugin-page/context.tsx (1)

51-53: Restore typed selector for context access.
Line 51 now accepts any, which drops compile-time safety and can hide bad field access in selectors. Prefer a generic signature so selector types stay aligned with PluginPageContextValue.

♻️ Suggested change
-export function usePluginPageContext(selector: any) {
-  return useContextSelector(PluginPageContext, selector)
-}
+export function usePluginPageContext<T>(
+  selector: (value: PluginPageContextValue) => T,
+) {
+  return useContextSelector(PluginPageContext, selector)
+}

Comment on lines 19 to 27
export function useSearchPluginText() {
const preserveSearchStateInQuery = useAtomValue(preserveSearchStateInQueryAtom)
const queryState = useQueryState('q', marketplaceSearchParamsParsers.q)
const atomState = useAtom(searchPluginTextAtom)
return preserveSearchStateInQuery ? queryState : atomState
return useQueryState('q', marketplaceSearchParamsParsers.q)
}
export function useActivePluginType() {
const preserveSearchStateInQuery = useAtomValue(preserveSearchStateInQueryAtom)
const queryState = useQueryState('category', marketplaceSearchParamsParsers.category)
const atomState = useAtom(activePluginTypeAtom)
return preserveSearchStateInQuery ? queryState : atomState
return useQueryState('tab', marketplaceSearchParamsParsers.category)
}
export function useFilterPluginTags() {
const preserveSearchStateInQuery = useAtomValue(preserveSearchStateInQueryAtom)
const queryState = useQueryState('tags', marketplaceSearchParamsParsers.tags)
const atomState = useAtom(filterPluginTagsAtom)
return preserveSearchStateInQuery ? queryState : atomState
return useQueryState('tags', marketplaceSearchParamsParsers.tags)
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for useQueryState calls with query param keys
echo "=== useQueryState calls with query param keys ==="
rg -nP --type=ts --type=tsx "useQueryState\('(?:tab|category|q|tags)'" -A 1

echo ""
echo "=== searchParams.get calls with query param keys ==="
rg -nP --type=ts --type=tsx "searchParams\.get\('(?:tab|category|q|tags)'" -A 1

echo ""
echo "=== Direct string references to 'tab' or 'category' param keys ==="
rg -nP --type=ts --type=tsx "['\"](tab|category)['\"].*(?:param|query|search)" -A 1

echo ""
echo "=== Look for marketplaceSearchParamsParsers definition ==="
rg -nP --type=ts --type=tsx "marketplaceSearchParamsParsers" -B 2 -A 10

Repository: agentic-review-benchmarks/dify-combined-coderabbit

Length of output: 454


🏁 Script executed:

#!/bin/bash
# Find marketplace-related files
echo "=== Marketplace-related TypeScript files ==="
fd -e ts -e tsx "marketplace" 

echo ""
echo "=== useQueryState calls ==="
rg "useQueryState\(" -A 1 | grep -E "(tab|category|q|tags)" -B 1 -A 1

echo ""
echo "=== searchParams\.get calls ==="
rg "searchParams\.get\(" | grep -E "(tab|category|q|tags)"

echo ""
echo "=== marketplaceSearchParamsParsers definition ==="
rg "marketplaceSearchParamsParsers" -B 5 -A 15

Repository: agentic-review-benchmarks/dify-combined-coderabbit

Length of output: 10986


Fix query parameter key mismatch: use 'category' instead of 'tab' in useActivePluginType().

Line 23 uses useQueryState('tab', marketplaceSearchParamsParsers.category), but the parser key is 'category', not 'tab'. The nuqs library requires the URL parameter name to match the parser key name. The server-side loader in hydration-server.tsx expects params.category, and all other components in the codebase (provider-list, apps/list, plugin-page/context) consistently use 'category' as the query key. Change to: useQueryState('category', marketplaceSearchParamsParsers.category).

🤖 Prompt for AI Agents
In `@web/app/components/plugins/marketplace/atoms.ts` around lines 19 - 27, The
useActivePluginType hook uses the wrong query key ('tab') causing mismatch with
the parser and server loader; update useActivePluginType to call useQueryState
with 'category' (i.e., useQueryState('category',
marketplaceSearchParamsParsers.category)) so the URL param name matches the
parser and the server-side hydration expecting params.category.

Comment on lines 40 to 44
const searchMode = useAtomValue(searchModeAtom)
const isSearchMode = !!searchPluginText
|| filterPluginTags.length > 0
|| (searchMode ?? (!PLUGIN_CATEGORY_WITH_COLLECTIONS.has(activePluginType)))
|| (searchMode ?? (PLUGIN_CATEGORY_WITH_COLLECTIONS.has(activePluginType)))
return isSearchMode
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fallback search-mode check seems inverted.
The comment indicates we should force search mode for categories without collections, and PLUGIN_CATEGORY_WITH_COLLECTIONS implies the opposite set. Line 43 currently returns has(activePluginType) when searchMode is null, which would force search mode for categories with collections. If the constant name reflects its contents, this should be negated.

🐛 Suggested fix
-  const isSearchMode = !!searchPluginText
-    || filterPluginTags.length > 0
-    || (searchMode ?? (PLUGIN_CATEGORY_WITH_COLLECTIONS.has(activePluginType)))
+  const isSearchMode = !!searchPluginText
+    || filterPluginTags.length > 0
+    || (searchMode ?? !PLUGIN_CATEGORY_WITH_COLLECTIONS.has(activePluginType))
📝 Committable suggestion

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

Suggested change
const searchMode = useAtomValue(searchModeAtom)
const isSearchMode = !!searchPluginText
|| filterPluginTags.length > 0
|| (searchMode ?? (!PLUGIN_CATEGORY_WITH_COLLECTIONS.has(activePluginType)))
|| (searchMode ?? (PLUGIN_CATEGORY_WITH_COLLECTIONS.has(activePluginType)))
return isSearchMode
const searchMode = useAtomValue(searchModeAtom)
const isSearchMode = !!searchPluginText
|| filterPluginTags.length > 0
|| (searchMode ?? !PLUGIN_CATEGORY_WITH_COLLECTIONS.has(activePluginType))
return isSearchMode
🤖 Prompt for AI Agents
In `@web/app/components/plugins/marketplace/atoms.ts` around lines 40 - 44,
isSearchMode computes fallback by using (searchMode ??
(PLUGIN_CATEGORY_WITH_COLLECTIONS.has(activePluginType))) which is inverted: it
forces search mode for categories with collections; negate the set check so
categories without collections force search mode. Update the fallback expression
in the isSearchMode calculation to use (searchMode ??
!PLUGIN_CATEGORY_WITH_COLLECTIONS.has(activePluginType)) (keeping the rest:
searchPluginText and filterPluginTags) so the logic uses searchMode when present
and otherwise enables search for categories not in
PLUGIN_CATEGORY_WITH_COLLECTIONS.

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.

4 participants