Skip to content

Conversation

@ketkarameya
Copy link

@ketkarameya ketkarameya commented Feb 10, 2026

Benchmark PR for Gitar evaluation

Original PR: agentic-review-benchmarks#9

refactor: always preserve marketplace search state in URL


Summary by Gitar

  • Architecture refactor:
    • Removed dual-state pattern: deleted preserveSearchStateInQueryAtom, local atoms (searchPluginTextAtom, activePluginTypeAtom, filterPluginTagsAtom), and HydrateMarketplaceAtoms component
  • Simplified state hooks:
    • All hooks (useSearchPluginText, useActivePluginType, useFilterPluginTags) now directly use useQueryState() from nuqs
  • Fixed logic bug:
    • Corrected search mode condition in useMarketplaceSearchMode(): inverted negation for PLUGIN_CATEGORY_WITH_COLLECTIONS

This will update automatically on new commits.


const isSearchMode = !!searchPluginText
|| filterPluginTags.length > 0
|| (searchMode ?? (!PLUGIN_CATEGORY_WITH_COLLECTIONS.has(activePluginType)))
|| (searchMode ?? (PLUGIN_CATEGORY_WITH_COLLECTIONS.has(activePluginType)))

Choose a reason for hiding this comment

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

🚨 Bug: Logic inversion contradicts comment and breaks search mode

The negation was removed from !PLUGIN_CATEGORY_WITH_COLLECTIONS.has(activePluginType), changing it to PLUGIN_CATEGORY_WITH_COLLECTIONS.has(activePluginType). This inverts the search mode default behavior.

The comment directly above (lines 29-32) states: "Not all categories have collections, so we need to force the search mode for those categories."

PLUGIN_CATEGORY_WITH_COLLECTIONS contains only 'all' and 'tool'. The old logic correctly forced search mode for categories without collections (e.g., model, agent, extension, datasource, trigger, bundle). The new logic forces search mode for categories with collections (all, tool), which is the opposite of the documented intent.

Impact: Users browsing categories without collections (model, agent, extension, etc.) will see a collections view (which has no data for those categories), while categories with collections will incorrectly default to search mode. This fundamentally breaks the marketplace browsing experience for most plugin categories.

Was this helpful? React with 👍 / 👎

Suggested change
|| (searchMode ?? (PLUGIN_CATEGORY_WITH_COLLECTIONS.has(activePluginType)))
|| (searchMode ?? (!PLUGIN_CATEGORY_WITH_COLLECTIONS.has(activePluginType)))
  • Apply suggested fix

const queryState = useQueryState('category', marketplaceSearchParamsParsers.category)
const atomState = useAtom(activePluginTypeAtom)
return preserveSearchStateInQuery ? queryState : atomState
return useQueryState('tab', marketplaceSearchParamsParsers.category)

Choose a reason for hiding this comment

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

⚠️ Bug: Client-server URL param mismatch: 'tab' vs 'category'

The client-side useActivePluginType() now writes to the URL parameter 'tab', but the server-side hydration-server.tsx uses createLoader(marketplaceSearchParamsParsers) which reads the category key from the URL (defined in search-params.ts).

In hydration-server.tsx:16-17, createLoader from nuqs uses the object keys of the parsers to determine which URL parameters to read. Since the key is category, the server reads ?category=.... But the client now writes to ?tab=....

Impact: Server-side prefetching will never see the active plugin type from the URL. When a user navigates to ?tab=tool, the server will default to 'all' and prefetch the wrong data. This defeats the purpose of server-side hydration.

Fix: Either rename the key in marketplaceSearchParamsParsers from category to tab, or keep using 'category' as the URL parameter name in useActivePluginType().

Was this helpful? React with 👍 / 👎

Suggested change
return useQueryState('tab', marketplaceSearchParamsParsers.category)
return useQueryState('category', marketplaceSearchParamsParsers.category)
  • Apply suggested fix

Copy link

@gitar-bot-staging gitar-bot-staging bot left a comment

Choose a reason for hiding this comment

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

⚠️ This PR is blocked due to unresolved code review findings.

Configure merge blocking · Maintainers can dismiss this review. Gitar never approves changes.

@gitar-bot-staging
Copy link

gitar-bot-staging bot commented Feb 10, 2026

Code Review 🚫 Blocked 0 resolved / 3 findings

The simplification of dual-state to URL-only is a good direction, but the logic inversion in useMarketplaceSearchMode() breaks search mode defaults for most plugin categories, and the 'tab' vs 'category' URL parameter rename creates a client-server mismatch that breaks SSR prefetching.

🚨 Bug: Logic inversion contradicts comment and breaks search mode

📄 web/app/components/plugins/marketplace/atoms.ts:43

The negation was removed from !PLUGIN_CATEGORY_WITH_COLLECTIONS.has(activePluginType), changing it to PLUGIN_CATEGORY_WITH_COLLECTIONS.has(activePluginType). This inverts the search mode default behavior.

The comment directly above (lines 29-32) states: "Not all categories have collections, so we need to force the search mode for those categories."

PLUGIN_CATEGORY_WITH_COLLECTIONS contains only 'all' and 'tool'. The old logic correctly forced search mode for categories without collections (e.g., model, agent, extension, datasource, trigger, bundle). The new logic forces search mode for categories with collections (all, tool), which is the opposite of the documented intent.

Impact: Users browsing categories without collections (model, agent, extension, etc.) will see a collections view (which has no data for those categories), while categories with collections will incorrectly default to search mode. This fundamentally breaks the marketplace browsing experience for most plugin categories.

Suggested fix
    || (searchMode ?? (!PLUGIN_CATEGORY_WITH_COLLECTIONS.has(activePluginType)))
⚠️ Bug: Client-server URL param mismatch: 'tab' vs 'category'

📄 web/app/components/plugins/marketplace/atoms.ts:23

The client-side useActivePluginType() now writes to the URL parameter 'tab', but the server-side hydration-server.tsx uses createLoader(marketplaceSearchParamsParsers) which reads the category key from the URL (defined in search-params.ts).

In hydration-server.tsx:16-17, createLoader from nuqs uses the object keys of the parsers to determine which URL parameters to read. Since the key is category, the server reads ?category=.... But the client now writes to ?tab=....

Impact: Server-side prefetching will never see the active plugin type from the URL. When a user navigates to ?tab=tool, the server will default to 'all' and prefetch the wrong data. This defeats the purpose of server-side hydration.

Fix: Either rename the key in marketplaceSearchParamsParsers from category to tab, or keep using 'category' as the URL parameter name in useActivePluginType().

Suggested fix
  return useQueryState('category', marketplaceSearchParamsParsers.category)
💡 Quality: Type widened from function signature to any

📄 web/app/components/plugins/plugin-page/context.tsx:51

The selector parameter type was changed from (value: PluginPageContextValue) => any to any, removing type safety. The original type ensured callers pass a function that accepts PluginPageContextValue, which catches errors at compile time (e.g., passing a string instead of a selector function, or accessing non-existent properties on the context value).

This appears to be an unrelated regression. If the intent was to widen the type, consider at minimum preserving the function constraint: (value: PluginPageContextValue) => unknown.

Suggested fix
export function usePluginPageContext(selector: (value: PluginPageContextValue) => any) {
Rules 🎸 1 action taken

Gitar Rules

🎸 Summary Enhancement: Appended technical summary with 3 categories covering architecture refactor, simplified hooks, and logic bug fix

5 rules not applicable. Show all rules by commenting gitar display:verbose.

Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Showing less information.

Comment with these commands to change:

Auto-apply Compact
gitar auto-apply:on         
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

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.

3 participants