├── apps
├── email
│ ├── .gitignore
│ ├── tsconfig.json
│ ├── emails
│ │ └── contact.tsx
│ └── package.json
├── app
│ ├── vitest.config.ts
│ ├── liveblocks.config.ts
│ ├── postcss.config.mjs
│ ├── tailwind.config.ts
│ ├── app
│ │ ├── icon.png
│ │ ├── (organization)
│ │ │ ├── minime
│ │ │ │ ├── analytics
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── page.tsx
│ │ │ │ ├── components
│ │ │ │ │ ├── layout
│ │ │ │ │ │ ├── app-shell.tsx
│ │ │ │ │ │ └── app-header.tsx
│ │ │ │ │ ├── articles
│ │ │ │ │ │ └── no-articles-placeholder.tsx
│ │ │ │ │ ├── projects
│ │ │ │ │ │ └── no-projects-placeholder.tsx
│ │ │ │ │ ├── bookmarks
│ │ │ │ │ │ └── no-bookmarks-placeholder.tsx
│ │ │ │ │ └── domain
│ │ │ │ │ │ └── use-domain-status.tsx
│ │ │ │ └── settings
│ │ │ │ │ └── layout.tsx
│ │ │ ├── tube
│ │ │ │ ├── studio
│ │ │ │ │ ├── [videoId]
│ │ │ │ │ │ ├── edit
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── final_view
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── test.tsx
│ │ │ │ └── automation
│ │ │ │ │ └── page.tsx
│ │ │ ├── chat
│ │ │ │ ├── settings
│ │ │ │ │ ├── data
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── voice
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── common
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── memory
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ └── plugins
│ │ │ │ │ │ └── page.tsx
│ │ │ │ ├── assistants
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── components
│ │ │ │ │ ├── codeblock.module.css
│ │ │ │ │ ├── welcome-message
│ │ │ │ │ │ └── custom-assistant-copy.tsx
│ │ │ │ │ ├── feedback
│ │ │ │ │ │ └── use-feedback.tsx
│ │ │ │ │ ├── settings
│ │ │ │ │ │ ├── models
│ │ │ │ │ │ │ └── api-key-info.tsx
│ │ │ │ │ │ └── setting-card.tsx
│ │ │ │ │ ├── messages
│ │ │ │ │ │ ├── image-message.tsx
│ │ │ │ │ │ ├── index.tsx
│ │ │ │ │ │ └── context-message.tsx
│ │ │ │ │ ├── chat-input
│ │ │ │ │ │ └── image-dropzone-root.tsx
│ │ │ │ │ └── pricing-modal.tsx
│ │ │ │ ├── page.tsx
│ │ │ │ ├── terms
│ │ │ │ │ └── page.tsx
│ │ │ │ └── privacy
│ │ │ │ │ └── page.tsx
│ │ │ ├── voice
│ │ │ │ └── layout.tsx
│ │ │ ├── test
│ │ │ │ ├── Test.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── resume
│ │ │ │ ├── jobs
│ │ │ │ │ └── page.tsx
│ │ │ │ ├── resumes
│ │ │ │ │ └── [id]
│ │ │ │ │ │ └── layout.tsx
│ │ │ │ └── components
│ │ │ │ │ └── resume
│ │ │ │ │ └── editor
│ │ │ │ │ └── shared
│ │ │ │ │ └── LoadingFallback.tsx
│ │ │ ├── settings
│ │ │ │ └── integrations
│ │ │ │ │ └── layout.tsx
│ │ │ ├── artifacts
│ │ │ │ ├── components
│ │ │ │ │ └── v2
│ │ │ │ │ │ └── overview.tsx
│ │ │ │ └── page.tsx
│ │ │ └── (home)
│ │ │ │ └── components
│ │ │ │ └── greeting.tsx
│ │ ├── apple-icon.png
│ │ ├── opengraph-image.png
│ │ ├── .well-known
│ │ │ └── vercel
│ │ │ │ └── flags
│ │ │ │ └── route.ts
│ │ ├── api
│ │ │ ├── prompts
│ │ │ │ └── route.ts
│ │ │ ├── uploadthing
│ │ │ │ └── route.ts
│ │ │ ├── changelogs
│ │ │ │ └── route.ts
│ │ │ ├── assistants
│ │ │ │ └── route.ts
│ │ │ ├── trpc
│ │ │ │ └── [trpc]
│ │ │ │ │ └── route.ts
│ │ │ ├── history
│ │ │ │ └── route.ts
│ │ │ ├── user
│ │ │ │ └── route.ts
│ │ │ ├── bookmarks
│ │ │ │ ├── collections
│ │ │ │ │ └── route.ts
│ │ │ │ ├── export
│ │ │ │ │ └── route.ts
│ │ │ │ └── t
│ │ │ │ │ └── [id]
│ │ │ │ │ └── route.ts
│ │ │ ├── feedback
│ │ │ │ └── route.ts
│ │ │ ├── search
│ │ │ │ └── route.ts
│ │ │ ├── subscribers
│ │ │ │ ├── [id]
│ │ │ │ │ └── route.ts
│ │ │ │ └── export
│ │ │ │ │ └── route.ts
│ │ │ └── auth
│ │ │ │ └── callback
│ │ │ │ └── route.ts
│ │ ├── (unsubscribe)
│ │ │ └── unsubscribe
│ │ │ │ └── action.ts
│ │ ├── (user)
│ │ │ └── user
│ │ │ │ └── [domain]
│ │ │ │ ├── components
│ │ │ │ ├── nothing-placeholder.tsx
│ │ │ │ ├── about.tsx
│ │ │ │ ├── toggle.tsx
│ │ │ │ └── watermark.tsx
│ │ │ │ └── projects
│ │ │ │ └── [slug]
│ │ │ │ └── action.ts
│ │ ├── manifest.ts
│ │ └── not-found.tsx
│ ├── types
│ │ ├── attachment.ts
│ │ ├── prompt.ts
│ │ ├── export.ts
│ │ ├── documents.ts
│ │ ├── prompts.ts
│ │ └── assistants.ts
│ ├── vercel.json
│ ├── public
│ │ ├── icons
│ │ │ ├── logo.png
│ │ │ ├── deepseek-color.png
│ │ │ ├── microsoft.svg
│ │ │ ├── xai.svg
│ │ │ ├── handdrawn_love.svg
│ │ │ ├── wavy.svg
│ │ │ ├── claude.svg
│ │ │ ├── groq.svg
│ │ │ ├── perplexity.svg
│ │ │ └── meta.svg
│ │ ├── images
│ │ │ ├── resume1.png
│ │ │ ├── resume2.png
│ │ │ ├── resume3.png
│ │ │ ├── resume4.png
│ │ │ ├── vineeth.png
│ │ │ ├── os-resume.png
│ │ │ └── signature.png
│ │ └── user-placeholder.svg
│ ├── sentry.client.config.ts
│ ├── services
│ │ ├── premium
│ │ │ └── index.ts
│ │ ├── prompts
│ │ │ └── index.ts
│ │ ├── sessions
│ │ │ └── index.ts
│ │ ├── assistants
│ │ │ └── index.ts
│ │ └── preferences
│ │ │ └── index.ts
│ ├── modules
│ │ └── tube
│ │ │ ├── comments
│ │ │ ├── ui
│ │ │ │ ├── components
│ │ │ │ │ ├── comment-list.tsx
│ │ │ │ │ ├── plan-badge.tsx
│ │ │ │ │ ├── load-more-comments-button.tsx
│ │ │ │ │ ├── comment-date.tsx
│ │ │ │ │ └── checkbox.tsx
│ │ │ │ └── views
│ │ │ │ │ └── comment-view.tsx
│ │ │ └── types.ts
│ │ │ ├── automation
│ │ │ └── ui
│ │ │ │ ├── components
│ │ │ │ └── test-custom-comment-form.tsx
│ │ │ │ └── views
│ │ │ │ └── automation-view.tsx
│ │ │ ├── videos
│ │ │ ├── types.ts
│ │ │ └── ui
│ │ │ │ ├── components
│ │ │ │ └── video-banner.tsx
│ │ │ │ └── views
│ │ │ │ └── video-view.tsx
│ │ │ ├── home
│ │ │ ├── categories
│ │ │ │ └── server
│ │ │ │ │ └── procedures.ts
│ │ │ └── ui
│ │ │ │ └── views
│ │ │ │ └── tube-view.tsx
│ │ │ ├── studio
│ │ │ └── ui
│ │ │ │ └── views
│ │ │ │ ├── video-view.tsx
│ │ │ │ └── studio-view.tsx
│ │ │ └── search
│ │ │ └── ui
│ │ │ └── views
│ │ │ └── search-view.tsx
│ ├── instrumentation.ts
│ ├── config
│ │ ├── constants.ts
│ │ ├── user-page.ts
│ │ ├── prompts.ts
│ │ └── index.ts
│ ├── lib
│ │ ├── mux.ts
│ │ ├── validations
│ │ │ ├── subscribe.ts
│ │ │ ├── article.ts
│ │ │ └── bookmark.ts
│ │ ├── constants
│ │ │ └── index.ts
│ │ ├── editor
│ │ │ └── react-renderer.tsx
│ │ ├── uploadthing.ts
│ │ ├── utils
│ │ │ ├── hotjar.ts
│ │ │ └── error.ts
│ │ ├── sharp.ts
│ │ ├── flags.ts
│ │ └── ai
│ │ │ └── tools
│ │ │ └── get-weather.ts
│ ├── context
│ │ ├── index.ts
│ │ └── react-query.tsx
│ ├── .npmrc
│ ├── artifacts
│ │ └── actions.ts
│ ├── actions
│ │ ├── job
│ │ │ └── schema.ts
│ │ └── categories
│ │ │ └── validation.ts
│ ├── tools
│ │ ├── index.ts
│ │ └── get-weather.ts
│ ├── hooks
│ │ ├── use-modal.tsx
│ │ ├── use-token-counter.tsx
│ │ ├── index.ts
│ │ ├── use-navigation.tsx
│ │ ├── use-app-command.tsx
│ │ ├── use-intersection-observer.ts
│ │ ├── use-mobile.tsx
│ │ ├── use-premium.tsx
│ │ ├── use-copy-to-clipboard.tsx
│ │ └── use-debounced-value.ts
│ ├── components
│ │ ├── client-only.tsx
│ │ └── billing
│ │ │ ├── check-and-redirect-for-upgrade.tsx
│ │ │ └── premium-modal.tsx
│ ├── helper
│ │ ├── preset-prompt-values.ts
│ │ └── tiptap-extensions.ts
│ ├── tsconfig.json
│ ├── store
│ │ ├── sessions
│ │ │ └── store.ts
│ │ └── preferences
│ │ │ └── store.ts
│ ├── trpc
│ │ ├── query-client.ts
│ │ └── server.tsx
│ ├── .gitignore
│ └── middleware.ts
├── web
│ ├── postcss.config.mjs
│ ├── tailwind.config.ts
│ ├── app
│ │ ├── icon.png
│ │ ├── apple-icon.png
│ │ ├── opengraph-image.png
│ │ ├── legal
│ │ │ └── (documents)
│ │ │ │ ├── privacy
│ │ │ │ ├── content.tsx
│ │ │ │ └── page.tsx
│ │ │ │ ├── terms
│ │ │ │ ├── content.tsx
│ │ │ │ └── page.tsx
│ │ │ │ ├── acceptable-use
│ │ │ │ ├── content.tsx
│ │ │ │ └── page.tsx
│ │ │ │ └── layout.tsx
│ │ ├── components
│ │ │ ├── header
│ │ │ │ └── logo.svg
│ │ │ ├── feature-hero
│ │ │ │ └── index.tsx
│ │ │ ├── LegalPage.tsx
│ │ │ └── footer
│ │ │ │ └── footer-link.tsx
│ │ ├── robots.ts
│ │ ├── (home)
│ │ │ └── components
│ │ │ │ └── cta-button.tsx
│ │ ├── styles
│ │ │ └── web.css
│ │ └── not-found.tsx
│ ├── public
│ │ └── home
│ │ │ ├── hero.png
│ │ │ ├── tube.webp
│ │ │ ├── chathub.png
│ │ │ └── watercolor-2.webp
│ ├── vercel.json
│ ├── .well-known
│ │ └── vercel
│ │ │ └── flags
│ │ │ └── route.ts
│ ├── instrumentation.ts
│ ├── mdx-components.tsx
│ ├── lib
│ │ └── features.ts
│ ├── tsconfig.json
│ ├── .gitignore
│ └── env.ts
├── storybook
│ ├── tailwind.config.ts
│ ├── public
│ │ └── favicon.ico
│ ├── next.config.ts
│ ├── postcss.config.mjs
│ ├── tsconfig.json
│ ├── .storybook
│ │ └── preview-head.html
│ ├── .gitignore
│ └── stories
│ │ └── label.stories.tsx
├── api
│ ├── app
│ │ ├── icon.png
│ │ ├── apple-icon.png
│ │ ├── cron
│ │ │ └── keep-alive
│ │ │ │ └── route.ts
│ │ ├── opengraph-image.png
│ │ ├── health
│ │ │ └── route.ts
│ │ └── layout.tsx
│ ├── sentry.client.config.ts
│ ├── instrumentation.ts
│ ├── vercel.json
│ ├── next.config.ts
│ ├── tsconfig.json
│ └── .gitignore
└── docs
│ ├── api-reference
│ └── endpoint
│ │ ├── get.mdx
│ │ ├── create.mdx
│ │ └── delete.mdx
│ ├── images
│ └── checks-passed.png
│ ├── package.json
│ └── snippets
│ └── snippet-intro.mdx
├── packages
├── cms
│ ├── .env.example
│ ├── typescript-config.json
│ ├── components
│ │ ├── feed.tsx
│ │ ├── toolbar.tsx
│ │ ├── body.tsx
│ │ └── image.tsx
│ ├── tsconfig.json
│ ├── next-config.ts
│ ├── keys.ts
│ └── package.json
├── backend
│ ├── .gitignore
│ ├── migrations
│ │ ├── 0016_mean_patriot.sql
│ │ ├── 0008_powerful_warpath.sql
│ │ ├── 0029_deep_the_executioner.sql
│ │ ├── 0021_red_iron_man.sql
│ │ ├── 0001_loving_sunset_bain.sql
│ │ ├── 0009_nervous_giant_girl.sql
│ │ ├── 0020_absurd_pretty_boy.sql
│ │ ├── 0010_puzzling_tarantula.sql
│ │ ├── 0012_flaky_micromacro.sql
│ │ ├── 0011_brown_iron_fist.sql
│ │ ├── 0015_light_jackpot.sql
│ │ ├── 0022_massive_violations.sql
│ │ ├── 0002_tense_darkstar.sql
│ │ ├── 0006_eager_robbie_robertson.sql
│ │ ├── 0007_slippery_jasper_sitwell.sql
│ │ ├── 0014_next_marvel_boy.sql
│ │ ├── 0027_jittery_purifiers.sql
│ │ ├── 0005_mature_night_thrasher.sql
│ │ ├── 0025_simple_cammi.sql
│ │ └── 0026_slippery_secret_warriors.sql
│ ├── auth
│ │ ├── index.ts
│ │ ├── session.ts
│ │ ├── client.ts
│ │ └── format.ts
│ ├── tsconfig.json
│ ├── drizzle.config.ts
│ └── database.ts
├── ai
│ ├── lib
│ │ ├── react.ts
│ │ └── provider.ts
│ ├── index.ts
│ ├── tsconfig.json
│ └── components
│ │ ├── thread.tsx
│ │ └── message.tsx
├── storage
│ ├── index.ts
│ ├── client.ts
│ ├── tsconfig.json
│ ├── keys.ts
│ └── package.json
├── design-system
│ ├── lib
│ │ ├── toast.ts
│ │ ├── fonts.ts
│ │ └── handle-error.ts
│ ├── components
│ │ ├── ui
│ │ │ ├── flex-spacer.tsx
│ │ │ ├── aspect-ratio.tsx
│ │ │ ├── beta-tag.tsx
│ │ │ ├── or-divider.tsx
│ │ │ ├── coming-soon.tsx
│ │ │ ├── skeleton.tsx
│ │ │ ├── collapsible.tsx
│ │ │ ├── placeholder-icon.tsx
│ │ │ ├── full-page-loader.tsx
│ │ │ ├── stagger-container.tsx
│ │ │ ├── loading-dots.tsx
│ │ │ ├── youtube-video.tsx
│ │ │ ├── audio-wave.tsx
│ │ │ └── bot-avatar.tsx
│ │ ├── minime
│ │ │ ├── client-only.tsx
│ │ │ ├── badge.tsx
│ │ │ └── input.tsx
│ │ ├── prose.tsx
│ │ ├── container.tsx
│ │ ├── precomposed
│ │ │ └── skeleton.tsx
│ │ ├── loading.tsx
│ │ ├── top-bar.tsx
│ │ ├── logo.tsx
│ │ └── toast.tsx
│ ├── postcss.config.mjs
│ ├── .npmrc
│ ├── tsconfig.json
│ ├── providers
│ │ └── theme.tsx
│ ├── components.json
│ └── hooks
│ │ └── use-mobile.tsx
├── tinybird
│ ├── .gitignore
│ ├── pipes
│ │ ├── total_cost_pipe.pipe
│ │ ├── cost_per_user_pipe.pipe
│ │ ├── count_per_day_pipe.pipe
│ │ ├── cost_per_model_pipe.pipe
│ │ ├── count_per_hour_pipe.pipe
│ │ ├── count_per_user_pipe.pipe
│ │ ├── count_per_model_pipe.pipe
│ │ ├── osav.pipe
│ │ ├── get_youtube_comment_reply_latest_oldest_mv.pipe
│ │ ├── get_youtube_comment_thread_latest_oldest_mv.pipe
│ │ └── get_last_sync_metadata.pipe
│ ├── tsconfig.json
│ ├── src
│ │ └── client.ts
│ ├── datasources
│ │ ├── youtube_comment_reply_latest_oldest.datasource
│ │ ├── youtube_comment_thread_latest_oldest.datasource
│ │ └── aiCall.datasource
│ └── package.json
├── collaboration
│ ├── hooks.ts
│ ├── tsconfig.json
│ ├── keys.ts
│ └── package.json
├── analytics
│ ├── google.ts
│ ├── vercel.ts
│ ├── tsconfig.json
│ ├── posthog
│ │ └── server.ts
│ ├── index.tsx
│ ├── keys.ts
│ └── package.json
├── webhooks
│ ├── index.ts
│ ├── tsconfig.json
│ ├── keys.ts
│ └── package.json
├── feature-flags
│ ├── index.ts
│ ├── components
│ │ └── toolbar.tsx
│ ├── tsconfig.json
│ ├── lib
│ │ ├── toolbar.ts
│ │ └── create-flag.ts
│ ├── keys.ts
│ ├── access.ts
│ └── package.json
├── email
│ ├── index.ts
│ ├── tsconfig.json
│ ├── keys.ts
│ └── package.json
├── observability
│ ├── log.ts
│ ├── tsconfig.json
│ ├── instrumentation.ts
│ ├── package.json
│ └── error.ts
├── tailwind-config
│ ├── index.ts
│ ├── tsconfig.json
│ └── package.json
├── lib
│ ├── postcss.config.js
│ ├── tsconfig.json
│ ├── src
│ │ ├── fuse.ts
│ │ ├── slugify.ts
│ │ └── format.ts
│ └── package.json
├── mux
│ ├── tsconfig.json
│ ├── keys.ts
│ └── package.json
├── testing
│ ├── tsconfig.json
│ ├── package.json
│ └── index.js
├── youtube
│ ├── tsconfig.json
│ └── package.json
├── payments
│ ├── tsconfig.json
│ ├── index.ts
│ ├── keys.ts
│ ├── ai.ts
│ └── package.json
├── security
│ ├── tsconfig.json
│ ├── keys.ts
│ ├── package.json
│ └── middleware.ts
├── seo
│ ├── tsconfig.json
│ ├── json-ld.tsx
│ └── package.json
├── typescript-config
│ ├── react-library.json
│ ├── package.json
│ ├── nextjs.json
│ └── base.json
├── jobs
│ ├── index.ts
│ ├── tsconfig.json
│ └── trigger.config.ts
├── next-config
│ ├── tsconfig.json
│ └── package.json
└── rate-limit
│ ├── keys.ts
│ └── package.json
├── .husky
└── pre-commit
├── turbo
└── generators
│ ├── package.json
│ └── templates
│ ├── package.json.hbs
│ └── tsconfig.json.hbs
├── pnpm-workspace.yaml
├── .github
├── FUNDING.yml
├── screenshots
│ ├── oschathub.png
│ ├── ostubehero.jpeg
│ ├── oschathubhero.png
│ ├── ostubethumbnail.webp
│ └── oschathubthumbnail.png
├── dependabot.yml
└── ISSUE_TEMPLATE
│ ├── feature_request.md
│ └── bug_report.md
├── .vscode
└── extensions.json
├── .npmrc
├── biome.json
├── turbo.json
└── .gitignore
/apps/email/.gitignore:
--------------------------------------------------------------------------------
1 | .react-email
--------------------------------------------------------------------------------
/packages/cms/.env.example:
--------------------------------------------------------------------------------
1 | BASEHUB_TOKEN=""
--------------------------------------------------------------------------------
/packages/cms/typescript-config.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | turbo run build
--------------------------------------------------------------------------------
/packages/backend/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .env
3 |
--------------------------------------------------------------------------------
/packages/ai/lib/react.ts:
--------------------------------------------------------------------------------
1 | export * from 'ai/react';
2 |
--------------------------------------------------------------------------------
/packages/storage/index.ts:
--------------------------------------------------------------------------------
1 | export * from '@vercel/blob';
2 |
--------------------------------------------------------------------------------
/packages/storage/client.ts:
--------------------------------------------------------------------------------
1 | export * from '@vercel/blob/client';
2 |
--------------------------------------------------------------------------------
/turbo/generators/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "commonjs"
3 | }
4 |
--------------------------------------------------------------------------------
/apps/app/vitest.config.ts:
--------------------------------------------------------------------------------
1 | export { default } from '@repo/testing';
2 |
--------------------------------------------------------------------------------
/packages/design-system/lib/toast.ts:
--------------------------------------------------------------------------------
1 | export { toast } from 'sonner';
2 |
--------------------------------------------------------------------------------
/packages/tinybird/.gitignore:
--------------------------------------------------------------------------------
1 | # tinybird
2 | .tinyb
3 | .venv
4 | .env
5 |
--------------------------------------------------------------------------------
/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | packages:
2 | - "apps/*"
3 | - "packages/*"
4 |
--------------------------------------------------------------------------------
/apps/app/liveblocks.config.ts:
--------------------------------------------------------------------------------
1 | export * from '@repo/collaboration/config';
2 |
--------------------------------------------------------------------------------
/packages/collaboration/hooks.ts:
--------------------------------------------------------------------------------
1 | export * from '@liveblocks/react/suspense';
2 |
--------------------------------------------------------------------------------
/packages/cms/components/feed.tsx:
--------------------------------------------------------------------------------
1 | export { Pump as Feed } from 'basehub/react-pump';
2 |
--------------------------------------------------------------------------------
/packages/cms/components/toolbar.tsx:
--------------------------------------------------------------------------------
1 | export { Toolbar } from 'basehub/next-toolbar';
2 |
--------------------------------------------------------------------------------
/apps/app/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | export { default } from '@repo/design-system/postcss.config.mjs';
2 |
--------------------------------------------------------------------------------
/apps/app/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | export { config as default } from '@repo/tailwind-config/config';
2 |
--------------------------------------------------------------------------------
/apps/web/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | export { default } from '@repo/design-system/postcss.config.mjs';
2 |
--------------------------------------------------------------------------------
/apps/web/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | export { config as default } from '@repo/tailwind-config/config';
2 |
--------------------------------------------------------------------------------
/packages/analytics/google.ts:
--------------------------------------------------------------------------------
1 | export { GoogleAnalytics } from '@next/third-parties/google';
2 |
--------------------------------------------------------------------------------
/packages/cms/components/body.tsx:
--------------------------------------------------------------------------------
1 | export { RichText as Body } from 'basehub/react-rich-text';
2 |
--------------------------------------------------------------------------------
/packages/cms/components/image.tsx:
--------------------------------------------------------------------------------
1 | export { BaseHubImage as Image } from 'basehub/next-image';
2 |
--------------------------------------------------------------------------------
/apps/storybook/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | export { config as default } from '@repo/tailwind-config/config';
2 |
--------------------------------------------------------------------------------
/packages/backend/migrations/0016_mean_patriot.sql:
--------------------------------------------------------------------------------
1 | ALTER TYPE "public"."provider" ADD VALUE 'perplexity';
--------------------------------------------------------------------------------
/apps/api/app/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/apps/api/app/icon.png
--------------------------------------------------------------------------------
/apps/app/app/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/apps/app/app/icon.png
--------------------------------------------------------------------------------
/apps/docs/api-reference/endpoint/get.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Get Plants'
3 | openapi: 'GET /plants'
4 | ---
5 |
--------------------------------------------------------------------------------
/apps/web/app/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/apps/web/app/icon.png
--------------------------------------------------------------------------------
/packages/analytics/vercel.ts:
--------------------------------------------------------------------------------
1 | export { Analytics as VercelAnalytics } from '@vercel/analytics/react';
2 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | custom: ['https://dub.sh/eqyg5Vn']
4 |
--------------------------------------------------------------------------------
/apps/app/types/attachment.ts:
--------------------------------------------------------------------------------
1 | export type TAttachment = {
2 | file?: File;
3 | base64?: string;
4 | };
5 |
--------------------------------------------------------------------------------
/apps/docs/api-reference/endpoint/create.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Create Plant'
3 | openapi: 'POST /plants'
4 | ---
5 |
--------------------------------------------------------------------------------
/packages/backend/migrations/0008_powerful_warpath.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "chat_messages" ADD COLUMN "ai_responses" json;
--------------------------------------------------------------------------------
/packages/backend/migrations/0029_deep_the_executioner.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "videos" ADD COLUMN "thumbnail_url" text;
--------------------------------------------------------------------------------
/apps/app/app/(organization)/minime/analytics/index.tsx:
--------------------------------------------------------------------------------
1 | export type IndexProps = 'visitors' | 'views' | 'clicks';
2 |
--------------------------------------------------------------------------------
/packages/backend/migrations/0021_red_iron_man.sql:
--------------------------------------------------------------------------------
1 | ALTER TYPE "public"."integration_state_platform" ADD VALUE 'TWITTER';
--------------------------------------------------------------------------------
/apps/api/app/apple-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/apps/api/app/apple-icon.png
--------------------------------------------------------------------------------
/apps/app/app/apple-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/apps/app/app/apple-icon.png
--------------------------------------------------------------------------------
/apps/app/types/prompt.ts:
--------------------------------------------------------------------------------
1 | export type TPrompt = {
2 | id: string;
3 | name: string;
4 | content: string;
5 | };
6 |
--------------------------------------------------------------------------------
/apps/app/vercel.json:
--------------------------------------------------------------------------------
1 | {
2 | "git": {
3 | "deploymentEnabled": {
4 | "main": true
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/apps/docs/api-reference/endpoint/delete.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | title: 'Delete Plant'
3 | openapi: 'DELETE /plants/{id}'
4 | ---
5 |
--------------------------------------------------------------------------------
/apps/web/app/apple-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/apps/web/app/apple-icon.png
--------------------------------------------------------------------------------
/apps/web/public/home/hero.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/apps/web/public/home/hero.png
--------------------------------------------------------------------------------
/packages/tinybird/pipes/total_cost_pipe.pipe:
--------------------------------------------------------------------------------
1 | NODE total_cost
2 | SQL >
3 | SELECT sum(cost) AS total_cost FROM aiCall
--------------------------------------------------------------------------------
/apps/api/sentry.client.config.ts:
--------------------------------------------------------------------------------
1 | import { initializeSentry } from '@repo/observability/client';
2 |
3 | initializeSentry();
4 |
--------------------------------------------------------------------------------
/apps/app/public/icons/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/apps/app/public/icons/logo.png
--------------------------------------------------------------------------------
/apps/app/sentry.client.config.ts:
--------------------------------------------------------------------------------
1 | import { initializeSentry } from '@repo/observability/client';
2 |
3 | initializeSentry();
4 |
--------------------------------------------------------------------------------
/apps/web/public/home/tube.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/apps/web/public/home/tube.webp
--------------------------------------------------------------------------------
/packages/backend/migrations/0001_loving_sunset_bain.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "chat_sessions" ALTER COLUMN "user_id" SET DATA TYPE uuid;
--------------------------------------------------------------------------------
/packages/backend/migrations/0009_nervous_giant_girl.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "preferences" ADD COLUMN "default_assistants" json NOT NULL;
--------------------------------------------------------------------------------
/packages/backend/migrations/0020_absurd_pretty_boy.sql:
--------------------------------------------------------------------------------
1 | ALTER TYPE "public"."integration_state_platform" ADD VALUE 'LINKEDIN';
--------------------------------------------------------------------------------
/.github/screenshots/oschathub.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/.github/screenshots/oschathub.png
--------------------------------------------------------------------------------
/apps/api/app/cron/keep-alive/route.ts:
--------------------------------------------------------------------------------
1 | export const POST = async () => {
2 | return new Response('OK', { status: 200 });
3 | };
4 |
--------------------------------------------------------------------------------
/apps/api/app/opengraph-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/apps/api/app/opengraph-image.png
--------------------------------------------------------------------------------
/apps/app/app/opengraph-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/apps/app/app/opengraph-image.png
--------------------------------------------------------------------------------
/apps/app/public/images/resume1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/apps/app/public/images/resume1.png
--------------------------------------------------------------------------------
/apps/app/public/images/resume2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/apps/app/public/images/resume2.png
--------------------------------------------------------------------------------
/apps/app/public/images/resume3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/apps/app/public/images/resume3.png
--------------------------------------------------------------------------------
/apps/app/public/images/resume4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/apps/app/public/images/resume4.png
--------------------------------------------------------------------------------
/apps/app/public/images/vineeth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/apps/app/public/images/vineeth.png
--------------------------------------------------------------------------------
/apps/app/services/premium/index.ts:
--------------------------------------------------------------------------------
1 | export * from '@/services/premium/client';
2 | export * from '@/services/premium/queries';
3 |
--------------------------------------------------------------------------------
/apps/app/services/prompts/index.ts:
--------------------------------------------------------------------------------
1 | export * from '@/services/prompts/client';
2 | export * from '@/services/prompts/queries';
3 |
--------------------------------------------------------------------------------
/apps/app/services/sessions/index.ts:
--------------------------------------------------------------------------------
1 | export * from '@/services/sessions/client';
2 | export * from '@/services/sessions/queries';
3 |
--------------------------------------------------------------------------------
/apps/docs/images/checks-passed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/apps/docs/images/checks-passed.png
--------------------------------------------------------------------------------
/apps/storybook/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/apps/storybook/public/favicon.ico
--------------------------------------------------------------------------------
/apps/web/app/opengraph-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/apps/web/app/opengraph-image.png
--------------------------------------------------------------------------------
/apps/web/public/home/chathub.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/apps/web/public/home/chathub.png
--------------------------------------------------------------------------------
/packages/backend/migrations/0010_puzzling_tarantula.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "preferences" ALTER COLUMN "default_assistants" DROP NOT NULL;
--------------------------------------------------------------------------------
/packages/design-system/components/ui/flex-spacer.tsx:
--------------------------------------------------------------------------------
1 | export const FlexSpacer = () => {
2 | return
;
3 | };
--------------------------------------------------------------------------------
/.github/screenshots/ostubehero.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/.github/screenshots/ostubehero.jpeg
--------------------------------------------------------------------------------
/apps/app/public/images/os-resume.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/apps/app/public/images/os-resume.png
--------------------------------------------------------------------------------
/apps/app/public/images/signature.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/apps/app/public/images/signature.png
--------------------------------------------------------------------------------
/apps/app/services/assistants/index.ts:
--------------------------------------------------------------------------------
1 | export * from '@/services/assistants/queries';
2 | export * from '@/services/assistants/client';
3 |
--------------------------------------------------------------------------------
/apps/web/vercel.json:
--------------------------------------------------------------------------------
1 | {
2 | "crons": [],
3 | "git": {
4 | "deploymentEnabled": {
5 | "main": true
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/.github/screenshots/oschathubhero.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/.github/screenshots/oschathubhero.png
--------------------------------------------------------------------------------
/apps/app/app/.well-known/vercel/flags/route.ts:
--------------------------------------------------------------------------------
1 | import { getFlags } from '@repo/feature-flags/access';
2 |
3 | export const GET = getFlags;
4 |
--------------------------------------------------------------------------------
/apps/app/services/preferences/index.ts:
--------------------------------------------------------------------------------
1 | export * from '@/services/preferences/client';
2 | export * from '@/services/preferences/queries';
3 |
--------------------------------------------------------------------------------
/apps/web/.well-known/vercel/flags/route.ts:
--------------------------------------------------------------------------------
1 | import { getFlags } from '@repo/feature-flags/access';
2 |
3 | export const GET = getFlags;
4 |
--------------------------------------------------------------------------------
/apps/web/public/home/watercolor-2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/apps/web/public/home/watercolor-2.webp
--------------------------------------------------------------------------------
/packages/backend/migrations/0012_flaky_micromacro.sql:
--------------------------------------------------------------------------------
1 | CREATE TYPE "public"."premium_tier" AS ENUM('PRO_MONTHLY', 'PRO_ANNUALLY', 'LIFETIME');
--------------------------------------------------------------------------------
/.github/screenshots/ostubethumbnail.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/.github/screenshots/ostubethumbnail.webp
--------------------------------------------------------------------------------
/apps/api/app/health/route.ts:
--------------------------------------------------------------------------------
1 | export const runtime = 'edge';
2 |
3 | export const GET = (): Response => new Response('OK', { status: 200 });
4 |
--------------------------------------------------------------------------------
/apps/app/modules/tube/comments/ui/components/comment-list.tsx:
--------------------------------------------------------------------------------
1 | export const CommentList = () => {
2 | return CommentList
;
3 | };
4 |
--------------------------------------------------------------------------------
/apps/app/public/icons/deepseek-color.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/apps/app/public/icons/deepseek-color.png
--------------------------------------------------------------------------------
/packages/backend/migrations/0011_brown_iron_fist.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "preferences" ALTER COLUMN "default_assistants" SET DEFAULT '["chathub"]'::json;
--------------------------------------------------------------------------------
/.github/screenshots/oschathubthumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kuluruvineeth/openstudio-beta/HEAD/.github/screenshots/oschathubthumbnail.png
--------------------------------------------------------------------------------
/packages/webhooks/index.ts:
--------------------------------------------------------------------------------
1 | import { getAppPortal, send } from './lib/svix';
2 |
3 | export const webhooks = {
4 | send,
5 | getAppPortal,
6 | };
7 |
--------------------------------------------------------------------------------
/apps/api/instrumentation.ts:
--------------------------------------------------------------------------------
1 | import { initializeSentry } from '@repo/observability/instrumentation';
2 |
3 | export const register = initializeSentry();
4 |
--------------------------------------------------------------------------------
/apps/app/instrumentation.ts:
--------------------------------------------------------------------------------
1 | import { initializeSentry } from '@repo/observability/instrumentation';
2 |
3 | export const register = initializeSentry();
4 |
--------------------------------------------------------------------------------
/apps/web/instrumentation.ts:
--------------------------------------------------------------------------------
1 | import { initializeSentry } from '@repo/observability/instrumentation';
2 |
3 | export const register = initializeSentry();
4 |
--------------------------------------------------------------------------------
/packages/feature-flags/index.ts:
--------------------------------------------------------------------------------
1 | import { createFlag } from './lib/create-flag';
2 |
3 | export const showBetaFeature = createFlag('showBetaFeature');
4 |
--------------------------------------------------------------------------------
/packages/email/index.ts:
--------------------------------------------------------------------------------
1 | import { Resend } from 'resend';
2 | import { keys } from './keys';
3 |
4 | export const resend = new Resend(keys().RESEND_TOKEN);
5 |
--------------------------------------------------------------------------------
/apps/email/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "include": ["**/*.ts", "**/*.tsx"],
4 | "exclude": ["node_modules"]
5 | }
6 |
--------------------------------------------------------------------------------
/packages/observability/log.ts:
--------------------------------------------------------------------------------
1 | import { log as logtail } from '@logtail/next';
2 |
3 | export const log = process.env.NODE_ENV === 'production' ? logtail : console;
4 |
--------------------------------------------------------------------------------
/packages/backend/migrations/0015_light_jackpot.sql:
--------------------------------------------------------------------------------
1 | ALTER TYPE "public"."provider" ADD VALUE 'meta';--> statement-breakpoint
2 | ALTER TYPE "public"."provider" ADD VALUE 'xai';
--------------------------------------------------------------------------------
/apps/app/types/export.ts:
--------------------------------------------------------------------------------
1 | import type { dataValidator } from '@/helper/validator';
2 | import type { z } from 'zod';
3 | export type ExportData = z.infer;
4 |
--------------------------------------------------------------------------------
/apps/app/config/constants.ts:
--------------------------------------------------------------------------------
1 | export const constants = {
2 | avatarColors: ['#063940', '#195e63', '#3e838c', '#8ebdb6', '#ece1c3'],
3 | };
4 |
5 | export const DEFAULT_LIMIT = 10;
6 |
--------------------------------------------------------------------------------
/apps/storybook/next.config.ts:
--------------------------------------------------------------------------------
1 | import type { NextConfig } from 'next';
2 |
3 | const nextConfig: NextConfig = {
4 | reactStrictMode: true,
5 | };
6 |
7 | export default nextConfig;
8 |
--------------------------------------------------------------------------------
/packages/tailwind-config/index.ts:
--------------------------------------------------------------------------------
1 | import resolveConfig from 'tailwindcss/resolveConfig';
2 | import { config } from './config';
3 |
4 | export const tailwind = resolveConfig(config);
5 |
--------------------------------------------------------------------------------
/packages/tinybird/pipes/cost_per_user_pipe.pipe:
--------------------------------------------------------------------------------
1 | NODE cost_per_user_node
2 | SQL >
3 | SELECT userId, sum(cost) AS cost FROM aiCall
4 | GROUP BY userId
5 | ORDER BY cost DESC
--------------------------------------------------------------------------------
/apps/app/lib/mux.ts:
--------------------------------------------------------------------------------
1 | import Mux from '@mux/mux-node';
2 |
3 | export const mux = new Mux({
4 | tokenId: process.env.MUX_TOKEN_ID,
5 | tokenSecret: process.env.MUX_TOKEN_SECRET,
6 | });
7 |
--------------------------------------------------------------------------------
/apps/app/lib/validations/subscribe.ts:
--------------------------------------------------------------------------------
1 | import * as z from 'zod';
2 |
3 | export const subscribeSchema = z.object({
4 | name: z.string().min(1).max(48),
5 | email: z.string().email(),
6 | });
7 |
--------------------------------------------------------------------------------
/packages/backend/migrations/0022_massive_violations.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "chat_messages" DROP COLUMN "ai_responses";--> statement-breakpoint
2 | ALTER TABLE "preferences" DROP COLUMN "default_assistants";
--------------------------------------------------------------------------------
/apps/storybook/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | },
6 | };
7 |
8 | export default config;
9 |
--------------------------------------------------------------------------------
/packages/backend/auth/index.ts:
--------------------------------------------------------------------------------
1 | export type { User } from '@supabase/supabase-js';
2 |
3 | export enum OpenStudioRole {
4 | Admin = 'admin',
5 | Editor = 'editor',
6 | Member = 'member',
7 | }
8 |
--------------------------------------------------------------------------------
/packages/lib/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | 'postcss-import': {},
4 | 'tailwindcss/nesting': {},
5 | tailwindcss: {},
6 | autoprefixer: {},
7 | },
8 | };
9 |
--------------------------------------------------------------------------------
/packages/backend/migrations/0002_tense_darkstar.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "chat_sessions" ALTER COLUMN "id" SET DATA TYPE text;--> statement-breakpoint
2 | ALTER TABLE "chat_sessions" ALTER COLUMN "id" DROP DEFAULT;
--------------------------------------------------------------------------------
/apps/app/lib/constants/index.ts:
--------------------------------------------------------------------------------
1 | export const StorageFolders = [
2 | 'avatars',
3 | 'og-images',
4 | 'editor-uploads',
5 | ] as const;
6 |
7 | export const THUMBNAIL_FALLBACK = '/icons/placeholder.svg';
8 |
--------------------------------------------------------------------------------
/packages/backend/migrations/0006_eager_robbie_robertson.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "chat_sessions" ALTER COLUMN "id" SET DATA TYPE text;--> statement-breakpoint
2 | ALTER TABLE "chat_sessions" ALTER COLUMN "id" DROP DEFAULT;
--------------------------------------------------------------------------------
/packages/backend/migrations/0007_slippery_jasper_sitwell.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "chat_messages" ALTER COLUMN "id" SET DATA TYPE text;--> statement-breakpoint
2 | ALTER TABLE "chat_messages" ALTER COLUMN "id" DROP DEFAULT;
--------------------------------------------------------------------------------
/apps/web/mdx-components.tsx:
--------------------------------------------------------------------------------
1 | import type { MDXComponents } from 'mdx/types';
2 |
3 | export function useMDXComponents(components: MDXComponents): MDXComponents {
4 | return {
5 | ...components,
6 | };
7 | }
8 |
--------------------------------------------------------------------------------
/packages/backend/auth/session.ts:
--------------------------------------------------------------------------------
1 | import { createClient } from './server';
2 |
3 | export async function getSession() {
4 | const client = await createClient();
5 |
6 | return client.auth.getSession();
7 | }
8 |
--------------------------------------------------------------------------------
/packages/tinybird/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["src"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/minime/page.tsx:
--------------------------------------------------------------------------------
1 | export const dynamic = 'force-dynamic';
2 |
3 | export default function MinimePage() {
4 | return Minime - WIP (a lot of bugs and unfinished features)
;
5 | }
6 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/tube/studio/[videoId]/edit/page.tsx:
--------------------------------------------------------------------------------
1 | import Editor from '@/modules/tube/studio/ui/components/editor/editor';
2 |
3 | export default function EditVideoPage() {
4 | return ;
5 | }
6 |
--------------------------------------------------------------------------------
/packages/ai/index.ts:
--------------------------------------------------------------------------------
1 | export * from 'ai';
2 | export * from 'ai/rsc';
3 | export * from '@ai-sdk/openai';
4 | export * from '@ai-sdk/google';
5 | export * from '@ai-sdk/anthropic';
6 | export * from '@ai-sdk/fireworks';
7 |
--------------------------------------------------------------------------------
/packages/backend/migrations/0014_next_marvel_boy.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "premium" ALTER COLUMN "userId" SET DATA TYPE varchar;--> statement-breakpoint
2 | ALTER TABLE "premium" ALTER COLUMN "organizationId" SET DATA TYPE varchar;
--------------------------------------------------------------------------------
/apps/app/context/index.ts:
--------------------------------------------------------------------------------
1 | export * from '@/context/chat';
2 | export * from '@/context/preferences';
3 | export * from '@/context/prompts';
4 | export * from '@/context/react-query';
5 | export * from '@/context/sessions';
6 |
--------------------------------------------------------------------------------
/packages/ai/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["**/*.ts", "**/*.tsx"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/feature-flags/components/toolbar.tsx:
--------------------------------------------------------------------------------
1 | import { VercelToolbar } from '@vercel/toolbar/next';
2 | import { keys } from '../keys';
3 |
4 | export const Toolbar = () => (keys().FLAGS_SECRET ? : null);
5 |
--------------------------------------------------------------------------------
/packages/tinybird/pipes/count_per_day_pipe.pipe:
--------------------------------------------------------------------------------
1 | NODE count_per_day_node
2 | SQL >
3 | SELECT toStartOfDay(fromUnixTimestamp64Milli(timestamp)) AS "day", count(*) AS count FROM aiCall
4 | GROUP BY day
5 | ORDER BY day
--------------------------------------------------------------------------------
/packages/cms/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["**/*.ts", "**/*.tsx"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/email/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["./*.ts", "./*.tsx"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/lib/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["**/*.ts", "**/*.tsx"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/mux/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["**/*.ts", "**/*.tsx"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/storage/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["**/*.ts", "**/*.tsx"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/testing/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/react-library.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["./src/*.tsx"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/youtube/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["**/*.ts", "**/*.tsx"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/analytics/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["**/*.ts", "**/*.tsx"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/design-system/components/ui/aspect-ratio.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio"
4 |
5 | const AspectRatio = AspectRatioPrimitive.Root
6 |
7 | export { AspectRatio }
8 |
--------------------------------------------------------------------------------
/packages/payments/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["**/*.ts", "**/*.tsx"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/security/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["**/*.ts", "**/*.tsx"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/seo/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/react-library.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["**/*.ts", "**/*.tsx"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/tinybird/pipes/cost_per_model_pipe.pipe:
--------------------------------------------------------------------------------
1 | NODE cost_per_model_node
2 | SQL >
3 | SELECT model, sum(cost) AS cost FROM aiCall
4 | GROUP BY model
5 | ORDER BY cost DESC
6 |
7 | /*
8 | i want to get the cost per model
--------------------------------------------------------------------------------
/packages/tinybird/pipes/count_per_hour_pipe.pipe:
--------------------------------------------------------------------------------
1 | NODE count_per_hour_node
2 | SQL >
3 | SELECT toStartOfHour(fromUnixTimestamp64Milli(timestamp)) AS "hour", count(*) AS count FROM aiCall
4 | GROUP BY hour
5 | ORDER BY hour
--------------------------------------------------------------------------------
/packages/webhooks/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["**/*.ts", "**/*.tsx"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/collaboration/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["**/*.ts", "**/*.tsx"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/feature-flags/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["**/*.ts", "**/*.tsx"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/observability/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["**/*.ts", "**/*.tsx"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/typescript-config/react-library.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "React Library",
4 | "extends": "./base.json",
5 | "compilerOptions": {
6 | "jsx": "react-jsx"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/packages/design-system/postcss.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('postcss-load-config').Config} */
2 | const config = {
3 | plugins: {
4 | tailwindcss: {},
5 | autoprefixer: {},
6 | },
7 | };
8 |
9 | export default config;
10 |
--------------------------------------------------------------------------------
/packages/jobs/index.ts:
--------------------------------------------------------------------------------
1 | export * from './tasks/videos/generate-description';
2 | export * from './tasks/videos/generate-title';
3 | export * from './tasks/videos/generate-chapters';
4 | export * from './tasks/videos/generate-video-metadata';
5 |
--------------------------------------------------------------------------------
/packages/lib/src/fuse.ts:
--------------------------------------------------------------------------------
1 | import Fuse from 'fuse.js';
2 |
3 | export const createFuse = (data: readonly T[], keys: string[]): Fuse =>
4 | new Fuse(data, {
5 | keys,
6 | minMatchCharLength: 1,
7 | threshold: 0.3,
8 | });
9 |
--------------------------------------------------------------------------------
/packages/next-config/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/react-library.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["**/*.ts", "**/*.tsx"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/tailwind-config/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/react-library.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["**/*.ts", "**/*.tsx"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/apps/api/vercel.json:
--------------------------------------------------------------------------------
1 | {
2 | "crons": [
3 | {
4 | "path": "/cron/keep-alive",
5 | "schedule": "0 1 * * *"
6 | }
7 | ],
8 | "git": {
9 | "deploymentEnabled": {
10 | "main": true
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/chat/settings/data/page.tsx:
--------------------------------------------------------------------------------
1 | import DataClientWrapper from './data-client-wrapper';
2 |
3 | export const dynamic = 'force-dynamic';
4 |
5 | export default function DataPage() {
6 | return ;
7 | }
8 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/chat/assistants/page.tsx:
--------------------------------------------------------------------------------
1 | import AssistantClientWrapper from './client-wrapper';
2 |
3 | export const dynamic = 'force-dynamic';
4 |
5 | export default function AssistantPage() {
6 | return ;
7 | }
8 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/chat/settings/voice/page.tsx:
--------------------------------------------------------------------------------
1 | import VoiceClientWrapper from './voice-client-wrapper';
2 |
3 | export const dynamic = 'force-dynamic';
4 |
5 | export default function VoicePage() {
6 | return ;
7 | }
8 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/chat/components/codeblock.module.css:
--------------------------------------------------------------------------------
1 | @import "highlight.js/styles/github-dark.css";
2 |
3 | .hljs-wrapper {
4 | @apply rounded-lg border bg-zinc-950;
5 | }
6 |
7 | .hljs-pre {
8 | @apply overflow-x-auto p-4;
9 | }
10 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/chat/settings/common/page.tsx:
--------------------------------------------------------------------------------
1 | import CommonClientWrapper from './common-client-wrapper';
2 |
3 | export const dynamic = 'force-dynamic';
4 |
5 | export default function CommonPage() {
6 | return ;
7 | }
8 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/chat/settings/memory/page.tsx:
--------------------------------------------------------------------------------
1 | import MemoryClientWrapper from './memory-client-wrapper';
2 |
3 | export const dynamic = 'force-dynamic';
4 |
5 | export default function MemoryPage() {
6 | return ;
7 | }
8 |
--------------------------------------------------------------------------------
/apps/app/modules/tube/automation/ui/components/test-custom-comment-form.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { useState } from 'react';
4 |
5 | export const TestCustomCommentForm = () => {
6 | const [testResult, setTestResult] = useState('');
7 | };
8 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/chat/settings/plugins/page.tsx:
--------------------------------------------------------------------------------
1 | import PluginsClientWrapper from './plugin-client-wrapper';
2 |
3 | export const dynamic = 'force-dynamic';
4 |
5 | export default function PluginsPage() {
6 | return ;
7 | }
8 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/tube/test.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { trpc } from '@/trpc/client';
4 |
5 | export default function Test() {
6 | const [data] = trpc.categories.getMany.useSuspenseQuery();
7 | return {JSON.stringify(data)}
;
8 | }
9 |
--------------------------------------------------------------------------------
/apps/app/modules/tube/comments/types.ts:
--------------------------------------------------------------------------------
1 | import type { inferRouterOutputs } from '@trpc/server';
2 |
3 | import type { AppRouter } from '@/trpc/routers/_app';
4 |
5 | export type CommentsGetManyOutput =
6 | inferRouterOutputs['comments']['getMany'];
7 |
--------------------------------------------------------------------------------
/apps/app/public/icons/microsoft.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apps/app/types/documents.ts:
--------------------------------------------------------------------------------
1 | export type TDocument = {
2 | id: string;
3 | content: File | string;
4 | isIndexing: boolean;
5 | isFailed: boolean;
6 | isIndexed: boolean;
7 | meta: any;
8 | createdAt: Date;
9 | updatedAt: Date;
10 | };
11 |
--------------------------------------------------------------------------------
/apps/docs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "docs",
3 | "private": true,
4 | "scripts": {
5 | "dev": "mintlify dev --port 3004",
6 | "lint": "mintlify broken-links"
7 | },
8 | "devDependencies": {
9 | "typescript": "^5.7.2"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/packages/feature-flags/lib/toolbar.ts:
--------------------------------------------------------------------------------
1 | import { withVercelToolbar } from '@vercel/toolbar/plugins/next';
2 | import { keys } from '../keys';
3 |
4 | export const withToolbar = (config: object) =>
5 | keys().FLAGS_SECRET ? withVercelToolbar()(config) : config;
6 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "biomejs.biome",
4 | "bradlc.vscode-tailwindcss",
5 | "Prisma.prisma",
6 | "unifiedjs.vscode-mdx",
7 | "mikestead.dotenv",
8 | "christian-kohler.npm-intellisense"
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/chat/page.tsx:
--------------------------------------------------------------------------------
1 | import ChatClientWrapper from './chat-client-wrapper';
2 |
3 | export const dynamic = 'force-dynamic';
4 |
5 | const ChatSessionPage = () => {
6 | return ;
7 | };
8 | export default ChatSessionPage;
9 |
--------------------------------------------------------------------------------
/apps/app/types/prompts.ts:
--------------------------------------------------------------------------------
1 | export type TConstructPrompt = {
2 | context?: string;
3 | image?: string;
4 | memories: string[];
5 | hasMessages: boolean;
6 | systemPrompt: string;
7 | formatInstructions?: boolean;
8 | userPrompt?: string;
9 | };
10 |
--------------------------------------------------------------------------------
/packages/cms/next-config.ts:
--------------------------------------------------------------------------------
1 | import type { NextConfig } from 'next';
2 |
3 | // This file is a stub for modifying the Next.js configuration.
4 | // It's handy for supplementing the default CMS configuration.
5 | export const withCMS = (config: NextConfig) => config;
6 |
--------------------------------------------------------------------------------
/packages/tinybird/pipes/count_per_user_pipe.pipe:
--------------------------------------------------------------------------------
1 | NODE count_per_user_node
2 | SQL >
3 | %
4 | SELECT count(*) AS count FROM aiCall
5 | WHERE "userEmail" = {{String(userEmail)}}
6 | AND toStartOfMonth(fromUnixTimestamp64Milli(timestamp)) = toStartOfMonth(now())
--------------------------------------------------------------------------------
/apps/app/modules/tube/comments/ui/components/plan-badge.tsx:
--------------------------------------------------------------------------------
1 | export const PlanBadge = () => {
2 | return (
3 |
4 | Plan
5 |
6 | );
7 | };
8 |
--------------------------------------------------------------------------------
/packages/design-system/components/ui/beta-tag.tsx:
--------------------------------------------------------------------------------
1 | export const BetaTag = () => {
2 | return (
3 |
4 | Beta
5 |
6 | );
7 | };
--------------------------------------------------------------------------------
/apps/app/app/(organization)/chat/components/welcome-message/custom-assistant-copy.tsx:
--------------------------------------------------------------------------------
1 | export const CustomAssistantCopy = () => {
2 | return (
3 | <>
4 | Design your perfect AI companion with tailored expertise and personalized
5 | knowledge.
6 | >
7 | );
8 | };
9 |
--------------------------------------------------------------------------------
/packages/feature-flags/lib/create-flag.ts:
--------------------------------------------------------------------------------
1 | import { unstable_flag as flag } from '@vercel/flags/next';
2 |
3 | export const createFlag = (key: string) =>
4 | flag({
5 | key,
6 | defaultValue: false,
7 | async decide() {
8 | return true;
9 | },
10 | });
11 |
--------------------------------------------------------------------------------
/packages/design-system/components/ui/or-divider.tsx:
--------------------------------------------------------------------------------
1 | export const OrDivider = () => (
2 |
7 | );
8 |
--------------------------------------------------------------------------------
/apps/app/app/api/prompts/route.ts:
--------------------------------------------------------------------------------
1 | // import { prompts } from '@/helper/prompts';
2 | import { type NextRequest, NextResponse } from 'next/server';
3 |
4 | export async function GET(req: NextRequest) {
5 | //TODO: Get prompts from the database
6 | return NextResponse.json({ prompts: [] });
7 | }
8 |
--------------------------------------------------------------------------------
/turbo/generators/templates/package.json.hbs:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/{{ name }}",
3 | "private": true,
4 | "version": "0.0.0",
5 | "scripts": {
6 | "clean": "git clean -xdf .cache .turbo dist node_modules",
7 | "typecheck": "tsc --noEmit --emitDeclarationOnly false"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | @hugeicons-pro:registry=https://npm.hugeicons.com/
2 | //npm.hugeicons.com/:_authToken=81385302-85F6A0C5-EC7F15D1-C4FFF15A
3 | @tiptap-pro:registry=https://registry.tiptap.dev/
4 | //registry.tiptap.dev/:_authToken=tPmWWOUOKVEUCUbCo8htHUPwKoq4+4xBXKghPxBzEVfhBsQuKlTgpAtkLnCTB4oAdTM5i/FNW1JNzsmTjKJEAg==
--------------------------------------------------------------------------------
/packages/typescript-config/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/typescript-config",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "clean": "git clean -xdf .cache .turbo dist node_modules",
7 | "typecheck": "tsc --noEmit --emitDeclarationOnly false"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/apps/app/.npmrc:
--------------------------------------------------------------------------------
1 | @hugeicons-pro:registry=https://npm.hugeicons.com/
2 | //npm.hugeicons.com/:_authToken=81385302-85F6A0C5-EC7F15D1-C4FFF15A
3 | @tiptap-pro:registry=https://registry.tiptap.dev/
4 | //registry.tiptap.dev/:_authToken=tPmWWOUOKVEUCUbCo8htHUPwKoq4+4xBXKghPxBzEVfhBsQuKlTgpAtkLnCTB4oAdTM5i/FNW1JNzsmTjKJEAg==
--------------------------------------------------------------------------------
/apps/app/artifacts/actions.ts:
--------------------------------------------------------------------------------
1 | 'use server';
2 |
3 | import { getSuggestionsByDocumentId } from '@/lib/queries';
4 |
5 | export async function getSuggestions({ documentId }: { documentId: string }) {
6 | const suggestions = await getSuggestionsByDocumentId({ documentId });
7 | return suggestions ?? [];
8 | }
9 |
--------------------------------------------------------------------------------
/apps/storybook/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": [
7 | "next-env.d.ts",
8 | "next.config.ts",
9 | "**/*.ts",
10 | "**/*.tsx",
11 | ".next/types/**/*.ts"
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/packages/backend/migrations/0027_jittery_purifiers.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "videos" ADD COLUMN "category_id" uuid;--> statement-breakpoint
2 | ALTER TABLE "videos" ADD CONSTRAINT "videos_category_id_categories_id_fk" FOREIGN KEY ("category_id") REFERENCES "public"."categories"("id") ON DELETE set null ON UPDATE no action;
--------------------------------------------------------------------------------
/apps/app/actions/job/schema.ts:
--------------------------------------------------------------------------------
1 | export interface JobListingParams {
2 | page: number;
3 | pageSize: number;
4 | filters?: {
5 | workLocation?: 'remote' | 'in_person' | 'hybrid';
6 | employmentType?: 'full_time' | 'part_time' | 'co_op' | 'internship';
7 | keywords?: string[];
8 | };
9 | }
10 |
--------------------------------------------------------------------------------
/packages/backend/auth/client.ts:
--------------------------------------------------------------------------------
1 | import { createBrowserClient } from '@supabase/ssr';
2 | import { keys } from '../keys';
3 |
4 | const env = keys();
5 |
6 | export const createClient = () =>
7 | createBrowserClient(
8 | env.NEXT_PUBLIC_SUPABASE_URL,
9 | env.NEXT_PUBLIC_SUPABASE_ANON_KEY
10 | );
11 |
--------------------------------------------------------------------------------
/packages/backend/migrations/0005_mature_night_thrasher.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE "chat_sessions" ALTER COLUMN "id" SET DATA TYPE uuid;--> statement-breakpoint
2 | ALTER TABLE "chat_sessions" ALTER COLUMN "id" SET DEFAULT gen_random_uuid();--> statement-breakpoint
3 | ALTER TABLE "chat_sessions" ADD COLUMN "custom_assistant" json;
--------------------------------------------------------------------------------
/apps/app/actions/categories/validation.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod';
2 |
3 | export const createCategoryBody = z.object({
4 | id: z.string().uuid().nullish(),
5 | name: z.string().max(30),
6 | description: z.string().max(300).nullish(),
7 | });
8 | export type CreateCategoryBody = z.infer;
9 |
--------------------------------------------------------------------------------
/apps/app/tools/index.ts:
--------------------------------------------------------------------------------
1 | export * from '@/tools/reader';
2 | export * from '@/tools/memory';
3 | export * from '@/tools/dalle';
4 | export * from '@/tools/google';
5 | export * from '@/tools/duckduckgo';
6 | export * from '@/tools/pie-chart';
7 | export * from '@/tools/bar-chart';
8 | export * from '@/tools/line-chart';
9 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/voice/layout.tsx:
--------------------------------------------------------------------------------
1 | import { WorkInProgress } from '@repo/design-system/components/ui/work-in-progress';
2 |
3 | //TODO: Remove this one once feature is completed
4 | export default function VoiceLayout({
5 | children,
6 | }: { children: React.ReactNode }) {
7 | return ;
8 | }
9 |
--------------------------------------------------------------------------------
/packages/design-system/.npmrc:
--------------------------------------------------------------------------------
1 | @hugeicons-pro:registry=https://npm.hugeicons.com/
2 | //npm.hugeicons.com/:_authToken=81385302-85F6A0C5-EC7F15D1-C4FFF15A
3 | @tiptap-pro:registry=https://registry.tiptap.dev/
4 | //registry.tiptap.dev/:_authToken=tPmWWOUOKVEUCUbCo8htHUPwKoq4+4xBXKghPxBzEVfhBsQuKlTgpAtkLnCTB4oAdTM5i/FNW1JNzsmTjKJEAg==
--------------------------------------------------------------------------------
/apps/app/app/(organization)/test/Test.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { trpc } from '@/trpc/client';
4 |
5 | export default function Test() {
6 | const videos = trpc.youtube.getVideos.useQuery();
7 |
8 | return (
9 |
10 |
{JSON.stringify(videos, null, 2)}
11 |
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/apps/docs/snippets/snippet-intro.mdx:
--------------------------------------------------------------------------------
1 | One of the core principles of software development is DRY (Don't Repeat
2 | Yourself). This is a principle that apply to documentation as
3 | well. If you find yourself repeating the same content in multiple places, you
4 | should consider creating a custom snippet to keep your content in sync.
5 |
--------------------------------------------------------------------------------
/packages/tinybird/src/client.ts:
--------------------------------------------------------------------------------
1 | import { Tinybird } from '@chronark/zod-bird';
2 |
3 | if (!process.env.TINYBIRD_API_KEY) {
4 | throw new Error('TINYBIRD_API_KEY is not set');
5 | }
6 |
7 | export const tb = new Tinybird({
8 | token: process.env.TINYBIRD_API_KEY,
9 | baseUrl: process.env.TINYBIRD_API_URL,
10 | });
11 |
--------------------------------------------------------------------------------
/packages/design-system/lib/fonts.ts:
--------------------------------------------------------------------------------
1 | import { cn } from '@repo/design-system/lib/utils';
2 | import { GeistMono } from 'geist/font/mono';
3 | import { GeistSans } from 'geist/font/sans';
4 |
5 | export const fonts = cn(
6 | GeistSans.variable,
7 | GeistMono.variable,
8 | 'touch-manipulation font-sans antialiased'
9 | );
10 |
--------------------------------------------------------------------------------
/apps/api/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { ReactNode } from 'react';
2 |
3 | type RootLayoutProperties = {
4 | readonly children: ReactNode;
5 | };
6 |
7 | const RootLayout = ({ children }: RootLayoutProperties) => (
8 |
9 | {children}
10 |
11 | );
12 |
13 | export default RootLayout;
14 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/test/page.tsx:
--------------------------------------------------------------------------------
1 | import { trpc } from '@/trpc/server';
2 | import Test from './Test';
3 |
4 | export const dynamic = 'force-dynamic';
5 |
6 | export default async function TestPage() {
7 | void trpc.youtube.getVideos.prefetch();
8 | return (
9 |
10 |
11 |
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/apps/web/app/legal/(documents)/privacy/content.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { LegalPage } from '@/app/components/LegalPage';
4 | import Content from './content.mdx';
5 |
6 | export default function PrivacyContent() {
7 | return (
8 | } />
9 | );
10 | }
11 |
--------------------------------------------------------------------------------
/packages/feature-flags/keys.ts:
--------------------------------------------------------------------------------
1 | import { createEnv } from '@t3-oss/env-nextjs';
2 | import { z } from 'zod';
3 |
4 | export const keys = () =>
5 | createEnv({
6 | server: {
7 | FLAGS_SECRET: z.string().min(1).optional(),
8 | },
9 | runtimeEnv: {
10 | FLAGS_SECRET: process.env.FLAGS_SECRET,
11 | },
12 | });
13 |
--------------------------------------------------------------------------------
/apps/email/emails/contact.tsx:
--------------------------------------------------------------------------------
1 | import { ContactTemplate } from '@repo/email/templates/contact';
2 |
3 | const ExampleContactEmail = () => (
4 |
9 | );
10 |
11 | export default ExampleContactEmail;
12 |
--------------------------------------------------------------------------------
/packages/cms/keys.ts:
--------------------------------------------------------------------------------
1 | import { createEnv } from '@t3-oss/env-nextjs';
2 | import { z } from 'zod';
3 |
4 | export const keys = () =>
5 | createEnv({
6 | server: {
7 | BASEHUB_TOKEN: z.string().min(1).startsWith('bshb_pk_'),
8 | },
9 | runtimeEnv: {
10 | BASEHUB_TOKEN: process.env.BASEHUB_TOKEN,
11 | },
12 | });
13 |
--------------------------------------------------------------------------------
/packages/design-system/lib/handle-error.ts:
--------------------------------------------------------------------------------
1 | 'use client';
2 | //TODO: add this later
3 | // import { parseError } from '@repo/lib/parse-error';
4 | import { toast } from './toast';
5 |
6 | export const handleError = (error: unknown): void => {
7 | // const message = parseError(error);
8 |
9 | toast.error('An error occurred');
10 | };
11 |
--------------------------------------------------------------------------------
/packages/design-system/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "paths": {
6 | "@repo/*": ["../*"],
7 | "@repo/design-system/*": ["./*"]
8 | }
9 | },
10 | "include": ["**/*.ts", "**/*.tsx"],
11 | "exclude": ["node_modules"]
12 | }
13 |
--------------------------------------------------------------------------------
/packages/security/keys.ts:
--------------------------------------------------------------------------------
1 | import { createEnv } from '@t3-oss/env-nextjs';
2 | import { z } from 'zod';
3 |
4 | export const keys = () =>
5 | createEnv({
6 | server: {
7 | ARCJET_KEY: z.string().min(1).startsWith('ajkey_').optional(),
8 | },
9 | runtimeEnv: {
10 | ARCJET_KEY: process.env.ARCJET_KEY,
11 | },
12 | });
13 |
--------------------------------------------------------------------------------
/apps/web/app/components/header/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/jobs/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "declaration": false,
6 | "declarationMap": false,
7 | "emitDeclarationOnly": false,
8 | "noEmit": true
9 | },
10 | "include": ["**/*.ts", "**/*.tsx"],
11 | "exclude": ["node_modules"]
12 | }
13 |
--------------------------------------------------------------------------------
/packages/tinybird/pipes/count_per_model_pipe.pipe:
--------------------------------------------------------------------------------
1 | NODE count_per_model_node
2 | SQL >
3 | %
4 | SELECT model, count(*) AS count FROM aiCall
5 | WHERE "userEmail" = {{String(userEmail)}} AND "model" = {{String(model)}}
6 | AND toStartOfMonth(fromUnixTimestamp64Milli(timestamp)) = toStartOfMonth(now())
7 | GROUP BY model
8 | ORDER BY count DESC
--------------------------------------------------------------------------------
/turbo/generators/templates/tsconfig.json.hbs:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/react-library.json",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "paths": {
6 | "@/*": ["./*"],
7 | "@repo/*": ["../../packages/*"]
8 | }
9 | },
10 | "include": ["**/*.ts", "**/*.tsx"],
11 | "exclude": ["node_modules"]
12 | }
13 |
--------------------------------------------------------------------------------
/apps/app/app/api/uploadthing/route.ts:
--------------------------------------------------------------------------------
1 | import { createRouteHandler } from 'uploadthing/next';
2 |
3 | import { ourFileRouter } from './core';
4 |
5 | // Export routes for Next App Router
6 | export const { GET, POST } = createRouteHandler({
7 | router: ourFileRouter,
8 |
9 | // Apply an (optional) custom config:
10 | // config: { ... },
11 | });
12 |
--------------------------------------------------------------------------------
/apps/app/lib/editor/react-renderer.tsx:
--------------------------------------------------------------------------------
1 | import { createRoot } from 'react-dom/client';
2 |
3 | export class ReactRenderer {
4 | static render(component: React.ReactElement, dom: HTMLElement) {
5 | const root = createRoot(dom);
6 | root.render(component);
7 |
8 | return {
9 | destroy: () => root.unmount(),
10 | };
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/packages/backend/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "declaration": false,
6 | "declarationMap": false,
7 | "emitDeclarationOnly": false,
8 | "noEmit": true
9 | },
10 | "include": ["**/*.ts", "**/*.tsx"],
11 | "exclude": ["node_modules"]
12 | }
13 |
--------------------------------------------------------------------------------
/apps/app/lib/uploadthing.ts:
--------------------------------------------------------------------------------
1 | import {
2 | generateUploadButton,
3 | generateUploadDropzone,
4 | } from '@uploadthing/react';
5 |
6 | import type { OurFileRouter } from '@/app/api/uploadthing/core';
7 |
8 | export const UploadButton: any = generateUploadButton();
9 | export const UploadDropzone: any = generateUploadDropzone();
10 |
--------------------------------------------------------------------------------
/packages/storage/keys.ts:
--------------------------------------------------------------------------------
1 | import { createEnv } from '@t3-oss/env-nextjs';
2 | import { z } from 'zod';
3 |
4 | export const keys = () =>
5 | createEnv({
6 | server: {
7 | BLOB_READ_WRITE_TOKEN: z.string().min(1).optional(),
8 | },
9 | runtimeEnv: {
10 | BLOB_READ_WRITE_TOKEN: process.env.BLOB_READ_WRITE_TOKEN,
11 | },
12 | });
13 |
--------------------------------------------------------------------------------
/packages/collaboration/keys.ts:
--------------------------------------------------------------------------------
1 | import { createEnv } from '@t3-oss/env-nextjs';
2 | import { z } from 'zod';
3 |
4 | export const keys = () =>
5 | createEnv({
6 | server: {
7 | LIVEBLOCKS_SECRET: z.string().min(1).startsWith('sk_').optional(),
8 | },
9 | runtimeEnv: {
10 | LIVEBLOCKS_SECRET: process.env.LIVEBLOCKS_SECRET,
11 | },
12 | });
13 |
--------------------------------------------------------------------------------
/apps/app/app/api/changelogs/route.ts:
--------------------------------------------------------------------------------
1 | import { database } from '@repo/backend/database';
2 | import { schema } from '@repo/backend/schema';
3 | import { type NextRequest, NextResponse } from 'next/server';
4 |
5 | export async function GET(req: NextRequest) {
6 | const changelogs = await database.select().from(schema.changelogs);
7 | return NextResponse.json({ changelogs });
8 | }
9 |
--------------------------------------------------------------------------------
/apps/web/app/legal/(documents)/terms/content.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { LegalPage } from '@/app/components/LegalPage';
4 | import Content from './content.mdx';
5 |
6 | export default function TermsContent() {
7 | return (
8 | }
12 | />
13 | );
14 | }
15 |
--------------------------------------------------------------------------------
/packages/design-system/components/ui/coming-soon.tsx:
--------------------------------------------------------------------------------
1 | import { Badge } from "@repo/design-system/components/ui/badge";
2 |
3 | export const ComingSoon = () => {
4 | return (
5 |
9 | Coming soon
10 |
11 | );
12 | };
--------------------------------------------------------------------------------
/apps/app/app/api/assistants/route.ts:
--------------------------------------------------------------------------------
1 | import { database } from '@repo/backend/database';
2 | import { schema } from '@repo/backend/schema';
3 | import { type NextRequest, NextResponse } from 'next/server';
4 |
5 | export async function GET(req: NextRequest) {
6 | const data = await database.select().from(schema.customAssistants);
7 | return NextResponse.json({ assistants: data || [] });
8 | }
9 |
--------------------------------------------------------------------------------
/apps/app/public/icons/xai.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apps/app/public/user-placeholder.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apps/web/lib/features.ts:
--------------------------------------------------------------------------------
1 | import type { ClockIcon } from 'lucide-react';
2 |
3 | export type Feature = {
4 | icon: typeof ClockIcon;
5 | name: string;
6 | href: string;
7 | description: string;
8 | formerly: string;
9 | short: string;
10 | };
11 |
12 | export const features: Record = {};
13 |
14 | // export const integrations: Feature = {
15 |
16 | // };
17 |
--------------------------------------------------------------------------------
/packages/payments/index.ts:
--------------------------------------------------------------------------------
1 | import 'server-only';
2 | import { lemonSqueezySetup } from '@lemonsqueezy/lemonsqueezy.js';
3 | import { keys } from './keys';
4 |
5 | lemonSqueezySetup({
6 | apiKey: keys().LEMON_SQUEEZY_API_KEY,
7 | onError: (error) => {
8 | console.error('Lemon Squeezy error:', error);
9 | },
10 | });
11 |
12 | export * from '@lemonsqueezy/lemonsqueezy.js';
13 |
--------------------------------------------------------------------------------
/apps/app/hooks/use-modal.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export function useModal() {
4 | const [isModalOpen, setIsModalOpen] = React.useState(false);
5 | const openModal = React.useCallback(() => setIsModalOpen(true), []);
6 | const closeModal = React.useCallback(() => setIsModalOpen(false), []);
7 |
8 | return { isModalOpen, openModal, closeModal, setIsModalOpen };
9 | }
10 |
--------------------------------------------------------------------------------
/apps/app/modules/tube/videos/types.ts:
--------------------------------------------------------------------------------
1 | import type { inferRouterOutputs } from '@trpc/server';
2 |
3 | import type { AppRouter } from '@/trpc/routers/_app';
4 |
5 | export type VideoGetOneOutput =
6 | inferRouterOutputs['videos']['getOne'];
7 |
8 | // TODO: Change to videos getMany
9 | export type VideoGetManyOutput =
10 | inferRouterOutputs['suggestions']['getMany'];
11 |
--------------------------------------------------------------------------------
/packages/design-system/components/ui/skeleton.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from "@repo/design-system/lib/utils"
2 |
3 | function Skeleton({
4 | className,
5 | ...props
6 | }: React.HTMLAttributes) {
7 | return (
8 |
12 | )
13 | }
14 |
15 | export { Skeleton }
16 |
--------------------------------------------------------------------------------
/apps/app/lib/utils/hotjar.ts:
--------------------------------------------------------------------------------
1 | import Hotjar from '@hotjar/browser';
2 |
3 | const siteId = process.env.NEXT_PUBLIC_HOTJAR_SITE_ID;
4 | const hotjarVersion = process.env.NEXT_PUBLIC_HOTJAR_VERSION;
5 |
6 | const initHotjar = () => {
7 | if (siteId && hotjarVersion) {
8 | Hotjar.init(Number.parseInt(siteId), Number.parseInt(hotjarVersion));
9 | }
10 | };
11 |
12 | export default initHotjar;
13 |
--------------------------------------------------------------------------------
/apps/web/app/legal/(documents)/acceptable-use/content.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { LegalPage } from '@/app/components/LegalPage';
4 | import Content from './content.mdx';
5 |
6 | export default function AcceptableUseContent() {
7 | return (
8 | }
12 | />
13 | );
14 | }
15 |
--------------------------------------------------------------------------------
/packages/design-system/components/minime/client-only.tsx:
--------------------------------------------------------------------------------
1 | import { type ReactNode, useEffect, useState } from 'react';
2 |
3 | export default function ClientOnly({ children }: { children: ReactNode }) {
4 | const [clientReady, setClientReady] = useState(false);
5 |
6 | useEffect(() => {
7 | setClientReady(true);
8 | }, []);
9 |
10 | return clientReady ? children : null;
11 | }
12 |
--------------------------------------------------------------------------------
/packages/design-system/components/prose.tsx:
--------------------------------------------------------------------------------
1 | import type { ComponentProps } from 'react';
2 | import { cn } from '../lib/utils';
3 |
4 | type ProseProperties = ComponentProps<'div'>;
5 |
6 | export const Prose = ({ className, ...properties }: ProseProperties) => (
7 |
11 | );
12 |
--------------------------------------------------------------------------------
/apps/app/components/client-only.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { type ReactNode, useEffect, useState } from 'react';
4 |
5 | export const ClientOnly = ({ children }: { children: ReactNode }) => {
6 | const [clientReady, setClientReady] = useState(false);
7 |
8 | useEffect(() => {
9 | setClientReady(true);
10 | }, []);
11 |
12 | return clientReady ? <>{children}> : null;
13 | };
14 |
--------------------------------------------------------------------------------
/apps/app/hooks/use-token-counter.tsx:
--------------------------------------------------------------------------------
1 | import { encodingForModel } from 'js-tiktoken';
2 |
3 | export const useTokenCounter = () => {
4 | const getTokenCount = (message: string) => {
5 | const enc = encodingForModel('gpt-4o');
6 | if (message) {
7 | return enc.encode(message).length;
8 | }
9 | return undefined;
10 | };
11 |
12 | return {
13 | getTokenCount,
14 | };
15 | };
16 |
--------------------------------------------------------------------------------
/packages/analytics/posthog/server.ts:
--------------------------------------------------------------------------------
1 | import 'server-only';
2 | import { PostHog } from 'posthog-node';
3 | import { keys } from '../keys';
4 |
5 | export const analytics = new PostHog(keys().NEXT_PUBLIC_POSTHOG_KEY, {
6 | host: keys().NEXT_PUBLIC_POSTHOG_HOST,
7 |
8 | // Don't batch events and flush immediately - we're running in a serverless environment
9 | flushAt: 1,
10 | flushInterval: 0,
11 | });
12 |
--------------------------------------------------------------------------------
/packages/observability/instrumentation.ts:
--------------------------------------------------------------------------------
1 | import { init } from '@sentry/nextjs';
2 | import { keys } from './keys';
3 |
4 | const opts = {
5 | dsn: keys().NEXT_PUBLIC_SENTRY_DSN,
6 | };
7 |
8 | export const initializeSentry = () => {
9 | if (process.env.NEXT_RUNTIME === 'nodejs') {
10 | init(opts);
11 | }
12 |
13 | if (process.env.NEXT_RUNTIME === 'edge') {
14 | init(opts);
15 | }
16 | };
17 |
--------------------------------------------------------------------------------
/apps/app/public/icons/handdrawn_love.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/design-system/components/container.tsx:
--------------------------------------------------------------------------------
1 | import type { ComponentProps } from 'react';
2 | import { cn } from '../lib/utils';
3 |
4 | type ContainerProperties = ComponentProps<'div'>;
5 |
6 | export const Container = ({
7 | className,
8 | ...properties
9 | }: ContainerProperties) => (
10 |
14 | );
15 |
--------------------------------------------------------------------------------
/packages/design-system/components/ui/collapsible.tsx:
--------------------------------------------------------------------------------
1 | "use client"
2 |
3 | import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"
4 |
5 | const Collapsible = CollapsiblePrimitive.Root
6 |
7 | const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger
8 |
9 | const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent
10 |
11 | export { Collapsible, CollapsibleTrigger, CollapsibleContent }
12 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/resume/jobs/page.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from 'next';
2 | import { JobListingsCard } from '../components/jobs/job-listings-card';
3 |
4 | export const dynamic = 'force-dynamic';
5 |
6 | export const metadata: Metadata = {
7 | title: 'Open Studio | Jobs',
8 | description: 'Open Studio | Jobs',
9 | };
10 |
11 | export default function JobsPage() {
12 | return ;
13 | }
14 |
--------------------------------------------------------------------------------
/apps/app/modules/tube/automation/ui/views/automation-view.tsx:
--------------------------------------------------------------------------------
1 | import { AutomationTabsSection } from '@/modules/tube/automation/ui/sections/tabs-section';
2 |
3 | export const AutomationView = () => {
4 | return (
5 |
10 | );
11 | };
12 |
--------------------------------------------------------------------------------
/packages/mux/keys.ts:
--------------------------------------------------------------------------------
1 | import { createEnv } from '@t3-oss/env-nextjs';
2 | import { z } from 'zod';
3 |
4 | export const keys = () =>
5 | createEnv({
6 | server: {
7 | MUX_TOKEN_ID: z.string().min(1),
8 | MUX_TOKEN_SECRET: z.string().min(1),
9 | },
10 | runtimeEnv: {
11 | MUX_TOKEN_ID: process.env.MUX_TOKEN_ID,
12 | MUX_TOKEN_SECRET: process.env.MUX_TOKEN_SECRET,
13 | },
14 | });
15 |
--------------------------------------------------------------------------------
/apps/app/hooks/index.ts:
--------------------------------------------------------------------------------
1 | export * from '@/hooks/use-clipboard';
2 | export * from '@/hooks/use-assistant-utils';
3 | export * from '@/hooks/use-image-attachment';
4 | export * from '@/hooks/use-llm-test';
5 | export * from '@/hooks/use-record-voice';
6 | export * from '@/hooks/use-scroll-to-bottom';
7 | export * from '@/hooks/use-text-selection';
8 | export * from '@/hooks/use-tools';
9 | export * from '@/hooks/use-attachment';
10 |
--------------------------------------------------------------------------------
/packages/design-system/components/ui/placeholder-icon.tsx:
--------------------------------------------------------------------------------
1 | export type TPlaceholderIconProps = {
2 | size?: number;
3 | color?: string;
4 | className?: string;
5 | strokeWidth?: any;
6 | variant?: any;
7 | };
8 |
9 | export const PlaceholderIcon = ({
10 | size,
11 | color,
12 | className,
13 | strokeWidth,
14 | }: TPlaceholderIconProps) => {
15 | return ;
16 | };
--------------------------------------------------------------------------------
/apps/app/app/(unsubscribe)/unsubscribe/action.ts:
--------------------------------------------------------------------------------
1 | 'use server';
2 |
3 | import { deleteSubscriber } from '@/actions/subscribers';
4 |
5 | export async function unsubscribe(subId: string, userId: string) {
6 | try {
7 | await deleteSubscriber(subId, userId);
8 | return {
9 | success: 'Unsubscribed',
10 | };
11 | } catch (err) {
12 | return {
13 | error: 'Something went wrong',
14 | };
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/packages/email/keys.ts:
--------------------------------------------------------------------------------
1 | import { createEnv } from '@t3-oss/env-nextjs';
2 | import { z } from 'zod';
3 |
4 | export const keys = () =>
5 | createEnv({
6 | server: {
7 | RESEND_FROM: z.string().min(1).email(),
8 | RESEND_TOKEN: z.string().min(1).startsWith('re_'),
9 | },
10 | runtimeEnv: {
11 | RESEND_FROM: process.env.RESEND_FROM,
12 | RESEND_TOKEN: process.env.RESEND_TOKEN,
13 | },
14 | });
15 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 |
4 | # Maintain dependencies for GitHub Actions
5 | - package-ecosystem: "github-actions"
6 | directory: "/"
7 | open-pull-requests-limit: 10
8 | schedule:
9 | interval: "monthly"
10 |
11 | # Maintain dependencies for npm
12 | - package-ecosystem: "npm"
13 | directory: "/"
14 | open-pull-requests-limit: 10
15 | schedule:
16 | interval: "monthly"
17 |
--------------------------------------------------------------------------------
/apps/app/app/(user)/user/[domain]/components/nothing-placeholder.tsx:
--------------------------------------------------------------------------------
1 | export function NothingPlaceholder({ name }: { name?: string }) {
2 | return (
3 |
4 |
Nothing here yet
5 |
6 | It looks like {name} is still working on it.
7 |
8 |
9 | );
10 | }
11 |
--------------------------------------------------------------------------------
/apps/app/modules/tube/home/categories/server/procedures.ts:
--------------------------------------------------------------------------------
1 | import { baseProcedure, createTRPCRouter } from '@/trpc/init';
2 | import { database } from '@repo/backend/database';
3 | import { categories } from '@repo/backend/schema';
4 |
5 | export const categoriesRouter = createTRPCRouter({
6 | getMany: baseProcedure.query(async () => {
7 | const data = await database.select().from(categories);
8 | return data;
9 | }),
10 | });
11 |
--------------------------------------------------------------------------------
/packages/testing/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/testing",
3 | "version": "0.0.0",
4 | "private": true,
5 | "main": "./index.js",
6 | "type": "commonjs",
7 | "scripts": {
8 | "clean": "git clean -xdf .cache .turbo dist node_modules",
9 | "typecheck": "tsc --noEmit --emitDeclarationOnly false"
10 | },
11 | "devDependencies": {
12 | "@vitejs/plugin-react": "^4.3.4",
13 | "vitest": "^2.1.8"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/apps/app/app/api/trpc/[trpc]/route.ts:
--------------------------------------------------------------------------------
1 | import { createTRPCContext } from '@/trpc/init';
2 | import { appRouter } from '@/trpc/routers/_app';
3 | import { fetchRequestHandler } from '@trpc/server/adapters/fetch';
4 | const handler = (req: Request) =>
5 | fetchRequestHandler({
6 | endpoint: '/api/trpc',
7 | req,
8 | router: appRouter,
9 | createContext: createTRPCContext,
10 | });
11 | export { handler as GET, handler as POST };
12 |
--------------------------------------------------------------------------------
/apps/web/app/components/feature-hero/index.tsx:
--------------------------------------------------------------------------------
1 | import type { features } from '@/lib/features';
2 | import { FeatureHeroInner } from './feature-hero-inner';
3 |
4 | type FeatureHeroProperties = (typeof features)[keyof typeof features];
5 |
6 | export const FeatureHero = ({
7 | icon: Icon,
8 | ...properties
9 | }: FeatureHeroProperties) => (
10 |
11 |
12 |
13 | );
14 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/chat/components/feedback/use-feedback.tsx:
--------------------------------------------------------------------------------
1 | import { FeedbackModal } from '@/app/(organization)/chat/components/feedback/feedback-modal';
2 | import { useState } from 'react';
3 |
4 | export const useFeedback = () => {
5 | const [open, setOpen] = useState(false);
6 | const renderModal = () => {
7 | return ;
8 | };
9 | return { open, setOpen, renderModal };
10 | };
11 |
--------------------------------------------------------------------------------
/apps/app/hooks/use-navigation.tsx:
--------------------------------------------------------------------------------
1 | import { create } from 'zustand';
2 |
3 | interface NavigationState {
4 | isOpen: boolean;
5 | toggle: () => void;
6 | setOpen: (value: boolean) => void;
7 | }
8 | const useNavigation = create((set) => ({
9 | isOpen: false,
10 | toggle: () => set((state) => ({ isOpen: !state.isOpen })),
11 | setOpen: (value) => set(() => ({ isOpen: value })),
12 | }));
13 |
14 | export default useNavigation;
15 |
--------------------------------------------------------------------------------
/apps/web/app/legal/(documents)/terms/page.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from 'next';
2 | import TermsContent from './content';
3 |
4 | export const dynamic = 'force-dynamic';
5 |
6 | const title = 'Terms of Service - Open Studio';
7 | const description = 'Terms of Service - Open Studio';
8 |
9 | export const metadata: Metadata = {
10 | title,
11 | description,
12 | };
13 |
14 | export default function Page() {
15 | return ;
16 | }
17 |
--------------------------------------------------------------------------------
/packages/backend/migrations/0025_simple_cammi.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE "categories" (
2 | "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3 | "name" text NOT NULL,
4 | "description" text,
5 | "created_at" timestamp DEFAULT now() NOT NULL,
6 | "updated_at" timestamp DEFAULT now() NOT NULL,
7 | CONSTRAINT "categories_name_unique" UNIQUE("name")
8 | );
9 | --> statement-breakpoint
10 | CREATE UNIQUE INDEX "name_idx" ON "categories" USING btree ("name");
--------------------------------------------------------------------------------
/packages/tinybird/datasources/youtube_comment_reply_latest_oldest.datasource:
--------------------------------------------------------------------------------
1 | SCHEMA >
2 | `organization_id` String,
3 | `newest_comment_id` AggregateFunction(argMax, String, DateTime),
4 | `newest_comment_time` AggregateFunction(max, DateTime),
5 | `oldest_comment_id` AggregateFunction(argMin, String, DateTime),
6 | `oldest_comment_time` AggregateFunction(min, DateTime)
7 |
8 | ENGINE "AggregatingMergeTree"
9 | ENGINE_SORTING_KEY "organization_id"
--------------------------------------------------------------------------------
/packages/tinybird/datasources/youtube_comment_thread_latest_oldest.datasource:
--------------------------------------------------------------------------------
1 | SCHEMA >
2 | `organization_id` String,
3 | `newest_comment_id` AggregateFunction(argMax, String, DateTime),
4 | `newest_comment_time` AggregateFunction(max, DateTime),
5 | `oldest_comment_id` AggregateFunction(argMin, String, DateTime),
6 | `oldest_comment_time` AggregateFunction(min, DateTime)
7 |
8 | ENGINE "AggregatingMergeTree"
9 | ENGINE_SORTING_KEY "organization_id"
--------------------------------------------------------------------------------
/apps/app/app/(organization)/minime/components/layout/app-shell.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from '@repo/design-system/lib/utils';
2 | import type React from 'react';
3 |
4 | interface Props extends React.HTMLAttributes {}
5 |
6 | export default function AppShell({ children, className, ...props }: Props) {
7 | return (
8 |
9 | {children}
10 |
11 | );
12 | }
13 |
--------------------------------------------------------------------------------
/apps/app/hooks/use-app-command.tsx:
--------------------------------------------------------------------------------
1 | import { create } from 'zustand';
2 |
3 | interface AppCommandState {
4 | isOpen: boolean;
5 | toggle: () => void;
6 | setOpen: (value: boolean) => void;
7 | }
8 | const useAppCommand = create((set) => ({
9 | isOpen: false,
10 | toggle: () => set((state) => ({ isOpen: !state.isOpen })),
11 | setOpen: (value) => set(() => ({ isOpen: value })),
12 | }));
13 |
14 | export default useAppCommand;
15 |
--------------------------------------------------------------------------------
/apps/app/modules/tube/studio/ui/views/video-view.tsx:
--------------------------------------------------------------------------------
1 | import { FormSection } from '../sections/form-section';
2 |
3 | interface PageProps {
4 | videoId: string;
5 | }
6 |
7 | export const VideoView = ({ videoId }: PageProps) => {
8 | return (
9 |
14 | );
15 | };
16 |
--------------------------------------------------------------------------------
/apps/web/app/legal/(documents)/privacy/page.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from 'next';
2 | import PrivacyContent from './content';
3 |
4 | export const dynamic = 'force-dynamic';
5 |
6 | const title = 'Privacy Policy - Open Studio';
7 | const description = 'Privacy Policy - Open Studio';
8 |
9 | export const metadata: Metadata = {
10 | title,
11 | description,
12 | };
13 |
14 | export default function Page() {
15 | return ;
16 | }
17 |
--------------------------------------------------------------------------------
/apps/app/app/api/history/route.ts:
--------------------------------------------------------------------------------
1 | import { getChatsByUserId } from '@/lib/queries';
2 | import { currentUser } from '@repo/backend/auth/utils';
3 | import { NextResponse } from 'next/server';
4 |
5 | export async function GET() {
6 | const user = await currentUser();
7 |
8 | if (!user) return new Response('Unauthorized', { status: 401 });
9 |
10 | const chats = await getChatsByUserId({ id: user.id });
11 |
12 | return NextResponse.json(chats);
13 | }
14 |
--------------------------------------------------------------------------------
/apps/app/components/billing/check-and-redirect-for-upgrade.tsx:
--------------------------------------------------------------------------------
1 | import { env } from '@/env';
2 | import { redirect } from 'next/navigation';
3 |
4 | export async function checkAndRedirectForUpgrade() {
5 | if (!env.NEXT_PUBLIC_WELCOME_UPGRADE_ENABLED) return;
6 |
7 | // const [data] = await trpc.user.getPremium.
8 | // const {premium} = data;
9 |
10 | // if(premium.lemon_squeezy_renews_at !== null) return;
11 |
12 | redirect('/welcome-upgrade');
13 | }
14 |
--------------------------------------------------------------------------------
/apps/app/lib/sharp.ts:
--------------------------------------------------------------------------------
1 | import sharp from 'sharp';
2 |
3 | export async function getBlurDataURL(src?: string, url?: string) {
4 | const res = await fetch(url ?? `${process.env.NEXT_PUBLIC_URL}${src}`);
5 | const buffer = await res.arrayBuffer();
6 | const { data } = await sharp(buffer)
7 | .resize(10)
8 | .png({ quality: 30 })
9 | .toBuffer({ resolveWithObject: true });
10 |
11 | return `data:image/png;base64,${data.toString('base64')}`;
12 | }
13 |
--------------------------------------------------------------------------------
/apps/web/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "@repo/typescript-config/nextjs.json",
4 | // "@repo/cms/typescript-config.json"
5 | ],
6 | "compilerOptions": {
7 | "baseUrl": ".",
8 | "paths": {
9 | "@/*": ["./*"],
10 | "@repo/*": ["../../packages/*"]
11 | }
12 | },
13 | "include": [
14 | "next-env.d.ts",
15 | "next.config.ts",
16 | "**/*.ts",
17 | "**/*.tsx",
18 | ".next/types/**/*.ts"
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/apps/api/next.config.ts:
--------------------------------------------------------------------------------
1 | import { config } from '@repo/next-config';
2 | import { withLogtail } from '@repo/observability/next-config';
3 | import type { NextConfig } from 'next';
4 |
5 | const nextConfig: NextConfig = withLogtail({ ...config });
6 |
7 | // if (env.VERCEL) {
8 | // nextConfig = withSentry(nextConfig);
9 | // }
10 |
11 | // if (env.ANALYZE === 'true') {
12 | // nextConfig = withAnalyzer(nextConfig);
13 | // }
14 |
15 | export default nextConfig;
16 |
--------------------------------------------------------------------------------
/packages/webhooks/keys.ts:
--------------------------------------------------------------------------------
1 | import { createEnv } from '@t3-oss/env-nextjs';
2 | import { z } from 'zod';
3 |
4 | export const keys = () =>
5 | createEnv({
6 | server: {
7 | SVIX_TOKEN: z
8 | .union([
9 | z.string().min(1).startsWith('sk_'),
10 | z.string().min(1).startsWith('testsk_'),
11 | ])
12 | .optional(),
13 | },
14 | runtimeEnv: {
15 | SVIX_TOKEN: process.env.SVIX_TOKEN,
16 | },
17 | });
18 |
--------------------------------------------------------------------------------
/packages/backend/drizzle.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'drizzle-kit';
2 | import { keys } from './keys';
3 |
4 | export default defineConfig({
5 | schema: './schema.ts',
6 | out: './migrations',
7 | dialect: 'postgresql',
8 | dbCredentials: {
9 | database: 'postgres',
10 | port: 5432,
11 | host: keys().POSTGRES_DATABASE_HOST,
12 | user: keys().POSTGRES_DATABASE_USER,
13 | password: keys().POSTGRES_DATABASE_PASSWORD,
14 | },
15 | });
16 |
--------------------------------------------------------------------------------
/packages/design-system/components/precomposed/skeleton.tsx:
--------------------------------------------------------------------------------
1 | import type { ComponentProps } from 'react';
2 | import { cn } from '../../lib/utils';
3 | import { Skeleton as ShadcnSkeleton } from '../ui/skeleton';
4 |
5 | type SkeletonProps = ComponentProps;
6 |
7 | export const Skeleton = ({ className, ...props }: SkeletonProps) => {
8 | return (
9 |
10 | );
11 | };
12 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/chat/components/settings/models/api-key-info.tsx:
--------------------------------------------------------------------------------
1 | import { Flex } from '@repo/design-system/components/ui/flex';
2 | import { Type } from '@repo/design-system/components/ui/text';
3 |
4 | export const ApiKeyInfo = () => {
5 | return (
6 |
7 |
8 |
9 |
10 | );
11 | };
12 |
--------------------------------------------------------------------------------
/packages/tinybird/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/tinybird",
3 | "version": "0.0.1",
4 | "description": "",
5 | "main": "src/index.ts",
6 | "keywords": [],
7 | "author": "kuluruvineeth",
8 | "license": "ISC",
9 | "dependencies": {
10 | "@chronark/zod-bird": "^0.3.9",
11 | "zod": "^3.23.8"
12 | },
13 | "devDependencies": {
14 | "@repo/typescript-config": "workspace:*",
15 | "@types/node": "^20",
16 | "typescript": "^5.4.5"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/apps/app/lib/utils/error.ts:
--------------------------------------------------------------------------------
1 | export type ActionError> = {
2 | error: string;
3 | } & E;
4 | export type ServerActionResponse<
5 | T,
6 | E extends object = Record,
7 | > = ActionError | T;
8 |
9 | // biome-ignore lint/suspicious/noExplicitAny:
10 | export function isActionError(error: any): error is ActionError {
11 | return error && typeof error === 'object' && 'error' in error && error.error;
12 | }
13 |
--------------------------------------------------------------------------------
/packages/ai/components/thread.tsx:
--------------------------------------------------------------------------------
1 | import type { HTMLAttributes } from 'react';
2 | import { twMerge } from 'tailwind-merge';
3 |
4 | type ThreadProps = HTMLAttributes;
5 |
6 | export const Thread = ({ children, className, ...props }: ThreadProps) => (
7 |
14 | {children}
15 |
16 | );
17 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/chat/components/settings/setting-card.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from '@repo/design-system/lib/utils';
2 | import type { ReactNode } from 'react';
3 |
4 | export type TSettingCard = {
5 | children: ReactNode;
6 | className?: string;
7 | };
8 |
9 | export const SettingCard = ({ children, className }: TSettingCard) => {
10 | return (
11 |
12 | {children}
13 |
14 | );
15 | };
16 |
--------------------------------------------------------------------------------
/apps/web/app/legal/(documents)/acceptable-use/page.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from 'next';
2 | import AcceptableUseContent from './content';
3 |
4 | export const dynamic = 'force-dynamic';
5 |
6 | const title = 'Acceptable Use Policy - Open Studio';
7 | const description = 'Acceptable Use Policy - Open Studio';
8 |
9 | export const metadata: Metadata = {
10 | title,
11 | description,
12 | };
13 |
14 | export default function Page() {
15 | return ;
16 | }
17 |
--------------------------------------------------------------------------------
/packages/payments/keys.ts:
--------------------------------------------------------------------------------
1 | import { createEnv } from '@t3-oss/env-nextjs';
2 | import { z } from 'zod';
3 |
4 | export const keys = () =>
5 | createEnv({
6 | server: {
7 | LEMON_SQUEEZY_API_KEY: z.string().min(1),
8 | LEMON_SQUEEZY_SIGNING_SECRET: z.string().min(1),
9 | },
10 | runtimeEnv: {
11 | LEMON_SQUEEZY_API_KEY: process.env.LEMON_SQUEEZY_API_KEY,
12 | LEMON_SQUEEZY_SIGNING_SECRET: process.env.LEMON_SQUEEZY_SIGNING_SECRET,
13 | },
14 | });
15 |
--------------------------------------------------------------------------------
/apps/app/helper/preset-prompt-values.ts:
--------------------------------------------------------------------------------
1 | import moment from 'moment';
2 |
3 | const presetValues = {
4 | '{{local_date}}': moment().format('YYYY-MM-DD'),
5 | '{{local_time}}': moment().format('HH:mm:ss'),
6 | '{{local_datetime}}': moment().format('YYYY-MM-DD HH:mm:ss'),
7 | };
8 |
9 | export const injectPresetValues = (prompt: string) => {
10 | return prompt.replace(
11 | /{{.*?}}/g,
12 | (match) => presetValues?.[match as keyof typeof presetValues] || match
13 | );
14 | };
15 |
--------------------------------------------------------------------------------
/packages/testing/index.js:
--------------------------------------------------------------------------------
1 | const path = require('node:path');
2 | const react = require('@vitejs/plugin-react');
3 | const { defineConfig } = require('vitest/config');
4 |
5 | const config = defineConfig({
6 | plugins: [react()],
7 | test: {
8 | environment: 'jsdom',
9 | },
10 | resolve: {
11 | alias: {
12 | '@': path.resolve(__dirname, './'),
13 | '@repo': path.resolve(__dirname, '../../packages'),
14 | },
15 | },
16 | });
17 |
18 | module.exports = config;
19 |
--------------------------------------------------------------------------------
/apps/app/modules/tube/comments/ui/views/comment-view.tsx:
--------------------------------------------------------------------------------
1 | import { CommentSection } from '@/modules/tube/comments/ui/sections/comment-section';
2 |
3 | export const CommentView = ({
4 | organizationId,
5 | }: {
6 | organizationId: string;
7 | }) => {
8 | return (
9 |
14 | );
15 | };
16 |
--------------------------------------------------------------------------------
/biome.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
3 | "extends": ["ultracite"],
4 | "javascript": {
5 | "globals": ["Liveblocks"]
6 | },
7 | "files": {
8 | "ignore": [
9 | "packages/design-system/components/ui/**",
10 | "packages/design-system/lib/**",
11 | "packages/design-system/hooks/**",
12 | "packages/collaboration/config.ts",
13 | "apps/docs/**/*.json",
14 | "apps/email/.react-email/**"
15 | ]
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/packages/design-system/providers/theme.tsx:
--------------------------------------------------------------------------------
1 | import type { ThemeProviderProps } from 'next-themes';
2 | import { ThemeProvider as NextThemeProvider } from 'next-themes';
3 |
4 | export const ThemeProvider = ({
5 | children,
6 | ...properties
7 | }: ThemeProviderProps) => (
8 |
15 | {children}
16 |
17 | );
18 |
--------------------------------------------------------------------------------
/packages/payments/ai.ts:
--------------------------------------------------------------------------------
1 | import { StripeAgentToolkit } from '@stripe/agent-toolkit/ai-sdk';
2 | import { keys } from './keys';
3 |
4 | export const paymentsAgentToolkit = new StripeAgentToolkit({
5 | secretKey: keys().STRIPE_SECRET_KEY,
6 | configuration: {
7 | actions: {
8 | paymentLinks: {
9 | create: true,
10 | },
11 | products: {
12 | create: true,
13 | },
14 | prices: {
15 | create: true,
16 | },
17 | },
18 | },
19 | });
20 |
--------------------------------------------------------------------------------
/packages/seo/json-ld.tsx:
--------------------------------------------------------------------------------
1 | import type { Thing, WithContext } from 'schema-dts';
2 |
3 | type JsonLdProps = {
4 | code: WithContext;
5 | };
6 |
7 | export const JsonLd = ({ code }: JsonLdProps) => (
8 |
13 | );
14 |
15 | export * from 'schema-dts';
16 |
--------------------------------------------------------------------------------
/packages/storage/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/storage",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "clean": "git clean -xdf .cache .turbo dist node_modules",
7 | "typecheck": "tsc --noEmit --emitDeclarationOnly false"
8 | },
9 | "dependencies": {
10 | "@t3-oss/env-nextjs": "^0.11.1",
11 | "@vercel/blob": "^0.27.0",
12 | "zod": "^3.24.1"
13 | },
14 | "devDependencies": {
15 | "@repo/typescript-config": "workspace:*"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/minime/settings/layout.tsx:
--------------------------------------------------------------------------------
1 | import AppShell from '@/app/(organization)/minime/components/layout/app-shell';
2 | import SettingsNav from '@/app/(organization)/minime/components/layout/settings-nav';
3 | import type * as React from 'react';
4 |
5 | export default function SettingsLayout({
6 | children,
7 | }: {
8 | children: React.ReactNode;
9 | }) {
10 | return (
11 |
12 |
13 | {children}
14 |
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/apps/app/modules/tube/comments/ui/components/load-more-comments-button.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { Button } from '@repo/design-system/components/ui/button';
4 | import { BarChart2Icon } from 'lucide-react';
5 |
6 | export function LoadMoreCommentsButton() {
7 | return (
8 |
9 |
13 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/packages/design-system/components/loading.tsx:
--------------------------------------------------------------------------------
1 | import { Loader2Icon } from 'lucide-react';
2 |
3 | export function Loading() {
4 | return (
5 |
6 |
7 |
8 | );
9 | }
10 |
11 | export function LoadingMiniSpinner() {
12 | return ;
13 | }
14 |
15 | export function ButtonLoader() {
16 | return ;
17 | }
18 |
--------------------------------------------------------------------------------
/packages/webhooks/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/webhooks",
3 | "version": "0.0.0",
4 | "scripts": {
5 | "clean": "git clean -xdf .cache .turbo dist node_modules",
6 | "typecheck": "tsc --noEmit --emitDeclarationOnly false"
7 | },
8 | "dependencies": {
9 | "@t3-oss/env-nextjs": "^0.11.1",
10 | "svix": "^1.44.0",
11 | "zod": "^3.24.1"
12 | },
13 | "devDependencies": {
14 | "@repo/typescript-config": "workspace:*",
15 | "typescript": "^5.7.2"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/packages/backend/auth/format.ts:
--------------------------------------------------------------------------------
1 | import type { User } from '@supabase/supabase-js';
2 |
3 | export const getUserName = (user: User): string => {
4 | let name = user.id;
5 | const email = user.email;
6 |
7 | if (email) {
8 | name = email;
9 | }
10 |
11 | if (user.user_metadata.first_name) {
12 | name = user.user_metadata.first_name;
13 | }
14 |
15 | if (user.user_metadata.last_name) {
16 | name = `${name} ${user.user_metadata.last_name}`;
17 | }
18 |
19 | return name;
20 | };
21 |
--------------------------------------------------------------------------------
/packages/rate-limit/keys.ts:
--------------------------------------------------------------------------------
1 | import { createEnv } from '@t3-oss/env-nextjs';
2 | import { z } from 'zod';
3 |
4 | export const keys = () =>
5 | createEnv({
6 | server: {
7 | UPSTASH_REDIS_REST_URL: z.string().min(1).url().optional(),
8 | UPSTASH_REDIS_REST_TOKEN: z.string().min(1).optional(),
9 | },
10 | runtimeEnv: {
11 | UPSTASH_REDIS_REST_URL: process.env.UPSTASH_REDIS_REST_URL,
12 | UPSTASH_REDIS_REST_TOKEN: process.env.UPSTASH_REDIS_REST_TOKEN,
13 | },
14 | });
15 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/resume/resumes/[id]/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { ReactNode } from 'react';
2 |
3 | export default function ResumeEditorLayout({
4 | children,
5 | }: {
6 | children: ReactNode;
7 | }) {
8 | return (
9 |
10 | {/* Background Layer */}
11 | {/*
*/}
12 |
13 | {/* Content Layer */}
14 |
{children}
15 |
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/apps/app/context/react-query.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 | import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
3 | import type { ReactNode } from 'react';
4 |
5 | const queryClient = new QueryClient({
6 | defaultOptions: {
7 | queries: {
8 | retry: 1,
9 | },
10 | },
11 | });
12 |
13 | export const ReactQueryProvider = ({ children }: { children: ReactNode }) => {
14 | return (
15 | {children}
16 | );
17 | };
18 |
--------------------------------------------------------------------------------
/packages/tinybird/pipes/osav.pipe:
--------------------------------------------------------------------------------
1 | NODE total_analytics
2 | SQL >
3 | % SELECT
4 | count() as visits
5 | FROM osa
6 | WHERE 1=1
7 | {% if defined(userId) %}
8 | AND userId = {{userId}}
9 | {% end %}
10 | {% if defined(page) %}
11 | AND page = {{page}}
12 | {% end %}
13 | {% if defined(start) and defined(end) %}
14 | AND timestamp BETWEEN parseDateTimeBestEffort({{start}}) AND parseDateTimeBestEffort({{end}})
15 | {% end %}
--------------------------------------------------------------------------------
/packages/typescript-config/nextjs.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "Next.js",
4 | "extends": "./base.json",
5 | "compilerOptions": {
6 | "plugins": [{ "name": "next" }],
7 | "module": "ESNext",
8 | "moduleResolution": "Bundler",
9 | "allowJs": true,
10 | "jsx": "preserve",
11 | "noEmit": true,
12 | "paths": {
13 | "@/*": ["./*"],
14 | "@repo/*": ["../../packages/*"]
15 | }
16 | },
17 | "exclude": ["node_modules"]
18 | }
19 |
--------------------------------------------------------------------------------
/apps/api/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "declaration": false,
6 | "declarationMap": false,
7 | "emitDeclarationOnly": false,
8 | "noEmit": true,
9 | "paths": {
10 | "@/*": ["./*"],
11 | "@repo/*": ["../../packages/*"]
12 | }
13 | },
14 | "include": [
15 | "next-env.d.ts",
16 | "next.config.ts",
17 | "**/*.ts",
18 | "**/*.tsx",
19 | ".next/types/**/*.ts"
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/apps/web/app/robots.ts:
--------------------------------------------------------------------------------
1 | import { env } from '@/env';
2 | import type { MetadataRoute } from 'next';
3 |
4 | const protocol = env.VERCEL_PROJECT_PRODUCTION_URL?.startsWith('https')
5 | ? 'https'
6 | : 'http';
7 | const url = new URL(`${protocol}://${env.VERCEL_PROJECT_PRODUCTION_URL}`);
8 |
9 | export default function robots(): MetadataRoute.Robots {
10 | return {
11 | rules: {
12 | userAgent: '*',
13 | allow: '/',
14 | },
15 | sitemap: new URL('/sitemap.xml', url.href).href,
16 | };
17 | }
18 |
--------------------------------------------------------------------------------
/packages/backend/database.ts:
--------------------------------------------------------------------------------
1 | import 'server-only';
2 | import { createClient } from '@supabase/supabase-js';
3 | import { drizzle } from 'drizzle-orm/postgres-js';
4 | import postgres from 'postgres';
5 | import { keys } from './keys';
6 | import * as schema from './schema';
7 | const env = keys();
8 | const client = postgres(env.POSTGRES_DATABASE_URL, { prepare: false });
9 |
10 | export const database = drizzle(client, { schema });
11 |
12 | const supabase = createClient(env.SUPABASE_URL, env.SUPABASE_SERVICE_ROLE_KEY);
13 |
--------------------------------------------------------------------------------
/apps/web/app/legal/(documents)/layout.tsx:
--------------------------------------------------------------------------------
1 | import { Container } from '@repo/design-system/components/container';
2 | import { Prose } from '@repo/design-system/components/prose';
3 | import type { ReactNode } from 'react';
4 |
5 | type LegalLayoutProps = {
6 | children: ReactNode;
7 | };
8 |
9 | const LegalLayout = ({ children }: LegalLayoutProps) => (
10 |
11 | {children}
12 |
13 | );
14 |
15 | export default LegalLayout;
16 |
--------------------------------------------------------------------------------
/packages/lib/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/lib",
3 | "version": "0.0.0",
4 | "private": true,
5 | "exports": {
6 | "./*": "./src/*.ts"
7 | },
8 | "devDependencies": {
9 | "@repo/typescript-config": "workspace:*",
10 | "tailwindcss": "^3.4.17",
11 | "typescript": "^5.7.3"
12 | },
13 | "dependencies": {
14 | "fuse.js": "^7.0.0",
15 | "server-only": "^0.0.1",
16 | "slugify": "^1.6.6"
17 | },
18 | "peerDependencies": {
19 | "next": "15.1.3",
20 | "react": "19.0.0"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/settings/integrations/layout.tsx:
--------------------------------------------------------------------------------
1 | import { Prose } from '@repo/design-system/components/prose';
2 | import type { ReactElement } from 'react';
3 |
4 | type IntegrationsLayoutProperties = {
5 | readonly children: ReactElement;
6 | };
7 |
8 | const IntegrationsLayout = async ({
9 | children,
10 | }: IntegrationsLayoutProperties) => (
11 |
14 | );
15 |
16 | export default IntegrationsLayout;
17 |
--------------------------------------------------------------------------------
/apps/app/helper/tiptap-extensions.ts:
--------------------------------------------------------------------------------
1 | import { Extension } from '@tiptap/react';
2 |
3 | export const ShiftEnterToLineBreak = Extension.create({
4 | name: 'shiftEnterToLineBreak',
5 | addKeyboardShortcuts() {
6 | return {
7 | 'Shift-Enter': (_) => {
8 | return _.editor.commands.enter();
9 | },
10 | };
11 | },
12 | });
13 |
14 | export const DisableEnter = Extension.create({
15 | name: 'disableEnter',
16 | addKeyboardShortcuts() {
17 | return {
18 | Enter: () => true,
19 | };
20 | },
21 | });
22 |
--------------------------------------------------------------------------------
/packages/tinybird/pipes/get_youtube_comment_reply_latest_oldest_mv.pipe:
--------------------------------------------------------------------------------
1 | NODE youtube_reply_latest_oldest_mv
2 | SQL >
3 | SELECT
4 | organization_id,
5 | argMaxState(id, published_at) AS newest_comment_id,
6 | maxState(published_at) AS newest_comment_time,
7 | argMinState(id, published_at) AS oldest_comment_id,
8 | minState(published_at) AS oldest_comment_time
9 | FROM youtube_comment_replies
10 | GROUP BY organization_id
11 |
12 | TYPE materialized
13 | DATASOURCE youtube_comment_reply_latest_oldest
--------------------------------------------------------------------------------
/apps/app/modules/tube/comments/ui/components/comment-date.tsx:
--------------------------------------------------------------------------------
1 | import { formatShortDate } from '@/lib/utils';
2 | import { cn } from '@repo/design-system/lib/utils';
3 |
4 | export function CommentDate(props: { date: Date; className?: string }) {
5 | return (
6 |
12 | {formatShortDate(props.date, { includeYear: true, lowerCase: true })}
13 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/apps/app/public/icons/wavy.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apps/app/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@repo/typescript-config/nextjs.json",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "declaration": false,
6 | "declarationMap": false,
7 | "emitDeclarationOnly": false,
8 | "noEmit": true,
9 | "paths": {
10 | "@/*": ["./*"],
11 | "@repo/*": ["../../packages/*"]
12 | }
13 | },
14 | "include": [
15 | "next-env.d.ts",
16 | "next.config.ts",
17 | "**/*.ts",
18 | "**/*.tsx",
19 | ".next/types/**/*.ts",
20 | "trigger.config.ts"
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/packages/tinybird/pipes/get_youtube_comment_thread_latest_oldest_mv.pipe:
--------------------------------------------------------------------------------
1 | NODE youtube_thread_latest_oldest_mv
2 | SQL >
3 | SELECT
4 | organization_id,
5 | argMaxState(id, published_at) AS newest_comment_id,
6 | maxState(published_at) AS newest_comment_time,
7 | argMinState(id, published_at) AS oldest_comment_id,
8 | minState(published_at) AS oldest_comment_time
9 | FROM youtube_comment_threads
10 | GROUP BY organization_id
11 |
12 | TYPE materialized
13 | DATASOURCE youtube_comment_thread_latest_oldest
--------------------------------------------------------------------------------
/packages/mux/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/mux",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "clean": "git clean -xdf .cache .turbo dist node_modules",
7 | "typecheck": "tsc --noEmit --emitDeclarationOnly false"
8 | },
9 | "dependencies": {
10 | "@mux/mux-node": "^9.0.1",
11 | "@t3-oss/env-nextjs": "^0.11.1",
12 | "zod": "^3.24.1"
13 | },
14 | "devDependencies": {
15 | "@repo/typescript-config": "workspace:*",
16 | "@types/node": "^22.12.0",
17 | "typescript": "^5.7.2"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/chat/components/messages/image-message.tsx:
--------------------------------------------------------------------------------
1 | import Image from 'next/image';
2 |
3 | export type ImageMessageProps = {
4 | image?: string;
5 | };
6 |
7 | export const ImageMessage = ({ image }: ImageMessageProps) => {
8 | if (!image) return null;
9 | return (
10 |
18 | );
19 | };
20 |
--------------------------------------------------------------------------------
/apps/web/app/(home)/components/cta-button.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { Button } from '@repo/design-system/components/ui/button';
4 | import type { ButtonProps } from '@repo/design-system/components/ui/button';
5 | import { ArrowRightIcon } from 'lucide-react';
6 |
7 | export const CTAButton = ({ size, ...properties }: ButtonProps) => (
8 |
13 | );
14 |
--------------------------------------------------------------------------------
/packages/rate-limit/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/rate-limit",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "clean": "git clean -xdf .cache .turbo dist node_modules",
7 | "typecheck": "tsc --noEmit --emitDeclarationOnly false"
8 | },
9 | "dependencies": {
10 | "@t3-oss/env-nextjs": "^0.11.1",
11 | "@upstash/ratelimit": "^2.0.5",
12 | "@upstash/redis": "^1.34.3",
13 | "zod": "^3.24.1"
14 | },
15 | "devDependencies": {
16 | "@repo/typescript-config": "workspace:*",
17 | "typescript": "^5.7.2"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/apps/app/app/(user)/user/[domain]/components/about.tsx:
--------------------------------------------------------------------------------
1 | import MDX from '@/app/(organization)/minime/components/markdown/mdx';
2 |
3 | export default function About({ content }: { content?: string }) {
4 | if (!content?.trim()?.length) {
5 | return null;
6 | }
7 | return (
8 |
9 | -
10 |
About
11 |
12 | -
13 |
14 |
15 |
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/packages/next-config/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/next-config",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "clean": "git clean -xdf .cache .turbo dist node_modules",
7 | "typecheck": "tsc --noEmit --emitDeclarationOnly false"
8 | },
9 | "devDependencies": {
10 | "@repo/typescript-config": "workspace:*",
11 | "next": "15.1.3"
12 | },
13 | "dependencies": {
14 | "@next/bundle-analyzer": "^15.1.3",
15 | "@t3-oss/env-core": "^0.11.1",
16 | "@t3-oss/env-nextjs": "^0.11.1",
17 | "zod": "^3.24.1"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/artifacts/components/v2/overview.tsx:
--------------------------------------------------------------------------------
1 | import { motion } from 'framer-motion';
2 |
3 | export const Overview = () => {
4 | return (
5 |
13 |
14 |
15 | );
16 | };
17 |
--------------------------------------------------------------------------------
/apps/app/app/api/user/route.ts:
--------------------------------------------------------------------------------
1 | import { updateUsername } from '@/actions/users';
2 | import { updateUserSchema } from '@/helper/validator';
3 | import { guard } from '@/lib/auth';
4 |
5 | export const PATCH = guard(
6 | async ({ user, body }) => {
7 | try {
8 | await updateUsername(user, body.username!);
9 |
10 | return new Response(null, { status: 200 });
11 | } catch (err) {
12 | return new Response(JSON.stringify(err), { status: 500 });
13 | }
14 | },
15 | {
16 | schemas: {
17 | bodySchema: updateUserSchema,
18 | },
19 | }
20 | );
21 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/minime/components/layout/app-header.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from '@repo/design-system/lib/utils';
2 | import type React from 'react';
3 |
4 | interface Props extends React.HTMLAttributes {
5 | title?: string;
6 | }
7 |
8 | export default function AppHeader({ title, children, className }: Props) {
9 | return (
10 |
13 | {title &&
{title}
}
14 | {children}
15 |
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/apps/app/app/api/bookmarks/collections/route.ts:
--------------------------------------------------------------------------------
1 | import { createCollection } from '@/actions/collections';
2 | import { guard } from '@/lib/auth';
3 | import { collectionSchema } from '@/lib/validations/bookmark';
4 |
5 | export const POST = guard(
6 | async ({ user, body }) => {
7 | try {
8 | await createCollection(user.id, body);
9 | return new Response(null, { status: 200 });
10 | } catch (err) {
11 | return new Response(null, { status: 500 });
12 | }
13 | },
14 | {
15 | schemas: {
16 | bodySchema: collectionSchema,
17 | },
18 | }
19 | );
20 |
--------------------------------------------------------------------------------
/apps/app/app/api/feedback/route.ts:
--------------------------------------------------------------------------------
1 | import { type NextRequest, NextResponse } from 'next/server';
2 |
3 | export async function POST(req: NextRequest) {
4 | const { feedback, feedbackType, email } = await req.json();
5 | if (!feedback || !feedbackType) {
6 | return NextResponse.json({
7 | success: false,
8 | error: 'Feedback and feedback type are required',
9 | });
10 | }
11 | // await database.insert(feedbacks).values({
12 | // feedback,
13 | // feedbackType,
14 | // email,
15 | // });
16 |
17 | return NextResponse.json({ success: true });
18 | }
19 |
--------------------------------------------------------------------------------
/apps/app/config/user-page.ts:
--------------------------------------------------------------------------------
1 | import type { UserPageConfig } from '@/types/minime';
2 |
3 | export const userPageConfig: UserPageConfig = {
4 | pages: [
5 | {
6 | title: 'Home',
7 | href: '/',
8 | icon: 'home',
9 | },
10 | {
11 | title: 'Articles',
12 | href: '/articles',
13 | icon: 'edit',
14 | },
15 | {
16 | title: 'Projects',
17 | href: '/projects',
18 | icon: 'layers',
19 | },
20 | {
21 | title: 'Bookmarks',
22 | href: '/bookmarks',
23 | icon: 'bookmark',
24 | },
25 | ],
26 | } as const;
27 |
--------------------------------------------------------------------------------
/packages/tinybird/pipes/get_last_sync_metadata.pipe:
--------------------------------------------------------------------------------
1 | NODE get_last_sync_metadata_node
2 | SQL >
3 | %
4 | SELECT
5 | organization_id,
6 | channel_id,
7 | video_id,
8 | last_sync_time,
9 | oldest_comment_time,
10 | newest_comment_time,
11 | next_page_token,
12 | comments_synced,
13 | sync_status,
14 | error_message
15 | FROM youtube_comment_sync_metadata
16 | WHERE organization_id = {{String(organization_id)}}
17 | AND channel_id = {{String(channel_id)}}
18 | ORDER BY created_at DESC
19 | LIMIT 1
--------------------------------------------------------------------------------
/packages/youtube/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/youtube",
3 | "version": "0.0.0",
4 | "private": true,
5 | "dependencies": {
6 | "@repo/backend": "workspace:^",
7 | "@t3-oss/env-nextjs": "^0.11.1",
8 | "drizzle-orm": "^0.38.4",
9 | "google-auth-library": "^9.15.1",
10 | "googleapis": "^144.0.0",
11 | "zod": "^3.24.1"
12 | },
13 | "devDependencies": {
14 | "@repo/typescript-config": "workspace:*",
15 | "@types/node": "22.10.2",
16 | "@types/react": "19.0.2",
17 | "@types/react-dom": "^19.0.2",
18 | "typescript": "^5.7.3"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/apps/app/modules/tube/home/ui/views/tube-view.tsx:
--------------------------------------------------------------------------------
1 | import { TubeNavbar } from '@/modules/tube/home/ui/components/tube-navbar';
2 | import { CategoriesSection } from '@/modules/tube/home/ui/sections/categories-section';
3 |
4 | interface TubeViewProps {
5 | categoryId?: string;
6 | }
7 |
8 | export const TubeView = ({ categoryId }: TubeViewProps) => {
9 | return (
10 | <>
11 |
12 |
13 |
14 |
15 | >
16 | );
17 | };
18 |
--------------------------------------------------------------------------------
/packages/lib/src/slugify.ts:
--------------------------------------------------------------------------------
1 | import createSlug from 'slugify';
2 | import slug from 'slugify';
3 |
4 | export const slugify = (text: string): string =>
5 | createSlug(text, { lower: true, strict: true });
6 |
7 | export const slugifyLax = (text: string): string =>
8 | createSlug(text, {
9 | lower: true,
10 | strict: false,
11 | trim: false,
12 | remove: /@/g,
13 | });
14 |
15 | export function slugifyv2(title?: string) {
16 | if (title) {
17 | return slug(title, {
18 | strict: true,
19 | lower: true,
20 | });
21 | }
22 |
23 | return undefined;
24 | }
25 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/chat/terms/page.tsx:
--------------------------------------------------------------------------------
1 | import { Mdx } from '@/app/(organization)/chat/components/mdx';
2 | import { termsMdx } from '@/config/terms';
3 | import { Flex } from '@repo/design-system/components/ui/flex';
4 |
5 | export const dynamic = 'force-dynamic';
6 |
7 | const TermsPage = () => {
8 | return (
9 |
10 |
11 |
12 |
13 |
14 | );
15 | };
16 |
17 | export default TermsPage;
18 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: enhancement
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
--------------------------------------------------------------------------------
/apps/app/app/api/search/route.ts:
--------------------------------------------------------------------------------
1 | import { DuckDuckGoSearch } from '@langchain/community/tools/duckduckgo_search';
2 | import { type NextRequest, NextResponse } from 'next/server';
3 |
4 | export async function POST(req: NextRequest) {
5 | const { query } = await req.json();
6 | if (!query) {
7 | return Response.json({ error: 'No Query provided' }, { status: 401 });
8 | }
9 | const tool = new DuckDuckGoSearch({ maxResults: 5 });
10 | // Get the results of a query by calling .invoke on the tool.
11 | const results = await tool.invoke(query);
12 | return NextResponse.json({ results: results });
13 | }
14 |
--------------------------------------------------------------------------------
/apps/app/app/manifest.ts:
--------------------------------------------------------------------------------
1 | import type { MetadataRoute } from 'next';
2 |
3 | export default function manifest(): MetadataRoute.Manifest {
4 | return {
5 | name: 'OpenStudio - ChatHub',
6 | short_name: 'ChatHub',
7 | description:
8 | 'OpenStudio - App of Apps, Your gateway to AI Powered Applications',
9 | start_url: '/',
10 | display: 'standalone',
11 | background_color: '#fff',
12 | theme_color: '#1d1d1d',
13 | icons: [
14 | {
15 | src: '/icons/chathub.svg',
16 | sizes: 'any',
17 | type: 'image/svg+xml',
18 | },
19 | ],
20 | };
21 | }
22 |
--------------------------------------------------------------------------------
/packages/design-system/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "new-york",
4 | "rsc": true,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "../tailwind-config/config.ts",
8 | "css": "styles/globals.css",
9 | "baseColor": "neutral",
10 | "cssVariables": true
11 | },
12 | "aliases": {
13 | "components": "@repo/design-system/components",
14 | "utils": "@repo/design-system/lib/utils",
15 | "hooks": "@repo/design-system/hooks",
16 | "lib": "@repo/design-system/lib",
17 | "ui": "@repo/design-system/components/ui"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/packages/payments/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/payments",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "clean": "git clean -xdf .cache .turbo dist node_modules",
7 | "typecheck": "tsc --noEmit --emitDeclarationOnly false"
8 | },
9 | "dependencies": {
10 | "@lemonsqueezy/lemonsqueezy.js": "^4.0.0",
11 | "@stripe/agent-toolkit": "^0.2.0",
12 | "@t3-oss/env-nextjs": "^0.11.1",
13 | "zod": "^3.24.1"
14 | },
15 | "devDependencies": {
16 | "@repo/typescript-config": "workspace:*",
17 | "@types/node": "^22.12.0",
18 | "typescript": "^5.7.2"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/apps/app/app/(user)/user/[domain]/components/toggle.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import useNavigation from '@/hooks/use-navigation';
4 | import Button from '@repo/design-system/components/minime/button';
5 | import { Icons } from '@repo/design-system/components/ui/icons';
6 |
7 | export default function CommandMenuToggle() {
8 | const setOpen = useNavigation((state) => state.setOpen);
9 | return (
10 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/apps/app/lib/flags.ts:
--------------------------------------------------------------------------------
1 | import { currentUser } from '@repo/backend/auth/utils';
2 | import { flag } from 'flags/next';
3 |
4 | //TODO: Just placeholder for now
5 |
6 | export const tubeFlag = flag({
7 | key: 'tube-flag',
8 | defaultValue: false,
9 | async identify() {
10 | const user = await currentUser();
11 | return {
12 | user: { email: user?.email },
13 | };
14 | },
15 | decide({ entities }) {
16 | return false;
17 | },
18 | });
19 |
20 | export const integrationFlag = flag({
21 | key: 'integration-flag',
22 | defaultValue: false,
23 | decide() {
24 | return false;
25 | },
26 | });
27 |
--------------------------------------------------------------------------------
/apps/app/store/sessions/store.ts:
--------------------------------------------------------------------------------
1 | import type { TSessionsState } from '@/types';
2 | import { create } from 'zustand';
3 | import { devtools, persist } from 'zustand/middleware';
4 |
5 | const initialState = {
6 | activeSessionId: undefined,
7 | };
8 |
9 | export const createSessionsStore = () =>
10 | create()(
11 | devtools(
12 | persist(
13 | (set, get) => ({
14 | ...initialState,
15 | setActiveSessionId: (id: string) => set({ activeSessionId: id }),
16 | }),
17 | {
18 | name: 'active-session',
19 | }
20 | )
21 | )
22 | );
23 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/minime/components/articles/no-articles-placeholder.tsx:
--------------------------------------------------------------------------------
1 | import { EmptyPlaceholder } from '@repo/design-system/components/ui/empty-placeholder';
2 |
3 | export default function NoArticlesPlaceholder({
4 | description = false,
5 | }: {
6 | description?: boolean;
7 | }) {
8 | return (
9 |
10 | No articles here yet
11 | {description && (
12 |
13 | Write an article and publish.
14 |
15 | )}
16 |
17 | );
18 | }
19 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/(home)/components/greeting.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | type GreetingProps = {
4 | firstName: string | null;
5 | };
6 |
7 | export const Greeting = ({ firstName }: GreetingProps) => {
8 | const date = new Date();
9 | const hours = date.getHours();
10 | let noun = 'day';
11 |
12 | if (hours < 12) {
13 | noun = 'morning';
14 | } else if (hours < 18) {
15 | noun = 'afternoon';
16 | } else {
17 | noun = 'evening';
18 | }
19 |
20 | const greeting = firstName ? `Good ${noun}, ${firstName}` : `Good ${noun}`;
21 |
22 | return {greeting}
;
23 | };
24 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/minime/components/projects/no-projects-placeholder.tsx:
--------------------------------------------------------------------------------
1 | import { EmptyPlaceholder } from '@repo/design-system/components/ui/empty-placeholder';
2 |
3 | export default function NoProjectsPlaceholder({
4 | description = false,
5 | }: {
6 | description?: boolean;
7 | }) {
8 | return (
9 |
10 | No projects here yet
11 | {description && (
12 |
13 | Add the projects you want to share.
14 |
15 | )}
16 |
17 | );
18 | }
19 |
--------------------------------------------------------------------------------
/apps/app/app/(user)/user/[domain]/projects/[slug]/action.ts:
--------------------------------------------------------------------------------
1 | 'use server';
2 |
3 | import { getProjectById } from '@/actions/projects';
4 |
5 | export async function unlockProject(prev: any, data: FormData) {
6 | const projectId = data.get('projectId') as string;
7 | const pw = data.get('password') as string;
8 | const project = await getProjectById(projectId);
9 | if (!project) {
10 | return {
11 | error: 'Project not found',
12 | };
13 | }
14 |
15 | if (project[0].password === pw) {
16 | return {
17 | unlocked: true,
18 | };
19 | }
20 | return {
21 | error: 'Incorrect Password',
22 | };
23 | }
24 |
--------------------------------------------------------------------------------
/packages/design-system/components/top-bar.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from '@repo/design-system/lib/utils';
2 | import type React from 'react';
3 |
4 | interface TopBarProps {
5 | children: React.ReactNode;
6 | className?: string;
7 | sticky?: boolean;
8 | }
9 |
10 | export function TopBar({ children, className, sticky = false }: TopBarProps) {
11 | return (
12 |
19 | {children}
20 |
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/minime/components/bookmarks/no-bookmarks-placeholder.tsx:
--------------------------------------------------------------------------------
1 | import { EmptyPlaceholder } from '@repo/design-system/components/ui/empty-placeholder';
2 |
3 | export default function NoBookmarksPlaceholder({
4 | description = false,
5 | }: {
6 | description?: boolean;
7 | }) {
8 | return (
9 |
10 | No bookmarks here yet
11 | {description && (
12 |
13 | Share the links you find useful here.
14 |
15 | )}
16 |
17 | );
18 | }
19 |
--------------------------------------------------------------------------------
/packages/design-system/components/ui/full-page-loader.tsx:
--------------------------------------------------------------------------------
1 | import { Spinner } from '@repo/design-system/components/ui/loading-spinner';
2 | import { Type } from '@repo/design-system/components/ui/text';
3 |
4 | export type FullPageLoaderProps = {
5 | label?: string;
6 | };
7 |
8 | export const FullPageLoader = ({ label }: FullPageLoaderProps) => {
9 | return (
10 |
11 |
12 | {label && (
13 |
14 | {label}
15 |
16 | )}
17 |
18 | );
19 | };
--------------------------------------------------------------------------------
/packages/security/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/security",
3 | "version": "0.0.0",
4 | "private": true,
5 | "type": "module",
6 | "scripts": {
7 | "clean": "git clean -xdf .cache .turbo dist node_modules",
8 | "typecheck": "tsc --noEmit --emitDeclarationOnly false"
9 | },
10 | "dependencies": {
11 | "@arcjet/next": "1.0.0-alpha.34",
12 | "@nosecone/next": "1.0.0-alpha.34",
13 | "@repo/backend": "workspace:*",
14 | "@t3-oss/env-nextjs": "^0.11.1",
15 | "zod": "^3.24.1"
16 | },
17 | "devDependencies": {
18 | "@repo/typescript-config": "workspace:*",
19 | "typescript": "^5.7.2"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/turbo.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://turbo.build/schema.json",
3 | "globalDependencies": ["**/.env.*local"],
4 | "ui": "tui",
5 | "envMode": "loose",
6 | "tasks": {
7 | "build": {
8 | "dependsOn": ["^build", "test"],
9 | "outputs": [".next/**", "!.next/cache/**"]
10 | },
11 | "test": {
12 | "dependsOn": ["^test"]
13 | },
14 | "analyze": {
15 | "dependsOn": ["^analyze"]
16 | },
17 | "dev": {
18 | "cache": false,
19 | "persistent": true
20 | },
21 | "clean": {
22 | "cache": false
23 | },
24 | "//#clean": {
25 | "cache": false
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/resume/components/resume/editor/shared/LoadingFallback.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from '@repo/design-system/lib/utils';
2 |
3 | interface LoadingFallbackProps {
4 | lines?: number;
5 | className?: string;
6 | }
7 |
8 | export function LoadingFallback({
9 | lines = 2,
10 | className,
11 | }: LoadingFallbackProps) {
12 | return (
13 |
14 |
15 | {Array.from({ length: lines }).map((_, i) => (
16 |
17 | ))}
18 |
19 | );
20 | }
21 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/tube/automation/page.tsx:
--------------------------------------------------------------------------------
1 | import { AutomationView } from '@/modules/tube/automation/ui/views/automation-view';
2 | import { HydrateClient, trpc } from '@/trpc/server';
3 | import type { Metadata } from 'next';
4 |
5 | export const dynamic = 'force-dynamic';
6 |
7 | export const metadata: Metadata = {
8 | title: 'Open Studio Tube - AI Automation',
9 | description: 'Open Studio Tube - AI Automation',
10 | };
11 |
12 | export default async function AutomationPage() {
13 | void trpc.profile.getOne.prefetch();
14 | return (
15 |
16 |
17 |
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/packages/design-system/components/ui/stagger-container.tsx:
--------------------------------------------------------------------------------
1 | import { motion } from "framer-motion";
2 |
3 | const containerVariants = {
4 | hidden: { opacity: 0 },
5 | visible: {
6 | opacity: 1,
7 | transition: {
8 | staggerChildren: 0.1,
9 | },
10 | },
11 | };
12 |
13 | export const StaggerContainer = ({
14 | children,
15 | }: {
16 | children: React.ReactNode;
17 | }) => {
18 | return (
19 |
26 | {children}
27 |
28 | );
29 | };
--------------------------------------------------------------------------------
/packages/seo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/seo",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "clean": "git clean -xdf .cache .turbo dist node_modules",
7 | "typecheck": "tsc --noEmit --emitDeclarationOnly false"
8 | },
9 | "dependencies": {
10 | "lodash.merge": "^4.6.2",
11 | "react": "^19.0.0",
12 | "schema-dts": "^1.1.2"
13 | },
14 | "devDependencies": {
15 | "@repo/typescript-config": "workspace:*",
16 | "@types/lodash.merge": "^4.6.9",
17 | "@types/node": "22.10.2",
18 | "@types/react": "19.0.2",
19 | "@types/react-dom": "^19.0.2",
20 | "next": "15.1.3"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/apps/app/lib/validations/article.ts:
--------------------------------------------------------------------------------
1 | import * as z from 'zod';
2 |
3 | export const articleCreateSchema = z.object({
4 | title: z.string().min(1),
5 | content: z.string().optional(),
6 | });
7 |
8 | export const articlePatchSchema = z
9 | .object({
10 | slug: z.string().min(1),
11 | title: z.string().min(1).max(70),
12 | content: z.string(),
13 | seoTitle: z.string().max(60).nullable(),
14 | seoDescription: z.string().max(160).nullable(),
15 | ogImage: z.string().url().nullable(),
16 | published: z.boolean(),
17 | publishedAt: z.string().date(),
18 | canonicalURL: z.string().url().nullable(),
19 | })
20 | .partial();
21 |
--------------------------------------------------------------------------------
/apps/api/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 | .pnpm-debug.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
38 | # prisma
39 | .env
40 |
41 | # react.email
42 | .react-email
43 |
44 | # Sentry
45 | .sentryclirc
--------------------------------------------------------------------------------
/apps/app/tools/get-weather.ts:
--------------------------------------------------------------------------------
1 | import { tool } from '@repo/ai';
2 | import { z } from 'zod';
3 |
4 | export const getWeather = tool({
5 | description: 'Get the current weather at a location',
6 | parameters: z.object({
7 | latitude: z.number(),
8 | longitude: z.number(),
9 | }),
10 | execute: async ({ latitude, longitude }) => {
11 | const response = await fetch(
12 | `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}¤t=temperature_2m&hourly=temperature_2m&daily=sunrise,sunset&timezone=auto`
13 | );
14 |
15 | const weatherData = await response.json();
16 | return weatherData;
17 | },
18 | });
19 |
--------------------------------------------------------------------------------
/apps/web/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 | .pnpm-debug.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
38 | # prisma
39 | .env
40 |
41 | # react.email
42 | .react-email
43 |
44 | # Sentry
45 | .sentryclirc
46 |
--------------------------------------------------------------------------------
/packages/design-system/components/minime/badge.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from '@repo/design-system/lib/utils';
2 | import type * as React from 'react';
3 |
4 | export interface BadgeProps extends React.HTMLAttributes {}
5 |
6 | function Badge({ className, ...props }: BadgeProps) {
7 | return (
8 |
15 | );
16 | }
17 |
18 | export { Badge };
19 |
--------------------------------------------------------------------------------
/apps/app/lib/ai/tools/get-weather.ts:
--------------------------------------------------------------------------------
1 | import { tool } from '@repo/ai';
2 | import { z } from 'zod';
3 |
4 | export const getWeather = tool({
5 | description: 'Get the current weather at a location',
6 | parameters: z.object({
7 | latitude: z.number(),
8 | longitude: z.number(),
9 | }),
10 | execute: async ({ latitude, longitude }) => {
11 | const response = await fetch(
12 | `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}¤t=temperature_2m&hourly=temperature_2m&daily=sunrise,sunset&timezone=auto`
13 | );
14 |
15 | const weatherData = await response.json();
16 | return weatherData;
17 | },
18 | });
19 |
--------------------------------------------------------------------------------
/apps/app/modules/tube/studio/ui/views/studio-view.tsx:
--------------------------------------------------------------------------------
1 | import { VideoSection } from '@/modules/tube/studio/ui/sections/video-section';
2 |
3 | export const StudioView = () => {
4 | return (
5 |
6 |
7 |
8 |
Channel Content
9 |
10 | Manage your channel content and videos
11 |
12 |
13 |
14 |
15 |
16 | );
17 | };
18 |
--------------------------------------------------------------------------------
/apps/app/trpc/query-client.ts:
--------------------------------------------------------------------------------
1 | import {
2 | QueryClient,
3 | defaultShouldDehydrateQuery,
4 | } from '@tanstack/react-query';
5 | import superjson from 'superjson';
6 | export function makeQueryClient() {
7 | return new QueryClient({
8 | defaultOptions: {
9 | queries: {
10 | staleTime: 30 * 1000,
11 | },
12 | dehydrate: {
13 | serializeData: superjson.serialize,
14 | shouldDehydrateQuery: (query) =>
15 | defaultShouldDehydrateQuery(query) ||
16 | query.state.status === 'pending',
17 | },
18 | hydrate: {
19 | deserializeData: superjson.deserialize,
20 | },
21 | },
22 | });
23 | }
24 |
--------------------------------------------------------------------------------
/apps/storybook/.storybook/preview-head.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
18 |
--------------------------------------------------------------------------------
/packages/design-system/hooks/use-mobile.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react"
2 |
3 | const MOBILE_BREAKPOINT = 768
4 |
5 | export function useIsMobile() {
6 | const [isMobile, setIsMobile] = React.useState(undefined)
7 |
8 | React.useEffect(() => {
9 | const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
10 | const onChange = () => {
11 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
12 | }
13 | mql.addEventListener("change", onChange)
14 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
15 | return () => mql.removeEventListener("change", onChange)
16 | }, [])
17 |
18 | return !!isMobile
19 | }
20 |
--------------------------------------------------------------------------------
/packages/typescript-config/base.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "Default",
4 | "compilerOptions": {
5 | "declaration": true,
6 | "declarationMap": true,
7 | "esModuleInterop": true,
8 | "forceConsistentCasingInFileNames": true,
9 | "incremental": false,
10 | "isolatedModules": true,
11 | "lib": ["es2022", "DOM", "DOM.Iterable"],
12 | "module": "NodeNext",
13 | "moduleDetection": "force",
14 | "moduleResolution": "NodeNext",
15 | "resolveJsonModule": true,
16 | "skipLibCheck": true,
17 | "strict": true,
18 | "target": "ES2022",
19 | "strictNullChecks": true
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/apps/app/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 | .pnpm-debug.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
38 | # prisma
39 | .env
40 |
41 | # react.email
42 | .react-email
43 |
44 | # Sentry
45 | .sentryclirc
46 |
47 | .trigger
--------------------------------------------------------------------------------
/apps/app/app/(organization)/chat/privacy/page.tsx:
--------------------------------------------------------------------------------
1 | import { Mdx } from '@/app/(organization)/chat/components/mdx';
2 | import { privacyPolicy } from '@/config/privacy';
3 | import { Flex } from '@repo/design-system/components/ui/flex';
4 |
5 | export const dynamic = 'force-dynamic';
6 |
7 | const PrivacyPage = () => {
8 | return (
9 |
10 |
11 |
17 |
18 |
19 | );
20 | };
21 | export default PrivacyPage;
22 |
--------------------------------------------------------------------------------
/apps/app/hooks/use-intersection-observer.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef, useState } from 'react';
2 |
3 | export const useIntersectionObserver = (options?: IntersectionObserverInit) => {
4 | const targetRef = useRef(null);
5 | const [isIntersecting, setIsIntersecting] = useState(false);
6 |
7 | useEffect(() => {
8 | const observer = new IntersectionObserver(([entry]) => {
9 | setIsIntersecting(entry.isIntersecting);
10 | }, options);
11 |
12 | if (targetRef.current) {
13 | observer.observe(targetRef.current);
14 | }
15 |
16 | return () => observer.disconnect();
17 | }, [options]);
18 |
19 | return { targetRef, isIntersecting };
20 | };
21 |
--------------------------------------------------------------------------------
/apps/app/hooks/use-mobile.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | const MOBILE_BREAKPOINT = 768;
4 |
5 | export function useIsMobile() {
6 | const [isMobile, setIsMobile] = React.useState(
7 | undefined
8 | );
9 |
10 | React.useEffect(() => {
11 | const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
12 | const onChange = () => {
13 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
14 | };
15 | mql.addEventListener('change', onChange);
16 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
17 | return () => mql.removeEventListener('change', onChange);
18 | }, []);
19 |
20 | return !!isMobile;
21 | }
22 |
--------------------------------------------------------------------------------
/apps/app/public/icons/claude.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apps/web/app/components/LegalPage.tsx:
--------------------------------------------------------------------------------
1 | import { format, parseISO } from 'date-fns';
2 |
3 | export function LegalPage(props: {
4 | date: string;
5 | title: string;
6 | content: React.ReactNode;
7 | }) {
8 | const { date, title, content } = props;
9 |
10 | return (
11 |
12 |
13 |
16 |
{title}
17 |
18 | {content}
19 |
20 | );
21 | }
22 |
--------------------------------------------------------------------------------
/packages/analytics/index.tsx:
--------------------------------------------------------------------------------
1 | import type { ReactNode } from 'react';
2 | import { GoogleAnalytics } from './google';
3 | import { keys } from './keys';
4 | import { PostHogProvider } from './posthog/client';
5 | import { VercelAnalytics } from './vercel';
6 |
7 | type AnalyticsProviderProps = {
8 | readonly children: ReactNode;
9 | };
10 |
11 | const { NEXT_PUBLIC_GA_MEASUREMENT_ID } = keys();
12 |
13 | export const AnalyticsProvider = ({ children }: AnalyticsProviderProps) => (
14 |
15 | {children}
16 |
17 | {NEXT_PUBLIC_GA_MEASUREMENT_ID && (
18 |
19 | )}
20 |
21 | );
22 |
--------------------------------------------------------------------------------
/packages/observability/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/observability",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "clean": "git clean -xdf .cache .turbo dist node_modules",
7 | "typecheck": "tsc --noEmit --emitDeclarationOnly false"
8 | },
9 | "dependencies": {
10 | "@logtail/next": "^0.1.7",
11 | "@sentry/nextjs": "^8.47.0",
12 | "@t3-oss/env-nextjs": "^0.11.1",
13 | "react": "^19.0.0",
14 | "zod": "^3.24.1"
15 | },
16 | "devDependencies": {
17 | "@repo/typescript-config": "workspace:*",
18 | "@types/node": "22.10.2",
19 | "@types/react": "19.0.2",
20 | "@types/react-dom": "^19.0.2",
21 | "typescript": "^5.7.2"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/apps/app/app/api/bookmarks/export/route.ts:
--------------------------------------------------------------------------------
1 | import { getBookmarksExport } from '@/actions/bookmarks';
2 | import { guard } from '@/lib/auth';
3 |
4 | export const GET = guard(async ({ user }) => {
5 | try {
6 | const { filename, content } = await getBookmarksExport(user.id);
7 | return new Response(content, {
8 | headers: {
9 | 'Content-Type': 'application/csv',
10 | 'Content-Disposition': `attachment; filename=${filename}`,
11 | },
12 | });
13 | } catch (err) {
14 | if (err instanceof Error) {
15 | return new Response(JSON.stringify(err.message), { status: 500 });
16 | }
17 |
18 | return new Response(JSON.stringify(err), { status: 500 });
19 | }
20 | });
21 |
--------------------------------------------------------------------------------
/apps/app/app/api/subscribers/[id]/route.ts:
--------------------------------------------------------------------------------
1 | import { deleteSubscriber } from '@/actions/subscribers';
2 | import { guard } from '@/lib/auth';
3 | import * as z from 'zod';
4 |
5 | const routeContextSchema = z.object({
6 | params: z.object({
7 | id: z.string().min(1),
8 | }),
9 | });
10 |
11 | export const DELETE = guard(
12 | async ({ user, ctx }) => {
13 | try {
14 | const { id } = await ctx.params;
15 |
16 | await deleteSubscriber(id, user.id);
17 |
18 | return new Response(null, { status: 200 });
19 | } catch (err) {
20 | return new Response(null, { status: 500 });
21 | }
22 | },
23 | { requiredPlan: 'Pro', schemas: { contextSchema: routeContextSchema } }
24 | );
25 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/artifacts/page.tsx:
--------------------------------------------------------------------------------
1 | import { Chat } from '@/app/(organization)/artifacts/components/v2/chat';
2 | import { DataStreamHandler } from '@/app/(organization)/artifacts/components/v2/data-stream-handler';
3 | import { DEFAULT_CHAT_MODEL } from '@/lib/ai/model';
4 | import { generateUUID } from '@/lib/utils';
5 |
6 | export const dynamic = 'force-dynamic';
7 |
8 | export default async function ChatPage() {
9 | const id = generateUUID();
10 |
11 | return (
12 | <>
13 |
19 |
20 | >
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/apps/app/hooks/use-premium.tsx:
--------------------------------------------------------------------------------
1 | import { isPremium } from '@/lib/utils/premium';
2 | import { usePremiumQueries } from '@/services/premium/queries';
3 |
4 | export function usePremium() {
5 | const {
6 | premiumQuery,
7 | extendPremiumMutation,
8 | cancelPremiumMutation,
9 | upgradeToPremiumMutation,
10 | } = usePremiumQueries();
11 |
12 | const premium = !!(
13 | premiumQuery.data?.premium &&
14 | isPremium(premiumQuery.data.premium.lemon_squeezy_renews_at)
15 | );
16 |
17 | return {
18 | isPremium: premium,
19 | premium: premiumQuery.data?.premium,
20 | user: premiumQuery.data?.user,
21 | messagesCountPerMonth: premiumQuery.data?.messagesCountPerMonth,
22 | };
23 | }
24 |
--------------------------------------------------------------------------------
/apps/app/app/api/auth/callback/route.ts:
--------------------------------------------------------------------------------
1 | import { createClient } from '@repo/backend/auth/server';
2 | import { redirect } from 'next/navigation';
3 |
4 | export async function GET(request: Request) {
5 | const { searchParams } = new URL(request.url);
6 | const code = searchParams.get('code');
7 | // if "next" is in param, use it as the redirect URL
8 | const next = searchParams.get('next') ?? '/setup';
9 |
10 | if (code) {
11 | const supabase = await createClient();
12 | const { error } = await supabase.auth.exchangeCodeForSession(code);
13 | if (!error) {
14 | redirect(`${next}`);
15 | }
16 | }
17 |
18 | // return the user to an error page with instructions
19 | redirect('/error');
20 | }
21 |
--------------------------------------------------------------------------------
/apps/app/middleware.ts:
--------------------------------------------------------------------------------
1 | import { updateSession } from '@repo/backend/auth/middleware';
2 | import type { NextResponse } from 'next/server';
3 | import type { NextRequest } from 'next/server';
4 |
5 | export const middleware = async (request: NextRequest): Promise =>
6 | updateSession(request);
7 |
8 | // export const config = {
9 | // matcher: [
10 | // '/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
11 | // ],
12 | // };
13 |
14 | export const config = {
15 | matcher: [
16 | '/((?!_next/static|_next/image|favicon.ico|api/uploadthing|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
17 | // Always run for API routes
18 | // '/(api|trpc)(.*)',
19 | ],
20 | };
21 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/tube/studio/page.tsx:
--------------------------------------------------------------------------------
1 | import { DEFAULT_LIMIT } from '@/config/constants';
2 | import { StudioView } from '@/modules/tube/studio/ui/views/studio-view';
3 | import { HydrateClient } from '@/trpc/server';
4 | import { trpc } from '@/trpc/server';
5 | import type { Metadata } from 'next';
6 |
7 | export const dynamic = 'force-dynamic';
8 |
9 | export const metadata: Metadata = {
10 | title: 'Studio',
11 | description: 'Studio',
12 | };
13 |
14 | const Page = async () => {
15 | void trpc.studio.getMany.prefetchInfinite({
16 | limit: DEFAULT_LIMIT,
17 | });
18 | return (
19 |
20 |
21 |
22 | );
23 | };
24 |
25 | export default Page;
26 |
--------------------------------------------------------------------------------
/apps/app/modules/tube/videos/ui/components/video-banner.tsx:
--------------------------------------------------------------------------------
1 | import { AlertTriangleIcon } from 'lucide-react';
2 |
3 | import type { VideoGetOneOutput } from '../../types';
4 |
5 | interface VideoBannerProps {
6 | status: VideoGetOneOutput['muxStatus'];
7 | }
8 |
9 | export const VideoBanner = ({ status }: VideoBannerProps) => {
10 | if (status === 'ready') return null;
11 |
12 | return (
13 |
14 |
15 |
16 | This video is still being processed.
17 |
18 |
19 | );
20 | };
21 |
--------------------------------------------------------------------------------
/apps/app/modules/tube/videos/ui/views/video-view.tsx:
--------------------------------------------------------------------------------
1 | import { TubeNavbar } from '@/modules/tube/home/ui/components/tube-navbar';
2 | import { VideoSection } from '../sections/video-section';
3 |
4 | interface VideoViewProps {
5 | videoId: string;
6 | }
7 |
8 | export const VideoView = ({ videoId }: VideoViewProps) => {
9 | return (
10 |
20 | );
21 | };
22 |
--------------------------------------------------------------------------------
/apps/email/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "email",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "build": "email build",
7 | "dev": "email dev --port 3003",
8 | "export": "email export",
9 | "clean": "git clean -xdf .cache .turbo dist node_modules",
10 | "typecheck": "tsc --noEmit --emitDeclarationOnly false"
11 | },
12 | "dependencies": {
13 | "@react-email/components": "0.0.31",
14 | "@repo/email": "workspace:*",
15 | "react": "19.0.0",
16 | "react-email": "3.0.4"
17 | },
18 | "devDependencies": {
19 | "@repo/typescript-config": "workspace:*",
20 | "@types/node": "22.10.2",
21 | "@types/react": "19.0.2",
22 | "typescript": "^5.7.2"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/apps/storybook/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.*
7 | .yarn/*
8 | !.yarn/patches
9 | !.yarn/plugins
10 | !.yarn/releases
11 | !.yarn/versions
12 |
13 | # testing
14 | /coverage
15 |
16 | # next.js
17 | /.next/
18 | /out/
19 |
20 | # production
21 | /build
22 |
23 | # misc
24 | .DS_Store
25 | *.pem
26 |
27 | # debug
28 | npm-debug.log*
29 | yarn-debug.log*
30 | yarn-error.log*
31 |
32 | # env files (can opt-in for commiting if needed)
33 | .env*
34 |
35 | # vercel
36 | .vercel
37 |
38 | # typescript
39 | *.tsbuildinfo
40 | next-env.d.ts
41 |
42 | *storybook.log
43 |
44 | # storybook
45 | storybook-static/
--------------------------------------------------------------------------------
/packages/ai/components/message.tsx:
--------------------------------------------------------------------------------
1 | import type { Message as MessageType } from 'ai';
2 | import type { ComponentProps } from 'react';
3 | import Markdown from 'react-markdown';
4 | import { twMerge } from 'tailwind-merge';
5 |
6 | type MessageProps = {
7 | data: MessageType;
8 | markdown?: ComponentProps;
9 | };
10 |
11 | export const Message = ({ data, markdown }: MessageProps) => (
12 |
20 | {data.content}
21 |
22 | );
23 |
--------------------------------------------------------------------------------
/packages/analytics/keys.ts:
--------------------------------------------------------------------------------
1 | import { createEnv } from '@t3-oss/env-nextjs';
2 | import { z } from 'zod';
3 |
4 | export const keys = () =>
5 | createEnv({
6 | client: {
7 | NEXT_PUBLIC_POSTHOG_KEY: z.string().min(1).startsWith('phc_'),
8 | NEXT_PUBLIC_POSTHOG_HOST: z.string().min(1).url(),
9 | NEXT_PUBLIC_GA_MEASUREMENT_ID: z
10 | .string()
11 | .min(1)
12 | .startsWith('G-')
13 | .optional(),
14 | },
15 | runtimeEnv: {
16 | NEXT_PUBLIC_POSTHOG_KEY: process.env.NEXT_PUBLIC_POSTHOG_KEY,
17 | NEXT_PUBLIC_POSTHOG_HOST: process.env.NEXT_PUBLIC_POSTHOG_HOST,
18 | NEXT_PUBLIC_GA_MEASUREMENT_ID: process.env.NEXT_PUBLIC_GA_MEASUREMENT_ID,
19 | },
20 | });
21 |
--------------------------------------------------------------------------------
/packages/email/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/email",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "clean": "git clean -xdf .cache .turbo dist node_modules",
7 | "typecheck": "tsc --noEmit --emitDeclarationOnly false"
8 | },
9 | "dependencies": {
10 | "@react-email/components": "0.0.31",
11 | "@t3-oss/env-nextjs": "^0.11.1",
12 | "react": "^19.0.0",
13 | "react-dom": "^19.0.0",
14 | "resend": "^4.0.1",
15 | "zod": "^3.24.1"
16 | },
17 | "devDependencies": {
18 | "@repo/typescript-config": "workspace:*",
19 | "@types/node": "22.10.2",
20 | "@types/react": "19.0.2",
21 | "@types/react-dom": "^19.0.2",
22 | "typescript": "^5.7.2"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/packages/cms/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/cms",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "basehub dev",
7 | "build": "basehub",
8 | "analyze": "basehub",
9 | "clean": "git clean -xdf .cache .turbo dist node_modules",
10 | "typecheck": "tsc --noEmit --emitDeclarationOnly false"
11 | },
12 | "dependencies": {
13 | "@t3-oss/env-nextjs": "^0.11.1",
14 | "basehub": "^7.5.32",
15 | "react": "^19.0.0",
16 | "zod": "^3.24.1"
17 | },
18 | "devDependencies": {
19 | "@repo/typescript-config": "workspace:*",
20 | "@types/node": "22.10.2",
21 | "@types/react": "19.0.2",
22 | "@types/react-dom": "^19.0.2",
23 | "next": "15.1.3"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/packages/tailwind-config/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/tailwind-config",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "clean": "git clean -xdf .cache .turbo dist node_modules",
7 | "typecheck": "tsc --noEmit --emitDeclarationOnly false"
8 | },
9 | "dependencies": {
10 | "@tailwindcss/container-queries": "^0.1.1",
11 | "@tailwindcss/forms": "^0.5.10",
12 | "@tailwindcss/typography": "^0.5.15",
13 | "tailwind-merge": "^2.6.0",
14 | "tailwindcss-animate": "^1.0.7",
15 | "tailwindcss-safe-area": "^0.6.0",
16 | "uploadthing": "^7.4.4"
17 | },
18 | "devDependencies": {
19 | "@repo/typescript-config": "workspace:*",
20 | "tailwindcss": "^3.4.17"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/apps/app/hooks/use-copy-to-clipboard.tsx:
--------------------------------------------------------------------------------
1 | import { useCallback, useState } from 'react';
2 |
3 | type CopiedValue = string | null;
4 |
5 | type CopyFn = (text: string) => Promise;
6 |
7 | export function useCopyToClipboard(): [CopiedValue, CopyFn] {
8 | const [copiedText, setCopiedText] = useState(null);
9 |
10 | const copy: CopyFn = useCallback(async (text) => {
11 | if (!navigator?.clipboard) {
12 | return false;
13 | }
14 |
15 | try {
16 | await navigator.clipboard.writeText(text);
17 | setCopiedText(text);
18 | return true;
19 | } catch (error) {
20 | setCopiedText(null);
21 | return false;
22 | }
23 | }, []);
24 |
25 | return [copiedText, copy];
26 | }
27 |
--------------------------------------------------------------------------------
/apps/web/app/components/footer/footer-link.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { Link } from '@repo/design-system/components/link';
4 | import { cn } from '@repo/design-system/lib/utils';
5 | import { usePathname } from 'next/navigation';
6 |
7 | type FooterLinkProperties = {
8 | readonly href: string;
9 | readonly name: string;
10 | };
11 |
12 | export const FooterLink = ({ href, name }: FooterLinkProperties) => {
13 | const pathname = usePathname();
14 | const active = pathname === href;
15 |
16 | return (
17 |
24 | {name}
25 |
26 | );
27 | };
28 |
--------------------------------------------------------------------------------
/apps/web/env.ts:
--------------------------------------------------------------------------------
1 | import { keys as cms } from '@repo/cms/keys';
2 | import { keys as email } from '@repo/email/keys';
3 | import { keys as flags } from '@repo/feature-flags/keys';
4 | import { keys as core } from '@repo/next-config/keys';
5 | import { keys as observability } from '@repo/observability/keys';
6 | import { keys as rateLimit } from '@repo/rate-limit/keys';
7 | import { keys as security } from '@repo/security/keys';
8 | import { createEnv } from '@t3-oss/env-nextjs';
9 |
10 | export const env = createEnv({
11 | extends: [
12 | cms(),
13 | core(),
14 | email(),
15 | observability(),
16 | flags(),
17 | security(),
18 | rateLimit(),
19 | ],
20 | server: {},
21 | client: {},
22 | runtimeEnv: {},
23 | });
24 |
--------------------------------------------------------------------------------
/packages/design-system/components/ui/loading-dots.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from '@repo/design-system/lib/utils';
2 |
3 | interface LoadingDotsProps {
4 | className?: string;
5 | }
6 |
7 | export function LoadingDots({ className }: LoadingDotsProps) {
8 | return (
9 |
10 | {[...Array(3)].map((_, i) => (
11 |
20 | ))}
21 |
22 | );
23 | }
--------------------------------------------------------------------------------
/apps/storybook/stories/label.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Meta, StoryObj } from '@storybook/react';
2 |
3 | import { Label } from '@repo/design-system/components/ui/label';
4 |
5 | /**
6 | * Renders an accessible label associated with controls.
7 | */
8 | const meta = {
9 | title: 'ui/Label',
10 | component: Label,
11 | tags: ['autodocs'],
12 | argTypes: {
13 | children: {
14 | control: { type: 'text' },
15 | },
16 | },
17 | args: {
18 | children: 'Your email address',
19 | htmlFor: 'email',
20 | },
21 | } satisfies Meta;
22 |
23 | export default meta;
24 |
25 | type Story = StoryObj;
26 |
27 | /**
28 | * The default form of the label.
29 | */
30 | export const Default: Story = {};
31 |
--------------------------------------------------------------------------------
/packages/collaboration/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/collaboration",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "clean": "git clean -xdf .cache .turbo dist node_modules",
7 | "typecheck": "tsc --noEmit --emitDeclarationOnly false"
8 | },
9 | "dependencies": {
10 | "@t3-oss/env-nextjs": "^0.11.1",
11 | "@liveblocks/client": "^2.15.1",
12 | "@liveblocks/node": "^2.15.1",
13 | "@liveblocks/react": "^2.15.1",
14 | "react": "^19.0.0",
15 | "server-only": "^0.0.1",
16 | "zod": "^3.24.1"
17 | },
18 | "devDependencies": {
19 | "@repo/typescript-config": "workspace:*",
20 | "@types/node": "22.10.2",
21 | "@types/react": "19.0.2",
22 | "@types/react-dom": "^19.0.2"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/packages/design-system/components/ui/youtube-video.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import YouTube from "react-youtube";
3 | import { cn } from "@repo/design-system/lib/utils";
4 |
5 | export function YouTubeVideo(props: {
6 | videoId: string;
7 | iframeClassName?: string;
8 | className?: string;
9 | opts?: {
10 | height?: string;
11 | width?: string;
12 | playerVars?: {
13 | autoplay?: number;
14 | };
15 | };
16 | }) {
17 | return (
18 |
27 | );
28 | }
29 |
--------------------------------------------------------------------------------
/packages/tinybird/datasources/aiCall.datasource:
--------------------------------------------------------------------------------
1 | SCHEMA >
2 | `userId` String `json:$.userId`,
3 | `organizationId` String `json:$.organizationId`,
4 | `userEmail` String `json:$.userEmail`,
5 | `timestamp` Int64 `json:$.timestamp`,
6 | `totalTokens` UInt64 `json:$.totalTokens`,
7 | `completionTokens` UInt64 `json:$.completionTokens`,
8 | `promptTokens` UInt64 `json:$.promptTokens`,
9 | `cost` Float32 `json:$.cost`,
10 | `model` String `json:$.model`,
11 | `provider` String `json:$.provider`,
12 | `label` Nullable(String) `json:$.label`,
13 | `data` Nullable(String) `json:$.data`
14 |
15 | ENGINE "MergeTree"
16 | ENGINE_SORTING_KEY userId, timestamp
17 | ENGINE_PARTITION_KEY "toYYYYMM(fromUnixTimestamp64Milli(timestamp))"
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # Dependencies
4 | node_modules
5 | .pnp
6 | .pnp.js
7 |
8 | # Local env files
9 | .env
10 | .env.local
11 | .env.development.local
12 | .env.test.local
13 | .env.production.local
14 |
15 | # # Hugeicons
16 | # .npmrc
17 |
18 | # Testing
19 | coverage
20 |
21 | # Turbo
22 | .turbo
23 |
24 | # # Hugeicons
25 | # .npmrc
26 |
27 | # Vercel
28 | .vercel
29 |
30 | # Build Outputs
31 | .next/
32 | out/
33 | build
34 | dist
35 |
36 |
37 | # Debug
38 | npm-debug.log*
39 | yarn-debug.log*
40 | yarn-error.log*
41 |
42 | # Misc
43 | .DS_Store
44 | *.pem
45 |
46 | # Sentry Config File
47 | .env.sentry-build-plugin
48 |
49 | # BaseHub
50 | .basehub
51 |
52 | .trigger
--------------------------------------------------------------------------------
/apps/app/public/icons/groq.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apps/app/trpc/server.tsx:
--------------------------------------------------------------------------------
1 | import 'server-only'; // <-- ensure this file cannot be imported from the client
2 | import { createHydrationHelpers } from '@trpc/react-query/rsc';
3 | import { cache } from 'react';
4 | import { createCallerFactory, createTRPCContext } from './init';
5 | import { makeQueryClient } from './query-client';
6 | import { appRouter } from './routers/_app';
7 | // IMPORTANT: Create a stable getter for the query client that
8 | // will return the same client during the same request.
9 | export const getQueryClient = cache(makeQueryClient);
10 | const caller = createCallerFactory(appRouter)(createTRPCContext);
11 | export const { trpc, HydrateClient } = createHydrationHelpers(
12 | caller,
13 | getQueryClient
14 | );
15 |
--------------------------------------------------------------------------------
/packages/observability/error.ts:
--------------------------------------------------------------------------------
1 | import { captureException } from '@sentry/nextjs';
2 | import { log } from './log';
3 |
4 | export const parseError = (error: unknown): string => {
5 | let message = 'An error occurred';
6 |
7 | if (error instanceof Error) {
8 | message = error.message;
9 | } else if (error && typeof error === 'object' && 'message' in error) {
10 | message = error.message as string;
11 | } else {
12 | message = String(error);
13 | }
14 |
15 | try {
16 | captureException(error);
17 | log.error(`Parsing error: ${message}`);
18 | } catch (newError) {
19 | // biome-ignore lint/suspicious/noConsole: Need console here
20 | console.error('Error parsing error:', newError);
21 | }
22 |
23 | return message;
24 | };
25 |
--------------------------------------------------------------------------------
/packages/design-system/components/ui/audio-wave.tsx:
--------------------------------------------------------------------------------
1 | import lottie from 'lottie-web';
2 | import { useEffect, useRef } from 'react';
3 |
4 | export const AudioWaveSpinner = () => {
5 | const animationContainer = useRef(null);
6 | useEffect(() => {
7 | if (
8 | animationContainer.current &&
9 | animationContainer?.current?.childNodes?.length === 0
10 | ) {
11 | const player = lottie.loadAnimation({
12 | container: animationContainer.current,
13 | renderer: 'svg',
14 | loop: true,
15 | autoplay: true,
16 | path: '../lib/microphone.json',
17 | });
18 | }
19 | }, []);
20 | return (
21 |
22 | );
23 | };
24 |
--------------------------------------------------------------------------------
/apps/app/public/icons/perplexity.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/backend/migrations/0026_slippery_secret_warriors.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE "videos" (
2 | "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3 | "title" text NOT NULL,
4 | "description" text,
5 | "user_id" uuid NOT NULL,
6 | "organization_id" uuid NOT NULL,
7 | "created_at" timestamp DEFAULT now() NOT NULL,
8 | "updated_at" timestamp DEFAULT now() NOT NULL
9 | );
10 | --> statement-breakpoint
11 | ALTER TABLE "videos" ADD CONSTRAINT "videos_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "auth"."users"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
12 | ALTER TABLE "videos" ADD CONSTRAINT "videos_organization_id_organization_id_fk" FOREIGN KEY ("organization_id") REFERENCES "public"."organization"("id") ON DELETE cascade ON UPDATE no action;
--------------------------------------------------------------------------------
/packages/design-system/components/ui/bot-avatar.tsx:
--------------------------------------------------------------------------------
1 | import Avatar from "boring-avatars";
2 |
3 | export type TBotAvatar = {
4 | name: string;
5 | size: number;
6 | };
7 |
8 | export const BotAvatar = ({ name, size }: TBotAvatar) => {
9 | return (
10 |
27 | );
28 | };
--------------------------------------------------------------------------------
/apps/app/app/(organization)/chat/components/chat-input/image-dropzone-root.tsx:
--------------------------------------------------------------------------------
1 | import { ImageDropzone } from '@/app/(organization)/chat/components/chat-input/image-dropzone';
2 | import type { FC } from 'react';
3 | import type { DropzoneState } from 'react-dropzone';
4 |
5 | export type IImageDropzoneRootProps = {
6 | children: React.ReactNode;
7 | dropzoneProps: DropzoneState;
8 | };
9 |
10 | export const ImageDropzoneRoot: FC = ({
11 | children,
12 | dropzoneProps,
13 | }) => {
14 | return (
15 |
19 | {children}
20 |
21 |
22 | );
23 | };
24 |
--------------------------------------------------------------------------------
/apps/app/modules/tube/search/ui/views/search-view.tsx:
--------------------------------------------------------------------------------
1 | import { TubeNavbar } from '@/modules/tube/home/ui/components/tube-navbar';
2 | import { CategoriesSection } from '@/modules/tube/home/ui/sections/categories-section';
3 | import { ResultsSection } from '../sections/results-section';
4 |
5 | interface PageProps {
6 | query: string | undefined;
7 | categoryId: string | undefined;
8 | }
9 |
10 | export const SearchView = ({ query, categoryId }: PageProps) => {
11 | return (
12 | <>
13 |
14 |
15 |
16 |
17 |
18 | >
19 | );
20 | };
21 |
--------------------------------------------------------------------------------
/packages/design-system/components/logo.tsx:
--------------------------------------------------------------------------------
1 | import { PersonStanding } from 'lucide-react';
2 | import { cn } from '../lib/utils';
3 |
4 | type LogoProperties = {
5 | readonly showName?: boolean;
6 | readonly className?: string;
7 | };
8 |
9 | export const Logomark = ({ className }: { className?: string }) => (
10 |
11 | );
12 |
13 | export const Logo = ({ showName, className }: LogoProperties) => (
14 |
15 |
16 |
22 | Open Studio
23 |
24 |
25 | );
26 |
--------------------------------------------------------------------------------
/packages/analytics/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/analytics",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "clean": "git clean -xdf .cache .turbo dist node_modules",
7 | "typecheck": "tsc --noEmit --emitDeclarationOnly false"
8 | },
9 | "dependencies": {
10 | "@next/third-parties": "^15.1.3",
11 | "@t3-oss/env-nextjs": "^0.11.1",
12 | "@vercel/analytics": "^1.4.1",
13 | "posthog-js": "^1.203.2",
14 | "posthog-node": "^4.3.2",
15 | "react": "^19.0.0",
16 | "server-only": "^0.0.1",
17 | "zod": "^3.24.1"
18 | },
19 | "devDependencies": {
20 | "@repo/typescript-config": "workspace:*",
21 | "@types/node": "22.10.2",
22 | "@types/react": "19.0.2",
23 | "@types/react-dom": "^19.0.2"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/tube/studio/[videoId]/final_view/page.tsx:
--------------------------------------------------------------------------------
1 | import { HydrateClient, trpc } from '@/trpc/server';
2 |
3 | import { VideoView } from '@/modules/tube/videos/ui/views/video-view';
4 |
5 | import { DEFAULT_LIMIT } from '@/config/constants';
6 |
7 | interface PageProps {
8 | params: Promise<{
9 | videoId: string;
10 | }>;
11 | }
12 |
13 | const Page = async ({ params }: PageProps) => {
14 | const { videoId } = await params;
15 |
16 | void trpc.videos.getOne.prefetch({ id: videoId });
17 | void trpc.comments.getMany.prefetchInfinite({
18 | videoId,
19 | limit: DEFAULT_LIMIT,
20 | });
21 |
22 | return (
23 |
24 |
25 |
26 | );
27 | };
28 |
29 | export default Page;
30 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: bug
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **next-forge version**
14 | I am using version ...
15 |
16 | **To Reproduce**
17 | Steps to reproduce the behavior:
18 | 1. Go to '...'
19 | 2. Click on '....'
20 | 3. Scroll down to '....'
21 | 4. See error
22 |
23 | **Expected behavior**
24 | A clear and concise description of what you expected to happen.
25 |
26 | **Screenshots**
27 | If applicable, add screenshots to help explain your problem.
28 |
29 | **Desktop (please complete the following information):**
30 | - OS: [e.g. MacOS]
31 | - Browser [e.g. chrome v130, safari]
32 |
--------------------------------------------------------------------------------
/apps/app/components/billing/premium-modal.tsx:
--------------------------------------------------------------------------------
1 | import { Pricing } from '@/components/billing/pricing';
2 | import {
3 | Dialog,
4 | DialogContent,
5 | } from '@repo/design-system/components/ui/dialog';
6 | import { useCallback, useState } from 'react';
7 |
8 | export function usePremiumModal() {
9 | const [isOpen, setIsOpen] = useState(false);
10 |
11 | const openModal = () => setIsOpen(true);
12 |
13 | const PremiumModal = useCallback(() => {
14 | return (
15 |
20 | );
21 | }, [isOpen]);
22 |
23 | return {
24 | openModal,
25 | PremiumModal,
26 | };
27 | }
28 |
--------------------------------------------------------------------------------
/packages/ai/lib/provider.ts:
--------------------------------------------------------------------------------
1 | import { createAnthropic } from '@ai-sdk/anthropic';
2 | import { createOpenAI } from '@ai-sdk/openai';
3 |
4 | export const createProvider = (provider: string, apiKey: any) => {
5 | switch (provider) {
6 | case 'openai':
7 | return createOpenAI({
8 | apiKey: apiKey.key,
9 | compatibility: 'strict',
10 | baseURL: `https://gateway.ai.cloudflare.com/v1/b8a66f8a4ddbd419ef8e4bdfeea7aa60/chathub/openai`,
11 | });
12 | case 'anthropic':
13 | return createAnthropic({
14 | apiKey: apiKey.key,
15 | baseURL: `https://gateway.ai.cloudflare.com/v1/b8a66f8a4ddbd419ef8e4bdfeea7aa60/chathub/anthropic`,
16 | });
17 | default:
18 | throw new Error(`Provider ${provider} not supported`);
19 | }
20 | };
21 |
--------------------------------------------------------------------------------
/packages/feature-flags/access.ts:
--------------------------------------------------------------------------------
1 | import { type ApiData, verifyAccess } from '@vercel/flags';
2 | import { type NextRequest, NextResponse } from 'next/server';
3 | import * as flags from './index';
4 |
5 | export const getFlags = async (request: NextRequest) => {
6 | const access = await verifyAccess(request.headers.get('Authorization'));
7 |
8 | if (!access) {
9 | return NextResponse.json(null, { status: 401 });
10 | }
11 |
12 | const definitions = Object.fromEntries(
13 | Object.values(flags).map((flag) => [
14 | flag.key,
15 | {
16 | origin: flag.origin,
17 | description: flag.description,
18 | options: flag.options,
19 | },
20 | ])
21 | );
22 |
23 | return NextResponse.json({
24 | definitions,
25 | });
26 | };
27 |
--------------------------------------------------------------------------------
/packages/security/middleware.ts:
--------------------------------------------------------------------------------
1 | import {
2 | type NoseconeOptions,
3 | defaults,
4 | withVercelToolbar,
5 | } from '@nosecone/next';
6 | export { createMiddleware as noseconeMiddleware } from '@nosecone/next';
7 |
8 | // Nosecone security headers configuration
9 | // https://docs.arcjet.com/nosecone/quick-start
10 | export const noseconeOptions: NoseconeOptions = {
11 | ...defaults,
12 | // Content Security Policy (CSP) is disabled by default because the values
13 | // depend on which Next Forge features are enabled. See
14 | // https://docs.next-forge.com/features/security/headers for guidance on how
15 | // to configure it.
16 | contentSecurityPolicy: false,
17 | };
18 |
19 | export const noseconeOptionsWithToolbar: NoseconeOptions =
20 | withVercelToolbar(noseconeOptions);
21 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/tube/studio/[videoId]/page.tsx:
--------------------------------------------------------------------------------
1 | import { VideoView } from '@/modules/tube/studio/ui/views/video-view';
2 | import { HydrateClient, trpc } from '@/trpc/server';
3 |
4 | export const dynamic = 'force-dynamic';
5 |
6 | // export const metadata: Metadata = {
7 | // title: 'Studio',
8 | // description: 'Studio',
9 | // };
10 |
11 | interface PageProps {
12 | params: Promise<{ videoId: string }>;
13 | }
14 |
15 | const Page = async ({ params }: PageProps) => {
16 | const { videoId } = await params;
17 |
18 | void trpc.studio.getOne.prefetch({ id: videoId });
19 | void trpc.categories.getMany.prefetch();
20 |
21 | return (
22 |
23 |
24 |
25 | );
26 | };
27 |
28 | export default Page;
29 |
--------------------------------------------------------------------------------
/apps/app/app/not-found.tsx:
--------------------------------------------------------------------------------
1 | import { EmptyState } from '@/components/empty-state';
2 | import { Link } from '@repo/design-system/components/link';
3 | import { Button } from '@repo/design-system/components/ui/button';
4 | import { SearchIcon } from 'lucide-react';
5 |
6 | export const dynamic = 'force-dynamic';
7 |
8 | const NotFound = () => (
9 |
10 |
15 |
18 |
19 |
20 | );
21 |
22 | export default NotFound;
23 |
--------------------------------------------------------------------------------
/apps/app/config/prompts.ts:
--------------------------------------------------------------------------------
1 | const relatedQuestionsSystemPrompt = `You're an helpful assistant`;
2 |
3 | const relatedQuestionsUserPrompt = (message: string, response: string) => `
4 | Given the initial message and the AI's response, act as a user and determine what you would ask or answer next based on the AI's response.
5 | Initial Message: """ ${message} """
6 | AI Response: """ ${response} """
7 | What would your next 2-3 short questions or response be as a user?
8 | `;
9 |
10 | const googleSearchPrompt = (input: string, information: string) =>
11 | `Answer the following question based on the information provided. Question: ${input} \n\n Information: \n\n ${information}`;
12 |
13 | export {
14 | googleSearchPrompt,
15 | relatedQuestionsSystemPrompt,
16 | relatedQuestionsUserPrompt,
17 | };
18 |
--------------------------------------------------------------------------------
/apps/app/app/(user)/user/[domain]/components/watermark.tsx:
--------------------------------------------------------------------------------
1 | import type { User } from '@repo/backend/auth';
2 | import { Badge } from '@repo/design-system/components/ui/badge';
3 | import Link from 'next/link';
4 |
5 | export default async function Watermark({ user }: { user: Pick }) {
6 | // const plan = await currentUser();
7 | // TODO: add pro plan
8 | // if (plan?.user_metadata.isPro) {
9 | // return null;
10 | // }
11 | return (
12 |
17 |
18 | Powered by Open Studio Minime
19 |
20 |
21 | );
22 | }
23 |
--------------------------------------------------------------------------------
/apps/app/hooks/use-debounced-value.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from 'react';
2 |
3 | /**
4 | * A hook that returns a debounced version of a value.
5 | * The debounced value will only update after the specified delay has passed without any new updates.
6 | *
7 | * @param value The value to debounce
8 | * @param delay The delay in milliseconds
9 | * @returns The debounced value
10 | */
11 | export function useDebouncedValue(value: T, delay: number): T {
12 | const [debouncedValue, setDebouncedValue] = useState(value);
13 |
14 | useEffect(() => {
15 | const timer = setTimeout(() => {
16 | setDebouncedValue(value);
17 | }, delay);
18 |
19 | return () => {
20 | clearTimeout(timer);
21 | };
22 | }, [value, delay]);
23 |
24 | return debouncedValue;
25 | }
26 |
--------------------------------------------------------------------------------
/apps/app/lib/validations/bookmark.ts:
--------------------------------------------------------------------------------
1 | import { validDomainRegex } from '@/helper/utils';
2 | import { URLRegex } from '@repo/design-system/lib/utils';
3 | import * as z from 'zod';
4 |
5 | export const collectionSchema = z.object({
6 | name: z.string().min(1).max(20),
7 | });
8 |
9 | export const bookmarkSchema = z.object({
10 | title: z.string().min(1).max(30),
11 | url: z.string().url(),
12 | collection: z.string().min(1).nullable().optional(),
13 | });
14 |
15 | export const bookmarkFormSchema = z.object({
16 | title: z.string().min(1).max(30),
17 | domain: z
18 | .string()
19 | .refine(
20 | (value) => validDomainRegex.test(value) || URLRegex.test(value),
21 | 'Enter valid domain or URL'
22 | ),
23 | collection: z.string().min(1).nullable().optional(),
24 | });
25 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/chat/components/messages/index.tsx:
--------------------------------------------------------------------------------
1 | import { PreviousMessages } from '@/app/(organization)/chat/components/messages/previous-messages';
2 | import { RecentMessage } from '@/app/(organization)/chat/components/messages/recent-message';
3 | import { WelcomeMessage } from '@/app/(organization)/chat/components/welcome-message';
4 |
5 | export const ChatMessages = () => {
6 | return (
7 |
17 | );
18 | };
19 |
--------------------------------------------------------------------------------
/packages/jobs/trigger.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from '@trigger.dev/sdk/v3';
2 |
3 | export default defineConfig({
4 | project: process.env.TRIGGER_PROJECT_ID! || 'proj_tgvhxgalgrurgqijuxed',
5 | runtime: 'node',
6 | logLevel: 'log',
7 | // The max compute seconds a task is allowed to run. If the task run exceeds this duration, it will be stopped.
8 | // You can override this on an individual task.
9 | // See https://trigger.dev/docs/runs/max-duration
10 | maxDuration: 3600,
11 | retries: {
12 | enabledInDev: true,
13 | default: {
14 | maxAttempts: 3,
15 | minTimeoutInMs: 1000,
16 | maxTimeoutInMs: 10000,
17 | factor: 2,
18 | randomize: true,
19 | },
20 | },
21 | build: {
22 | external: ['sharp'],
23 | },
24 | dirs: ['tasks'],
25 | });
26 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/chat/components/messages/context-message.tsx:
--------------------------------------------------------------------------------
1 | import { ToolBadge } from '@/app/(organization)/chat/components/tools/tool-badge';
2 | import { QuoteUpSquareIcon } from '@hugeicons-pro/core-stroke-rounded';
3 | import { Flex } from '@repo/design-system/components/ui/flex';
4 | import { Type } from '@repo/design-system/components/ui/text';
5 |
6 | export type ContextMessageProps = {
7 | context?: string;
8 | };
9 |
10 | export const ContextMessage = ({ context }: ContextMessageProps) => {
11 | if (!context) return null;
12 | return (
13 |
14 |
15 |
16 | {context}
17 |
18 |
19 | );
20 | };
21 |
--------------------------------------------------------------------------------
/apps/web/app/styles/web.css:
--------------------------------------------------------------------------------
1 | .shiki {
2 | background-color: var(--shiki-light-bg);
3 | color: var(--shiki-light);
4 | @apply border-border;
5 | }
6 |
7 | .shiki span {
8 | color: var(--shiki-light);
9 | }
10 |
11 | .dark .shiki {
12 | background-color: var(--shiki-dark-bg);
13 | color: var(--shiki-dark);
14 | }
15 |
16 | .dark .shiki span {
17 | color: var(--shiki-dark);
18 | }
19 |
20 | .shiki code {
21 | display: grid;
22 | font-size: 13px;
23 | counter-reset: line;
24 | }
25 |
26 | .shiki .line:before {
27 | content: counter(line);
28 | counter-increment: line;
29 |
30 | @apply inline-block w-4 mr-8 text-muted-foreground text-right;
31 | }
32 |
33 | .shiki[title]:before {
34 | content: attr(title);
35 | @apply inline-block text-muted-foreground text-right mb-6 text-sm;
36 | }
37 |
--------------------------------------------------------------------------------
/apps/app/app/api/subscribers/export/route.ts:
--------------------------------------------------------------------------------
1 | import { getSubscibersExport } from '@/actions/subscribers';
2 | import { guard } from '@/lib/auth';
3 |
4 | export const GET = guard(
5 | async ({ user }) => {
6 | try {
7 | const { content, filename } = await getSubscibersExport(user.id);
8 |
9 | return new Response(content, {
10 | headers: {
11 | 'Content-Type': 'application/csv',
12 | 'Content-Disposition': `attachment; filename=${filename}`,
13 | },
14 | });
15 | } catch (err) {
16 | if (err instanceof Error) {
17 | return new Response(JSON.stringify(err.message), { status: 500 });
18 | }
19 |
20 | return new Response(JSON.stringify(err), { status: 500 });
21 | }
22 | },
23 | {
24 | requiredPlan: 'Pro',
25 | }
26 | );
27 |
--------------------------------------------------------------------------------
/apps/web/app/not-found.tsx:
--------------------------------------------------------------------------------
1 | import { EmptyState } from '@repo/design-system/components/empty-state';
2 | import { Link } from '@repo/design-system/components/link';
3 | import { Button } from '@repo/design-system/components/ui/button';
4 | import { SearchIcon } from 'lucide-react';
5 |
6 | export const dynamic = 'force-dynamic';
7 |
8 | const NotFound = () => (
9 |
10 |
15 |
18 |
19 |
20 | );
21 |
22 | export default NotFound;
23 |
--------------------------------------------------------------------------------
/apps/app/app/api/bookmarks/t/[id]/route.ts:
--------------------------------------------------------------------------------
1 | import { recordClick } from '@/lib/tinybird';
2 | import type { NextRequest } from 'next/server';
3 | import * as z from 'zod';
4 |
5 | // export const runtime = "edge";
6 |
7 | const routeContextSchema = z.object({
8 | params: z.object({
9 | id: z.string().min(1),
10 | }),
11 | });
12 |
13 | export async function GET(
14 | req: NextRequest,
15 | context: z.infer
16 | ) {
17 | const contextPromise = await context;
18 | const ctx = routeContextSchema.safeParse({
19 | params: {
20 | id: contextPromise.params.id,
21 | },
22 | });
23 | if (!ctx.success) {
24 | return new Response(ctx.error.issues[0].message, {
25 | status: 422,
26 | });
27 | }
28 |
29 | return recordClick(req, ctx.data.params.id);
30 | }
31 |
--------------------------------------------------------------------------------
/apps/app/store/preferences/store.ts:
--------------------------------------------------------------------------------
1 | import { defaultPreferences } from '@/config';
2 | import type { TApiKeys, TPreferences, TPreferencesState } from '@/types';
3 | import { create } from 'zustand';
4 |
5 | const initialState = {
6 | preferences: {
7 | id: '',
8 | organizationId: '',
9 | ...defaultPreferences,
10 | } satisfies TPreferences,
11 | apiKeys: [] as TApiKeys[],
12 | };
13 |
14 | export const createPreferencesStore = () =>
15 | create((set, get) => ({
16 | ...initialState,
17 | setPreferences: (preferences: Partial) => {
18 | const existingPreferences = get().preferences;
19 | set({ preferences: { ...existingPreferences, ...preferences } });
20 | },
21 | setApiKeys: (apiKeys: TApiKeys[]) => {
22 | set({ apiKeys });
23 | },
24 | }));
25 |
--------------------------------------------------------------------------------
/packages/design-system/components/toast.tsx:
--------------------------------------------------------------------------------
1 | import { Toaster as SonnerToaster, toast } from 'sonner';
2 |
3 | export function toastSuccess(options: { title?: string; description: string }) {
4 | return toast.success(options.title || 'Success', {
5 | description: options.description,
6 | });
7 | }
8 |
9 | export function toastError(options: { title?: string; description: string }) {
10 | return toast.error(options.title || 'Error', {
11 | description: options.description,
12 | duration: 10_000,
13 | });
14 | }
15 |
16 | export function toastInfo(options: {
17 | title: string;
18 | description: string;
19 | duration?: number;
20 | }) {
21 | return toast(options.title, {
22 | description: options.description,
23 | duration: options.duration,
24 | });
25 | }
26 |
27 | export const Toaster = SonnerToaster;
28 |
--------------------------------------------------------------------------------
/packages/lib/src/format.ts:
--------------------------------------------------------------------------------
1 | export const formatDate = (date: Date): string =>
2 | new Intl.DateTimeFormat('en-US', {
3 | month: 'short',
4 | day: 'numeric',
5 | year: 'numeric',
6 | timeZone: 'America/New_York',
7 | }).format(date);
8 |
9 | export const capitalize = (input: string): string => {
10 | if (input === 'ai') {
11 | return input.toUpperCase();
12 | }
13 |
14 | return input.charAt(0).toUpperCase() + input.slice(1);
15 | };
16 |
17 | export const formatBytes = (bytes: number): string => {
18 | if (bytes === 0) {
19 | return '0 Bytes';
20 | }
21 |
22 | const base = 1024;
23 | const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
24 | const index = Math.floor(Math.log(bytes) / Math.log(base));
25 |
26 | return `${Number.parseFloat((bytes / base ** index).toFixed(2))} ${sizes[index]}`;
27 | };
28 |
--------------------------------------------------------------------------------
/apps/app/config/index.ts:
--------------------------------------------------------------------------------
1 | import { constants } from '@/config/constants';
2 | import { docs } from '@/config/docs';
3 | import { examplePrompts } from '@/config/example-prompts';
4 | import { links } from '@/config/links';
5 | import { defaultPreferences } from '@/config/preferences';
6 | import * as prompts from '@/config/prompts';
7 | import { models } from '@/types';
8 |
9 | const configs = {
10 | version: '0.0.1',
11 | ...links,
12 | ...prompts,
13 | ollamaTagsEndpoint: '/api/tags',
14 | heroVideo:
15 | 'https://4sz5k3dpgfzlfzup.public.blob.vercel-storage.com/Build%20Your%20AI%20Chat%20Platform%20_%20ChatHub!%20_%20Next.js,%20OpenAI,%20Gemini,%20Claude,%20Ollama,%20Langchain%20_%20Intro%F0%9F%9A%80-S5FHJCnti4nM84ukVbZjplxrq3BRmm.mp4',
16 | };
17 | export { configs, defaultPreferences, examplePrompts, models, docs, constants };
18 |
--------------------------------------------------------------------------------
/apps/app/types/assistants.ts:
--------------------------------------------------------------------------------
1 | import type { TModelItem, TProvider } from './models';
2 |
3 | export type TAssistantType = 'base' | 'custom';
4 | export type TAssistant = {
5 | key: string;
6 | name: string;
7 | description: string | null;
8 | systemPrompt: string;
9 | iconURL: string | null;
10 | provider: TProvider;
11 | baseModel: string;
12 | type: 'base' | 'custom';
13 | };
14 | export type TAssistantsProvider = {
15 | children: React.ReactNode;
16 | };
17 | export type TAssistantMenuItem = {
18 | name: string;
19 | key: string;
20 | icon: () => React.ReactNode;
21 | component: React.ReactNode;
22 | };
23 | export type TAssistantsContext = {
24 | open: () => void;
25 | dismiss: () => void;
26 | assistants: TAssistant[];
27 | selectedAssistant?: {
28 | assistant: TAssistant;
29 | model: TModelItem;
30 | };
31 | };
32 |
--------------------------------------------------------------------------------
/packages/design-system/components/minime/input.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from '@repo/design-system/lib/utils';
2 | import * as React from 'react';
3 |
4 | export interface InputProps
5 | extends React.InputHTMLAttributes {}
6 |
7 | const Input = React.forwardRef(
8 | ({ className, type, ...props }, ref) => {
9 | return (
10 |
19 | );
20 | }
21 | );
22 | Input.displayName = 'Input';
23 |
24 | export default Input;
25 |
--------------------------------------------------------------------------------
/apps/app/modules/tube/comments/ui/components/checkbox.tsx:
--------------------------------------------------------------------------------
1 | import type React from 'react';
2 | import { forwardRef } from 'react';
3 |
4 | export const Checkbox = forwardRef(
5 | (
6 | props: {
7 | checked: boolean;
8 | disabled?: boolean;
9 | onChange: (event: React.ChangeEvent) => void;
10 | },
11 | ref: React.Ref
12 | ) => {
13 | return (
14 |
22 | );
23 | }
24 | );
25 |
26 | Checkbox.displayName = 'Checkbox';
27 |
--------------------------------------------------------------------------------
/apps/app/public/icons/meta.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/minime/components/domain/use-domain-status.tsx:
--------------------------------------------------------------------------------
1 | import { fetcher } from '@/helper/utils';
2 | import type { DomainStatus } from '@/types/minime';
3 | import { useQuery } from '@tanstack/react-query';
4 |
5 | const useDomainStatus = (
6 | domain: string | null
7 | ): {
8 | status: DomainStatus;
9 | domainRes: any;
10 | isLoading: boolean;
11 | mutate: () => void;
12 | } => {
13 | const {
14 | data,
15 | refetch: mutate,
16 | isLoading,
17 | } = useQuery({
18 | queryKey: ['domain', domain],
19 | queryFn: () => fetcher(`/api/user/domain/${domain}`),
20 | enabled: !!domain,
21 | staleTime: 0,
22 | });
23 |
24 | return {
25 | status: data?.status as DomainStatus,
26 | domainRes: data?.domainRes,
27 | isLoading,
28 | mutate,
29 | };
30 | };
31 |
32 | export default useDomainStatus;
33 |
--------------------------------------------------------------------------------
/packages/feature-flags/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@repo/feature-flags",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "clean": "git clean -xdf .cache .turbo dist node_modules",
7 | "typecheck": "tsc --noEmit --emitDeclarationOnly false"
8 | },
9 | "dependencies": {
10 | "@repo/analytics": "workspace:*",
11 | "@repo/design-system": "workspace:*",
12 | "@t3-oss/env-nextjs": "^0.11.1",
13 | "@vercel/flags": "^2.6.3",
14 | "@vercel/toolbar": "^0.1.30",
15 | "react": "^19.0.0",
16 | "zod": "^3.24.1"
17 | },
18 | "peerDependencies": {
19 | "next": "15.1.3"
20 | },
21 | "devDependencies": {
22 | "@repo/typescript-config": "workspace:*",
23 | "typescript": "^5.7.2",
24 | "@types/node": "22.10.2",
25 | "@types/react": "19.0.2",
26 | "@types/react-dom": "^19.0.2"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/apps/app/app/(organization)/chat/components/pricing-modal.tsx:
--------------------------------------------------------------------------------
1 | import { Pricing } from '@/components/billing/pricing';
2 | import { useRootContext } from '@/context/root';
3 | import {
4 | Dialog,
5 | DialogContent,
6 | DialogHeader,
7 | DialogTitle,
8 | } from '@repo/design-system/components/ui/dialog';
9 |
10 | export const PricingModal = () => {
11 | const { openPricingModal, setOpenPricingModal } = useRootContext();
12 |
13 | return (
14 |
25 | );
26 | };
27 |
--------------------------------------------------------------------------------