Skip to content

Conversation

@NykolaySavin
Copy link
Collaborator

@NykolaySavin NykolaySavin commented Nov 20, 2025

User description

Implements issue #211 - shows clear visual indicators when tools require sign-in

Changes:

  • Added requiresAuth field to ToolConfig interface
  • Marked 14 AI-powered tools as requiring authentication
  • 2 non-AI tools (document-chunker, link-validator) remain public and are allowed for try for non-authenticated users (previously all were restricted)
  • Tools listing page shows lock icons and banner for unauthenticated users
  • 'Try It' tab is grayed out with lock icon when auth required
  • Conditionally enforces auth only for tools that need it

PR Type

Enhancement


Description

  • Added requiresAuth field to ToolConfig interface for authentication control

  • Marked 14 AI-powered tools as requiring authentication, 2 non-AI tools as public

  • Updated tools listing page with lock icons and authentication banner for unauthenticated users

  • Modified Try It tab to show lock icon and tooltip when authentication required

  • Conditionally wraps tool pages in AuthenticatedToolPage based on requiresAuth flag

  • Updated cost estimate for English Dialect Detector to reflect Claude usage


Diagram Walkthrough

flowchart LR
  A["ToolConfig Interface"] -->|"add requiresAuth field"| B["Tool Configurations"]
  B -->|"mark 14 AI tools"| C["requiresAuth: true"]
  B -->|"mark 2 utility tools"| D["requiresAuth: false"]
  C -->|"display lock icons"| E["Tools Listing Page"]
  C -->|"disable Try It tab"| F["Tool Detail Page"]
  E -->|"show auth banner"| G["Unauthenticated Users"]
  F -->|"conditional wrapping"| H["AuthenticatedToolPage"]
Loading

File Walkthrough

Relevant files
Enhancement
Tool.ts
Add requiresAuth field to ToolConfig                                         

internal-packages/ai/src/tools/base/Tool.ts

  • Added optional requiresAuth boolean field to ToolConfig interface
  • Field defaults to true for AI-powered tools with explanatory comment
+1/-0     
layout.tsx
Pass toolConfig to ToolTabs component                                       

apps/web/src/app/tools/[toolId]/layout.tsx

  • Pass toolConfig prop to ToolTabs component for authentication checking
+1/-1     
GenericToolTryPage.tsx
Conditionally enforce authentication for tools                     

apps/web/src/app/tools/components/GenericToolTryPage.tsx

  • Import toolRegistry from @roast/ai package
  • Check tool's requiresAuth flag and conditionally wrap content in
    AuthenticatedToolPage
  • Only enforce authentication for tools that require it, allowing public
    tools to work without sign-in
  • Refactored JSX structure to separate content rendering from
    authentication wrapper
+111/-100
ToolTabs.tsx
Add lock icon to Try It tab when auth required                     

apps/web/src/app/tools/components/ToolTabs.tsx

  • Added session checking with useSession hook to detect authenticated
    users
  • Accept toolConfig prop to determine authentication requirements
  • Display locked Try It tab with lock icon and tooltip when tool
    requires auth and user is unauthenticated
  • Conditionally render Try It as disabled div or active link based on
    authentication status
+39/-11 
page.tsx
Add auth banner and lock icons to tools listing                   

apps/web/src/app/tools/page.tsx

  • Convert page to client component with 'use client' directive
  • Import useSession hook and LockClosedIcon for authentication UI
  • Add authentication banner for unauthenticated users explaining auth
    requirements
  • Display lock icons on tool cards that require authentication
  • Count and conditionally show banner based on authenticated status and
    available auth-required tools
+37/-3   
Configuration changes
configs.ts
Mark tools with authentication requirements                           

internal-packages/ai/src/tools/configs.ts

  • Added requiresAuth: true to 14 AI-powered tool configurations
  • Added requiresAuth: false to 2 non-AI utility tools (document-chunker,
    link-validator)
  • Updated cost estimate for language-convention-detector from no LLM
    calls to 2 Claude calls
+18/-1   
generated-schemas.ts
Update auto-generated tool schemas with auth                         

internal-packages/ai/src/tools/generated-schemas.ts

  • Updated schema hash to reflect new requiresAuth field additions
  • Added requiresAuth property to all tool schemas matching configs.ts
  • Propagated authentication requirements across all 16 modified tool
    schemas
+33/-17 

Summary by CodeRabbit

  • New Features

    • Per-tool authentication control: restricted tools show lock icons and a gated "Try it" area
    • Authentication-aware Tools Index: banner prompts sign-in when restricted tools exist; some tools remain accessible without auth
  • Bug Fixes / UX

    • Hides gated state while auth status is loading to avoid flicker
  • Tests

    • Simplified tooling page test to a direct file/content verification

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

Implements issue #211 - shows clear visual indicators when tools require sign-in

Changes:
- Added requiresAuth field to ToolConfig interface
- Marked 14 AI-powered tools as requiring authentication
- 3 non-AI tools (document-chunker, link-validator) remain public
- Tools listing page shows lock icons and banner for unauthenticated users
- 'Try It' tab is grayed out with lock icon when auth required
- Conditionally enforces auth only for tools that need it

UX improvements:
- Clear visual indicators before clicking (lock icons)
- Helpful banner explaining auth requirements
- Users can still access documentation and use non-AI tools
- Hover tooltips on disabled tabs
- No changes for authenticated users
@vercel
Copy link

vercel bot commented Nov 20, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Updated (UTC)
roast-my-post Ready Ready Preview Nov 20, 2025 6:58pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 20, 2025

Walkthrough

Adds a per-tool requiresAuth flag and threads it through tool configs and UI: layout now passes toolConfig, ToolTabs and GenericToolTryPage use the flag and session state to gate access, and the tools index shows lock indicators and an auth banner when relevant.

Changes

Cohort / File(s) Summary
Tool configuration updates
internal-packages/ai/src/tools/base/Tool.ts, internal-packages/ai/src/tools/configs.ts, internal-packages/ai/src/tools/generated-schemas.ts
Added optional requiresAuth?: boolean to ToolConfig and set requiresAuth values across tool configs/schemas (most true; some false like document-chunker).
Layout & prop threading
apps/web/src/app/tools/[toolId]/layout.tsx
Passes toolConfig into ToolTabs invocation (<ToolTabs toolId={toolId} toolConfig={toolConfig} />).
ToolTabs authentication gating
apps/web/src/app/tools/components/ToolTabs.tsx
ToolTabs props/signature updated to accept toolConfig; uses useSession and toolConfig.requiresAuth to compute isLocked; renders a lock UI (with LockClosedIcon) when locked and session indicates unauthenticated/loading handling.
GenericToolTryPage conditional wrapping
apps/web/src/app/tools/components/GenericToolTryPage.tsx
Retrieves tool config from toolRegistry, computes requiresAuth, refactors UI into content and conditionally wraps with AuthenticatedToolPage only when auth is required.
Tools index page auth indicators
apps/web/src/app/tools/page.tsx
Adds useSession, computes authRequiredCount, shows an auth banner when unauthenticated and any tool requires auth, and displays lock icons on tool cards requiring auth with layout adjustments.
Tests
apps/web/src/app/tools/__tests__/tool-pages.vtest.tsx
Replaced dynamic import test with a synchronous filesystem existence/content check for page.tsx.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Page as Tools Page / Layout
    participant ToolTabs as ToolTabs Component
    participant Session as Session Service
    participant TryArea as "Try It" UI / AuthenticatedToolPage

    User->>Page: Open tool page
    Page->>ToolTabs: render(toolId, toolConfig)
    ToolTabs->>Session: useSession() (checks auth)
    Session-->>ToolTabs: session (authenticated / null / loading)

    alt toolConfig.requiresAuth == true
        alt session.authenticated
            ToolTabs->>TryArea: render Try It link (unlocked)
        else session.unauthenticated
            ToolTabs->>TryArea: render lock UI + tooltip (disabled)
        else session.loading
            ToolTabs->>TryArea: render neutral/loading state (avoid lock flash)
        end
    else toolConfig.requiresAuth == false
        ToolTabs->>TryArea: render Try It link (always accessible)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Pay attention to session loading handling in ToolTabs to avoid flicker/false-locked state.
  • Verify requiresAuth defaults and that configs/schemas consistently reflect intended access.
  • Review GenericToolTryPage conditional wrapper to ensure public tools render correctly without auth wrapper.

Possibly related PRs

Suggested labels

Review effort 4/5

Poem

I’m a rabbit with a tiny key,
Hopping through tools—some locked for me.
I show a padlock, guard the gate,
Sign in to play, or skip if it’s straight.
🐇🔐✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding visual authentication indicators for AI-powered tools, which aligns with the PR's core objective of displaying lock icons and authentication requirements.
✨ 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 fix/issue-211-ai-tools-auth-indicator

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fd52b8b and ed051f5.

📒 Files selected for processing (1)
  • apps/web/src/app/tools/__tests__/tool-pages.vtest.tsx (1 hunks)
⏰ 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). (6)
  • GitHub Check: Integration Tests
  • GitHub Check: Build Application
  • GitHub Check: Docker Build Test
  • GitHub Check: Unit Tests
  • GitHub Check: Build and Push Docker Images (Dockerfile.worker, -worker, worker)
  • GitHub Check: Build and Push Docker Images (Dockerfile, main)
🔇 Additional comments (1)
apps/web/src/app/tools/__tests__/tool-pages.vtest.tsx (1)

47-56: FS-based existence/content check for main tools page looks good

This refactor aligns the main tools page test with the rest of the suite (simple filesystem + content assertions) and correctly targets ../page.tsx with checks for both the default export and ToolsIndexPage. No functional or structural issues from this change.


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.

@qodo-code-review
Copy link

qodo-code-review bot commented Nov 20, 2025

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
Missing server-side auth enforcement

Description: Relying solely on client-side checks (requiresAuth and session) to gate access risks
bypass if server APIs don't enforce authentication; ensure server-side execution endpoints
validate auth for tools marked as requiring it.
GenericToolTryPage.tsx [382-536]

Referred Code
const toolConfig = toolRegistry[toolId];
const requiresAuth = toolConfig?.requiresAuth !== false; // Default to true if not specified

const content = (
  <>
    <div className="space-y-6">
      <form onSubmit={handleSubmit} className="space-y-6 bg-white p-6 rounded-lg shadow-sm border">
          {fields.map(renderField)}

          {/* Multiple examples with labels */}
          {exampleInputs && exampleInputs.length > 0 && (
            <div className="border-t pt-4">
              <p className="text-sm font-medium text-gray-700 mb-3">Load an example:</p>
              <div className="space-y-2">
                {exampleInputs.map((example, i) => (
                  <button
                    key={i}
                    type="button"
                    onClick={() => loadExample(example.value)}
                    disabled={isLoading}
                    className="w-full text-left px-4 py-3 bg-gray-50 hover:bg-gray-100 disabled:bg-gray-200 disabled:cursor-not-allowed rounded-lg border border-gray-200 transition-colors group"


 ... (clipped 134 lines)
Ticket Compliance
🟡
🎫 #211
🟢 When the user is not logged in, AI-powered tools should not be usable via the Try
experience.
Clearly indicate to unauthenticated users that certain tools require sign-in (e.g., gray
out or lock the Try area, or show a message).
Allow access to non-AI/public tools even when not logged in.
Provide messaging or visual indicators on the tools listing and/or tool pages explaining
access restrictions.
Verify in a running environment that unauthenticated users cannot navigate to or use Try
It for auth-required tools and that links are disabled correctly.
Confirm UX details match product intent (grayed-out styling, tooltip copy, banner
visibility) across breakpoints and themes.
Ensure the selected set of tools marked requiresAuth true/false aligns with product
decisions.
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
Missing Auth Logs: The PR introduces authentication gating for tool usage but adds no logging for critical
auth-related actions (e.g., blocked access, attempts to use locked tools), making audit
reconstruction potentially incomplete.

Referred Code
// Only wrap in AuthenticatedToolPage if tool requires auth
return requiresAuth ? (
  <AuthenticatedToolPage toolName={toolConfig?.name}>
    {content}
  </AuthenticatedToolPage>
) : content;

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Loading State Gaps: The Try It tab disables only when not loading and unauthenticated, but no explicit UI
handling is shown during loading or for missing toolConfig, which could cause edge-case UX
inconsistencies.

Referred Code
const pathname = usePathname();
const { data: session, status } = useSession();
const isLoading = status === 'loading';
const isAuthenticated = !!session?.user;

const normalizedPath = pathname.replace(/\/+$/, ''); // Remove trailing slashes
const isDocsPage = normalizedPath === `/tools/${toolId}/docs` || normalizedPath === `/tools/${toolId}`;
const isTryPage = normalizedPath === `/tools/${toolId}/try`;

// Check if tool requires auth and user is not authenticated
const requiresAuth = toolConfig.requiresAuth !== false; // Default to true if not specified
const isLocked = requiresAuth && !isAuthenticated && !isLoading;

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@NykolaySavin
Copy link
Collaborator Author

Banner
image

Tools restriction
image

@qodo-code-review
Copy link

qodo-code-review bot commented Nov 20, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
General
Prevent tab state UI flicker

Prevent a UI flicker on the "Try It" tab by handling the loading state
separately. Show a disabled placeholder while the session is loading, then show
either the locked or active tab state.

apps/web/src/app/tools/components/ToolTabs.tsx [26]

-const isLocked = requiresAuth && !isAuthenticated && !isLoading;
+const isLocked = requiresAuth && !isAuthenticated;
 
+// ... inside the return statement ...
+{isLoading ? (
+  <div className="py-2 px-1 border-b-2 border-transparent font-medium text-sm opacity-50 cursor-wait flex items-center gap-1.5">
+    <span>Try It</span>
+  </div>
+) : isLocked ? (
+  <div
+    className="py-2 px-1 border-b-2 border-transparent font-medium text-sm opacity-50 cursor-not-allowed flex items-center gap-1.5 group relative"
+    title="Sign in required to try this tool"
+  >
+    ...
+  </div>
+) : (
+  <Link ...>
+    Try It
+  </Link>
+)}
+

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies a UI flicker and provides a valid solution by introducing a distinct loading state for the tab, which improves the user experience during authentication checks.

Medium
  • Update

Copy link
Contributor

@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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
internal-packages/ai/src/tools/generated-schemas.ts (1)

2282-2291: fallacy-review missing requiresAuth here but set to true in configs.ts

In this schema, the fallacy-review tool’s config block does not include a requiresAuth field, while fallacyReviewConfig in internal-packages/ai/src/tools/configs.ts sets requiresAuth: true. That divergence can lead to inconsistent metadata depending on which source a consumer reads for auth requirements.

I’d suggest either:

  • Adding requiresAuth: true to the underlying Tool.config for fallacy-review and regenerating this file, or
  • Intentionally deciding that fallacy-review does not require auth and updating fallacyReviewConfig to match.

Given other AI-powered tools are marked as requiring auth in both places, aligning this one for consistency seems important.

🧹 Nitpick comments (3)
internal-packages/ai/src/tools/base/Tool.ts (1)

6-16: Consider centralizing requiresAuth defaulting logic around ToolConfig

Adding requiresAuth?: boolean to ToolConfig with the “defaults to true” comment is good. Right now, the defaulting behavior (config.requiresAuth !== false) is implemented in multiple UI consumers instead of being encapsulated.

Optionally, you could add a small helper here, e.g. export const toolRequiresAuth = (config: ToolConfig) => config.requiresAuth !== false;, and reuse it across the app so future changes to the default behavior are made in one place.

internal-packages/ai/src/tools/configs.ts (1)

13-228: Per-tool requiresAuth values align with business rules; consider DRYing out auth semantics

All tool configs here are marked as expected: LLM-backed tools are requiresAuth: true, while document-chunker and link-validator are explicitly requiresAuth: false, matching the “two public tools, others require sign-in” behavior.

Given multiple callers now use the pattern config.requiresAuth !== false to implement the “default true” rule, it might be worth exporting a helper (e.g. toolRequiresAuth(config)) from this module or Tool.ts and reusing it in the UI and any server-side checks to keep semantics in sync as new tools are added.

apps/web/src/app/tools/page.tsx (1)

5-6: Auth banner and per-tool lock indicators are consistent with requiresAuth semantics

Using useSession plus isLoading/isAuthenticated to drive:

  • authRequiredCount = tools.filter(tool => tool.requiresAuth !== false).length
  • showAuthBanner for unauthenticated users, and
  • showLock on individual cards when requiresAuth && !isAuthenticated && !isLoading

lines up with the configuration in allToolConfigs (only document-chunker and link-validator set requiresAuth: false). The UX—banner explanation plus subtle lock icon on affected tools—also reads clearly, and avoiding the banner/lock while status === 'loading' is a nice touch.

If more components start needing the same requiresAuth !== false + isAuthenticated logic (e.g., beyond this page and ToolTabs), consider a small shared helper/hook to keep the behavior DRY, but not strictly necessary right now.

Also applies to: 9-11, 27-30, 40-43, 54-69, 87-102

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6991587 and fd52b8b.

📒 Files selected for processing (7)
  • apps/web/src/app/tools/[toolId]/layout.tsx (1 hunks)
  • apps/web/src/app/tools/components/GenericToolTryPage.tsx (3 hunks)
  • apps/web/src/app/tools/components/ToolTabs.tsx (2 hunks)
  • apps/web/src/app/tools/page.tsx (5 hunks)
  • internal-packages/ai/src/tools/base/Tool.ts (1 hunks)
  • internal-packages/ai/src/tools/configs.ts (17 hunks)
  • internal-packages/ai/src/tools/generated-schemas.ts (17 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
apps/web/src/app/tools/components/ToolTabs.tsx (1)
internal-packages/ai/src/tools/base/Tool.ts (1)
  • ToolConfig (6-16)
apps/web/src/app/tools/page.tsx (1)
apps/web/src/__mocks__/next-auth/react.js (2)
  • useSession (4-7)
  • useSession (4-7)
apps/web/src/app/tools/[toolId]/layout.tsx (1)
apps/web/src/app/tools/components/ToolTabs.tsx (1)
  • ToolTabs (14-72)
apps/web/src/app/tools/components/GenericToolTryPage.tsx (2)
internal-packages/ai/src/tools/configs.ts (1)
  • toolRegistry (258-260)
apps/web/src/app/tools/components/AuthenticatedToolPage.tsx (1)
  • AuthenticatedToolPage (20-101)
⏰ 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). (6)
  • GitHub Check: Build Application
  • GitHub Check: Integration Tests
  • GitHub Check: Docker Build Test
  • GitHub Check: Unit Tests
  • GitHub Check: Build and Push Docker Images (Dockerfile, main)
  • GitHub Check: Build and Push Docker Images (Dockerfile.worker, -worker, worker)
🔇 Additional comments (8)
internal-packages/ai/src/tools/generated-schemas.ts (1)

19-21: requiresAuth flags and public tools look consistent with the per-tool auth design

The schema configs correctly mark all the LLM-backed tools as requiresAuth: true and the two non-LLM utilities (document-chunker, link-validator) as requiresAuth: false, which matches the stated behavior of “most AI tools require sign-in, but these two remain public”. No changes needed here.

Also applies to: 182-184, 463-465, 676-678, 788-790, 986-988, 1124-1126, 1240-1242, 1403-1405, 1513-1517, 1636-1638, 1754-1756, 2058-2060, 2388-2390

apps/web/src/app/tools/[toolId]/layout.tsx (1)

26-27: Correctly threading toolConfig into ToolTabs for auth-aware tabs

Passing toolConfig={toolConfig} here cleanly enables ToolTabs to use requiresAuth without changing layout semantics. The lookup from toolRegistry ensures the prop is a proper ToolConfig. Looks good.

Also applies to: 47-49

apps/web/src/app/tools/components/GenericToolTryPage.tsx (3)

4-4: LGTM!

The toolRegistry import is correctly sourced and necessary for looking up tool-specific configuration.


381-383: LGTM! Safe default behavior.

The authentication check correctly defaults to requiring auth when requiresAuth is not explicitly set to false. The optional chaining safely handles cases where the tool isn't found in the registry.


385-536: LGTM! Clean conditional authentication wrapping.

The implementation correctly extracts the UI into a content variable and conditionally wraps it with AuthenticatedToolPage based on the tool's auth requirements. This achieves the PR's goal of selective authentication enforcement without altering the core UI logic.

apps/web/src/app/tools/components/ToolTabs.tsx (3)

5-12: LGTM! Required imports and interface update.

The new imports support the authentication-aware behavior, and the toolConfig prop addition to ToolTabsProps is intentional to enable per-tool auth configuration.


43-55: LGTM! Clear visual indicator for locked state.

The locked tab UI effectively communicates the authentication requirement with a lock icon, reduced opacity, and an accessible tooltip. The title attribute provides a fallback for keyboard navigation.


56-67: LGTM! Preserves original functionality.

The unlocked state correctly maintains the original "Try It" link behavior with proper active state styling.

Comment on lines +14 to +26
export function ToolTabs({ toolId, toolConfig }: ToolTabsProps) {
const pathname = usePathname();
const { data: session, status } = useSession();
const isLoading = status === 'loading';
const isAuthenticated = !!session?.user;

const normalizedPath = pathname.replace(/\/+$/, ''); // Remove trailing slashes
const isDocsPage = normalizedPath === `/tools/${toolId}/docs` || normalizedPath === `/tools/${toolId}`;
const isTryPage = normalizedPath === `/tools/${toolId}/try`;

// Check if tool requires auth and user is not authenticated
const requiresAuth = toolConfig.requiresAuth !== false; // Default to true if not specified
const isLocked = requiresAuth && !isAuthenticated && !isLoading;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

LGTM! Correct authentication state management.

The authentication check properly handles the loading state by excluding it from isLocked, preventing premature display of the lock icon while the session is being verified. The default auth requirement logic is consistent with GenericToolTryPage.tsx.

Optional: Consider test bypass consistency

AuthenticatedToolPage includes test bypass logic for Playwright tests (checking __test_bypass_auth and localStorage). ToolTabs doesn't include this, which might cause the tab to show as locked during tests even when the page itself allows access. This is likely fine if tests navigate directly to the /try route, but consider verifying test coverage handles this correctly.


🏁 Script executed:

#!/bin/bash
# Check if there are E2E tests that interact with tool tabs for auth-required tools
rg -n "ToolTabs|Try It" --type=ts --type=tsx -g "*test*" -g "*spec*" -A 3 -B 3

Length of output: 27


🏁 Script executed:

#!/bin/bash
# Search for test files referencing ToolTabs or auth-related tests
rg -n "ToolTabs" --type=ts -g "*test*" -g "*spec*" -A 3 -B 3

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Check if __test_bypass_auth logic exists in AuthenticatedToolPage for comparison
rg -n "__test_bypass_auth" --type=ts -A 5 -B 5

Length of output: 2979


🏁 Script executed:

#!/bin/bash
# Search for e2e or test directory structure to understand test organization
fd -t f -e test.ts -e spec.ts -e e2e.ts | head -20

Length of output: 401


🏁 Script executed:

#!/bin/bash
# View the full ToolTabs.tsx file to see if it has test bypass logic
cat apps/web/src/app/tools/components/ToolTabs.tsx

Length of output: 2883


🏁 Script executed:

#!/bin/bash
# Check the tools-auth.spec.ts test file to see if it tests ToolTabs or tab locking
cat apps/web/tests/playwright/tools-auth.spec.ts

Length of output: 13590


🏁 Script executed:

#!/bin/bash
# Search for any test bypass checks in ToolTabs across all files
rg -n "test_bypass" apps/web/src/app/tools/components/ToolTabs.tsx

Length of output: 0


ToolTabs is missing test bypass logic that exists in AuthenticatedToolPage—add for consistency.

The verification confirms the inconsistency: AuthenticatedToolPage (lines 37-42) checks for __test_bypass_auth and localStorage bypass flags, but ToolTabs (lines 14-26 in the reviewed code) does not. The current tests work despite this because they navigate directly to /tools/{toolId}/try, bypassing the tab UI entirely. However, the inconsistency should be resolved to prevent issues if the tab UI is accessed through navigation or if tests are refactored to validate tab locking behavior.

Suggested fix: Add the same test bypass check to ToolTabs.tsx that exists in AuthenticatedToolPage.tsx:

  • Check (window as any).__test_bypass_auth or localStorage.getItem('playwright-auth-bypass')
  • Set isLocked = false when bypass is active (matching AuthenticatedToolPage behavior)
🤖 Prompt for AI Agents
In apps/web/src/app/tools/components/ToolTabs.tsx around lines 14 to 26,
ToolTabs lacks the test bypass logic present in AuthenticatedToolPage which
causes inconsistent test behavior; add the same bypass check by reading (window
as any).__test_bypass_auth || localStorage.getItem('playwright-auth-bypass')
and, when that flag is truthy, force isLocked to false (i.e., treat the tool as
unlocked), ensuring you guard access to window for SSR if needed so the bypass
only runs in the browser.

Changed the test to check file existence and content instead of
dynamically importing the module, which fails for client components
in the test environment.

All 8 tests now pass.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants