Full Code of zaidmukaddam/scira for AI

main 7215d5302303 cached
390 files
4.9 MB
1.3M tokens
2006 symbols
1 requests
Download .txt
Showing preview only (5,156K chars total). Download the full file or copy to clipboard to get everything.
Repository: zaidmukaddam/scira
Branch: main
Commit: 7215d5302303
Files: 390
Total size: 4.9 MB

Directory structure:
gitextract_hejsnn8z/

├── .dockerignore
├── .eslintrc.json
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── config.yml
│   │   └── feature_request.md
│   └── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .prettierrc
├── .vercelignore
├── .vscode/
│   └── settings.json
├── Dockerfile
├── LICENSE
├── README.md
├── ai/
│   ├── models.ts
│   └── providers.ts
├── app/
│   ├── (auth)/
│   │   ├── layout.tsx
│   │   ├── sign-in/
│   │   │   └── page.tsx
│   │   └── sign-up/
│   │       └── page.tsx
│   ├── (content)/
│   │   ├── about/
│   │   │   └── page.tsx
│   │   ├── layout.tsx
│   │   ├── privacy-policy/
│   │   │   └── page.tsx
│   │   ├── terms/
│   │   │   └── page.tsx
│   │   └── x-wrapped/
│   │       ├── [username]/
│   │       │   └── page.tsx
│   │       ├── layout.tsx
│   │       └── page.tsx
│   ├── (search)/
│   │   └── page.tsx
│   ├── actions.ts
│   ├── api/
│   │   ├── auth/
│   │   │   └── [...all]/
│   │   │       └── route.ts
│   │   ├── clean_images/
│   │   │   └── route.ts
│   │   ├── export/
│   │   │   ├── docx/
│   │   │   │   └── route.ts
│   │   │   └── pdf/
│   │   │       └── route.ts
│   │   ├── lookout/
│   │   │   └── route.ts
│   │   ├── mcp/
│   │   │   ├── apps/
│   │   │   │   ├── bridge/
│   │   │   │   │   └── route.ts
│   │   │   │   └── resource/
│   │   │   │       └── read/
│   │   │   │           └── route.ts
│   │   │   ├── elicitation/
│   │   │   │   └── respond/
│   │   │   │       └── route.ts
│   │   │   ├── oauth/
│   │   │   │   ├── callback/
│   │   │   │   │   └── route.ts
│   │   │   │   └── client-metadata/
│   │   │   │       └── [serverId]/
│   │   │   │           └── route.ts
│   │   │   └── servers/
│   │   │       ├── [id]/
│   │   │       │   ├── oauth/
│   │   │       │   │   ├── callback/
│   │   │       │   │   │   └── route.ts
│   │   │       │   │   ├── disconnect/
│   │   │       │   │   │   └── route.ts
│   │   │       │   │   └── start/
│   │   │       │   │       └── route.ts
│   │   │       │   ├── route.ts
│   │   │       │   └── tools/
│   │   │       │       └── route.ts
│   │   │       ├── route.ts
│   │   │       └── test/
│   │   │           └── route.ts
│   │   ├── og/
│   │   │   ├── chat/
│   │   │   │   └── [id]/
│   │   │   │       └── route.tsx
│   │   │   └── x-wrapped/
│   │   │       └── route.tsx
│   │   ├── preferences/
│   │   │   └── route.ts
│   │   ├── proxy-image/
│   │   │   └── route.ts
│   │   ├── raycast/
│   │   │   └── route.ts
│   │   ├── search/
│   │   │   ├── [id]/
│   │   │   │   ├── stop/
│   │   │   │   │   └── route.ts
│   │   │   │   └── stream/
│   │   │   │       └── route.ts
│   │   │   └── route.ts
│   │   ├── suggest/
│   │   │   └── route.ts
│   │   ├── transcribe/
│   │   │   └── route.ts
│   │   ├── upload/
│   │   │   └── route.ts
│   │   ├── x-wrapped/
│   │   │   └── route.ts
│   │   └── xql/
│   │       └── route.ts
│   ├── apps/
│   │   ├── layout.tsx
│   │   └── page.tsx
│   ├── connectors/
│   │   └── [provider]/
│   │       └── callback/
│   │           └── page.tsx
│   ├── error.tsx
│   ├── global-error.tsx
│   ├── globals.css
│   ├── layout.tsx
│   ├── lookout/
│   │   ├── components/
│   │   │   ├── action-buttons.tsx
│   │   │   ├── empty-state.tsx
│   │   │   ├── index.ts
│   │   │   ├── loading-skeleton.tsx
│   │   │   ├── lookout-card.tsx
│   │   │   ├── lookout-details-sidebar.tsx
│   │   │   ├── lookout-form.tsx
│   │   │   ├── pro-upgrade-screen.tsx
│   │   │   ├── run-status-badge.tsx
│   │   │   ├── status-badge.tsx
│   │   │   ├── time-picker.tsx
│   │   │   ├── timezone-selector.tsx
│   │   │   └── warning-card.tsx
│   │   ├── constants.ts
│   │   ├── hooks/
│   │   │   └── use-lookout-form.ts
│   │   ├── layout.tsx
│   │   ├── page.tsx
│   │   └── utils/
│   │       └── time-utils.ts
│   ├── manifest.ts
│   ├── new/
│   │   └── page.tsx
│   ├── not-found.tsx
│   ├── pricing/
│   │   ├── _component/
│   │   │   └── pricing-table.tsx
│   │   └── page.tsx
│   ├── providers.tsx
│   ├── robots.txt
│   ├── search/
│   │   └── [id]/
│   │       ├── loading-old.tsx
│   │       └── page.tsx
│   ├── searches/
│   │   └── page.tsx
│   ├── settings/
│   │   └── page.tsx
│   ├── share/
│   │   └── [id]/
│   │       └── page.tsx
│   ├── success/
│   │   └── page.tsx
│   ├── voice/
│   │   ├── components/
│   │   │   └── pro-upgrade-screen.tsx
│   │   ├── layout.tsx
│   │   └── page.tsx
│   └── xql/
│       └── page.tsx
├── components/
│   ├── InstallPrompt.tsx
│   ├── academic-papers.tsx
│   ├── ai-elements/
│   │   └── web-preview.tsx
│   ├── app-sidebar.tsx
│   ├── auth-card.tsx
│   ├── build-search.tsx
│   ├── canvas-renderer.tsx
│   ├── charts/
│   │   ├── area-chart.tsx
│   │   ├── area.tsx
│   │   ├── bar-chart.tsx
│   │   ├── bar-x-axis.tsx
│   │   ├── bar-y-axis.tsx
│   │   ├── bar.tsx
│   │   ├── chart-context.tsx
│   │   ├── grid.tsx
│   │   ├── line-chart.tsx
│   │   ├── line.tsx
│   │   ├── tooltip/
│   │   │   ├── chart-tooltip.tsx
│   │   │   ├── date-ticker.tsx
│   │   │   ├── index.ts
│   │   │   ├── tooltip-box.tsx
│   │   │   ├── tooltip-content.tsx
│   │   │   ├── tooltip-dot.tsx
│   │   │   └── tooltip-indicator.tsx
│   │   └── x-axis.tsx
│   ├── chat-dialogs.tsx
│   ├── chat-history-dialog.tsx
│   ├── chat-interface.tsx
│   ├── chat-state.ts
│   ├── chat-text-highlighter.tsx
│   ├── client-analytics.tsx
│   ├── connectors-search-results.tsx
│   ├── core/
│   │   ├── border-trail.tsx
│   │   ├── sliding-number.tsx
│   │   ├── text-loop.tsx
│   │   └── text-shimmer.tsx
│   ├── crypto-charts.tsx
│   ├── crypto-coin-data.tsx
│   ├── currency_conv.tsx
│   ├── data-stream-provider.tsx
│   ├── dialogs/
│   │   ├── share-dialog.tsx
│   │   └── use-share-dialog.tsx
│   ├── emails/
│   │   └── lookout-completed.tsx
│   ├── example-categories.tsx
│   ├── extreme-search.tsx
│   ├── file-query-search.tsx
│   ├── flight-tracker.tsx
│   ├── github-search.tsx
│   ├── haptics-provider.tsx
│   ├── icons/
│   │   ├── agent-network-icon.tsx
│   │   ├── apps-icon.tsx
│   │   └── mcp-logo.tsx
│   ├── interactive-charts.tsx
│   ├── interactive-maps.tsx
│   ├── interactive-stock-chart.tsx
│   ├── keyboard-shortcuts-dialog.tsx
│   ├── kibo-ui/
│   │   └── table/
│   │       └── index.tsx
│   ├── list-view.tsx
│   ├── logos/
│   │   ├── elevenlabs-logo.tsx
│   │   ├── exa-logo.tsx
│   │   ├── sarvam-logo.tsx
│   │   ├── scira-logo.tsx
│   │   └── vercel-logo.tsx
│   ├── map-components.tsx
│   ├── markdown.tsx
│   ├── mcp-elicitation-modal.tsx
│   ├── mcp-server-list.tsx
│   ├── memory-dialog.tsx
│   ├── message-parts/
│   │   └── index.tsx
│   ├── message.tsx
│   ├── messages.tsx
│   ├── movie-info.tsx
│   ├── multi-search.tsx
│   ├── nearby-search-map-view.tsx
│   ├── new-chat-hotkey.tsx
│   ├── onchain-crypto-components.tsx
│   ├── place-card.tsx
│   ├── placeholder-image.tsx
│   ├── prediction-search.tsx
│   ├── reasoning-part.tsx
│   ├── reddit-search.tsx
│   ├── retrieve-results.tsx
│   ├── reui/
│   │   ├── stepper.tsx
│   │   └── timeline.tsx
│   ├── scira-logo-header.tsx
│   ├── searches-page.tsx
│   ├── settings/
│   │   └── theme-previews.tsx
│   ├── settings-dialog.tsx
│   ├── share/
│   │   ├── index.tsx
│   │   ├── share-attachments-badge.tsx
│   │   ├── share-button.tsx
│   │   └── share-dialog.tsx
│   ├── share-viewer.tsx
│   ├── sidebar-layout.tsx
│   ├── sign-in-prompt-dialog.tsx
│   ├── spotify-search-results.tsx
│   ├── student-domain-request-button.tsx
│   ├── supported-domains-list.tsx
│   ├── text-translate.tsx
│   ├── theme-switcher.tsx
│   ├── tool-invocation-list-view.tsx
│   ├── trending-tv-movies-results.tsx
│   ├── ui/
│   │   ├── accordion.tsx
│   │   ├── alert-dialog.tsx
│   │   ├── alert.tsx
│   │   ├── animated-beam.tsx
│   │   ├── audio-lines.tsx
│   │   ├── audio-player.tsx
│   │   ├── avatar.tsx
│   │   ├── badge.tsx
│   │   ├── button-group.tsx
│   │   ├── button.tsx
│   │   ├── calendar.tsx
│   │   ├── card.tsx
│   │   ├── carousel.tsx
│   │   ├── chart.tsx
│   │   ├── checkbox.tsx
│   │   ├── collapsible.tsx
│   │   ├── command.tsx
│   │   ├── dialog.tsx
│   │   ├── drawer.tsx
│   │   ├── dropdown-menu.tsx
│   │   ├── empty.tsx
│   │   ├── form-component.tsx
│   │   ├── form.tsx
│   │   ├── grip.tsx
│   │   ├── hover-card.tsx
│   │   ├── hugeicons.tsx
│   │   ├── input-group.tsx
│   │   ├── input.tsx
│   │   ├── kbd.tsx
│   │   ├── kibo-ui/
│   │   │   └── contribution-graph/
│   │   │       └── index.tsx
│   │   ├── label.tsx
│   │   ├── live-waveform.tsx
│   │   ├── loading.tsx
│   │   ├── magic-edit-icon.tsx
│   │   ├── magic-wand-icon.tsx
│   │   ├── matrix.tsx
│   │   ├── model-selector.tsx
│   │   ├── navigation-menu.tsx
│   │   ├── orb.tsx
│   │   ├── popover.tsx
│   │   ├── pro-accordion.tsx
│   │   ├── processor-icon.tsx
│   │   ├── progress-ring.tsx
│   │   ├── progress.tsx
│   │   ├── scroll-area.tsx
│   │   ├── scrub-bar.tsx
│   │   ├── select.tsx
│   │   ├── separator.tsx
│   │   ├── settings.tsx
│   │   ├── sheet.tsx
│   │   ├── sidebar.tsx
│   │   ├── sileo-toaster.tsx
│   │   ├── skeleton.tsx
│   │   ├── sonner.tsx
│   │   ├── spinner.tsx
│   │   ├── switch.tsx
│   │   ├── table.tsx
│   │   ├── tabs.tsx
│   │   ├── text-rotate.tsx
│   │   ├── textarea.tsx
│   │   ├── tooltip.tsx
│   │   ├── transcript-viewer.tsx
│   │   ├── voice-button.tsx
│   │   └── voice-picker.tsx
│   ├── user-cache-status.tsx
│   ├── weather-chart.tsx
│   ├── x-search.tsx
│   ├── xql-pro-upgrade-screen.tsx
│   └── youtube-search-results.tsx
├── components.json
├── contexts/
│   └── user-context.tsx
├── docker-compose.yml
├── drizzle/
│   └── migrations/
│       └── meta/
│           ├── 0000_snapshot.json
│           ├── 0001_snapshot.json
│           ├── 0002_snapshot.json
│           ├── 0003_snapshot.json
│           ├── 0004_snapshot.json
│           ├── 0005_snapshot.json
│           ├── 0006_snapshot.json
│           ├── 0007_snapshot.json
│           ├── 0008_snapshot.json
│           ├── 0009_snapshot.json
│           ├── 0010_snapshot.json
│           ├── 0011_snapshot.json
│           └── _journal.json
├── drizzle.config.ts
├── env/
│   ├── client.ts
│   └── server.ts
├── hooks/
│   ├── use-auto-resume.ts
│   ├── use-cached-user-data.tsx
│   ├── use-chat-prefetch.ts
│   ├── use-github-stars.ts
│   ├── use-local-storage.tsx
│   ├── use-location.ts
│   ├── use-lookouts.ts
│   ├── use-media-query.tsx
│   ├── use-mobile.ts
│   ├── use-optimized-scroll.ts
│   ├── use-synced-preferences.tsx
│   ├── use-transcript-viewer.ts
│   ├── use-usage-data.ts
│   ├── use-user-data.ts
│   ├── use-voice-client.ts
│   └── use-window-size.tsx
├── instrumentation.ts
├── lib/
│   ├── auth-client.ts
│   ├── auth-utils.ts
│   ├── auth.ts
│   ├── better-all.ts
│   ├── canvas/
│   │   ├── catalog.ts
│   │   ├── registry.tsx
│   │   └── renderer.tsx
│   ├── chat-messages.ts
│   ├── connectors.tsx
│   ├── constants.ts
│   ├── db/
│   │   ├── chat-queries.ts
│   │   ├── index.ts
│   │   ├── queries.ts
│   │   └── schema.ts
│   ├── discount.ts
│   ├── email.ts
│   ├── errors.ts
│   ├── mcp/
│   │   ├── auth-headers.ts
│   │   ├── catalog-icons.ts
│   │   ├── crypto.ts
│   │   ├── managed-credentials.ts
│   │   ├── oauth.ts
│   │   └── server-config.ts
│   ├── memory-actions.ts
│   ├── notte.ts
│   ├── parser.ts
│   ├── performance-cache.ts
│   ├── r2.ts
│   ├── rate-limit.ts
│   ├── redis.ts
│   ├── search/
│   │   ├── auto-router.ts
│   │   ├── chat-title.ts
│   │   ├── group-config.ts
│   │   ├── server-helpers.ts
│   │   └── tool-loader.ts
│   ├── search-utils.ts
│   ├── subscription.ts
│   ├── tools/
│   │   ├── academic-search.ts
│   │   ├── build-tools.ts
│   │   ├── code-context.ts
│   │   ├── code-interpreter.ts
│   │   ├── connectors-search.ts
│   │   ├── crypto-tools.ts
│   │   ├── currency-converter.ts
│   │   ├── datetime.ts
│   │   ├── extreme-search.ts
│   │   ├── file-query-search.ts
│   │   ├── flight-tracker.ts
│   │   ├── github-search.ts
│   │   ├── greeting.ts
│   │   ├── index.ts
│   │   ├── map-tools.ts
│   │   ├── mcp-client.ts
│   │   ├── mcp-search.ts
│   │   ├── movie-tv-search.ts
│   │   ├── prediction-search.ts
│   │   ├── reddit-search.ts
│   │   ├── retrieve.ts
│   │   ├── spotify-search.ts
│   │   ├── stock-chart.ts
│   │   ├── supermemory.ts
│   │   ├── text-translate.ts
│   │   ├── trending-movies.ts
│   │   ├── trending-tv.ts
│   │   ├── weather.ts
│   │   ├── web-search.ts
│   │   ├── x-search.ts
│   │   └── youtube-search.ts
│   ├── types.ts
│   ├── user-data-server.ts
│   ├── user-data.ts
│   └── utils.ts
├── next.config.ts
├── package.json
├── postcss.config.mjs
├── proxy.ts
├── public/
│   ├── .well-known/
│   │   └── microsoft-identity-association.json
│   ├── audio-capture-processor.js
│   ├── pcm-processor-worklet.js
│   └── privacy-policy.html
├── sandbox.py
├── tsconfig.json
└── vercel.ts

================================================
FILE CONTENTS
================================================

================================================
FILE: .dockerignore
================================================
Dockerfile
.dockerignore
node_modules
npm-debug.log
README.md
.next
.git

================================================
FILE: .eslintrc.json
================================================
{
  "extends": "next/core-web-vitals"
}


================================================
FILE: .github/FUNDING.yml
================================================
github: zaidmukaddam


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug Report
about: Report a bug or unexpected behavior
title: '[BUG] '
labels: bug
assignees: ''
---

## Bug Description
A clear and concise description of what the bug is.

## Steps to Reproduce
1. Go to '...'
2. Click on '...'
3. Scroll down to '...'
4. See error

## Expected Behavior
A clear and concise description of what you expected to happen.

## Actual Behavior
A clear and concise description of what actually happened.

## Screenshots
If applicable, add screenshots to help explain your problem.

## Environment
- **OS**: [e.g., macOS, Windows, Linux]
- **Browser**: [e.g., Chrome, Safari, Firefox]
- **Version**: [e.g., 22]
- **Device**: [e.g., Desktop, Mobile]

## Additional Context
Add any other context about the problem here (error messages, logs, etc.).

## Possible Solution
If you have suggestions on how to fix the bug, please describe them here.



================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: true
contact_links:
  - name: Question or Discussion
    url: https://github.com/zaidmukaddam/scira/discussions
    about: Ask questions or discuss ideas with the community
  - name: Documentation
    url: https://github.com/zaidmukaddam/scira/blob/main/README.md
    about: Check out the project documentation



================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature Request
about: Suggest an idea or new feature for this project
title: '[FEATURE] '
labels: enhancement
assignees: ''
---

## Feature Description
A clear and concise description of the feature you'd like to see.

## Problem Statement
Is your feature request related to a problem? Please describe.
Example: I'm always frustrated when [...]

## Proposed Solution
A clear and concise description of what you want to happen.

## Alternatives Considered
A clear and concise description of any alternative solutions or features you've considered.

## Use Cases
Describe specific scenarios where this feature would be useful.

## Additional Context
Add any other context, mockups, or screenshots about the feature request here.

## Implementation Ideas
If you have technical suggestions on how this could be implemented, please share them here.



================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
## Description
<!-- Provide a brief description of the changes in this PR -->

## Type of Change
<!-- Mark the relevant option with an "x" -->

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Documentation update
- [ ] Code refactoring
- [ ] Performance improvement
- [ ] Dependency update

## Related Issues
<!-- Link to related issues using #issue_number -->
Closes #

## Changes Made
<!-- List the specific changes made in this PR -->

- 
- 
- 

## Testing
<!-- Describe the tests you ran to verify your changes -->

- [ ] Tested locally
- [ ] Added/updated unit tests
- [ ] Added/updated integration tests
- [ ] All tests pass

### Test Environment
- **OS**: 
- **Browser**: 
- **Node Version**: 

## Screenshots
<!-- If applicable, add screenshots to demonstrate the changes -->

## Checklist
<!-- Mark completed items with an "x" -->

- [ ] My code follows the project's style guidelines
- [ ] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings or errors
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published

## Additional Notes
<!-- Add any additional notes or context about the PR here -->



================================================
FILE: .gitignore
================================================
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem
__pycache__/
*.pyc

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# env files
.env*.local
.env

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts

certificates
creds.ts

# local SQL scripts
*.sql


# IDE / AI tools
.cursor/
.codex/
.claude/
.opencode/
.agents/

video/node_modules

================================================
FILE: .prettierrc
================================================
{
  "semi": true,
  "singleQuote": true,
  "trailingComma": "all",
  "printWidth": 120,
  "tabWidth": 2,
  "useTabs": false
}


================================================
FILE: .vercelignore
================================================
.codex
.codex
.cursor
.opencode
.claude
.vscode
add_dodo_indexes.sql
reindex_tables.sql
create_indexes.sql
sandbox.py
vercel_old.json
creds.ts

================================================
FILE: .vscode/settings.json
================================================
{
  "typescript.tsdk": "node_modules/typescript/lib"
}


================================================
FILE: Dockerfile
================================================
# syntax=docker.io/docker/dockerfile:1

# Base image: Using Node.js 22 with Alpine Linux for a minimal footprint
FROM node:22-alpine AS base

# Stage 1: Dependencies
# This stage is responsible for installing all npm dependencies
FROM base AS deps
# Installing libc6-compat for Alpine Linux compatibility with certain Node.js packages
# Required for some npm packages that have native dependencies
RUN apk add --no-cache libc6-compat

WORKDIR /app

# Copy package files and install dependencies using pnpm
# pnpm is used for faster and more efficient package management
COPY package.json pnpm-lock.yaml* ./
RUN corepack enable pnpm && pnpm i;

# Stage 2: Building the application
# This stage builds the Next.js application
FROM base AS builder
WORKDIR /app
# Copy node_modules from deps stage
COPY --from=deps /app/node_modules ./node_modules
# Copy all source files
COPY . .
# Copy environment variables for build configuration
COPY .env .env
# Build the Next.js application
RUN npm run build

# Stage 3: Production runtime
# Final stage that runs the application
FROM base AS runner
LABEL org.opencontainers.image.name="scira.app"
WORKDIR /app

# Set production environment
ENV NODE_ENV=production

# Create a non-root user for security
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

# Copy only the necessary files for running the application
# Static files for serving
COPY --from=builder /app/public ./public

# Copy the standalone build output and static files
# Using Next.js output tracing to minimize the final image size
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

# Switch to non-root user for security
USER nextjs

# Expose the port the app runs on
EXPOSE 3000

# Configure the server
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"

# Start the Next.js application
CMD ["node", "server.js"]


================================================
FILE: LICENSE
================================================
                    GNU AFFERO GENERAL PUBLIC LICENSE
                       Version 3, 19 November 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.

  A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate.  Many developers of free software are heartened and
encouraged by the resulting cooperation.  However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.

  The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community.  It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server.  Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.

  An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals.  This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU Affero General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Remote Network Interaction; Use with the GNU General Public License.

  Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software.  This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time.  Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    Scira
    Copyright (C) 2024-present Zaid Mukaddam

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

  If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source.  For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code.  There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.

  You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<https://www.gnu.org/licenses/>.


================================================
FILE: README.md
================================================
# Scira

Research at the speed of thought. The agentic research platform that plans, retrieves, and cites — so you can think faster.

<a href="https://vercel.com/oss">
  <img alt="Vercel OSS Program" src="https://vercel.com/oss/program-badge.svg" />
</a>

<br />

![Scira](/app/opengraph-image.png)

<br />

🔗 **[Try Scira at scira.ai](https://scira.ai)**

[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/zaidmukaddam/scira)

## Powered By

<div align="center">

|          [Vercel AI SDK](https://sdk.vercel.ai/docs)          |                [Exa AI](https://exa.ai)                |             [Upstash](https://upstash.com)              |
| :-----------------------------------------------------------: | :----------------------------------------------------: | :-----------------------------------------------------: |
| <img src="/public/one.svg" alt="Vercel AI SDK" height="40" /> | <img src="/public/exa.png" alt="Exa AI" height="40" /> | <img src="/public/upstash.svg" alt="Upstash" height="40" /> |
|            For AI model integration and streaming             |          For web search and content retrieval          |        For serverless Redis and rate limiting           |

</div>

## Special Thanks

<div align="center" markdown="1">

[![Warp](https://github.com/user-attachments/assets/2bda420d-4211-4900-a37e-e3c7056d799c)](https://www.warp.dev/?utm_source=github&utm_medium=referral&utm_campaign=scira)<br>

### **[Warp, the intelligent terminal](https://www.warp.dev/?utm_source=github&utm_medium=referral&utm_campaign=scira)**<br>

[Available for MacOS, Linux, & Windows](https://www.warp.dev/?utm_source=github&utm_medium=referral&utm_campaign=scira)<br>
[Visit warp.dev to learn more](https://www.warp.dev/?utm_source=github&utm_medium=referral&utm_campaign=scira)

</div>

## How It Works

1. **Ask anything** — Type a question, upload a PDF, or paste a URL. Pick a mode or let Scira decide for you.
2. **Scira plans & retrieves** — The agent breaks your question into sub-tasks, searches live sources, and cross-checks the evidence.
3. **Get cited answers** — Receive a grounded answer with inline citations. Click any source to verify it yourself.

## Features

### Core Capabilities

- **Agentic Planning** — Breaks complex questions into steps, selects the right models and tools, then executes multi-step workflows end to end
- **Grounded Retrieval** — Every answer comes with inline citations you can click to audit the evidence yourself
- **Extensible & Open** — AGPL-3.0 licensed. Self-host, bring your own models, connect custom tools, and tailor everything to your workflow
- **Lookouts** — Schedule recurring research agents that monitor topics, track changes, and email you updates

### Search Modes (17 modes)

| Mode | Description |
|---|---|
| **Web** | Search the entire web with AI-powered analysis |
| **Chat** | Talk to the model directly, no search |
| **X** | Real-time posts, trends, and conversations |
| **Stocks** | Market data, charts, and financial analysis |
| **Code** | Get context about languages and frameworks |
| **Academic** | Research papers, citations, and scholarly sources |
| **Extreme** | Deep research with multiple sources and analysis |
| **Reddit** | Discussions, opinions, and community insights |
| **GitHub** | Repositories, code, and developer discussions |
| **Crypto** | Cryptocurrency research powered by CoinGecko |
| **Prediction** | Prediction markets from Polymarket and Kalshi |
| **YouTube** | Video summaries, transcripts, and analysis |
| **Spotify** | Search songs, artists, and albums |
| **Connectors** | Search Google Drive, Notion & OneDrive *(Pro)* |
| **Memory** | Your personal memory companion *(Pro)* |
| **Voice** | Conversational AI with real-time voice *(Pro)* |
| **XQL** | Advanced X query language for tweet analysis *(Pro)* |

### Tools (28 tools)

#### Search & Retrieval
- **Web search** — Multi-query parallel web search with deduplication using Exa, Firecrawl, Parallel, and Tavily
- **Extreme search** — LLM-driven deep research agent with multi-step planning, code execution, and R2 artifact storage
- **Academic search** — Search academic papers and research using Exa and Firecrawl
- **Reddit search** — Search Reddit with configurable time ranges using Parallel
- **X search** — Search X posts with date range filtering and handle inclusion/exclusion using xAI Grok
- **YouTube search** — Search videos, channels, playlists with transcript extraction using Supadata
- **GitHub search** — Search repositories with structured metadata extraction using Firecrawl
- **Spotify search** — Search tracks, artists, albums, and playlists via Spotify Web API
- **URL content retrieval** — Extract content from any URL including tweets, YouTube, TikTok, and Instagram

#### Financial & Market Data
- **Stock charts** — Interactive stock charts with OHLC data, earnings, and news using Valyu, Tavily, and Exa
- **Currency converter** — Forex and crypto conversion with real-time rates using Valyu
- **Crypto tools** — Cryptocurrency data, contract lookups, and OHLC charts using CoinGecko
- **Prediction markets** — Query Polymarket and Kalshi data with Cohere reranking using Valyu

#### Location & Travel
- **Weather** — Current weather, 5-day forecast, air quality, and 16-day extended forecast using OpenWeatherMap and Open-Meteo
- **Maps & geocoding** — Forward/reverse geocoding and nearby place discovery using Google Maps API
- **Flight tracking** — Real-time flight status with departure/arrival details

#### Media & Entertainment
- **Movie/TV search** — Search movies and TV shows with detailed cast, ratings, and metadata using TMDB
- **Trending movies** — Today's trending movies from TMDB
- **Trending TV shows** — Today's trending TV shows from TMDB

#### Productivity & Utilities
- **Code interpreter** — Write and execute Python code in a sandboxed Daytona environment with chart generation
- **Code context** — Get contextual information about programming topics using Exa Context API
- **Text translation** — Translate text (and text within images) between languages using AI models
- **File query search** — Semantic search over uploaded files (PDF, CSV, DOCX, Excel) with Cohere embeddings and reranking
- **Connectors search** — Search connected Google Drive, Notion, and OneDrive using Supermemory
- **Memory tools** — Save and search personal memories using Supermemory
- **Date & time** — Current date/time in multiple formats with timezone support
- **Greeting** — Personalized time-of-day-aware greetings

## LLM Models Supported

- **xAI**: Grok 3, Grok 3 Mini, Grok 4, Grok 4 Fast, Grok 4.1 Fast, Grok Code
- **OpenAI**: GPT 4.1 (Nano/Mini/Standard), GPT 5 (Nano/Mini/Medium/Standard), GPT 5.1 (Instant/Thinking/Codex), GPT 5.2 (Instant/Thinking/Codex), o3, o4 mini, GPT OSS 20B/120B
- **Anthropic**: Claude Haiku 4.5, Claude Sonnet 4.5, Claude 4.5 Opus, Claude 4.6 Opus
- **Google**: Gemini 2.5 Flash (Lite/Standard), Gemini 2.5 Pro, Gemini 3 Flash, Gemini 3 Pro
- **Alibaba (Qwen)**: Qwen 3 (4B/32B/235B), Qwen 3 VL, Qwen 3 Max, Qwen 3 Coder (Small/Standard/Plus/Next), Qwen 3 Next 80B
- **Mistral**: Ministral 3 (3B/8B/14B), Mistral Large 3, Mistral Medium, Magistral (Small/Medium), Devstral 2 (Small/Standard)
- **DeepSeek**: DeepSeek v3, v3.1 Terminus, v3.2, R1, R1 0528
- **Zhipu (GLM)**: GLM 4.5, GLM 4.5 Air, GLM 4.6, GLM 4.6V, GLM 4.7, GLM 4.7 Flash
- **Cohere**: Command A, Command A Thinking
- **MoonShot**: Kimi K2, Kimi K2.5
- **Minimax**: M1 80K, M2, M2.1, M2.1 Lightning
- **ByteDance**: Seed 1.6, Seed 1.6 Flash, Seed 1.8
- **Arcee**: Trinity Mini, Trinity Large
- **Others**: Vercel v0 (1.0/1.5), Amazon Nova 2 Lite, Xiaomi Mimo V2 Flash, StepFun Step 3.5 Flash, Kwaipilot KAT-Coder-Pro V1

## Built with

- [Next.js](https://nextjs.org/) - React framework
- [Tailwind CSS](https://tailwindcss.com/) - Styling
- [Vercel AI SDK](https://sdk.vercel.ai/docs) - AI model integration and streaming
- [Shadcn/UI](https://ui.shadcn.com/) - UI components
- [Exa.AI](https://exa.ai/) - Web search, academic search, and content retrieval
- [Firecrawl](https://firecrawl.dev/) - Web scraping with structured extraction
- [Parallel](https://parallel.ai/) - Web and Reddit search
- [Tavily](https://tavily.com/) - Web search and financial news
- [Valyu](https://valyu.network/) - Financial data, forex, and prediction markets
- [Supadata](https://supadata.ai/) - YouTube search, transcripts, and social media
- [CoinGecko](https://www.coingecko.com/) - Cryptocurrency market data
- [Spotify](https://developer.spotify.com/) - Music search
- [OpenWeatherMap](https://openweathermap.org/) - Weather data
- [Open-Meteo](https://open-meteo.com/) - Extended forecasts and geocoding
- [Daytona](https://daytona.io/) - Code execution sandbox
- [Google Maps](https://developers.google.com/maps) - Geocoding and places
- [TMDB](https://www.themoviedb.org/) - Movie and TV data
- [Cohere](https://cohere.com/) - Embeddings and reranking
- [Supermemory](https://supermemory.ai/) - Memory management and connector search
- [Upstash](https://upstash.com/) - Serverless Redis and rate limiting
- [Cloudflare R2](https://www.cloudflare.com/r2/) - Object storage for artifacts
- [ElevenLabs](https://elevenlabs.io/) - Voice synthesis
- [Better Auth](https://github.com/better-auth/better-auth) - Authentication
- [Drizzle ORM](https://orm.drizzle.team/) - Database management
- [Novita AI](https://novita.ai) - AI Inference

### Deploy your own

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fzaidmukaddam%2Fscira&env=XAI_API_KEY,OPENAI_API_KEY,ANTHROPIC_API_KEY,GROQ_API_KEY,GOOGLE_GENERATIVE_AI_API_KEY,DAYTONA_API_KEY,DATABASE_URL,BETTER_AUTH_SECRET,GITHUB_CLIENT_ID,GITHUB_CLIENT_SECRET,GOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRET,TWITTER_CLIENT_ID,TWITTER_CLIENT_SECRET,REDIS_URL,ELEVENLABS_API_KEY,TAVILY_API_KEY,EXA_API_KEY,SUPADATA_API_KEY,TMDB_API_KEY,YT_ENDPOINT,FIRECRAWL_API_KEY,OPENWEATHER_API_KEY,GOOGLE_MAPS_API_KEY,MAPBOX_ACCESS_TOKEN,AVIATION_STACK_API_KEY,CRON_SECRET,BLOB_READ_WRITE_TOKEN,MEM0_API_KEY,MEM0_ORG_ID,MEM0_PROJECT_ID,SMITHERY_API_KEY,NEXT_PUBLIC_MAPBOX_TOKEN,NEXT_PUBLIC_POSTHOG_KEY,NEXT_PUBLIC_POSTHOG_HOST,NEXT_PUBLIC_SCIRA_PUBLIC_API_KEY,SCIRA_API_KEY&envDescription=API%20keys%20and%20configuration%20required%20for%20Scira%20to%20function)

## Set Scira as your default search engine

1. **Open the Chrome browser settings**:
   - Click on the three vertical dots in the upper right corner of the browser.
   - Select "Settings" from the dropdown menu.

2. **Go to the search engine settings**:
   - In the left sidebar, click on "Search engine."
   - Then select "Manage search engines and site search."

3. **Add a new search engine**:
   - Click on "Add" next to "Site search."

4. **Set the search engine name**:
   - Enter `Scira` in the "Search engine" field.

5. **Set the search engine URL**:
   - Enter `https://scira.ai?q=%s` in the "URL with %s in place of query" field.

6. **Set the search engine shortcut**:
   - Enter `sh` in the "Shortcut" field.

7. **Set Default**:
   - Click on the three dots next to the search engine you just added.
   - Select "Make default" from the dropdown menu.

After completing these steps, you should be able to use Scira as your default search engine in Chrome.

### Local development

#### Run via Docker

The application can be run using Docker in two ways:

##### Using Docker Compose (Recommended)

1. Make sure you have Docker and Docker Compose installed on your system
2. Create a `.env` file based on `.env.example` with your API keys
3. Run the following command in the project root:
   ```bash
   docker compose up
   ```
4. The application will be available at `http://localhost:3000`

##### Using Docker Directly

1. Create a `.env` file based on `.env.example` with your API keys
2. Build the Docker image:
   ```bash
   docker build -t scira.app .
   ```
3. Run the container:
   ```bash
   docker run --env-file .env -p 3000:3000 scira.app
   ```

The application uses a multi-stage build process to minimize the final image size and implements security best practices. The production image runs on Node.js LTS with Alpine Linux for a minimal footprint.

#### Run with Node.js

To run the application locally without Docker:

1. Sign up for accounts with the required AI providers:
   - OpenAI (required)
   - Anthropic (required)
   - Exa (required for web search feature)
2. Copy `.env.example` to `.env.local` and fill in your API keys
3. Install dependencies:
   ```bash
   pnpm install
   ```
4. Start the development server:
   ```bash
   pnpm dev
   ```
5. Open `http://localhost:3000` in your browser

# License

This project is licensed under the AGPLv3 License - see the [LICENSE](LICENSE) file for details.


================================================
FILE: ai/models.ts
================================================
// Pure model data and helper functions — no server SDK imports
interface ModelParameters {
  temperature?: number;
  topP?: number;
  topK?: number;
  minP?: number;
  frequencyPenalty?: number;
  presencePenalty?: number;
  maxOutputTokens?: number;
}

// Provider definitions for model categorization
export type ModelProvider =
  | 'scira'
  | 'xai'
  | 'openai'
  | 'anthropic'
  | 'google'
  | 'alibaba'
  | 'mistral'
  | 'deepseek'
  | 'zhipu'
  | 'cohere'
  | 'moonshot'
  | 'minimax'
  | 'bytedance'
  | 'arcee'
  | 'vercel'
  | 'amazon'
  | 'xiaomi'
  | 'kwaipilot'
  | 'stepfun'
  | 'sarvam'
  | 'inception'
  | 'nvidia';

export interface ProviderInfo {
  id: ModelProvider;
  name: string;
  icon: string; // SVG path or icon identifier
  hasNew?: boolean;
}

export const PROVIDERS: Record<ModelProvider, ProviderInfo> = {
  scira: { id: 'scira', name: 'Scira', icon: 'scira' },
  xai: { id: 'xai', name: 'xAI', icon: 'xai', hasNew: true },
  openai: { id: 'openai', name: 'OpenAI', icon: 'openai', hasNew: true },
  anthropic: { id: 'anthropic', name: 'Anthropic', icon: 'anthropic', hasNew: true },
  google: { id: 'google', name: 'Google', icon: 'google', hasNew: true },
  alibaba: { id: 'alibaba', name: 'Alibaba', icon: 'alibaba', hasNew: true },
  zhipu: { id: 'zhipu', name: 'Zhipu AI', icon: 'zhipu' },
  minimax: { id: 'minimax', name: 'Minimax', icon: 'minimax', hasNew: true },
  deepseek: { id: 'deepseek', name: 'DeepSeek', icon: 'deepseek' },
  moonshot: { id: 'moonshot', name: 'MoonShot', icon: 'moonshot' },
  cohere: { id: 'cohere', name: 'Cohere', icon: 'cohere' },
  bytedance: { id: 'bytedance', name: 'ByteDance', icon: 'bytedance', hasNew: true },
  mistral: { id: 'mistral', name: 'Mistral', icon: 'mistral', hasNew: true },
  arcee: { id: 'arcee', name: 'Arcee', icon: 'arcee' },
  vercel: { id: 'vercel', name: 'Vercel', icon: 'vercel' },
  amazon: { id: 'amazon', name: 'Amazon', icon: 'amazon' },
  xiaomi: { id: 'xiaomi', name: 'Xiaomi', icon: 'xiaomi' },
  kwaipilot: { id: 'kwaipilot', name: 'Kwaipilot', icon: 'kwaipilot' },
  stepfun: { id: 'stepfun', name: 'StepFun', icon: 'stepfun' },
  sarvam: { id: 'sarvam', name: 'Sarvam', icon: 'sarvam', hasNew: true },
  inception: { id: 'inception', name: 'Inception', icon: 'inception', hasNew: true },
  nvidia: { id: 'nvidia', name: 'NVIDIA', icon: 'nvidia', hasNew: true },
};

export interface Model {
  value: string;
  label: string;
  description: string;
  vision: boolean;
  reasoning: boolean;
  experimental: boolean;
  category: string;
  pdf: boolean;
  pro: boolean;
  max?: boolean; // Requires Max plan (superset of Pro)
  requiresAuth: boolean;
  freeUnlimited: boolean;
  maxOutputTokens: number;
  extreme?: boolean;
  fast?: boolean;
  isNew?: boolean;
  parameters?: ModelParameters;
  provider?: ModelProvider; // Optional - will be derived if not specified
}

export const models: Model[] = [
  {
    value: 'scira-auto',
    label: 'Auto',
    description: 'Automatically routes your query to the best model',
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    provider: 'scira',
  },
  // Models (xAI)
  {
    value: 'scira-grok-3-mini',
    label: 'Grok 3 Mini',
    description: "xAI's recent smallest LLM",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    provider: 'xai',
  },
  {
    value: 'scira-grok-3',
    label: 'Grok 3',
    description: "xAI's recent smartest LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    provider: 'xai',
  },
  {
    // grok-4.20-multi-agent-beta-latest
    value: 'grok-4.20-multi-agent-beta-latest',
    label: 'Grok 4.20 Multi Agent Beta',
    description: "xAI's experimental beta multi-agent model",
    vision: true,
    reasoning: true,
    experimental: true,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 30000,
    isNew: true,
    provider: 'xai',
  },
  {
    value: 'scira-grok-4',
    label: 'Grok 4',
    description: "xAI's most intelligent LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    provider: 'xai',
  },
  {
    value: 'scira-grok-4.20-experimental-beta-0304',
    label: 'Grok 4.20 Beta',
    description: "xAI's experimental beta chat model",
    vision: true,
    reasoning: false,
    experimental: true,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 30000,
    isNew: true,
    provider: 'xai',
  },
  {
    value: 'scira-grok-4.20-experimental-beta-0304-thinking',
    label: 'Grok 4.20 Beta Thinking',
    description: "xAI's experimental beta reasoning model",
    vision: true,
    reasoning: true,
    experimental: true,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 30000,
    isNew: true,
    provider: 'xai',
  },
  {
    value: 'scira-default',
    label: 'Grok 4.1 Fast',
    description: "xAI's greatest and fastest multimodel LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Free',
    pdf: false,
    pro: false,
    requiresAuth: false,
    freeUnlimited: false,
    maxOutputTokens: 30000,
    extreme: true,
    fast: true,
    isNew: true,
    provider: 'xai',
  },
  {
    value: 'scira-sarvam-105b',
    label: 'Sarvam 105B',
    description: "Sarvam's flagship model for chat and reasoning",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    provider: 'sarvam',
    parameters: {
      temperature: 0.5,
    },
  },
  {
    value: 'scira-grok4.1-fast-thinking',
    label: 'Grok 4.1 Fast Thinking',
    description: "xAI's greatest and fastest multimodel reasoning LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 30000,
    extreme: true,
    fast: true,
    isNew: true,
    provider: 'xai',
  },
  {
    value: 'scira-grok-4-fast',
    label: 'Grok 4 Fast',
    description: "xAI's previous fastest multimodel LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 30000,
    extreme: true,
    fast: true,
    isNew: false,
    provider: 'xai',
  },
  {
    value: 'scira-grok-4-fast-think',
    label: 'Grok 4 Fast Thinking',
    description: "xAI's previous fastest multimodel reasoning LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 30000,
    extreme: true,
    fast: true,
    isNew: false,
    parameters: {
      maxOutputTokens: 30000,
    },
    provider: 'xai',
  },
  {
    value: 'scira-code',
    label: 'Grok Code',
    description: "xAI's advanced coding LLM",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    fast: true,
    provider: 'xai',
  },
  {
    value: 'scira-seed-2.0-mini',
    label: 'Seed 2.0 Mini',
    description: "ByteDance's compact and efficient reasoning model",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    fast: true,
    provider: 'bytedance',
  },
  {
    value: 'scira-seed-2.0-lite',
    label: 'Seed 2.0 Lite',
    description: "ByteDance's lightweight vision model",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    fast: true,
    provider: 'bytedance',
  },
  {
    value: 'scira-seed-1.6',
    label: 'Seed 1.6',
    description: "ByteDance's recent reasoning model",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    provider: 'bytedance',
  },
  {
    value: 'scira-seed-1.8',
    label: 'Seed 1.8',
    description: "ByteDance's latest reasoning model",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: false,
    provider: 'bytedance',
  },
  {
    value: 'scira-seed-1.6-flash',
    label: 'Seed 1.6 Flash',
    description: "ByteDance's fast vision reasoning model",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    fast: true,
    provider: 'bytedance',
  },
  {
    value: 'scira-qwen-32b',
    label: 'Qwen 3 32B',
    description: "Alibaba's base LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Free',
    pdf: false,
    pro: false,
    requiresAuth: false,
    freeUnlimited: false,
    maxOutputTokens: 40960,
    fast: true,
    parameters: {
      temperature: 0.7,
      topP: 0.8,
      topK: 20,
      minP: 0,
    },
    provider: 'alibaba',
  },
  {
    value: 'scira-qwen-32b-thinking',
    label: 'Qwen 3 32B Thinking',
    description: "Alibaba's base reasoning LLM",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Free',
    pdf: false,
    pro: false,
    requiresAuth: false,
    freeUnlimited: false,
    maxOutputTokens: 40960,
    fast: true,
    parameters: {
      temperature: 0.6,
      topP: 0.95,
      topK: 20,
      minP: 0,
    },
    provider: 'alibaba',
  },
  {
    value: 'scira-nemotron-3-super',
    label: 'Nemotron 3 Super',
    description: "NVIDIA's powerful Nemotron 3 model",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Free',
    pdf: false,
    pro: false,
    requiresAuth: false,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    provider: 'nvidia',
  },
  {
    value: 'scira-qwen-4b',
    label: 'Qwen 3 4B',
    description: "Alibaba's small base LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Free',
    pdf: false,
    pro: false,
    requiresAuth: false,
    maxOutputTokens: 16000,
    freeUnlimited: false,
    parameters: {
      temperature: 0.7,
      topP: 0.8,
      topK: 20,
      minP: 0,
    },
    provider: 'alibaba',
  },
  {
    value: 'scira-qwen-4b-thinking',
    label: 'Qwen 3 4B Thinking',
    description: "Alibaba's small base LLM",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Free',
    pdf: false,
    pro: false,
    requiresAuth: true,
    maxOutputTokens: 16000,
    freeUnlimited: false,
    parameters: {
      temperature: 0.6,
      topP: 0.95,
      topK: 20,
      minP: 0,
    },
    provider: 'alibaba',
  },
  {
    value: 'scira-gpt-oss-20',
    label: 'GPT OSS 20B',
    description: "OpenAI's small OSS LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Free',
    pdf: false,
    pro: false,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    fast: true,
    provider: 'openai',
  },
  {
    value: 'scira-gpt5-nano',
    label: 'GPT 5 Nano',
    description: "OpenAI's smallest flagship LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Free',
    pdf: true,
    pro: false,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    extreme: true,
    fast: true,
    provider: 'openai',
  },
  {
    value: 'scira-google-lite',
    label: 'Gemini 2.5 Flash Lite',
    description: "Google's advanced small LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Free',
    pdf: true,
    pro: false,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 10000,
    extreme: true,
    isNew: false,
    provider: 'google',
  },
  {
    value: 'scira-ministral-3b',
    label: 'Ministral 3 3B',
    description: "Mistral's mini-model 3B multi-modal LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Free',
    pdf: true,
    pro: false,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    provider: 'mistral',
  },
  {
    value: 'scira-ministral-8b',
    label: 'Ministral 3 8B',
    description: "Mistral's mini-model 8B multi-modal LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Free',
    pdf: true,
    pro: false,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    provider: 'mistral',
  },
  {
    value: 'scira-devstral',
    label: 'Devstral 2',
    description: "Mistral's coding-focused LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Free',
    pdf: true,
    pro: false,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    provider: 'mistral',
  },
  {
    value: 'scira-devstral-small',
    label: 'Devstral Small 2',
    description: "Mistral's small coding-focused LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Free',
    pdf: true,
    pro: false,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    provider: 'mistral',
  },
  {
    value: 'scira-ministral-14b',
    label: 'Ministral 3 14B',
    description: "Mistral's mini-model 14B multi-modal LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    provider: 'mistral',
  },
  {
    value: 'scira-mistral-large',
    label: 'Mistral Large 3',
    description: "Mistral's latest and greatest large multi-modal LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    provider: 'mistral',
  },
  {
    value: 'scira-mistral-medium',
    label: 'Mistral Medium',
    description: "Mistral's medium multi-modal LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: false,
    provider: 'mistral',
  },
  {
    value: 'scira-magistral-small',
    label: 'Magistral Small',
    description: "Mistral's small reasoning LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: false,
    provider: 'mistral',
  },
  {
    value: 'scira-magistral-medium',
    label: 'Magistral Medium',
    description: "Mistral's medium reasoning LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: false,
    provider: 'mistral',
  },
  {
    value: 'scira-mistral-small',
    label: 'Mistral Small 4',
    description: "Mistral's small efficient model",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Free',
    pdf: false,
    pro: false,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    provider: 'mistral',
  },
  {
    value: 'scira-mistral-small-think',
    label: 'Mistral Small 4 Thinking',
    description: "Mistral's small model with reasoning mode enabled",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Free',
    pdf: false,
    pro: false,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    provider: 'mistral',
  },
  {
    value: 'scira-leanstral',
    label: 'Leanstral',
    description: "Mistral's lean and efficient small model",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Free',
    pdf: false,
    pro: false,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    provider: 'mistral',
  },
  {
    value: 'scira-trinity-mini',
    label: 'Trinity Mini',
    description: "Arcee's small reasoning LLM",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: false,
    parameters: {
      temperature: 0.15,
      topK: 50,
      topP: 0.75,
      minP: 0.06,
    },
    provider: 'arcee',
  },
  {
    value: 'scira-trinity-large',
    label: 'Trinity Large',
    description: "Arcee's large reasoning LLM via OpenRouter",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Free',
    pdf: false,
    pro: false,
    requiresAuth: false,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    parameters: {
      temperature: 0.15,
      topK: 50,
      topP: 0.75,
      minP: 0.06,
    },
    provider: 'arcee',
  },
  {
    value: 'scira-gpt-oss-120',
    label: 'GPT OSS 120B',
    description: "OpenAI's advanced OSS LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    fast: true,
    provider: 'openai',
  },
  {
    value: 'scira-gpt-4.1-nano',
    label: 'GPT 4.1 Nano',
    description: "OpenAI's smallest LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Free',
    pdf: true,
    pro: false,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    extreme: true,
    fast: true,
    provider: 'openai',
  },
  {
    value: 'scira-gpt-4.1-mini',
    label: 'GPT 4.1 Mini',
    description: "OpenAI's small LLM",
    vision: true,
    reasoning: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    fast: true,
    extreme: true,
    experimental: false,
    provider: 'openai',
  },
  {
    value: 'scira-gpt-4.1',
    label: 'GPT 4.1',
    description: "OpenAI's LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    extreme: true,
    fast: false,
    isNew: false,
    provider: 'openai',
  },
  {
    value: 'scira-gpt-5.1',
    label: 'GPT 5.1 Instant',
    description: "OpenAI's fast and smart LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    extreme: true,
    fast: false,
    isNew: false,
    provider: 'openai',
  },
  {
    value: 'scira-gpt-5.1-thinking',
    label: 'GPT 5.1 Thinking',
    description: "OpenAI's recent and smart reasoning LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    extreme: true,
    fast: false,
    isNew: false,
    provider: 'openai',
  },
  {
    value: 'scira-gpt-5.2',
    label: 'GPT 5.2 Instant',
    description: "OpenAI's latest and greatest LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    extreme: true,
    fast: false,
    isNew: false,
    provider: 'openai',
  },
  {
    value: 'scira-gpt-5.3-chat-latest',
    label: 'GPT 5.3 Instant',
    description: "OpenAI's latest chat-optimized LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    extreme: true,
    fast: false,
    isNew: true,
    provider: 'openai',
  },
  {
    value: 'scira-gpt-5.4',
    label: 'GPT 5.4 Instant',
    description: "OpenAI's latest and greatest LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    extreme: true,
    fast: false,
    isNew: true,
    provider: 'openai',
  },
  {
    value: 'scira-gpt-5.4-mini',
    label: 'GPT 5.4 Mini',
    description: "OpenAI's small GPT 5.4 model",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Free',
    pdf: true,
    pro: false,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    extreme: true,
    fast: true,
    isNew: true,
    provider: 'openai',
  },
  {
    value: 'scira-gpt-5.4-nano',
    label: 'GPT 5.4 Nano',
    description: "OpenAI's smallest GPT 5.4 model",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Free',
    pdf: true,
    pro: false,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    extreme: true,
    fast: true,
    isNew: true,
    provider: 'openai',
  },
  {
    value: 'scira-gpt-5.4-thinking',
    label: 'GPT 5.4 Thinking',
    description: "OpenAI's latest and greatest reasoning LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    extreme: true,
    fast: false,
    isNew: true,
    provider: 'openai',
  },
  {
    value: 'scira-gpt-5.4-thinking-xhigh',
    label: 'GPT 5.4 Thinking XHigh',
    description: "OpenAI's latest and greatest reasoning LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    extreme: true,
    fast: false,
    isNew: true,
    provider: 'openai',
  },
  {
    value: 'scira-gpt-5.2-thinking',
    label: 'GPT 5.2 Thinking',
    description: "OpenAI's latest and greatest reasoning LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    extreme: true,
    fast: false,
    isNew: false,
    provider: 'openai',
  },
  {
    value: 'scira-gpt-5.2-thinking-xhigh',
    label: 'GPT 5.2 Thinking XHigh',
    description: "OpenAI's latest and greatest reasoning LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    extreme: true,
    fast: false,
    isNew: false,
    provider: 'openai',
  },
  {
    value: 'scira-gpt5-mini',
    label: 'GPT 5 Mini',
    description: "OpenAI's small flagship LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    extreme: true,
    fast: false,
    isNew: false,
    provider: 'openai',
  },
  {
    value: 'scira-gpt5',
    label: 'GPT 5',
    description: "OpenAI's flagship LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    extreme: true,
    fast: false,
    isNew: false,
    provider: 'openai',
  },
  {
    value: 'scira-o4-mini',
    label: 'o4 mini',
    description: "OpenAI's recent mini reasoning LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    fast: false,
    isNew: false,
    provider: 'openai',
  },
  {
    value: 'scira-o3',
    label: 'o3',
    description: "OpenAI's advanced LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    fast: false,
    isNew: false,
    provider: 'openai',
  },
  {
    value: 'scira-gpt5-medium',
    label: 'GPT 5 Medium',
    description: "OpenAI's latest flagship reasoning LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    extreme: true,
    fast: false,
    isNew: false,
    provider: 'openai',
  },
  {
    value: 'scira-gpt-5.1-codex',
    label: 'GPT 5.1 Codex',
    description: "OpenAI's advanced coding LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    extreme: true,
    fast: false,
    isNew: false,
    provider: 'openai',
  },
  {
    value: 'scira-gpt-5.1-codex-mini',
    label: 'GPT 5.1 Codex Mini',
    description: "OpenAI's advanced coding LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    extreme: true,
    fast: false,
    isNew: false,
    provider: 'openai',
  },
  {
    value: 'scira-gpt-5.1-codex-max',
    label: 'GPT 5.1 Codex Max',
    description: "OpenAI's advanced coding LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    extreme: true,
    fast: false,
    isNew: false,
    provider: 'openai',
  },
  {
    value: 'scira-gpt-5.2-codex',
    label: 'GPT 5.2 Codex',
    description: "OpenAI's latest advanced coding LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    extreme: true,
    fast: false,
    isNew: false,
    provider: 'openai',
  },
  {
    value: 'scira-gpt-5.3-codex',
    label: 'GPT 5.3 Codex',
    description: "OpenAI's latest advanced coding LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    extreme: true,
    fast: false,
    isNew: true,
    provider: 'openai',
  },
  {
    value: 'scira-gpt5-codex',
    label: 'GPT 5 Codex',
    description: "OpenAI's advanced coding LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    extreme: true,
    fast: false,
    isNew: false,
    provider: 'openai',
  },
  {
    value: 'scira-cmd-a',
    label: 'Command A',
    description: "Cohere's advanced command LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: false,
    provider: 'cohere',
  },
  {
    value: 'scira-cmd-a-think',
    label: 'Command A Thinking',
    description: "Cohere's advanced command LLM with thinking",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    provider: 'cohere',
  },
  {
    value: 'scira-kat-coder',
    label: 'KAT-Coder-Pro V1',
    description: "Kwaipilot's advanced coding LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    provider: 'kwaipilot',
  },
  {
    value: 'scira-deepseek-v3',
    label: 'DeepSeek v3',
    description: "DeepSeek's previous advanced chat LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: false,
    parameters: {
      temperature: 0.7,
      topP: 0.8,
      topK: 20,
      minP: 0,
    },
    provider: 'deepseek',
  },
  {
    value: 'scira-deepseek-v3.1-terminus',
    label: 'DeepSeek v3.1 Terminus',
    description: "DeepSeek's advanced chat LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: false,
    parameters: {
      temperature: 0.7,
      topP: 0.8,
      topK: 20,
      minP: 0,
    },
    provider: 'deepseek',
  },
  {
    value: 'scira-deepseek-chat',
    label: 'DeepSeek v3.2',
    description: "DeepSeek's advanced chat LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    parameters: {
      temperature: 1.0,
      topP: 0.95,
    },
    provider: 'deepseek',
  },
  {
    value: 'scira-deepseek-chat-think',
    label: 'DeepSeek v3.2 Thinking',
    description: "DeepSeek's advanced chat LLM with thinking",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    provider: 'deepseek',
  },
  {
    value: 'scira-deepseek-chat-exp',
    label: 'DeepSeek v3.2 Exp',
    description: "DeepSeek's advanced chat LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: false,
    provider: 'deepseek',
  },
  {
    value: 'scira-deepseek-chat-think-exp',
    label: 'DeepSeek v3.2 Exp Thinking',
    description: "DeepSeek's advanced chat LLM with thinking",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: false,
    provider: 'deepseek',
  },
  {
    value: 'scira-deepseek-r1',
    label: 'DeepSeek R1',
    description: "DeepSeek's advanced reasoning LLM",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: false,
    provider: 'deepseek',
  },
  {
    value: 'scira-deepseek-r1-0528',
    label: 'DeepSeek R1 0528',
    description: "DeepSeek's advanced reasoning LLM",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: false,
    provider: 'deepseek',
  },
  {
    value: 'scira-qwen-coder-small',
    label: 'Qwen 3 Coder 30B A3B Instruct',
    description: "Alibaba's advanced coding LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 10000,
    fast: false,
    parameters: {
      temperature: 0.7,
      topP: 0.8,
      topK: 20,
      minP: 0,
    },
    isNew: false,
    provider: 'alibaba',
  },
  {
    value: 'scira-qwen-coder',
    label: 'Qwen 3 Coder',
    description: "Alibaba's advanced coding LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 130000,
    fast: false,
    provider: 'alibaba',
  },
  {
    value: 'scira-qwen-coder-plus',
    label: 'Qwen 3 Coder Plus',
    description: "Alibaba's extremely advanced coding LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 130000,
    fast: false,
    provider: 'alibaba',
  },
  {
    value: 'scira-qwen-3.5',
    label: 'Qwen 3.5 397B A17B',
    description: "Alibaba's latest flagship LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 130000,
    fast: false,
    isNew: true,
    parameters: {
      temperature: 0.7,
      topP: 0.8,
      topK: 20,
      minP: 0,
      presencePenalty: 1.5,
    },
    provider: 'alibaba',
  },
  {
    value: 'scira-qwen-3.5-plus',
    label: 'Qwen 3.5 Plus',
    description: "Alibaba's latest flagship LLM with vision and reasoning",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 130000,
    fast: false,
    isNew: true,
    provider: 'alibaba',
  },
  {
    value: 'scira-qwen-3.5-27b',
    label: 'Qwen 3.5 27B',
    description: "Alibaba's Qwen 3.5 27B vision reasoning LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    fast: true,
    isNew: true,
    provider: 'alibaba',
  },
  {
    value: 'scira-qwen-3.5-35b',
    label: 'Qwen 3.5 35B A3B',
    description: "Alibaba's Qwen 3.5 35B A3B vision reasoning LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    fast: true,
    isNew: true,
    provider: 'alibaba',
  },
  {
    value: 'scira-qwen-3.5-122b',
    label: 'Qwen 3.5 122B A10B',
    description: "Alibaba's Qwen 3.5 122B A10B vision reasoning LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    fast: false,
    isNew: true,
    provider: 'alibaba',
  },
  {
    value: 'scira-qwen-3.5-flash',
    label: 'Qwen 3.5 Flash',
    description: "Alibaba's fast vision reasoning LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 10000,
    fast: true,
    isNew: true,
    provider: 'alibaba',
    parameters: {
      temperature: 1,
      topP: 0.95,
      topK: 20,
      minP: 0,
      presencePenalty: 1.5,
    },
  },
  {
    value: 'scira-qwen-coder-next',
    label: 'Qwen 3 Coder Next',
    description: "Alibaba's next-gen coding LLM",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 130000,
    fast: false,
    isNew: true,
    provider: 'alibaba',
  },
  {
    value: 'scira-qwen-3-vl-30b',
    label: 'Qwen 3 VL 30B',
    description: "Alibaba's advanced vision LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 130000,
    fast: true,
    parameters: {
      temperature: 0.7,
      topP: 0.8,
      topK: 20,
      minP: 0,
    },
    provider: 'alibaba',
  },
  {
    value: 'scira-qwen-3-vl-30b-thinking',
    label: 'Qwen 3 VL 30B Thinking',
    description: "Alibaba's advanced vision LLM with thinking",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 130000,
    fast: true,
    parameters: {
      temperature: 0.7,
      topP: 0.8,
      topK: 20,
      minP: 0,
    },
    isNew: false,
    provider: 'alibaba',
  },
  {
    value: 'scira-qwen-3-next',
    label: 'Qwen 3 Next 80B A3B Instruct',
    description: "Qwen's advanced instruct LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 100000,
    fast: true,
    isNew: false,
    parameters: {
      temperature: 0.7,
      topP: 0.8,
      minP: 0,
    },
    provider: 'alibaba',
  },
  {
    value: 'scira-qwen-3-next-think',
    label: 'Qwen 3 Next 80B A3B Thinking',
    description: "Qwen's advanced thinking LLM",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 100000,
    isNew: false,
    parameters: {
      temperature: 0.6,
      topP: 0.95,
      minP: 0,
    },
    provider: 'alibaba',
  },
  {
    value: 'scira-qwen-3-max',
    label: 'Qwen 3 Max',
    description: "Qwen's advanced instruct LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 10000,
    isNew: false,
    provider: 'alibaba',
  },
  {
    value: 'scira-qwen-3-max-preview',
    label: 'Qwen 3 Max Preview',
    description: "Qwen's advanced instruct LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 10000,
    isNew: false,
    provider: 'alibaba',
  },
  {
    value: 'scira-qwen-3-max-preview-thinking',
    label: 'Qwen 3 Max Thinking',
    description: "Qwen's most advanced reasoning LLM",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 10000,
    isNew: true,
    provider: 'alibaba',
  },
  {
    value: 'scira-qwen-235',
    label: 'Qwen 3 235B A22B',
    description: "Qwen's advanced instruct LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 100000,
    parameters: {
      temperature: 0.7,
      topP: 0.8,
      minP: 0,
    },
    provider: 'alibaba',
  },
  {
    value: 'scira-qwen-235-think',
    label: 'Qwen 3 235B A22B Thinking',
    description: "Qwen's advanced thinking LLM",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 100000,
    parameters: {
      temperature: 0.6,
      topP: 0.95,
      minP: 0,
    },
    provider: 'alibaba',
  },
  {
    value: 'scira-qwen-3-vl',
    label: 'Qwen 3 VL',
    description: "Qwen's advanced vision LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 10000,
    parameters: {
      temperature: 0.6,
      topP: 0.95,
      minP: 0,
    },
    isNew: false,
    provider: 'alibaba',
  },
  {
    value: 'scira-qwen-3-vl-thinking',
    label: 'Qwen 3 VL Thinking',
    description: "Qwen's advanced vision LLM with thinking",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 10000,
    parameters: {
      temperature: 0.6,
      topP: 0.95,
      minP: 0,
    },
    isNew: false,
    provider: 'alibaba',
  },
  {
    value: 'scira-kimi-k2.5',
    label: 'Kimi K2.5',
    description: "MoonShot AI's latest vision-enabled LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Free',
    pdf: false,
    pro: false,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 10000,
    isNew: true,
    provider: 'moonshot',
  },
  {
    value: 'scira-kimi-k2.5-thinking',
    label: 'Kimi K2.5 Thinking',
    description: "MoonShot AI's latest multi-modal LLM with thinking",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 10000,
    isNew: true,
    provider: 'moonshot',
  },
  {
    value: 'scira-kimi-k2-v2',
    label: 'Kimi K2 0905',
    description: "MoonShot AI's advanced base LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Free',
    pdf: false,
    pro: false,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 10000,
    fast: true,
    parameters: {
      temperature: 0.6,
    },
    provider: 'moonshot',
  },
  {
    value: 'scira-kimi-k2-v2-thinking',
    label: 'Kimi K2 Thinking',
    description: "MoonShot AI's advanced base LLM with thinking",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 10000,
    fast: true,
    parameters: {
      temperature: 1,
    },
    isNew: false,
    provider: 'moonshot',
  },
  {
    value: 'scira-minimax',
    label: 'Minimax M1 80K',
    description: "Minimax's advanced reasoning LLM",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 10000,
    isNew: false,
    parameters: {
      temperature: 0.6,
    },
    provider: 'minimax',
  },
  {
    value: 'scira-minimax-m2',
    label: 'Minimax M2',
    description: "Minimax's advanced reasoning LLM",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 10000,
    isNew: false,
    parameters: {
      temperature: 1.0,
      topP: 0.95,
      topK: 40,
    },
    provider: 'minimax',
  },
  {
    value: 'scira-minimax-m2.1',
    label: 'Minimax M2.1',
    description: "Minimax's latest advanced reasoning LLM",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 10000,
    isNew: false,
    parameters: {
      temperature: 1.0,
      topP: 0.95,
      topK: 40,
    },
    provider: 'minimax',
  },
  {
    value: 'scira-minimax-m2.1-lightning',
    label: 'Minimax M2.1 Lightning',
    description: "Minimax's fast advanced reasoning LLM",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 10000,
    isNew: false,
    fast: true,
    parameters: {
      temperature: 1.0,
      topP: 0.95,
      topK: 40,
    },
    provider: 'minimax',
  },
  {
    value: 'scira-minimax-m2.7',
    label: 'MiniMax M2.7',
    description: "MiniMax's latest high-speed reasoning LLM",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 10000,
    fast: true,
    isNew: true,
    parameters: {
      temperature: 1.0,
      topP: 0.95,
      topK: 40,
    },
    provider: 'minimax',
  },
  {
    value: 'scira-minimax-m2.5',
    label: 'Minimax M2.5',
    description: "Minimax's most capable reasoning LLM",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 10000,
    isNew: false,
    parameters: {
      temperature: 1.0,
      topP: 0.95,
      topK: 40,
    },
    provider: 'minimax',
  },
  {
    value: 'scira-glm-4.6',
    label: 'GLM 4.6',
    description: "Zhipu AI's advanced reasoning LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 20000,
    isNew: false,
    fast: true,
    parameters: {
      temperature: 0.6,
      topP: 0.95,
    },
    provider: 'zhipu',
  },
  {
    value: 'scira-glm-4.6v-flash',
    label: 'GLM 4.6V Flash',
    description: "Zhipu AI's fast vision reasoning LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Free',
    pdf: false,
    pro: false,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 20000,
    isNew: false,
    fast: true,
    parameters: {
      temperature: 0.8,
      topP: 0.6,
      topK: 2,
      frequencyPenalty: 1.1,
    },
    provider: 'zhipu',
  },
  {
    value: 'scira-glm-4.6v',
    label: 'GLM 4.6V',
    description: "Zhipu AI's advanced vision reasoning LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 20000,
    isNew: false,
    parameters: {
      temperature: 0.8,
      topP: 0.6,
      topK: 2,
      frequencyPenalty: 1.1,
    },
    provider: 'zhipu',
  },
  {
    value: 'scira-glm-4.7',
    label: 'GLM 4.7',
    description: "Zhipu AI's latest advanced reasoning LLM",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 20000,
    isNew: false,
    fast: true,
    parameters: {
      temperature: 1,
      topP: 0.95,
    },
  },
  {
    value: 'scira-glm-4.7-flash',
    label: 'GLM 4.7 Flash',
    description: "Zhipu AI's latest fast vision reasoning LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 20000,
    isNew: false,
    fast: true,
    provider: 'zhipu',
  },
  {
    value: 'scira-glm-5',
    label: 'GLM 5',
    description: "Zhipu AI's most powerful LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 20000,
    isNew: true,
    parameters: {
      temperature: 1,
      topP: 0.95,
    },
    provider: 'zhipu',
  },
  {
    value: 'scira-glm-5-thinking',
    label: 'GLM 5 Thinking',
    description: "Zhipu AI's most powerful reasoning LLM",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 20000,
    isNew: true,
    parameters: {
      temperature: 1,
      topP: 0.95,
    },
    provider: 'zhipu',
  },
  {
    value: 'scira-glm-air',
    label: 'GLM 4.5 Air',
    description: "Zhipu AI's efficient base LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 130000,
    parameters: {
      temperature: 0.6,
      topP: 0.95,
    },
    provider: 'zhipu',
  },
  {
    value: 'scira-glm',
    label: 'GLM 4.5',
    description: "Zhipu AI's previous advanced LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 13000,
    parameters: {
      temperature: 0.6,
      topP: 0.95,
    },
    provider: 'zhipu',
  },
  {
    value: 'scira-google',
    label: 'Gemini 2.5 Flash',
    description: "Google's advanced small LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    extreme: true,
    maxOutputTokens: 10000,
    isNew: false,
    provider: 'google',
  },
  {
    value: 'scira-google-think',
    label: 'Gemini 2.5 Flash Thinking',
    description: "Google's advanced small LLM with thinking",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    extreme: true,
    maxOutputTokens: 10000,
    isNew: false,
    provider: 'google',
  },
  {
    value: 'scira-google-pro',
    label: 'Gemini 2.5 Pro',
    description: "Google's advanced LLM",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    extreme: true,
    maxOutputTokens: 10000,
    isNew: false,
    provider: 'google',
  },
  {
    value: 'scira-google-pro-think',
    label: 'Gemini 2.5 Pro Thinking',
    description: "Google's advanced LLM with thinking",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    extreme: true,
    maxOutputTokens: 10000,
    isNew: false,
    provider: 'google',
  },
  {
    value: 'scira-gemini-3-flash',
    label: 'Gemini 3 Flash',
    description: "Google's latest small SOTA LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    extreme: true,
    maxOutputTokens: 10000,
    isNew: true,
    provider: 'google',
  },
  {
    value: 'scira-gemini-3-flash-think',
    label: 'Gemini 3 Flash Thinking',
    description: "Google's latest small SOTA LLM with thinking",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    extreme: true,
    maxOutputTokens: 10000,
    isNew: true,
    provider: 'google',
  },
  {
    value: 'scira-gemini-3.1-flash-lite',
    label: 'Gemini 3.1 Flash Lite',
    description: "Google's newest lightweight flash LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Free',
    pdf: true,
    pro: false,
    requiresAuth: false,
    freeUnlimited: false,
    extreme: true,
    maxOutputTokens: 10000,
    fast: true,
    isNew: true,
    provider: 'google',
  },
  {
    value: 'scira-gemini-3.1-flash-lite-think',
    label: 'Gemini 3.1 Flash Lite Thinking',
    description: "Google's newest lightweight flash LLM with thinking",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    extreme: true,
    maxOutputTokens: 10000,
    fast: true,
    isNew: true,
    provider: 'google',
  },
  {
    value: 'scira-gemini-3.1-pro',
    label: 'Gemini 3.1 Pro',
    description: "Google's newest SOTA LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Max',
    pdf: true,
    pro: true,
    max: true,
    requiresAuth: true,
    freeUnlimited: false,
    extreme: true,
    maxOutputTokens: 10000,
    isNew: true,
    provider: 'google',
  },
  {
    value: 'scira-anthropic-small',
    label: 'Claude Haiku 4.5',
    description: "Anthropic's fast and efficient LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: true,
    pro: true,
    max: false,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 8000,
    isNew: false,
    provider: 'anthropic',
  },
  {
    value: 'scira-anthropic',
    label: 'Claude Sonnet 4.5',
    description: "Anthropic's latest and greatest LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Max',
    pdf: true,
    pro: true,
    max: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 8000,
    isNew: false,
    provider: 'anthropic',
  },
  {
    value: 'scira-anthropic-think',
    label: 'Claude Sonnet 4.5 Thinking',
    description: "Anthropic's latest and greatest LLM with thinking",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Max',
    pdf: true,
    pro: true,
    max: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 8000,
    isNew: false,
    provider: 'anthropic',
  },
  {
    value: 'scira-anthropic-sonnet-4.6',
    label: 'Claude Sonnet 4.6',
    description: "Anthropic's latest Sonnet LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Max',
    pdf: true,
    pro: true,
    max: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 8000,
    isNew: true,
    provider: 'anthropic',
  },
  {
    value: 'scira-anthropic-sonnet-4.6-think',
    label: 'Claude Sonnet 4.6 Thinking',
    description: "Anthropic's latest Sonnet LLM with thinking",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Max',
    pdf: true,
    pro: true,
    max: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 8000,
    isNew: true,
    provider: 'anthropic',
  },
  {
    value: 'scira-anthropic-opus',
    label: 'Claude 4.5 Opus',
    description: "Anthropic's previous advanced LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Max',
    pdf: true,
    pro: true,
    max: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 8000,
    isNew: false,
    provider: 'anthropic',
  },
  {
    value: 'scira-anthropic-opus-think',
    label: 'Claude 4.5 Opus Thinking',
    description: "Anthropic's previous advanced LLM with thinking",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Max',
    pdf: true,
    pro: true,
    max: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 8000,
    isNew: false,
    provider: 'anthropic',
  },
  {
    value: 'scira-anthropic-opus-4.6',
    label: 'Claude 4.6 Opus',
    description: "Anthropic's most advanced LLM",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Max',
    pdf: true,
    pro: true,
    max: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 8000,
    isNew: true,
    provider: 'anthropic',
  },
  {
    value: 'scira-anthropic-opus-4.6-think',
    label: 'Claude 4.6 Opus Thinking',
    description: "Anthropic's most advanced LLM with thinking",
    vision: true,
    reasoning: true,
    experimental: false,
    category: 'Max',
    pdf: true,
    pro: true,
    max: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 8000,
    isNew: true,
    provider: 'anthropic',
  },
  {
    value: 'scira-mimo-v2-flash',
    label: 'Mimo V2 Flash',
    description: "Xiaomi's fast Mimo V2 Flash model via OpenRouter (thinking disabled)",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    provider: 'xiaomi',
  },
  {
    value: 'scira-mimo-v2-pro',
    label: 'Mimo V2 Pro',
    description: "Xiaomi's advanced Mimo V2 Pro model",
    vision: false,
    reasoning: true,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    provider: 'xiaomi',
  },
  {
    value: 'scira-nova-2-lite',
    label: 'Nova 2 Lite',
    description: "Amazon's latest and smallest LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    provider: 'amazon',
  },
  {
    value: 'scira-v0-10',
    label: 'Vercel v0 1.0',
    description: "Vercel's v0 1.0 model",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    provider: 'vercel',
  },
  {
    value: 'scira-v0-15',
    label: 'Vercel v0 1.5',
    description: "Vercel's v0 1.5 model",
    vision: true,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 16000,
    isNew: true,
    provider: 'vercel',
  },
  {
    value: 'scira-step-3.5-flash',
    label: 'Step 3.5 Flash',
    description: "StepFun's fast and efficient LLM",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Free',
    pdf: false,
    pro: false,
    requiresAuth: false,
    freeUnlimited: false,
    maxOutputTokens: 8000,
    fast: true,
    isNew: true,
    provider: 'stepfun',
  },
  {
    value: 'scira-mercury-2',
    label: 'Mercury 2',
    description: "Inception's diffusion-based language model",
    vision: false,
    reasoning: false,
    experimental: false,
    category: 'Pro',
    pdf: false,
    pro: true,
    requiresAuth: true,
    freeUnlimited: false,
    maxOutputTokens: 1000,
    fast: true,
    isNew: true,
    provider: 'inception',
  },
];

// Helper functions for model access checks
export function getModelConfig(modelValue: string) {
  return models.find((model) => model.value === modelValue);
}

export function requiresAuthentication(modelValue: string): boolean {
  const model = getModelConfig(modelValue);
  return model?.requiresAuth || false;
}

export function requiresProSubscription(modelValue: string): boolean {
  const model = getModelConfig(modelValue);
  return model?.pro || false;
}

export function requiresMaxSubscription(modelValue: string): boolean {
  const model = getModelConfig(modelValue);
  return model?.max || false;
}

export function isFreeUnlimited(modelValue: string): boolean {
  const model = getModelConfig(modelValue);
  return model?.freeUnlimited || false;
}

export function hasVisionSupport(modelValue: string): boolean {
  const model = getModelConfig(modelValue);
  return model?.vision || false;
}

export function hasPdfSupport(modelValue: string): boolean {
  const model = getModelConfig(modelValue);
  // Models with vision support can also handle PDFs
  return model?.pdf || false;
}

export function hasReasoningSupport(modelValue: string): boolean {
  const model = getModelConfig(modelValue);
  return model?.reasoning || false;
}

export function isExperimentalModel(modelValue: string): boolean {
  const model = getModelConfig(modelValue);
  return model?.experimental || false;
}

export function getMaxOutputTokens(modelValue: string): number {
  const model = getModelConfig(modelValue);
  return model?.maxOutputTokens || 8000;
}

export function getModelParameters(modelValue: string): ModelParameters {
  const model = getModelConfig(modelValue);
  return model?.parameters || {};
}

// Access control helper
export function canUseModel(
  modelValue: string,
  user: any,
  isProUser: boolean,
  isMaxUser: boolean = false,
): { canUse: boolean; reason?: string } {
  const model = getModelConfig(modelValue);

  if (!model) {
    return { canUse: false, reason: 'Model not found' };
  }

  // Check if model requires authentication
  if (model.requiresAuth && !user) {
    return { canUse: false, reason: 'authentication_required' };
  }

  // Check if model requires Max subscription
  if (model.max && !isMaxUser) {
    return { canUse: false, reason: 'max_subscription_required' };
  }

  // Check if model requires Pro subscription (Max is a superset of Pro)
  if (model.pro && !isProUser && !isMaxUser) {
    return { canUse: false, reason: 'pro_subscription_required' };
  }

  return { canUse: true };
}

// Helper to check if user should bypass rate limits
export function shouldBypassRateLimits(modelValue: string, user: any): boolean {
  const model = getModelConfig(modelValue);
  return Boolean(user && model?.freeUnlimited);
}

// Get acceptable file types for a model
export function getAcceptedFileTypes(modelValue: string, isProUser: boolean): string {
  const model = getModelConfig(modelValue);
  // Document file types for file_query_search tool - available for ALL models
  const documentTypes = '.csv,.xlsx,.xls,.docx';

  // Vision models get images + documents, PDF models also get PDFs
  if (model?.vision) {
    if (model?.pdf) {
      return `image/*,.pdf,${documentTypes}`;
    }
    return `image/*,${documentTypes}`;
  }

  // Non-vision models only get document types for file_query_search
  return documentTypes;
}

// Check if a model supports extreme mode
export function supportsExtremeMode(modelValue: string): boolean {
  // Extreme mode restrictions removed: allow all models in extreme mode
  return true;
}

// Get models that support extreme mode
export function getExtremeModels(): Model[] {
  // With restrictions removed, all models are considered extreme-capable
  return models;
}

// Models that support canvas mode (spec generation)
const CANVAS_MODELS = new Set([
  'scira-code',
  'scira-gpt-5.2',
  'scira-gpt-5.3-chat-latest',
  'scira-gpt-5.4',
  'scira-gpt-5.4-mini',
  'scira-gpt-5.4-nano',
  'scira-gpt-5.4-thinking',
  'scira-gpt-5.4-thinking-xhigh',
  'scira-gpt-5.2-thinking',
  'scira-gpt-5.2-thinking-xhigh',
  'scira-anthropic',
  'scira-anthropic-sonnet-4.6',
  'scira-anthropic-sonnet-4.6-think',
  'scira-anthropic-opus-4.6',
  'scira-anthropic-opus-4.6-think',
  'scira-glm-5',
  'scira-glm-4.7',
  'scira-kimi-k2.5',
  'scira-qwen-3.5',
  'scira-qwen-3.5-plus',
  'scira-seed-1.8',
  'scira-deepseek-chat',
  'scira-gpt-5.2-codex',
  'scira-gpt-5.3-codex',
  'scira-gemini-3.1-pro',
]);

export function supportsCanvasMode(modelValue: string): boolean {
  return CANVAS_MODELS.has(modelValue);
}

// Restricted regions for OpenAI and Anthropic models
const RESTRICTED_REGIONS = ['CN', 'KP', 'RU']; // China, North Korea, Russia

// Models that should be filtered in restricted regions
const OPENAI_MODELS = [
  'scira-gpt-4.1',
  'scira-gpt-4.1-mini',
  'scira-gpt-4.1-nano',
  'scira-gpt5',
  'scira-gpt5-mini',
  'scira-gpt5-nano',
  'scira-gpt5-medium',
  'scira-gpt5-codex',
  'scira-gpt-5.1',
  'scira-gpt-5.1-codex',
  'scira-gpt-5.1-codex-mini',
  'scira-gpt-5.1-codex-max',
  'scira-gpt-5.1-thinking',
  'scira-gpt-5.2',
  'scira-gpt-5.4',
  'scira-gpt-5.4-mini',
  'scira-gpt-5.4-nano',
  'scira-gpt-5.4-thinking',
  'scira-gpt-5.4-thinking-xhigh',
  'scira-gpt-5.2-thinking',
  'scira-gpt-5.2-thinking-xhigh',
  'scira-gpt-5.2-codex',
  'scira-gpt-5.3-codex',
  'scira-o3',
  'scira-o4-mini',
];

const ANTHROPIC_MODELS = [
  'scira-haiku',
  'scira-anthropic-small',
  'scira-anthropic',
  'scira-anthropic-think',
  'scira-anthropic-opus',
  'scira-anthropic-opus-think',
  'scira-anthropic-sonnet-4.6',
  'scira-anthropic-sonnet-4.6-think',
  'scira-anthropic-opus-4.6',
  'scira-anthropic-opus-4.6-think',
];

// Check if a model should be filtered based on region
export function isModelRestrictedInRegion(modelValue: string, countryCode?: string): boolean {
  if (!countryCode) return false;

  const isRestricted = RESTRICTED_REGIONS.includes(countryCode.toUpperCase());
  if (!isRestricted) return false;

  const isOpenAI = OPENAI_MODELS.includes(modelValue);
  const isAnthropic = ANTHROPIC_MODELS.includes(modelValue);

  return isOpenAI || isAnthropic;
}

// Filter models based on user's region
export function getFilteredModels(countryCode?: string): Model[] {
  if (!countryCode || !RESTRICTED_REGIONS.includes(countryCode.toUpperCase())) {
    return models;
  }

  return models.filter((model) => !isModelRestrictedInRegion(model.value, countryCode));
}

// Legacy arrays for backward compatibility (deprecated - use helper functions instead)
export const authRequiredModels = models.filter((m) => m.requiresAuth).map((m) => m.value);
export const proRequiredModels = models.filter((m) => m.pro).map((m) => m.value);
export const freeUnlimitedModels = models.filter((m) => m.freeUnlimited).map((m) => m.value);

// Helper function to derive provider from model value/label patterns
export function getModelProvider(modelValue: string, label?: string): ModelProvider {
  const value = modelValue.toLowerCase();
  const modelLabel = (label || '').toLowerCase();

  // xAI (Grok)
  if (
    value.includes('grok') ||
    value.includes('scira-default') ||
    (value.includes('scira-code') && !value.includes('codex'))
  ) {
    return 'xai';
  }

  // OpenAI (GPT, o3, o4)
  if (value.includes('gpt') || value.includes('scira-o3') || value.includes('scira-o4')) {
    return 'openai';
  }

  // Anthropic (Claude)
  if (value.includes('anthropic') || value.includes('haiku') || modelLabel.includes('claude')) {
    return 'anthropic';
  }

  // Google (Gemini)
  if (value.includes('google') || value.includes('gemini')) {
    return 'google';
  }

  // Alibaba (Qwen)
  if (value.includes('qwen')) {
    return 'alibaba';
  }

  // Mistral (Mistral, Ministral, Magistral, Devstral, Leanstral)
  if (
    value.includes('mistral') ||
    value.includes('ministral') ||
    value.includes('magistral') ||
    value.includes('devstral') ||
    value.includes('leanstral')
  ) {
    return 'mistral';
  }

  // DeepSeek
  if (value.includes('deepseek')) {
    return 'deepseek';
  }

  // Zhipu (GLM)
  if (value.includes('glm')) {
    return 'zhipu';
  }

  // Cohere (Command)
  if (value.includes('cmd') || modelLabel.includes('command')) {
    return 'cohere';
  }

  // MoonShot (Kimi)
  if (value.includes('kimi')) {
    return 'moonshot';
  }

  // Minimax
  if (value.includes('minimax')) {
    return 'minimax';
  }

  // ByteDance (Seed)
  if (value.includes('seed')) {
    return 'bytedance';
  }

  // Arcee (Trinity)
  if (value.includes('trinity')) {
    return 'arcee';
  }

  // Vercel (v0)
  if (value.includes('v0')) {
    return 'vercel';
  }

  // Amazon (Nova)
  if (value.includes('nova')) {
    return 'amazon';
  }

  // Xiaomi (Mimo)
  if (value.includes('mimo')) {
    return 'xiaomi';
  }

  // Kwaipilot (KAT)
  if (value.includes('kat')) {
    return 'kwaipilot';
  }

  // StepFun (Step)
  if (value.includes('step')) {
    return 'stepfun';
  }

  // Sarvam
  if (value.includes('sarvam')) {
    return 'sarvam';
  }

  // Inception (Mercury)
  if (value.includes('mercury')) {
    return 'inception';
  }

  // Default fallback
  return 'openai';
}

// Get provider info for a model
export function getModelProviderInfo(modelValue: string): ProviderInfo {
  const model = getModelConfig(modelValue);
  const provider = model?.provider || getModelProvider(modelValue, model?.label);
  return PROVIDERS[provider];
}

// Get all unique providers that have models
export function getActiveProviders(): ProviderInfo[] {
  const providerSet = new Set<ModelProvider>();
  for (const model of models) {
    const provider = model.provider || getModelProvider(model.value, model.label);
    providerSet.add(provider);
  }
  return Array.from(providerSet).map((p) => PROVIDERS[p]);
}

// Get models by provider
export function getModelsByProvider(provider: ModelProvider): Model[] {
  return models.filter((m) => {
    const modelProvider = m.provider || getModelProvider(m.value, m.label);
    return modelProvider === provider;
  });
}


================================================
FILE: ai/providers.ts
================================================
import 'server-only';
import { wrapLanguageModel, customProvider, extractReasoningMiddleware, gateway } from 'ai';

import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
import { createOpenAI } from '@ai-sdk/openai';
import { createWebSocketFetch } from 'ai-sdk-openai-websocket-fetch';
import { xai } from '@ai-sdk/xai';
import { groq } from '@ai-sdk/groq';
import { mistral } from '@ai-sdk/mistral';
import { google } from '@ai-sdk/google';
import { baseten } from '@ai-sdk/baseten';
import { anthropic } from '@ai-sdk/anthropic';
import { cohere } from '@ai-sdk/cohere';
import { createOpenRouter } from '@openrouter/ai-sdk-provider';
import { createRetryable } from 'ai-retry';
import { createWorkersAI } from 'workers-ai-provider';

const ark = createOpenAICompatible({
  name: 'ark',
  baseURL: 'https://ark.ap-southeast.bytepluses.com/api/v3',
  apiKey: process.env.ARK_API_KEY,
});

const sarvam = createOpenAICompatible({
  name: 'sarvam',
  baseURL: 'https://api.sarvam.ai/v1',
  apiKey: process.env.SARVAM_API_KEY,
});

const zai = createOpenAICompatible({
  name: 'zai',
  baseURL: 'https://api.z.ai/api/paas/v4',
  apiKey: process.env.ZAI_API_KEY,
});

const middleware = extractReasoningMiddleware({
  tagName: 'think',
});

const middlewareWithStartWithReasoning = extractReasoningMiddleware({
  tagName: 'think',
  startWithReasoning: true,
});

const huggingface = createOpenAICompatible({
  name: 'huggingface',
  baseURL: 'https://router.huggingface.co/v1',
  apiKey: process.env.HF_TOKEN,
});

const novita = createOpenAICompatible({
  name: 'novita',
  baseURL: 'https://api.novita.ai/openai',
  apiKey: process.env.NOVITA_API_KEY,
});

const workersai = createWorkersAI({
  accountId: process.env.CLOUDFLARE_ACCOUNT_ID!,
  apiKey: process.env.CLOUDFLARE_API_TOKEN!,
});

const openrouter = createOpenRouter({
  apiKey: process.env.OPENROUTER_API_KEY,
  headers: {
    'HTTP-Referer': 'https://sciraai.in',
    'X-Title': 'Scira AI',
    'Content-Type': 'application/json',
  },
});

const minimax = createOpenAICompatible({
  name: 'minimax',
  baseURL: 'https://api.minimax.io/v1',
  apiKey: process.env.MINIMAX_API_KEY,
});

const wsFetch = createWebSocketFetch();
const openai = createOpenAI({
  fetch: wsFetch,
});

const openai_2 = createOpenAI({
  apiKey: process.env.OPENAI_API_KEY_2,
  fetch: wsFetch,
});

export const scira = customProvider({
  languageModels: {
    'scira-arch-router': huggingface.chatModel('katanemo/Arch-Router-1.5B:hf-inference'),
    'scira-default': xai('grok-4-1-fast-non-reasoning'),
    'scira-auto': xai('grok-4-1-fast-non-reasoning'),
    'scira-sarvam-105b': sarvam.chatModel('sarvam-105b'),
    'scira-grok4.1-fast-thinking': xai('grok-4-1-fast-reasoning'),
    'scira-ext-1': createRetryable({
      model: xai('grok-4-1-fast-reasoning'),
      retries: [gateway('xai/grok-4.1-fast-reasoning')],
    }),
    'scira-ext-2': createRetryable({
      model: openai('gpt-5.4'),
      retries: [openai_2('gpt-5.4')],
    }),
    // 'scira-ext-3': gateway('anthropic/claude-sonnet-4.6'),
    'scira-ext-4': createRetryable({
      model: workersai('@cf/zai-org/glm-4.7-flash'),
      retries: [novita.chatModel('zai-org/glm-4.7-flash')],
    }),
    'scira-ext-5': gateway('moonshotai/kimi-k2.5'),
    'scira-ext-6': createRetryable({
      model: google('gemini-3.1-pro-preview'),
      retries: [gateway('google/gemini-3.1-pro-preview')],
    }),
    'scira-ext-7': gateway('alibaba/qwen3.5-flash'),
    'scira-ext-8': xai('grok-4.20-experimental-beta-0304-non-reasoning'),
    'scira-nano': groq('llama-3.3-70b-versatile'),
    'scira-name': createRetryable({
      model: gateway('google/gemini-2.5-flash-lite-preview-09-2025'),
      retries: [google('gemini-2.5-flash-lite-preview-09-2025'), google('gemini-2.5-flash-lite')],
    }),
    'scira-grok-3-mini': xai('grok-3-mini'),
    'scira-grok-3': xai('grok-3'),
    'scira-grok-4': xai('grok-4'),
    'scira-grok-4.20-experimental-beta-0304': xai('grok-4.20-non-reasoning-latest'),
    'scira-grok-4.20-experimental-beta-0304-thinking': xai('grok-4.20-reasoning-latest'),
    'scira-grok-4-fast': xai('grok-4-fast-non-reasoning'),
    'scira-grok-4-fast-think': xai('grok-4-fast-reasoning'),
    'scira-code': xai('grok-code-fast-1'),
    'scira-enhance': groq('moonshotai/kimi-k2-instruct-0905'),
    'scira-follow-up': createRetryable({
      model: google('gemini-2.5-flash-lite-preview-09-2025'),
      retries: [
        google('gemini-2.5-flash-lite'),
        gateway('google/gemini-2.5-flash-lite'),
        gateway('google/gemini-2.5-flash-lite-preview-09-2025'),
      ],
    }),
    'scira-qwen-4b': huggingface.chatModel('Qwen/Qwen3-4B-Instruct-2507:nscale'),
    'scira-qwen-4b-thinking': wrapLanguageModel({
      model: huggingface.chatModel('Qwen/Qwen3-4B-Thinking-2507:nscale'),
      middleware: [middlewareWithStartWithReasoning],
    }),
    'scira-gpt-4.1-nano': createRetryable({
      model: openai('gpt-4.1-nano'),
      retries: [openai_2('gpt-4.1-nano')],
    }),
    'scira-gpt-4.1-mini': createRetryable({
      model: openai('gpt-4.1-mini'),
      retries: [openai_2('gpt-4.1-mini')],
    }),
    'scira-gpt-4.1': createRetryable({
      model: openai('gpt-4.1'),
      retries: [openai_2('gpt-4.1')],
    }),
    'scira-gpt-5.1': createRetryable({
      model: openai('gpt-5.1'),
      retries: [openai_2('gpt-5.1')],
    }),
    'scira-gpt-5.1-thinking': createRetryable({
      model: openai('gpt-5.1'),
      retries: [openai_2('gpt-5.1')],
    }),
    'scira-gpt-5.2': createRetryable({
      model: openai('gpt-5.2'),
      retries: [openai_2('gpt-5.2')],
    }),
    'scira-gpt-5.3-chat-latest': createRetryable({
      model: openai('gpt-5.3-chat-latest'),
      retries: [openai_2('gpt-5.3-chat-latest')],
    }),
    'scira-gpt-5.4': createRetryable({
      model: openai('gpt-5.4'),
      retries: [openai_2('gpt-5.4')],
    }),
    'scira-gpt-5.4-mini': createRetryable({
      model: openai('gpt-5.4-mini'),
      retries: [openai_2('gpt-5.4-mini')],
    }),
    'scira-gpt-5.4-nano': createRetryable({
      model: openai('gpt-5.4-nano'),
      retries: [openai_2('gpt-5.4-nano')],
    }),
    'scira-gpt-5.4-thinking': createRetryable({
      model: openai('gpt-5.4'),
      retries: [openai_2('gpt-5.4')],
    }),
    'scira-gpt-5.4-thinking-xhigh': createRetryable({
      model: openai('gpt-5.4'),
      retries: [openai_2('gpt-5.4')],
    }),
    'scira-gpt-5.2-thinking': createRetryable({
      model: openai('gpt-5.2'),
      retries: [openai_2('gpt-5.2')],
    }),
    'scira-gpt-5.2-thinking-xhigh': createRetryable({
      model: openai('gpt-5.2'),
      retries: [openai_2('gpt-5.2')],
    }),
    'scira-gpt-5.1-codex': createRetryable({
      model: openai('gpt-5.1-codex'),
      retries: [openai_2('gpt-5.1-codex')],
    }),
    'scira-gpt-5.1-codex-mini': createRetryable({
      model: openai('gpt-5.1-codex-mini'),
      retries: [openai_2('gpt-5.1-codex-mini')],
    }),
    'scira-gpt-5.1-codex-max': createRetryable({
      model: openai('gpt-5.1-codex-max'),
      retries: [openai_2('gpt-5.1-codex-max')],
    }),
    'scira-gpt-5.2-codex': createRetryable({
      model: openai('gpt-5.2-codex'),
      retries: [openai_2('gpt-5.2-codex')],
    }),
    'scira-gpt-5.3-codex': createRetryable({
      model: openai('gpt-5.3-codex'),
      retries: [openai_2('gpt-5.3-codex')],
    }),
    'scira-gpt5': createRetryable({
      model: openai('gpt-5'),
      retries: [openai_2('gpt-5')],
    }),
    'scira-gpt5-medium': createRetryable({
      model: openai('gpt-5'),
      retries: [openai_2('gpt-5')],
    }),
    'scira-gpt5-mini': createRetryable({
      model: openai('gpt-5-mini'),
      retries: [openai_2('gpt-5-mini')],
    }),
    'scira-gpt5-nano': createRetryable({
      model: openai('gpt-5-nano'),
      retries: [openai_2('gpt-5-nano')],
    }),
    'scira-o3': createRetryable({
      model: openai('o3'),
      retries: [openai_2('o3')],
    }),
    'scira-o4-mini': createRetryable({
      model: openai('o4-mini'),
      retries: [openai_2('o4-mini')],
    }),
    'scira-gpt5-codex': createRetryable({
      model: openai('gpt-5-codex'),
      retries: [openai_2('gpt-5-codex')],
    }),
    'scira-qwen-32b': wrapLanguageModel({
      model: groq('qwen/qwen3-32b'),
      middleware,
    }),
    'scira-qwen-32b-thinking': wrapLanguageModel({
      model: groq('qwen/qwen3-32b'),
      middleware,
    }),
    'scira-gpt-oss-20': wrapLanguageModel({
      model: groq('openai/gpt-oss-20b'),
      middleware,
    }),
    'scira-nemotron-3-super': workersai('@cf/nvidia/nemotron-3-120b-a12b'),
    'scira-gpt-oss-120': wrapLanguageModel({
      model: baseten('openai/gpt-oss-120b'),
      middleware,
    }),
    'scira-trinity-mini': wrapLanguageModel({
      model: gateway('arcee-ai/trinity-mini'),
      middleware,
    }),
    'scira-trinity-large': wrapLanguageModel({
      model: openrouter('arcee-ai/trinity-large-preview:free'),
      middleware,
    }),
    'scira-step-3.5-flash': openrouter('stepfun/step-3.5-flash:free'),
    'scira-kat-coder': gateway('kwaipilot/kat-coder-pro-v1'),
    'scira-deepseek-v3': baseten('deepseek-ai/DeepSeek-V3-0324'),
    'scira-deepseek-v3.1-terminus': gateway('deepseek/deepseek-v3.1-terminus'),
    'scira-deepseek-chat': gateway('deepseek/deepseek-v3.2'),
    'scira-deepseek-chat-think': gateway('deepseek/deepseek-v3.2-thinking'),
    'scira-deepseek-chat-exp': gateway('deepseek/deepseek-v3.2-exp'),
    'scira-deepseek-chat-think-exp': wrapLanguageModel({
      model: novita.chatModel('deepseek/deepseek-v3.2-exp'),
      middleware,
    }),
    'scira-v0-10': gateway('vercel/v0-1.0-md'),
    'scira-v0-15': gateway('vercel/v0-1.5-md'),
    'scira-deepseek-r1': wrapLanguageModel({
      model: novita.chatModel('deepseek/deepseek-r1-turbo'),
      middleware,
    }),
    'scira-deepseek-r1-0528': wrapLanguageModel({
      model: novita.chatModel('deepseek/deepseek-r1-0528'),
      middleware,
    }),
    'scira-qwen-coder-small': gateway('alibaba/qwen3-coder-30b-a3b'),
    'scira-qwen-coder': baseten('Qwen/Qwen3-Coder-480B-A35B-Instruct'),
    'scira-qwen-coder-plus': gateway('alibaba/qwen3-coder-plus'),
    'scira-qwen-coder-next': novita.chatModel('qwen/qwen3-coder-next'),
    'scira-qwen-30': huggingface.chatModel('Qwen/Qwen3-30B-A3B-Instruct-2507:nebius'),
    'scira-qwen-30-think': wrapLanguageModel({
      model: huggingface.chatModel('Qwen/Qwen3-30B-A3B-Thinking-2507:nebius'),
      middleware,
    }),
    'scira-qwen-3-vl-30b': novita.chatModel('qwen/qwen3-vl-30b-a3b-instruct'),
    'scira-qwen-3-vl-30b-thinking': wrapLanguageModel({
      model: novita.chatModel('qwen/qwen3-vl-30b-a3b-thinking'),
      middleware,
    }),
    'scira-qwen-3-next': huggingface.chatModel('Qwen/Qwen3-Next-80B-A3B-Instruct:hyperbolic'),
    'scira-qwen-3-next-think': wrapLanguageModel({
      model: huggingface.chatModel('Qwen/Qwen3-Next-80B-A3B-Thinking:hyperbolic'),
      middleware: [middlewareWithStartWithReasoning],
    }),
    'scira-qwen-3-max': gateway('alibaba/qwen3-max'),
    'scira-qwen-3-max-preview': gateway('alibaba/qwen3-max-preview'),
    'scira-qwen-3-max-preview-thinking': gateway('alibaba/qwen3-max-thinking'),
    'scira-qwen-235': gateway('alibaba/qwen-3-235b'),
    'scira-qwen-235-think': wrapLanguageModel({
      model: huggingface.chatModel('Qwen/Qwen3-235B-A22B-Thinking-2507:fireworks-ai'),
      middleware: [middlewareWithStartWithReasoning],
    }),
    'scira-qwen-3.5-27b': novita.chatModel('qwen/qwen3.5-27b'),
    'scira-qwen-3.5-35b': novita.chatModel('qwen/qwen3.5-35b-a3b'),
    'scira-qwen-3.5-122b': novita.chatModel('qwen/qwen3.5-122b-a10b'),
    'scira-qwen-3.5': novita.chatModel('qwen/qwen3.5-397b-a17b'),
    'scira-qwen-3.5-plus': gateway('alibaba/qwen3.5-plus'),
    'scira-qwen-3.5-flash': gateway('alibaba/qwen3.5-flash'),
    'scira-qwen-3-vl': gateway('alibaba/qwen3-vl-instruct'),
    'scira-qwen-3-vl-thinking': wrapLanguageModel({
      model: gateway('alibaba/qwen3-vl-thinking'),
      middleware,
    }),
    'scira-glm-air': gateway('zai/glm-4.5-air'),
    'scira-glm': wrapLanguageModel({
      model: gateway('zai/glm-4.5'),
      middleware,
    }),
    'scira-glm-4.6': wrapLanguageModel({
      model: huggingface.chatModel('zai-org/GLM-4.6:zai-org'),
      middleware,
    }),
    'scira-glm-4.6v-flash': wrapLanguageModel({
      model: huggingface.chatModel('zai-org/GLM-4.6V-Flash:zai-org'),
      middleware,
    }),
    'scira-glm-4.6v': wrapLanguageModel({
      model: huggingface.chatModel('zai-org/GLM-4.6V:zai-org'),
      middleware,
    }),
    'scira-glm-4.7': wrapLanguageModel({
      model: huggingface.chatModel('zai-org/GLM-4.7:novita'),
      middleware,
    }),
    'scira-glm-4.7-flash': createRetryable({
      model: novita.chatModel('zai-org/glm-4.7-flash'),
      retries: [gateway('zai/glm-4.7-flashx')],
    }),
    'scira-glm-5': wrapLanguageModel({
      model: zai('glm-5-turbo'),
      middleware,
    }),
    'scira-glm-5-thinking': wrapLanguageModel({
      model: zai('glm-5-turbo'),
      middleware,
    }),
    'scira-minimax': wrapLanguageModel({
      model: novita.chatModel('minimaxai/minimax-m1-80k'),
      middleware,
    }),
    'scira-minimax-m2': wrapLanguageModel({
      model: gateway('minimax/minimax-m2'),
      middleware,
    }),
    'scira-minimax-m2.1': wrapLanguageModel({
      model: gateway('minimax/minimax-m2.1'),
      middleware,
    }),
    'scira-minimax-m2.1-lightning': wrapLanguageModel({
      model: gateway('minimax/minimax-m2.1-lightning'),
      middleware,
    }),
    'scira-minimax-m2.7': wrapLanguageModel({
      model: minimax.chatModel('MiniMax-M2.7-highspeed'),
      middleware,
    }),
    'scira-minimax-m2.5': createRetryable({
      model: baseten.chatModel('MiniMaxAI/MiniMax-M2.5'),
      retries: [
        minimax.chatModel('MiniMax-M2.5-highspeed'),
        novita.chatModel('minimax/minimax-m2.5'),
        gateway('minimax/minimax-m2.5'),
      ],
    }),
    'scira-cmd-a': cohere('command-a-03-2025'),
    'scira-cmd-a-think': cohere('command-a-reasoning-08-2025'),
    'scira-kimi-k2-v2': groq('moonshotai/kimi-k2-instruct-0905'),
    'scira-kimi-k2-v2-thinking': wrapLanguageModel({
      model: gateway('moonshotai/kimi-k2-thinking-turbo'),
      middleware,
    }),
    'scira-kimi-k2.5': createRetryable({
      model: baseten.chatModel('moonshotai/Kimi-K2.5'),
      retries: [gateway('moonshotai/kimi-k2.5')],
    }),
    'scira-kimi-k2.5-thinking': gateway('moonshotai/kimi-k2.5'),
    'scira-ministral-3b': mistral('ministral-3b-2512'),
    'scira-ministral-8b': mistral('ministral-8b-2512'),
    'scira-ministral-14b': mistral('ministral-14b-2512'),
    'scira-mistral-large': mistral('mistral-large-2512'),
    'scira-mistral-medium': mistral('mistral-medium-2508'),
    'scira-magistral-small': mistral('magistral-small-2509'),
    'scira-magistral-medium': mistral('magistral-medium-2509'),
    'scira-mistral-small': mistral('mistral-small-2603'),
    'scira-mistral-small-think': mistral('mistral-small-2603'),
    'scira-leanstral': mistral('labs-leanstral-2603'),
    'scira-devstral': mistral('devstral-2512'),
    'scira-devstral-small': mistral('labs-devstral-small-2512'),
    'scira-google-lite': google('gemini-flash-lite-latest'),
    'scira-google': google('gemini-flash-latest'),
    'scira-google-think': google('gemini-flash-latest'),
    'scira-google-pro': createRetryable({
      model: google('gemini-2.5-pro'),
      retries: [gateway('google/gemini-2.5-pro')],
    }),
    'scira-google-pro-think': createRetryable({
      model: google('gemini-2.5-pro'),
      retries: [gateway('google/gemini-2.5-pro')],
    }),
    'scira-gemini-3-flash': createRetryable({
      model: google('gemini-3-flash-preview'),
      retries: [gateway('google/gemini-3-flash')],
    }),
    'scira-gemini-3-flash-think': google('gemini-3-flash-preview'),
    'scira-gemini-3.1-flash-lite': createRetryable({
      model: gateway('google/gemini-3.1-flash-lite-preview'),
      retries: [google('gemini-3.1-flash-lite-preview')],
    }),
    'scira-gemini-3.1-flash-lite-think': createRetryable({
      model: gateway('google/gemini-3.1-flash-lite-preview'),
      retries: [google('gemini-3.1-flash-lite-preview')],
    }),
    'scira-gemini-3.1-pro': createRetryable({
      model: google('gemini-3.1-pro-preview'),
      retries: [gateway('google/gemini-3.1-pro-preview')],
    }),
    'scira-anthropic-small': anthropic('claude-haiku-4-5'),
    'scira-anthropic': anthropic('claude-sonnet-4-5'),
    'scira-anthropic-think': anthropic('claude-sonnet-4-5'),
    'scira-anthropic-sonnet-4.6': anthropic('claude-sonnet-4-6'),
    'scira-anthropic-sonnet-4.6-think': anthropic('claude-sonnet-4-6'),
    'scira-mimo-v2-flash': wrapLanguageModel({
      model: gateway('xiaomi/mimo-v2-flash'),
      middleware,
    }),
    'scira-mimo-v2-pro': wrapLanguageModel({
      model: gateway('xiaomi/mimo-v2-pro'),
      middleware,
    }),
    'scira-anthropic-opus': anthropic('claude-opus-4-5'),
    'scira-anthropic-opus-think': anthropic('claude-opus-4-5'),
    'scira-anthropic-opus-4.6': anthropic('claude-opus-4-6'),
    'scira-anthropic-opus-4.6-think': anthropic('claude-opus-4-6'),
    'scira-nova-2-lite': gateway('amazon/nova-2-lite'),
    'scira-seed-1.6': wrapLanguageModel({
      model: ark('seed-1-6-250915'),
      middleware,
    }),
    'scira-seed-1.8': wrapLanguageModel({
      model: ark('seed-1-8-251228'),
      middleware,
    }),
    'scira-seed-2.0-mini': wrapLanguageModel({
      model: ark('seed-2-0-mini-260215'),
      middleware,
    }),
    'scira-seed-2.0-lite': ark('seed-2-0-lite-260228'),
    'scira-seed-1.6-flash': wrapLanguageModel({
      model: ark('seed-1-6-flash-250715'),
      middleware,
    }),
    'scira-mercury-2': gateway('inception/mercury-2'),
  },
});

// Re-export all model data and pure helpers from the client-safe models module
export type { ModelProvider, ProviderInfo, Model } from './models';
export {
  PROVIDERS,
  models,
  getModelConfig,
  requiresAuthentication,
  requiresProSubscription,
  requiresMaxSubscription,
  isFreeUnlimited,
  hasVisionSupport,
  hasPdfSupport,
  hasReasoningSupport,
  isExperimentalModel,
  getMaxOutputTokens,
  getModelParameters,
  canUseModel,
  shouldBypassRateLimits,
  getAcceptedFileTypes,
  supportsExtremeMode,
  getExtremeModels,
  supportsCanvasMode,
  isModelRestrictedInRegion,
  getFilteredModels,
  authRequiredModels,
  proRequiredModels,
  freeUnlimitedModels,
  getModelProvider,
  getModelProviderInfo,
  getActiveProviders,
  getModelsByProvider,
} from './models';


================================================
FILE: app/(auth)/layout.tsx
================================================
'use client';

import Link from 'next/link';
import { Carousel, CarouselContent, CarouselItem, type CarouselApi } from '@/components/ui/carousel';
import { useState, useEffect } from 'react';
import Autoplay from 'embla-carousel-autoplay';
import { SciraLogo } from '@/components/logos/scira-logo';
import { Brain, Search, Eye, Mic, Blocks } from 'lucide-react';

const testimonials = [
  {
    content:
      'Scira is better than Grok at digging up information from X, its own platform! I asked it 3 different queries to help scrape and find some data points I was interested in about my own account and Scira did much much better with insanely accurate answers!',
    author: 'Chris Universe',
    handle: '@chrisuniverseb',
    link: 'https://x.com/chrisuniverseb/status/1943025911043100835',
  },
  {
    content: 'Scira does a really good job scraping through the reddit mines.',
    author: 'nyaaier',
    handle: '@nyaaier',
    link: 'https://x.com/nyaaier/status/1932810453107065284',
  },
  {
    content:
      "I searched for myself using Gemini 2.5 Pro in extreme mode to see what results it could generate. It is not just the best, it is wild. And the best part is it's 100% accurate.",
    author: 'Aniruddha Dak',
    handle: '@aniruddhadak',
    link: 'https://x.com/aniruddhadak/status/1917140602107445545',
  },
  {
    content:
      'Read nothing the whole sem and here I am with Scira to top my mid sems! Literally so good to get all the related diagrams, points and topics from the website my professor uses.',
    author: 'Rajnandinit',
    handle: '@itsRajnandinit',
    link: 'https://x.com/itsRajnandinit/status/1897896134837682288',
  },
];

const features = [
  { icon: Brain, label: 'Agentic Planning', description: 'Multi-step research, automated' },
  { icon: Search, label: 'Cited Answers', description: 'Every claim linked to a source' },
  { icon: Eye, label: 'Lookouts', description: 'Scheduled research, auto-delivered' },
  { icon: Mic, label: 'Voice Mode', description: 'Conversational AI research' },
  { icon: Blocks, label: 'Apps', description: '100+ connected tools via MCP' },
];

export default function AuthLayout({ children }: { children: React.ReactNode }) {
  const [api, setApi] = useState<CarouselApi>();
  const [current, setCurrent] = useState(0);

  useEffect(() => {
    if (!api) return;
    setCurrent(api.selectedScrollSnap());
    api.on('select', () => {
      setCurrent(api.selectedScrollSnap());
    });
  }, [api]);

  return (
    <div className="flex min-h-svh w-full bg-background">
      {/* Left Panel */}
      <div className="hidden lg:flex lg:w-[45%] xl:w-[50%] flex-col relative overflow-hidden">
        {/* Background */}
        <div className="absolute inset-0 pixel-grid-bg opacity-30" />
        <div className="absolute inset-0 bg-linear-to-br from-background via-background to-muted/30" />

        {/* Content */}
        <div className="relative flex-1 flex flex-col items-center justify-center px-12 xl:px-20">
          <div className="w-full max-w-md">
            {/* Logo */}
            <Link href="/" className="inline-flex items-center gap-3 mb-12 group">
              <SciraLogo className="size-10 transition-transform duration-300 group-hover:scale-110" />
              <span className="text-4xl font-light tracking-tighter font-be-vietnam-pro text-foreground">
                scira
              </span>
            </Link>

            {/* Tagline */}
            <div className="mb-12">
              <p className="text-2xl xl:text-3xl font-light tracking-tight leading-snug text-foreground/90 font-be-vietnam-pro">
                Research anything.
                <br />
                Do anything.
              </p>
              <p className="mt-4 text-sm text-muted-foreground leading-relaxed max-w-sm">
                Deep web research, cited answers, and 100+ connected apps. One assistant for everything you need.
              </p>
            </div>

            {/* Feature Pills */}
            <div className="grid grid-cols-2 gap-2.5 mb-12">
              {features.map((f) => (
                <div key={f.label} className="flex items-start gap-3 p-3 rounded-xl border border-border/30 bg-card/20">
                  <f.icon className="w-4 h-4 text-muted-foreground mt-0.5 shrink-0" />
                  <div>
                    <p className="text-xs font-medium text-foreground leading-tight">{f.label}</p>
                    <p className="text-[10px] text-muted-foreground leading-tight mt-0.5">{f.description}</p>
                  </div>
                </div>
              ))}
            </div>

            {/* Testimonial Carousel */}
            <div className="relative">
              <Carousel
                className="w-full"
                opts={{ loop: true }}
                setApi={setApi}
                plugins={[
                  Autoplay({
                    delay: 6000,
                    stopOnInteraction: true,
                    stopOnMouseEnter: true,
                  }),
                ]}
              >
                <CarouselContent>
                  {testimonials.map((testimonial, index) => (
                    <CarouselItem key={index}>
                      <Link
                        href={testimonial.link}
                        target="_blank"
                        className="block group/testimonial"
                      >
                        <div className="p-5 rounded-xl border border-border/50 bg-card/30 hover:bg-card hover:border-border transition-all duration-300">
                          <blockquote className="text-sm leading-relaxed text-muted-foreground group-hover/testimonial:text-foreground/80 transition-colors mb-4 line-clamp-3">
                            &ldquo;{testimonial.content}&rdquo;
                          </blockquote>
                          <div className="flex items-center gap-2">
                            <span className="text-sm font-medium text-foreground">
                              {testimonial.author}
                            </span>
                            <span className="text-xs text-muted-foreground font-pixel">
                              {testimonial.handle}
                            </span>
                          </div>
                        </div>
                      </Link>
                    </CarouselItem>
                  ))}
                </CarouselContent>
              </Carousel>

              {/* Indicators */}
              <div className="flex items-center gap-2 mt-5">
                {testimonials.map((_, index) => (
                  <button
                    key={index}
                    onClick={() => api?.scrollTo(index)}
                    className={`h-1 rounded-full transition-all duration-500 ${index === current
                        ? 'w-8 bg-foreground'
                        : 'w-2 bg-foreground/15 hover:bg-foreground/30'
                      }`}
                    aria-label={`Go to testimonial ${index + 1}`}
                  />
                ))}
              </div>
            </div>
          </div>
        </div>

        {/* Bottom Stats */}
        <div className="relative px-12 xl:px-20 pb-10">
          <div className="flex items-center gap-6 text-xs text-muted-foreground">
            {[
              { num: '5M+', label: 'searches' },
              { num: '100K+', label: 'users' },
              { num: '11K+', label: 'stars' },
            ].map((s, i) => (
              <div key={s.label} className="flex items-center gap-1.5">
                {i > 0 && <span className="w-px h-3 bg-border/50 mr-1.5" />}
                <span className="font-pixel">{s.num}</span>
                <span className="text-[10px]">{s.label}</span>
              </div>
            ))}
          </div>
        </div>
      </div>

      {/* Right Panel - Auth Form */}
      <div className="flex-1 lg:w-[55%] xl:w-[50%] flex flex-col bg-background lg:border-l lg:border-border/50">
        {/* Mobile Header */}
        <header className="lg:hidden flex items-center justify-between h-16 border-b border-border/50 px-6">
          <Link href="/" className="flex items-center gap-2.5">
            <SciraLogo className="size-6" />
            <span className="text-2xl font-light tracking-tighter font-be-vietnam-pro">scira</span>
          </Link>
          <div className="flex items-center gap-4 text-[10px] text-muted-foreground">
            <span className="font-pixel">5M+ searches</span>
            <span className="w-px h-3 bg-border/50" />
            <span className="font-pixel">100K+ users</span>
          </div>
        </header>

        {/* Form Container */}
        <div className="flex-1 flex items-center justify-center px-6 py-12">
          {children}
        </div>

        {/* Footer */}
        <footer className="flex items-center justify-center gap-6 h-12 text-xs text-muted-foreground px-6">
          <span>Trusted by researchers worldwide</span>
          <span className="w-px h-3 bg-border/30" />
          <Link href="/about" className="hover:text-foreground transition-colors">About</Link>
          <Link href="/terms" className="hover:text-foreground transition-colors">Terms</Link>
        </footer>
      </div>
    </div>
  );
}


================================================
FILE: app/(auth)/sign-in/page.tsx
================================================
import { Suspense } from 'react';
import AuthCard from '@/components/auth-card';

function SignInContent() {
  return (
    <AuthCard
      title="Welcome back"
      description="Sign in to access your research history and continue where you left off."
      mode="sign-in"
    />
  );
}

export default function SignInPage() {
  return (
    <Suspense>
      <SignInContent />
    </Suspense>
  );
}


================================================
FILE: app/(auth)/sign-up/page.tsx
================================================
import { Suspense } from 'react';
import AuthCard from '@/components/auth-card';

function SignUpContent() {
  return (
    <AuthCard
      title="Create an account"
      description="Join 100K+ researchers using AI-powered search with real-time citations."
      mode="sign-up"
    />
  );
}

export default function SignUpPage() {
  return (
    <Suspense>
      <SignUpContent />
    </Suspense>
  );
}


================================================
FILE: app/(content)/about/page.tsx
================================================
'use client';

import {
  Brain,
  Search,
  ArrowUpRight,
  ArrowRight,
  Bot,
  GraduationCap,
  Eye,
  Filter,
  X,
  Sparkles,
  Check,
  Quote,
  Globe,
  FileText,
  Mic,
  Code,
  BarChart3,
  Newspaper,
  BookOpen,
  Music,
  TrendingUp,
  MessageSquare,
  Bitcoin,
  Plug,
  Database,
  Headphones,
  ChartNoAxesCombined,
} from 'lucide-react';
import { AnimatedBeam } from '@/components/ui/animated-beam';
import Link from 'next/link';
import Image from 'next/image';
import React, { useState, useMemo, useEffect, useRef } from 'react';
import { cn } from '@/lib/utils';
import { Button } from '@/components/ui/button';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command';
import { useRouter } from 'next/navigation';
import { GithubLogoIcon, XLogoIcon } from '@phosphor-icons/react';
import {
  ProAccordion,
  ProAccordionItem,
  ProAccordionTrigger,
  ProAccordionContent,
} from '@/components/ui/pro-accordion';
import { useGitHubStars } from '@/hooks/use-github-stars';
import { models } from '@/ai/models';
import { VercelLogo } from '@/components/logos/vercel-logo';
import { ExaLogo } from '@/components/logos/exa-logo';
import { ElevenLabsLogo } from '@/components/logos/elevenlabs-logo';
import { PRICING, SEARCH_LIMITS } from '@/lib/constants';

import { ThemeSwitcher } from '@/components/theme-switcher';
import { SciraLogo } from '@/components/logos/scira-logo';
import { getSearchGroups } from '@/lib/utils';

const testimonials = [
  {
    content:
      'Scira is better than Grok at digging up information from X, its own platform! Scira did much much better with insanely accurate answers!',
    author: 'Chris Universe',
    handle: '@chrisuniverseb',
  },
  {
    content: 'Scira does a really good job scraping through the reddit mines.',
    author: 'nyaaier',
    handle: '@nyaaier',
  },
  {
    content:
      "I searched for myself using Gemini 2.5 Pro in extreme mode. It is not just the best, it is wild. And the best part is it's 100% accurate.",
    author: 'Aniruddha Dak',
    handle: '@aniruddhadak',
  },
  {
    content:
      'Read nothing the whole sem and here I am with Scira to top my mid sems! Literally so good to get all the related diagrams, points and topics.',
    author: 'Rajnandinit',
    handle: '@itsRajnandinit',
  },
];

function AnimatedCounter({ target, suffix = '' }: { target: string; suffix?: string }) {
  const ref = useRef<HTMLSpanElement>(null);
  const [visible, setVisible] = useState(false);

  useEffect(() => {
    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) setVisible(true);
      },
      { threshold: 0.5 },
    );
    if (ref.current) observer.observe(ref.current);
    return () => observer.disconnect();
  }, []);

  return (
    <span
      ref={ref}
      className={`transition-all duration-700 ${visible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-2'}`}
    >
      {target}
      {suffix}
    </span>
  );
}

const AppCircle = React.forwardRef<HTMLDivElement, { favicon: string; label: string; className?: string }>(
  ({ favicon, label, className }, ref) => (
    <div
      ref={ref}
      className={cn(
        'z-10 flex size-12 items-center justify-center rounded-full border-2 bg-background p-2.5 shadow-[0_0_20px_-12px_rgba(0,0,0,0.8)]',
        className,
      )}
    >
      {/* eslint-disable-next-line @next/next/no-img-element */}
      <img
        src={`/api/proxy-image?url=${encodeURIComponent(`https://www.google.com/s2/favicons?domain=${favicon}&sz=64`)}`}
        alt={label}
        width={24}
        height={24}
        className="rounded object-contain"
      />
    </div>
  ),
);
AppCircle.displayName = 'AppCircle';

function AppsBeamSection() {
  const containerRef = useRef<HTMLDivElement>(null);
  const centerRef = useRef<HTMLDivElement>(null);
  const l0 = useRef<HTMLDivElement>(null);
  const l1 = useRef<HTMLDivElement>(null);
  const l2 = useRef<HTMLDivElement>(null);
  const l3 = useRef<HTMLDivElement>(null);
  const l4 = useRef<HTMLDivElement>(null);
  const r0 = useRef<HTMLDivElement>(null);
  const r1 = useRef<HTMLDivElement>(null);
  const r2 = useRef<HTMLDivElement>(null);
  const r3 = useRef<HTMLDivElement>(null);
  const r4 = useRef<HTMLDivElement>(null);

  return (
    <section className="border-t border-border/50 bg-muted/10">
      <div className="max-w-6xl mx-auto px-6 py-24">
        <div className="text-center mb-16 max-w-xl mx-auto">
          <span className="font-pixel text-lg uppercase tracking-[0.2em] text-primary/80 mb-4 block">Apps</span>
          <h2 className="text-3xl sm:text-4xl font-light tracking-tight font-be-vietnam-pro mb-4">
            Your tools, <span className="font-pixel text-3xl sm:text-4xl">connected.</span>
          </h2>
          <p className="text-muted-foreground leading-relaxed">
            Connect 100+ apps via MCP and let Scira take action inside them. Research and act, without leaving the
            conversation.
          </p>
        </div>

        <div
          className="relative flex h-[600px] w-full items-center justify-center overflow-hidden p-14"
          ref={containerRef}
        >
          <div className="flex size-full max-h-[500px] max-w-2xl flex-col items-stretch justify-between">
            {/* Row 1 — top */}
            <div className="flex flex-row items-center justify-between">
              <AppCircle ref={l0} favicon="github.com" label="GitHub" />
              <AppCircle ref={r0} favicon="vercel.com" label="Vercel" />
            </div>
            {/* Row 2 */}
            <div className="flex flex-row items-center justify-between">
              <AppCircle ref={l1} favicon="notion.so" label="Notion" />
              <AppCircle ref={r1} favicon="stripe.com" label="Stripe" />
            </div>
            {/* Row 3 — center */}
            <div className="flex flex-row items-center justify-between">
              <AppCircle ref={l2} favicon="slack.com" label="Slack" />
              <div
                ref={centerRef}
                className="z-10 flex size-16 items-center justify-center rounded-2xl border-2 border-primary/30 bg-background p-3 shadow-[0_0_20px_-12px_rgba(0,0,0,0.8)]"
              >
                <SciraLogo className="size-8" />
              </div>
              <AppCircle ref={r2} favicon="linear.app" label="Linear" />
            </div>
            {/* Row 4 */}
            <div className="flex flex-row items-center justify-between">
              <AppCircle ref={l3} favicon="google.com" label="Google" />
              <AppCircle ref={r3} favicon="huggingface.co" label="Hugging Face" />
            </div>
            {/* Row 5 — bottom */}
            <div className="flex flex-row items-center justify-between">
              <AppCircle ref={l4} favicon="cloudflare.com" label="Cloudflare" />
              <AppCircle ref={r4} favicon="trivago.com" label="Trivago" />
            </div>
          </div>

          {/* Left beams */}
          <AnimatedBeam
            containerRef={containerRef}
            fromRef={l0}
            toRef={centerRef}
            curvature={-75}
            endYOffset={-10}
            gradientStartColor="var(--primary)"
            gradientStopColor="var(--secondary)"
          />
          <AnimatedBeam
            containerRef={containerRef}
            fromRef={l1}
            toRef={centerRef}
            curvature={-30}
            endYOffset={-5}
            gradientStartColor="var(--primary)"
            gradientStopColor="var(--secondary)"
          />
          <AnimatedBeam
            containerRef={containerRef}
            fromRef={l2}
            toRef={centerRef}
            gradientStartColor="var(--primary)"
            gradientStopColor="var(--secondary)"
          />
          <AnimatedBeam
            containerRef={containerRef}
            fromRef={l3}
            toRef={centerRef}
            curvature={30}
            endYOffset={5}
            gradientStartColor="var(--primary)"
            gradientStopColor="var(--secondary)"
          />
          <AnimatedBeam
            containerRef={containerRef}
            fromRef={l4}
            toRef={centerRef}
            curvature={75}
            endYOffset={10}
            gradientStartColor="var(--primary)"
            gradientStopColor="var(--secondary)"
          />
          {/* Right beams */}
          <AnimatedBeam
            containerRef={containerRef}
            fromRef={r0}
            toRef={centerRef}
            curvature={-75}
            endYOffset={-10}
            reverse
            gradientStartColor="var(--secondary)"
            gradientStopColor="var(--primary)"
          />
          <AnimatedBeam
            containerRef={containerRef}
            fromRef={r1}
            toRef={centerRef}
            curvature={-30}
            endYOffset={-5}
            reverse
            gradientStartColor="var(--secondary)"
            gradientStopColor="var(--primary)"
          />
          <AnimatedBeam
            containerRef={containerRef}
            fromRef={r2}
            toRef={centerRef}
            reverse
            gradientStartColor="var(--secondary)"
            gradientStopColor="var(--primary)"
          />
          <AnimatedBeam
            containerRef={containerRef}
            fromRef={r3}
            toRef={centerRef}
            curvature={30}
            endYOffset={5}
            reverse
            gradientStartColor="var(--secondary)"
            gradientStopColor="var(--primary)"
          />
          <AnimatedBeam
            containerRef={containerRef}
            fromRef={r4}
            toRef={centerRef}
            curvature={75}
            endYOffset={10}
            reverse
            gradientStartColor="var(--secondary)"
            gradientStopColor="var(--primary)"
          />
        </div>

        <div className="text-center mt-6">
          <Link
            href="/apps"
            className="inline-flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground transition-colors group"
          >
            Browse all apps
            <ArrowUpRight className="h-3.5 w-3.5 group-hover:translate-x-0.5 group-hover:-translate-y-0.5 transition-transform" />
          </Link>
        </div>
      </div>
    </section>
  );
}

export default function AboutPage() {
  const router = useRouter();
  const [selectedCategory, setSelectedCategory] = useState<string>('all');
  const [selectedCapabilities, setSelectedCapabilities] = useState<string[]>([]);
  const [openCategory, setOpenCategory] = useState(false);
  const [openCapabilities, setOpenCapabilities] = useState(false);
  const [showAllModels, setShowAllModels] = useState(false);
  const { data: githubStars, isLoading: isLoadingStars } = useGitHubStars();
  const visibleGroups = useMemo(
    () =>
      getSearchGroups('parallel').filter(
        (g) => g.show && !['extreme', 'connectors', 'memory'].includes(g.id as string),
      ),
    [],
  );
  const [selectedGroup, setSelectedGroup] = useState<string>(visibleGroups[0]?.id || 'web');

  const handleSearch = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    const formData = new FormData(e.currentTarget);
    const query = formData.get('query')?.toString();
    if (query) {
      const params = new URLSearchParams({ q: query, group: String(selectedGroup) });
      router.push(`/?${params.toString()}`);
    }
  };

  const searchModes = [
    { icon: Globe, name: 'Web', description: 'Search the entire web with AI-powered analysis' },
    { icon: MessageSquare, name: 'Chat', description: 'Talk to the model directly, no search' },
    { icon: XLogoIcon, name: 'X', description: 'Real-time posts, trends, and conversations' },
    { icon: TrendingUp, name: 'Stocks', description: 'Market data, charts, and financial analysis' },
    { icon: Code, name: 'Code', description: 'Get context about languages and frameworks' },
    { icon: BookOpen, name: 'Academic', description: 'Research papers, citations, and scholarly sources' },
    { icon: BarChart3, name: 'Extreme', description: 'Deep research with multiple sources and analysis' },
    { icon: Newspaper, name: 'Reddit', description: 'Discussions, opinions, and community insights' },
    { icon: Search, name: 'GitHub', description: 'Repositories, code, and developer discussions' },
    { icon: Bitcoin, name: 'Crypto', description: 'Cryptocurrency research powered by CoinGecko' },
    { icon: ChartNoAxesCombined, name: 'Prediction', description: 'Prediction markets from Polymarket and Kalshi' },
    { icon: Music, name: 'YouTube', description: 'Video summaries, transcripts, and analysis' },
    { icon: Headphones, name: 'Spotify', description: 'Search songs, artists, and albums' },
    { icon: Plug, name: 'Connectors', description: 'Search Google Drive, Notion & OneDrive', pro: true },
    { icon: Database, name: 'Memory', description: 'Your personal memory companion', pro: true },
    { icon: Mic, name: 'Voice', description: 'Conversational AI with real-time voice', pro: true },
    { icon: FileText, name: 'XQL', description: 'Advanced X query language for tweet analysis', pro: true },
  ];

  return (
    <div className="min-h-screen bg-background">
      {/* Navigation */}
      <header className="sticky top-0 z-50 bg-background/80 backdrop-blur-md border-b border-border/50">
        <div className="max-w-6xl mx-auto">
          <div className="flex items-center justify-between h-14 px-6">
            <Link href="/" className="flex items-center gap-2.5 group">
              <SciraLogo className="size-6 transition-transform duration-300 group-hover:scale-110" />
              <span className="text-xl font-light tracking-tighter font-be-vietnam-pro">scira</span>
            </Link>

            <nav className="hidden md:flex items-center gap-6">
              <Link href="/pricing" className="text-sm text-muted-foreground hover:text-foreground transition-colors">
                Pricing
              </Link>
              <Link
                href="https://git.new/scira"
                className="flex items-center gap-1.5 text-sm text-muted-foreground hover:text-foreground transition-colors"
                target="_blank"
              >
                <GithubLogoIcon className="h-3.5 w-3.5" />
                GitHub
                {!isLoadingStars && githubStars && (
                  <span className="text-[10px] tabular-nums text-muted-foreground/70">
                    {githubStars > 1000 ? `${(githubStars / 1000).toFixed(1)}k` : githubStars}
                  </span>
                )}
              </Link>
            </nav>

            <div className="flex items-center gap-3">
              <ThemeSwitcher />
              <Button size="sm" className="h-8 px-5 text-sm rounded-full font-medium" onClick={() => router.push('/')}>
                Try Scira
                <ArrowRight className="w-3 h-3 ml-1" />
              </Button>
            </div>
          </div>
        </div>
      </header>

      {/* Hero Section */}
      <section className="relative overflow-hidden">
        <div className="absolute inset-0 pixel-grid-bg opacity-40" />
        <div className="absolute inset-0 bg-linear-to-b from-transparent via-transparent to-background" />

        <div className="relative max-w-6xl mx-auto px-6 pt-20 sm:pt-32 pb-24">
          <div className="max-w-3xl">
            {/* Eyebrow */}
            <div className="animate-fade-in-up inline-flex items-center gap-2.5 mb-8 px-3 py-1.5 bg-muted/50 border border-border/50 rounded-full">
              <span className="font-pixel text-[10px] uppercase tracking-[0.2em] text-muted-foreground">
                Open Source
              </span>
              <span className="w-1 h-1 rounded-full bg-primary/60 animate-pulse-subtle" />
              <span className="font-pixel text-[10px] uppercase tracking-[0.2em] text-muted-foreground">AGPL-3.0</span>
            </div>

            {/* Title */}
            <h1 className="animate-fade-in-up delay-100 text-5xl sm:text-6xl lg:text-[5.5rem] font-light tracking-tight leading-[1.05] text-foreground font-be-vietnam-pro mb-3">
              Research anything.
            </h1>
            <p className="animate-fade-in-up delay-200 font-pixel text-5xl sm:text-6xl lg:text-7xl tracking-tight text-foreground/90 mb-8">
              Do anything.
            </p>

            {/* Description */}
            <p className="animate-fade-in-up delay-300 text-lg sm:text-xl text-muted-foreground leading-relaxed mb-10 max-w-xl">
              The AI assistant that searches the web in depth, cites its sources, and connects to 100+ apps so you can
              act on what you find.
            </p>

            {/* Search Form */}
            <form onSubmit={handleSearch} className="animate-fade-in-up delay-400 mb-8">
              <div className="flex flex-col sm:flex-row gap-3">
                <div className="flex-1 relative group">
                  <input
                    name="query"
                    type="text"
                    placeholder="Ask anything..."
                    className="w-full h-12 px-5 text-base bg-background border border-border rounded-xl focus:border-primary/50 focus:ring-2 focus:ring-primary/10 focus:outline-none transition-all placeholder:text-muted-foreground/60"
                  />
                </div>
                <Popover>
                  <PopoverTrigger asChild>
                    <button
                      type="button"
                      className="h-12 px-4 text-sm text-muted-foreground bg-background border border-border rounded-xl hover:border-primary/30 transition-all flex items-center justify-between gap-2 min-w-[140px]"
                    >
                      <span>{visibleGroups.find((g) => g.id === selectedGroup)?.name || 'Mode'}</span>
                      <ArrowUpRight className="h-3 w-3 opacity-50" />
                    </button>
                  </PopoverTrigger>
                  <PopoverContent align="start" className="p-0 w-64 rounded-xl">
                    <Command>
                      <CommandInput placeholder="Search modes..." className="h-10" />
                      <CommandList>
                        <CommandEmpty>No mode found.</CommandEmpty>
                        <CommandGroup>
                          {visibleGroups.map((g) => (
                            <CommandItem
                              key={g.id}
                              value={g.id}
                              onSelect={() => setSelectedGroup(g.id)}
                              className="text-sm"
                            >
                              <div className="flex flex-col">
                                <span className="font-medium">{g.name}</span>
                                <span className="text-xs text-muted-foreground">{g.description}</span>
                              </div>
                            </CommandItem>
                          ))}
                        </CommandGroup>
                      </CommandList>
                    </Command>
                  </PopoverContent>
                </Popover>
                <button
                  type="submit"
                  className="h-12 px-8 bg-foreground text-background font-medium rounded-xl hover:opacity-90 transition-all active:scale-[0.98]"
                >
                  Search
                </button>
              </div>
            </form>

            {/* Quick Links */}
            <div className="animate-fade-in-up delay-500 flex flex-wrap items-center gap-4">
              <Link
                href="https://git.new/scira"
                className="inline-flex items-center gap-2 text-sm text-foreground hover:text-foreground/70 transition-colors group"
                target="_blank"
              >
                <GithubLogoIcon className="h-4 w-4" />
                <span>Star on GitHub</span>
                {!isLoadingStars && githubStars && (
                  <span className="text-xs text-muted-foreground font-pixel">
                    {githubStars > 1000 ? `${(githubStars / 1000).toFixed(1)}k` : githubStars}
                  </span>
                )}
              </Link>
              <span className="w-px h-4 bg-border" />
              <Link
                href="/"
                className="inline-flex items-center gap-1.5 text-sm text-muted-foreground hover:text-foreground transition-colors group"
              >
                <span>Try now</span>
                <ArrowUpRight className="h-3 w-3 group-hover:translate-x-0.5 group-hover:-translate-y-0.5 transition-transform" />
              </Link>
            </div>
          </div>

          {/* Stats */}
          <div className="mt-20 lg:absolute lg:right-6 lg:top-32 lg:mt-0">
            <div className="flex lg:flex-col gap-10 lg:gap-8">
              {[
                { value: '5M', suffix: '+', label: 'Searches' },
                { value: '100K', suffix: '+', label: 'Users' },
                {
                  value: isLoadingStars
                    ? '...'
                    : `${githubStars && githubStars > 1000 ? `${(githubStars / 1000).toFixed(1)}k` : githubStars || '11k'}`,
                  suffix: '+',
                  label: 'Stars',
                },
              ].map((stat) => (
                <div key={stat.label}>
                  <div className="text-3xl lg:text-4xl font-pixel tracking-tight text-foreground">
                    <AnimatedCounter target={stat.value} suffix={stat.suffix} />
                  </div>
                  <div className="text-[10px] text-muted-foreground mt-1 font-medium uppercase tracking-[0.15em]">
                    {stat.label}
                  </div>
                </div>
              ))}
            </div>
          </div>
        </div>
      </section>

      {/* How It Works */}
      <section className="border-t border-border/50 bg-muted/10">
        <div className="max-w-6xl mx-auto px-6 py-24">
          <div className="text-center mb-16">
            <span className="font-pixel text-[10px] uppercase tracking-[0.2em] text-primary/80 mb-4 block">
              How it works
            </span>
            <h2 className="text-3xl sm:text-4xl font-light tracking-tight font-be-vietnam-pro">
              Three steps. <span className="font-pixel text-2xl sm:text-3xl">Zero friction.</span>
            </h2>
          </div>

          <div className="grid grid-cols-1 md:grid-cols-3 gap-8 max-w-4xl mx-auto">
            {[
              {
                step: '01',
                title: 'Ask anything',
                description: 'Type a question, upload a PDF, or paste a URL. Pick a mode or let Scira decide for you.',
              },
              {
                step: '02',
                title: 'Scira plans & retrieves',
                description:
                  'The agent breaks your question into sub-tasks, searches live sources, and cross-checks the evidence.',
              },
              {
                step: '03',
                title: 'Get cited answers',
                description: 'Receive a grounded answer with inline citations. Click any source to verify it yourself.',
              },
            ].map((item) => (
              <div key={item.step} className="relative text-center group">
                <div className="font-pixel-grid text-7xl sm:text-8xl text-border/60 group-hover:text-primary/15 transition-colors duration-500 mb-3 select-none">
                  {item.step}
                </div>
                <h3 className="text-base font-semibold mb-2 text-foreground">{item.title}</h3>
                <p className="text-sm text-muted-foreground leading-relaxed">{item.description}</p>
              </div>
            ))}
          </div>

          {/* CTA */}
          <div className="text-center mt-14">
            <Button className="rounded-full px-8 h-11" onClick={() => router.push('/')}>
              Try it now &mdash; it&apos;s free
              <ArrowRight className="w-3.5 h-3.5 ml-2" />
            </Button>
          </div>
        </div>
      </section>

      {/* Features - Bento Grid */}
      <section className="border-t border-border/50">
        <div className="max-w-6xl mx-auto px-6 py-24">
          <div className="mb-16 max-w-lg">
            <span className="font-pixel text-[10px] uppercase tracking-[0.2em] text-primary/80 mb-4 block">
              Capabilities
            </span>
            <h2 className="text-3xl sm:text-4xl font-light tracking-tight font-be-vietnam-pro mb-4">
              Built for the way <span className="font-pixel text-3xl sm:text-4xl">you</span> think
            </h2>
            <p className="text-muted-foreground leading-relaxed">
              Research, plan, connect, and act. Everything in one place.
            </p>
          </div>

          {/* Bento Grid */}
          <div className="grid grid-cols-1 md:grid-cols-6 gap-4">
            {/* Large card - Agentic Planning */}
            <div className="md:col-span-4 group p-8 sm:p-10 rounded-2xl border border-border/50 bg-card/50 hover:bg-card hover:border-border transition-all duration-300 min-h-[240px]">
              <div className="flex items-start justify-between mb-6">
                <Brain className="h-6 w-6 text-muted-foreground group-hover:text-foreground transition-colors" />
                <span className="font-pixel-grid text-5xl text-border/40 group-hover:text-border/60 transition-colors select-none leading-none">
                  01
                </span>
              </div>
              <h3 className="text-xl font-semibold mb-3 text-foreground">Agentic Planning</h3>
              <p className="text-sm text-muted-foreground leading-relaxed max-w-md mb-6">
                Breaks complex questions into steps, selects the right models and tools, then executes multi-step
                workflows end to end. Ask one question, get a research report.
              </p>
              <div className="flex flex-wrap items-center gap-2">
                {['Multi-step reasoning', 'Tool orchestration', 'Auto-planning'].map((tag) => (
                  <span
                    key={tag}
                    className="font-pixel text-[9px] uppercase tracking-wider text-muted-foreground bg-muted/50 px-2.5 py-1 rounded-full"
                  >
                    {tag}
                  </span>
                ))}
              </div>
            </div>

            {/* Small card - Grounded Retrieval */}
            <div className="md:col-span-2 group p-8 rounded-2xl border border-border/50 bg-card/50 hover:bg-card hover:border-border transition-all duration-300 min-h-[240px]">
              <div className="flex items-start justify-between mb-6">
                <Search className="h-6 w-6 text-muted-foreground group-hover:text-foreground transition-colors" />
                <span className="font-pixel-grid text-5xl text-border/40 group-hover:text-border/60 transition-colors select-none leading-none">
                  02
                </span>
              </div>
              <h3 className="text-lg font-semibold mb-3 text-foreground">Grounded Retrieval</h3>
              <p className="text-sm text-muted-foreground leading-relaxed">
                Every answer comes with inline citations. Click any source to audit the evidence yourself.
              </p>
            </div>

            {/* Small card - Extensible & Open */}
            <div className="md:col-span-2 group p-8 rounded-2xl border border-border/50 bg-card/50 hover:bg-card hover:border-border transition-all duration-300 min-h-[240px]">
              <div className="flex items-start justify-between mb-6">
                <Bot className="h-6 w-6 text-muted-foreground group-hover:text-foreground transition-colors" />
                <span className="font-pixel-grid text-5xl text-border/40 group-hover:text-border/60 transition-colors select-none leading-none">
                  03
                </span>
              </div>
              <h3 className="text-lg font-semibold mb-3 text-foreground">Extensible & Open</h3>
              <p className="text-sm text-muted-foreground leading-relaxed">
                AGPL-3.0. Self-host, bring your own models, connect custom tools, and tailor everything to your
                workflow.
              </p>
            </div>

            {/* Large card - Lookouts */}
            <div className="md:col-span-4 group p-8 sm:p-10 rounded-2xl border border-border/50 bg-card/50 hover:bg-card hover:border-border transition-all duration-300 min-h-[240px]">
              <div className="flex items-start justify-between mb-6">
                <Eye className="h-6 w-6 text-muted-foreground group-hover:text-foreground transition-colors" />
                <span className="font-pixel-grid text-5xl text-border/40 group-hover:text-border/60 transition-colors select-none leading-none">
                  04
                </span>
              </div>
              <h3 className="text-xl font-semibold mb-3 text-foreground">Lookouts</h3>
              <p className="text-sm text-muted-foreground leading-relaxed max-w-md mb-6">
                Schedule recurring research agents that monitor topics, track changes, and email you updates. Set it
                once, stay informed forever.
              </p>
              <div className="flex flex-wrap items-center gap-2">
                {['Scheduled runs', 'Email alerts', 'Change detection'].map((tag) => (
                  <span
                    key={tag}
                    className="font-pixel text-[9px] uppercase tracking-wider text-muted-foreground bg-muted/50 px-2.5 py-1 rounded-full"
                  >
                    {tag}
                  </span>
                ))}
              </div>
            </div>
          </div>
        </div>
      </section>

      {/* Search Modes Showcase */}
      <section className="border-t border-border/50 bg-muted/10">
        <div className="max-w-6xl mx-auto px-6 py-24">
          <div className="flex flex-col lg:flex-row lg:items-end lg:justify-between gap-6 mb-12">
            <div className="max-w-lg">
              <span className="font-pixel text-[10px] uppercase tracking-[0.2em] text-primary/80 mb-4 block">
                {searchModes.length} Modes
              </span>
              <h2 className="text-3xl sm:text-4xl font-light tracking-tight font-be-vietnam-pro mb-4">
                One box, <span className="font-pixel text-3xl sm:text-4xl">every</span> source
              </h2>
              <p className="text-muted-foreground leading-relaxed">
                Each mode is fine-tuned for a specific type of research. Pick one, or let Scira choose.
              </p>
            </div>
            <div className="flex items-center gap-3">
              <span className="font-pixel text-[9px] uppercase tracking-wider text-muted-foreground bg-muted/50 px-2.5 py-1 rounded-full">
                {searchModes.filter((m) => !('pro' in m && m.pro)).length} Free
              </span>
              <span className="font-pixel text-[9px] uppercase tracking-wider text-primary bg-primary/10 px-2.5 py-1 rounded-full">
                {searchModes.filter((m) => 'pro' in m && m.pro).length} Pro
              </span>
            </div>
          </div>

          <div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-3">
            {searchModes.map((mode, i) => (
              <div
                key={mode.name}
                className="group relative p-4 sm:p-5 rounded-2xl border border-border/50 bg-card/30 hover:bg-card hover:border-border transition-all duration-200 cursor-default"
              >
                <div className="flex items-start justify-between mb-4">
                  <mode.icon className="h-5 w-5 text-muted-foreground group-hover:text-foreground transition-colors" />
                  {'pro' in mode && mode.pro ? (
                    <span className="font-pixel text-[8px] uppercase tracking-wider text-primary bg-primary/10 px-1.5 py-0.5 rounded-full">
                      Pro
                    </span>
                  ) : (
                    <span className="font-pixel-grid text-lg text-border/40 select-none leading-none">
                      {String(i + 1).padStart(2, '0')}
                    </span>
                  )}
                </div>
                <h3 className="text-xs sm:text-sm font-medium text-foreground mb-1">{mode.name}</h3>
                <p className="text-[10px] sm:text-[11px] text-muted-foreground leading-relaxed">{mode.description}</p>
              </div>
            ))}
          </div>
        </div>
      </section>

      {/* Apps Section */}
      <AppsBeamSection />

      {/* Testimonials */}
      <section className="border-t border-border/50">
        <div className="max-w-6xl mx-auto px-6 py-24">
          <div className="text-center mb-16 max-w-lg mx-auto">
            <span className="font-pixel text-[10px] uppercase tracking-[0.2em] text-primary/80 mb-4 block">
              Wall of Love
            </span>
            <h2 className="text-3xl sm:text-4xl font-light tracking-tight font-be-vietnam-pro">
              Don&apos;t take our word for it
            </h2>
          </div>

          <div className="grid grid-cols-1 sm:grid-cols-2 gap-4 max-w-4xl mx-auto">
            {testimonials.map((t) => (
              <div
                key={t.handle}
                className="p-6 rounded-2xl border border-border/50 bg-card/30 hover:bg-card hover:border-border transition-all duration-200"
              >
                <Quote className="h-4 w-4 text-primary/40 mb-4" />
                <p className="text-sm text-foreground/80 leading-relaxed mb-5">{t.content}</p>
                <div className="flex items-center gap-2">
                  <span className="text-sm font-medium text-foreground">{t.author}</span>
                  <span className="text-xs text-muted-foreground font-pixel">{t.handle}</span>
                </div>
              </div>
            ))}
          </div>
        </div>
      </section>

      {/* Social Proof Marquee */}
      <section className="border-t border-border/50 bg-muted/20 overflow-hidden">
        <div className="max-w-6xl mx-auto px-6 py-12">
          <div className="flex flex-col md:flex-row md:items-center md:justify-between gap-8">
            <div className="flex flex-wrap items-center gap-8">
              <div className="flex items-center gap-3 group">
                <Image
                  src="https://cdn.prod.website-files.com/657b3d8ca1cab4015f06c850/680a4d679063da73487739e0_No1prgold-caps-removebg-preview.png"
                  alt="Tiny Startups"
                  width={28}
                  height={28}
                  className="opacity-50 group-hover:opacity-100 transition-opacity duration-300"
                />
                <div>
                  <p className="text-xs font-semibold text-foreground">#1 Product</p>
                  <p className="text-[10px] text-muted-foreground font-pixel uppercase tracking-wider">Tiny Startups</p>
                </div>
              </div>
              <span className="w-px h-8 bg-border/50" />
              <div className="flex items-center gap-3 group">
                <Image
                  src="/Winner-Medal-Weekly.svg"
                  alt="Peerlist"
                  width={28}
                  height={28}
                  className="opacity-50 group-hover:opacity-100 transition-opacity duration-300"
                />
                <div>
                  <p className="text-xs font-semibold text-foreground">#1 Project</p>
                  <p className="text-[10px] text-muted-foreground font-pixel uppercase tracking-wider">Peerlist</p>
                </div>
              </div>
            </div>
            <a
              href="https://openalternative.co/scira?utm_source=openalternative&utm_medium=badge&utm_campaign=embed&utm_content=tool-scira"
              target="_blank"
              className="opacity-50 hover:opacity-100 transition-opacity duration-300"
            >
              <Image
                src="https://openalternative.co/scira/badge.svg?theme=dark&width=200&height=50"
                width={150}
                height={38}
                alt="Scira badge"
              />
            </a>
          </div>
        </div>
      </section>

      {/* Built With */}
      <section className="border-t border-border/50">
        <div className="max-w-6xl mx-auto px-6 py-14">
          <div className="flex flex-col md:flex-row md:items-center gap-8 md:gap-16">
            <span className="font-pixel text-[10px] uppercase tracking-[0.2em] text-muted-foreground shrink-0">
              Built with
            </span>
            <div className="flex flex-wrap items-center gap-10 md:gap-14">
              {[
                { logo: VercelLogo, name: 'Vercel AI SDK' },
                { logo: ExaLogo, name: 'Exa Search' },
                { logo: ElevenLabsLogo, name: 'ElevenLabs' },
              ].map((partner) => (
                <div
                  key={partner.name}
                  className="flex items-center gap-3 opacity-50 hover:opacity-100 transition-opacity duration-300"
                >
                  <partner.logo />
                  <span className="text-sm text-muted-foreground">{partner.name}</span>
                </div>
              ))}
            </div>
          </div>
        </div>
      </section>

      {/* Featured on Vercel */}
      <section className="border-t border-border/50">
        <div className="max-w-7xl mx-auto">
          <div className="grid grid-cols-1 lg:grid-cols-2">
            <div className="px-6 py-20 lg:py-28 lg:pr-16 relative">
              {/* Decorative number */}
              <span className="font-pixel-grid text-[120px] sm:text-[160px] text-border/20 absolute -top-4 -left-4 select-none leading-none pointer-events-none">
                V
              </span>
              <div className="relative">
                <span className="font-pixel text-[10px] uppercase tracking-[0.2em] text-primary/80 mb-4 block">
                  Press
                </span>
                <h2 className="text-3xl sm:text-4xl font-light tracking-tight font-be-vietnam-pro mb-2">Featured on</h2>
                <p className="font-pixel text-3xl sm:text-4xl text-foreground/90 mb-6">Vercel Blog</p>
                <p className="text-sm text-muted-foreground leading-relaxed mb-8 max-w-md">
                  Recognized for innovative use of AI technology and pushing the boundaries of what&apos;s possible with
                  the Vercel AI SDK.
                </p>
                <Link
                  href="https://vercel.com/blog/ai-sdk-4-1"
                  className="inline-flex items-center gap-2 text-sm font-medium text-foreground hover:text-foreground/70 transition-colors group px-5 py-2.5 border border-border rounded-full hover:border-foreground/20"
                  target="_blank"
                >
                  Read the feature
                  <ArrowUpRight className="h-3 w-3 group-hover:translate-x-0.5 group-hover:-translate-y-0.5 transition-transform" />
                </Link>
              </div>
            </div>
            <div className="relative aspect-video lg:aspect-auto lg:h-full border-t lg:border-t-0 lg:border-l border-border/50 overflow-hidden">
              <Image src="/vercel-featured.png" alt="Featured on Vercel Blog" fill className="object-cover" />
            </div>
          </div>
        </div>
      </section>

      {/* Inline CTA */}
      <section className="border-t border-border/50 bg-muted/10">
        <div className="max-w-6xl mx-auto px-6 py-20">
          <div className="max-w-2xl mx-auto text-center">
            <h2 className="text-2xl sm:text-3xl font-light tracking-tight font-be-vietnam-pro mb-4">
              Ready to <span className="font-pixel">think faster?</span>
            </h2>
            <p className="text-muted-foreground mb-8 max-w-md mx-auto">
              Join 100K+ users who research smarter and get things done with Scira.
            </p>
            <div className="flex items-center justify-center gap-4">
              <Button className="rounded-full px-8 h-11" onClick={() => router.push('/')}>
                Start for free
                <ArrowRight className="w-3.5 h-3.5 ml-2" />
              </Button>
              <Button variant="outline" className="rounded-full px-8 h-11" onClick={() => router.push('/pricing')}>
                See pricing
              </Button>
            </div>
          </div>
        </div>
      </section>

      {/* Models Section */}
      <section className="border-t border-border/50">
        <div className="max-w-6xl mx-auto px-6 py-24">
          <div className="flex flex-col lg:flex-row lg:items-end lg:justify-between gap-6 mb-12">
            <div className="max-w-lg">
              <span className="font-pixel text-[10px] uppercase tracking-[0.2em] text-primary/80 mb-4 block">
                AI Providers
              </span>
              <h2 className="text-3xl sm:text-4xl font-light tracking-tight font-be-vietnam-pro mb-4">
                Every model, <span className="font-pixel text-3xl sm:text-4xl">one place</span>
              </h2>
              <p className="text-muted-foreground leading-relaxed">
                Switch between models on the fly. Use the best tool for each question.
              </p>
            </div>
            <div className="font-pixel-grid text-6xl sm:text-7xl text-border/30 select-none leading-none shrink-0">
              {models.length}
            </div>
          </div>

          {/* Filter Controls */}
          <div className="flex flex-wrap gap-3 mb-8">
            <Popover open={openCategory} onOpenChange={setOpenCategory}>
              <PopoverTrigger asChild>
                <Button
                  variant="outline"
                  role="combobox"
                  aria-expanded={openCategory}
                  className="h-9 justify-between rounded-full text-xs"
                >
                  {selectedCategory === 'all' ? 'All Categories' : selectedCategory}
                  <ArrowUpRight className="ml-2 h-3 w-3 opacity-50" />
                </Button>
              </PopoverTrigger>
              <PopoverContent className="w-[200px] p-0 rounded-xl">
                <Command>
                  <CommandInput placeholder="Search..." className="h-9" />
                  <CommandList>
                    <CommandEmpty>No category found.</CommandEmpty>
                    <CommandGroup>
                      {[
                        { value: 'all', label: 'All Categories' },
                        { value: 'Free', label: 'Free' },
                        { value: 'Pro', label: 'Pro' },
                        { value: 'Experimental', label: 'Experimental' },
                      ].map((category) => (
                        <CommandItem
                          key={category.value}
                          value={category.value}
                          onSelect={(v) => {
                            setSelectedCategory(v);
                            setOpenCategory(false);
                          }}
                        >
                          {category.label}
                        </CommandItem>
                      ))}
                    </CommandGroup>
                  </CommandList>
                </Command>
              </PopoverContent>
            </Popover>

            <Popover open={openCapabilities} onOpenChange={setOpenCapabilities}>
              <PopoverTrigger asChild>
                <Button
                  variant="outline"
                  role="combobox"
                  aria-expanded={openCapabilities}
                  className="h-9 justify-between rounded-full text-xs"
                >
                  {selectedCapabilities.length === 0
                    ? 'All Capabilities'
                    : selectedCapabilities.length === 1
                      ? selectedCapabilities[0]
                      : `${selectedCapabilities.length} selected`}
                  <ArrowUpRight className="ml-2 h-3 w-3 opacity-50" />
                </Button>
              </PopoverTrigger>
              <PopoverContent className="w-[200px] p-0 rounded-xl">
                <Command>
                  <CommandInput placeholder="Search..." className="h-9" />
                  <CommandList>
                    <CommandEmpty>No capability found.</CommandEmpty>
                    <CommandGroup>
                      {[
                        { value: 'vision', label: 'Vision' },
                        { value: 'reasoning', label: 'Reasoning' },
                        { value: 'pdf', label: 'PDF' },
                      ].map((capability) => (
                
Download .txt
gitextract_hejsnn8z/

├── .dockerignore
├── .eslintrc.json
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── config.yml
│   │   └── feature_request.md
│   └── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .prettierrc
├── .vercelignore
├── .vscode/
│   └── settings.json
├── Dockerfile
├── LICENSE
├── README.md
├── ai/
│   ├── models.ts
│   └── providers.ts
├── app/
│   ├── (auth)/
│   │   ├── layout.tsx
│   │   ├── sign-in/
│   │   │   └── page.tsx
│   │   └── sign-up/
│   │       └── page.tsx
│   ├── (content)/
│   │   ├── about/
│   │   │   └── page.tsx
│   │   ├── layout.tsx
│   │   ├── privacy-policy/
│   │   │   └── page.tsx
│   │   ├── terms/
│   │   │   └── page.tsx
│   │   └── x-wrapped/
│   │       ├── [username]/
│   │       │   └── page.tsx
│   │       ├── layout.tsx
│   │       └── page.tsx
│   ├── (search)/
│   │   └── page.tsx
│   ├── actions.ts
│   ├── api/
│   │   ├── auth/
│   │   │   └── [...all]/
│   │   │       └── route.ts
│   │   ├── clean_images/
│   │   │   └── route.ts
│   │   ├── export/
│   │   │   ├── docx/
│   │   │   │   └── route.ts
│   │   │   └── pdf/
│   │   │       └── route.ts
│   │   ├── lookout/
│   │   │   └── route.ts
│   │   ├── mcp/
│   │   │   ├── apps/
│   │   │   │   ├── bridge/
│   │   │   │   │   └── route.ts
│   │   │   │   └── resource/
│   │   │   │       └── read/
│   │   │   │           └── route.ts
│   │   │   ├── elicitation/
│   │   │   │   └── respond/
│   │   │   │       └── route.ts
│   │   │   ├── oauth/
│   │   │   │   ├── callback/
│   │   │   │   │   └── route.ts
│   │   │   │   └── client-metadata/
│   │   │   │       └── [serverId]/
│   │   │   │           └── route.ts
│   │   │   └── servers/
│   │   │       ├── [id]/
│   │   │       │   ├── oauth/
│   │   │       │   │   ├── callback/
│   │   │       │   │   │   └── route.ts
│   │   │       │   │   ├── disconnect/
│   │   │       │   │   │   └── route.ts
│   │   │       │   │   └── start/
│   │   │       │   │       └── route.ts
│   │   │       │   ├── route.ts
│   │   │       │   └── tools/
│   │   │       │       └── route.ts
│   │   │       ├── route.ts
│   │   │       └── test/
│   │   │           └── route.ts
│   │   ├── og/
│   │   │   ├── chat/
│   │   │   │   └── [id]/
│   │   │   │       └── route.tsx
│   │   │   └── x-wrapped/
│   │   │       └── route.tsx
│   │   ├── preferences/
│   │   │   └── route.ts
│   │   ├── proxy-image/
│   │   │   └── route.ts
│   │   ├── raycast/
│   │   │   └── route.ts
│   │   ├── search/
│   │   │   ├── [id]/
│   │   │   │   ├── stop/
│   │   │   │   │   └── route.ts
│   │   │   │   └── stream/
│   │   │   │       └── route.ts
│   │   │   └── route.ts
│   │   ├── suggest/
│   │   │   └── route.ts
│   │   ├── transcribe/
│   │   │   └── route.ts
│   │   ├── upload/
│   │   │   └── route.ts
│   │   ├── x-wrapped/
│   │   │   └── route.ts
│   │   └── xql/
│   │       └── route.ts
│   ├── apps/
│   │   ├── layout.tsx
│   │   └── page.tsx
│   ├── connectors/
│   │   └── [provider]/
│   │       └── callback/
│   │           └── page.tsx
│   ├── error.tsx
│   ├── global-error.tsx
│   ├── globals.css
│   ├── layout.tsx
│   ├── lookout/
│   │   ├── components/
│   │   │   ├── action-buttons.tsx
│   │   │   ├── empty-state.tsx
│   │   │   ├── index.ts
│   │   │   ├── loading-skeleton.tsx
│   │   │   ├── lookout-card.tsx
│   │   │   ├── lookout-details-sidebar.tsx
│   │   │   ├── lookout-form.tsx
│   │   │   ├── pro-upgrade-screen.tsx
│   │   │   ├── run-status-badge.tsx
│   │   │   ├── status-badge.tsx
│   │   │   ├── time-picker.tsx
│   │   │   ├── timezone-selector.tsx
│   │   │   └── warning-card.tsx
│   │   ├── constants.ts
│   │   ├── hooks/
│   │   │   └── use-lookout-form.ts
│   │   ├── layout.tsx
│   │   ├── page.tsx
│   │   └── utils/
│   │       └── time-utils.ts
│   ├── manifest.ts
│   ├── new/
│   │   └── page.tsx
│   ├── not-found.tsx
│   ├── pricing/
│   │   ├── _component/
│   │   │   └── pricing-table.tsx
│   │   └── page.tsx
│   ├── providers.tsx
│   ├── robots.txt
│   ├── search/
│   │   └── [id]/
│   │       ├── loading-old.tsx
│   │       └── page.tsx
│   ├── searches/
│   │   └── page.tsx
│   ├── settings/
│   │   └── page.tsx
│   ├── share/
│   │   └── [id]/
│   │       └── page.tsx
│   ├── success/
│   │   └── page.tsx
│   ├── voice/
│   │   ├── components/
│   │   │   └── pro-upgrade-screen.tsx
│   │   ├── layout.tsx
│   │   └── page.tsx
│   └── xql/
│       └── page.tsx
├── components/
│   ├── InstallPrompt.tsx
│   ├── academic-papers.tsx
│   ├── ai-elements/
│   │   └── web-preview.tsx
│   ├── app-sidebar.tsx
│   ├── auth-card.tsx
│   ├── build-search.tsx
│   ├── canvas-renderer.tsx
│   ├── charts/
│   │   ├── area-chart.tsx
│   │   ├── area.tsx
│   │   ├── bar-chart.tsx
│   │   ├── bar-x-axis.tsx
│   │   ├── bar-y-axis.tsx
│   │   ├── bar.tsx
│   │   ├── chart-context.tsx
│   │   ├── grid.tsx
│   │   ├── line-chart.tsx
│   │   ├── line.tsx
│   │   ├── tooltip/
│   │   │   ├── chart-tooltip.tsx
│   │   │   ├── date-ticker.tsx
│   │   │   ├── index.ts
│   │   │   ├── tooltip-box.tsx
│   │   │   ├── tooltip-content.tsx
│   │   │   ├── tooltip-dot.tsx
│   │   │   └── tooltip-indicator.tsx
│   │   └── x-axis.tsx
│   ├── chat-dialogs.tsx
│   ├── chat-history-dialog.tsx
│   ├── chat-interface.tsx
│   ├── chat-state.ts
│   ├── chat-text-highlighter.tsx
│   ├── client-analytics.tsx
│   ├── connectors-search-results.tsx
│   ├── core/
│   │   ├── border-trail.tsx
│   │   ├── sliding-number.tsx
│   │   ├── text-loop.tsx
│   │   └── text-shimmer.tsx
│   ├── crypto-charts.tsx
│   ├── crypto-coin-data.tsx
│   ├── currency_conv.tsx
│   ├── data-stream-provider.tsx
│   ├── dialogs/
│   │   ├── share-dialog.tsx
│   │   └── use-share-dialog.tsx
│   ├── emails/
│   │   └── lookout-completed.tsx
│   ├── example-categories.tsx
│   ├── extreme-search.tsx
│   ├── file-query-search.tsx
│   ├── flight-tracker.tsx
│   ├── github-search.tsx
│   ├── haptics-provider.tsx
│   ├── icons/
│   │   ├── agent-network-icon.tsx
│   │   ├── apps-icon.tsx
│   │   └── mcp-logo.tsx
│   ├── interactive-charts.tsx
│   ├── interactive-maps.tsx
│   ├── interactive-stock-chart.tsx
│   ├── keyboard-shortcuts-dialog.tsx
│   ├── kibo-ui/
│   │   └── table/
│   │       └── index.tsx
│   ├── list-view.tsx
│   ├── logos/
│   │   ├── elevenlabs-logo.tsx
│   │   ├── exa-logo.tsx
│   │   ├── sarvam-logo.tsx
│   │   ├── scira-logo.tsx
│   │   └── vercel-logo.tsx
│   ├── map-components.tsx
│   ├── markdown.tsx
│   ├── mcp-elicitation-modal.tsx
│   ├── mcp-server-list.tsx
│   ├── memory-dialog.tsx
│   ├── message-parts/
│   │   └── index.tsx
│   ├── message.tsx
│   ├── messages.tsx
│   ├── movie-info.tsx
│   ├── multi-search.tsx
│   ├── nearby-search-map-view.tsx
│   ├── new-chat-hotkey.tsx
│   ├── onchain-crypto-components.tsx
│   ├── place-card.tsx
│   ├── placeholder-image.tsx
│   ├── prediction-search.tsx
│   ├── reasoning-part.tsx
│   ├── reddit-search.tsx
│   ├── retrieve-results.tsx
│   ├── reui/
│   │   ├── stepper.tsx
│   │   └── timeline.tsx
│   ├── scira-logo-header.tsx
│   ├── searches-page.tsx
│   ├── settings/
│   │   └── theme-previews.tsx
│   ├── settings-dialog.tsx
│   ├── share/
│   │   ├── index.tsx
│   │   ├── share-attachments-badge.tsx
│   │   ├── share-button.tsx
│   │   └── share-dialog.tsx
│   ├── share-viewer.tsx
│   ├── sidebar-layout.tsx
│   ├── sign-in-prompt-dialog.tsx
│   ├── spotify-search-results.tsx
│   ├── student-domain-request-button.tsx
│   ├── supported-domains-list.tsx
│   ├── text-translate.tsx
│   ├── theme-switcher.tsx
│   ├── tool-invocation-list-view.tsx
│   ├── trending-tv-movies-results.tsx
│   ├── ui/
│   │   ├── accordion.tsx
│   │   ├── alert-dialog.tsx
│   │   ├── alert.tsx
│   │   ├── animated-beam.tsx
│   │   ├── audio-lines.tsx
│   │   ├── audio-player.tsx
│   │   ├── avatar.tsx
│   │   ├── badge.tsx
│   │   ├── button-group.tsx
│   │   ├── button.tsx
│   │   ├── calendar.tsx
│   │   ├── card.tsx
│   │   ├── carousel.tsx
│   │   ├── chart.tsx
│   │   ├── checkbox.tsx
│   │   ├── collapsible.tsx
│   │   ├── command.tsx
│   │   ├── dialog.tsx
│   │   ├── drawer.tsx
│   │   ├── dropdown-menu.tsx
│   │   ├── empty.tsx
│   │   ├── form-component.tsx
│   │   ├── form.tsx
│   │   ├── grip.tsx
│   │   ├── hover-card.tsx
│   │   ├── hugeicons.tsx
│   │   ├── input-group.tsx
│   │   ├── input.tsx
│   │   ├── kbd.tsx
│   │   ├── kibo-ui/
│   │   │   └── contribution-graph/
│   │   │       └── index.tsx
│   │   ├── label.tsx
│   │   ├── live-waveform.tsx
│   │   ├── loading.tsx
│   │   ├── magic-edit-icon.tsx
│   │   ├── magic-wand-icon.tsx
│   │   ├── matrix.tsx
│   │   ├── model-selector.tsx
│   │   ├── navigation-menu.tsx
│   │   ├── orb.tsx
│   │   ├── popover.tsx
│   │   ├── pro-accordion.tsx
│   │   ├── processor-icon.tsx
│   │   ├── progress-ring.tsx
│   │   ├── progress.tsx
│   │   ├── scroll-area.tsx
│   │   ├── scrub-bar.tsx
│   │   ├── select.tsx
│   │   ├── separator.tsx
│   │   ├── settings.tsx
│   │   ├── sheet.tsx
│   │   ├── sidebar.tsx
│   │   ├── sileo-toaster.tsx
│   │   ├── skeleton.tsx
│   │   ├── sonner.tsx
│   │   ├── spinner.tsx
│   │   ├── switch.tsx
│   │   ├── table.tsx
│   │   ├── tabs.tsx
│   │   ├── text-rotate.tsx
│   │   ├── textarea.tsx
│   │   ├── tooltip.tsx
│   │   ├── transcript-viewer.tsx
│   │   ├── voice-button.tsx
│   │   └── voice-picker.tsx
│   ├── user-cache-status.tsx
│   ├── weather-chart.tsx
│   ├── x-search.tsx
│   ├── xql-pro-upgrade-screen.tsx
│   └── youtube-search-results.tsx
├── components.json
├── contexts/
│   └── user-context.tsx
├── docker-compose.yml
├── drizzle/
│   └── migrations/
│       └── meta/
│           ├── 0000_snapshot.json
│           ├── 0001_snapshot.json
│           ├── 0002_snapshot.json
│           ├── 0003_snapshot.json
│           ├── 0004_snapshot.json
│           ├── 0005_snapshot.json
│           ├── 0006_snapshot.json
│           ├── 0007_snapshot.json
│           ├── 0008_snapshot.json
│           ├── 0009_snapshot.json
│           ├── 0010_snapshot.json
│           ├── 0011_snapshot.json
│           └── _journal.json
├── drizzle.config.ts
├── env/
│   ├── client.ts
│   └── server.ts
├── hooks/
│   ├── use-auto-resume.ts
│   ├── use-cached-user-data.tsx
│   ├── use-chat-prefetch.ts
│   ├── use-github-stars.ts
│   ├── use-local-storage.tsx
│   ├── use-location.ts
│   ├── use-lookouts.ts
│   ├── use-media-query.tsx
│   ├── use-mobile.ts
│   ├── use-optimized-scroll.ts
│   ├── use-synced-preferences.tsx
│   ├── use-transcript-viewer.ts
│   ├── use-usage-data.ts
│   ├── use-user-data.ts
│   ├── use-voice-client.ts
│   └── use-window-size.tsx
├── instrumentation.ts
├── lib/
│   ├── auth-client.ts
│   ├── auth-utils.ts
│   ├── auth.ts
│   ├── better-all.ts
│   ├── canvas/
│   │   ├── catalog.ts
│   │   ├── registry.tsx
│   │   └── renderer.tsx
│   ├── chat-messages.ts
│   ├── connectors.tsx
│   ├── constants.ts
│   ├── db/
│   │   ├── chat-queries.ts
│   │   ├── index.ts
│   │   ├── queries.ts
│   │   └── schema.ts
│   ├── discount.ts
│   ├── email.ts
│   ├── errors.ts
│   ├── mcp/
│   │   ├── auth-headers.ts
│   │   ├── catalog-icons.ts
│   │   ├── crypto.ts
│   │   ├── managed-credentials.ts
│   │   ├── oauth.ts
│   │   └── server-config.ts
│   ├── memory-actions.ts
│   ├── notte.ts
│   ├── parser.ts
│   ├── performance-cache.ts
│   ├── r2.ts
│   ├── rate-limit.ts
│   ├── redis.ts
│   ├── search/
│   │   ├── auto-router.ts
│   │   ├── chat-title.ts
│   │   ├── group-config.ts
│   │   ├── server-helpers.ts
│   │   └── tool-loader.ts
│   ├── search-utils.ts
│   ├── subscription.ts
│   ├── tools/
│   │   ├── academic-search.ts
│   │   ├── build-tools.ts
│   │   ├── code-context.ts
│   │   ├── code-interpreter.ts
│   │   ├── connectors-search.ts
│   │   ├── crypto-tools.ts
│   │   ├── currency-converter.ts
│   │   ├── datetime.ts
│   │   ├── extreme-search.ts
│   │   ├── file-query-search.ts
│   │   ├── flight-tracker.ts
│   │   ├── github-search.ts
│   │   ├── greeting.ts
│   │   ├── index.ts
│   │   ├── map-tools.ts
│   │   ├── mcp-client.ts
│   │   ├── mcp-search.ts
│   │   ├── movie-tv-search.ts
│   │   ├── prediction-search.ts
│   │   ├── reddit-search.ts
│   │   ├── retrieve.ts
│   │   ├── spotify-search.ts
│   │   ├── stock-chart.ts
│   │   ├── supermemory.ts
│   │   ├── text-translate.ts
│   │   ├── trending-movies.ts
│   │   ├── trending-tv.ts
│   │   ├── weather.ts
│   │   ├── web-search.ts
│   │   ├── x-search.ts
│   │   └── youtube-search.ts
│   ├── types.ts
│   ├── user-data-server.ts
│   ├── user-data.ts
│   └── utils.ts
├── next.config.ts
├── package.json
├── postcss.config.mjs
├── proxy.ts
├── public/
│   ├── .well-known/
│   │   └── microsoft-identity-association.json
│   ├── audio-capture-processor.js
│   ├── pcm-processor-worklet.js
│   └── privacy-policy.html
├── sandbox.py
├── tsconfig.json
└── vercel.ts
Download .txt
SYMBOL INDEX (2006 symbols across 323 files)

FILE: ai/models.ts
  type ModelParameters (line 2) | interface ModelParameters {
  type ModelProvider (line 13) | type ModelProvider =
  type ProviderInfo (line 37) | interface ProviderInfo {
  constant PROVIDERS (line 44) | const PROVIDERS: Record<ModelProvider, ProviderInfo> = {
  type Model (line 69) | interface Model {
  function getModelConfig (line 2646) | function getModelConfig(modelValue: string) {
  function requiresAuthentication (line 2650) | function requiresAuthentication(modelValue: string): boolean {
  function requiresProSubscription (line 2655) | function requiresProSubscription(modelValue: string): boolean {
  function requiresMaxSubscription (line 2660) | function requiresMaxSubscription(modelValue: string): boolean {
  function isFreeUnlimited (line 2665) | function isFreeUnlimited(modelValue: string): boolean {
  function hasVisionSupport (line 2670) | function hasVisionSupport(modelValue: string): boolean {
  function hasPdfSupport (line 2675) | function hasPdfSupport(modelValue: string): boolean {
  function hasReasoningSupport (line 2681) | function hasReasoningSupport(modelValue: string): boolean {
  function isExperimentalModel (line 2686) | function isExperimentalModel(modelValue: string): boolean {
  function getMaxOutputTokens (line 2691) | function getMaxOutputTokens(modelValue: string): number {
  function getModelParameters (line 2696) | function getModelParameters(modelValue: string): ModelParameters {
  function canUseModel (line 2702) | function canUseModel(
  function shouldBypassRateLimits (line 2733) | function shouldBypassRateLimits(modelValue: string, user: any): boolean {
  function getAcceptedFileTypes (line 2739) | function getAcceptedFileTypes(modelValue: string, isProUser: boolean): s...
  function supportsExtremeMode (line 2757) | function supportsExtremeMode(modelValue: string): boolean {
  function getExtremeModels (line 2763) | function getExtremeModels(): Model[] {
  constant CANVAS_MODELS (line 2769) | const CANVAS_MODELS = new Set([
  function supportsCanvasMode (line 2797) | function supportsCanvasMode(modelValue: string): boolean {
  constant RESTRICTED_REGIONS (line 2802) | const RESTRICTED_REGIONS = ['CN', 'KP', 'RU'];
  constant OPENAI_MODELS (line 2805) | const OPENAI_MODELS = [
  constant ANTHROPIC_MODELS (line 2833) | const ANTHROPIC_MODELS = [
  function isModelRestrictedInRegion (line 2847) | function isModelRestrictedInRegion(modelValue: string, countryCode?: str...
  function getFilteredModels (line 2860) | function getFilteredModels(countryCode?: string): Model[] {
  function getModelProvider (line 2874) | function getModelProvider(modelValue: string, label?: string): ModelProv...
  function getModelProviderInfo (line 2993) | function getModelProviderInfo(modelValue: string): ProviderInfo {
  function getActiveProviders (line 3000) | function getActiveProviders(): ProviderInfo[] {
  function getModelsByProvider (line 3010) | function getModelsByProvider(provider: ModelProvider): Model[] {

FILE: app/(auth)/layout.tsx
  function AuthLayout (line 48) | function AuthLayout({ children }: { children: React.ReactNode }) {

FILE: app/(auth)/sign-in/page.tsx
  function SignInContent (line 4) | function SignInContent() {
  function SignInPage (line 14) | function SignInPage() {

FILE: app/(auth)/sign-up/page.tsx
  function SignUpContent (line 4) | function SignUpContent() {
  function SignUpPage (line 14) | function SignUpPage() {

FILE: app/(content)/about/page.tsx
  function AnimatedCounter (line 85) | function AnimatedCounter({ target, suffix = '' }: { target: string; suff...
  function AppsBeamSection (line 133) | function AppsBeamSection() {
  function AboutPage (line 308) | function AboutPage() {

FILE: app/(content)/layout.tsx
  function ContentLayout (line 3) | function ContentLayout({ children }: { children: React.ReactNode }) {

FILE: app/(content)/privacy-policy/page.tsx
  function PrivacyPage (line 30) | function PrivacyPage() {

FILE: app/(content)/terms/page.tsx
  function TermsPage (line 18) | function TermsPage() {

FILE: app/(content)/x-wrapped/[username]/page.tsx
  type XWrappedData (line 17) | interface XWrappedData {
  function StatCard (line 41) | function StatCard({
  function SentimentBar (line 74) | function SentimentBar({ positive, neutral, negative, delay = 0 }: { posi...
  function XWrappedUsernamePage (line 90) | function XWrappedUsernamePage() {

FILE: app/(content)/x-wrapped/layout.tsx
  function XWrappedLayout (line 29) | function XWrappedLayout({ children }: { children: React.ReactNode }) {

FILE: app/(content)/x-wrapped/page.tsx
  function XWrappedPage (line 13) | function XWrappedPage() {

FILE: app/actions.ts
  function getCurrentUser (line 90) | async function getCurrentUser() {
  function getLightweightUser (line 97) | async function getLightweightUser() {
  function getChatMeta (line 104) | async function getChatMeta(chatId: string, viewerUserId?: string) {
  function getUserCountryCode (line 137) | async function getUserCountryCode() {
  function suggestQuestions (line 156) | async function suggestQuestions(history: any[]) {
  function checkImageModeration (line 230) | async function checkImageModeration(images: string[]) {
  function generateTitleFromUserMessage (line 248) | async function generateTitleFromUserMessage({ message }: { message: UIMe...
  function enhancePrompt (line 312) | async function enhancePrompt(raw: string) {
  type GenerateSpeechResult (line 362) | interface GenerateSpeechResult {
  function generateSpeech (line 368) | async function generateSpeech(text: string): Promise<GenerateSpeechResul...
  function getGroupConfig (line 385) | async function getGroupConfig(...args: Parameters<typeof getSearchGroupC...
  function getRecentChats (line 391) | async function getRecentChats(
  function getUserChats (line 418) | async function getUserChats(
  function loadMoreChats (line 443) | async function loadMoreChats(
  function deleteChat (line 470) | async function deleteChat(chatId: string) {
  function bulkDeleteChats (line 484) | async function bulkDeleteChats(chatIds: string[]) {
  function updateChatVisibility (line 512) | async function updateChatVisibility(chatId: string, visibility: 'private...
  function updateChatPinned (line 545) | async function updateChatPinned(chatId: string, isPinned: boolean) {
  function getChatInfo (line 559) | async function getChatInfo(chatId: string) {
  function deleteTrailingMessages (line 572) | async function deleteTrailingMessages({ id }: { id: string }) {
  function updateChatTitle (line 596) | async function updateChatTitle(chatId: string, title: string) {
  function forkChat (line 609) | async function forkChat(
  function branchOutChat (line 680) | async function branchOutChat({
  function getSubDetails (line 765) | async function getSubDetails() {
  function previewMaxUpgrade (line 782) | async function previewMaxUpgrade() {
  function upgradeToMax (line 874) | async function upgradeToMax() {
  function previewDowngradeToPro (line 950) | async function previewDowngradeToPro() {
  function downgradeToPro (line 1011) | async function downgradeToPro() {
  function getUserMessageCount (line 1063) | async function getUserMessageCount(providedUser?: User | null) {
  function getUserExtremeSearchCount (line 1097) | async function getUserExtremeSearchCount(providedUser?: User | null) {
  function incrementUserMessageCount (line 1131) | async function incrementUserMessageCount() {
  function getExtremeSearchUsageCount (line 1155) | async function getExtremeSearchUsageCount(providedUser?: User | null) {
  function getMessageCountByUserId (line 1193) | async function getMessageCountByUserId(userId: string) {
  function getExtremeSearchCountByUserId (line 1207) | async function getExtremeSearchCountByUserId(userId: string) {
  function getAnthropicUsageCountByUserId (line 1221) | async function getAnthropicUsageCountByUserId(userId: string) {
  function getAnthropicUsageCountAction (line 1231) | async function getAnthropicUsageCountAction(providedUser?: User | null) {
  function getAgentModeUsageCountAction (line 1263) | async function getAgentModeUsageCountAction(providedUser?: User | null) {
  function incrementAnthropicUsageAction (line 1295) | async function incrementAnthropicUsageAction(model?: string | null) {
  function getGoogleUsageCountByUserId (line 1319) | async function getGoogleUsageCountByUserId(userId: string) {
  function getGoogleUsageCountAction (line 1329) | async function getGoogleUsageCountAction(providedUser?: User | null) {
  function incrementGoogleUsageAction (line 1358) | async function incrementGoogleUsageAction(model?: string | null) {
  function getMessageCountAndExtremeSearchByUserIdAction (line 1384) | async function getMessageCountAndExtremeSearchByUserIdAction(userId: str...
  type DiscountConfigParams (line 1429) | type DiscountConfigParams = {
  function getDiscountConfigAction (line 1434) | async function getDiscountConfigAction(params?: DiscountConfigParams) {
  function getHistoricalUsage (line 1467) | async function getHistoricalUsage(providedUser?: User | null, days: numb...
  function getCustomInstructions (line 1525) | async function getCustomInstructions(providedUser?: User | null) {
  function saveCustomInstructions (line 1542) | async function saveCustomInstructions(content: string) {
  function deleteCustomInstructionsAction (line 1572) | async function deleteCustomInstructionsAction() {
  function getUserPreferences (line 1590) | async function getUserPreferences(providedUser?: User | null) {
  function saveUserPreferences (line 1607) | async function saveUserPreferences(
  function routeWithAutoRouter (line 1654) | async function routeWithAutoRouter({
  function syncUserPreferences (line 1762) | async function syncUserPreferences() {
  function getProUserStatusOnly (line 1781) | async function getProUserStatusOnly(): Promise<boolean> {
  function getDodoSubscriptionHistory (line 1789) | async function getDodoSubscriptionHistory() {
  function getDodoSubscriptionProStatus (line 1802) | async function getDodoSubscriptionProStatus() {
  function getDodoSubscriptionExpirationDate (line 1824) | async function getDodoSubscriptionExpirationDate() {
  function frequencyToCron (line 1838) | function frequencyToCron(frequency: string, time: string, timezone: stri...
  function calculateNextRun (line 1871) | function calculateNextRun(cronSchedule: string, timezone: string): Date {
  function calculateOnceNextRun (line 1897) | function calculateOnceNextRun(time: string, timezone: string, date?: str...
  function createScheduledLookout (line 1920) | async function createScheduledLookout({
  function getUserLookouts (line 2095) | async function getUserLookouts() {
  function updateLookoutStatusAction (line 2125) | async function updateLookoutStatusAction({
  function updateLookoutAction (line 2174) | async function updateLookoutAction({
  function deleteLookoutAction (line 2309) | async function deleteLookoutAction({ id }: { id: string }) {
  function testLookoutAction (line 2341) | async function testLookoutAction({ id }: { id: string }) {
  function getUserLocation (line 2391) | async function getUserLocation() {
  function createConnectorAction (line 2423) | async function createConnectorAction(provider: ConnectorProvider) {
  function listUserConnectorsAction (line 2440) | async function listUserConnectorsAction() {
  function deleteConnectorAction (line 2457) | async function deleteConnectorAction(connectionId: string) {
  function manualSyncConnectorAction (line 2478) | async function manualSyncConnectorAction(provider: ConnectorProvider) {
  function getConnectorSyncStatusAction (line 2499) | async function getConnectorSyncStatusAction(provider: ConnectorProvider) {
  function getStudentDomainsAction (line 2517) | async function getStudentDomainsAction() {
  type ChatMeta (line 2561) | interface ChatMeta {
  function stripMarkdown (line 2566) | function stripMarkdown(text: string): string {
  function buildPreviewMap (line 2601) | async function buildPreviewMap(chatIds: string[]): Promise<Record<string...
  function getAllChatsWithPreview (line 2645) | async function getAllChatsWithPreview(limit: number = 25, offset: number...
  function searchChatsByTitle (line 2680) | async function searchChatsByTitle(query: string, limit: number = 25, off...

FILE: app/api/clean_images/route.ts
  function GET (line 7) | async function GET(req: NextRequest) {
  function deleteAllObjectsWithPrefix (line 25) | async function deleteAllObjectsWithPrefix(prefix: string): Promise<numbe...

FILE: app/api/export/docx/route.ts
  type DocxExportMeta (line 24) | interface DocxExportMeta {
  type DocxExportBody (line 29) | interface DocxExportBody {
  function isRecord (line 35) | function isRecord(value: unknown): value is Record<string, unknown> {
  function isString (line 39) | function isString(value: unknown): value is string {
  function parseDocxExportBody (line 43) | function parseDocxExportBody(value: unknown): DocxExportBody | null {
  function preprocessMarkdown (line 63) | function preprocessMarkdown(md: string): string {
  function simplifyLatex (line 152) | function simplifyLatex(lx: string): string {
  function processInlineText (line 314) | function processInlineText(
  function flattenInlineTokens (line 384) | function flattenInlineTokens(
  function POST (line 476) | async function POST(req: NextRequest) {

FILE: app/api/export/pdf/route.ts
  function wrapText (line 18) | function wrapText(text: string, widthFn: (s: string) => number, maxWidth...
  function measureTextWidth (line 93) | function measureTextWidth(font: any, text: string, size: number, fallbac...
  function extractMathSvg (line 101) | function extractMathSvg(markup: string) {
  function cleanMathSvg (line 107) | function cleanMathSvg(
  type PdfExportMeta (line 149) | interface PdfExportMeta {
  type PdfExportBody (line 154) | interface PdfExportBody {
  function isRecord (line 160) | function isRecord(value: unknown): value is Record<string, unknown> {
  function isString (line 164) | function isString(value: unknown): value is string {
  function parsePdfExportBody (line 168) | function parsePdfExportBody(value: unknown): PdfExportBody | null {
  function POST (line 187) | async function POST(req: NextRequest) {

FILE: app/api/lookout/route.ts
  function truncateMarkdown (line 65) | function truncateMarkdown(text: string, maxLength: number): string {
  constant STATIC_TOOLS (line 198) | const STATIC_TOOLS: Record<string, any> = {
  constant DATASTREAM_TOOL_FACTORIES (line 221) | const DATASTREAM_TOOL_FACTORIES: Record<string, (dataStream: UIMessageSt...
  constant SEARCH_MODE_TOOLS (line 231) | const SEARCH_MODE_TOOLS: Record<string, readonly string[]> = {
  function getToolsForSearchMode (line 259) | function getToolsForSearchMode(
  function getSystemPromptForSearchMode (line 292) | function getSystemPromptForSearchMode(searchMode: string): string {
  function checkUserIsProById (line 538) | async function checkUserIsProById(userId: string): Promise<boolean> {
  function POST (line 568) | async function POST(req: Request) {

FILE: app/api/mcp/apps/bridge/route.ts
  function POST (line 21) | async function POST(request: Request) {

FILE: app/api/mcp/apps/resource/read/route.ts
  function extractUiResourceMeta (line 14) | function extractUiResourceMeta(resource: unknown, content: unknown) {
  function POST (line 32) | async function POST(request: Request) {

FILE: app/api/mcp/elicitation/respond/route.ts
  constant ELICITATION_RESPONSE_KEY_PREFIX (line 8) | const ELICITATION_RESPONSE_KEY_PREFIX = 'mcp:elicitation:response:';
  constant ELICITATION_PENDING_KEY_PREFIX (line 9) | const ELICITATION_PENDING_KEY_PREFIX = 'mcp:elicitation:pending:';
  function getElicitationResponseKey (line 11) | function getElicitationResponseKey(elicitationId: string) {
  function getElicitationPendingKey (line 15) | function getElicitationPendingKey(elicitationId: string) {
  function POST (line 25) | async function POST(request: Request) {

FILE: app/api/mcp/oauth/callback/route.ts
  function assertProUser (line 7) | function assertProUser(user: Awaited<ReturnType<typeof getCurrentUser>>) {
  function redirectToApps (line 13) | function redirectToApps(request: Request, status: 'success' | 'error', m...
  function GET (line 21) | async function GET(request: Request) {

FILE: app/api/mcp/oauth/client-metadata/[serverId]/route.ts
  function getAppOrigin (line 3) | function getAppOrigin(request: Request) {
  function GET (line 11) | async function GET(

FILE: app/api/mcp/servers/[id]/oauth/callback/route.ts
  function assertProUser (line 6) | function assertProUser(user: Awaited<ReturnType<typeof getCurrentUser>>) {
  function redirectToApps (line 12) | function redirectToApps(request: Request, status: 'success' | 'error', m...
  function GET (line 20) | async function GET(

FILE: app/api/mcp/servers/[id]/oauth/disconnect/route.ts
  function assertProUser (line 5) | function assertProUser(user: Awaited<ReturnType<typeof getCurrentUser>>) {
  function POST (line 11) | async function POST(

FILE: app/api/mcp/servers/[id]/oauth/start/route.ts
  function assertProUser (line 8) | function assertProUser(user: Awaited<ReturnType<typeof getCurrentUser>>) {
  function POST (line 14) | async function POST(

FILE: app/api/mcp/servers/[id]/route.ts
  function assertProUser (line 42) | function assertProUser(user: Awaited<ReturnType<typeof getCurrentUser>>) {
  function serializeMcpServer (line 48) | function serializeMcpServer(server: {
  function PATCH (line 100) | async function PATCH(
  function DELETE (line 205) | async function DELETE(

FILE: app/api/mcp/servers/[id]/tools/route.ts
  function GET (line 8) | async function GET(

FILE: app/api/mcp/servers/route.ts
  function assertProUser (line 35) | function assertProUser(user: Awaited<ReturnType<typeof getCurrentUser>>) {
  function serializeMcpServer (line 41) | function serializeMcpServer(server: {
  function GET (line 91) | async function GET() {
  function POST (line 103) | async function POST(request: Request) {

FILE: app/api/mcp/servers/test/route.ts
  function assertProUser (line 23) | function assertProUser(user: Awaited<ReturnType<typeof getCurrentUser>>) {
  function normalizeMcpTestErrorMessage (line 29) | function normalizeMcpTestErrorMessage(
  function POST (line 50) | async function POST(request: Request) {

FILE: app/api/og/chat/[id]/route.tsx
  type TextPart (line 8) | interface TextPart {
  type MessagePart (line 13) | interface MessagePart {
  function getTextFromParts (line 19) | function getTextFromParts(parts: unknown): string {
  function stripMarkdown (line 26) | function stripMarkdown(text: string): string {
  function truncateText (line 63) | function truncateText(text: string, maxLength: number): string {
  function GET (line 80) | async function GET(_: Request, { params }: { params: Promise<{ id: strin...

FILE: app/api/og/x-wrapped/route.tsx
  function GET (line 6) | async function GET() {

FILE: app/api/preferences/route.ts
  function GET (line 5) | async function GET() {
  function POST (line 22) | async function POST(request: Request) {

FILE: app/api/proxy-image/route.ts
  function GET (line 3) | async function GET(request: NextRequest) {

FILE: app/api/raycast/route.ts
  function POST (line 73) | async function POST(req: Request) {

FILE: app/api/search/[id]/stop/route.ts
  function DELETE (line 9) | async function DELETE(req: Request, { params }: { params: Promise<{ id: ...

FILE: app/api/search/[id]/stream/route.ts
  function GET (line 13) | async function GET(req: Request, { params }: { params: Promise<{ id: str...

FILE: app/api/search/route.ts
  type CriticalChecksResult (line 70) | interface CriticalChecksResult {
  type ChatInitializationParams (line 81) | interface ChatInitializationParams {
  function initializeChatAndChecks (line 95) | function initializeChatAndChecks({
  function getStreamContext (line 386) | async function getStreamContext() {
  function POST (line 391) | async function POST(req: Request) {

FILE: app/api/suggest/route.ts
  function GET (line 1) | async function GET(request: Request) {

FILE: app/api/transcribe/route.ts
  function POST (line 6) | async function POST(request: NextRequest) {

FILE: app/api/upload/route.ts
  constant IMAGE_TYPES (line 18) | const IMAGE_TYPES = ['image/jpeg', 'image/png', 'image/gif'];
  constant DOCUMENT_TYPES (line 21) | const DOCUMENT_TYPES = [
  constant VALID_TYPES (line 29) | const VALID_TYPES = [...IMAGE_TYPES, ...DOCUMENT_TYPES];
  constant MAX_IMAGE_SIZE (line 32) | const MAX_IMAGE_SIZE = 5 * 1024 * 1024;
  constant MAX_DOCUMENT_SIZE (line 33) | const MAX_DOCUMENT_SIZE = 50 * 1024 * 1024;
  function isImageType (line 35) | function isImageType(contentType: string): boolean {
  function getMaxSizeForType (line 39) | function getMaxSizeForType(contentType: string): number {
  function sanitizeExtension (line 71) | function sanitizeExtension(raw: string): string {
  function isOwnR2Url (line 77) | function isOwnR2Url(url: string): boolean {
  function parseLimit (line 88) | function parseLimit(raw: string | null, defaultVal: number, max: number)...
  type UploadedFile (line 94) | interface UploadedFile {
  constant VERCEL_BLOB_PATTERN (line 105) | const VERCEL_BLOB_PATTERN = '.public.blob.vercel-storage.com';
  function isVercelBlobUrl (line 107) | function isVercelBlobUrl(url: string): boolean {
  type DbFileRow (line 112) | type DbFileRow = {
  function GET (line 120) | async function GET(request: NextRequest) {
  function POST (line 293) | async function POST(request: NextRequest) {
  function DELETE (line 366) | async function DELETE(request: NextRequest) {

FILE: app/api/x-wrapped/route.ts
  type CitationSource (line 10) | interface CitationSource {
  type XWrappedData (line 15) | interface XWrappedData {
  function extractTweetId (line 46) | function extractTweetId(url?: string | null): string | null {
  function toMonthName (line 51) | function toMonthName(date: Date): string {
  function clampPercent (line 55) | function clampPercent(value: number): number {
  constant CACHE_TTL_SECONDS (line 61) | const CACHE_TTL_SECONDS = 5 * 60;
  function POST (line 63) | async function POST(req: NextRequest) {

FILE: app/api/xql/route.ts
  method execute (line 59) | async execute({
  type XQLMessage (line 120) | type XQLMessage = UIMessage<never, UIDataTypes, InferUITools<typeof tool...
  function POST (line 122) | async function POST(req: Request) {

FILE: app/apps/layout.tsx
  function AppsLayout (line 30) | function AppsLayout({ children }: { children: React.ReactNode }) {

FILE: app/apps/page.tsx
  type CatalogAuth (line 41) | type CatalogAuth = 'oauth' | 'apikey' | 'open';
  type CategoryId (line 42) | type CategoryId = 'all' | 'dev' | 'productivity' | 'design' | 'crm' | 'p...
  type CatalogField (line 44) | interface CatalogField {
  type OAuthSetupField (line 53) | interface OAuthSetupField {
  type CatalogItem (line 61) | interface CatalogItem {
  constant CATEGORIES (line 75) | const CATEGORIES: { id: CategoryId; label: string }[] = [
  constant CATALOG (line 91) | const CATALOG: CatalogItem[] = [
  constant FEATURED_NAMES (line 227) | const FEATURED_NAMES = ['Notion', 'Rube', 'GitHub', 'Exa Search', 'Verce...
  constant CATALOG_URLS (line 228) | const CATALOG_URLS = new Set(CATALOG.map((i) => i.url.replace(/\/$/, '')));
  function getTransportType (line 232) | function getTransportType(url: string): 'sse' | 'http' {
  constant SLD_TLDS (line 238) | const SLD_TLDS = new Set([
  function rootDomain (line 247) | function rootDomain(serverUrl: string): string {
  function faviconUrl (line 257) | function faviconUrl(serverUrl: string): string {
  constant AUTH_LABELS (line 264) | const AUTH_LABELS: Record<CatalogAuth, string> = { oauth: 'OAuth', apike...
  function isOauthWithClientSetup (line 266) | function isOauthWithClientSetup(item: CatalogItem) {
  function ServiceIcon (line 272) | function ServiceIcon({ url, name, size = 24, customIcon, serverUrl }: { ...
  function CatalogCard (line 291) | function CatalogCard({
  function CardSkeleton (line 360) | function CardSkeleton() {
  function McpMarketplaceContent (line 383) | function McpMarketplaceContent() {
  function AppsPage (line 1535) | function AppsPage() {

FILE: app/connectors/[provider]/callback/page.tsx
  function ConnectorCallbackPage (line 11) | function ConnectorCallbackPage() {

FILE: app/error.tsx
  function Error (line 10) | function Error({ error, reset }: { error: Error & { digest?: string }; r...

FILE: app/global-error.tsx
  type GlobalErrorProps (line 34) | interface GlobalErrorProps {
  function GlobalError (line 39) | function GlobalError({ error, reset }: GlobalErrorProps) {

FILE: app/layout.tsx
  function RootLayout (line 138) | async function RootLayout({

FILE: app/lookout/components/action-buttons.tsx
  type ActionButtonsProps (line 10) | interface ActionButtonsProps {
  function ActionButtons (line 19) | function ActionButtons({

FILE: app/lookout/components/empty-state.tsx
  type EmptyStateProps (line 8) | interface EmptyStateProps {
  function EmptyState (line 16) | function EmptyState({
  function NoActiveLookoutsEmpty (line 44) | function NoActiveLookoutsEmpty() {
  function NoArchivedLookoutsEmpty (line 54) | function NoArchivedLookoutsEmpty() {

FILE: app/lookout/components/loading-skeleton.tsx
  type LoadingSkeletonProps (line 7) | interface LoadingSkeletonProps {
  function LookoutSkeleton (line 12) | function LookoutSkeleton({ showActions = true }: { showActions?: boolean...
  function LoadingSkeletons (line 41) | function LoadingSkeletons({ count = 3, showActions = true }: LoadingSkel...

FILE: app/lookout/components/lookout-card.tsx
  type LookoutRun (line 14) | interface LookoutRun {
  type Lookout (line 24) | interface Lookout {
  type LookoutCardProps (line 39) | interface LookoutCardProps {
  function LookoutCard (line 49) | function LookoutCard({

FILE: app/lookout/components/lookout-details-sidebar.tsx
  type LookoutRun (line 26) | interface LookoutRun {
  type LookoutWithHistory (line 36) | interface LookoutWithHistory {
  type LookoutDetailsSidebarProps (line 52) | interface LookoutDetailsSidebarProps {
  function LookoutDetailsSidebar (line 62) | function LookoutDetailsSidebar({

FILE: app/lookout/components/lookout-form.tsx
  type LookoutFormProps (line 21) | interface LookoutFormProps {
  function LookoutForm (line 32) | function LookoutForm({

FILE: app/lookout/components/pro-upgrade-screen.tsx
  type ProUpgradeScreenProps (line 7) | interface ProUpgradeScreenProps {
  constant FEATURES (line 13) | const FEATURES = [
  function ProUpgradeScreen (line 31) | function ProUpgradeScreen(_props: ProUpgradeScreenProps) {

FILE: app/lookout/components/run-status-badge.tsx
  type LookoutRunStatus (line 5) | type LookoutRunStatus = 'success' | 'error' | 'timeout';
  type RunStatusBadgeProps (line 7) | interface RunStatusBadgeProps {
  function RunStatusBadge (line 12) | function RunStatusBadge({ status, size = 'sm' }: RunStatusBadgeProps) {

FILE: app/lookout/components/status-badge.tsx
  type StatusBadgeProps (line 9) | interface StatusBadgeProps {
  function StatusBadge (line 14) | function StatusBadge({ status, size = 'sm' }: StatusBadgeProps) {

FILE: app/lookout/components/time-picker.tsx
  type TimePickerProps (line 7) | interface TimePickerProps {
  function TimePicker (line 15) | function TimePicker({ value, onChange, name, selectedDate, filterPastTim...

FILE: app/lookout/components/timezone-selector.tsx
  type TimezoneSelectorProps (line 12) | interface TimezoneSelectorProps {
  function TimezoneSelector (line 17) | function TimezoneSelector({ value, onChange }: TimezoneSelectorProps) {

FILE: app/lookout/components/warning-card.tsx
  type WarningCardProps (line 8) | interface WarningCardProps {
  function WarningCard (line 31) | function WarningCard({ type, icon, message, className = '' }: WarningCar...
  function TotalLimitWarning (line 55) | function TotalLimitWarning() {
  function DailyLimitWarning (line 59) | function DailyLimitWarning() {

FILE: app/lookout/constants.ts
  constant LOOKOUT_SEARCH_MODES (line 13) | const LOOKOUT_SEARCH_MODES = [
  type LookoutSearchMode (line 24) | type LookoutSearchMode = (typeof LOOKOUT_SEARCH_MODES)[number]['value'];
  function getRandomExamples (line 353) | function getRandomExamples(count: number = 3) {
  constant LOOKOUT_LIMITS (line 368) | const LOOKOUT_LIMITS = {
  constant DEFAULT_FORM_VALUES (line 373) | const DEFAULT_FORM_VALUES = {

FILE: app/lookout/hooks/use-lookout-form.ts
  type LookoutFormData (line 8) | interface LookoutFormData {
  type LookoutFormHookReturn (line 19) | interface LookoutFormHookReturn {
  function useLookoutForm (line 56) | function useLookoutForm(detectedTimezone: string = DEFAULT_FORM_VALUES.T...

FILE: app/lookout/layout.tsx
  type LookoutLayoutProps (line 41) | interface LookoutLayoutProps {
  function LookoutLayout (line 45) | function LookoutLayout({ children }: LookoutLayoutProps) {

FILE: app/lookout/page.tsx
  type Lookout (line 40) | interface Lookout {
  function LookoutPage (line 64) | function LookoutPage() {

FILE: app/manifest.ts
  function manifest (line 3) | function manifest(): MetadataRoute.Manifest {

FILE: app/new/page.tsx
  function NewPage (line 3) | async function NewPage() {

FILE: app/not-found.tsx
  function NotFound (line 9) | function NotFound() {

FILE: app/pricing/_component/pricing-table.tsx
  type SubscriptionDetails (line 45) | type SubscriptionDetails = {
  type SubscriptionDetailsResult (line 59) | type SubscriptionDetailsResult = {
  type PricingTableProps (line 66) | interface PricingTableProps {
  function PricingTable (line 95) | function PricingTable({ subscriptionDetails, user }: PricingTableProps) {

FILE: app/pricing/page.tsx
  function PricingPage (line 7) | async function PricingPage() {

FILE: app/providers.tsx
  function Providers (line 28) | function Providers({ children }: { children: ReactNode }) {

FILE: app/search/[id]/loading-old.tsx
  function Loading (line 1) | function Loading() {

FILE: app/search/[id]/page.tsx
  constant CHAT_PRIMARY_BACKOFF_MAX_WAIT_MS (line 16) | const CHAT_PRIMARY_BACKOFF_MAX_WAIT_MS = 15_000;
  constant CHAT_PRIMARY_BACKOFF_INITIAL_DELAY_MS (line 17) | const CHAT_PRIMARY_BACKOFF_INITIAL_DELAY_MS = 250;
  constant CHAT_PRIMARY_BACKOFF_MAX_DELAY_MS (line 18) | const CHAT_PRIMARY_BACKOFF_MAX_DELAY_MS = 2_000;
  function sleep (line 20) | async function sleep(ms: number): Promise<void> {
  function getFreshUserFromSession (line 24) | async function getFreshUserFromSession(): Promise<User | null> {
  function getChatWithMessagesFromPrimary (line 32) | async function getChatWithMessagesFromPrimary({
  function getChatWithMessagesFromPrimaryWithBackoff (line 51) | async function getChatWithMessagesFromPrimaryWithBackoff(id: string): Pr...
  function generateMetadata (line 72) | async function generateMetadata({ params }: { params: Promise<{ id: stri...
  function Page (line 118) | async function Page(props: { params: Promise<{ id: string }> }) {

FILE: app/searches/page.tsx
  function SearchesPageSkeleton (line 10) | function SearchesPageSkeleton() {
  function Page (line 50) | function Page() {

FILE: app/settings/page.tsx
  function SettingsContent (line 41) | function SettingsContent() {
  function SettingsPage (line 353) | function SettingsPage() {

FILE: app/share/[id]/page.tsx
  function generateMetadata (line 12) | async function generateMetadata({ params }: { params: Promise<{ id: stri...
  function Page (line 57) | async function Page(props: { params: Promise<{ id: string }> }) {

FILE: app/success/page.tsx
  constant PRO_FEATURES (line 12) | const PRO_FEATURES = [
  constant MAX_FEATURES (line 19) | const MAX_FEATURES = [
  function SuccessPage (line 26) | function SuccessPage() {

FILE: app/voice/components/pro-upgrade-screen.tsx
  type ProUpgradeScreenProps (line 8) | interface ProUpgradeScreenProps {
  constant FEATURES (line 14) | const FEATURES = [
  function ProUpgradeScreen (line 20) | function ProUpgradeScreen({ user }: ProUpgradeScreenProps) {

FILE: app/voice/layout.tsx
  function VoiceLayout (line 36) | function VoiceLayout({

FILE: app/voice/page.tsx
  constant VOICES (line 19) | const VOICES: { value: VoiceType; label: string; description: string }[]...
  constant VOICE_STORAGE_KEY (line 27) | const VOICE_STORAGE_KEY = "scira.voice.selected-voice";
  constant MUTE_STORAGE_KEY (line 28) | const MUTE_STORAGE_KEY = "scira.voice.mic-muted";
  constant TRANSCRIPT_VISIBLE_KEY (line 29) | const TRANSCRIPT_VISIBLE_KEY = "scira.voice.transcript-visible";
  function isVoiceType (line 31) | function isVoiceType(value: string): value is VoiceType {
  function readStoredVoice (line 35) | function readStoredVoice(): VoiceType {
  function readStoredMuted (line 42) | function readStoredMuted(): boolean {
  function persistPreference (line 47) | function persistPreference(key: string, value: string) {
  function useOrbColors (line 54) | function useOrbColors(): [string, string] {
  function resolveColors (line 79) | function resolveColors(): [string, string] {
  function readStoredTranscriptVisible (line 106) | function readStoredTranscriptVisible(): boolean {
  function VoicePage (line 113) | function VoicePage() {

FILE: app/xql/page.tsx
  function XQLPageContent (line 26) | function XQLPageContent() {
  function XQLPage (line 514) | function XQLPage() {

FILE: components/InstallPrompt.tsx
  function InstallPrompt (line 9) | function InstallPrompt() {

FILE: components/academic-papers.tsx
  type AcademicResult (line 11) | interface AcademicResult {
  type AcademicSearchQueryResult (line 19) | interface AcademicSearchQueryResult {
  type AcademicSearchResponse (line 24) | interface AcademicSearchResponse {
  type AcademicSearchArgs (line 28) | interface AcademicSearchArgs {
  type NormalizedAcademicSearchArgs (line 33) | interface NormalizedAcademicSearchArgs {
  type AcademicPapersProps (line 38) | interface AcademicPapersProps {

FILE: components/ai-elements/web-preview.tsx
  type WebPreviewContextValue (line 27) | interface WebPreviewContextValue {
  type WebPreviewProps (line 44) | type WebPreviewProps = ComponentProps<"div"> & {
  type WebPreviewNavigationProps (line 92) | type WebPreviewNavigationProps = ComponentProps<"div">;
  type WebPreviewNavigationButtonProps (line 107) | type WebPreviewNavigationButtonProps = ComponentProps<typeof Button> & {
  type WebPreviewUrlProps (line 139) | type WebPreviewUrlProps = ComponentProps<typeof Input>;
  type WebPreviewBodyProps (line 185) | type WebPreviewBodyProps = ComponentProps<"iframe"> & {
  type WebPreviewConsoleProps (line 212) | type WebPreviewConsoleProps = ComponentProps<"div"> & {

FILE: components/app-sidebar.tsx
  type VisibilityType (line 109) | type VisibilityType = 'public' | 'private';
  type SignedOutLink (line 111) | type SignedOutLink = {
  type UserDropdownContentProps (line 119) | interface UserDropdownContentProps {
  function UserDropdownContent (line 128) | function UserDropdownContent({
  type AppSidebarProps (line 430) | interface AppSidebarProps {

FILE: components/auth-card.tsx
  type AuthProvider (line 9) | type AuthProvider = 'github' | 'google' | 'twitter' | 'microsoft';
  type AuthIconProps (line 11) | interface AuthIconProps extends React.ComponentProps<'svg'> {}
  type SignInButtonProps (line 60) | interface SignInButtonProps {
  type AuthCardProps (line 70) | interface AuthCardProps {
  function AuthCard (line 116) | function AuthCard({ title, description, mode = 'sign-in' }: AuthCardProp...

FILE: components/build-search.tsx
  function inferLanguage (line 45) | function inferLanguage(path: string): string {
  function StatusBadge (line 77) | function StatusBadge({ status }: { status: string }) {
  function CollapsibleCard (line 99) | function CollapsibleCard({
  function RuntimeLogo (line 366) | function RuntimeLogo({ runtime }: { runtime: string }) {
  constant TOOL_ICONS (line 732) | const TOOL_ICONS: Record<string, string> = {
  function formatToolInput (line 742) | function formatToolInput(toolName: string, input: Record<string, unknown...
  function BoxAgentResultInner (line 761) | function BoxAgentResultInner({

FILE: components/canvas-renderer.tsx
  type CanvasRendererProps (line 7) | interface CanvasRendererProps {

FILE: components/charts/area-chart.tsx
  function isPostOverlayComponent (line 28) | function isPostOverlayComponent(child: ReactElement): boolean {
  type AreaChartProps (line 49) | interface AreaChartProps {
  constant DEFAULT_MARGIN (line 66) | const DEFAULT_MARGIN: Margin = { top: 40, right: 40, bottom: 40, left: 4...
  function extractAreaConfigs (line 69) | function extractAreaConfigs(children: ReactNode): LineConfig[] {
  type ChartInnerProps (line 106) | interface ChartInnerProps {
  function ChartInner (line 117) | function ChartInner({
  function AreaChart (line 361) | function AreaChart({

FILE: components/charts/area.tsx
  type CurveFactory (line 8) | type CurveFactory = any;
  type AreaProps (line 21) | interface AreaProps {
  function Area (line 46) | function Area({

FILE: components/charts/bar-chart.tsx
  type BarOrientation (line 26) | type BarOrientation = "vertical" | "horizontal";
  type BarChartProps (line 28) | interface BarChartProps {
  constant DEFAULT_MARGIN (line 55) | const DEFAULT_MARGIN: Margin = { top: 40, right: 40, bottom: 40, left: 4...
  function extractBarConfigs (line 58) | function extractBarConfigs(children: ReactNode): LineConfig[] {
  function isPostOverlayComponent (line 97) | function isPostOverlayComponent(child: ReactElement): boolean {
  type ChartInnerProps (line 116) | interface ChartInnerProps {
  function ChartInner (line 132) | function ChartInner({
  function BarChart (line 543) | function BarChart({

FILE: components/charts/bar-x-axis.tsx
  type BarXAxisProps (line 8) | interface BarXAxisProps {
  type BarXAxisLabelProps (line 17) | interface BarXAxisLabelProps {
  function BarXAxisLabel (line 25) | function BarXAxisLabel({
  function BarXAxis (line 69) | function BarXAxis({

FILE: components/charts/bar-y-axis.tsx
  type BarYAxisProps (line 8) | interface BarYAxisProps {
  type BarYAxisLabelProps (line 15) | interface BarYAxisLabelProps {
  function BarYAxisLabel (line 22) | function BarYAxisLabel({
  function BarYAxis (line 57) | function BarYAxis({

FILE: components/charts/bar.tsx
  type BarLineCap (line 7) | type BarLineCap = "round" | "butt" | number;
  type BarAnimationType (line 8) | type BarAnimationType = "grow" | "fade";
  type BarProps (line 10) | interface BarProps {
  constant BAR_EASING (line 32) | const BAR_EASING = "cubic-bezier(0.85, 0, 0.15, 1)";
  type AnimatedBarProps (line 34) | interface AnimatedBarProps {
  function AnimatedBar (line 52) | function AnimatedBar({
  function Bar (line 156) | function Bar({

FILE: components/charts/chart-context.tsx
  type ScaleLinear (line 5) | type ScaleLinear<Output, _Input = number> = ReturnType<
  type ScaleTime (line 8) | type ScaleTime<Output, _Input = Date | number> = ReturnType<
  type ScaleBand (line 11) | type ScaleBand<Domain extends { toString(): string }> = ReturnType<
  type Margin (line 40) | interface Margin {
  type TooltipData (line 47) | interface TooltipData {
  type LineConfig (line 60) | interface LineConfig {
  type ChartContextValue (line 66) | interface ChartContextValue {
  function ChartProvider (line 125) | function ChartProvider({
  function useChart (line 137) | function useChart(): ChartContextValue {

FILE: components/charts/grid.tsx
  type GridProps (line 7) | interface GridProps {
  function Grid (line 30) | function Grid({

FILE: components/charts/line-chart.tsx
  function isPostOverlayComponent (line 28) | function isPostOverlayComponent(child: ReactElement): boolean {
  type LineChartProps (line 49) | interface LineChartProps {
  constant DEFAULT_MARGIN (line 66) | const DEFAULT_MARGIN: Margin = { top: 40, right: 40, bottom: 40, left: 4...
  function extractLineConfigs (line 69) | function extractLineConfigs(children: ReactNode): LineConfig[] {
  type ChartInnerProps (line 106) | interface ChartInnerProps {
  function ChartInner (line 117) | function ChartInner({
  function LineChart (line 361) | function LineChart({

FILE: components/charts/line.tsx
  type CurveFactory (line 8) | type CurveFactory = any;
  type LineProps (line 14) | interface LineProps {
  function Line (line 31) | function Line({

FILE: components/charts/tooltip/chart-tooltip.tsx
  type ChartTooltipProps (line 15) | interface ChartTooltipProps {
  function ChartTooltip (line 35) | function ChartTooltip({

FILE: components/charts/tooltip/date-ticker.tsx
  constant TICKER_ITEM_HEIGHT (line 6) | const TICKER_ITEM_HEIGHT = 24;
  type DateTickerProps (line 8) | interface DateTickerProps {
  function DateTicker (line 14) | function DateTicker({ currentIndex, labels, visible }: DateTickerProps) {

FILE: components/charts/tooltip/tooltip-box.tsx
  type TooltipBoxProps (line 11) | interface TooltipBoxProps {
  function TooltipBox (line 38) | function TooltipBox({

FILE: components/charts/tooltip/tooltip-content.tsx
  type TooltipRow (line 7) | interface TooltipRow {
  type TooltipContentProps (line 13) | interface TooltipContentProps {
  function TooltipContent (line 20) | function TooltipContent({ title, rows, children }: TooltipContentProps) {

FILE: components/charts/tooltip/tooltip-dot.tsx
  type TooltipDotProps (line 10) | interface TooltipDotProps {
  function TooltipDot (line 20) | function TooltipDot({

FILE: components/charts/tooltip/tooltip-indicator.tsx
  type IndicatorWidth (line 10) | type IndicatorWidth =
  type TooltipIndicatorProps (line 17) | interface TooltipIndicatorProps {
  function resolveWidth (line 46) | function resolveWidth(width: IndicatorWidth): number {
  function TooltipIndicator (line 64) | function TooltipIndicator({

FILE: components/charts/x-axis.tsx
  type XAxisProps (line 8) | interface XAxisProps {
  type XAxisLabelProps (line 15) | interface XAxisLabelProps {
  function XAxisLabel (line 23) | function XAxisLabel({
  function XAxis (line 69) | function XAxis({ numTicks = 5, tickerHalfWidth = 50 }: XAxisProps) {

FILE: components/chat-dialogs.tsx
  type PostMessageUpgradeDialogProps (line 25) | interface PostMessageUpgradeDialogProps {
  type LookoutAnnouncementDialogProps (line 210) | interface LookoutAnnouncementDialogProps {
  type ChatDialogsProps (line 344) | interface ChatDialogsProps {

FILE: components/chat-history-dialog.tsx
  constant SCROLL_THRESHOLD (line 59) | const SCROLL_THRESHOLD = 0.5;
  constant FOCUS_DELAY (line 60) | const FOCUS_DELAY = 100;
  type Chat (line 62) | interface Chat {
  type ChatHistoryDialogProps (line 72) | interface ChatHistoryDialogProps {
  type SearchMode (line 79) | type SearchMode = 'all' | 'title' | 'date' | 'visibility';
  function isValidChatId (line 82) | function isValidChatId(id: string): boolean {
  function parseChatDate (line 86) | function parseChatDate(value: Date | string | number): Date {
  function getChatActivityDate (line 107) | function getChatActivityDate(chat: Chat): Date {
  function categorizeChatsByDate (line 112) | function categorizeChatsByDate(chats: Chat[]) {
  function fuzzySearch (line 213) | function fuzzySearch(query: string, text: string): boolean {
  function parseDateQuery (line 234) | function parseDateQuery(dateStr: string): Date | null {
  function isSameDay (line 262) | function isSameDay(date1: Date, date2: Date): boolean {
  function advancedSearch (line 271) | function advancedSearch(chat: Chat, query: string, mode: SearchMode): bo...
  function ChatHistoryDialog (line 332) | function ChatHistoryDialog({ open, onOpenChange, user }: ChatHistoryDial...
  function ChatHistoryButton (line 1555) | function ChatHistoryButton({ onClickAction }: { onClickAction: () => voi...

FILE: components/chat-interface.tsx
  type ChatInterfaceProps (line 87) | interface ChatInterfaceProps {
  type AutoRouterConfig (line 95) | interface AutoRouterConfig {
  constant INITIAL_QUERY_DEDUPE_WINDOW_MS (line 103) | const INITIAL_QUERY_DEDUPE_WINDOW_MS = 5000;
  type VisibilityType (line 551) | type VisibilityType = 'public' | 'private';
  method prepareSendMessagesRequest (line 603) | prepareSendMessagesRequest({ messages, body }) {

FILE: components/chat-state.ts
  type ChatState (line 1) | interface ChatState {
  type Attachment (line 20) | interface Attachment {
  type ChatAction (line 28) | type ChatAction =

FILE: components/chat-text-highlighter.tsx
  type ChatTextHighlighterProps (line 6) | interface ChatTextHighlighterProps {
  type PopupPosition (line 13) | interface PopupPosition {

FILE: components/client-analytics.tsx
  function ClientAnalytics (line 17) | function ClientAnalytics(): React.JSX.Element {

FILE: components/connectors-search-results.tsx
  type Document (line 33) | interface Document {
  type ConnectorsSearchResultsProps (line 57) | interface ConnectorsSearchResultsProps {
  function ConnectorsSearchResults (line 325) | function ConnectorsSearchResults({

FILE: components/core/border-trail.tsx
  type BorderTrailProps (line 5) | type BorderTrailProps = {
  function BorderTrail (line 14) | function BorderTrail({ className, size = 60, transition, delay, onAnimat...

FILE: components/core/sliding-number.tsx
  constant TRANSITION (line 6) | const TRANSITION = {
  function Digit (line 13) | function Digit({ value, place }: { value: number; place: number }) {
  function Number (line 32) | function Number({ mv, number }: { mv: MotionValue<number>; number: numbe...
  type SlidingNumberProps (line 76) | type SlidingNumberProps = {
  function SlidingNumber (line 82) | function SlidingNumber({ value, padStart = false, decimalSeparator = '.'...

FILE: components/core/text-loop.tsx
  type TextLoopProps (line 6) | type TextLoopProps = {
  function TextLoop (line 15) | function TextLoop({

FILE: components/core/text-shimmer.tsx
  type TextShimmerProps (line 6) | interface TextShimmerProps {
  function TextShimmer (line 14) | function TextShimmer({ children, as: Component = 'p', className, duratio...

FILE: components/crypto-charts.tsx
  type CryptoTickersProps (line 28) | interface CryptoTickersProps {
  type CryptoChartProps (line 33) | interface CryptoChartProps {
  type CandlestickData (line 39) | interface CandlestickData {
  type CandlestickProps (line 49) | interface CandlestickProps {

FILE: components/crypto-coin-data.tsx
  type CoinDataProps (line 9) | interface CoinDataProps {

FILE: components/currency_conv.tsx
  type CurrencyConverterProps (line 7) | interface CurrencyConverterProps {

FILE: components/data-stream-provider.tsx
  type DataStreamContextValue (line 7) | interface DataStreamContextValue {
  function DataStreamProvider (line 14) | function DataStreamProvider({ children }: { children: React.ReactNode }) {
  function useDataStream (line 22) | function useDataStream() {

FILE: components/dialogs/share-dialog.tsx
  type ShareIconDialogProps (line 9) | interface ShareIconDialogProps {
  function ShareIconDialog (line 18) | function ShareIconDialog({

FILE: components/dialogs/use-share-dialog.tsx
  type UseShareDialogProps (line 5) | interface UseShareDialogProps {
  type UseShareDialogReturn (line 12) | interface UseShareDialogReturn {
  function useShareDialog (line 26) | function useShareDialog({

FILE: components/emails/lookout-completed.tsx
  type LookoutCompletedEmailProps (line 20) | interface LookoutCompletedEmailProps {
  function LookoutCompletedEmail (line 130) | function LookoutCompletedEmail({

FILE: components/example-categories.tsx
  type ExampleItem (line 17) | interface ExampleItem {
  type Category (line 22) | interface Category {
  type ExampleCategoriesProps (line 89) | interface ExampleCategoriesProps {

FILE: components/extreme-search.tsx
  function downloadImageBlob (line 62) | async function downloadImageBlob(url: string, filename: string): Promise...
  type ExtremeSearchSource (line 173) | interface ExtremeSearchSource {
  type SearchQuery (line 302) | interface SearchQuery {
  type CodeExecution (line 312) | interface CodeExecution {
  type ThinkingExecution (line 321) | interface ThinkingExecution {
  type DoneExecution (line 327) | interface DoneExecution {
  type XSearchExecution (line 332) | interface XSearchExecution {
  type FileQueryExecution (line 350) | interface FileQueryExecution {
  type BrowsePageExecution (line 363) | interface BrowsePageExecution {
  type QueryGroup (line 989) | type QueryGroup = {
  type XSearchGroup (line 994) | type XSearchGroup = {
  type FileQueryGroup (line 999) | type FileQueryGroup = {
  type TimelineItem (line 1004) | type TimelineItem =

FILE: components/file-query-search.tsx
  type FileQueryResult (line 23) | interface FileQueryResult {
  type QuerySearchResult (line 29) | interface QuerySearchResult {
  type FileQuerySearchResponse (line 34) | interface FileQuerySearchResponse {
  type FileQuerySearchArgs (line 42) | interface FileQuerySearchArgs {

FILE: components/flight-tracker.tsx
  type FlightApiResponse (line 6) | interface FlightApiResponse {
  type FlightTrackerProps (line 51) | interface FlightTrackerProps {
  function FlightTracker (line 55) | function FlightTracker({ data }: FlightTrackerProps) {

FILE: components/github-search.tsx
  type GitHubResult (line 66) | type GitHubResult = {
  type GitHubSearchQueryResult (line 79) | type GitHubSearchQueryResult = {
  type GitHubSearchResponse (line 84) | type GitHubSearchResponse = {
  type GitHubSearchArgs (line 88) | type GitHubSearchArgs = {

FILE: components/haptics-provider.tsx
  constant INTERACTIVE_SELECTOR (line 6) | const INTERACTIVE_SELECTOR =
  constant HAPTIC_TRIGGERS (line 29) | const HAPTIC_TRIGGERS = new Set([
  function resolveHapticTrigger (line 39) | function resolveHapticTrigger(element: HTMLElement): string {
  function HapticsProvider (line 76) | function HapticsProvider() {

FILE: components/icons/agent-network-icon.tsx
  function AgentNetworkIcon (line 3) | function AgentNetworkIcon(props: SVGProps<SVGSVGElement>) {

FILE: components/icons/apps-icon.tsx
  function AppsIcon (line 3) | function AppsIcon(props: SVGProps<SVGSVGElement>) {

FILE: components/icons/mcp-logo.tsx
  function McpLogoIcon (line 3) | function McpLogoIcon(props: SVGProps<SVGSVGElement>) {

FILE: components/interactive-charts.tsx
  constant CHART_COLORS (line 17) | const CHART_COLORS = {
  type BaseChart (line 26) | interface BaseChart {

FILE: components/interactive-maps.tsx
  type Location (line 9) | interface Location {
  type Photo (line 14) | interface Photo {
  type Place (line 22) | interface Place {
  type InteractiveMapProps (line 49) | interface InteractiveMapProps {
  class ZoomControl (line 161) | class ZoomControl extends L.Control {
    method onAdd (line 162) | public onAdd(mapInstance: Leaflet.Map): HTMLElement {

FILE: components/interactive-stock-chart.tsx
  constant CURRENCY_SYMBOLS (line 41) | const CURRENCY_SYMBOLS = {
  type StockChartProps (line 99) | interface StockChartProps {
  type ProcessedSeriesData (line 210) | interface ProcessedSeriesData {

FILE: components/keyboard-shortcuts-dialog.tsx
  type KeyboardShortcutsDialogProps (line 23) | interface KeyboardShortcutsDialogProps {
  type ShortcutGroup (line 28) | interface ShortcutGroup {
  function KeyboardShortcutsDialog (line 38) | function KeyboardShortcutsDialog({ open, onOpenChange }: KeyboardShortcu...

FILE: components/kibo-ui/table/index.tsx
  type TableProviderProps (line 52) | type TableProviderProps<TData, TValue> = {
  function TableProvider (line 59) | function TableProvider<TData, TValue>({
  type TableHeadProps (line 95) | type TableHeadProps = {
  type TableHeaderGroupProps (line 110) | type TableHeaderGroupProps = {
  type TableHeaderProps (line 124) | type TableHeaderProps = {
  type TableColumnHeaderProps (line 139) | interface TableColumnHeaderProps<TData, TValue>
  function TableColumnHeader (line 145) | function TableColumnHeader<TData, TValue>({
  type TableCellProps (line 197) | type TableCellProps = {
  type TableRowProps (line 208) | type TableRowProps = {
  type TableBodyProps (line 224) | type TableBodyProps = {

FILE: components/list-view.tsx
  type Location (line 7) | interface Location {
  type Photo (line 12) | interface Photo {
  type Place (line 21) | interface Place {
  type PlaceCardProps (line 43) | interface PlaceCardProps {

FILE: components/logos/elevenlabs-logo.tsx
  function ElevenLabsLogo (line 1) | function ElevenLabsLogo() {

FILE: components/logos/exa-logo.tsx
  function ExaLogo (line 1) | function ExaLogo() {

FILE: components/logos/sarvam-logo.tsx
  function SarvamLogo (line 1) | function SarvamLogo({

FILE: components/logos/scira-logo.tsx
  function SciraLogo (line 1) | function SciraLogo({

FILE: components/logos/vercel-logo.tsx
  function VercelLogo (line 1) | function VercelLogo() {

FILE: components/map-components.tsx
  type Location (line 9) | interface Location {
  type Place (line 14) | interface Place {
  type MapProps (line 24) | interface MapProps {
  type MapContainerProps (line 351) | interface MapContainerProps {

FILE: components/markdown.tsx
  type FilePreviewDefinition (line 95) | interface FilePreviewDefinition {
  type TaggedLinkData (line 102) | interface TaggedLinkData {
  constant NON_DOWNLOADABLE_EXTENSIONS (line 107) | const NON_DOWNLOADABLE_EXTENSIONS = new Set(['html', 'htm', 'php', 'asp'...
  constant FILE_TYPE_MAP (line 109) | const FILE_TYPE_MAP: Record<string, { typeLabel: string; icon: LucideIco...
  function parseUrlLike (line 173) | function parseUrlLike(href: string): URL | null {
  function getAppPreviewHref (line 182) | function getAppPreviewHref(href: string): string {
  function getAppPreviewScreenshotSrc (line 187) | function getAppPreviewScreenshotSrc(href: string): string | null {
  function getAppPreviewDescription (line 191) | function getAppPreviewDescription(href: string): string {
  function extractFilenameFromHref (line 205) | function extractFilenameFromHref(href: string, fallbackText?: string): s...
  function getFilePreviewDefinition (line 218) | function getFilePreviewDefinition(href: string, fallbackText?: string): ...
  function parseTaggedLinkContent (line 243) | function parseTaggedLinkContent(raw: string): TaggedLinkData | null {
  type MarkdownRendererProps (line 329) | interface MarkdownRendererProps {
  type CitationLink (line 334) | interface CitationLink {
  type CitationGroup (line 345) | interface CitationGroup {
  type CodeBlockProps (line 367) | interface CodeBlockProps {
  constant AUTO_COLLAPSE_THRESHOLD (line 374) | const AUTO_COLLAPSE_THRESHOLD = 25;
  constant PREVIEW_LINES (line 375) | const PREVIEW_LINES = 4;
  type CodeBlockState (line 378) | interface CodeBlockState {
  constant CLEANUP_INTERVAL_MS (line 394) | const CLEANUP_INTERVAL_MS = 5 * 60 * 1000;
  constant MAX_ENTRY_AGE_MS (line 395) | const MAX_ENTRY_AGE_MS = 30 * 60 * 1000;
  function cleanupOldEntries (line 399) | function cleanupOldEntries() {
  function getCodeBlockStateKey (line 414) | function getCodeBlockStateKey(content: string): string {
  type CodeBlockInnerProps (line 426) | interface CodeBlockInnerProps extends CodeBlockProps {
  function extractLinksWithLexer (line 1108) | function extractLinksWithLexer(
  function fetchMetadata (line 1738) | function fetchMetadata(url: string) {
  function preloadCitationMetadata (line 1752) | function preloadCitationMetadata(content: string) {
  type CitationGroupProps (line 2039) | interface CitationGroupProps {
  function downloadFileBlob (line 2254) | async function downloadFileBlob(url: string, filename: string): Promise<...
  function downloadImageBlob (line 2325) | async function downloadImageBlob(url: string, filename: string): Promise...
  method text (line 2635) | text(text: string) {
  method hr (line 2754) | hr() {
  method paragraph (line 2757) | paragraph(children) {
  method code (line 2791) | code(children, language) {
  method codespan (line 2799) | codespan(code) {
  method link (line 2804) | link(href, text) {
  method image (line 2854) | image(src, alt, title) {
  method heading (line 2859) | heading(children, level) {
  method list (line 2878) | list(children, ordered) {
  method listItem (line 2893) | listItem(children) {
  method blockquote (line 2901) | blockquote(children) {
  method strong (line 2912) | strong(children) {
  method em (line 2920) | em(children) {
  method table (line 2928) | table(children) {
  method tableRow (line 2932) | tableRow(children) {
  method tableCell (line 2936) | tableCell(children, flags) {
  method tableHeader (line 2968) | tableHeader(children) {
  method tableBody (line 2976) | tableBody(children) {

FILE: components/mcp-elicitation-modal.tsx
  type ElicitationData (line 13) | interface ElicitationData {
  type SchemaProperty (line 22) | interface SchemaProperty {
  type RequestedSchema (line 39) | interface RequestedSchema {
  function parseSchema (line 45) | function parseSchema(raw: unknown): RequestedSchema {
  function FormField (line 50) | function FormField({
  function getDefaultValue (line 171) | function getDefaultValue(prop: SchemaProperty): unknown {
  function buildElicitationContent (line 180) | function buildElicitationContent(
  type McpElicitationModalProps (line 242) | interface McpElicitationModalProps {
  function McpElicitationModal (line 247) | function McpElicitationModal({ elicitation, onClose }: McpElicitationMod...

FILE: components/mcp-server-list.tsx
  type MCPServer (line 9) | interface MCPServer {
  type MCPServerListProps (line 25) | interface MCPServerListProps {

FILE: components/memory-dialog.tsx
  function MemoryDialog (line 15) | function MemoryDialog() {

FILE: components/message-parts/index.tsx
  type SourceUIPart (line 31) | type SourceUIPart = {
  type SourceItem (line 39) | type SourceItem = {
  type SourceMetadata (line 48) | type SourceMetadata = {
  type XaiMultiAgentToolPart (line 65) | type XaiMultiAgentToolPart = {
  function IconArrowInbox (line 126) | function IconArrowInbox(props: React.SVGProps<SVGSVGElement>) {
  function isToolPartType (line 140) | function isToolPartType(partType: string) {
  function isSourcePartType (line 144) | function isSourcePartType(partType: string) {
  function isXaiMultiAgentToolPart (line 148) | function isXaiMultiAgentToolPart(part: ChatMessage['parts'][number]) {
  function getXaiMultiAgentToolLabel (line 152) | function getXaiMultiAgentToolLabel(partType: XaiMultiAgentToolPart['type...
  function CopyIcon (line 156) | function CopyIcon(props: React.SVGProps<SVGSVGElement>) {
  function TryAgainIcon (line 170) | function TryAgainIcon(props: React.SVGProps<SVGSVGElement>) {
  function formatDynamicToolName (line 322) | function formatDynamicToolName(partType: string, dynamicToolName?: strin...
  function getDynamicStepState (line 333) | function getDynamicStepState(part: any): 'loading' | 'done' | 'error' {
  function getDynamicOutputText (line 339) | function getDynamicOutputText(output: any): string | null {
  function formatValue (line 366) | function formatValue(val: unknown): string {
  constant STRUCTURED_CONTENT_BLOCKLIST (line 392) | const STRUCTURED_CONTENT_BLOCKLIST = new Set([
  function extractStructuredContent (line 405) | function extractStructuredContent(output: unknown): Record<string, unkno...
  function isMarkdownLike (line 420) | function isMarkdownLike(val: unknown): val is string {
  function isTableLike (line 425) | function isTableLike(val: unknown): val is Record<string, unknown>[] {
  type McpApprovalData (line 645) | interface McpApprovalData {
  function extractApprovalData (line 653) | function extractApprovalData(output: unknown): McpApprovalData | null {
  type McpAppRenderData (line 673) | interface McpAppRenderData {
  constant SANDBOX_ORIGIN (line 683) | const SANDBOX_ORIGIN = process.env.NEXT_PUBLIC_MCP_SANDBOX_ORIGIN || '';
  function getSandboxUrl (line 689) | function getSandboxUrl(resourceUri: string): string | null {
  function getSafeToolUiResourceUri (line 694) | function getSafeToolUiResourceUri(candidate: unknown): string | undefined {
  function logMcpAppDebug (line 703) | function logMcpAppDebug(event: string, details?: Record<string, unknown>) {
  function extractMcpAppRenderData (line 707) | function extractMcpAppRenderData(output: unknown): McpAppRenderData | nu...
  function normalizeMcpAppToolResult (line 774) | function normalizeMcpAppToolResult(
  function McpAppOutputBlock (line 820) | function McpAppOutputBlock({
  type McpTimelineEntry (line 1655) | type McpTimelineEntry =
  type InlineElicitationData (line 1660) | interface InlineElicitationData {
  type InlineSchemaProperty (line 1669) | interface InlineSchemaProperty {
  type InlineRequestedSchema (line 1679) | interface InlineRequestedSchema {
  function parseInlineSchema (line 1685) | function parseInlineSchema(raw: unknown): InlineRequestedSchema {
  function getInlineDefaultValue (line 1690) | function getInlineDefaultValue(prop: InlineSchemaProperty): unknown {
  function buildInlineElicitationContent (line 1697) | function buildInlineElicitationContent(
  function getPendingInlineElicitations (line 1723) | function getPendingInlineElicitations(
  function McpInlineElicitationCard (line 1754) | function McpInlineElicitationCard({
  type MessagePartRendererProps (line 2360) | interface MessagePartRendererProps {
  function CanvasSpecRenderer (line 2388) | function CanvasSpecRenderer({ parts, isStreaming }: { parts: ChatMessage...

FILE: components/message.tsx
  type EnhancedErrorDisplayProps (line 47) | interface EnhancedErrorDisplayProps {
  type MessageProps (line 274) | interface MessageProps {
  type MessageEditorProps (line 306) | interface MessageEditorProps {
  constant MAX_EDITOR_FILES (line 316) | const MAX_EDITOR_FILES = 4;
  constant MAX_EDITOR_IMAGE_SIZE (line 317) | const MAX_EDITOR_IMAGE_SIZE = 5 * 1024 * 1024;
  constant MAX_EDITOR_DOCUMENT_SIZE (line 318) | const MAX_EDITOR_DOCUMENT_SIZE = 50 * 1024 * 1024;
  constant EDITOR_ACCEPTED_FILE_TYPES (line 319) | const EDITOR_ACCEPTED_FILE_TYPES = 'image/*,.pdf,.csv,.xlsx,.xls,.docx';
  constant EDITOR_DOCUMENT_MIME_TYPES (line 320) | const EDITOR_DOCUMENT_MIME_TYPES = [
  function isImageFile (line 327) | function isImageFile(file: File): boolean {
  function getMaxSizeForFile (line 331) | function getMaxSizeForFile(file: File): number {
  function insertFileParts (line 335) | function insertFileParts(
  function fileToDataURL (line 359) | function fileToDataURL(file: File): Promise<string> {
  constant USER_MESSAGE_MAX_HEIGHT (line 821) | const USER_MESSAGE_MAX_HEIGHT = 125;

FILE: components/messages.tsx
  type PartInfo (line 12) | interface PartInfo {
  type MessagesProps (line 18) | interface MessagesProps {

FILE: components/movie-info.tsx
  type MediaDetails (line 10) | interface MediaDetails {
  type TMDBResultProps (line 42) | interface TMDBResultProps {

FILE: components/multi-search.tsx
  type SearchImage (line 63) | type SearchImage = {
  type SearchResult (line 68) | type SearchResult = {
  type SearchQueryResult (line 76) | type SearchQueryResult = {
  type MultiSearchResponse (line 82) | type MultiSearchResponse = {
  type Topic (line 86) | type Topic = 'general' | 'news';
  type MultiSearchArgs (line 88) | type MultiSearchArgs = {
  type NormalizedMultiSearchArgs (line 95) | type NormalizedMultiSearchArgs = {
  constant PREVIEW_IMAGE_COUNT (line 103) | const PREVIEW_IMAGE_COUNT = 5;

FILE: components/nearby-search-map-view.tsx
  type Location (line 10) | interface Location {
  type Photo (line 15) | interface Photo {
  type Place (line 23) | interface Place {
  type NearbySearchMapViewProps (line 57) | interface NearbySearchMapViewProps {

FILE: components/new-chat-hotkey.tsx
  function isEditableTarget (line 6) | function isEditableTarget(target: EventTarget | null): boolean {
  function NewChatHotkey (line 13) | function NewChatHotkey() {

FILE: components/onchain-crypto-components.tsx
  type OnChainTokenPriceProps (line 14) | interface OnChainTokenPriceProps {

FILE: components/place-card.tsx
  type Location (line 18) | interface Location {
  type Photo (line 23) | interface Photo {
  type Place (line 31) | interface Place {
  type PlaceCardProps (line 63) | interface PlaceCardProps {

FILE: components/placeholder-image.tsx
  type PlaceholderImageProps (line 5) | interface PlaceholderImageProps {

FILE: components/prediction-search.tsx
  type PredictionMarket (line 91) | type PredictionMarket = {
  type PredictionSearchResponse (line 121) | type PredictionSearchResponse = {
  type PredictionSearchArgs (line 132) | type PredictionSearchArgs = {

FILE: components/reasoning-part.tsx
  type ReasoningPartViewProps (line 9) | interface ReasoningPartViewProps {
  type TableFlags (line 21) | interface TableFlags {
  method code (line 42) | code(code: string, language?: string) {
  method codespan (line 52) | codespan(code: string) {
  method paragraph (line 62) | paragraph(text: ReactNode) {
  method strong (line 69) | strong(text: ReactNode) {
  method heading (line 76) | heading(text: ReactNode, level: number) {
  method link (line 94) | link(href: string, text: ReactNode) {
  method list (line 106) | list(body: ReactNode, ordered: boolean) {
  method listItem (line 117) | listItem(text: ReactNode) {
  method blockquote (line 124) | blockquote(text: ReactNode) {
  method hr (line 134) | hr() {
  method table (line 137) | table(children: ReactNode[]) {
  method tableRow (line 144) | tableRow(content: ReactNode) {
  method tableCell (line 151) | tableCell(children: ReactNode[], flags: TableFlags) {

FILE: components/reddit-search.tsx
  type RedditResult (line 55) | type RedditResult = {
  type RedditSearchQueryResult (line 66) | type RedditSearchQueryResult = {
  type RedditSearchResponse (line 71) | type RedditSearchResponse = {
  type RedditSearchArgs (line 75) | type RedditSearchArgs = {

FILE: components/retrieve-results.tsx
  type RetrieveResult (line 16) | interface RetrieveResult {
  type RetrieveResponse (line 36) | interface RetrieveResponse {

FILE: components/reui/stepper.tsx
  type StepperOrientation (line 20) | type StepperOrientation = "horizontal" | "vertical"
  type StepState (line 21) | type StepState = "active" | "completed" | "inactive" | "loading"
  type StepIndicators (line 22) | type StepIndicators = {
  type StepperContextValue (line 29) | interface StepperContextValue {
  type StepItemContextValue (line 43) | interface StepItemContextValue {
  function useStepper (line 55) | function useStepper() {
  function useStepItem (line 61) | function useStepItem() {
  type StepperProps (line 67) | interface StepperProps extends HTMLAttributes<HTMLDivElement> {
  function Stepper (line 75) | function Stepper({
  type StepperItemProps (line 169) | interface StepperItemProps extends React.HTMLAttributes<HTMLDivElement> {
  function StepperItem (line 176) | function StepperItem({
  type StepperTriggerProps (line 216) | interface StepperTriggerProps extends React.ButtonHTMLAttributes<HTMLBut...
  function StepperTrigger (line 220) | function StepperTrigger({
  function StepperIndicator (line 325) | function StepperIndicator({
  function StepperSeparator (line 358) | function StepperSeparator({ className }: React.ComponentProps<"div">) {
  function StepperTitle (line 373) | function StepperTitle({ children, className }: React.ComponentProps<"h3"...
  function StepperDescription (line 390) | function StepperDescription({
  function StepperNav (line 410) | function StepperNav({ children, className }: React.ComponentProps<"nav">) {
  function StepperPanel (line 428) | function StepperPanel({ children, className }: React.ComponentProps<"div...
  type StepperContentProps (line 442) | interface StepperContentProps extends React.ComponentProps<"div"> {
  function StepperContent (line 447) | function StepperContent({

FILE: components/reui/timeline.tsx
  type TimelineContextValue (line 15) | type TimelineContextValue = {
  type TimelineProps (line 34) | interface TimelineProps extends HTMLAttributes<HTMLDivElement> {
  function Timeline (line 41) | function Timeline({
  function TimelineContent (line 84) | function TimelineContent({
  type TimelineDateProps (line 98) | interface TimelineDateProps extends HTMLAttributes<HTMLTimeElement> {
  function TimelineDate (line 102) | function TimelineDate({
  function TimelineHeader (line 122) | function TimelineHeader({
  type TimelineIndicatorProps (line 132) | interface TimelineIndicatorProps extends HTMLAttributes<HTMLDivElement> {
  function TimelineIndicator (line 136) | function TimelineIndicator({
  type TimelineItemProps (line 160) | interface TimelineItemProps extends HTMLAttributes<HTMLDivElement> {
  function TimelineItem (line 164) | function TimelineItem({ step, className, ...props }: TimelineItemProps) {
  function TimelineSeparator (line 181) | function TimelineSeparator({
  function TimelineTitle (line 199) | function TimelineTitle({

FILE: components/searches-page.tsx
  function getModelLabel (line 55) | function getModelLabel(modelValue: string): string {
  type Chat (line 60) | interface Chat {
  type SearchesPageProps (line 72) | interface SearchesPageProps {
  type VisibilityFilter (line 76) | type VisibilityFilter = 'all' | 'public' | 'private';
  type DateFilter (line 77) | type DateFilter = 'all' | 'today' | 'week' | 'month';
  type SortOrder (line 78) | type SortOrder = 'newest' | 'oldest';
  constant ITEMS_PER_PAGE (line 80) | const ITEMS_PER_PAGE = 25;
  function fuzzySearch (line 82) | function fuzzySearch(query: string, text: string): boolean {
  function advancedSearch (line 94) | function advancedSearch(
  type TimeGroup (line 137) | type TimeGroup = 'pinned' | 'today' | 'yesterday' | 'this_week' | 'this_...
  function getChatTimeGroup (line 139) | function getChatTimeGroup(chat: Chat): TimeGroup {
  constant GROUP_LABELS (line 149) | const GROUP_LABELS: Record<TimeGroup, string> = {
  constant GROUP_ORDER (line 158) | const GROUP_ORDER: TimeGroup[] = ['pinned', 'today', 'yesterday', 'this_...
  function SearchesPage (line 160) | function SearchesPage({ userId }: SearchesPageProps) {

FILE: components/settings-dialog.tsx
  type SettingsDialogProps (line 117) | interface SettingsDialogProps {
  function ProfileSection (line 130) | function ProfileSection({ user, subscriptionData, isProUser, isProStatus...
  type AutoRouterRoute (line 260) | type AutoRouterRoute = {
  type AutoRouterConfig (line 266) | type AutoRouterConfig = {
  function getDefaultAutoRouterRoutes (line 270) | function getDefaultAutoRouterRoutes(): AutoRouterRoute[] {
  function PreferencesSection (line 301) | function PreferencesSection({
  type TimePeriod (line 1095) | type TimePeriod = '7d' | '30d' | '12m';
  function UsageSection (line 1097) | function UsageSection({ user }: any) {
  function SubscriptionSection (line 1540) | function SubscriptionSection({ subscriptionData, isProUser, user }: any) {
  type UploadedFile (line 2041) | interface UploadedFile {
  type UploadsResponse (line 2052) | interface UploadsResponse {
  type FileFilter (line 2058) | type FileFilter = 'all' | 'images' | 'documents';
  function formatBytes (line 2060) | function formatBytes(bytes: number): string {
  constant IMAGE_MIMES (line 2068) | const IMAGE_MIMES = ['image/jpeg', 'image/png', 'image/gif'];
  constant IMAGE_EXTENSIONS (line 2069) | const IMAGE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif'];
  constant FILE_TYPES (line 2071) | const FILE_TYPES = {
  type DetectedType (line 2082) | type DetectedType = keyof typeof FILE_TYPES;
  function detectFileType (line 2084) | function detectFileType(mediaType: string | null, filename: string): Det...
  function getFileCategory (line 2096) | function getFileCategory(mediaType: string | null, filename: string): 'i...
  function FileTypeIcon (line 2100) | function FileTypeIcon({
  function UploadsSection (line 2128) | function UploadsSection() {
  function MemoriesSection (line 2592) | function MemoriesSection() {
  function ConnectorsSection (line 2782) | function ConnectorsSection({ user }: { user: any }) {
  type McpServerRecord (line 3198) | interface McpServerRecord {
  function McpSection (line 3221) | function McpSection({ user, isProUser }: { user: any; isProUser?: boolea...
  function SettingsDialog (line 3838) | function SettingsDialog({

FILE: components/settings/theme-previews.tsx
  type ThemeOption (line 8) | interface ThemeOption {
  function ThemeMiniPreview (line 15) | function ThemeMiniPreview({
  function ThemePreviews (line 66) | function ThemePreviews({ className, variant = 'full' }: { className?: st...

FILE: components/share-viewer.tsx
  type ShareViewerProps (line 18) | interface ShareViewerProps {
  function ShareViewer (line 27) | function ShareViewer({ chatId, chatTitle, shareUrl, messages, isSignedIn...

FILE: components/share/share-attachments-badge.tsx
  type ShareAttachmentsBadgeProps (line 6) | interface ShareAttachmentsBadgeProps {
  function getAttachmentLabel (line 11) | function getAttachmentLabel(attachment: Attachment, index: number): stri...
  function getAttachmentKind (line 21) | function getAttachmentKind(attachment: Attachment): 'image' | 'document'...
  function ShareAttachmentsBadge (line 37) | function ShareAttachmentsBadge({ attachments, className }: ShareAttachme...

FILE: components/share/share-button.tsx
  function IconArrowOutOfBox (line 9) | function IconArrowOutOfBox(props: React.SVGProps<SVGSVGElement>) {
  type ShareButtonProps (line 23) | interface ShareButtonProps {
  function ShareButton (line 35) | function ShareButton({

FILE: components/share/share-dialog.tsx
  type ShareDialogProps (line 23) | interface ShareDialogProps {
  function ShareDialog (line 33) | function ShareDialog({

FILE: components/sidebar-layout.tsx
  function SidebarLayout (line 9) | function SidebarLayout({ children }: { children: React.ReactNode }) {

FILE: components/sign-in-prompt-dialog.tsx
  type SignInPromptDialogProps (line 13) | interface SignInPromptDialogProps {
  type SignInButtonProps (line 18) | interface SignInButtonProps {
  function SignInPromptDialog (line 117) | function SignInPromptDialog({ open, onOpenChange }: SignInPromptDialogPr...

FILE: components/spotify-search-results.tsx
  type AudioPlayerState (line 89) | interface AudioPlayerState {
  type TabType (line 96) | type TabType = 'tracks' | 'artists' | 'albums' | 'playlists';
  type SpotifySearchResultsProps (line 702) | interface SpotifySearchResultsProps {

FILE: components/student-domain-request-button.tsx
  function StudentDomainRequestButton (line 19) | function StudentDomainRequestButton() {

FILE: components/supported-domains-list.tsx
  type SupportedDomainsListProps (line 20) | interface SupportedDomainsListProps {
  type DomainsData (line 24) | interface DomainsData {
  function SupportedDomainsList (line 32) | function SupportedDomainsList({ className }: SupportedDomainsListProps) {

FILE: components/text-translate.tsx
  type TextTranslateToolArgs (line 23) | interface TextTranslateToolArgs {
  type TextTranslateToolResult (line 29) | interface TextTranslateToolResult {
  type TextTranslateProps (line 34) | interface TextTranslateProps {
  function normalizeLanguageCode (line 40) | function normalizeLanguageCode(value: string | undefined | null): string {
  function getLanguageName (line 46) | function getLanguageName(languageCode: string): string {
  function copyToClipboard (line 56) | async function copyToClipboard(text: string, label: string) {
  function SimpleAudioPlayer (line 66) | function SimpleAudioPlayer({
  function LoadingMatrix (line 107) | function LoadingMatrix() {
  function TranscriptPlayer (line 126) | function TranscriptPlayer({
  function TextTranslate (line 175) | function TextTranslate({ args, result, className }: TextTranslateProps) {

FILE: components/theme-switcher.tsx
  type ThemeConfig (line 10) | interface ThemeConfig {
  constant THEMES (line 18) | const THEMES: ThemeConfig[] = [
  function ThemeSwatch (line 84) | function ThemeSwatch({ colors, size = 'sm' }: { colors: [string, string,...
  function ThemeSwitcher (line 95) | function ThemeSwitcher() {

FILE: components/tool-invocation-list-view.tsx
  function CodeInterpreterView (line 252) | function CodeInterpreterView({

FILE: components/trending-tv-movies-results.tsx
  type TrendingItem (line 9) | interface TrendingItem {
  type TrendingResultsProps (line 23) | interface TrendingResultsProps {

FILE: components/ui/accordion.tsx
  function Accordion (line 9) | function Accordion({
  function AccordionItem (line 15) | function AccordionItem({
  function AccordionTrigger (line 28) | function AccordionTrigger({
  function AccordionContent (line 50) | function AccordionContent({

FILE: components/ui/alert-dialog.tsx
  function AlertDialog (line 9) | function AlertDialog({
  function AlertDialogTrigger (line 15) | function AlertDialogTrigger({
  function AlertDialogPortal (line 23) | function AlertDialogPortal({
  function AlertDialogOverlay (line 31) | function AlertDialogOverlay({
  function AlertDialogContent (line 47) | function AlertDialogContent({
  function AlertDialogHeader (line 66) | function AlertDialogHeader({
  function AlertDialogFooter (line 79) | function AlertDialogFooter({
  function AlertDialogTitle (line 95) | function AlertDialogTitle({
  function AlertDialogDescription (line 108) | function AlertDialogDescription({
  function AlertDialogAction (line 121) | function AlertDialogAction({
  function AlertDialogCancel (line 133) | function AlertDialogCancel({

FILE: components/ui/alert.tsx
  function Alert (line 22) | function Alert({
  function AlertTitle (line 37) | function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
  function AlertDescription (line 50) | function AlertDescription({

FILE: components/ui/animated-beam.tsx
  type AnimatedBeamProps (line 8) | interface AnimatedBeamProps {

FILE: components/ui/audio-lines.tsx
  type AudioLinesIconHandle (line 8) | interface AudioLinesIconHandle {
  type AudioLinesIconProps (line 13) | interface AudioLinesIconProps extends HTMLAttributes<HTMLDivElement> {

FILE: components/ui/audio-player.tsx
  type ReadyState (line 28) | enum ReadyState {
  type NetworkState (line 36) | enum NetworkState {
  function formatTime (line 43) | function formatTime(seconds: number) {
  type AudioPlayerItem (line 56) | interface AudioPlayerItem<TData = unknown> {
  type AudioPlayerApi (line 62) | interface AudioPlayerApi<TData = unknown> {
  function useAudioPlayer (line 80) | function useAudioPlayer<TData = unknown>(): AudioPlayerApi<TData> {
  function AudioPlayerProvider (line 102) | function AudioPlayerProvider<TData = unknown>({
  type SpinnerProps (line 380) | interface SpinnerProps {
  function Spinner (line 384) | function Spinner({ className }: SpinnerProps) {
  type PlayButtonProps (line 399) | interface PlayButtonProps extends React.ComponentProps<typeof Button> {
  type AudioPlayerButtonProps (line 444) | interface AudioPlayerButtonProps<TData = unknown>
  function AudioPlayerButton (line 449) | function AudioPlayerButton<TData = unknown>({
  type Callback (line 490) | type Callback = (delta: number) => void
  function useAnimationFrame (line 492) | function useAnimationFrame(callback: Callback) {
  constant PLAYBACK_SPEEDS (line 520) | const PLAYBACK_SPEEDS = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2] as const
  type AudioPlayerSpeedProps (line 522) | interface AudioPlayerSpeedProps
  function AudioPlayerSpeed (line 527) | function AudioPlayerSpeed({
  type AudioPlayerSpeedButtonGroupProps (line 568) | interface AudioPlayerSpeedButtonGroupProps
  function AudioPlayerSpeedButtonGroup (line 573) | function AudioPlayerSpeedButtonGroup({

FILE: components/ui/avatar.tsx
  function Avatar (line 8) | function Avatar({
  function AvatarImage (line 24) | function AvatarImage({
  function AvatarFallback (line 37) | function AvatarFallback({

FILE: components/ui/badge.tsx
  function Badge (line 30) | function Badge({

FILE: components/ui/button-group.tsx
  function ButtonGroup (line 24) | function ButtonGroup({
  function ButtonGroupText (line 40) | function ButtonGroupText({
  function ButtonGroupSeparator (line 60) | function ButtonGroupSeparator({

FILE: components/ui/calendar.tsx
  function Calendar (line 18) | function Calendar({
  function CalendarDayButton (line 182) | function CalendarDayButton({

FILE: components/ui/card.tsx
  function Card (line 5) | function Card({ className, ...props }: React.ComponentProps<"div">) {
  function CardHeader (line 18) | function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
  function CardTitle (line 31) | function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
  function CardDescription (line 41) | function CardDescription({ className, ...props }: React.ComponentProps<"...
  function CardAction (line 51) | function CardAction({ className, ...props }: React.ComponentProps<"div">) {
  function CardContent (line 64) | function CardContent({ className, ...props }: React.ComponentProps<"div"...
  function CardFooter (line 74) | function CardFooter({ className, ...props }: React.ComponentProps<"div">) {

FILE: components/ui/carousel.tsx
  type CarouselApi (line 12) | type CarouselApi = UseEmblaCarouselType[1]
  type UseCarouselParameters (line 13) | type UseCarouselParameters = Parameters<typeof useEmblaCarousel>
  type CarouselOptions (line 14) | type CarouselOptions = UseCarouselParameters[0]
  type CarouselPlugin (line 15) | type CarouselPlugin = UseCarouselParameters[1]
  type CarouselProps (line 17) | type CarouselProps = {
  type CarouselContextProps (line 24) | type CarouselContextProps = {
  function useCarousel (line 35) | function useCarousel() {
  function Carousel (line 45) | function Carousel({
  function CarouselContent (line 135) | function CarouselContent({ className, ...props }: React.ComponentProps<"...
  function CarouselItem (line 156) | function CarouselItem({ className, ...props }: React.ComponentProps<"div...
  function CarouselPrevious (line 174) | function CarouselPrevious({
  function CarouselNext (line 204) | function CarouselNext({

FILE: components/ui/chart.tsx
  constant THEMES (line 9) | const THEMES = { light: "", dark: ".dark" } as const
  type ChartConfig (line 11) | type ChartConfig = {
  type ChartContextProps (line 21) | type ChartContextProps = {
  function useChart (line 27) | function useChart() {
  function ChartContainer (line 37) | function ChartContainer({
  function ChartTooltipContent (line 107) | function ChartTooltipContent({
  function ChartLegendContent (line 255) | function ChartLegendContent({
  function getPayloadConfigFromPayload (line 312) | function getPayloadConfigFromPayload(

FILE: components/ui/checkbox.tsx
  function Checkbox (line 9) | function Checkbox({

FILE: components/ui/collapsible.tsx
  function Collapsible (line 5) | function Collapsible({
  function CollapsibleTrigger (line 11) | function CollapsibleTrigger({
  function CollapsibleContent (line 22) | function CollapsibleContent({

FILE: components/ui/command.tsx
  function Command (line 16) | function Command({
  function CommandDialog (line 32) | function CommandDialog({
  function CommandInput (line 63) | function CommandInput({
  function CommandList (line 85) | function CommandList({
  function CommandEmpty (line 101) | function CommandEmpty({
  function CommandGroup (line 113) | function CommandGroup({
  function CommandSeparator (line 129) | function CommandSeparator({
  function CommandItem (line 142) | function CommandItem({
  function CommandShortcut (line 158) | function CommandShortcut({

FILE: components/ui/dialog.tsx
  function Dialog (line 9) | function Dialog({
  function DialogTrigger (line 15) | function DialogTrigger({
  function DialogPortal (line 21) | function DialogPortal({
  function DialogClose (line 27) | function DialogClose({
  function DialogOverlay (line 33) | function DialogOverlay({
  function DialogContent (line 49) | function DialogContent({
  function DialogHeader (line 83) | function DialogHeader({ className, ...props }: React.ComponentProps<"div...
  function DialogFooter (line 93) | function DialogFooter({ className, ...props }: React.ComponentProps<"div...
  function DialogTitle (line 106) | function DialogTitle({
  function DialogDescription (line 119) | function DialogDescription({

FILE: components/ui/drawer.tsx
  function Drawer (line 8) | function Drawer({
  function DrawerTrigger (line 14) | function DrawerTrigger({
  function DrawerPortal (line 20) | function DrawerPortal({
  function DrawerClose (line 26) | function DrawerClose({
  function DrawerOverlay (line 32) | function DrawerOverlay({
  function DrawerContent (line 48) | function DrawerContent({
  function DrawerHeader (line 75) | function DrawerHeader({ className, ...props }: React.ComponentProps<"div...
  function DrawerFooter (line 88) | function DrawerFooter({ className, ...props }: React.ComponentProps<"div...
  function DrawerTitle (line 98) | function DrawerTitle({
  function DrawerDescription (line 111) | function DrawerDescription({

FILE: components/ui/dropdown-menu.tsx
  function DropdownMenu (line 9) | function DropdownMenu({
  function DropdownMenuPortal (line 15) | function DropdownMenuPortal({
  function DropdownMenuTrigger (line 23) | function DropdownMenuTrigger({
  function DropdownMenuContent (line 34) | function DropdownMenuContent({
  function DropdownMenuGroup (line 54) | function DropdownMenuGroup({
  function DropdownMenuItem (line 62) | function DropdownMenuItem({
  function DropdownMenuCheckboxItem (line 85) | function DropdownMenuCheckboxItem({
  function DropdownMenuRadioGroup (line 111) | function DropdownMenuRadioGroup({
  function DropdownMenuRadioItem (line 122) | function DropdownMenuRadioItem({
  function DropdownMenuLabel (line 146) | function DropdownMenuLabel({
  function DropdownMenuSeparator (line 166) | function DropdownMenuSeparator({
  function DropdownMenuShortcut (line 179) | function DropdownMenuShortcut({
  function DropdownMenuSub (line 195) | function DropdownMenuSub({
  function DropdownMenuSubTrigger (line 201) | function DropdownMenuSubTrigger({
  function DropdownMenuSubContent (line 225) | function DropdownMenuSubContent({

FILE: components/ui/empty.tsx
  function Empty (line 5) | function Empty({ className, ...props }: React.ComponentProps<'div'>) {
  function EmptyHeader (line 18) | function EmptyHeader({ className, ...props }: React.ComponentProps<'div'...
  function EmptyMedia (line 43) | function EmptyMedia({
  function EmptyTitle (line 58) | function EmptyTitle({ className, ...props }: React.ComponentProps<'div'>) {
  function EmptyDescription (line 62) | function EmptyDescription({ className, ...props }: React.ComponentProps<...
  function EmptyContent (line 75) | function EmptyContent({ className, ...props }: React.ComponentProps<'div...

FILE: components/ui/form-component.tsx
  type SvgIconComponent (line 93) | type SvgIconComponent = React.ComponentType<React.SVGProps<SVGSVGElement>>;
  type HugeiconsIconProp (line 94) | type HugeiconsIconProp = React.ComponentProps<typeof HugeiconsIcon>['ico...
  function FlexibleIcon (line 109) | function FlexibleIcon({
  constant PROVIDER_ORDER (line 352) | const PROVIDER_ORDER: (ModelProvider | 'all')[] = [
  function getCountryCodeOnce (line 382) | async function getCountryCodeOnce(): Promise<string | null> {
  type TypewriterResumeCache (line 399) | interface TypewriterResumeCache {
  type ModelSwitcherProps (line 408) | interface ModelSwitcherProps {
  type SearchIndexEntry (line 544) | type SearchIndexEntry = {
  type Attachment (line 1921) | interface Attachment {
  constant MAX_FILES (line 1950) | const MAX_FILES = 4;
  constant MAX_IMAGE_SIZE (line 1951) | const MAX_IMAGE_SIZE = 5 * 1024 * 1024;
  constant MAX_DOCUMENT_SIZE (line 1952) | const MAX_DOCUMENT_SIZE = 50 * 1024 * 1024;
  constant MAX_INPUT_CHARS (line 1953) | const MAX_INPUT_CHARS = 50000;
  type UploadingAttachment (line 2171) | interface UploadingAttachment {
  type FormComponentProps (line 2176) | interface FormComponentProps {
  type GroupSelectorProps (line 2213) | interface GroupSelectorProps {
  type ConnectorSelectorProps (line 2224) | interface ConnectorSelectorProps {
  type McpServerSelectorProps (line 2346) | interface McpServerSelectorProps {
  constant WEB_SEARCH_PROVIDERS (line 2735) | const WEB_SEARCH_PROVIDERS: Array<{

FILE: components/ui/form.tsx
  type FormFieldContextValue (line 21) | type FormFieldContextValue<
  type FormItemContextValue (line 68) | type FormItemContextValue = {
  function FormItem (line 76) | function FormItem({ className, ...props }: React.ComponentProps<"div">) {
  function FormLabel (line 90) | function FormLabel({
  function FormControl (line 107) | function FormControl({ ...props }: React.ComponentProps<typeof Slot>) {
  function FormDescription (line 125) | function FormDescription({ className, ...props }: React.ComponentProps<"...
  function FormMessage (line 138) | function FormMessage({ className, ...props }: React.ComponentProps<"p">) {

FILE: components/ui/grip.tsx
  type GripIconHandle (line 9) | interface GripIconHandle {
  type GripIconProps (line 14) | interface GripIconProps extends HTMLAttributes<HTMLDivElement> {
  constant CIRCLES (line 18) | const CIRCLES = [

FILE: components/ui/hover-card.tsx
  function HoverCard (line 8) | function HoverCard({
  function HoverCardTrigger (line 14) | function HoverCardTrigger({
  function HoverCardContent (line 22) | function HoverCardContent({

FILE: components/ui/hugeicons.tsx
  type BaseProps (line 6) | type BaseProps = React.ComponentProps<typeof BaseHugeiconsIcon>;
  function HugeiconsIcon (line 8) | function HugeiconsIcon({ strokeWidth: _ignored, ...rest }: BaseProps) {

FILE: components/ui/input-group.tsx
  function InputGroup (line 11) | function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
  function InputGroupAddon (line 44) | function InputGroupAddon({
  function InputGroupButton (line 83) | function InputGroupButton({
  function InputGroupText (line 102) | function InputGroupText({ className, ...props }: React.ComponentProps<"s...
  function InputGroupInput (line 114) | function InputGroupInput({
  function InputGroupTextarea (line 127) | function InputGroupTextarea({

FILE: components/ui/input.tsx
  function Input (line 5) | function Input({ className, type, ...props }: React.ComponentProps<"inpu...

FILE: components/ui/kbd.tsx
  function Kbd (line 3) | function Kbd({ className, ...props }: React.ComponentProps<"kbd">) {
  function KbdGroup (line 18) | function KbdGroup({ className, ...props }: React.ComponentProps<"div">) {

FILE: components/ui/kibo-ui/contribution-graph/index.tsx
  type Activity (line 26) | type Activity = {
  type Week (line 32) | type Week = Array<Activity | undefined>;
  type Labels (line 34) | type Labels = {
  type MonthLabel (line 44) | type MonthLabel = {
  constant DEFAULT_MONTH_LABELS (line 49) | const DEFAULT_MONTH_LABELS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', ...
  constant DEFAULT_LABELS (line 51) | const DEFAULT_LABELS: Labels = {
  type ContributionGraphContextType (line 61) | type ContributionGraphContextType = {
  type ContributionGraphProps (line 188) | type ContributionGraphProps = HTMLAttributes<HTMLDivElement> & {
  type ContributionGraphBlockProps (line 262) | type ContributionGraphBlockProps = HTMLAttributes<SVGRectElement> & {
  type ContributionGraphCalendarProps (line 311) | type ContributionGraphCalendarProps = Omit<HTMLAttributes<HTMLDivElement...
  type ContributionGraphFooterProps (line 354) | type ContributionGraphFooterProps = HTMLAttributes<HTMLDivElement>;
  type ContributionGraphTotalCountProps (line 360) | type ContributionGraphTotalCountProps = Omit<HTMLAttributes<HTMLDivEleme...
  type ContributionGraphLegendProps (line 380) | type ContributionGraphLegendProps = Omit<HTMLAttributes<HTMLDivElement>,...

FILE: components/ui/label.tsx
  function Label (line 8) | function Label({

FILE: components/ui/live-waveform.tsx
  type LiveWaveformProps (line 7) | type LiveWaveformProps = HTMLAttributes<HTMLDivElement> & {

FILE: components/ui/loading.tsx
  function ClassicLoader (line 3) | function ClassicLoader({ className, size = 'md' }: { className?: string;...

FILE: components/ui/magic-edit-icon.tsx
  type MagicEditIconProps (line 3) | interface MagicEditIconProps extends SVGProps<SVGSVGElement> {
  function MagicEditIcon (line 7) | function MagicEditIcon({ size = 24, ...props }: MagicEditIconProps) {

FILE: components/ui/magic-wand-icon.tsx
  type MagicWandIconProps (line 3) | interface MagicWandIconProps extends SVGProps<SVGSVGElement> {
  function MagicWandIcon (line 7) | function MagicWandIcon({ size = 24, className, ...props }: MagicWandIcon...

FILE: components/ui/matrix.tsx
  type Frame (line 8) | type Frame = number[][]
  type MatrixMode (line 9) | type MatrixMode = "default" | "vu"
  type CellPosition (line 11) | interface CellPosition {
  type MatrixProps (line 16) | interface MatrixProps extends React.HTMLAttributes<HTMLDivElement> {
  function clamp (line 37) | function clamp(value: number): number {
  function ensureFrameSize (line 41) | function ensureFrameSize(frame: Frame, rows: number, cols: number): Frame {
  function useAnimation (line 53) | function useAnimation(
  function emptyFrame (line 125) | function emptyFrame(rows: number, cols: number): Frame {
  function setPixel (line 129) | function setPixel(frame: Frame, row: number, col: number, value: number)...
  function vu (line 293) | function vu(columns: number, levels: number[]): Frame {

FILE: components/ui/model-selector.tsx
  type ModelSelectorDialogProps (line 252) | interface ModelSelectorDialogProps {
  function sortModelsForList (line 265) | function sortModelsForList(
  function ModelSelectorDialog (line 301) | function ModelSelectorDialog({

FILE: components/ui/navigation-menu.tsx
  function NavigationMenu (line 8) | function NavigationMenu({
  function NavigationMenuList (line 32) | function NavigationMenuList({
  function NavigationMenuItem (line 48) | function NavigationMenuItem({
  function NavigationMenuTrigger (line 65) | function NavigationMenuTrigger({
  function NavigationMenuContent (line 85) | function NavigationMenuContent({
  function NavigationMenuViewport (line 102) | function NavigationMenuViewport({
  function NavigationMenuLink (line 124) | function NavigationMenuLink({
  function NavigationMenuIndicator (line 140) | function NavigationMenuIndicator({

FILE: components/ui/orb.tsx
  type AgentState (line 8) | type AgentState = null | "thinking" | "listening" | "talking"
  type OrbProps (line 10) | type OrbProps = {
  function Orb (line 26) | function Orb({
  function Scene (line 69) | function Scene({
  function splitmix32 (line 266) | function splitmix32(a: number) {
  function clamp01 (line 278) | function clamp01(n: number) {

FILE: components/ui/popover.tsx
  function Popover (line 8) | function Popover({
  function PopoverTrigger (line 14) | function PopoverTrigger({
  function PopoverContent (line 20) | function PopoverContent({
  function PopoverAnchor (line 42) | function PopoverAnchor({

FILE: components/ui/processor-icon.tsx
  type ProcessorIconProps (line 3) | interface ProcessorIconProps extends SVGProps<SVGSVGElement> {
  function ProcessorIcon (line 7) | function ProcessorIcon({ size = 24, className, ...props }: ProcessorIcon...

FILE: components/ui/progress-ring.tsx
  type ProgressRingProps (line 4) | interface ProgressRingProps {

FILE: components/ui/progress.tsx
  function Progress (line 8) | function Progress({

FILE: components/ui/scroll-area.tsx
  function ScrollArea (line 8) | function ScrollArea({
  function ScrollBar (line 31) | function ScrollBar({

FILE: components/ui/scrub-bar.tsx
  function formatTimestamp (line 16) | function formatTimestamp(value: number) {
  type ScrubBarContextValue (line 24) | interface ScrubBarContextValue {
  function useScrubBarContext (line 35) | function useScrubBarContext() {
  type ScrubBarContainerProps (line 43) | interface ScrubBarContainerProps extends HTMLAttributes<HTMLDivElement> {
  function ScrubBarContainer (line 51) | function ScrubBarContainer({
  type ScrubBarTrackProps (line 86) | type ScrubBarTrackProps = HTMLAttributes<HTMLDivElement>
  function ScrubBarTrack (line 88) | function ScrubBarTrack({ className, children, ...props }: ScrubBarTrackP...
  type ScrubBarProgressProps (line 157) | type ScrubBarProgressProps = Omit<ComponentProps<typeof Progress>, "value">
  function ScrubBarProgress (line 159) | function ScrubBarProgress({ className, ...props }: ScrubBarProgressProps) {
  type ScrubBarThumbProps (line 173) | type ScrubBarThumbProps = HTMLAttributes<HTMLDivElement>
  function ScrubBarThumb (line 175) | function ScrubBarThumb({ className, children, ...props }: ScrubBarThumbP...
  type ScrubBarTimeLabelProps (line 193) | interface ScrubBarTimeLabelProps extends HTMLAttributes<HTMLSpanElement> {
  function ScrubBarTimeLabel (line 198) | function ScrubBarTimeLabel({

FILE: components/ui/select.tsx
  function Select (line 9) | function Select({
  function SelectGroup (line 15) | function SelectGroup({
  function SelectValue (line 21) | function SelectValue({
  function SelectTrigger (line 27) | function SelectTrigger({
  function SelectContent (line 53) | function SelectContent({
  function SelectLabel (line 90) | function SelectLabel({
  function SelectItem (line 103) | function SelectItem({
  function SelectSeparator (line 130) | function SelectSeparator({
  function SelectScrollUpButton (line 143) | function SelectScrollUpButton({
  function SelectScrollDownButton (line 161) | function SelectScrollDownButton({

FILE: components/ui/separator.tsx
  function Separator (line 8) | function Separator({

FILE: components/ui/settings.tsx
  type SettingsIconHandle (line 9) | interface SettingsIconHandle {
  type SettingsIconProps (line 14) | interface SettingsIconProps extends HTMLAttributes<HTMLDivElement> {

FILE: components/ui/sheet.tsx
  function Sheet (line 9) | function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive....
  function SheetTrigger (line 13) | function SheetTrigger({
  function SheetClose (line 19) | function SheetClose({
  function SheetPortal (line 25) | function SheetPortal({
  function SheetOverlay (line 31) | function SheetOverlay({
  function SheetContent (line 47) | function SheetContent({
  function SheetHeader (line 84) | function SheetHeader({ className, ...props }: React.ComponentProps<"div"...
  function SheetFooter (line 94) | function SheetFooter({ className, ...props }: React.ComponentProps<"div"...
  function SheetTitle (line 104) | function SheetTitle({
  function SheetDescription (line 117) | function SheetDescription({

FILE: components/ui/sidebar.tsx
  constant SIDEBAR_COOKIE_NAME (line 16) | const SIDEBAR_COOKIE_NAME = 'sidebar_state';
  constant SIDEBAR_WIDTH (line 17) | const SIDEBAR_WIDTH = '16rem';
  constant SIDEBAR_WIDTH_MOBILE (line 18) | const SIDEBAR_WIDTH_MOBILE = '18rem';
  constant SIDEBAR_WIDTH_ICON (line 19) | const SIDEBAR_WIDTH_ICON = '3rem';
  constant SIDEBAR_KEYBOARD_SHORTCUT (line 20) | const SIDEBAR_KEYBOARD_SHORTCUT = 'b';
  type SidebarContextProps (line 22) | type SidebarContextProps = {
  function useSidebar (line 34) | function useSidebar() {
  function SidebarProvider (line 43) | function SidebarProvider({
  function Sidebar (line 146) | function Sidebar({
  function SidebarSimpleLeftSquareIcon (line 255) | function SidebarSimpleLeftSquareIcon(props: React.ComponentProps<'svg'>) {
  function SidebarTrigger (line 274) | function SidebarTrigger({ className, onClick, ...props }: React.Componen...
  function SidebarRail (line 296) | function SidebarRail({ className, ...props }: React.ComponentProps<'butt...
  function SidebarInset (line 321) | function SidebarInset({ className, ...props }: React.ComponentProps<'mai...
  function SidebarInput (line 335) | function SidebarInput({ className, ...props }: React.ComponentProps<type...
  function SidebarHeader (line 346) | function SidebarHeader({ className, ...props }: React.ComponentProps<'di...
  function SidebarFooter (line 357) | function SidebarFooter({ className, ...props }: React.ComponentProps<'di...
  function SidebarSeparator (line 368) | function SidebarSeparator({ className, ...props }: React.ComponentProps<...
  function SidebarContent (line 379) | function SidebarContent({ className, ...props }: React.ComponentProps<'d...
  function SidebarGroup (line 393) | function SidebarGroup({ className, ...props }: React.ComponentProps<'div...
  function SidebarGroupLabel (line 404) | function SidebarGroupLabel({
  function SidebarGroupAction (line 425) | function SidebarGroupAction({
  function SidebarGroupContent (line 448) | function SidebarGroupContent({ className, ...props }: React.ComponentPro...
  function SidebarMenu (line 459) | function SidebarMenu({ className, ...props }: React.ComponentProps<'ul'>) {
  function SidebarMenuItem (line 470) | function SidebarMenuItem({ className, ...props }: React.ComponentProps<'...
  function SidebarMenuButton (line 503) | function SidebarMenuButton({
  function SidebarMenuAction (line 548) | function SidebarMenuAction({
  function SidebarMenuBadge (line 579) | function SidebarMenuBadge({ className, ...props }: React.ComponentProps<...
  function SidebarMenuSkeleton (line 598) | function SidebarMenuSkeleton({
  function SidebarMenuSub (line 631) | function SidebarMenuSub({ className, ...props }: React.ComponentProps<'u...
  function SidebarMenuSubItem (line 646) | function SidebarMenuSubItem({ className, ...props }: React.ComponentProp...
  function SidebarMenuSubButton (line 657) | function SidebarMenuSubButton({

FILE: components/ui/sileo-toaster.tsx
  function Toaster (line 6) | function Toaster({

FILE: components/ui/skeleton.tsx
  function Skeleton (line 3) | function Skeleton({ className, ...props }: React.ComponentProps<"div">) {

FILE: components/ui/spinner.tsx
  function Spinner (line 5) | function Spinner({ className, ...props }: Omit<React.ComponentProps<'svg...

FILE: components/ui/switch.tsx
  function Switch (line 8) | function Switch({

FILE: components/ui/table.tsx
  function Table (line 7) | function Table({ className, ...props }: React.ComponentProps<"table">) {
  function TableHeader (line 22) | function TableHeader({ className, ...props }: React.ComponentProps<"thea...
  function TableBody (line 32) | function TableBody({ className, ...props }: React.ComponentProps<"tbody"...
  function TableFooter (line 42) | function TableFooter({ className, ...props }: React.ComponentProps<"tfoo...
  function TableRow (line 55) | function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
  function TableHead (line 68) | function TableHead({ className, ...props }: React.ComponentProps<"th">) {
  function TableCell (line 81) | function TableCell({ className, ...props }: React.ComponentProps<"td">) {
  function TableCaption (line 94) | function TableCaption({

FILE: components/ui/tabs.tsx
  function Tabs (line 8) | function Tabs({
  function TabsList (line 21) | function TabsList({
  function TabsTrigger (line 37) | function TabsTrigger({
  function TabsContent (line 53) | function TabsContent({

FILE: components/ui/text-rotate.tsx
  type TextRotateProps (line 32) | interface TextRotateProps {
  type TextRotateRef (line 147) | interface TextRotateRef {
  type WordObject (line 179) | interface WordObject {

FILE: components/ui/textarea.tsx
  function Textarea (line 5) | function Textarea({ className, ...props }: React.ComponentProps<"textare...

FILE: components/ui/tooltip.tsx
  function TooltipProvider (line 8) | function TooltipProvider({
  function Tooltip (line 21) | function Tooltip({
  function TooltipTrigger (line 31) | function TooltipTrigger({
  function TooltipContent (line 37) | function TooltipContent({

FILE: components/ui/transcript-viewer.tsx
  type TranscriptGap (line 32) | type TranscriptGap = Extract<TranscriptSegment, { kind: "gap" }>
  type TranscriptViewerContextValue (line 34) | type TranscriptViewerContextValue = UseTranscriptViewerResult & {
  function useTranscriptViewerContext (line 41) | function useTranscriptViewerContext() {
  type TranscriptViewerProviderProps (line 51) | type TranscriptViewerProviderProps = {
  function TranscriptViewerProvider (line 56) | function TranscriptViewerProvider({
  type AudioType (line 67) | type AudioType =
  type TranscriptViewerContainerProps (line 76) | type TranscriptViewerContainerProps = {
  function TranscriptViewerContainer (line 89) | function TranscriptViewerContainer({
  type TranscriptViewerWordStatus (line 149) | type TranscriptViewerWordStatus = "spoken" | "unspoken" | "current"
  type TranscriptViewerWordProps (line 150) | interface TranscriptViewerWordProps
  function TranscriptViewerWord (line 157) | function TranscriptViewerWord({
  type TranscriptViewerWordsProps (line 183) | interface TranscriptViewerWordsProps extends HTMLAttributes<HTMLDivEleme...
  function TranscriptViewerWords (line 196) | function TranscriptViewerWords({
  function TranscriptViewerAudio (line 292) | function TranscriptViewerAudio({
  type RenderChildren (line 306) | type RenderChildren = (state: { isPlaying: boolean }) => ReactNode
  type TranscriptViewerPlayPauseButtonProps (line 308) | type TranscriptViewerPlayPauseButtonProps = Omit<
  function TranscriptViewerPlayPauseButton (line 315) | function TranscriptViewerPlayPauseButton({
  type TranscriptViewerScrubBarProps (line 352) | type TranscriptViewerScrubBarProps = Omit<
  function TranscriptViewerScrubBar (line 366) | function TranscriptViewerScrubBar({

FILE: components/ui/voice-button.tsx
  type VoiceButtonState (line 10) | type VoiceButtonState =
  type VoiceButtonProps (line 17) | interface VoiceButtonProps

FILE: components/ui/voice-picker.tsx
  function useOrbColors (line 28) | function useOrbColors(): [string, string] {
  function resolveColors (line 53) | function resolveColors(): [string, string] {
  type VoicePickerProps (line 96) | interface VoicePickerProps {
  function VoicePicker (line 106) | function VoicePicker({
  type VoicePickerItemProps (line 176) | interface VoicePickerItemProps {
  function VoicePickerItem (line 182) | function VoicePickerItem({

FILE: components/user-cache-status.tsx
  type UserCacheStatusProps (line 10) | interface UserCacheStatusProps {
  function UserCacheStatus (line 14) | function UserCacheStatus({ className }: UserCacheStatusProps) {

FILE: components/weather-chart.tsx
  type WeatherDataPoint (line 28) | interface WeatherDataPoint {
  type AirPollutionData (line 47) | interface AirPollutionData {
  type DailyForecastSummary (line 64) | interface DailyForecastSummary {
  type OpenMeteo16DayData (line 78) | interface OpenMeteo16DayData {
  type WeatherChartProps (line 90) | interface WeatherChartProps {
  function convertWindSpeed (line 95) | function convertWindSpeed(speed: number): number {
  function getWeatherIconUrl (line 100) | function getWeatherIconUrl(iconCode: string): string {
  function mapWMOCodeToWeather (line 105) | function mapWMOCodeToWeather(code: number): { description: string; icon:...
  function formatTime (line 141) | function formatTime(timestamp: number): string {
  function getAirQualityInfo (line 146) | function getAirQualityInfo(aqi: number): { label: string; colorClass: st...

FILE: components/x-search.tsx
  type Citation (line 53) | interface Citation {
  type Source (line 62) | interface Source {
  type XSearchQueryResult (line 68) | interface XSearchQueryResult {
  type XSearchResponse (line 77) | interface XSearchResponse {
  type XSearchArgs (line 83) | interface XSearchArgs {
  type NormalizedXSearchArgs (line 94) | interface NormalizedXSearchArgs {
  type XSearchProps (line 99) | interface XSearchProps {
  function extractTweetId (line 105) | function extractTweetId(url?: string | null) {

FILE: components/xql-pro-upgrade-screen.tsx
  constant FEATURES (line 7) | const FEATURES = [
  function XQLProUpgradeScreen (line 13) | function XQLProUpgradeScreen() {

FILE: components/youtube-search-results.tsx
  type TranscriptChunk (line 13) | interface TranscriptChunk {
  type VideoDetails (line 95) | interface VideoDetails {
  type VideoStats (line 106) | interface VideoStats {
  type VideoResult (line 113) | interface VideoResult {
  type YouTubeSearchResponse (line 129) | interface YouTubeSearchResponse {
  type YouTubeSearchResultsProps (line 133) | interface YouTubeSearchResultsProps {

FILE: contexts/user-context.tsx
  type UserContextType (line 7) | interface UserContextType {
  type UserProviderProps (line 56) | interface UserProviderProps {
  function UserProvider (line 60) | function UserProvider({ children }: UserProviderProps) {
  function useUser (line 66) | function useUser(): UserContextType {
  function useIsProUser (line 77) | function useIsProUser() {
  function useSubscriptionStatus (line 82) | function useSubscriptionStatus() {

FILE: hooks/use-auto-resume.ts
  type UseAutoResumeParams (line 8) | type UseAutoResumeParams = {
  function useAutoResume (line 15) | function useAutoResume({

FILE: hooks/use-cached-user-data.tsx
  function useCachedUserData (line 10) | function useCachedUserData() {
  function useCachedIsProUser (line 124) | function useCachedIsProUser() {
  function useCachedSubscriptionStatus (line 130) | function useCachedSubscriptionStatus() {

FILE: hooks/use-chat-prefetch.ts
  function useChatPrefetch (line 7) | function useChatPrefetch() {

FILE: hooks/use-github-stars.ts
  type GitHubRepo (line 3) | interface GitHubRepo {
  function useGitHubStars (line 9) | function useGitHubStars() {

FILE: hooks/use-local-storage.tsx
  function getStoredValue (line 4) | function getStoredValue<T>(key: string, defaultValue: T): T {
  function useLocalStorage (line 21) | function useLocalStorage<T>(key: string, defaultValue: T): [T, (value: T...

FILE: hooks/use-location.ts
  type LocationData (line 4) | interface LocationData {
  function fetchLocationOnce (line 14) | async function fetchLocationOnce(): Promise<LocationData> {
  function useLocation (line 41) | function useLocation(): LocationData {

FILE: hooks/use-lookouts.ts
  type LookoutRunStatus (line 15) | type LookoutRunStatus = 'success' | 'error' | 'timeout';
  type LookoutRun (line 17) | interface LookoutRun {
  type Lookout (line 27) | interface Lookout {
  function getLastRunStatus (line 43) | function getLastRunStatus(lookout: Lookout): LookoutRunStatus | null {
  function getLastRunError (line 49) | function getLastRunError(lookout: Lookout): string | null {
  function useLookouts (line 65) | function useLookouts() {
  function useFilteredLookouts (line 433) | function useFilteredLookouts(filter: 'active' | 'archived' | 'all' = 'al...

FILE: hooks/use-media-query.tsx
  function useMediaQuery (line 4) | function useMediaQuery(query: string) {

FILE: hooks/use-mobile.ts
  constant MOBILE_BREAKPOINT (line 3) | const MOBILE_BREAKPOINT = 768
  function useIsMobile (line 5) | function useIsMobile() {

FILE: hooks/use-optimized-scroll.ts
  constant NEAR_BOTTOM_THRESHOLD (line 3) | const NEAR_BOTTOM_THRESHOLD = 80;
  type UseOptimizedScrollOptions (line 5) | interface UseOptimizedScrollOptions {
  function useOptimizedScroll (line 10) | function useOptimizedScroll(

FILE: hooks/use-synced-preferences.tsx
  type PreferenceKey (line 7) | type PreferenceKey =
  type AutoRouterConfig (line 21) | type AutoRouterConfig = {
  type PreferenceValue (line 29) | type PreferenceValue = string | string[] | boolean | AutoRouterConfig | ...
  constant DEBOUNCE_MS (line 31) | const DEBOUNCE_MS = 300;
  constant MIGRATION_KEY_PREFIX (line 32) | const MIGRATION_KEY_PREFIX = 'scira-prefs-migrated-';
  type UserPreferencesRecord (line 34) | interface UserPreferencesRecord {
  function fetchUserPreferences (line 38) | async function fetchUserPreferences(): Promise<UserPreferencesRecord | n...
  function persistUserPreferences (line 51) | async function persistUserPreferences(
  function getStoredValue (line 70) | function getStoredValue<T>(key: string, defaultValue: T): T {
  function hasMigratedPreferences (line 86) | function hasMigratedPreferences(userId: string): boolean {
  function markPreferencesMigrated (line 92) | function markPreferencesMigrated(userId: string): void {
  function collectLocalStoragePreferences (line 98) | function collectLocalStoragePreferences(): Partial<Record<PreferenceKey,...
  function useSyncedPreferences (line 132) | function useSyncedPreferences<T extends PreferenceValue>(

FILE: hooks/use-transcript-viewer.ts
  type ComposeSegmentsOptions (line 13) | type ComposeSegmentsOptions = {
  type BaseSegment (line 17) | type BaseSegment = {
  type TranscriptWord (line 22) | type TranscriptWord = BaseSegment & {
  type GapSegment (line 29) | type GapSegment = BaseSegment & {
  type TranscriptSegment (line 33) | type TranscriptSegment = TranscriptWord | GapSegment
  type ComposeSegmentsResult (line 35) | type ComposeSegmentsResult = {
  type SegmentComposer (line 40) | type SegmentComposer = (
  function composeSegments (line 44) | function composeSegments(
  type UseTranscriptViewerProps (line 137) | type UseTranscriptViewerProps = {
  type UseTranscriptViewerResult (line 148) | type UseTranscriptViewerResult = {
  function useTranscriptViewer (line 169) | function useTranscriptViewer({

FILE: hooks/use-usage-data.ts
  function useUsageData (line 7) | function useUsageData(user: User | null, enabled: boolean = true) {

FILE: hooks/use-user-data.ts
  function useUserData (line 6) | function useUserData() {
  function useIsProUser (line 93) | function useIsProUser() {
  function useSubscriptionStatus (line 99) | function useSubscriptionStatus() {

FILE: hooks/use-voice-client.ts
  type VoiceType (line 5) | type VoiceType = "Ara" | "Rex" | "Sal" | "Eve" | "Leo";
  type AgentState (line 6) | type AgentState = null | "thinking" | "listening" | "talking";
  type VoiceClientOptions (line 8) | interface VoiceClientOptions {
  type ConversationTurn (line 14) | interface ConversationTurn {
  type VoiceStats (line 25) | interface VoiceStats {
  type UseVoiceClientReturn (line 32) | interface UseVoiceClientReturn {
  constant CHUNK_DURATION_MS (line 50) | const CHUNK_DURATION_MS = 100;
  constant DEFAULT_VOICE_INSTRUCTIONS (line 53) | const DEFAULT_VOICE_INSTRUCTIONS = `Your Name is Scira named as [sci-ra]...
  constant VOICE_BACKEND_URL (line 135) | const VOICE_BACKEND_URL =
  type SessionResponse (line 138) | interface SessionResponse {
  function getMicrophoneAccessErrorMessage (line 148) | function getMicrophoneAccessErrorMessage(err: unknown): string | null {
  constant BASE64_CHUNK_BYTES (line 175) | const BASE64_CHUNK_BYTES = 0x2000;
  function int16ToBase64Chunked (line 178) | function int16ToBase64Chunked(int16Array: Int16Array): string {
  function base64PCM16ToFloat32 (line 189) | function base64PCM16ToFloat32(base64: string): Float32Array {
  function useVoiceClient (line 203) | function useVoiceClient(

FILE: hooks/use-window-size.tsx
  type WindowSize (line 5) | interface WindowSize {
  function useWindowSize (line 10) | function useWindowSize(): WindowSize {

FILE: instrumentation.ts
  function register (line 1) | async function register() {

FILE: lib/auth.ts
  function safeParseDate (line 44) | function safeParseDate(value: string | Date | null | undefined): Date | ...
  function parseBooleanFlag (line 51) | function parseBooleanFlag(value: unknown): boolean {
  function handleSubscriptionWebhook (line 73) | async function handleSubscriptionWebhook(payload: any, status: string) {

FILE: lib/better-all.ts
  type BetterAllOptions (line 1) | interface BetterAllOptions {
  function isBetterAllDebugEnabled (line 5) | function isBetterAllDebugEnabled() {
  function getBetterAllOptions (line 13) | function getBetterAllOptions() {

FILE: lib/canvas/registry.tsx
  constant PIE_COLORS (line 875) | const PIE_COLORS = [
  constant CHART_COLORS (line 888) | const CHART_COLORS = [
  function pickChartColor (line 900) | function pickChartColor(seed?: string): string {
  function stripLinks (line 911) | function stripLinks(text: string): string {
  function sanitizeInlineHtml (line 916) | function sanitizeInlineHtml(text: string): string {
  function shouldAngleLabels (line 935) | function shouldAngleLabels(items: Array<Record<string, unknown>>): boole...
  function yAxisWidth (line 942) | function yAxisWidth(items: Array<Record<string, unknown>>, valueKey: str...
  function toNumeric (line 951) | function toNumeric(v: unknown): number {
  function processChartData (line 961) | function processChartData(
  function Fallback (line 1016) | function Fallback({ type }: { type: string }) {

FILE: lib/canvas/renderer.tsx
  type CanvasRendererProps (line 19) | interface CanvasRendererProps {
  function sanitizeSpec (line 29) | function sanitizeSpec(spec: Spec): Spec {
  function CanvasRenderer (line 40) | function CanvasRenderer({

FILE: lib/chat-messages.ts
  function convertToUIMessages (line 6) | function convertToUIMessages(messages: Message[]): ChatMessage[] {
  function convertLegacyToolInvocation (line 31) | function convertLegacyToolInvocation(part: unknown): unknown {
  function convertLegacyReasoningPart (line 75) | function convertLegacyReasoningPart(part: unknown): unknown {

FILE: lib/connectors.tsx
  function getClient (line 6) | function getClient() {
  type ConnectorProvider (line 12) | type ConnectorProvider = 'google-drive' | 'notion' | 'onedrive';
  type ConnectorConfig (line 14) | interface ConnectorConfig {
  constant CONNECTOR_ICONS (line 73) | const CONNECTOR_ICONS: Record<string, (props: SVGProps<SVGSVGElement>) =...
  constant CONNECTOR_CONFIGS (line 79) | const CONNECTOR_CONFIGS: Record<ConnectorProvider, ConnectorConfig> = {
  function getBaseUrl (line 103) | function getBaseUrl() {
  function createConnection (line 110) | async function createConnection(provider: ConnectorProvider, userId: str...
  function createGoogleDriveConnection (line 143) | async function createGoogleDriveConnection(userId: string) {
  function getConnection (line 148) | async function getConnection(provider: ConnectorProvider, userId: string) {
  function listUserConnections (line 178) | async function listUserConnections(userId: string) {
  function deleteConnection (line 229) | async function deleteConnection(connectionId: string) {
  function manualSync (line 243) | async function manualSync(provider: ConnectorProvider, userId: string) {
  function getSyncStatus (line 264) | async function getSyncStatus(provider: ConnectorProvider, userId: string) {
  function getGoogleDriveConnection (line 334) | async function getGoogleDriveConnection(userId: string) {
  function listGoogleDriveConnections (line 338) | async function listGoogleDriveConnections(userId: string) {
  function deleteGoogleDriveConnection (line 343) | async function deleteGoogleDriveConnection(connectionId: string) {
  function manualSyncGoogleDrive (line 347) | async function manualSyncGoogleDrive(userId: string) {

FILE: lib/constants.ts
  constant SEARCH_LIMITS (line 2) | const SEARCH_LIMITS = {
  constant AGENT_MODE_MONTHLY_LIMIT (line 8) | const AGENT_MODE_MONTHLY_LIMIT = 50;
  constant PRICING (line 10) | const PRICING = {
  constant CURRENCIES (line 15) | const CURRENCIES = {
  constant SNAPSHOT_NAME (line 20) | const SNAPSHOT_NAME = 'scira-analysis:1771010549';

FILE: lib/db/chat-queries.ts
  type MessagePage (line 8) | interface MessagePage {
  function getRecentMessagesPage (line 13) | async function getRecentMessagesPage({
  function getChatWithInitialMessages (line 41) | async function getChatWithInitialMessages({
  function getChatWithUserAndInitialMessages (line 92) | async function getChatWithUserAndInitialMessages({
  function getChatsWithInitialMessages (line 146) | async function getChatsWithInitialMessages({
  function getChatVisibilityAndOwnership (line 222) | async function getChatVisibilityAndOwnership({ id, userId }: { id: strin...
  function getAdditionalMessages (line 272) | async function getAdditionalMessages({

FILE: lib/db/queries.ts
  type VisibilityType (line 30) | type VisibilityType = 'public' | 'private';
  type DodoSubscriptionRow (line 31) | type DodoSubscriptionRow = typeof dodosubscription.$inferSelect;
  function getValidDate (line 33) | function getValidDate(value: Date | string | null | undefined): Date | n...
  function isActiveDodoSubscriptionRecord (line 41) | function isActiveDodoSubscriptionRecord(
  function getCachedOrFreshDodoSubscriptions (line 59) | async function getCachedOrFreshDodoSubscriptions(userId: string) {
  function saveChat (line 92) | async function saveChat({
  function deleteChatById (line 115) | async function deleteChatById({ id }: { id: string }) {
  function getChatsByUserId (line 144) | async function getChatsByUserId({
  function getRecentChatsByUserId (line 245) | async function getRecentChatsByUserId({ userId, limit = 8 }: { userId: s...
  function getChatWithUserById (line 315) | async function getChatWithUserById({ id }: { id: string }) {
  function saveMessages (line 339) | async function saveMessages({ messages }: { messages: Array<Message> }) {
  function getMessageById (line 464) | async function getMessageById({ id }: { id: string }) {
  function deleteMessagesByChatIdAfterTimestamp (line 472) | async function deleteMessagesByChatIdAfterTimestamp({ chatId, timestamp ...
  function deleteTrailingMessages (line 482) | async function deleteTrailingMessages({ id }: { id: string }) {
  function updateChatVisibilityById (line 495) | async function updateChatVisibilityById({
  function updateChatTitleById (line 527) | async function updateChatTitleById({ chatId, title }: { chatId: string; ...
  function updateChatPinnedById (line 540) | async function updateChatPinnedById({ chatId, isPinned }: { chatId: stri...
  function getMessageCountByUserId (line 549) | async function getMessageCountByUserId({ id }: { id: string }) {
  function createStreamId (line 557) | async function createStreamId({ streamId, chatId }: { streamId: string; ...
  function saveNewChatWithStream (line 569) | async function saveNewChatWithStream({
  function getLatestStreamIdByChatId (line 624) | async function getLatestStreamIdByChatId({ chatId }: { chatId: string })...
  function getLatestUserMessageIdByChatId (line 643) | async function getLatestUserMessageIdByChatId({ chatId }: { chatId: stri...
  function getExtremeSearchUsageByUserId (line 658) | async function getExtremeSearchUsageByUserId({ userId }: { userId: strin...
  function incrementExtremeSearchUsage (line 687) | async function incrementExtremeSearchUsage({ userId }: { userId: string ...
  function getExtremeSearchCount (line 725) | async function getExtremeSearchCount({ userId }: { userId: string }): Pr...
  function getAnthropicUsageByUserId (line 735) | async function getAnthropicUsageByUserId({ userId }: { userId: string }) {
  function incrementAnthropicUsage (line 765) | async function incrementAnthropicUsage({ userId, model }: { userId: stri...
  function getAnthropicUsageCount (line 807) | async function getAnthropicUsageCount({ userId }: { userId: string }): P...
  function getGoogleUsageByUserId (line 817) | async function getGoogleUsageByUserId({ userId }: { userId: string }) {
  function incrementGoogleUsage (line 844) | async function incrementGoogleUsage({ userId, model }: { userId: string;...
  function getGoogleUsageCount (line 884) | async function getGoogleUsageCount({ userId }: { userId: string }): Prom...
  function getMessageUsageByUserId (line 894) | async function getMessageUsageByUserId({ userId }: { userId: string }) {
  function incrementMessageUsage (line 919) | async function incrementMessageUsage({ userId }: { userId: string }) {
  function getMessageCount (line 960) | async function getMessageCount({ userId }: { userId: string }): Promise<...
  function getMessageCountAndExtremeSearchByUserId (line 974) | async function getMessageCountAndExtremeSearchByUserId({
  function getHistoricalUsageData (line 1009) | async function getHistoricalUsageData({ userId, months = 6 }: { userId: ...
  function getAgentModeRequestCountForCurrentMonth (line 1048) | async function getAgentModeRequestCountForCurrentMonth({ userId }: { use...
  function trackAgentModeUsageEventForMessage (line 1077) | async function trackAgentModeUsageEventForMessage({
  function getCustomInstructionsByUserId (line 1112) | async function getCustomInstructionsByUserId({ userId }: { userId: strin...
  function createCustomInstructions (line 1127) | async function createCustomInstructions({ userId, content }: { userId: s...
  function updateCustomInstructions (line 1143) | async function updateCustomInstructions({ userId, content }: { userId: s...
  function deleteCustomInstructions (line 1160) | async function deleteCustomInstructions({ userId }: { userId: string }) {
  function getUserPreferencesByUserId (line 1174) | async function getUserPreferencesByUserId({ userId }: { userId: string }) {
  function upsertUserPreferences (line 1189) | async function upsertUserPreferences({
  type UserMcpServerInput (line 1262) | interface UserMcpServerInput {
  function createUserMcpServer (line 1283) | async function createUserMcpServer(input: UserMcpServerInput) {
  function getUserMcpServersByUserId (line 1315) | async function getUserMcpServersByUserId({
  function getUserMcpServerById (line 1347) | async function getUserMcpServerById({ id, userId }: { id: string; userId...
  function updateUserMcpServer (line 1360) | async function updateUserMcpServer({
  function deleteUserMcpServer (line 1405) | async function deleteUserMcpServer({ id, userId }: { id: string; userId:...
  function getDodoSubscriptionsByUserId (line 1418) | async function getDodoSubscriptionsByUserId({ userId }: { userId: string...
  function getDodoSubscriptionById (line 1426) | async function getDodoSubscriptionById({ subscriptionId }: { subscriptio...
  function getActiveDodoSubscriptionsByUserId (line 1439) | async function getActiveDodoSubscriptionsByUserId({ userId }: { userId: ...
  function getTotalDodoSubscriptionAmountByUserId (line 1456) | async function getTotalDodoSubscriptionAmountByUserId({ userId }: { user...
  function hasActiveDodoSubscription (line 1466) | async function hasActiveDodoSubscription({ userId }: { userId: string }) {
  function isDodoSubscriptionExpired (line 1491) | async function isDodoSubscriptionExpired({ userId }: { userId: string }) {
  function getDodoSubscriptionExpirationInfo (line 1501) | async function getDodoSubscriptionExpirationInfo({ userId }: { userId: s...
  function createLookout (line 1538) | async function createLookout({
  function updateLookout (line 1611) | async function updateLookout({
  function updateLookoutStatus (line 1651) | async function updateLookoutStatus({
  function updateLookoutLastRun (line 1671) | async function updateLookoutLastRun({
  function getLookoutRunStats (line 1732) | async function getLookoutRunStats({ id }: { id: string }) {
  function deleteLookout (line 1753) | async function deleteLookout({ id }: { id: string }) {
  function createBuildSession (line 1763) | async function createBuildSession({
  function updateBuildSession (line 1792) | async function updateBuildSession({
  function getBuildSessionByChatId (line 1831) | async function getBuildSessionByChatId({ chatId }: { chatId: string }) {
  function getBuildSessionsByUserId (line 1841) | async function getBuildSessionsByUserId({ userId, limit = 20 }: { userId...

FILE: lib/db/schema.ts
  type User (line 647) | type User = InferSelectModel<typeof user>;
  type Session (line 648) | type Session = InferSelectModel<typeof session>;
  type Account (line 649) | type Account = InferSelectModel<typeof account>;
  type Verification (line 650) | type Verification = InferSelectModel<typeof verification>;
  type Chat (line 651) | type Chat = InferSelectModel<typeof chat>;
  type Message (line 652) | type Message = InferSelectModel<typeof message>;
  type Stream (line 653) | type Stream = InferSelectModel<typeof stream>;
  type Subscription (line 654) | type Subscription = InferSelectModel<typeof subscription>;
  type Payment (line 655) | type Payment = InferSelectModel<typeof payment>;
  type DodoSubscription (line 656) | type DodoSubscription = InferSelectModel<typeof dodosubscription>;
  type ExtremeSearchUsage (line 657) | type ExtremeSearchUsage = InferSelectModel<typeof extremeSearchUsage>;
  type MessageUsage (line 658) | type MessageUsage = InferSelectModel<typeof messageUsage>;
  type AnthropicUsage (line 659) | type AnthropicUsage = InferSelectModel<typeof anthropicUsage>;
  type GoogleUsage (line 660) | type GoogleUsage = InferSelectModel<typeof googleUsage>;
  type AgentModeUsageEvents (line 661) | type AgentModeUsageEvents = InferSelectModel<typeof agentModeUsageEvents>;
  type CustomInstructions (line 662) | type CustomInstructions = InferSelectModel<typeof customInstructions>;
  type UserPreferences (line 663) | type UserPreferences = InferSelectModel<typeof userPreferences>;
  type Lookout (line 664) | type Lookout = InferSelectModel<typeof lookout>;
  type UserMcpServer (line 665) | type UserMcpServer = InferSelectModel<typeof userMcpServer>;
  type BuildSession (line 666) | type BuildSession = InferSelectModel<typeof buildSession>;

FILE: lib/discount.ts
  type DiscountConfig (line 3) | interface DiscountConfig {
  function isStudentEmail (line 16) | function isStudentEmail(email: string, studentDomains: string[]): boolean {
  function getDiscountConfig (line 43) | async function getDiscountConfig(userEmail?: string, isIndianUser?: bool...

FILE: lib/email.ts
  type SendLookoutCompletionEmailParams (line 7) | interface SendLookoutCompletionEmailParams {
  function sendLookoutCompletionEmail (line 14) | async function sendLookoutCompletionEmail({

FILE: lib/errors.ts
  type ErrorType (line 1) | type ErrorType =
  type Surface (line 11) | type Surface = 'chat' | 'auth' | 'api' | 'stream' | 'database' | 'histor...
  type ErrorCode (line 13) | type ErrorCode = `${ErrorType}:${Surface}`;
  type ErrorVisibility (line 15) | type ErrorVisibility = 'response' | 'log' | 'none';
  class ChatSDKError (line 27) | class ChatSDKError extends Error {
    method constructor (line 32) | constructor(errorCode: ErrorCode, cause?: string) {
    method toResponse (line 44) | public toResponse() {
  function getMessageByErrorCode (line 67) | function getMessageByErrorCode(errorCode: ErrorCode): string {
  function getStatusCodeByType (line 117) | function getStatusCodeByType(type: ErrorType) {
  function isAuthError (line 141) | function isAuthError(error: ChatSDKError): boolean {
  function isUpgradeRequiredError (line 145) | function isUpgradeRequiredError(error: ChatSDKError): boolean {
  function isModelError (line 149) | function isModelError(error: ChatSDKError): boolean {
  function isSignInRequired (line 153) | function isSignInRequired(error: ChatSDKError): boolean {
  function isProRequired (line 159) | function isProRequired(error: ChatSDKError): boolean {
  function isRateLimited (line 163) | function isRateLimited(error: ChatSDKError): boolean {
  function getErrorActions (line 168) | function getErrorActions(error: ChatSDKError): {
  function getErrorIcon (line 199) | function getErrorIcon(error: ChatSDKError): 'warning' | 'error' | 'upgra...

FILE: lib/mcp/auth-headers.ts
  function resolveMcpAuthHeaders (line 7) | async function resolveMcpAuthHeaders({

FILE: lib/mcp/catalog-icons.ts
  constant MCP_CATALOG_ICONS (line 2) | const MCP_CATALOG_ICONS: Record<string, string> = {
  function getMcpCatalogIcon (line 7) | function getMcpCatalogIcon(serverUrl: string): string | undefined {
  constant MCP_COMPONENT_ICON_URLS (line 12) | const MCP_COMPONENT_ICON_URLS = new Set([

FILE: lib/mcp/crypto.ts
  constant ALGORITHM (line 6) | const ALGORITHM = 'aes-256-gcm';
  constant IV_LENGTH (line 7) | const IV_LENGTH = 12;
  function getEncryptionKey (line 9) | function getEncryptionKey() {
  function encryptMcpCredentials (line 13) | function encryptMcpCredentials(value: string) {
  function decryptMcpCredentials (line 23) | function decryptMcpCredentials(value: string) {

FILE: lib/mcp/managed-credentials.ts
  constant MANAGED_SERVERS (line 6) | const MANAGED_SERVERS: Record<string, { clientIdEnv: string; clientSecre...
  type ManagedServer (line 14) | type ManagedServer = Pick<UserMcpServer,
  function injectManagedOAuthCredentials (line 22) | function injectManagedOAuthCredentials<T extends ManagedServer>(server: ...

FILE: lib/mcp/oauth.ts
  type OAuthEndpointConfig (line 8) | interface OAuthEndpointConfig {
  type OAuthStatePayload (line 17) | interface OAuthStatePayload {
  type OAuthTokenResponse (line 25) | interface OAuthTokenResponse {
  type OAuthServerMetadata (line 40) | interface OAuthServerMetadata {
  type OAuthProtectedResourceMetadata (line 49) | interface OAuthProtectedResourceMetadata {
  constant SLACK_MCP_RESOURCE_HOST (line 54) | const SLACK_MCP_RESOURCE_HOST = 'mcp.slack.com';
  constant SLACK_AUTHORIZATION_ENDPOINT (line 55) | const SLACK_AUTHORIZATION_ENDPOINT = 'https://slack.com/oauth/v2_user/au...
  constant SLACK_TOKEN_ENDPOINT (line 56) | const SLACK_TOKEN_ENDPOINT = 'https://slack.com/api/oauth.v2.user.access';
  constant SLACK_DEFAULT_BOT_SCOPES (line 58) | const SLACK_DEFAULT_BOT_SCOPES = 'search:read.files search:read.public u...
  constant SLACK_DEFAULT_USER_SCOPES (line 59) | const SLACK_DEFAULT_USER_SCOPES = [
  constant OIDC_ONLY_SCOPES (line 78) | const OIDC_ONLY_SCOPES = new Set(['openid', 'offline_access']);
  function stripOidcScopes (line 80) | function stripOidcScopes(scope: string | null): string | null {
  function isGitHubOAuthEndpoint (line 90) | function isGitHubOAuthEndpoint(url: string) {
  function isSlackOAuthEndpoint (line 99) | function isSlackOAuthEndpoint(url: string) {
  function isSlackUserOAuthEndpoint (line 108) | function isSlackUserOAuthEndpoint(url: string) {
  function isVercelOAuthEndpoint (line 117) | function isVercelOAuthEndpoint(url: string) {
  function isCanvaOAuthEndpoint (line 126) | function isCanvaOAuthEndpoint(url: string) {
  function getTrustedAppOrigin (line 135) | function getTrustedAppOrigin(requestOrigin: string) {
  function getConfiguredAppOrigin (line 143) | function getConfiguredAppOrigin() {
  function getOAuthCallbackUri (line 151) | function getOAuthCallbackUri(origin: string) {
  function toBase64Url (line 155) | function toBase64Url(input: Buffer | string) {
  function fromBase64Url (line 160) | function fromBase64Url(value: string) {
  function getStateSigningKey (line 166) | function getStateSigningKey() {
  function createCodeVerifier (line 172) | function createCodeVerifier() {
  function createCodeChallenge (line 176) | function createCodeChallenge(verifier: string) {
  function signStatePayload (line 180) | function signStatePayload(payloadBase64: string) {
  function safeJsonParse (line 184) | function safeJsonParse<T>(value: string): T | null {
  function normalizeOrigin (line 192) | function normalizeOrigin(value: string) {
  function canonicalizeResourceUri (line 196) | function canonicalizeResourceUri(rawUrl: string) {
  function parseChallengeParams (line 206) | function parseChallengeParams(challenge: string) {
  function parseBearerChallenge (line 219) | function parseBearerChallenge(header: string | null) {
  function getProtectedResourceMetadataUrls (line 230) | function getProtectedResourceMetadataUrls(serverUrl: string) {
  function getAuthorizationServerMetadataUrls (line 240) | function getAuthorizationServerMetadataUrls(issuerUrl: string) {
  function fetchJson (line 258) | async function fetchJson<T>(url: string) {
  function discoverProtectedResourceMetadata (line 269) | async function discoverProtectedResourceMetadata(serverUrl: string) {
  function discoverAuthorizationServerMetadata (line 313) | async function discoverAuthorizationServerMetadata(issuerUrl: string) {
  function postTokenRequest (line 340) | async function postTokenRequest(tokenUrl: string, body: URLSearchParams) {
  function resolveOAuthClientId (line 372) | function resolveOAuthClientId({
  function registerDynamicOAuthClient (line 400) | async function registerDynamicOAuthClient({
  function resolveOAuthEndpoints (line 449) | async function resolveOAuthEndpoints(
  function buildMcpOAuthAuthorizationUrl (line 538) | async function buildMcpOAuthAuthorizationUrl({
  function verifyMcpOAuthState (line 677) | function verifyMcpOAuthState({
  function exchangeMcpOAuthCode (line 706) | async function exchangeMcpOAuthCode({
  function resolveMcpOAuthAccessToken (line 772) | async function resolveMcpOAuthAccessToken({

FILE: lib/mcp/server-config.ts
  type McpAuthType (line 6) | type McpAuthType = 'none' | 'bearer' | 'header' | 'oauth';
  type McpTransportType (line 7) | type McpTransportType = 'http' | 'sse';
  type McpCredentialPayload (line 9) | interface McpCredentialPayload {
  type McpOAuthCredentialPayload (line 15) | interface McpOAuthCredentialPayload {
  type McpServerInput (line 21) | interface McpServerInput {
  function validateMcpServerUrl (line 38) | function validateMcpServerUrl(url: string) {
  function getEncryptedMcpCredentials (line 56) | function getEncryptedMcpCredentials(input: McpServerInput) {
  function getMcpCredentialPayload (line 77) | function getMcpCredentialPayload(server: Pick<UserMcpServer, 'authType' ...
  function getMcpAuthHeaders (line 85) | function getMcpAuthHeaders(server: Pick<UserMcpServer, 'authType' | 'enc...
  function getEncryptedOAuthValue (line 99) | function getEncryptedOAuthValue(value: string | undefined) {
  function decryptOAuthValue (line 105) | function decryptOAuthValue(encrypted: string | null | undefined) {
  function normalizeMcpScopes (line 116) | function normalizeMcpScopes(scopes: string | undefined) {
  function validateMcpOAuthConfig (line 126) | function validateMcpOAuthConfig(input: Pick<

FILE: lib/memory-actions.ts
  type MemoryItem (line 13) | interface MemoryItem {
  type MemoryResponse (line 37) | interface MemoryResponse {
  function searchMemories (line 45) | async function searchMemories(query: string, page = 1, pageSize = 20): P...
  function getAllMemories (line 74) | async function getAllMemories(page = 1, pageSize = 20): Promise<MemoryRe...
  function deleteMemory (line 102) | async function deleteMemory(memoryId: string) {

FILE: lib/notte.ts
  constant NOTTE_SCRAPE_URL (line 3) | const NOTTE_SCRAPE_URL = 'https://api.notte.cc/scrape';
  type NotteSessionProfile (line 5) | interface NotteSessionProfile {
  type NotteProxyConfig (line 10) | interface NotteProxyConfig {
  type NotteScrapeRequest (line 15) | interface NotteScrapeRequest {
  type NotteImageData (line 43) | interface NotteImageData {
  type NotteStructuredData (line 49) | interface NotteStructuredData<T = unknown> {
  type NotteScrapeResponse (line 55) | interface NotteScrapeResponse<T = unknown> {
  type NotteClient (line 61) | interface NotteClient {
  class NotteApiError (line 65) | class NotteApiError extends Error {
    method constructor (line 69) | constructor(message: string, status: number, body: string) {
  function getNotteApiKey (line 77) | function getNotteApiKey(providedApiKey?: string) {
  function compactObject (line 83) | function compactObject<T extends Record<string, unknown>>(value: T) {
  function buildScrapePayload (line 89) | function buildScrapePayload(request: NotteScrapeRequest) {
  function createNotteClient (line 119) | function createNotteClient(providedApiKey?: string): NotteClient {
  function scrapeWebpageWithNotte (line 147) | async function scrapeWebpageWithNotte<T = unknown>(

FILE: lib/parser.ts
  constant LINK_PATTERN (line 4) | const LINK_PATTERN = /^\[.*?\]\(.*?\)$/;
  constant BOLD_PATTERN (line 5) | const BOLD_PATTERN = /^\*\*.*?\*\*$/;
  constant ITALIC_PATTERN (line 7) | const ITALIC_PATTERN = /^\*(?!\*).+\*$/;
  constant TABLE_ROW_PATTERN (line 8) | const TABLE_ROW_PATTERN = /^\|.+\|$/;
  constant TABLE_DELIMITER_PATTERN (line 10) | const TABLE_DELIMITER_PATTERN = /^\|\s*:?-{3,}:?\s*(?:\|\s*:?-{3,}:?\s*)...
  constant WHITESPACE_PATTERN (line 11) | const WHITESPACE_PATTERN = /\s/;
  constant RICH_TAGS (line 14) | const RICH_TAGS = ['app_preview', 'download'] as const;
  constant RICH_TAG_OPEN_RE (line 16) | const RICH_TAG_OPEN_RE = new RegExp(`<(${RICH_TAGS.join('|')})>`, 'i');
  class MarkdownJoiner (line 18) | class MarkdownJoiner {
    method processText (line 28) | processText(text: string): string {
    method flushTableLine (line 137) | private flushTableLine(): string {
    method isTableHeaderCandidate (line 167) | private isTableHeaderCandidate(line: string): boolean {
    method isCompleteLink (line 171) | private isCompleteLink(): boolean {
    method isCompleteBold (line 176) | private isCompleteBold(): boolean {
    method isCompleteItalic (line 181) | private isCompleteItalic(): boolean {
    method isFalsePositiveTag (line 186) | private isFalsePositiveTag(char: string): boolean {
    method isFalsePositive (line 193) | private isFalsePositive(char: string): boolean {
    method clearBuffer (line 214) | private clearBuffer(): void {
    method flush (line 219) | flush(): string {
  method transform (line 235) | transform(chunk, controller) {
  method flush (line 248) | flush(controller) {

FILE: lib/performance-cache.ts
  type CacheEntry (line 7) | interface CacheEntry<T> {
  type LRUNode (line 15) | interface LRUNode<T> {
  class PerformanceCache (line 22) | class PerformanceCache<T> {
    method constructor (line 32) | constructor(name: string, maxSize: number = 1000, ttlMs: number = 2 * ...
    method get (line 57) | get(key: string): T | null {
    method set (line 76) | set(key: string, data: T): void {
    method delete (line 112) | delete(key: string): void {
    method clear (line 120) | clear(): void {
    method evictLeastRecentlyUsed (line 127) | private evictLeastRecentlyUsed(): void {
    method addToHead (line 136) | private addToHead(node: LRUNode<T>): void {
    method removeNode (line 151) | private removeNode(node: LRUNode<T>): void {
    method moveToHead (line 166) | private moveToHead(node: LRUNode<T>): void {
    method cleanup (line 172) | private cleanup(): void {
  function extractSessionToken (line 217) | function extractSessionToken(headers: Headers): string | null {
  function getProUserStatus (line 226) | function getProUserStatus(userId: string): boolean | null {
  function setProUserStatus (line 231) | function setProUserStatus(userId: string, isProUser: boolean): void {
  function computeAndCacheProUserStatus (line 236) | function computeAndCacheProUserStatus(userId: string, subscriptionData: ...
  function getDodoSubscriptions (line 244) | function getDodoSubscriptions(userId: string) {
  function setDodoSubscriptions (line 249) | function setDodoSubscriptions(userId: string, subscriptions: any) {
  function getDodoSubscriptionExpiration (line 254) | function getDodoSubscriptionExpiration(userId: string) {
  function setDodoSubscriptionExpiration (line 259) | function setDodoSubscriptionExpiration(userId: string, expirationData: a...
  function getDodoProStatus (line 264) | function getDodoProStatus(userId: string) {
  function setDodoProStatus (line 269) | function setDodoProStatus(userId: string, statusData: any) {
  function invalidateUserCaches (line 275) | function invalidateUserCaches(userId: string) {
  function invalidateAllCaches (line 296) | function invalidateAllCaches() {

FILE: lib/r2.ts
  constant R2_BUCKET_NAME (line 12) | const R2_BUCKET_NAME = process.env.R2_BUCKET_NAME!;
  constant R2_PUBLIC_URL (line 13) | const R2_PUBLIC_URL = process.env.R2_PUBLIC_URL!;

FILE: lib/rate-limit.ts
  function getClientIdentifier (line 13) | function getClientIdentifier(req: Request): string {

FILE: lib/redis.ts
  function getResumableStreamClients (line 6) | function getResumableStreamClients() {

FILE: lib/search-utils.ts
  function extractChatSearchableText (line 7) | function extractChatSearchableText(chat: Chat, messages: Message[]): str...
  function extractChatPreview (line 35) | function extractChatPreview(messages: Message[], maxLength: number = 150...

FILE: lib/search/auto-router.ts
  type AutoRouterRoute (line 9) | interface AutoRouterRoute {
  function routeWithAutoRouter (line 15) | async function routeWithAutoRouter({

FILE: lib/search/chat-title.ts
  function generateTitleFromUserMessage (line 10) | async function generateTitleFromUserMessage({ message }: { message: UIMe...

FILE: lib/search/group-config.ts
  type LegacyGroupId (line 8) | type LegacyGroupId = SearchGroupId | 'buddy';
  function getGroupConfig (line 2431) | async function getGroupConfig(

FILE: lib/search/server-helpers.ts
  function getCurrentUser (line 13) | async function getCurrentUser() {
  function getLightweightUser (line 17) | async function getLightweightUser() {
  function getMessageCountAndExtremeSearchByUserIdAction (line 21) | async function getMessageCountAndExtremeSearchByUserIdAction(userId: str...

FILE: lib/search/tool-loader.ts
  type ExtremeSearchModelId (line 5) | type ExtremeSearchModelId =
  type LoadConfiguredToolsParams (line 14) | interface LoadConfiguredToolsParams {
  function loadConfiguredTools (line 27) | async function loadConfiguredTools({

FILE: lib/subscription.ts
  type SubscriptionDetails (line 21) | type SubscriptionDetails = {
  type SubscriptionDetailsResult (line 35) | type SubscriptionDetailsResult = {
  type DodoSubscriptionRecord (line 42) | interface DodoSubscriptionRecord {
  function toDate (line 50) | function toDate(value: Date | string | null | undefined): Date | null {
  function isDodoSubscriptionWithinPaidPeriod (line 57) | function isDodoSubscriptionWithinPaidPeriod(subscriptionRow: DodoSubscri...
  function isDodoSubscriptionActiveForAccess (line 63) | function isDodoSubscriptionActiveForAccess(subscriptionRow: DodoSubscrip...
  function checkDodoSubscriptionProStatus (line 72) | async function checkDodoSubscriptionProStatus(userId: string): Promise<b...
  function getComprehensiveProStatus (line 123) | async function getComprehensiveProStatus(
  function getSubscriptionDetails (line 169) | async function getSubscriptionDetails(): Promise<SubscriptionDetailsResu...
  function isUserSubscribed (line 292) | async function isUserSubscribed(): Promise<boolean> {
  function isUserProCached (line 312) | async function isUserProCached(): Promise<boolean> {
  function hasAccessToProduct (line 334) | async function hasAccessToProduct(productId: string): Promise<boolean> {
  function getUserSubscriptionStatus (line 342) | async function getUserSubscriptionStatus(): Promise<'active' | 'canceled...
  function getDodoSubscriptionExpirationDate (line 388) | async function getDodoSubscriptionExpirationDate(): Promise<Date | null> {
  function getProStatusWithSource (line 456) | async function getProStatusWithSource(): Promise<{

FILE: lib/tools/academic-search.ts
  function academicSearchTool (line 13) | function academicSearchTool(dataStream?: UIMessageStreamWriter<ChatMessa...

FILE: lib/tools/build-tools.ts
  constant LOG_PREFIX (line 21) | const LOG_PREFIX = '🔨 [Build]';
  constant SUPPORTED_RUNTIMES (line 23) | const SUPPORTED_RUNTIMES: Runtime[] = ['node', 'python', 'golang', 'ruby...
  class BoxManager (line 25) | class BoxManager {
    method constructor (line 34) | constructor(userId: string, existingBoxId?: string | null) {
    method setRuntime (line 41) | setRuntime(runtime: Runtime) {
    method getRuntime (line 49) | getRuntime(): Runtime {
    method getBox (line 53) | async getBox(): Promise<Box> {
    method reconnectBox (line 73) | private async reconnectBox(boxId: string): Promise<Box> {
    method initBox (line 89) | private async initBox(): Promise<Box> {
    method getBoxId (line 130) | getBoxId(): string | null {
    method getMcpServerNames (line 134) | getMcpServerNames(): string[] {
    method hasVercelMcp (line 138) | hasVercelMcp(): boolean {
    method cleanup (line 143) | async cleanup() {
  function createBoxExecTool (line 152) | function createBoxExecTool(dataStream: UIMessageStreamWriter<ChatMessage...
  function createBoxWriteFileTool (line 200) | function createBoxWriteFileTool(dataStream: UIMessageStreamWriter<ChatMe...
  function createBoxDownloadTool (line 245) | function createBoxDownloadTool(dataStream: UIMessageStreamWriter<ChatMes...
  type UploadedFileContext (line 341) | interface UploadedFileContext {
  function createBoxAgentTool (line 347) | function createBoxAgentTool(
  function createBoxCodeTool (line 529) | function createBoxCodeTool(dataStream: UIMessageStreamWriter<ChatMessage...
  function createBrowsePageTool (line 586) | function createBrowsePageTool(dataStream: UIMessageStreamWriter<ChatMess...
  function createBuildWebSearchTool (line 661) | function createBuildWebSearchTool(dataStream: UIMessageStreamWriter<Chat...
  function createBoxInitTool (line 860) | function createBoxInitTool(
  function createBuildTools (line 977) | function createBuildTools(

FILE: lib/tools/connectors-search.ts
  type DocumentChunk (line 9) | interface DocumentChunk {
  type DocumentMetadata (line 15) | interface DocumentMetadata {
  type SupermemoryDocument (line 22) | interface SupermemoryDocument {
  type SupermemorySearchResult (line 32) | interface SupermemorySearchResult {
  type EnhancedDocument (line 37) | interface EnhancedDocument {
  type SearchSuccessResponse (line 57) | interface SearchSuccessResponse {
  type SearchErrorResponse (line 65) | interface SearchErrorResponse {
  type SearchResponse (line 71) | type SearchResponse = SearchSuccessResponse | SearchErrorResponse;
  function createConnectorsSearchTool (line 77) | function createConnectorsSearchTool(userId: string, selectedConnectors?:...

FILE: lib/tools/crypto-tools.ts
  method ohlcResponse (line 175) | async ohlcResponse() {
  method coinDataResponse (line 186) | async coinDataResponse() {
  method ohlcData (line 211) | async ohlcData() {
  method coinData (line 214) | async coinData() {

FILE: lib/tools/currency-converter.ts
  type ForexResult (line 18) | type ForexResult = {
  method forwardRateRaw (line 67) | async forwardRateRaw() {
  method reverseRateRaw (line 70) | async reverseRateRaw() {

FILE: lib/tools/extreme-search.ts
  type CitationSource (line 42) | interface CitationSource {
  constant FILE_READERS (line 75) | const FILE_READERS = {
  type SupportedMimeType (line 85) | type SupportedMimeType = keyof typeof FILE_READERS;
  function isSupportedMimeType (line 87) | function isSupportedMimeType(mimeType: string): mimeType is SupportedMim...
  type FileQueryResult (line 91) | interface FileQueryResult {
  type ChartArtifact (line 97) | interface ChartArtifact {
  function createFileRetriever (line 104) | async function createFileRetriever(file: { url: string; contentType: str...
  function buildFileRetrievers (line 124) | async function buildFileRetrievers(files: { url: string; contentType: st...
  function searchFilesForQuery (line 147) | async function searchFilesForQuery(
  type ContentExtractionStrategy (line 222) | interface ContentExtractionStrategy {
  type MetadataSciraResponse (line 226) | interface MetadataSciraResponse {
  function isHttpUrl (line 238) | function isHttpUrl(url: string) {
  function buildMetadataFallbackContent (line 247) | function buildMetadataFallbackContent(params: {
  function getHostnameForUrl (line 263) | function getHostnameForUrl(url: string) {
  function inferTitleFromMarkdown (line 271) | function inferTitleFromMarkdown(markdown: string, fallback: string) {
  function getMetadataFallbackResults (line 281) | async function getMetadataFallbackResults(urls: string[], logPrefix: str...
  class ExaContentStrategy (line 353) | class ExaContentStrategy implements ContentExtractionStrategy {
    method constructor (line 354) | constructor(
    method getContents (line 359) | async getContents(links: string[]): Promise<SearchResult[]> {
  type SearchResult (line 461) | interface SearchResult {
  type Research (line 475) | type Research = {
  type SearchCategory (line 482) | enum SearchCategory {
  type SearchProviderStrategy (line 491) | interface SearchProviderStrategy {
  class ExaSearchStrategy (line 501) | class ExaSearchStrategy implements SearchProviderStrategy {
    method constructor (line 502) | constructor(private exa: Exa) {}
    method search (line 504) | async search(
  type FileContext (line 566) | interface FileContext {
  function extremeSearch (line 572) | async function extremeSearch(
  function extremeSearchTool (line 1926) | function extremeSearchTool(

FILE: lib/tools/file-query-search.ts
  constant FILE_READERS (line 14) | const FILE_READERS = {
  type SupportedMimeType (line 34) | type SupportedMimeType = keyof typeof FILE_READERS;
  function isSupportedMimeType (line 36) | function isSupportedMimeType(mimeType: string): mimeType is SupportedMim...
  type FileContext (line 40) | interface FileContext {
  type FileQueryResult (line 46) | interface FileQueryResult {
  type QuerySearchResult (line 52) | interface QuerySearchResult {
  function createRetriever (line 57) | async function createRetriever(file: FileContext): Promise<BaseRetriever> {
  function buildRetrieversByUrl (line 81) | async function buildRetrieversByUrl(files: FileContext[]) {
  function searchFiles (line 109) | async function searchFiles(
  function createFileQuerySearchTool (line 167) | function createFileQuerySearchTool(files: FileContext[], dataStream?: UI...

FILE: lib/tools/github-search.ts
  function parseCount (line 32) | function parseCount(value: unknown): number | undefined {
  function getGitHubResultUrl (line 46) | function getGitHubResultUrl(result: unknown): string {
  function isGitHubRepoUrl (line 51) | function isGitHubRepoUrl(rawUrl: string): boolean {
  type GitHubResult (line 99) | type GitHubResult = {
  type GitHubSearchQueryResult (line 113) | type GitHubSearchQueryResult = {
  type GitHubSearchResponse (line 118) | type GitHubSearchResponse = {
  function githubSearchTool (line 122) | function githubSearchTool(dataStream?: UIMessageStreamWriter<ChatMessage...

FILE: lib/tools/map-tools.ts
  type GoogleResult (line 7) | interface GoogleResult {

FILE: lib/tools/mcp-client.ts
  constant DEFAULT_MCP_SERVER_LIMIT (line 14) | const DEFAULT_MCP_SERVER_LIMIT = Number.MAX_SAFE_INTEGER;
  constant MCP_TOOL_LOAD_TIMEOUT_MS (line 15) | const MCP_TOOL_LOAD_TIMEOUT_MS = 20000;
  constant ELICITATION_TIMEOUT_MS (line 16) | const ELICITATION_TIMEOUT_MS = 5 * 60 * 1000;
  type ElicitResult (line 21) | type ElicitResult = { action: 'accept' | 'decline' | 'cancel'; content?:...
  constant ELICITATION_RESPONSE_KEY_PREFIX (line 24) | const ELICITATION_RESPONSE_KEY_PREFIX = 'mcp:elicitation:response:';
  constant ELICITATION_PENDING_KEY_PREFIX (line 25) | const ELICITATION_PENDING_KEY_PREFIX = 'mcp:elicitation:pending:';
  function getElicitationResponseKey (line 27) | function getElicitationResponseKey(elicitationId: string) {
  function getElicitationPendingKey (line 31) | function getElicitationPendingKey(elicitationId: string) {
  function getToolUiResourceUri (line 35) | function getToolUiResourceUri(toolDef: any): string | null {
  function withMcpAppBridgeMeta (line 49) | function withMcpAppBridgeMeta({
  function toSafeSlug (line 76) | function toSafeSlug(value: string) {
  function withTimeout (line 84) | async function withTimeout<T>(promise: Promise<T>, timeoutMs: number, me...
  function waitForElicitation (line 99) | function waitForElicitation(elicitationId: string): Promise<ElicitResult> {
  type ResolvedMcpTools (line 137) | interface ResolvedMcpTools {
  function resolveUserMcpTools (line 144) | async function resolveUserMcpTools({

FILE: lib/tools/prediction-search.ts
  type PolymarketOutcome (line 10) | interface PolymarketOutcome {
  type PolymarketMarket (line 16) | interface PolymarketMarket {
  type PolymarketContent (line 28) | interface PolymarketContent {
  type KalshiOutcome (line 41) | interface KalshiOutcome {
  type KalshiMarket (line 49) | interface KalshiMarket {
  type KalshiContent (line 62) | interface KalshiContent {
  type ValyuResult (line 76) | interface ValyuResult {
  type ValyuSearchResponse (line 100) | interface ValyuSearchResponse {
  type PredictionMarket (line 115) | interface PredictionMarket {
  function parsePolymarketResult (line 145) | function parsePolymarketResult(result: ValyuResult): PredictionMarket {
  function parseKalshiResult (line 176) | function parseKalshiResult(result: ValyuResult): PredictionMarket {
  function predictionSearchTool (line 207) | function predictionSearchTool(dataStream?: UIMessageStreamWriter<ChatMes...

FILE: lib/tools/reddit-search.ts
  type ParallelSearchResult (line 10) | interface ParallelSearchResult {
  type ParallelSearchResponse (line 17) | interface ParallelSearchResponse {
  type TimeRange (line 21) | type TimeRange = 'day' | 'week' | 'month' | 'year';
  function getAfterDateFromTimeRange (line 23) | function getAfterDateFromTimeRange(timeRange: TimeRange | undefined): st...
  function getTimeRangeAtIndex (line 40) | function getTimeRangeAtIndex(timeRanges: TimeRange[] | undefined, index:...
  function parallelSearch (line 45) | async function parallelSearch(
  function redditSearchTool (line 61) | function redditSearchTool(dataStream?: UIMessageStreamWriter<ChatMessage...

FILE: lib/tools/retrieve.ts
  type TranscriptSegment (line 15) | interface TranscriptSegment {
  type TranscriptJobResult (line 24) | interface TranscriptJobResult {
  type TranscriptDirectResult (line 32) | interface TranscriptDirectResult {
  type TranscriptJobResponse (line 38) | interface TranscriptJobResponse {
  function detectPlatform (line 43) | function detectPlatform(url: string): 'twitter' | 'youtube' | 'tiktok' |...
  type SupadataAuthor (line 86) | interface SupadataAuthor {
  type SupadataStats (line 93) | interface SupadataStats {
  type SupadataMedia (line 100) | interface SupadataMedia {
  type SupadataMetadata (line 107) | interface SupadataMetadata {
  function buildSupadataTitle (line 123) | function buildSupadataTitle(metadata: SupadataMetadata, transcript: stri...
  function formatSupadataResponse (line 152) | function formatSupadataResponse(metadata: SupadataMetadata, url: string,...
  function retrieveSingleUrl (line 212) | async function retrieveSingleUrl(

FILE: lib/tools/spotify-search.ts
  type SpotifyImage (line 9) | interface SpotifyImage {
  type SpotifyArtist (line 15) | interface SpotifyArtist {
  type SpotifyAlbum (line 25) | interface SpotifyAlbum {
  type SpotifyTrack (line 36) | interface SpotifyTrack {
  type SpotifyPlaylistOwner (line 49) | interface SpotifyPlaylistOwner {
  type SpotifyPlaylist (line 55) | interface SpotifyPlaylist {
  type SpotifySearchResponse (line 66) | interface SpotifySearchResponse {
  function getAccessToken (line 96) | async function getAccessToken(): Promise<string> {
  type SearchType (line 131) | type SearchType = 'track' | 'artist' | 'album' | 'playlist';
  function spotifySearch (line 133) | async function spotifySearch(
  type SpotifyTrackResult (line 175) | interface SpotifyTrackResult {
  type SpotifyArtistResult (line 193) | interface SpotifyArtistResult {
  type SpotifyAlbumResult (line 203) | interface SpotifyAlbumResult {
  type SpotifyPlaylistResult (line 214) | interface SpotifyPlaylistResult {
  type SpotifySearchResult (line 225) | interface SpotifySearchResult {
  function createTrackDocument (line 244) | function createTrackDocument(track: SpotifyTrackResult): string {
  function createArtistDocument (line 249) | function createArtistDocument(artist: SpotifyArtistResult): string {
  function createAlbumDocument (line 256) | function createAlbumDocument(album: SpotifyAlbumResult): string {
  function createPlaylistDocument (line 260) | function createPlaylistDocument(playlist: SpotifyPlaylistResult): string {
  function rerankResults (line 266) | async function rerankResults<T>(
  method rerankedTracks (line 400) | async rerankedTracks() {
  method rerankedArtists (line 403) | async rerankedArtists() {
  method rerankedAlbums (line 406) | async rerankedAlbums() {
  method rerankedPlaylists (line 409) | async rerankedPlaylists() {

FILE: lib/tools/stock-chart.ts
  constant CURRENCY_SYMBOLS (line 11) | const CURRENCY_SYMBOLS = {
  type NewsResult (line 38) | interface NewsResult {
  type NewsGroup (line 47) | interface NewsGroup {
  type ValyuOHLC (line 53) | interface ValyuOHLC {
  type ValyuEarning (line 62) | interface ValyuEarning {
  type ValyuResult (line 71) | interface ValyuResult {
  type ValyuEarningsResult (line 86) | interface ValyuEarningsResult {
  type CompanyStatistics (line 102) | interface CompanyStatistics {
  type BalanceSheetItem (line 179) | interface BalanceSheetItem {
  type IncomeStatementItem (line 248) | interface IncomeStatementItem {
  type CashFlowItem (line 280) | interface CashFlowItem {
  type DividendData (line 319) | interface DividendData {
  type InsiderTransaction (line 324) | interface InsiderTransaction {
  type MarketMover (line 334) | interface MarketMover {
  type SECFiling (line 348) | interface SECFiling {
  type SECFilingPromise (line 371) | interface SECFilingPromise {
  type FinancialPromise (line 377) | interface FinancialPromise {
  type FinancialDataBundle (line 383) | interface FinancialDataBundle {
  function buildSecFilings (line 393) | function buildSecFilings(params: {
  function extractFinancialData (line 429) | function extractFinancialData(params: { allResults: any[]; financialProm...
  function buildNewsResults (line 941) | function buildNewsResults(
  function isValyuOHLCArray (line 1019) | function isValyuOHLCArray(value: unknown): value is ValyuOHLC[] {
  function isValyuEarningsArray (line 1032) | function isValyuEarningsArray(value: unknown): value is ValyuEarning[] {
  function isValyuResult (line 1045) | function isValyuResult(obj: unknown): obj is ValyuResult {
  function isValyuEarningsResult (line 1051) | function isValyuEarningsResult(obj: unknown): obj is ValyuEarningsResult {
  function getTickerFromResult (line 1057) | function getTickerFromResult(r: ValyuResult): string | undefined {
  function getTickerFromEarningsResult (line 1069) | function getTickerFromEarningsResult(r: ValyuEarningsResult): string | u...

FILE: lib/tools/supermemory.ts
  function createMemoryTools (line 5) | function createMemoryTools(userId: string) {
  type SearchMemoryTool (line 11) | type SearchMemoryTool = Tool<
  type AddMemoryTool (line 29) | type AddMemoryTool = Tool<

FILE: lib/tools/text-translate.ts
  type TextTranslateToolInput (line 7) | interface TextTranslateToolInput {
  type TextTranslateToolOutput (line 13) | interface TextTranslateToolOutput {
  type ImageContext (line 18) | interface ImageContext {
  type ToolContext (line 24) | interface ToolContext {
  constant TRANSLATEGEMMA_PROMPT_TEMPLATE (line 28) | const TRANSLATEGEMMA_PROMPT_TEMPLATE = `You are a professional {SOURCE_L...
  constant TRANSLATEGEMMA_IMAGE_PROMPT_TEMPLATE (line 36) | const TRANSLATEGEMMA_IMAGE_PROMPT_TEMPLATE = `Translate the text in this...
  function normalizeLanguageCode (line 38) | function normalizeLanguageCode(languageCode: string): string {
  function getLanguageName (line 44) | function getLanguageName(languageCode: string): string {
  function renderTranslateGemmaPrompt (line 53) | function renderTranslateGemmaPrompt(args: {
  function renderTranslateGemmaImagePrompt (line 67) | function renderTranslateGemmaImagePrompt(args: {
  function detectLanguageCode (line 83) | async function detectLanguageCode(text: string): Promise<string> {

FILE: lib/tools/weather.ts
  method weatherResponse (line 90) | async weatherResponse() {
  method airPollutionResponse (line 93) | async airPollutionResponse() {
  method openMeteoResponse (line 98) | async openMeteoResponse() {
  method weatherData (line 109) | async weatherData() {
  method airPollutionData (line 112) | async airPollutionData() {
  method openMeteoData (line 115) | async openMeteoData() {

FILE: lib/tools/web-search.ts
  function getSearchClients (line 19) | function getSearchClients() {
  type SearchStrategy (line 91) | interface SearchStrategy {
  class ParallelSearchStrategy (line 114) | class ParallelSearchStrategy implements SearchStrategy {
    method constructor (line 115) | constructor(
    method search (line 120) | async search(
  class FirecrawlSearchStrategy (line 287) | class FirecrawlSearchStrategy implements SearchStrategy {
    method constructor (line 288) | constructor(private firecrawl: FirecrawlApp) {}
    method search (line 290) | async search(
  class ExaSearchStrategy (line 443) | class ExaSearchStrategy implements SearchStrategy {
    method constructor (line 444) | constructor(
    method search (line 449) | async search(
  constant WEB_SEARCH_PROVIDERS (line 596) | const WEB_SEARCH_PROVIDERS = ['exa', 'parallel', 'firecrawl'] as const;
  type WebSearchProvider (line 597) | type WebSearchProvider = (typeof WEB_SEARCH_PROVIDERS)[number];
  function webSearchTool (line 623) | function webSearchTool(

FILE: lib/tools/x-search.ts
  type CitationSource (line 10) | interface CitationSource {
  function xSearchTool (line 15) | function xSearchTool(dataStream?: UIMessageStreamWriter<ChatMessage>) {

FILE: lib/tools/youtube-search.ts
  type VideoDetails (line 8) | interface VideoDetails {
  type VideoStats (line 19) | interface VideoStats {
  type VideoResult (line 26) | interface VideoResult {
  type TimeRange (line 42) | type TimeRange = 'day' | 'week' | 'month' | 'year' | 'anytime';
  type SupadataYouTubeChannel (line 44) | interface SupadataYouTubeChannel {
  type SupadataYouTubeVideo (line 51) | interface SupadataYouTubeVideo {
  constant SEARCH_LIMIT (line 65) | const SEARCH_LIMIT = 12;
  constant YOUTUBE_BASE_URL (line 66) | const YOUTUBE_BASE_URL = 'https://www.youtube.com/watch?v=';
  type SearchMode (line 69) | type SearchMode = z.infer<typeof searchModeEnum>;
  type ChannelVideoType (line 70) | type ChannelVideoType = z.infer<typeof channelVideoTypeEnum>;
  function dedupeVideos (line 81) | function dedupeVideos(videos: SupadataYouTubeVideo[]) {
  function extractChaptersFromDescription (line 92) | function extractChaptersFromDescription(description?: string): string[] ...
  function generateChaptersFromTranscriptChunks (line 108) | function generateChaptersFromTranscriptChunks(
  function buildTranscriptArtifacts (line 150) | async function buildTranscriptArtifacts(supadata: Supadata, videoUrl: st...
  function fetchMetadataWithRetry (line 234) | async function fetchMetadataWithRetry(supadata: Supadata, videoUrl: stri...
  function mapTimeRangeToSupadata (line 253) | function mapTimeRangeToSupadata(timeRange: TimeRange) {
  function resolveNumber (line 258) | function resolveNumber(value: unknown): number | undefined {
  function flattenVideoIds (line 269) | function flattenVideoIds(ids?: { videoIds?: string[]; shortIds?: string[...
  function normalizeHandle (line 274) | function normalizeHandle(query: string) {
  function extractPlaylistId (line 278) | function extractPlaylistId(query: string) {
  function resolveChannelIdFromQuery (line 291) | async function resolveChannelIdFromQuery(supadata: Supadata, query: stri...
  function resolvePlaylistIdFromQuery (line 327) | async function resolvePlaylistIdFromQuery(supadata: Supadata, query: str...
  function getVideosForMode (line 356) | async function getVideosForMode({

FILE: lib/types.ts
  type DataPart (line 42) | type DataPart = { type: 'append-message'; message: string };
  type DataQueryCompletionPart (line 43) | type DataQueryCompletionPart = {
  type DataExtremeSearchPart (line 55) | type DataExtremeSearchPart = {
  type MessageMetadata (line 158) | type MessageMetadata = z.infer<typeof messageMetadataSchema>;
  type weatherTool (line 160) | type weatherTool = InferUITool<typeof weatherTool>;
  type academicSearchTool (line 161) | type academicSearchTool = InferUITool<ReturnType<typeof academicSearchTo...
  type codeInterpreterTool (line 162) | type codeInterpreterTool = InferUITool<typeof codeInterpreterTool>;
  type coinDataTool (line 163) | type coinDataTool = InferUITool<typeof coinDataTool>;
  type coinOhlcTool (line 164) | type coinOhlcTool = InferUITool<typeof coinOhlcTool>;
  type currencyConverterTool (line 165) | type currencyConverterTool = InferUITool<typeof currencyConverterTool>;
  type redditSearchTool (line 166) | type redditSearchTool = InferUITool<ReturnType<typeof redditSearchTool>>;
  type githubSearchTool (line 167) | type githubSearchTool = InferUITool<ReturnType<typeof githubSearchTool>>;
  type retrieveTool (line 168) | type retrieveTool = InferUITool<typeof retrieveTool>;
  type trendingMoviesTool (line 169) | type trendingMoviesTool = InferUITool<typeof trendingMoviesTool>;
  type textTranslateTool (line 170) | type textTranslateTool = InferUITool<typeof textTranslateTool>;
  type xSearchTool (line 171) | type xSearchTool = InferUITool<ReturnType<typeof xSearchTool>>;
  type stockChartTool (line 172) | type stockChartTool = InferUITool<typeof stockChartTool>;
  type greetingTool (line 173) | type greetingTool = InferUITool<ReturnType<typeof greetingTool>>;
  type flightTrackerTool (line 174) | type flightTrackerTool = InferUITool<typeof flightTrackerTool>;
  type findPlaceOnMapTool (line 175) | type findPlaceOnMapTool = InferUITool<typeof findPlaceOnMapTool>;
  type nearbyPlacesSearchTool (line 176) | type nearbyPlacesSearchTool = InferUITool<typeof nearbyPlacesSearchTool>;
  type webSearch (line 177) | type webSearch = InferUITool<ReturnType<typeof webSearchTool>>;
  type extremeSearchTool (line 178) | type extremeSearchTool = InferUITool<ReturnType<typeof extremeSearchTool>>;
  type movieTvSearchTool (line 179) | type movieTvSearchTool = InferUITool<typeof movieTvSearchTool>;
  type trendingTvTool (line 180) | type trendingTvTool = InferUITool<typeof trendingTvTool>;
  type youtubeSearchTool (line 181) | type youtubeSearchTool = InferUITool<typeof youtubeSearchTool>;
  type coinDataByContractTool (line 182) | type coinDataByContractTool = InferUITool<typeof coinDataByContractTool>;
  type datetimeTool (line 183) | type datetimeTool = InferUITool<typeof datetimeTool>;
  type createConnectorsSearchTool (line 184) | type createConnectorsSearchTool = InferUITool<ReturnType<typeof createCo...
  type createMemoryTools (line 185) | type createMemoryTools = InferUITool<SearchMemoryTool>;
  type addMemoryTools (line 186) | type addMemoryTools = InferUITool<AddMemoryTool>;
  type codeContextTool (line 187) | type codeContextTool = InferUITool<typeof codeContextTool>;
  type fileQuerySearchTool (line 188) | type fileQuerySearchTool = InferUITool<ReturnType<typeof createFileQuery...
  type spotifySearchTool (line 189) | type spotifySearchTool = InferUITool<typeof spotifySearchTool>;
  type predictionSearchTool (line 190) | type predictionSearchTool = InferUITool<ReturnType<typeof predictionSear...
  type BuildTools (line 192) | type BuildTools = ReturnType<typeof createBuildTools> extends { tools: i...
  type boxInitTool (line 193) | type boxInitTool = InferUITool<BuildTools[keyof BuildTools]>;
  type boxExecTool (line 194) | type boxExecTool = InferUITool<BuildTools[keyof BuildTools]>;
  type boxWriteTool (line 195) | type boxWriteTool = InferUITool<BuildTools[keyof BuildTools]>;
  type boxReadTool (line 196) | type boxReadTool = InferUITool<BuildTools[keyof BuildTools]>;
  type boxListFilesTool (line 197) | type boxListFilesTool = InferUITool<BuildTools[keyof BuildTools]>;
  type boxDownloadTool (line 198) | type boxDownloadTool = InferUITool<BuildTools[keyof BuildTools]>;
  type boxAgentTool (line 199) | type boxAgentTool = InferUITool<BuildTools[keyof BuildTools]>;
  type boxCodeTool (line 200) | type boxCodeTool = InferUITool<BuildTools[keyof BuildTools]>;
  type boxBrowsePageTool (line 201) | type boxBrowsePageTool = InferUITool<BuildTools[keyof BuildTools]>;
  type ChatTools (line 205) | type ChatTools = {
  type AgentStreamEvent (line 264) | type AgentStreamEvent =
  type DataBuildSearchPart (line 269) | type DataBuildSearchPart = {
  type DataPredictionResultsPart (line 362) | type DataPredictionResultsPart = {
  type CustomUIDataTypes (line 403) | type CustomUIDataTypes = {
  type ChatMessage (line 432) | type ChatMessage = UIMessage<MessageMetadata, CustomUIDataTypes, ChatToo...
  type Attachment (line 434) | interface Attachment {

FILE: lib/user-data-server.ts
  function createLightweightAuthSessionKey (line 16) | function createLightweightAuthSessionKey(token: string): string {
  function invalidateSessionCacheForUser (line 20) | function invalidateSessionCacheForUser(userId: string): void {
  function invalidateSessionCacheForToken (line 31) | function invalidateSessionCacheForToken(token: string): void {
  type DodoSubscriptionStatus (line 45) | type DodoSubscriptionStatus = 'active' | 'on_hold' | 'cancelled' | 'expi...
  type PolarSubscriptionStatus (line 46) | type PolarSubscriptionStatus =
  type ProSource (line 54) | type ProSource = 'polar' | 'dodo' | 'none';
  type PlanTier (line 55) | type PlanTier = 'free' | 'pro' | 'max';
  type SubscriptionStatus (line 56) | type SubscriptionStatus = 'active' | 'canceled' | 'expired' | 'none';
  type DodoSubscriptionData (line 59) | interface DodoSubscriptionData {
  type PolarSubscriptionData (line 76) | interface PolarSubscriptionData {
  type DodoExpirationInfo (line 90) | interface DodoExpirationInfo {
  function getActiveDodoSubscriptions (line 98) | function getActiveDodoSubscriptions(subscriptions: DodoSubscriptionData[...
  function getDodoExpirationInfoFromSubscriptions (line 112) | function getDodoExpirationInfoFromSubscriptions(
  type DodoSubscriptionDetails (line 135) | interface DodoSubscriptionDetails {
  type ComprehensiveUserData (line 145) | interface ComprehensiveUserData {
  type LightweightUserAuth (line 164) | interface LightweightUserAuth {
  constant CACHE_TTL_MS (line 171) | const CACHE_TTL_MS = 5 * 60 * 1000;
  constant LIGHTWEIGHT_CACHE_TTL_MS (line 172) | const LIGHTWEIGHT_CACHE_TTL_MS = 2 * 60 * 1000;
  constant USER_DATA_CACHE_MAX (line 173) | const USER_DATA_CACHE_MAX = 2000;
  constant LIGHTWEIGHT_AUTH_CACHE_MAX (line 174) | const LIGHTWEIGHT_AUTH_CACHE_MAX = 3000;
  constant CUSTOM_INSTRUCTIONS_CACHE_MAX (line 175) | const CUSTOM_INSTRUCTIONS_CACHE_MAX = 2000;
  constant USER_PREFERENCES_CACHE_MAX (line 176) | const USER_PREFERENCES_CACHE_MAX = 2000;
  type CacheEntry (line 178) | type CacheEntry<T> = { value: T; expiresAt: number };
  class LruTtlCache (line 180) | class LruTtlCache<T> {
    method constructor (line 184) | constructor(maxSize: number) {
    method get (line 188) | get(key: string): T | undefined {
    method set (line 201) | set(key: string, value: T, ttlMs: number): void {
    method delete (line 212) | delete(key: string): void {
    method clear (line 216) | clear(): void {
  constant CUSTOM_INSTRUCTIONS_CACHE_TTL_MS (line 226) | const CUSTOM_INSTRUCTIONS_CACHE_TTL_MS = 15 * 60 * 1000;
  constant USER_PREFERENCES_CACHE_TTL_MS (line 230) | const USER_PREFERENCES_CACHE_TTL_MS = 15 * 60 * 1000;
  function getCachedUserData (line 232) | function getCachedUserData(userId: string): ComprehensiveUserData | null {
  function setCachedUserData (line 236) | function setCachedUserData(userId: string, data: ComprehensiveUserData):...
  function clearUserDataCache (line 240) | function clearUserDataCache(userId: string): void {
  function clearAllUserDataCache (line 249) | function clearAllUserDataCache(): void {
  function getCachedLightweightAuth (line 256) | function getCachedLightweightAuth(userId: string): LightweightUserAuth |...
  function setCachedLightweightAuth (line 260) | function setCachedLightweightAuth(userId: string, data: LightweightUserA...
  function getCachedCustomInstructionsByUserId (line 268) | async function getCachedCustomInstructionsByUserId(
  function clearCustomInstructionsCache (line 283) | function clearCustomInstructionsCache(userId?: string): void {
  function getCachedUserPreferencesByUserId (line 295) | async function getCachedUserPreferencesByUserId(
  function clearUserPreferencesCache (line 310) | function clearUserPreferencesCache(userId?: string): void {
  method polarQuery (line 372) | async polarQuery() {
  method dodoCheck (line 395) | async dodoCheck() {
  method userWithSubscriptions (line 488) | async userWithSubscriptions() {
  method dodoSubscriptions (line 516) | async dodoSubscriptions() {
  function isUserPro (line 690) | async function isUserPro(): Promise<boolean> {
  function getUserSubscriptionStatus (line 695) | async function getUserSubscriptionStatus(): Promise<'active' | 'canceled...
  function getProSource (line 700) | async function getProSource(): Promise<'polar' | 'dodo' | 'none'> {

FILE: lib/utils.ts
  function cn (line 25) | function cn(...inputs: ClassValue[]) {
  function normalizeError (line 29) | function normalizeError(err: unknown): string {
  type SearchGroupId (line 41) | type SearchGroupId =
  type SearchProvider (line 68) | type SearchProvider = keyof typeof searchProviderInfo;
  function getWebSearchDescription (line 71) | function getWebSearchDescription(provider: SearchProvider = 'exa'): stri...
  function getSearchGroups (line 77) | function getSearchGroups(searchProvider: SearchProvider = 'exa') {
  type SearchGroup (line 221) | type SearchGroup = (typeof searchGroups)[number];

FILE: next.config.ts
  method headers (line 106) | async headers() {
  method redirects (line 142) | async redirects() {

FILE: proxy.ts
  function proxy (line 7) | async function proxy(request: NextRequest) {

FILE: public/audio-capture-processor.js
  class AudioCaptureProcessor (line 4) | class AudioCaptureProcessor extends AudioWorkletProcessor {
    method constructor (line 5) | constructor() {
    method process (line 24) | process(inputs, outputs) {

FILE: public/pcm-processor-worklet.js
  class PCMProcessor (line 5) | class PCMProcessor extends AudioWorkletProcessor {
    method constructor (line 6) | constructor() {
    method process (line 22) | process(inputs) {
Condensed preview — 390 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (5,311K chars).
[
  {
    "path": ".dockerignore",
    "chars": 72,
    "preview": "Dockerfile\n.dockerignore\nnode_modules\nnpm-debug.log\nREADME.md\n.next\n.git"
  },
  {
    "path": ".eslintrc.json",
    "chars": 40,
    "preview": "{\n  \"extends\": \"next/core-web-vitals\"\n}\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 21,
    "preview": "github: zaidmukaddam\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 879,
    "preview": "---\nname: Bug Report\nabout: Report a bug or unexpected behavior\ntitle: '[BUG] '\nlabels: bug\nassignees: ''\n---\n\n## Bug De"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 334,
    "preview": "blank_issues_enabled: true\ncontact_links:\n  - name: Question or Discussion\n    url: https://github.com/zaidmukaddam/scir"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 856,
    "preview": "---\nname: Feature Request\nabout: Suggest an idea or new feature for this project\ntitle: '[FEATURE] '\nlabels: enhancement"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "chars": 1603,
    "preview": "## Description\n<!-- Provide a brief description of the changes in this PR -->\n\n## Type of Change\n<!-- Mark the relevant "
  },
  {
    "path": ".gitignore",
    "chars": 543,
    "preview": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pn"
  },
  {
    "path": ".prettierrc",
    "chars": 126,
    "preview": "{\n  \"semi\": true,\n  \"singleQuote\": true,\n  \"trailingComma\": \"all\",\n  \"printWidth\": 120,\n  \"tabWidth\": 2,\n  \"useTabs\": fa"
  },
  {
    "path": ".vercelignore",
    "chars": 142,
    "preview": ".codex\n.codex\n.cursor\n.opencode\n.claude\n.vscode\nadd_dodo_indexes.sql\nreindex_tables.sql\ncreate_indexes.sql\nsandbox.py\nve"
  },
  {
    "path": ".vscode/settings.json",
    "chars": 55,
    "preview": "{\n  \"typescript.tsdk\": \"node_modules/typescript/lib\"\n}\n"
  },
  {
    "path": "Dockerfile",
    "chars": 1908,
    "preview": "# syntax=docker.io/docker/dockerfile:1\n\n# Base image: Using Node.js 22 with Alpine Linux for a minimal footprint\nFROM no"
  },
  {
    "path": "LICENSE",
    "chars": 34459,
    "preview": "                    GNU AFFERO GENERAL PUBLIC LICENSE\n                       Version 3, 19 November 2007\n\n Copyright (C)"
  },
  {
    "path": "README.md",
    "chars": 12829,
    "preview": "# Scira\n\nResearch at the speed of thought. The agentic research platform that plans, retrieves, and cites — so you can t"
  },
  {
    "path": "ai/models.ts",
    "chars": 69594,
    "preview": "// Pure model data and helper functions — no server SDK imports\ninterface ModelParameters {\n  temperature?: number;\n  to"
  },
  {
    "path": "ai/providers.ts",
    "chars": 18642,
    "preview": "import 'server-only';\nimport { wrapLanguageModel, customProvider, extractReasoningMiddleware, gateway } from 'ai';\n\nimpo"
  },
  {
    "path": "app/(auth)/layout.tsx",
    "chars": 9302,
    "preview": "'use client';\n\nimport Link from 'next/link';\nimport { Carousel, CarouselContent, CarouselItem, type CarouselApi } from '"
  },
  {
    "path": "app/(auth)/sign-in/page.tsx",
    "chars": 402,
    "preview": "import { Suspense } from 'react';\nimport AuthCard from '@/components/auth-card';\n\nfunction SignInContent() {\n  return (\n"
  },
  {
    "path": "app/(auth)/sign-up/page.tsx",
    "chars": 407,
    "preview": "import { Suspense } from 'react';\nimport AuthCard from '@/components/auth-card';\n\nfunction SignUpContent() {\n  return (\n"
  },
  {
    "path": "app/(content)/about/page.tsx",
    "chars": 64907,
    "preview": "'use client';\n\nimport {\n  Brain,\n  Search,\n  ArrowUpRight,\n  ArrowRight,\n  Bot,\n  GraduationCap,\n  Eye,\n  Filter,\n  X,\n "
  },
  {
    "path": "app/(content)/layout.tsx",
    "chars": 175,
    "preview": "import React from 'react';\n\nexport default function ContentLayout({ children }: { children: React.ReactNode }) {\n  retur"
  },
  {
    "path": "app/(content)/privacy-policy/page.tsx",
    "chars": 14192,
    "preview": "import type { Metadata } from 'next';\nimport Link from 'next/link';\nimport { ArrowLeft, Clock, Shield, ArrowUpRight } fr"
  },
  {
    "path": "app/(content)/terms/page.tsx",
    "chars": 18670,
    "preview": "import Link from 'next/link';\nimport { ArrowLeft, Clock, FileText, ArrowUpRight } from 'lucide-react';\nimport { SciraLog"
  },
  {
    "path": "app/(content)/x-wrapped/[username]/page.tsx",
    "chars": 16229,
    "preview": "'use client';\n\nimport { useEffect, useState } from 'react';\nimport { useRouter, useParams } from 'next/navigation';\nimpo"
  },
  {
    "path": "app/(content)/x-wrapped/layout.tsx",
    "chars": 1012,
    "preview": "import type { Metadata } from 'next';\n\nexport const metadata: Metadata = {\n  title: 'X Wrapped 2025 - Your Year on X',\n "
  },
  {
    "path": "app/(content)/x-wrapped/page.tsx",
    "chars": 4281,
    "preview": "'use client';\n\nimport { useState } from 'react';\nimport { useRouter } from 'next/navigation';\nimport { motion } from 'fr"
  },
  {
    "path": "app/(search)/page.tsx",
    "chars": 455,
    "preview": "import dynamic from 'next/dynamic';\nimport React from 'react';\n\nconst ChatInterface = dynamic(() => import('@/components"
  },
  {
    "path": "app/actions.ts",
    "chars": 86911,
    "preview": "// app/actions.ts\n'use server';\n\nimport { geolocation } from '@vercel/functions';\nimport { serverEnv } from '@/env/serve"
  },
  {
    "path": "app/api/auth/[...all]/route.ts",
    "chars": 142,
    "preview": "import { auth } from \"@/lib/auth\";\nimport { toNextJsHandler } from \"better-auth/next-js\";\n\nexport const { POST, GET } = "
  },
  {
    "path": "app/api/clean_images/route.ts",
    "chars": 1879,
    "preview": "import { serverEnv } from '@/env/server';\nimport { ListObjectsV2Command, DeleteObjectsCommand } from '@aws-sdk/client-s3"
  },
  {
    "path": "app/api/export/docx/route.ts",
    "chars": 28632,
    "preview": "import { NextRequest, NextResponse } from 'next/server';\nimport { Lexer } from 'marked';\nimport {\n  Document,\n  Packer,\n"
  },
  {
    "path": "app/api/export/pdf/route.ts",
    "chars": 78150,
    "preview": "import { NextRequest, NextResponse } from 'next/server';\nimport { PDFDocument, StandardFonts, rgb, PDFName, PDFString } "
  },
  {
    "path": "app/api/lookout/route.ts",
    "chars": 40121,
    "preview": "// /app/api/lookout/route.ts\nimport { generateTitleFromUserMessage } from '@/app/actions';\nimport { convertToModelMessag"
  },
  {
    "path": "app/api/mcp/apps/bridge/route.ts",
    "chars": 3478,
    "preview": "import { createMCPClient } from '@ai-sdk/mcp';\nimport { z } from 'zod';\nimport { getCurrentUser } from '@/app/actions';\n"
  },
  {
    "path": "app/api/mcp/apps/resource/read/route.ts",
    "chars": 3710,
    "preview": "import { createMCPClient } from '@ai-sdk/mcp';\nimport { z } from 'zod';\nimport { getCurrentUser } from '@/app/actions';\n"
  },
  {
    "path": "app/api/mcp/elicitation/respond/route.ts",
    "chars": 2066,
    "preview": "import { getCurrentUser } from '@/app/actions';\nimport { ChatSDKError } from '@/lib/errors';\nimport { pendingElicitation"
  },
  {
    "path": "app/api/mcp/oauth/callback/route.ts",
    "chars": 2953,
    "preview": "import { getCurrentUser } from '@/app/actions';\nimport { getUserMcpServerById, updateUserMcpServer } from '@/lib/db/quer"
  },
  {
    "path": "app/api/mcp/oauth/client-metadata/[serverId]/route.ts",
    "chars": 990,
    "preview": "import { NextResponse } from 'next/server';\n\nfunction getAppOrigin(request: Request) {\n  const oauthOrigin = process.env"
  },
  {
    "path": "app/api/mcp/servers/[id]/oauth/callback/route.ts",
    "chars": 2548,
    "preview": "import { getCurrentUser } from '@/app/actions';\nimport { getUserMcpServerById, updateUserMcpServer } from '@/lib/db/quer"
  },
  {
    "path": "app/api/mcp/servers/[id]/oauth/disconnect/route.ts",
    "chars": 1325,
    "preview": "import { getCurrentUser } from '@/app/actions';\nimport { getUserMcpServerById, updateUserMcpServer } from '@/lib/db/quer"
  },
  {
    "path": "app/api/mcp/servers/[id]/oauth/start/route.ts",
    "chars": 2054,
    "preview": "import { getCurrentUser } from '@/app/actions';\nimport { getUserMcpServerById } from '@/lib/db/queries';\nimport { ChatSD"
  },
  {
    "path": "app/api/mcp/servers/[id]/route.ts",
    "chars": 8394,
    "preview": "import { getCurrentUser } from '@/app/actions';\nimport { ChatSDKError } from '@/lib/errors';\nimport {\n  deleteUserMcpSer"
  },
  {
    "path": "app/api/mcp/servers/[id]/tools/route.ts",
    "chars": 1638,
    "preview": "import { createMCPClient } from '@ai-sdk/mcp';\nimport { getCurrentUser } from '@/app/actions';\nimport { getUserMcpServer"
  },
  {
    "path": "app/api/mcp/servers/route.ts",
    "chars": 5150,
    "preview": "import { getCurrentUser } from '@/app/actions';\nimport { ChatSDKError } from '@/lib/errors';\nimport { createUserMcpServe"
  },
  {
    "path": "app/api/mcp/servers/test/route.ts",
    "chars": 5911,
    "preview": "import { createMCPClient } from '@ai-sdk/mcp';\nimport { getCurrentUser } from '@/app/actions';\nimport { ChatSDKError } f"
  },
  {
    "path": "app/api/og/chat/[id]/route.tsx",
    "chars": 8517,
    "preview": "/* eslint-disable @next/next/no-img-element */\nimport { ImageResponse } from 'next/og';\nimport { getChatWithUserById, ge"
  },
  {
    "path": "app/api/og/x-wrapped/route.tsx",
    "chars": 3373,
    "preview": "/* eslint-disable @next/next/no-img-element */\nimport { ImageResponse } from 'next/og';\nimport fs from 'fs';\nimport path"
  },
  {
    "path": "app/api/preferences/route.ts",
    "chars": 1496,
    "preview": "import { getUser } from '@/lib/auth-utils';\nimport { upsertUserPreferences } from '@/lib/db/queries';\nimport { clearUser"
  },
  {
    "path": "app/api/proxy-image/route.ts",
    "chars": 1332,
    "preview": "import { NextRequest, NextResponse } from 'next/server';\n\nexport async function GET(request: NextRequest) {\n  try {\n    "
  },
  {
    "path": "app/api/raycast/route.ts",
    "chars": 5027,
    "preview": "import { webSearchTool } from '@/lib/tools';\nimport { xSearchTool } from '@/lib/tools/x-search';\nimport { convertToModel"
  },
  {
    "path": "app/api/search/[id]/stop/route.ts",
    "chars": 1669,
    "preview": "import { auth } from '@/lib/auth';\nimport { getChatById, getLatestStreamIdByChatId } from '@/lib/db/queries';\nimport { C"
  },
  {
    "path": "app/api/search/[id]/stream/route.ts",
    "chars": 3865,
    "preview": "import { auth } from '@/lib/auth';\nimport { getChatById, getMessagesByChatId, getStreamIdsByChatId } from '@/lib/db/quer"
  },
  {
    "path": "app/api/search/route.ts",
    "chars": 67987,
    "preview": "// /app/api/chat/route.ts\nimport {\n  convertToModelMessages,\n  generateText,\n  Output,\n  streamText,\n  pruneMessages,\n  "
  },
  {
    "path": "app/api/suggest/route.ts",
    "chars": 1415,
    "preview": "export async function GET(request: Request) {\n  const { searchParams } = new URL(request.url);\n  const query = searchPar"
  },
  {
    "path": "app/api/transcribe/route.ts",
    "chars": 862,
    "preview": "import { NextRequest, NextResponse } from 'next/server';\n\nimport { elevenlabs } from '@ai-sdk/elevenlabs';\nimport { expe"
  },
  {
    "path": "app/api/upload/route.ts",
    "chars": 14448,
    "preview": "import { PutObjectCommand, DeleteObjectCommand, ListObjectsV2Command, HeadObjectCommand } from '@aws-sdk/client-s3';\nimp"
  },
  {
    "path": "app/api/x-wrapped/route.ts",
    "chars": 17341,
    "preview": "import { NextRequest, NextResponse } from 'next/server';\nimport { xai } from '@ai-sdk/xai';\nimport { generateText, Outpu"
  },
  {
    "path": "app/api/xql/route.ts",
    "chars": 8462,
    "preview": "import { getCurrentUser } from '@/app/actions';\nimport {\n  convertToModelMessages,\n  streamText,\n  ToolSet,\n  tool,\n  ha"
  },
  {
    "path": "app/apps/layout.tsx",
    "chars": 870,
    "preview": "import React from 'react';\nimport type { Metadata } from 'next';\nimport { SidebarLayout } from '@/components/sidebar-lay"
  },
  {
    "path": "app/apps/page.tsx",
    "chars": 84915,
    "preview": "'use client';\n\nimport { useState, useMemo, Suspense, useEffect } from 'react';\nimport { useRouter, useSearchParams } fro"
  },
  {
    "path": "app/connectors/[provider]/callback/page.tsx",
    "chars": 3760,
    "preview": "'use client';\n\nimport { useEffect, useState } from 'react';\nimport { useRouter, useParams } from 'next/navigation';\nimpo"
  },
  {
    "path": "app/error.tsx",
    "chars": 2081,
    "preview": "'use client';\n\nimport { useEffect } from 'react';\nimport Link from 'next/link';\nimport Image from 'next/image';\nimport {"
  },
  {
    "path": "app/global-error.tsx",
    "chars": 6471,
    "preview": "'use client';\n\nimport { useEffect, useState } from 'react';\nimport Link from 'next/link';\nimport { RefreshCw, Home, Tria"
  },
  {
    "path": "app/globals.css",
    "chars": 51218,
    "preview": "@source \"../node_modules/@cloudflare/kumo/dist/**/*.{js,jsx,ts,tsx}\";\n@import '@cloudflare/kumo/styles/tailwind';\n@impor"
  },
  {
    "path": "app/layout.tsx",
    "chars": 4186,
    "preview": "import './globals.css';\nimport 'katex/dist/katex.min.css';\nimport 'leaflet/dist/leaflet.css';\n\nimport { Metadata, Viewpo"
  },
  {
    "path": "app/lookout/components/action-buttons.tsx",
    "chars": 5574,
    "preview": "'use client';\n\nimport React from 'react';\nimport { HugeiconsIcon } from '@/components/ui/hugeicons';\nimport { PauseIcon,"
  },
  {
    "path": "app/lookout/components/empty-state.tsx",
    "chars": 1791,
    "preview": "'use client';\n\nimport React from 'react';\nimport { HugeiconsIcon } from '@/components/ui/hugeicons';\nimport { Binoculars"
  },
  {
    "path": "app/lookout/components/index.ts",
    "chars": 702,
    "preview": "// Component exports for easier importing\nexport { StatusBadge } from './status-badge';\nexport { LookoutSkeleton, Loadin"
  },
  {
    "path": "app/lookout/components/loading-skeleton.tsx",
    "chars": 1787,
    "preview": "'use client';\n\nimport React from 'react';\nimport { Card, CardContent, CardHeader } from '@/components/ui/card';\nimport {"
  },
  {
    "path": "app/lookout/components/lookout-card.tsx",
    "chars": 5103,
    "preview": "'use client';\n\nimport React from 'react';\nimport Link from 'next/link';\nimport { HugeiconsIcon } from '@/components/ui/h"
  },
  {
    "path": "app/lookout/components/lookout-details-sidebar.tsx",
    "chars": 18262,
    "preview": "'use client';\n\nimport React from 'react';\nimport { format } from 'date-fns';\nimport { HugeiconsIcon } from '@/components"
  },
  {
    "path": "app/lookout/components/lookout-form.tsx",
    "chars": 11238,
    "preview": "'use client';\n\nimport React from 'react';\nimport { format } from 'date-fns';\nimport { HugeiconsIcon } from '@/components"
  },
  {
    "path": "app/lookout/components/pro-upgrade-screen.tsx",
    "chars": 3243,
    "preview": "\"use client\";\n\nimport { useRouter } from \"next/navigation\";\nimport { AlarmClock, Clock, Zap } from \"lucide-react\";\nimpor"
  },
  {
    "path": "app/lookout/components/run-status-badge.tsx",
    "chars": 1158,
    "preview": "'use client';\n\nimport { Badge } from '@/components/ui/badge';\n\nexport type LookoutRunStatus = 'success' | 'error' | 'tim"
  },
  {
    "path": "app/lookout/components/status-badge.tsx",
    "chars": 1829,
    "preview": "'use client';\n\nimport React from 'react';\nimport { HugeiconsIcon } from '@/components/ui/hugeicons';\nimport { Clock01Ico"
  },
  {
    "path": "app/lookout/components/time-picker.tsx",
    "chars": 5632,
    "preview": "'use client';\n\nimport React from 'react';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "
  },
  {
    "path": "app/lookout/components/timezone-selector.tsx",
    "chars": 3481,
    "preview": "'use client';\n\nimport React from 'react';\nimport { HugeiconsIcon } from '@/components/ui/hugeicons';\nimport { CircleArro"
  },
  {
    "path": "app/lookout/components/warning-card.tsx",
    "chars": 1797,
    "preview": "'use client';\n\nimport React from 'react';\nimport { HugeiconsIcon } from '@/components/ui/hugeicons';\nimport { Alert02Ico"
  },
  {
    "path": "app/lookout/constants.ts",
    "chars": 17619,
    "preview": "import {\n  AtomicPowerIcon,\n  GlobalSearchIcon,\n  MicroscopeIcon,\n  YoutubeIcon,\n  RedditIcon,\n  Github01Icon,\n  AppleSt"
  },
  {
    "path": "app/lookout/hooks/use-lookout-form.ts",
    "chars": 9837,
    "preview": "'use client';\n\nimport React from 'react';\nimport { sileo } from 'sileo';\nimport { DEFAULT_FORM_VALUES } from '../constan"
  },
  {
    "path": "app/lookout/layout.tsx",
    "chars": 1549,
    "preview": "import React from 'react';\nimport type { Metadata } from 'next';\nimport { SidebarLayout } from '@/components/sidebar-lay"
  },
  {
    "path": "app/lookout/page.tsx",
    "chars": 31957,
    "preview": "'use client';\n\nimport React from 'react';\nimport { HugeiconsIcon } from '@/components/ui/hugeicons';\nimport { PlusSignIc"
  },
  {
    "path": "app/lookout/utils/time-utils.ts",
    "chars": 2437,
    "preview": "// Helper functions for time conversion and formatting\n\nexport const convertTo12Hour = (hour24: number): number => {\n  i"
  },
  {
    "path": "app/manifest.ts",
    "chars": 1078,
    "preview": "import type { MetadataRoute } from 'next';\n\nexport default function manifest(): MetadataRoute.Manifest {\n  return {\n    "
  },
  {
    "path": "app/new/page.tsx",
    "chars": 106,
    "preview": "import { redirect } from 'next/navigation';\n\nexport default async function NewPage() {\n  redirect('/');\n}\n"
  },
  {
    "path": "app/not-found.tsx",
    "chars": 1613,
    "preview": "'use client';\n\nimport Link from 'next/link';\nimport Image from 'next/image';\nimport { motion } from 'framer-motion';\nimp"
  },
  {
    "path": "app/pricing/_component/pricing-table.tsx",
    "chars": 58845,
    "preview": "'use client';\n\nimport { Button } from '@/components/ui/button';\nimport {\n  AlertDialog,\n  AlertDialogAction,\n  AlertDial"
  },
  {
    "path": "app/pricing/page.tsx",
    "chars": 708,
    "preview": "// Force dynamic rendering to access headers\nexport const dynamic = 'force-dynamic';\n\nimport { getCurrentUser } from '@/"
  },
  {
    "path": "app/providers.tsx",
    "chars": 1712,
    "preview": "'use client';\n\nimport { ThemeProvider } from 'next-themes';\nimport { ReactNode } from 'react';\nimport { QueryClient, Que"
  },
  {
    "path": "app/robots.txt",
    "chars": 22,
    "preview": "User-Agent: *\nAllow: /"
  },
  {
    "path": "app/search/[id]/loading-old.tsx",
    "chars": 9939,
    "preview": "export default function Loading() {\n  return (\n    <div className=\"flex flex-col font-sans items-center min-h-screen bg-"
  },
  {
    "path": "app/search/[id]/page.tsx",
    "chars": 6071,
    "preview": "import { notFound, redirect } from 'next/navigation';\nimport { ChatInterface } from '@/components/chat-interface';\nimpor"
  },
  {
    "path": "app/searches/page.tsx",
    "chars": 2583,
    "preview": "'use client';\n\nimport { useEffect } from 'react';\nimport { useRouter } from 'next/navigation';\nimport { useUser } from '"
  },
  {
    "path": "app/settings/page.tsx",
    "chars": 18694,
    "preview": "'use client';\n\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';\nimport { useUser } from "
  },
  {
    "path": "app/share/[id]/page.tsx",
    "chars": 2568,
    "preview": "import { notFound } from 'next/navigation';\nimport { Metadata } from 'next';\nimport { eq } from 'drizzle-orm';\nimport { "
  },
  {
    "path": "app/success/page.tsx",
    "chars": 9971,
    "preview": "'use client';\n\nimport { Button } from '@/components/ui/button';\nimport { Check, ArrowRight, Loader2, Infinity, Cpu, File"
  },
  {
    "path": "app/voice/components/pro-upgrade-screen.tsx",
    "chars": 4018,
    "preview": "\"use client\";\n\nimport { useRouter } from \"next/navigation\";\nimport { Mic, Globe, Zap } from \"lucide-react\";\nimport { Sci"
  },
  {
    "path": "app/voice/layout.tsx",
    "chars": 948,
    "preview": "import { Metadata } from \"next\";\n\nconst title = \"Scira Voice\";\nconst description = \"Have a voice conversation with Scira"
  },
  {
    "path": "app/voice/page.tsx",
    "chars": 26692,
    "preview": "\"use client\";\n\nimport { useEffect, useState, useCallback, useMemo, useRef } from \"react\";\nimport { motion, AnimatePresen"
  },
  {
    "path": "app/xql/page.tsx",
    "chars": 23476,
    "preview": "'use client';\n\nimport React, { useState, useRef, useCallback } from 'react';\nimport { useChat } from '@ai-sdk/react';\nim"
  },
  {
    "path": "components/InstallPrompt.tsx",
    "chars": 3035,
    "preview": "'use client';\n\nimport { useEffect, useState } from 'react';\nimport { motion, AnimatePresence } from 'motion/react';\nimpo"
  },
  {
    "path": "components/academic-papers.tsx",
    "chars": 14598,
    "preview": "import { Book, ArrowUpRight, ChevronDown } from 'lucide-react';\nimport { Sheet, SheetContent } from '@/components/ui/she"
  },
  {
    "path": "components/ai-elements/web-preview.tsx",
    "chars": 7082,
    "preview": "\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n  Collapsible,\n  CollapsibleContent,\n  Collapsi"
  },
  {
    "path": "components/app-sidebar.tsx",
    "chars": 68648,
    "preview": "'use client';\n\nimport React, { memo, useMemo } from 'react';\nimport Link from 'next/link';\nimport { usePathname, useRout"
  },
  {
    "path": "components/auth-card.tsx",
    "chars": 10617,
    "preview": "'use client';\n\nimport { useState } from 'react';\nimport { parseAsString, useQueryState } from 'nuqs';\nimport { authClien"
  },
  {
    "path": "components/build-search.tsx",
    "chars": 58815,
    "preview": "'use client';\n\nimport { memo, useState, useRef, useEffect, useMemo, type SVGProps } from 'react';\nimport { motion, Anima"
  },
  {
    "path": "components/canvas-renderer.tsx",
    "chars": 912,
    "preview": "\"use client\";\n\nimport React, { memo } from \"react\";\nimport { type Spec } from \"@json-render/react\";\nimport { CanvasRende"
  },
  {
    "path": "components/charts/area-chart.tsx",
    "chars": 10787,
    "preview": "\"use client\";\n\nimport { localPoint } from \"@visx/event\";\nimport { ParentSize } from \"@visx/responsive\";\nimport { scaleLi"
  },
  {
    "path": "components/charts/area.tsx",
    "chars": 9680,
    "preview": "\"use client\";\n\nimport { curveMonotoneX } from \"@visx/curve\";\nimport { AreaClosed, LinePath } from \"@visx/shape\";\n\n// Cur"
  },
  {
    "path": "components/charts/bar-chart.tsx",
    "chars": 16816,
    "preview": "\"use client\";\n\nimport { localPoint } from \"@visx/event\";\nimport { ParentSize } from \"@visx/responsive\";\nimport { scaleBa"
  },
  {
    "path": "components/charts/bar-x-axis.tsx",
    "chars": 3806,
    "preview": "\"use client\";\n\nimport { motion } from \"motion/react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { cn "
  },
  {
    "path": "components/charts/bar-y-axis.tsx",
    "chars": 3430,
    "preview": "\"use client\";\n\nimport { motion } from \"motion/react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { cn "
  },
  {
    "path": "components/charts/bar.tsx",
    "chars": 10804,
    "preview": "\"use client\";\n\nimport { motion } from \"motion/react\";\nimport { useEffect, useId, useMemo, useState } from \"react\";\nimpor"
  },
  {
    "path": "components/charts/chart-context.tsx",
    "chars": 4037,
    "preview": "\"use client\";\n\nimport type { scaleBand, scaleLinear, scaleTime } from \"@visx/scale\";\n\ntype ScaleLinear<Output, _Input = "
  },
  {
    "path": "components/charts/grid.tsx",
    "chars": 4879,
    "preview": "\"use client\";\n\nimport { GridColumns, GridRows } from \"@visx/grid\";\nimport { useId } from \"react\";\nimport { chartCssVars,"
  },
  {
    "path": "components/charts/line-chart.tsx",
    "chars": 10821,
    "preview": "\"use client\";\n\nimport { localPoint } from \"@visx/event\";\nimport { ParentSize } from \"@visx/responsive\";\nimport { scaleLi"
  },
  {
    "path": "components/charts/line.tsx",
    "chars": 6981,
    "preview": "\"use client\";\n\nimport { curveNatural } from \"@visx/curve\";\nimport { LinePath } from \"@visx/shape\";\n\n// CurveFactory type"
  },
  {
    "path": "components/charts/tooltip/chart-tooltip.tsx",
    "chars": 6499,
    "preview": "\"use client\";\n\nimport { motion, useSpring } from \"motion/react\";\nimport { useEffect, useMemo, useState } from \"react\";\ni"
  },
  {
    "path": "components/charts/tooltip/date-ticker.tsx",
    "chars": 3936,
    "preview": "\"use client\";\n\nimport { motion, useSpring } from \"motion/react\";\nimport { useEffect, useMemo, useRef } from \"react\";\n\nco"
  },
  {
    "path": "components/charts/tooltip/index.ts",
    "chars": 484,
    "preview": "export { ChartTooltip, type ChartTooltipProps } from \"./chart-tooltip\";\nexport { DateTicker, type DateTickerProps } from"
  },
  {
    "path": "components/charts/tooltip/tooltip-box.tsx",
    "chars": 4564,
    "preview": "\"use client\";\n\nimport { motion, useSpring } from \"motion/react\";\nimport type { RefObject } from \"react\";\nimport { useEff"
  },
  {
    "path": "components/charts/tooltip/tooltip-content.tsx",
    "chars": 4569,
    "preview": "\"use client\";\n\nimport { AnimatePresence, motion } from \"motion/react\";\nimport { type ReactNode, useEffect, useRef, useSt"
  },
  {
    "path": "components/charts/tooltip/tooltip-dot.tsx",
    "chars": 1084,
    "preview": "\"use client\";\n\nimport { motion, useSpring } from \"motion/react\";\nimport { useEffect } from \"react\";\nimport { chartCssVar"
  },
  {
    "path": "components/charts/tooltip/tooltip-indicator.tsx",
    "chars": 3128,
    "preview": "\"use client\";\n\nimport { motion, useSpring } from \"motion/react\";\nimport { useEffect } from \"react\";\nimport { chartCssVar"
  },
  {
    "path": "components/charts/x-axis.tsx",
    "chars": 3797,
    "preview": "\"use client\";\n\nimport { motion } from \"motion/react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { cn "
  },
  {
    "path": "components/chat-dialogs.tsx",
    "chars": 16933,
    "preview": "import React from 'react';\nimport { Button } from '@/components/ui/button';\nimport { HugeiconsIcon } from '@/components/"
  },
  {
    "path": "components/chat-history-dialog.tsx",
    "chars": 59412,
    "preview": "/* eslint-disable react-hooks/exhaustive-deps */\n'use client';\n\nimport { useEffect, useState, useRef, useCallback, useMe"
  },
  {
    "path": "components/chat-interface.tsx",
    "chars": 81295,
    "preview": "'use client';\n/* eslint-disable @next/next/no-img-element */\n\n// React and React-related imports\nimport React, { memo, u"
  },
  {
    "path": "components/chat-state.ts",
    "chars": 3867,
    "preview": "export interface ChatState {\n  // UI state\n  hasSubmitted: boolean;\n  hasManuallyScrolled: boolean;\n  showUpgradeDialog:"
  },
  {
    "path": "components/chat-text-highlighter.tsx",
    "chars": 5050,
    "preview": "'use client';\n\nimport React, { useCallback, useState, useRef, useEffect } from 'react';\nimport { cn } from '@/lib/utils'"
  },
  {
    "path": "components/client-analytics.tsx",
    "chars": 511,
    "preview": "'use client';\n\nimport React from 'react';\nimport dynamic from 'next/dynamic';\n\n// Defer analytics loading - not critical"
  },
  {
    "path": "components/connectors-search-results.tsx",
    "chars": 16474,
    "preview": "'use client';\n\nimport React from 'react';\nimport {\n  FileText,\n  Image as ImageIcon,\n  ExternalLink,\n  ChevronDown,\n  Ar"
  },
  {
    "path": "components/core/border-trail.tsx",
    "chars": 1235,
    "preview": "'use client';\nimport { cn } from '@/lib/utils';\nimport { motion, Transition } from 'motion/react';\n\ntype BorderTrailProp"
  },
  {
    "path": "components/core/sliding-number.tsx",
    "chars": 3142,
    "preview": "'use client';\nimport { useEffect, useId } from 'react';\nimport { MotionValue, motion, useSpring, useTransform, motionVal"
  },
  {
    "path": "components/core/text-loop.tsx",
    "chars": 1594,
    "preview": "'use client';\nimport { cn } from '@/lib/utils';\nimport { motion, AnimatePresence, Transition, Variants } from 'motion/re"
  },
  {
    "path": "components/core/text-shimmer.tsx",
    "chars": 1644,
    "preview": "'use client';\nimport React, { useMemo } from 'react';\nimport { motion } from 'motion/react';\nimport { cn } from '@/lib/u"
  },
  {
    "path": "components/crypto-charts.tsx",
    "chars": 36083,
    "preview": "/* eslint-disable @next/next/no-img-element */\n'use client';\n\nimport React, { memo, useState } from 'react';\nimport Link"
  },
  {
    "path": "components/crypto-coin-data.tsx",
    "chars": 13615,
    "preview": "/* eslint-disable @next/next/no-img-element */\n'use client';\n\nimport React, { memo, useState } from 'react';\n\nimport { C"
  },
  {
    "path": "components/currency_conv.tsx",
    "chars": 5566,
    "preview": "import { Input } from '@/components/ui/input';\nimport { Button } from '@/components/ui/button';\nimport { Loader2, ArrowU"
  },
  {
    "path": "components/data-stream-provider.tsx",
    "chars": 983,
    "preview": "'use client';\n\nimport React, { createContext, useContext, useMemo, useState } from 'react';\nimport type { DataUIPart } f"
  },
  {
    "path": "components/dialogs/share-dialog.tsx",
    "chars": 11804,
    "preview": "'use client';\n\nimport React, { useState } from 'react';\nimport { GlobeHemisphereWestIcon, LockIcon, CopyIcon, CheckIcon,"
  },
  {
    "path": "components/dialogs/use-share-dialog.tsx",
    "chars": 1482,
    "preview": "'use client';\n\nimport { useState, useCallback } from 'react';\n\ninterface UseShareDialogProps {\n  chatId?: string;\n  curr"
  },
  {
    "path": "components/emails/lookout-completed.tsx",
    "chars": 8508,
    "preview": "import * as React from 'react';\nimport {\n  Html,\n  Head,\n  Preview,\n  Body,\n  Container,\n  Section,\n  Img,\n  Text,\n  But"
  },
  {
    "path": "components/example-categories.tsx",
    "chars": 8387,
    "preview": "'use client';\n\nimport React, { useState, useCallback, memo, useEffect, useRef } from 'react';\nimport { motion, AnimatePr"
  },
  {
    "path": "components/extreme-search.tsx",
    "chars": 157974,
    "preview": "/* eslint-disable @next/next/no-img-element */\n'use client';\n\nimport { Sheet, SheetContent } from '@/components/ui/sheet"
  },
  {
    "path": "components/file-query-search.tsx",
    "chars": 12286,
    "preview": "// /components/file-query-search.tsx\nimport React, { useState, useMemo } from 'react';\nimport { FileText, FileSpreadshee"
  },
  {
    "path": "components/flight-tracker.tsx",
    "chars": 9848,
    "preview": "'use client';\n\nimport { Plane, Clock, AlertCircle } from 'lucide-react';\nimport { useEffect, useState } from 'react';\n\ni"
  },
  {
    "path": "components/github-search.tsx",
    "chars": 18655,
    "preview": "// /components/github-search.tsx\n/* eslint-disable @next/next/no-img-element */\nimport React, { useState } from 'react';"
  },
  {
    "path": "components/haptics-provider.tsx",
    "chars": 3108,
    "preview": "'use client';\n\nimport { useEffect } from 'react';\nimport { useWebHaptics } from 'web-haptics/react';\n\nconst INTERACTIVE_"
  },
  {
    "path": "components/icons/agent-network-icon.tsx",
    "chars": 845,
    "preview": "import type { SVGProps } from 'react';\n\nexport function AgentNetworkIcon(props: SVGProps<SVGSVGElement>) {\n  return (\n  "
  },
  {
    "path": "components/icons/apps-icon.tsx",
    "chars": 1104,
    "preview": "import type { SVGProps } from 'react';\n\nexport function AppsIcon(props: SVGProps<SVGSVGElement>) {\n  return (\n    <svg x"
  },
  {
    "path": "components/icons/mcp-logo.tsx",
    "chars": 1066,
    "preview": "import type { SVGProps } from 'react';\n\nexport function McpLogoIcon(props: SVGProps<SVGSVGElement>) {\n  return (\n    <sv"
  },
  {
    "path": "components/interactive-charts.tsx",
    "chars": 17516,
    "preview": "import React, { useMemo } from 'react';\nimport dynamic from 'next/dynamic';\nimport type { EChartsOption } from 'echarts-"
  },
  {
    "path": "components/interactive-maps.tsx",
    "chars": 17602,
    "preview": "'use client';\n\nimport 'leaflet/dist/leaflet.css';\nimport { cn } from '@/lib/utils';\nimport type * as Leaflet from 'leafl"
  },
  {
    "path": "components/interactive-stock-chart.tsx",
    "chars": 100347,
    "preview": "import React, { useMemo, useCallback, useEffect, useState, startTransition, memo } from 'react';\nimport dynamic from 'ne"
  },
  {
    "path": "components/keyboard-shortcuts-dialog.tsx",
    "chars": 7388,
    "preview": "'use client';\n\nimport { useState } from 'react';\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, Dialog"
  },
  {
    "path": "components/kibo-ui/table/index.tsx",
    "chars": 6454,
    "preview": "import type {\n  Cell,\n  Column,\n  ColumnDef,\n  Header,\n  HeaderGroup,\n  Row,\n  SortingState,\n  Table,\n} from \"@tanstack/"
  },
  {
    "path": "components/list-view.tsx",
    "chars": 4510,
    "preview": "/* eslint-disable @next/next/no-img-element */\nimport React from 'react';\nimport { cn } from '@/lib/utils';\nimport { But"
  },
  {
    "path": "components/logos/elevenlabs-logo.tsx",
    "chars": 735,
    "preview": "export function ElevenLabsLogo() {\n  return (\n    <div className=\"flex items-center justify-center\">\n      {/* Dark logo"
  },
  {
    "path": "components/logos/exa-logo.tsx",
    "chars": 1988,
    "preview": "export function ExaLogo() {\n  return (\n    <svg height=\"20\" viewBox=\"0 0 278 100\" fill=\"none\" xmlns=\"http://www.w3.org/2"
  },
  {
    "path": "components/logos/sarvam-logo.tsx",
    "chars": 23876,
    "preview": "export function SarvamLogo({\n  className,\n  width,\n  height,\n  color = 'currentColor',\n}: {\n  className?: string;\n  widt"
  },
  {
    "path": "components/logos/scira-logo.tsx",
    "chars": 3726,
    "preview": "export function SciraLogo({\n  className,\n  width,\n  height,\n  color = 'currentColor',\n}: {\n  className?: string;\n  width"
  },
  {
    "path": "components/logos/vercel-logo.tsx",
    "chars": 1245,
    "preview": "export function VercelLogo() {\n  return (\n    <svg\n      xmlns=\"http://www.w3.org/2000/svg\"\n      aria-label=\"Vercel log"
  },
  {
    "path": "components/map-components.tsx",
    "chars": 14521,
    "preview": "'use client';\n\nimport 'leaflet/dist/leaflet.css';\nimport React, { useEffect, useRef, useState, memo } from 'react';\nimpo"
  },
  {
    "path": "components/markdown.tsx",
    "chars": 119882,
    "preview": "import 'katex/dist/katex.min.css';\n\nimport { Geist_Mono } from 'next/font/google';\nimport { Prism as SyntaxHighlighter }"
  },
  {
    "path": "components/mcp-elicitation-modal.tsx",
    "chars": 14158,
    "preview": "'use client';\n\nimport { useState, useCallback } from 'react';\nimport { Dialog, DialogContent, DialogHeader, DialogTitle,"
  },
  {
    "path": "components/mcp-server-list.tsx",
    "chars": 9003,
    "preview": "import React from 'react';\nimport { motion } from 'framer-motion';\nimport { Copy, ExternalLink, Server, Database, Networ"
  },
  {
    "path": "components/memory-dialog.tsx",
    "chars": 8301,
    "preview": "'use client';\n\nimport { useState } from 'react';\nimport { useQuery, useMutation, useQueryClient, useInfiniteQuery } from"
  },
  {
    "path": "components/message-parts/index.tsx",
    "chars": 226067,
    "preview": "import React, { memo, useState, useRef, useEffect, useMemo, useCallback } from 'react';\nimport { AppsIcon } from '@/comp"
  },
  {
    "path": "components/message.tsx",
    "chars": 78169,
    "preview": "/* eslint-disable @next/next/no-img-element */\nimport React, { useState, useCallback, useRef, useEffect } from 'react';\n"
  },
  {
    "path": "components/messages.tsx",
    "chars": 18372,
    "preview": "import React, { useMemo, useState, useRef, useEffect, useCallback } from 'react';\nimport { Message } from '@/components/"
  },
  {
    "path": "components/movie-info.tsx",
    "chars": 11380,
    "preview": "/* eslint-disable @next/next/no-img-element */\nimport React, { useState } from 'react';\nimport { motion } from 'framer-m"
  },
  {
    "path": "components/multi-search.tsx",
    "chars": 29474,
    "preview": "// /components/multi-search.tsx\n/* eslint-disable @next/next/no-img-element */\nimport React from 'react';\n\nimport { Butt"
  },
  {
    "path": "components/nearby-search-map-view.tsx",
    "chars": 21229,
    "preview": "/* eslint-disable @next/next/no-img-element */\nimport 'leaflet/dist/leaflet.css';\nimport React, { useState, memo, useCal"
  },
  {
    "path": "components/new-chat-hotkey.tsx",
    "chars": 1296,
    "preview": "'use client';\n\nimport { useEffect } from 'react';\nimport { useRouter } from 'next/navigation';\n\nfunction isEditableTarge"
  },
  {
    "path": "components/onchain-crypto-components.tsx",
    "chars": 6282,
    "preview": "'use client';\n\nimport React from 'react';\nimport { sileo } from 'sileo';\n\n// UI Components\nimport { Card } from '@/compo"
  },
  {
    "path": "components/place-card.tsx",
    "chars": 15466,
    "preview": "/* eslint-disable @next/next/no-img-element */\nimport React, { useState } from 'react';\nimport { DateTime } from 'luxon'"
  },
  {
    "path": "components/placeholder-image.tsx",
    "chars": 3060,
    "preview": "import React from 'react';\nimport { ImageIcon } from 'lucide-react';\nimport { cn } from '@/lib/utils';\n\ninterface Placeh"
  },
  {
    "path": "components/prediction-search.tsx",
    "chars": 17566,
    "preview": "// /components/prediction-search.tsx\n'use client';\n\nimport React, { useState } from 'react';\nimport { Sheet, SheetConten"
  },
  {
    "path": "components/reasoning-part.tsx",
    "chars": 14151,
    "preview": "import React, { useRef, useEffect, ReactNode } from 'react';\nimport { AnimatePresence, motion } from 'framer-motion';\nim"
  },
  {
    "path": "components/reddit-search.tsx",
    "chars": 15849,
    "preview": "// /components/reddit-search.tsx\n/* eslint-disable @next/next/no-img-element */\nimport React, { useState } from 'react';"
  },
  {
    "path": "components/retrieve-results.tsx",
    "chars": 16084,
    "preview": "/* eslint-disable @next/next/no-img-element */\n'use client';\n\nimport React from 'react';\nimport Image from 'next/image';"
  },
  {
    "path": "components/reui/stepper.tsx",
    "chars": 11939,
    "preview": "\"use client\"\n\nimport {\n  Children,\n  createContext,\n  HTMLAttributes,\n  isValidElement,\n  ReactElement,\n  useCallback,\n "
  },
  {
    "path": "components/reui/timeline.tsx",
    "chars": 5658,
    "preview": "\"use client\"\n\nimport {\n  createContext,\n  HTMLAttributes,\n  useCallback,\n  useContext,\n  useState,\n} from \"react\"\nimport"
  },
  {
    "path": "components/scira-logo-header.tsx",
    "chars": 325,
    "preview": "import React from 'react';\nimport { SciraLogo } from './logos/scira-logo';\n\nexport const SciraLogoHeader = () => (\n  <di"
  },
  {
    "path": "components/searches-page.tsx",
    "chars": 35754,
    "preview": "'use client';\n\nimport { useState, useEffect, useCallback, useMemo } from 'react';\nimport { useInfiniteQuery, useQueryCli"
  },
  {
    "path": "components/settings/theme-previews.tsx",
    "chars": 5839,
    "preview": "'use client';\n\nimport { useTheme } from 'next-themes';\nimport { useEffect, useMemo, useState } from 'react';\n\nimport { c"
  },
  {
    "path": "components/settings-dialog.tsx",
    "chars": 165867,
    "preview": "'use client';\n\nimport { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';\nimport { Badge } from '@/co"
  },
  {
    "path": "components/share/index.tsx",
    "chars": 92,
    "preview": "export { ShareDialog } from './share-dialog';\nexport { ShareButton } from './share-button';\n"
  },
  {
    "path": "components/share/share-attachments-badge.tsx",
    "chars": 2053,
    "preview": "import React from 'react';\nimport { FileText, Image as ImageIcon, File } from 'lucide-react';\nimport { cn } from '@/lib/"
  },
  {
    "path": "components/share/share-button.tsx",
    "chars": 4518,
    "preview": "'use client';\n\nimport React, { useState } from 'react';\nimport { GlobeHemisphereWestIcon } from '@phosphor-icons/react';"
  },
  {
    "path": "components/share/share-dialog.tsx",
    "chars": 11378,
    "preview": "'use client';\n\nimport React, { useState, useEffect } from 'react';\nimport {\n  CopyIcon,\n  CheckIcon,\n  GlobeIcon,\n  Lock"
  },
  {
    "path": "components/share-viewer.tsx",
    "chars": 7628,
    "preview": "'use client';\n\nimport React, { useMemo, useState, useTransition } from 'react';\nimport Link from 'next/link';\nimport { u"
  },
  {
    "path": "components/sidebar-layout.tsx",
    "chars": 1501,
    "preview": "'use client';\n\nimport React, { useState, useCallback, useEffect } from 'react';\nimport { SidebarInset } from '@/componen"
  },
  {
    "path": "components/sign-in-prompt-dialog.tsx",
    "chars": 9596,
    "preview": "'use client';\n\nimport { useState } from 'react';\nimport { Button } from '@/components/ui/button';\nimport { Dialog, Dialo"
  },
  {
    "path": "components/spotify-search-results.tsx",
    "chars": 41248,
    "preview": "'use client';\n\nimport React, { useState, useRef, useEffect, useCallback } from 'react';\nimport { cn } from '@/lib/utils'"
  },
  {
    "path": "components/student-domain-request-button.tsx",
    "chars": 7190,
    "preview": "'use client';\n\nimport { useState } from 'react';\nimport { Button } from '@/components/ui/button';\nimport {\n  Dialog,\n  D"
  },
  {
    "path": "components/supported-domains-list.tsx",
    "chars": 7051,
    "preview": "'use client';\n\nimport { useState } from 'react';\nimport { Button } from '@/components/ui/button';\nimport {\n  Dialog,\n  D"
  },
  {
    "path": "components/text-translate.tsx",
    "chars": 14975,
    "preview": "'use client';\n\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { sileo } from '"
  },
  {
    "path": "components/theme-switcher.tsx",
    "chars": 6653,
    "preview": "'use client';\n\nimport { MonitorIcon, SunIcon, MoonStarIcon, ChevronDownIcon } from 'lucide-react';\nimport { motion, Anim"
  }
]

// ... and 190 more files (download for full content)

About this extraction

This page contains the full source code of the zaidmukaddam/scira GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 390 files (4.9 MB), approximately 1.3M tokens, and a symbol index with 2006 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!