vibefast-cli 0.6.2 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/recipes.test.js +5 -5
- package/dist/__tests__/recipes.test.js.map +1 -1
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +136 -48
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +106 -89
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/remove.js +1 -1
- package/dist/commands/remove.js.map +1 -1
- package/dist/core/__tests__/fsx.test.js +3 -1
- package/dist/core/__tests__/fsx.test.js.map +1 -1
- package/dist/core/__tests__/prompt.test.js +12 -12
- package/dist/core/__tests__/prompt.test.js.map +1 -1
- package/dist/core/__tests__/validate.test.js +4 -3
- package/dist/core/__tests__/validate.test.js.map +1 -1
- package/dist/core/auth.d.ts.map +1 -1
- package/dist/core/auth.js +8 -0
- package/dist/core/auth.js.map +1 -1
- package/dist/core/codemod.d.ts +13 -0
- package/dist/core/codemod.d.ts.map +1 -1
- package/dist/core/codemod.js +50 -0
- package/dist/core/codemod.js.map +1 -1
- package/dist/core/errors.js +1 -1
- package/dist/core/fsx.js +1 -1
- package/dist/core/fsx.js.map +1 -1
- package/dist/core/recipes.d.ts.map +1 -1
- package/dist/core/recipes.js +71 -9
- package/dist/core/recipes.js.map +1 -1
- package/package.json +1 -1
- package/recipes/animated-chip/recipe.json +15 -0
- package/recipes/animated-chip@latest.zip +0 -0
- package/recipes/animated-switch/recipe.json +15 -0
- package/recipes/animated-switch@latest.zip +0 -0
- package/recipes/audio-recorder@latest.zip +0 -0
- package/recipes/charts/apps/native/src/features/charts/components/doughnut-chart.tsx +29 -18
- package/recipes/charts@latest.zip +0 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/message-list.tsx +1 -1
- package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-smart-scroll-manager.ts +6 -0
- package/recipes/chatbot/recipe.json +21 -5
- package/recipes/chatbot@latest.zip +0 -0
- package/recipes/glowing-button/recipe.json +1 -3
- package/recipes/glowing-button@latest.zip +0 -0
- package/recipes/image-analysis/recipe.json +36 -19
- package/recipes/image-analysis@latest.zip +0 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/app/_layout.tsx +1 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/app/gallery.tsx +1 -1
- package/recipes/image-generator/apps/native/src/features/image-generator/components/gallery-image.tsx +2 -3
- package/recipes/image-generator/recipe.json +5 -3
- package/recipes/image-generator@latest.zip +0 -0
- package/recipes/ios-widget/recipe.json +24 -0
- package/recipes/ios-widget@latest.zip +0 -0
- package/recipes/number-stepper/recipe.json +15 -0
- package/recipes/number-stepper@latest.zip +0 -0
- package/recipes/payments/recipe.json +30 -0
- package/recipes/payments@latest.zip +0 -0
- package/recipes/posthog.json +2 -1
- package/recipes/progress-circle/recipe.json +15 -0
- package/recipes/progress-circle@latest.zip +0 -0
- package/recipes/quiz@latest.zip +0 -0
- package/recipes/sentry.json +2 -1
- package/recipes/swipe-slider/recipe.json +15 -0
- package/recipes/swipe-slider@latest.zip +0 -0
- package/recipes/{0 → timeline}/recipe.json +3 -6
- package/recipes/timeline@latest.zip +0 -0
- package/recipes/tracker-app@latest.zip +0 -0
- package/recipes/upload-all.sh +13 -2
- package/recipes/voice-bot/recipe.json +15 -2
- package/recipes/voice-bot@latest.zip +0 -0
- package/recipes/wake-word/apps/native/src/app/(root)/(protected)/test-wake-word.tsx +0 -2
- package/recipes/wake-word/recipe.json +2 -2
- package/recipes/wake-word@latest.zip +0 -0
- package/src/__tests__/recipes.test.ts +5 -5
- package/src/commands/add.ts +230 -54
- package/src/commands/init.ts +118 -102
- package/src/commands/remove.ts +1 -1
- package/src/core/__tests__/fsx.test.ts +3 -1
- package/src/core/__tests__/prompt.test.ts +12 -12
- package/src/core/__tests__/validate.test.ts +4 -3
- package/src/core/auth.ts +8 -0
- package/src/core/codemod.ts +66 -0
- package/src/core/errors.ts +1 -1
- package/src/core/fsx.ts +1 -1
- package/src/core/recipes.ts +73 -9
- package/2/.claude/agents/architect.md +0 -74
- package/2/.claude/agents/convex-reviewer.md +0 -267
- package/2/.claude/agents/debug-detective.md +0 -62
- package/2/.claude/agents/learner.md +0 -64
- package/2/.claude/agents/perf-optimizer.md +0 -71
- package/2/.claude/agents/security-researcher.md +0 -42
- package/2/.claude/agents/tech-researcher.md +0 -46
- package/2/.claude/agents/ux-designer.md +0 -45
- package/2/.claude/commands/create-app-design.md +0 -279
- package/2/.claude/commands/create-prd-interactive.md +0 -113
- package/2/.claude/commands/create-prd.md +0 -111
- package/2/.claude/commands/create-tech-stack.md +0 -345
- package/2/.claude/commands/update-app-design.md +0 -298
- package/2/.claude/commands/update-project-structure.md +0 -14
- package/2/.claude/commands/update-tech-stack.md +0 -325
- package/2/.claude/docs/CONVEX_FEATURES_PLAN.md +0 -249
- package/2/.claude/docs/app-design-document.md +0 -0
- package/2/.claude/docs/project-status.md +0 -25
- package/2/.claude/docs/project-structure.md +0 -7
- package/2/.claude/docs/tech-stack.md +0 -157
- package/2/.claude/scripts/tree.sh +0 -70
- package/2/.claude/settings.json +0 -30
- package/2/.cursor/commands/code-review-high.md +0 -190
- package/2/.cursorignore +0 -3
- package/2/.github/ISSUE_TEMPLATE.md +0 -13
- package/2/.github/PULL_REQUEST_TEMPLATE.md +0 -23
- package/2/.github/actions/eas-build/action.yml +0 -85
- package/2/.github/actions/setup-jdk-generate-apk/action.yml +0 -48
- package/2/.github/actions/setup-node-pnpm-install/action.yml +0 -29
- package/2/.github/scripts/expo-doctor.sh +0 -26
- package/2/.github/workflows/compress-images.yml +0 -48
- package/2/.github/workflows/e2e-android-eas-build.yml +0 -111
- package/2/.github/workflows/e2e-android-maestro.yml +0 -52
- package/2/.github/workflows/e2e-android.yml +0 -119
- package/2/.github/workflows/eas-build-prod.yml +0 -43
- package/2/.github/workflows/eas-build-qa.yml +0 -47
- package/2/.github/workflows/expo-doctor.yml +0 -61
- package/2/.github/workflows/lint-ts.yml +0 -49
- package/2/.github/workflows/new-app-version.yml +0 -65
- package/2/.github/workflows/new-github-release.yml +0 -34
- package/2/.github/workflows/stale.yml +0 -24
- package/2/.github/workflows/test.yml +0 -50
- package/2/.github/workflows/type-check.yml +0 -54
- package/2/.husky/commit-msg +0 -1
- package/2/.husky/common.sh +0 -8
- package/2/.husky/post-merge +0 -18
- package/2/.husky/pre-commit +0 -24
- package/2/.prettierignore +0 -14
- package/2/.prettierrc.json +0 -10
- package/2/.vibefast/README.md +0 -59
- package/2/.vibefast/config.json +0 -4
- package/2/.vibefast/journal.json +0 -234
- package/2/.vibefast/starter.json +0 -5
- package/2/AGENTS.md +0 -48
- package/2/LICENSE +0 -21
- package/2/README.md +0 -127
- package/2/apps/native/__mocks__/bottom-sheet.js +0 -6
- package/2/apps/native/__mocks__/expo-router.js +0 -16
- package/2/apps/native/__mocks__/react-native-gesture-handler.ts +0 -17
- package/2/apps/native/app-env.d.ts +0 -2
- package/2/apps/native/app.config.ts +0 -167
- package/2/apps/native/assets/adaptive-icon.png +0 -0
- package/2/apps/native/assets/favicon.png +0 -0
- package/2/apps/native/assets/fonts/Inter.ttf +0 -0
- package/2/apps/native/assets/fonts/SF-Pro-Display-Bold.otf +0 -0
- package/2/apps/native/assets/fonts/SF-Pro-Display-Medium.otf +0 -0
- package/2/apps/native/assets/fonts/SF-Pro-Display-Regular.otf +0 -0
- package/2/apps/native/assets/fonts/SF-Pro-Display-Semibold.otf +0 -0
- package/2/apps/native/assets/fonts/SpaceMono-Regular.ttf +0 -0
- package/2/apps/native/assets/icon.png +0 -0
- package/2/apps/native/assets/images/cover-image.png +0 -0
- package/2/apps/native/assets/lottie-animations/onboarding-1.json +0 -6504
- package/2/apps/native/assets/lottie-animations/onboarding-2.json +0 -1993
- package/2/apps/native/assets/lottie-animations/onboarding-3.json +0 -50159
- package/2/apps/native/assets/lottie-animations/onboarding-4.json +0 -735
- package/2/apps/native/assets/lottie-animations/onboarding-6.json +0 -2167
- package/2/apps/native/assets/splash-icon.png +0 -0
- package/2/apps/native/babel.config.js +0 -39
- package/2/apps/native/eas.json +0 -75
- package/2/apps/native/env.js +0 -196
- package/2/apps/native/global.css +0 -51
- package/2/apps/native/index.ts +0 -5
- package/2/apps/native/jest-setup.ts +0 -7
- package/2/apps/native/jest.config.js +0 -72
- package/2/apps/native/metro.config.js +0 -85
- package/2/apps/native/nativewind-env.d.ts +0 -1
- package/2/apps/native/package.json +0 -232
- package/2/apps/native/scripts/DRY_RUN_REPORT.md +0 -0
- package/2/apps/native/scripts/QUICK_START.md +0 -76
- package/2/apps/native/scripts/README.md +0 -187
- package/2/apps/native/scripts/convex-setup.js +0 -48
- package/2/apps/native/scripts/genrate-apk-and-install +0 -39
- package/2/apps/native/scripts/i18next-syntax-validation.js +0 -23
- package/2/apps/native/scripts/starter-setup.mjs +0 -246
- package/2/apps/native/src/api-client/auth.ts +0 -68
- package/2/apps/native/src/api-client/chatbot.ts +0 -83
- package/2/apps/native/src/api-client/client.ts +0 -4
- package/2/apps/native/src/api-client/image-generator.ts +0 -34
- package/2/apps/native/src/api-client/index.ts +0 -27
- package/2/apps/native/src/api-client/payments.ts +0 -44
- package/2/apps/native/src/api-client/reporting.ts +0 -29
- package/2/apps/native/src/api-client/shared.ts +0 -43
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/_layout.tsx +0 -166
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/index.tsx +0 -174
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/profile.tsx +0 -320
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/settings.tsx +0 -344
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/style/_layout.tsx +0 -198
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/style/accordion.tsx +0 -60
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/style/advanced.tsx +0 -24
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/style/avatar.tsx +0 -154
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/style/badge-chips-toggle.tsx +0 -81
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/style/buttons.tsx +0 -24
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/style/charts.tsx +0 -3
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/style/date-picker.tsx +0 -120
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/style/file-picker.tsx +0 -133
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/style/gallery-video.tsx +0 -119
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/style/index.tsx +0 -69
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/style/inputs-stepper.tsx +0 -78
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/style/picker-dropdown.tsx +0 -56
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/style/popover-bottomsheet.tsx +0 -229
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/style/progress.tsx +0 -38
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/style/searchbar.tsx +0 -70
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/style/sliders.tsx +0 -93
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/style/spinner.tsx +0 -80
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/style/switch.tsx +0 -47
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/style/table.tsx +0 -352
- package/2/apps/native/src/app/(root)/(protected)/(tabs)/style/tabs-timeline.tsx +0 -122
- package/2/apps/native/src/app/(root)/(protected)/_layout.tsx +0 -143
- package/2/apps/native/src/app/(root)/(protected)/audio-recorder/index.tsx +0 -5
- package/2/apps/native/src/app/(root)/(protected)/charts/index.tsx +0 -6
- package/2/apps/native/src/app/(root)/(protected)/chatbot/index.tsx +0 -2
- package/2/apps/native/src/app/(root)/(protected)/image-generator/gallery.tsx +0 -3
- package/2/apps/native/src/app/(root)/(protected)/image-generator/index.tsx +0 -3
- package/2/apps/native/src/app/(root)/(protected)/paywall/index.tsx +0 -74
- package/2/apps/native/src/app/(root)/(protected)/paywall/local.tsx +0 -25
- package/2/apps/native/src/app/(root)/(protected)/paywall/remote.tsx +0 -23
- package/2/apps/native/src/app/(root)/(protected)/quick-actions-demo/index.tsx +0 -32
- package/2/apps/native/src/app/(root)/(protected)/quiz/index.tsx +0 -47
- package/2/apps/native/src/app/(root)/(protected)/test-wake-word.tsx +0 -214
- package/2/apps/native/src/app/(root)/(protected)/tracker-app/index.tsx +0 -1
- package/2/apps/native/src/app/(root)/(protected)/voice-bot/index.tsx +0 -27
- package/2/apps/native/src/app/(root)/(public)/(auth)/_layout.tsx +0 -44
- package/2/apps/native/src/app/(root)/(public)/(auth)/forgot-password.tsx +0 -185
- package/2/apps/native/src/app/(root)/(public)/(auth)/login.tsx +0 -219
- package/2/apps/native/src/app/(root)/(public)/(auth)/otp-verification.tsx +0 -369
- package/2/apps/native/src/app/(root)/(public)/(auth)/reset-password.tsx +0 -247
- package/2/apps/native/src/app/(root)/(public)/(auth)/signup.tsx +0 -207
- package/2/apps/native/src/app/(root)/(public)/_layout.tsx +0 -60
- package/2/apps/native/src/app/(root)/(public)/onboarding/demo-one.tsx +0 -5
- package/2/apps/native/src/app/(root)/(public)/onboarding/demo-two.tsx +0 -52
- package/2/apps/native/src/app/(root)/(public)/onboarding/index.tsx +0 -82
- package/2/apps/native/src/app/(root)/_layout.tsx +0 -30
- package/2/apps/native/src/app/+html.tsx +0 -46
- package/2/apps/native/src/app/[...messing].tsx +0 -24
- package/2/apps/native/src/app/_layout.tsx +0 -56
- package/2/apps/native/src/app/tsconfig.json +0 -3
- package/2/apps/native/src/components/advanced-ui/buttons/glowing-button.tsx +0 -366
- package/2/apps/native/src/components/analytics/navigation-tracker.tsx +0 -10
- package/2/apps/native/src/components/demo/advanced-ui-components.tsx +0 -46
- package/2/apps/native/src/components/demo/buttons-demo.tsx +0 -56
- package/2/apps/native/src/components/demo/colors-demo.tsx +0 -52
- package/2/apps/native/src/components/demo/dropdown-picker-demo.tsx +0 -274
- package/2/apps/native/src/components/demo/inputs-demo.tsx +0 -99
- package/2/apps/native/src/components/demo/notification-demo.tsx +0 -434
- package/2/apps/native/src/components/demo/title-demo.tsx +0 -16
- package/2/apps/native/src/components/demo/toast-demo.tsx +0 -81
- package/2/apps/native/src/components/demo/typography-demo.tsx +0 -28
- package/2/apps/native/src/components/performance/render-performance-monitor.tsx +0 -36
- package/2/apps/native/src/components/ui/accordion.tsx +0 -138
- package/2/apps/native/src/components/ui/avatar.tsx +0 -66
- package/2/apps/native/src/components/ui/badge.tsx +0 -68
- package/2/apps/native/src/components/ui/bottom-sheet.tsx +0 -61
- package/2/apps/native/src/components/ui/colors.js +0 -290
- package/2/apps/native/src/components/ui/core/button.tsx +0 -317
- package/2/apps/native/src/components/ui/core/card.tsx +0 -40
- package/2/apps/native/src/components/ui/core/checkbox.tsx +0 -264
- package/2/apps/native/src/components/ui/core/feature-button.tsx +0 -162
- package/2/apps/native/src/components/ui/core/focus-aware-status-bar.tsx +0 -21
- package/2/apps/native/src/components/ui/core/image.tsx +0 -30
- package/2/apps/native/src/components/ui/core/inputs/floating-text-input.tsx +0 -369
- package/2/apps/native/src/components/ui/core/inputs/input-otp.tsx +0 -304
- package/2/apps/native/src/components/ui/core/inputs/input.tsx +0 -373
- package/2/apps/native/src/components/ui/core/list.tsx +0 -60
- package/2/apps/native/src/components/ui/core/navigation/animated-header.tsx +0 -87
- package/2/apps/native/src/components/ui/core/navigation/screen-footer.tsx +0 -67
- package/2/apps/native/src/components/ui/core/overlays/dropdown.tsx +0 -290
- package/2/apps/native/src/components/ui/core/overlays/full-screen-loading.tsx +0 -15
- package/2/apps/native/src/components/ui/core/overlays/modal-keyboard-aware-scroll-view.tsx +0 -46
- package/2/apps/native/src/components/ui/core/overlays/modal.tsx +0 -247
- package/2/apps/native/src/components/ui/core/pagination-dots.tsx +0 -231
- package/2/apps/native/src/components/ui/core/pressable.tsx +0 -48
- package/2/apps/native/src/components/ui/core/progress-bar.tsx +0 -47
- package/2/apps/native/src/components/ui/core/progress.tsx +0 -149
- package/2/apps/native/src/components/ui/core/select.tsx +0 -261
- package/2/apps/native/src/components/ui/core/spinner.tsx +0 -387
- package/2/apps/native/src/components/ui/core/text.tsx +0 -45
- package/2/apps/native/src/components/ui/core/toast.tsx +0 -190
- package/2/apps/native/src/components/ui/custom-switch.tsx +0 -90
- package/2/apps/native/src/components/ui/date-time-picker.tsx +0 -268
- package/2/apps/native/src/components/ui/debug.ts +0 -2
- package/2/apps/native/src/components/ui/extras/debug-credit-tester.tsx +0 -107
- package/2/apps/native/src/components/ui/extras/debug-mmkv-state.tsx +0 -53
- package/2/apps/native/src/components/ui/extras/handle-error.ts +0 -191
- package/2/apps/native/src/components/ui/extras/hello-wave.tsx +0 -70
- package/2/apps/native/src/components/ui/extras/icon.tsx +0 -36
- package/2/apps/native/src/components/ui/extras/network-connectivity-wrapper.tsx +0 -36
- package/2/apps/native/src/components/ui/extras/offline-indicator.tsx +0 -55
- package/2/apps/native/src/components/ui/extras/social-login-buttons.tsx +0 -296
- package/2/apps/native/src/components/ui/file-picker.tsx +0 -177
- package/2/apps/native/src/components/ui/gallery.tsx +0 -79
- package/2/apps/native/src/components/ui/icons/apple.tsx +0 -19
- package/2/apps/native/src/components/ui/icons/arrow-right.tsx +0 -26
- package/2/apps/native/src/components/ui/icons/camera.tsx +0 -26
- package/2/apps/native/src/components/ui/icons/caret-down.tsx +0 -20
- package/2/apps/native/src/components/ui/icons/chevron-up.tsx +0 -21
- package/2/apps/native/src/components/ui/icons/claude.tsx +0 -15
- package/2/apps/native/src/components/ui/icons/copy.tsx +0 -27
- package/2/apps/native/src/components/ui/icons/deepseek.tsx +0 -15
- package/2/apps/native/src/components/ui/icons/download.tsx +0 -32
- package/2/apps/native/src/components/ui/icons/feed.tsx +0 -12
- package/2/apps/native/src/components/ui/icons/gemini.tsx +0 -15
- package/2/apps/native/src/components/ui/icons/github.tsx +0 -30
- package/2/apps/native/src/components/ui/icons/google.tsx +0 -24
- package/2/apps/native/src/components/ui/icons/groq.tsx +0 -15
- package/2/apps/native/src/components/ui/icons/home.tsx +0 -19
- package/2/apps/native/src/components/ui/icons/index.tsx +0 -26
- package/2/apps/native/src/components/ui/icons/language.tsx +0 -33
- package/2/apps/native/src/components/ui/icons/llama.tsx +0 -15
- package/2/apps/native/src/components/ui/icons/microphone.tsx +0 -20
- package/2/apps/native/src/components/ui/icons/mistral.tsx +0 -22
- package/2/apps/native/src/components/ui/icons/nutrition.tsx +0 -15
- package/2/apps/native/src/components/ui/icons/openai.tsx +0 -15
- package/2/apps/native/src/components/ui/icons/perplexity.tsx +0 -22
- package/2/apps/native/src/components/ui/icons/qwen.tsx +0 -15
- package/2/apps/native/src/components/ui/icons/rate.tsx +0 -24
- package/2/apps/native/src/components/ui/icons/report.tsx +0 -20
- package/2/apps/native/src/components/ui/icons/send-horizontal.tsx +0 -26
- package/2/apps/native/src/components/ui/icons/settings.tsx +0 -12
- package/2/apps/native/src/components/ui/icons/share.tsx +0 -16
- package/2/apps/native/src/components/ui/icons/square.tsx +0 -9
- package/2/apps/native/src/components/ui/icons/style.tsx +0 -22
- package/2/apps/native/src/components/ui/icons/support.tsx +0 -27
- package/2/apps/native/src/components/ui/icons/trash2.tsx +0 -42
- package/2/apps/native/src/components/ui/icons/user.tsx +0 -12
- package/2/apps/native/src/components/ui/icons/website.tsx +0 -28
- package/2/apps/native/src/components/ui/icons/wifi-off.tsx +0 -17
- package/2/apps/native/src/components/ui/index.tsx +0 -14
- package/2/apps/native/src/components/ui/nav-item.tsx +0 -42
- package/2/apps/native/src/components/ui/patterns/index.ts +0 -16
- package/2/apps/native/src/components/ui/picker.tsx +0 -244
- package/2/apps/native/src/components/ui/popover.tsx +0 -313
- package/2/apps/native/src/components/ui/primitives/index.ts +0 -38
- package/2/apps/native/src/components/ui/radio-group.tsx +0 -47
- package/2/apps/native/src/components/ui/searchbar.tsx +0 -118
- package/2/apps/native/src/components/ui/sheet.tsx +0 -93
- package/2/apps/native/src/components/ui/switch.tsx +0 -37
- package/2/apps/native/src/components/ui/table.tsx +0 -296
- package/2/apps/native/src/components/ui/tabs.tsx +0 -115
- package/2/apps/native/src/components/ui/toggle.tsx +0 -50
- package/2/apps/native/src/components/ui/utils.tsx +0 -34
- package/2/apps/native/src/components/ui/video.tsx +0 -39
- package/2/apps/native/src/core/analytics/analytics-service.ts +0 -94
- package/2/apps/native/src/core/analytics/index.ts +0 -2
- package/2/apps/native/src/core/analytics/posthog-analytics-adapter.ts +0 -192
- package/2/apps/native/src/core/auth/auth-service.ts +0 -33
- package/2/apps/native/src/core/auth/index.ts +0 -1
- package/2/apps/native/src/core/cache/__tests__/cache-service.test.ts +0 -599
- package/2/apps/native/src/core/cache/cache-service.ts +0 -89
- package/2/apps/native/src/core/cache/index.ts +0 -45
- package/2/apps/native/src/core/config/config.service.ts +0 -153
- package/2/apps/native/src/core/config/index.ts +0 -2
- package/2/apps/native/src/core/config/telemetry.ts +0 -38
- package/2/apps/native/src/core/local-notifications/local-notification-manager.ts +0 -409
- package/2/apps/native/src/core/logging/custom-transports.ts +0 -126
- package/2/apps/native/src/core/logging/index.ts +0 -1
- package/2/apps/native/src/core/logging/logger.ts +0 -182
- package/2/apps/native/src/core/navigation/deep-link-handler.ts +0 -295
- package/2/apps/native/src/core/navigation/navigation-types.ts +0 -53
- package/2/apps/native/src/core/payments/index.ts +0 -1
- package/2/apps/native/src/core/payments/payment-service.ts +0 -32
- package/2/apps/native/src/core/quick-actions/index.ts +0 -2
- package/2/apps/native/src/core/quick-actions/quick-actions-adapter.ts +0 -54
- package/2/apps/native/src/core/quick-actions/types.ts +0 -29
- package/2/apps/native/src/core/storage/index.ts +0 -1
- package/2/apps/native/src/core/storage/mmkv.ts +0 -62
- package/2/apps/native/src/core/storage/notification-storage.ts +0 -312
- package/2/apps/native/src/core/types/common.ts +0 -0
- package/2/apps/native/src/core/utils/convex-http-api.ts +0 -30
- package/2/apps/native/src/features/audio-recorder/components/audio-player.tsx +0 -301
- package/2/apps/native/src/features/audio-recorder/components/audio-recorder.tsx +0 -373
- package/2/apps/native/src/features/audio-recorder/components/audio-waveform.tsx +0 -270
- package/2/apps/native/src/features/audio-recorder/components/index.ts +0 -4
- package/2/apps/native/src/features/audio-recorder/components/recording-list.tsx +0 -89
- package/2/apps/native/src/features/audio-recorder/demo/audio-player-demo.tsx +0 -66
- package/2/apps/native/src/features/audio-recorder/demo/audio-recorder-cloud.tsx +0 -68
- package/2/apps/native/src/features/audio-recorder/demo/audio-recorder-interview.tsx +0 -102
- package/2/apps/native/src/features/audio-recorder/demo/basic.tsx +0 -27
- package/2/apps/native/src/features/audio-recorder/demo/index.ts +0 -5
- package/2/apps/native/src/features/audio-recorder/demo/with-recording-list-demo.tsx +0 -82
- package/2/apps/native/src/features/authentication/components/auth-watcher.tsx +0 -115
- package/2/apps/native/src/features/authentication/components/login-form.tsx +0 -85
- package/2/apps/native/src/features/authentication/services/__tests__/convex-auth.adapter.test.ts +0 -399
- package/2/apps/native/src/features/authentication/services/convex-auth.adapter.ts +0 -497
- package/2/apps/native/src/features/authentication/services/index.ts +0 -2
- package/2/apps/native/src/features/charts/README.md +0 -185
- package/2/apps/native/src/features/charts/app/preview.tsx +0 -226
- package/2/apps/native/src/features/charts/components/area-chart.tsx +0 -43
- package/2/apps/native/src/features/charts/components/bar-chart.tsx +0 -146
- package/2/apps/native/src/features/charts/components/candlestick-chart.tsx +0 -199
- package/2/apps/native/src/features/charts/components/chart-card.tsx +0 -68
- package/2/apps/native/src/features/charts/components/column-chart.tsx +0 -146
- package/2/apps/native/src/features/charts/components/doughnut-chart.tsx +0 -260
- package/2/apps/native/src/features/charts/components/index.ts +0 -13
- package/2/apps/native/src/features/charts/components/line-chart.tsx +0 -311
- package/2/apps/native/src/features/charts/components/radar-chart.tsx +0 -183
- package/2/apps/native/src/features/charts/components/radial-bar-chart.tsx +0 -191
- package/2/apps/native/src/features/charts/components/stacked-area-chart.tsx +0 -268
- package/2/apps/native/src/features/charts/components/stacked-bar-chart.tsx +0 -325
- package/2/apps/native/src/features/charts/data/mock-data.ts +0 -186
- package/2/apps/native/src/features/charts/types/index.ts +0 -69
- package/2/apps/native/src/features/chatbot/app/index.tsx +0 -303
- package/2/apps/native/src/features/chatbot/components/chat-header-buttons.tsx +0 -60
- package/2/apps/native/src/features/chatbot/components/chat-input-bar.tsx +0 -470
- package/2/apps/native/src/features/chatbot/components/chat-markdown.tsx +0 -576
- package/2/apps/native/src/features/chatbot/components/chat-message-bubble.tsx +0 -247
- package/2/apps/native/src/features/chatbot/components/chat-settings-modal.tsx +0 -162
- package/2/apps/native/src/features/chatbot/components/image-preview-list.tsx +0 -116
- package/2/apps/native/src/features/chatbot/components/markdown/code-block.tsx +0 -166
- package/2/apps/native/src/features/chatbot/components/markdown/index.ts +0 -11
- package/2/apps/native/src/features/chatbot/components/markdown/table-renderer.tsx +0 -130
- package/2/apps/native/src/features/chatbot/components/message-error-boundary.tsx +0 -79
- package/2/apps/native/src/features/chatbot/components/message-list.tsx +0 -174
- package/2/apps/native/src/features/chatbot/components/model-selector.tsx +0 -284
- package/2/apps/native/src/features/chatbot/components/report-content-modal.tsx +0 -189
- package/2/apps/native/src/features/chatbot/components/suggested-messages.tsx +0 -68
- package/2/apps/native/src/features/chatbot/constants/models.ts +0 -21
- package/2/apps/native/src/features/chatbot/constants/report-reasons.ts +0 -10
- package/2/apps/native/src/features/chatbot/hooks/use-attachment-cache.ts +0 -144
- package/2/apps/native/src/features/chatbot/hooks/use-chat-config.ts +0 -665
- package/2/apps/native/src/features/chatbot/hooks/use-chat-handlers.ts +0 -360
- package/2/apps/native/src/features/chatbot/hooks/use-chatbot-settings.ts +0 -90
- package/2/apps/native/src/features/chatbot/hooks/use-conversation.ts +0 -80
- package/2/apps/native/src/features/chatbot/hooks/use-image-picker.ts +0 -123
- package/2/apps/native/src/features/chatbot/hooks/use-keyboard-coordinator.ts +0 -162
- package/2/apps/native/src/features/chatbot/hooks/use-smart-scroll-manager.ts +0 -214
- package/2/apps/native/src/features/chatbot/models/index.ts +0 -87
- package/2/apps/native/src/features/chatbot/models/models.ts +0 -163
- package/2/apps/native/src/features/chatbot/models/providers.ts +0 -63
- package/2/apps/native/src/features/chatbot/models/types.ts +0 -41
- package/2/apps/native/src/features/chatbot/services/file-uploader.ts +0 -239
- package/2/apps/native/src/features/chatbot/services/message-handler-service.ts +0 -181
- package/2/apps/native/src/features/chatbot/types/index.ts +0 -61
- package/2/apps/native/src/features/chatbot/utils/chat-telemetry.ts +0 -92
- package/2/apps/native/src/features/image-generator/app/_layout.tsx +0 -26
- package/2/apps/native/src/features/image-generator/app/gallery.tsx +0 -217
- package/2/apps/native/src/features/image-generator/app/index.tsx +0 -237
- package/2/apps/native/src/features/image-generator/components/gallery-image.tsx +0 -25
- package/2/apps/native/src/features/image-generator/components/image-detail-modal.tsx +0 -215
- package/2/apps/native/src/features/image-generator/components/image-model-selector.tsx +0 -210
- package/2/apps/native/src/features/image-generator/components/image-placeholder.tsx +0 -26
- package/2/apps/native/src/features/image-generator/hooks/use-image-gallery.ts +0 -71
- package/2/apps/native/src/features/image-generator/hooks/use-image-generator-settings.ts +0 -152
- package/2/apps/native/src/features/image-generator/hooks/use-image-generator.ts +0 -93
- package/2/apps/native/src/features/image-generator/models/models.ts +0 -66
- package/2/apps/native/src/features/image-generator/services/image-gallery-service.ts +0 -98
- package/2/apps/native/src/features/image-generator/services/image-save-service.ts +0 -121
- package/2/apps/native/src/features/onboarding/analytics/index.ts +0 -9
- package/2/apps/native/src/features/onboarding/components/onboarding-with-analytics.tsx +0 -141
- package/2/apps/native/src/features/onboarding/components/onboarding.tsx +0 -173
- package/2/apps/native/src/features/onboarding/config/onboarding-flow-config.ts +0 -189
- package/2/apps/native/src/features/onboarding/demo-one/app/index.tsx +0 -43
- package/2/apps/native/src/features/onboarding/demo-one/data.ts +0 -32
- package/2/apps/native/src/features/onboarding/hooks/use-onboarding-analytics.ts +0 -323
- package/2/apps/native/src/features/onboarding/services/onboarding-analytics.ts +0 -432
- package/2/apps/native/src/features/payments/README.md +0 -200
- package/2/apps/native/src/features/payments/app/local-paywall.tsx +0 -194
- package/2/apps/native/src/features/payments/app/remote-paywall.tsx +0 -79
- package/2/apps/native/src/features/payments/components/payment-initializer.tsx +0 -95
- package/2/apps/native/src/features/payments/components/paywall-error-state.tsx +0 -60
- package/2/apps/native/src/features/payments/components/paywall-local-mode.tsx +0 -116
- package/2/apps/native/src/features/payments/components/paywall-product-card.tsx +0 -133
- package/2/apps/native/src/features/payments/components/paywall-remote-mode.tsx +0 -146
- package/2/apps/native/src/features/payments/hooks/use-entitlement.ts +0 -63
- package/2/apps/native/src/features/payments/index.ts +0 -8
- package/2/apps/native/src/features/payments/services/revenuecat-adapter.ts +0 -407
- package/2/apps/native/src/features/quick-actions/components/quick-actions-demo.tsx +0 -139
- package/2/apps/native/src/features/quick-actions/config/default-actions.ts +0 -83
- package/2/apps/native/src/features/quick-actions/hooks/use-quick-actions.ts +0 -45
- package/2/apps/native/src/features/quick-actions/index.ts +0 -4
- package/2/apps/native/src/features/quick-actions/utils/quick-actions-manager.ts +0 -105
- package/2/apps/native/src/features/quiz/components/question.tsx +0 -67
- package/2/apps/native/src/features/quiz/config.ts +0 -11
- package/2/apps/native/src/features/quiz/index.tsx +0 -133
- package/2/apps/native/src/features/settings/ui/debug-info.tsx +0 -75
- package/2/apps/native/src/features/settings/ui/dev-tools.tsx +0 -1
- package/2/apps/native/src/features/settings/ui/item.tsx +0 -45
- package/2/apps/native/src/features/settings/ui/items-container.tsx +0 -23
- package/2/apps/native/src/features/settings/ui/language-item.tsx +0 -52
- package/2/apps/native/src/features/settings/ui/notification-item.tsx +0 -59
- package/2/apps/native/src/features/settings/ui/theme-item.tsx +0 -45
- package/2/apps/native/src/features/tracker-app/app/index.tsx +0 -108
- package/2/apps/native/src/features/tracker-app/components/animated-number.tsx +0 -102
- package/2/apps/native/src/features/tracker-app/components/calorie-card.tsx +0 -66
- package/2/apps/native/src/features/tracker-app/components/circular-progress.tsx +0 -97
- package/2/apps/native/src/features/tracker-app/components/floating-add-button.tsx +0 -27
- package/2/apps/native/src/features/tracker-app/components/macro-card.tsx +0 -80
- package/2/apps/native/src/features/tracker-app/components/promo-banner.tsx +0 -98
- package/2/apps/native/src/features/tracker-app/components/recently-logged.tsx +0 -64
- package/2/apps/native/src/features/tracker-app/components/week-calendar.tsx +0 -68
- package/2/apps/native/src/features/vibefast-features.ts +0 -42
- package/2/apps/native/src/features/voice-bot/README.md +0 -185
- package/2/apps/native/src/features/voice-bot/components/conversation-status.tsx +0 -76
- package/2/apps/native/src/features/voice-bot/components/index.ts +0 -4
- package/2/apps/native/src/features/voice-bot/components/message-input.tsx +0 -98
- package/2/apps/native/src/features/voice-bot/components/voice-bot-screen.tsx +0 -173
- package/2/apps/native/src/features/voice-bot/components/voice-controls.tsx +0 -73
- package/2/apps/native/src/features/voice-bot/index.ts +0 -3
- package/2/apps/native/src/features/voice-bot/services/index.ts +0 -1
- package/2/apps/native/src/features/voice-bot/services/use-voice-bot.ts +0 -161
- package/2/apps/native/src/features/voice-bot/types.ts +0 -29
- package/2/apps/native/src/features/wake-word/components/index.ts +0 -1
- package/2/apps/native/src/features/wake-word/components/wake-word-indicator.tsx +0 -61
- package/2/apps/native/src/features/wake-word/constants.ts +0 -10
- package/2/apps/native/src/features/wake-word/hooks/use-wake-word.ts +0 -181
- package/2/apps/native/src/features/wake-word/index.ts +0 -22
- package/2/apps/native/src/features/wake-word/services/audio-session.ts +0 -40
- package/2/apps/native/src/features/wake-word/services/event-bus.ts +0 -31
- package/2/apps/native/src/features/wake-word/services/keywords.ts +0 -88
- package/2/apps/native/src/features/wake-word/services/wake-word-manager.ts +0 -249
- package/2/apps/native/src/features/wake-word/types.ts +0 -22
- package/2/apps/native/src/lib/env.js +0 -13
- package/2/apps/native/src/lib/hooks/index.tsx +0 -6
- package/2/apps/native/src/lib/hooks/use-device-identifier.tsx +0 -80
- package/2/apps/native/src/lib/hooks/use-gradual-animation.ts +0 -28
- package/2/apps/native/src/lib/hooks/use-is-first-time.tsx +0 -25
- package/2/apps/native/src/lib/hooks/use-navigation-analytics.ts +0 -44
- package/2/apps/native/src/lib/hooks/use-navigation-options.tsx +0 -87
- package/2/apps/native/src/lib/hooks/use-push-notifications.ts +0 -250
- package/2/apps/native/src/lib/hooks/use-responsive-size.tsx +0 -37
- package/2/apps/native/src/lib/hooks/use-selected-theme.tsx +0 -38
- package/2/apps/native/src/lib/hooks/use-viewport-lazy-loading.tsx +0 -124
- package/2/apps/native/src/lib/i18n/index.tsx +0 -30
- package/2/apps/native/src/lib/i18n/react-i18next.d.ts +0 -9
- package/2/apps/native/src/lib/i18n/resources.ts +0 -25
- package/2/apps/native/src/lib/i18n/types.ts +0 -23
- package/2/apps/native/src/lib/i18n/utils.tsx +0 -112
- package/2/apps/native/src/lib/index.tsx +0 -3
- package/2/apps/native/src/lib/state/auth-client-slice.ts +0 -34
- package/2/apps/native/src/lib/state/index.ts +0 -1
- package/2/apps/native/src/lib/storage.tsx +0 -7
- package/2/apps/native/src/lib/test-utils.tsx +0 -43
- package/2/apps/native/src/lib/use-theme-config.tsx +0 -108
- package/2/apps/native/src/lib/utils.ts +0 -29
- package/2/apps/native/src/polyfills.ts +0 -61
- package/2/apps/native/src/providers/convex-provider.tsx +0 -31
- package/2/apps/native/src/providers/index.tsx +0 -6
- package/2/apps/native/src/providers/notification-provider.tsx +0 -168
- package/2/apps/native/src/providers/posthog-provider.tsx +0 -47
- package/2/apps/native/src/providers/root-providers.tsx +0 -46
- package/2/apps/native/src/providers/sentry-provider.tsx +0 -62
- package/2/apps/native/src/providers/splash-screen-provider.tsx +0 -122
- package/2/apps/native/src/providers/theme-provider.tsx +0 -67
- package/2/apps/native/src/translations/ar.json +0 -394
- package/2/apps/native/src/translations/de.json +0 -394
- package/2/apps/native/src/translations/en.json +0 -394
- package/2/apps/native/src/translations/es.json +0 -394
- package/2/apps/native/src/translations/fr.json +0 -394
- package/2/apps/native/src/types/flash-list.d.ts +0 -3
- package/2/apps/native/src/types/index.ts +0 -3
- package/2/apps/native/src/types/react-native-reanimated.d.ts +0 -5
- package/2/apps/native/tailwind.config.js +0 -57
- package/2/apps/native/targets/widget/AppIntent.swift +0 -46
- package/2/apps/native/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-20x20@1x.png +0 -0
- package/2/apps/native/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-20x20@2x.png +0 -0
- package/2/apps/native/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-20x20@3x.png +0 -0
- package/2/apps/native/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-29x29@1x.png +0 -0
- package/2/apps/native/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-29x29@2x.png +0 -0
- package/2/apps/native/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-29x29@3x.png +0 -0
- package/2/apps/native/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-40x40@1x.png +0 -0
- package/2/apps/native/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-40x40@2x.png +0 -0
- package/2/apps/native/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-40x40@3x.png +0 -0
- package/2/apps/native/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-60x60@2x.png +0 -0
- package/2/apps/native/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-60x60@3x.png +0 -0
- package/2/apps/native/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-76x76@1x.png +0 -0
- package/2/apps/native/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-76x76@2x.png +0 -0
- package/2/apps/native/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-83.5x83.5@2x.png +0 -0
- package/2/apps/native/targets/widget/Assets.xcassets/AppIcon.appiconset/Contents.json +0 -122
- package/2/apps/native/targets/widget/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png +0 -0
- package/2/apps/native/targets/widget/CalorieTrackerWidget.swift +0 -424
- package/2/apps/native/targets/widget/HabitTrackerWidget.swift +0 -305
- package/2/apps/native/targets/widget/Info.plist +0 -11
- package/2/apps/native/targets/widget/WidgetLiveActivity.swift +0 -75
- package/2/apps/native/targets/widget/expo-target.config.js +0 -10
- package/2/apps/native/targets/widget/generated.entitlements +0 -5
- package/2/apps/native/targets/widget/index.swift +0 -18
- package/2/apps/native/targets/widget/widgets.swift +0 -96
- package/2/apps/native/tsconfig.json +0 -88
- package/2/apps/native/vitest.config.mts +0 -14
- package/2/apps/web/README.md +0 -36
- package/2/apps/web/app/favicon.ico +0 -0
- package/2/apps/web/app/globals.css +0 -122
- package/2/apps/web/app/layout.tsx +0 -38
- package/2/apps/web/app/page.tsx +0 -35
- package/2/apps/web/app/users/page.tsx +0 -301
- package/2/apps/web/components/AdminDashboard.tsx +0 -336
- package/2/apps/web/components/AppleLogo.tsx +0 -15
- package/2/apps/web/components/GitHubLogo.tsx +0 -11
- package/2/apps/web/components/GoogleLogo.tsx +0 -23
- package/2/apps/web/components/Layout.tsx +0 -77
- package/2/apps/web/components/ThemeToggle.tsx +0 -23
- package/2/apps/web/components/UserMenu.tsx +0 -66
- package/2/apps/web/components/auth/CodeInput.tsx +0 -24
- package/2/apps/web/components/auth/ResetPasswordWithEmailCode.tsx +0 -85
- package/2/apps/web/components/auth/SignInFormEmailCode.tsx +0 -72
- package/2/apps/web/components/auth/SignInFormEmailLink.tsx +0 -81
- package/2/apps/web/components/auth/SignInFormPassword.tsx +0 -17
- package/2/apps/web/components/auth/SignInFormPasswordAndCustomField.tsx +0 -42
- package/2/apps/web/components/auth/SignInFormPasswordAndResetViaCode.tsx +0 -32
- package/2/apps/web/components/auth/SignInFormPasswordAndVerifyViaCode.tsx +0 -86
- package/2/apps/web/components/auth/SignInFormPhoneCode.tsx +0 -89
- package/2/apps/web/components/auth/SignInFormsShowcase.tsx +0 -64
- package/2/apps/web/components/auth/SignInMethodDivider.tsx +0 -17
- package/2/apps/web/components/auth/SignInWithEmailCode.tsx +0 -49
- package/2/apps/web/components/auth/SignInWithOAuth.tsx +0 -16
- package/2/apps/web/components/auth/SignInWithPassword.tsx +0 -100
- package/2/apps/web/components/auth/oauth/SignInWithApple.tsx +0 -27
- package/2/apps/web/components/auth/oauth/SignInWithGitHub.tsx +0 -27
- package/2/apps/web/components/auth/oauth/SignInWithGoogle.tsx +0 -27
- package/2/apps/web/components/ui/button.tsx +0 -60
- package/2/apps/web/components/ui/card.tsx +0 -92
- package/2/apps/web/components/ui/dialog.tsx +0 -143
- package/2/apps/web/components/ui/dropdown-menu.tsx +0 -257
- package/2/apps/web/components/ui/input-otp.tsx +0 -77
- package/2/apps/web/components/ui/input.tsx +0 -21
- package/2/apps/web/components/ui/skeleton.tsx +0 -13
- package/2/apps/web/components/ui/tabs.tsx +0 -66
- package/2/apps/web/components/ui/toast.tsx +0 -130
- package/2/apps/web/components/ui/toaster.tsx +0 -36
- package/2/apps/web/components/ui/toggle-group.tsx +0 -83
- package/2/apps/web/components/ui/toggle.tsx +0 -47
- package/2/apps/web/components/ui/use-toast.ts +0 -192
- package/2/apps/web/components.json +0 -22
- package/2/apps/web/eslint.config.mjs +0 -18
- package/2/apps/web/lib/convex-provider.tsx +0 -18
- package/2/apps/web/lib/utils.ts +0 -6
- package/2/apps/web/next.config.ts +0 -7
- package/2/apps/web/package.json +0 -46
- package/2/apps/web/postcss.config.mjs +0 -7
- package/2/apps/web/public/file.svg +0 -1
- package/2/apps/web/public/globe.svg +0 -1
- package/2/apps/web/public/next.svg +0 -1
- package/2/apps/web/public/vercel.svg +0 -1
- package/2/apps/web/public/window.svg +0 -1
- package/2/apps/web/tsconfig.json +0 -34
- package/2/bts.jsonc +0 -21
- package/2/commitlint.config.js +0 -1
- package/2/eslint.config.mjs +0 -182
- package/2/lint-staged.config.js +0 -16
- package/2/package.json +0 -64
- package/2/packages/backend/.env.example +0 -20
- package/2/packages/backend/convex/README.md +0 -90
- package/2/packages/backend/convex/_generated/api.d.ts +0 -2599
- package/2/packages/backend/convex/_generated/api.js +0 -23
- package/2/packages/backend/convex/_generated/dataModel.d.ts +0 -60
- package/2/packages/backend/convex/_generated/server.d.ts +0 -149
- package/2/packages/backend/convex/_generated/server.js +0 -90
- package/2/packages/backend/convex/agents.ts +0 -116
- package/2/packages/backend/convex/auth.config.ts +0 -8
- package/2/packages/backend/convex/auth.ts +0 -103
- package/2/packages/backend/convex/authCustomEmailOtpProvider.ts +0 -175
- package/2/packages/backend/convex/authOtp.ts +0 -144
- package/2/packages/backend/convex/authPasswordReset.ts +0 -367
- package/2/packages/backend/convex/authPasswordResetActions.ts +0 -150
- package/2/packages/backend/convex/chatbot/index.ts +0 -30
- package/2/packages/backend/convex/chatbotAgent.ts +0 -1085
- package/2/packages/backend/convex/chatbotHistory.ts +0 -307
- package/2/packages/backend/convex/convex.config.ts +0 -13
- package/2/packages/backend/convex/deviceGrants.ts +0 -58
- package/2/packages/backend/convex/grantFunctions.ts +0 -444
- package/2/packages/backend/convex/http.ts +0 -8
- package/2/packages/backend/convex/imageGeneration/index.ts +0 -12
- package/2/packages/backend/convex/imageGeneratorFunctions.ts +0 -290
- package/2/packages/backend/convex/lib/ai/analysisConfigs.ts +0 -257
- package/2/packages/backend/convex/lib/ai/config.ts +0 -71
- package/2/packages/backend/convex/lib/ai/geminiAdapter.ts +0 -43
- package/2/packages/backend/convex/lib/ai/openaiAdapter.ts +0 -43
- package/2/packages/backend/convex/lib/ai/schemas.ts +0 -79
- package/2/packages/backend/convex/lib/config.ts +0 -111
- package/2/packages/backend/convex/lib/rateLimit.ts +0 -100
- package/2/packages/backend/convex/lib/telemetry.ts +0 -29
- package/2/packages/backend/convex/paymentFunctions.ts +0 -119
- package/2/packages/backend/convex/payments/index.ts +0 -13
- package/2/packages/backend/convex/pushNotificationFunctions.ts +0 -342
- package/2/packages/backend/convex/ragKnowledge.ts +0 -714
- package/2/packages/backend/convex/rateLimit.ts +0 -13
- package/2/packages/backend/convex/recordingFunctions.ts +0 -98
- package/2/packages/backend/convex/reportFunctions.ts +0 -344
- package/2/packages/backend/convex/reporting/index.ts +0 -9
- package/2/packages/backend/convex/router.ts +0 -81
- package/2/packages/backend/convex/schema.ts +0 -237
- package/2/packages/backend/convex/shared/email.ts +0 -172
- package/2/packages/backend/convex/shared/files.ts +0 -96
- package/2/packages/backend/convex/shared/index.ts +0 -17
- package/2/packages/backend/convex/shared/templates/PasswordResetEmail.tsx +0 -72
- package/2/packages/backend/convex/shared/templates/VerificationCodeEmail.tsx +0 -65
- package/2/packages/backend/convex/sharedUsers.ts +0 -48
- package/2/packages/backend/convex/tools/index.ts +0 -18
- package/2/packages/backend/convex/tools/knowledgeRetrieval.ts +0 -92
- package/2/packages/backend/convex/tools/tavilySearch.ts +0 -83
- package/2/packages/backend/convex/tools/userProfile.ts +0 -72
- package/2/packages/backend/convex/tsconfig.json +0 -25
- package/2/packages/backend/convex/users.ts +0 -54
- package/2/packages/backend/index.ts +0 -20
- package/2/packages/backend/package.json +0 -32
- package/2/packages/ui/README.md +0 -63
- package/2/packages/ui/index.ts +0 -1
- package/2/packages/ui/package.json +0 -21
- package/2/packages/ui/src/components/SharedButton.tsx +0 -31
- package/2/packages/ui/src/components/SharedCard.tsx +0 -48
- package/2/packages/ui/src/components/index.ts +0 -2
- package/2/packages/ui/tsconfig.json +0 -10
- package/2/pnpm-lock.yaml +0 -23292
- package/2/pnpm-workspace.yaml +0 -3
- package/2/scripts/i18next-syntax-validation.js +0 -1
- package/2/tsconfig.json +0 -43
- package/2/turbo.json +0 -33
- package/2/vercel.json +0 -6
- package/2/vf-agent/agent-teams/team-vibefast.yaml +0 -14
- package/2/vf-agent/agents/analyst.md +0 -53
- package/2/vf-agent/agents/architect.md +0 -105
- package/2/vf-agent/agents/dev.md +0 -40
- package/2/vf-agent/agents/orchestrator.md +0 -181
- package/2/vf-agent/agents/pm.md +0 -48
- package/2/vf-agent/agents/po.md +0 -38
- package/2/vf-agent/agents/qa.md +0 -30
- package/2/vf-agent/agents/sm.md +0 -38
- package/2/vf-agent/agents/ux-expert.md +0 -33
- package/2/vf-agent/checklists/po-master-checklist.md +0 -73
- package/2/vf-agent/checklists/story-dod-checklist.md +0 -37
- package/2/vf-agent/core-config.yaml +0 -43
- package/2/vf-agent/data/knowledge_base/backend/convex-advanced.md +0 -43
- package/2/vf-agent/data/knowledge_base/backend/convex-database.md +0 -53
- package/2/vf-agent/data/knowledge_base/backend/convex-main.md +0 -65
- package/2/vf-agent/data/knowledge_base/backend/full-guidelines.md +0 -795
- package/2/vf-agent/data/knowledge_base/coding-standards.md +0 -253
- package/2/vf-agent/data/knowledge_base/frontend/full-guidelines.md +0 -254
- package/2/vf-agent/data/knowledge_base/frontend/image-handling.md +0 -48
- package/2/vf-agent/data/knowledge_base/frontend/react-native-main.md +0 -24
- package/2/vf-agent/data/knowledge_base/frontend/ui-and-styling.md +0 -169
- package/2/vf-agent/data/knowledge_base/general-principles.md +0 -26
- package/2/vf-agent/data/knowledge_base/master-rulebook.md +0 -42
- package/2/vf-agent/data/knowledge_base/starter-docs/audio-recorder-reference.md +0 -98
- package/2/vf-agent/data/knowledge_base/starter-docs/authentication-reference.md +0 -155
- package/2/vf-agent/data/knowledge_base/starter-docs/charts-reference.md +0 -149
- package/2/vf-agent/data/knowledge_base/starter-docs/chatbot-reference.md +0 -123
- package/2/vf-agent/data/knowledge_base/starter-docs/feature-reference-index.md +0 -211
- package/2/vf-agent/data/knowledge_base/starter-docs/features-overview.md +0 -221
- package/2/vf-agent/data/knowledge_base/starter-docs/image-analyzer-reference.md +0 -118
- package/2/vf-agent/data/knowledge_base/starter-docs/image-generator-reference.md +0 -110
- package/2/vf-agent/data/knowledge_base/starter-docs/index.md +0 -28
- package/2/vf-agent/data/knowledge_base/starter-docs/onboarding-reference.md +0 -96
- package/2/vf-agent/data/knowledge_base/starter-docs/payments-reference.md +0 -148
- package/2/vf-agent/data/knowledge_base/starter-docs/prd.md +0 -82
- package/2/vf-agent/data/knowledge_base/starter-docs/push-notifications-reference.md +0 -453
- package/2/vf-agent/data/knowledge_base/starter-docs/quick-actions-reference.md +0 -253
- package/2/vf-agent/data/knowledge_base/starter-docs/quiz-reference.md +0 -169
- package/2/vf-agent/data/knowledge_base/starter-docs/settings-reference.md +0 -146
- package/2/vf-agent/data/knowledge_base/starter-docs/tech-stack.md +0 -159
- package/2/vf-agent/data/knowledge_base/starter-docs/tracker-app-reference.md +0 -150
- package/2/vf-agent/data/knowledge_base/starter-docs/unified-project-structure.md +0 -98
- package/2/vf-agent/data/knowledge_base/testing/backend-testing.md +0 -54
- package/2/vf-agent/data/knowledge_base/testing/frontend-testing.md +0 -71
- package/2/vf-agent/data/knowledge_base/testing/testing-strategy.md +0 -31
- package/2/vf-agent/tasks/advanced-elicitation.md +0 -117
- package/2/vf-agent/tasks/brownfield-create-epic.md +0 -160
- package/2/vf-agent/tasks/create-deep-research-prompt.md +0 -278
- package/2/vf-agent/tasks/create-doc.md +0 -42
- package/2/vf-agent/tasks/create-story.md +0 -43
- package/2/vf-agent/tasks/document-project.md +0 -343
- package/2/vf-agent/tasks/facilitate-brainstorming-session.md +0 -136
- package/2/vf-agent/tasks/index-docs.md +0 -173
- package/2/vf-agent/tasks/kb-mode-interaction.md +0 -75
- package/2/vf-agent/tasks/review-story.md +0 -154
- package/2/vf-agent/tasks/shard-doc.md +0 -185
- package/2/vf-agent/tasks/troubleshoot-issue.md +0 -65
- package/2/vf-agent/tasks/validate-next-story.md +0 -47
- package/2/vf-agent/templates/brainstorming-output-tmpl.yaml +0 -156
- package/2/vf-agent/templates/brownfield-architecture-tmpl.yaml +0 -111
- package/2/vf-agent/templates/brownfield-prd-tmpl.yaml +0 -247
- package/2/vf-agent/templates/competitor-analysis-tmpl.yaml +0 -293
- package/2/vf-agent/templates/market-research-tmpl.yaml +0 -252
- package/2/vf-agent/templates/project-brief-tmpl.yaml +0 -221
- package/2/vf-agent/templates/story-tmpl.yaml +0 -143
- package/recipes/0/apps/native/src/components/advanced-ui/timeline/demo.tsx +0 -444
- package/recipes/0/apps/native/src/components/advanced-ui/timeline/timeline-view.tsx +0 -355
- package/recipes/0/apps/native/src/components/advanced-ui/timeline/types.ts +0 -31
- package/recipes/wake-word/scripts/download-vosk-model.mjs +0 -121
- /package/{2 → recipes/animated-chip}/apps/native/src/components/advanced-ui/chip/animated-chip.tsx +0 -0
- /package/{2 → recipes/animated-chip}/apps/native/src/components/advanced-ui/chip/chip.tsx +0 -0
- /package/{2 → recipes/animated-chip}/apps/native/src/components/advanced-ui/chip/demo.tsx +0 -0
- /package/{2 → recipes/animated-chip}/apps/native/src/components/advanced-ui/chip/types.ts +0 -0
- /package/{2 → recipes/animated-switch}/apps/native/src/components/advanced-ui/switch/animated-switch.tsx +0 -0
- /package/{2 → recipes/animated-switch}/apps/native/src/components/advanced-ui/switch/demo.tsx +0 -0
- /package/{2 → recipes/animated-switch}/apps/native/src/components/advanced-ui/switch/types.ts +0 -0
- /package/{2 → recipes/glowing-button}/apps/native/src/components/advanced-ui/buttons/demo.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/assets/features/image-analyzer/front.jpg +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/assets/features/image-analyzer/side.jpg +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/assets/features/image-analyzer/threeQuarter.jpg +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/api-client/image-analyzer.ts +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/app/(root)/(protected)/analysis/[type]/_layout.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/app/(root)/(protected)/analysis/[type]/analysis-options.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/app/(root)/(protected)/analysis/[type]/camera.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/app/(root)/(protected)/analysis/[type]/index.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/app/(root)/(protected)/analysis/[type]/loading.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/app/(root)/(protected)/analysis/[type]/results.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/app/(root)/(protected)/analysis/[type]/trait-details.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/app/analysis-options-screen.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/app/camera.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/app/image-capture-screen.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/app/loading-screen.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/app/loading.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/app/results.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/app/trait-details.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/app/use-analysis-data.ts +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/app/use-results-screen.ts +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/components/results/achievement-badge.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/components/results/achievement-card.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/components/results/achievement-unlocked-modal.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/components/results/achievements-section.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/components/results/advice-list.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/components/results/circular-progress.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/components/results/content-card.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/components/results/error-state.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/components/results/index.ts +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/components/results/loading-state.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/components/results/profile-image.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/components/results/results-header.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/components/results/score-display.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/components/results/share-options-modal.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/components/results/traits-grid.tsx +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/config/analysis-config.ts +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/config/master-analysis-config.ts +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/hooks/index.ts +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/hooks/use-analysis.ts +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/hooks/use-image-analysis.ts +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/services/analysis-service.ts +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/services/share-service.ts +0 -0
- /package/{2 → recipes/image-analysis}/apps/native/src/features/image-analyzer/services/trait-details-service.ts +0 -0
- /package/{2 → recipes/image-analysis}/packages/backend/convex/imageAnalysis/index.ts +0 -0
- /package/{2 → recipes/image-analysis}/packages/backend/convex/imageAnalysisFunctions.ts +0 -0
- /package/{2 → recipes/image-analysis}/packages/backend/convex/lib/ai/imageAnalysisAdapter.ts +0 -0
- /package/{2 → recipes/number-stepper}/apps/native/src/components/advanced-ui/stepper/children/button/stepper-button.tsx +0 -0
- /package/{2 → recipes/number-stepper}/apps/native/src/components/advanced-ui/stepper/children/button/types.ts +0 -0
- /package/{2 → recipes/number-stepper}/apps/native/src/components/advanced-ui/stepper/children/content/stepper-content.tsx +0 -0
- /package/{2 → recipes/number-stepper}/apps/native/src/components/advanced-ui/stepper/children/content/types.ts +0 -0
- /package/{2 → recipes/number-stepper}/apps/native/src/components/advanced-ui/stepper/children/value/stepper-value.tsx +0 -0
- /package/{2 → recipes/number-stepper}/apps/native/src/components/advanced-ui/stepper/children/value/types.ts +0 -0
- /package/{2 → recipes/number-stepper}/apps/native/src/components/advanced-ui/stepper/context/stepper-context.ts +0 -0
- /package/{2 → recipes/number-stepper}/apps/native/src/components/advanced-ui/stepper/context/types.ts +0 -0
- /package/{2 → recipes/number-stepper}/apps/native/src/components/advanced-ui/stepper/demo.tsx +0 -0
- /package/{2 → recipes/number-stepper}/apps/native/src/components/advanced-ui/stepper/index.ts +0 -0
- /package/{2 → recipes/number-stepper}/apps/native/src/components/advanced-ui/stepper/stepper.tsx +0 -0
- /package/{2 → recipes/number-stepper}/apps/native/src/components/advanced-ui/stepper/types.ts +0 -0
- /package/{2 → recipes/progress-circle}/apps/native/src/components/advanced-ui/progress-bars/animated-progress-bar.tsx +0 -0
- /package/{2 → recipes/progress-circle}/apps/native/src/components/advanced-ui/progress-bars/dropdown-picker-page.tsx +0 -0
- /package/{2 → recipes/progress-circle}/apps/native/src/components/advanced-ui/progress-bars/progress-circle-page.tsx +0 -0
- /package/{2 → recipes/progress-circle}/apps/native/src/components/advanced-ui/progress-bars/progress-circle.tsx +0 -0
- /package/{2 → recipes/swipe-slider}/apps/native/src/components/advanced-ui/sliders/swipe-slider-page.tsx +0 -0
- /package/{2 → recipes/swipe-slider}/apps/native/src/components/advanced-ui/sliders/swipe-slider.tsx +0 -0
- /package/{2 → recipes/timeline}/apps/native/src/components/advanced-ui/timeline/demo.tsx +0 -0
- /package/{2 → recipes/timeline}/apps/native/src/components/advanced-ui/timeline/timeline-view.tsx +0 -0
- /package/{2 → recipes/timeline}/apps/native/src/components/advanced-ui/timeline/types.ts +0 -0
- /package/{2 → recipes/wake-word}/apps/native/scripts/download-vosk-model.mjs +0 -0
|
@@ -1,795 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: whenever you have to do anything related to convex, you can use it.
|
|
3
|
-
globs:
|
|
4
|
-
alwaysApply: false
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
these are convex db rules for react with convex, keep them as detailed and everytghign convex related same just change the react bits to react native expo stuff.
|
|
8
|
-
|
|
9
|
-
# Convex guidelines
|
|
10
|
-
|
|
11
|
-
> All `convex/...` paths below are relative to the monorepo package at `packages/backend/convex/`.
|
|
12
|
-
|
|
13
|
-
## Function guidelines
|
|
14
|
-
|
|
15
|
-
### New function syntax
|
|
16
|
-
|
|
17
|
-
- ALWAYS use the new function syntax for Convex functions. For example:
|
|
18
|
-
`typescript
|
|
19
|
-
import { query } from "./_generated/server";
|
|
20
|
-
import { v } from "convex/values";
|
|
21
|
-
export const f = query({
|
|
22
|
-
args: {},
|
|
23
|
-
returns: v.null(),
|
|
24
|
-
handler: async (ctx, args) => {
|
|
25
|
-
// Function body
|
|
26
|
-
},
|
|
27
|
-
});
|
|
28
|
-
`
|
|
29
|
-
|
|
30
|
-
### Http endpoint syntax
|
|
31
|
-
|
|
32
|
-
- HTTP endpoints are defined in `convex/http.ts` and require an `httpAction` decorator. For example:
|
|
33
|
-
`typescript
|
|
34
|
-
import { httpRouter } from "convex/server";
|
|
35
|
-
import { httpAction } from "./_generated/server";
|
|
36
|
-
const http = httpRouter();
|
|
37
|
-
http.route({
|
|
38
|
-
path: "/echo",
|
|
39
|
-
method: "POST",
|
|
40
|
-
handler: httpAction(async (ctx, req) => {
|
|
41
|
-
const body = await req.bytes();
|
|
42
|
-
return new Response(body, { status: 200 });
|
|
43
|
-
}),
|
|
44
|
-
});
|
|
45
|
-
`
|
|
46
|
-
- HTTP endpoints are always registered at the exact path you specify in the `path` field. For example, if you specify `/api/someRoute`, the endpoint will be registered at `/api/someRoute`.
|
|
47
|
-
|
|
48
|
-
### Validators
|
|
49
|
-
|
|
50
|
-
- Below is an example of an array validator:
|
|
51
|
-
```typescript
|
|
52
|
-
import { mutation } from "./\_generated/server";
|
|
53
|
-
import { v } from "convex/values";
|
|
54
|
-
|
|
55
|
-
export default mutation({
|
|
56
|
-
args: {
|
|
57
|
-
simpleArray: v.array(v.union(v.string(), v.number())),
|
|
58
|
-
},
|
|
59
|
-
handler: async (ctx, args) => {
|
|
60
|
-
//...
|
|
61
|
-
},
|
|
62
|
-
});
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
- Below is an example of a schema with validators that codify a discriminated union type:
|
|
66
|
-
```typescript
|
|
67
|
-
import { defineSchema, defineTable } from "convex/server";
|
|
68
|
-
import { v } from "convex/values";
|
|
69
|
-
|
|
70
|
-
export default defineSchema({
|
|
71
|
-
results: defineTable(
|
|
72
|
-
v.union(
|
|
73
|
-
v.object({
|
|
74
|
-
kind: v.literal("error"),
|
|
75
|
-
errorMessage: v.string(),
|
|
76
|
-
}),
|
|
77
|
-
v.object({
|
|
78
|
-
kind: v.literal("success"),
|
|
79
|
-
value: v.number(),
|
|
80
|
-
}),
|
|
81
|
-
),
|
|
82
|
-
)
|
|
83
|
-
});
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
- Always use the `v.null()` validator when returning a null value. Below is an example query that returns a null value:
|
|
87
|
-
```typescript
|
|
88
|
-
import { query } from "./\_generated/server";
|
|
89
|
-
import { v } from "convex/values";
|
|
90
|
-
|
|
91
|
-
export const exampleQuery = query({
|
|
92
|
-
args: {},
|
|
93
|
-
returns: v.null(),
|
|
94
|
-
handler: async (ctx, args) => {
|
|
95
|
-
console.log("This query returns a null value");
|
|
96
|
-
return null;
|
|
97
|
-
},
|
|
98
|
-
});
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
- Here are the valid Convex types along with their respective validators:
|
|
102
|
-
Convex Type | TS/JS type | Example Usage | Validator for argument validation and schemas | Notes |
|
|
103
|
-
| ----------- | ------------| -----------------------| -----------------------------------------------| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
104
|
-
| Id | string | `doc._id` | `v.id(tableName)` | |
|
|
105
|
-
| Null | null | `null` | `v.null()` | JavaScript's `undefined` is not a valid Convex value. Functions the return `undefined` or do not return will return `null` when called from a client. Use `null` instead. |
|
|
106
|
-
| Int64 | bigint | `3n` | `v.int64()` | Int64s only support BigInts between -2^63 and 2^63-1. Convex supports `bigint`s in most modern browsers. |
|
|
107
|
-
| Float64 | number | `3.1` | `v.number()` | Convex supports all IEEE-754 double-precision floating point numbers (such as NaNs). Inf and NaN are JSON serialized as strings. |
|
|
108
|
-
| Boolean | boolean | `true` | `v.boolean()` |
|
|
109
|
-
| String | string | `"abc"` | `v.string()` | Strings are stored as UTF-8 and must be valid Unicode sequences. Strings must be smaller than the 1MB total size limit when encoded as UTF-8. |
|
|
110
|
-
| Bytes | ArrayBuffer | `new ArrayBuffer(8)` | `v.bytes()` | Convex supports first class bytestrings, passed in as `ArrayBuffer`s. Bytestrings must be smaller than the 1MB total size limit for Convex types. |
|
|
111
|
-
| Array | Array] | `[1, 3.2, "abc"]` | `v.array(values)` | Arrays can have at most 8192 values. |
|
|
112
|
-
| Object | Object | `{a: "abc"}` | `v.object({property: value})` | Convex only supports "plain old JavaScript objects" (objects that do not have a custom prototype). Objects can have at most 1024 entries. Field names must be nonempty and not start with "$" or "_". |
|
|
113
|
-
| Record | Record | `{"a": "1", "b": "2"}` | `v.record(keys, values)` | Records are objects at runtime, but can have dynamic keys. Keys must be only ASCII characters, nonempty, and not start with "$" or "\_". |
|
|
114
|
-
|
|
115
|
-
### Function registration
|
|
116
|
-
|
|
117
|
-
- Use `internalQuery`, `internalMutation`, and `internalAction` to register internal functions. These functions are private and aren't part of an app's API. They can only be called by other Convex functions. These functions are always imported from `./_generated/server`.
|
|
118
|
-
- Use `query`, `mutation`, and `action` to register public functions. These functions are part of the public API and are exposed to the public Internet. Do NOT use `query`, `mutation`, or `action` to register sensitive internal functions that should be kept private.
|
|
119
|
-
- You CANNOT register a function through the `api` or `internal` objects.
|
|
120
|
-
- ALWAYS include argument and return validators for all Convex functions. This includes all of `query`, `internalQuery`, `mutation`, `internalMutation`, `action`, and `internalAction`. If a function doesn't return anything, include `returns: v.null()` as its output validator.
|
|
121
|
-
- If the JavaScript implementation of a Convex function doesn't have a return value, it implicitly returns `null`.
|
|
122
|
-
|
|
123
|
-
### Function calling
|
|
124
|
-
|
|
125
|
-
- Use `ctx.runQuery` to call a query from a query, mutation, or action.
|
|
126
|
-
- Use `ctx.runMutation` to call a mutation from a mutation or action.
|
|
127
|
-
- Use `ctx.runAction` to call an action from an action.
|
|
128
|
-
- ONLY call an action from another action if you need to cross runtimes (e.g. from V8 to Node). Otherwise, pull out the shared code into a helper async function and call that directly instead.
|
|
129
|
-
- Try to use as few calls from actions to queries and mutations as possible. Queries and mutations are transactions, so splitting logic up into multiple calls introduces the risk of race conditions.
|
|
130
|
-
- All of these calls take in a `FunctionReference`. Do NOT try to pass the callee function directly into one of these calls.
|
|
131
|
-
- When using `ctx.runQuery`, `ctx.runMutation`, or `ctx.runAction` to call a function in the same file, specify a type annotation on the return value to work around TypeScript circularity limitations. For example,
|
|
132
|
-
```
|
|
133
|
-
export const f = query({
|
|
134
|
-
args: { name: v.string() },
|
|
135
|
-
returns: v.string(),
|
|
136
|
-
handler: async (ctx, args) => {
|
|
137
|
-
return "Hello " + args.name;
|
|
138
|
-
},
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
export const g = query({
|
|
142
|
-
args: {},
|
|
143
|
-
returns: v.null(),
|
|
144
|
-
handler: async (ctx, args) => {
|
|
145
|
-
const result: string = await ctx.runQuery(api.example.f, { name: "Bob" });
|
|
146
|
-
return null;
|
|
147
|
-
},
|
|
148
|
-
});
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
### Function references
|
|
152
|
-
|
|
153
|
-
- Function references are pointers to registered Convex functions.
|
|
154
|
-
- Use the `api` object defined by the framework in `convex/_generated/api.ts` to call public functions registered with `query`, `mutation`, or `action`.
|
|
155
|
-
- Use the `internal` object defined by the framework in `convex/_generated/api.ts` to call internal (or private) functions registered with `internalQuery`, `internalMutation`, or `internalAction`.
|
|
156
|
-
- Convex uses file-based routing, so a public function defined in `convex/example.ts` named `f` has a function reference of `api.example.f`.
|
|
157
|
-
- A private function defined in `convex/example.ts` named `g` has a function reference of `internal.example.g`.
|
|
158
|
-
- Functions can also registered within directories nested within the `convex/` folder. For example, a public function `h` defined in `convex/messages/access.ts` has a function reference of `api.messages.access.h`.
|
|
159
|
-
|
|
160
|
-
### Api design
|
|
161
|
-
|
|
162
|
-
- Convex uses file-based routing, so thoughtfully organize files with public query, mutation, or action functions within the `convex/` directory.
|
|
163
|
-
- Use `query`, `mutation`, and `action` to define public functions.
|
|
164
|
-
- Use `internalQuery`, `internalMutation`, and `internalAction` to define private, internal functions.
|
|
165
|
-
|
|
166
|
-
### Pagination
|
|
167
|
-
|
|
168
|
-
- Paginated queries are queries that return a list of results in incremental pages.
|
|
169
|
-
- You can define pagination using the following syntax:
|
|
170
|
-
|
|
171
|
-
```ts
|
|
172
|
-
import { v } from "convex/values";
|
|
173
|
-
import { query, mutation } from "./_generated/server";
|
|
174
|
-
import { paginationOptsValidator } from "convex/server";
|
|
175
|
-
export const listWithExtraArg = query({
|
|
176
|
-
args: { paginationOpts: paginationOptsValidator, author: v.string() },
|
|
177
|
-
handler: async (ctx, args) => {
|
|
178
|
-
return await ctx.db
|
|
179
|
-
.query("messages")
|
|
180
|
-
.filter((q) => q.eq(q.field("author"), args.author))
|
|
181
|
-
.order("desc")
|
|
182
|
-
.paginate(args.paginationOpts);
|
|
183
|
-
},
|
|
184
|
-
});
|
|
185
|
-
```
|
|
186
|
-
Note: `paginationOpts` is an object with the following properties:
|
|
187
|
-
- `numItems`: the maximum number of documents to return (the validator is `v.number()`)
|
|
188
|
-
- `cursor`: the cursor to use to fetch the next page of documents (the validator is `v.union(v.string(), v.null())`)
|
|
189
|
-
|
|
190
|
-
- A query that ends in `.paginate()` returns an object that has the following properties: - page (contains an array of documents that you fetches) - isDone (a boolean that represents whether or not this is the last page of documents) - continueCursor (a string that represents the cursor to use to fetch the next page of documents)
|
|
191
|
-
|
|
192
|
-
## Validator guidelines
|
|
193
|
-
|
|
194
|
-
- `v.bigint()` is deprecated for representing signed 64-bit integers. Use `v.int64()` instead.
|
|
195
|
-
- Use `v.record()` for defining a record type. `v.map()` and `v.set()` are not supported.
|
|
196
|
-
|
|
197
|
-
## Schema guidelines
|
|
198
|
-
|
|
199
|
-
- Always define your schema in `convex/schema.ts`.
|
|
200
|
-
- Always import the schema definition functions from `convex/server`:
|
|
201
|
-
- System fields are automatically added to all documents and are prefixed with an underscore. The two system fields that are automatically added to all documents are `_creationTime` which has the validator `v.number()` and `_id` which has the validator `v.id(tableName)`.
|
|
202
|
-
- Always include all index fields in the index name. For example, if an index is defined as `["field1", "field2"]`, the index name should be "by_field1_and_field2".
|
|
203
|
-
- Index fields must be queried in the same order they are defined. If you want to be able to query by "field1" then "field2" and by "field2" then "field1", you must create separate indexes.
|
|
204
|
-
|
|
205
|
-
## Typescript guidelines
|
|
206
|
-
|
|
207
|
-
- You can use the helper typescript type `Id` imported from './\_generated/dataModel' to get the type of the id for a given table. For example if there is a table called 'users' you can use `Id<'users'>` to get the type of the id for that table.
|
|
208
|
-
- If you need to define a `Record` make sure that you correctly provide the type of the key and value in the type. For example a validator `v.record(v.id('users'), v.string())` would have the type `Record<Id<'users'>, string>`. Below is an example of using `Record` with an `Id` type in a query:
|
|
209
|
-
```ts
|
|
210
|
-
import { query } from "./\_generated/server";
|
|
211
|
-
import { Doc, Id } from "./\_generated/dataModel";
|
|
212
|
-
|
|
213
|
-
export const exampleQuery = query({
|
|
214
|
-
args: { userIds: v.array(v.id("users")) },
|
|
215
|
-
returns: v.record(v.id("users"), v.string()),
|
|
216
|
-
handler: async (ctx, args) => {
|
|
217
|
-
const idToUsername: Record<Id<"users">, string> = {};
|
|
218
|
-
for (const userId of args.userIds) {
|
|
219
|
-
const user = await ctx.db.get(userId);
|
|
220
|
-
if (user) {
|
|
221
|
-
users[user._id] = user.username;
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
return idToUsername;
|
|
226
|
-
},
|
|
227
|
-
});
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
- Be strict with types, particularly around id's of documents. For example, if a function takes in an id for a document in the 'users' table, take in `Id<'users'>` rather than `string`.
|
|
231
|
-
- Always use `as const` for string literals in discriminated union types.
|
|
232
|
-
- When using the `Array` type, make sure to always define your arrays as `const array: Array<T> = [...];`
|
|
233
|
-
- When using the `Record` type, make sure to always define your records as `const record: Record<KeyType, ValueType> = {...};`
|
|
234
|
-
- Always add `@types/node` to your `package.json` when using any Node.js built-in modules.
|
|
235
|
-
|
|
236
|
-
## Full text search guidelines
|
|
237
|
-
|
|
238
|
-
- A query for "10 messages in channel '#general' that best match the query 'hello hi' in their body" would look like:
|
|
239
|
-
|
|
240
|
-
const messages = await ctx.db
|
|
241
|
-
.query("messages")
|
|
242
|
-
.withSearchIndex("search_body", (q) =>
|
|
243
|
-
q.search("body", "hello hi").eq("channel", "#general"),
|
|
244
|
-
)
|
|
245
|
-
.take(10);
|
|
246
|
-
|
|
247
|
-
## Query guidelines
|
|
248
|
-
|
|
249
|
-
- Do NOT use `filter` in queries. Instead, define an index in the schema and use `withIndex` instead.
|
|
250
|
-
- Convex queries do NOT support `.delete()`. Instead, `.collect()` the results, iterate over them, and call `ctx.db.delete(row._id)` on each result.
|
|
251
|
-
- Use `.unique()` to get a single document from a query. This method will throw an error if there are multiple documents that match the query.
|
|
252
|
-
- When using async iteration, don't use `.collect()` or `.take(n)` on the result of a query. Instead, use the `for await (const row of query)` syntax.
|
|
253
|
-
|
|
254
|
-
### Ordering
|
|
255
|
-
|
|
256
|
-
- By default Convex always returns documents in ascending `_creationTime` order.
|
|
257
|
-
- You can use `.order('asc')` or `.order('desc')` to pick whether a query is in ascending or descending order. If the order isn't specified, it defaults to ascending.
|
|
258
|
-
- Document queries that use indexes will be ordered based on the columns in the index and can avoid slow table scans.
|
|
259
|
-
|
|
260
|
-
## Mutation guidelines
|
|
261
|
-
|
|
262
|
-
- Use `ctx.db.replace` to fully replace an existing document. This method will throw an error if the document does not exist.
|
|
263
|
-
- Use `ctx.db.patch` to shallow merge updates into an existing document. This method will throw an error if the document does not exist.
|
|
264
|
-
|
|
265
|
-
## Action guidelines
|
|
266
|
-
|
|
267
|
-
- Always add `"use node";` to the top of files containing actions that use Node.js built-in modules.
|
|
268
|
-
- Never use `ctx.db` inside of an action. Actions don't have access to the database.
|
|
269
|
-
- Below is an example of the syntax for an action:
|
|
270
|
-
```ts
|
|
271
|
-
import { action } from "./\_generated/server";
|
|
272
|
-
|
|
273
|
-
export const exampleAction = action({
|
|
274
|
-
args: {},
|
|
275
|
-
returns: v.null(),
|
|
276
|
-
handler: async (ctx, args) => {
|
|
277
|
-
console.log("This action does not return anything");
|
|
278
|
-
return null;
|
|
279
|
-
},
|
|
280
|
-
});
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
## Scheduling guidelines
|
|
284
|
-
|
|
285
|
-
### Cron guidelines
|
|
286
|
-
|
|
287
|
-
- Only use the `crons.interval` or `crons.cron` methods to schedule cron jobs. Do NOT use the `crons.hourly`, `crons.daily`, or `crons.weekly` helpers.
|
|
288
|
-
- Both cron methods take in a FunctionReference. Do NOT try to pass the function directly into one of these methods.
|
|
289
|
-
- Define crons by declaring the top-level `crons` object, calling some methods on it, and then exporting it as default. For example,
|
|
290
|
-
```ts
|
|
291
|
-
import { cronJobs } from "convex/server";
|
|
292
|
-
import { internal } from "./\_generated/api";
|
|
293
|
-
import { internalAction } from "./\_generated/server";
|
|
294
|
-
|
|
295
|
-
const empty = internalAction({
|
|
296
|
-
args: {},
|
|
297
|
-
returns: v.null(),
|
|
298
|
-
handler: async (ctx, args) => {
|
|
299
|
-
console.log("empty");
|
|
300
|
-
},
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
const crons = cronJobs();
|
|
304
|
-
|
|
305
|
-
// Run `internal.crons.empty` every two hours.
|
|
306
|
-
crons.interval("delete inactive users", { hours: 2 }, internal.crons.empty, {});
|
|
307
|
-
|
|
308
|
-
export default crons;
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
- You can register Convex functions within `crons.ts` just like any other file.
|
|
312
|
-
- If a cron calls an internal function, always import the `internal` object from '\_generated/api`, even if the internal function is registered in the same file.
|
|
313
|
-
|
|
314
|
-
## File storage guidelines
|
|
315
|
-
|
|
316
|
-
- Convex includes file storage for large files like images, videos, and PDFs.
|
|
317
|
-
- The `ctx.storage.getUrl()` method returns a signed URL for a given file. It returns `null` if the file doesn't exist.
|
|
318
|
-
- Do NOT use the deprecated `ctx.storage.getMetadata` call for loading a file's metadata.
|
|
319
|
-
|
|
320
|
-
Instead, query the `_storage` system table. For example, you can use `ctx.db.system.get` to get an `Id<"_storage">`.
|
|
321
|
-
```
|
|
322
|
-
import { query } from "./_generated/server";
|
|
323
|
-
import { Id } from "./_generated/dataModel";
|
|
324
|
-
|
|
325
|
-
type FileMetadata = {
|
|
326
|
-
_id: Id<"_storage">;
|
|
327
|
-
_creationTime: number;
|
|
328
|
-
contentType?: string;
|
|
329
|
-
sha256: string;
|
|
330
|
-
size: number;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
export const exampleQuery = query({
|
|
334
|
-
args: { fileId: v.id("_storage") },
|
|
335
|
-
returns: v.null();
|
|
336
|
-
handler: async (ctx, args) => {
|
|
337
|
-
const metadata: FileMetadata | null = await ctx.db.system.get(args.fileId);
|
|
338
|
-
console.log(metadata);
|
|
339
|
-
return null;
|
|
340
|
-
},
|
|
341
|
-
});
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
- Convex storage stores items as `Blob` objects. You must convert all items to/from a `Blob` when using Convex storage.
|
|
345
|
-
|
|
346
|
-
# Examples:
|
|
347
|
-
|
|
348
|
-
## Example: chat-app
|
|
349
|
-
|
|
350
|
-
### Task
|
|
351
|
-
|
|
352
|
-
```
|
|
353
|
-
Create a real-time chat application backend with AI responses. The app should:
|
|
354
|
-
- Allow creating users with names
|
|
355
|
-
- Support multiple chat channels
|
|
356
|
-
- Enable users to send messages to channels
|
|
357
|
-
- Automatically generate AI responses to user messages
|
|
358
|
-
- Show recent message history
|
|
359
|
-
|
|
360
|
-
The backend should provide APIs for:
|
|
361
|
-
1. User management (creation)
|
|
362
|
-
2. Channel management (creation)
|
|
363
|
-
3. Message operations (sending, listing)
|
|
364
|
-
4. AI response generation using OpenAI's GPT-4
|
|
365
|
-
|
|
366
|
-
Messages should be stored with their channel, author, and content. The system should maintain message order
|
|
367
|
-
and limit history display to the 10 most recent messages per channel.
|
|
368
|
-
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
### Analysis
|
|
372
|
-
|
|
373
|
-
1. Task Requirements Summary:
|
|
374
|
-
|
|
375
|
-
- Build a real-time chat backend with AI integration
|
|
376
|
-
- Support user creation
|
|
377
|
-
- Enable channel-based conversations
|
|
378
|
-
- Store and retrieve messages with proper ordering
|
|
379
|
-
- Generate AI responses automatically
|
|
380
|
-
|
|
381
|
-
2. Main Components Needed:
|
|
382
|
-
|
|
383
|
-
- Database tables: users, channels, messages
|
|
384
|
-
- Public APIs for user/channel management
|
|
385
|
-
- Message handling functions
|
|
386
|
-
- Internal AI response generation system
|
|
387
|
-
- Context loading for AI responses
|
|
388
|
-
|
|
389
|
-
3. Public API and Internal Functions Design:
|
|
390
|
-
Public Mutations:
|
|
391
|
-
|
|
392
|
-
- createUser:
|
|
393
|
-
- file path: convex/index.ts
|
|
394
|
-
- arguments: {name: v.string()}
|
|
395
|
-
- returns: v.object({userId: v.id("users")})
|
|
396
|
-
- purpose: Create a new user with a given name
|
|
397
|
-
- createChannel:
|
|
398
|
-
- file path: convex/index.ts
|
|
399
|
-
- arguments: {name: v.string()}
|
|
400
|
-
- returns: v.object({channelId: v.id("channels")})
|
|
401
|
-
- purpose: Create a new channel with a given name
|
|
402
|
-
- sendMessage:
|
|
403
|
-
- file path: convex/index.ts
|
|
404
|
-
- arguments: {channelId: v.id("channels"), authorId: v.id("users"), content: v.string()}
|
|
405
|
-
- returns: v.null()
|
|
406
|
-
- purpose: Send a message to a channel and schedule a response from the AI
|
|
407
|
-
|
|
408
|
-
Public Queries:
|
|
409
|
-
|
|
410
|
-
- listMessages:
|
|
411
|
-
- file path: convex/index.ts
|
|
412
|
-
- arguments: {channelId: v.id("channels")}
|
|
413
|
-
- returns: v.array(v.object({
|
|
414
|
-
\_id: v.id("messages"),
|
|
415
|
-
\_creationTime: v.number(),
|
|
416
|
-
channelId: v.id("channels"),
|
|
417
|
-
authorId: v.optional(v.id("users")),
|
|
418
|
-
content: v.string(),
|
|
419
|
-
}))
|
|
420
|
-
- purpose: List the 10 most recent messages from a channel in descending creation order
|
|
421
|
-
|
|
422
|
-
Internal Functions:
|
|
423
|
-
|
|
424
|
-
- generateResponse:
|
|
425
|
-
- file path: convex/index.ts
|
|
426
|
-
- arguments: {channelId: v.id("channels")}
|
|
427
|
-
- returns: v.null()
|
|
428
|
-
- purpose: Generate a response from the AI for a given channel
|
|
429
|
-
- loadContext:
|
|
430
|
-
- file path: convex/index.ts
|
|
431
|
-
- arguments: {channelId: v.id("channels")}
|
|
432
|
-
- returns: v.array(v.object({
|
|
433
|
-
\_id: v.id("messages"),
|
|
434
|
-
\_creationTime: v.number(),
|
|
435
|
-
channelId: v.id("channels"),
|
|
436
|
-
authorId: v.optional(v.id("users")),
|
|
437
|
-
content: v.string(),
|
|
438
|
-
}))
|
|
439
|
-
- writeAgentResponse:
|
|
440
|
-
- file path: convex/index.ts
|
|
441
|
-
- arguments: {channelId: v.id("channels"), content: v.string()}
|
|
442
|
-
- returns: v.null()
|
|
443
|
-
- purpose: Write an AI response to a given channel
|
|
444
|
-
|
|
445
|
-
4. Schema Design:
|
|
446
|
-
|
|
447
|
-
- users
|
|
448
|
-
- validator: { name: v.string() }
|
|
449
|
-
- indexes: <none>
|
|
450
|
-
- channels
|
|
451
|
-
- validator: { name: v.string() }
|
|
452
|
-
- indexes: <none>
|
|
453
|
-
- messages
|
|
454
|
-
- validator: { channelId: v.id("channels"), authorId: v.optional(v.id("users")), content: v.string() }
|
|
455
|
-
- indexes
|
|
456
|
-
- by_channel: ["channelId"]
|
|
457
|
-
|
|
458
|
-
5. Background Processing:
|
|
459
|
-
|
|
460
|
-
- AI response generation runs asynchronously after each user message
|
|
461
|
-
- Uses OpenAI's GPT-4 to generate contextual responses
|
|
462
|
-
- Maintains conversation context using recent message history
|
|
463
|
-
|
|
464
|
-
### Implementation
|
|
465
|
-
|
|
466
|
-
#### package.json
|
|
467
|
-
|
|
468
|
-
```typescript
|
|
469
|
-
{
|
|
470
|
-
"name": "chat-app",
|
|
471
|
-
"description": "This example shows how to build a chat app without authentication.",
|
|
472
|
-
"version": "1.0.0",
|
|
473
|
-
"dependencies": {
|
|
474
|
-
"convex": "^1.17.4",
|
|
475
|
-
"openai": "^4.79.0"
|
|
476
|
-
},
|
|
477
|
-
"devDependencies": {
|
|
478
|
-
"typescript": "^5.7.3"
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
```
|
|
482
|
-
|
|
483
|
-
#### tsconfig.json
|
|
484
|
-
|
|
485
|
-
```typescript
|
|
486
|
-
{
|
|
487
|
-
"compilerOptions": {
|
|
488
|
-
"target": "ESNext",
|
|
489
|
-
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
|
490
|
-
"skipLibCheck": true,
|
|
491
|
-
"allowSyntheticDefaultImports": true,
|
|
492
|
-
"strict": true,
|
|
493
|
-
"forceConsistentCasingInFileNames": true,
|
|
494
|
-
"module": "ESNext",
|
|
495
|
-
"moduleResolution": "Bundler",
|
|
496
|
-
"resolveJsonModule": true,
|
|
497
|
-
"isolatedModules": true,
|
|
498
|
-
"allowImportingTsExtensions": true,
|
|
499
|
-
"noEmit": true,
|
|
500
|
-
"jsx": "react-jsx"
|
|
501
|
-
},
|
|
502
|
-
"exclude": ["convex"],
|
|
503
|
-
"include": ["**/src/**/*.tsx", "**/src/**/*.ts", "vite.config.ts"]
|
|
504
|
-
}
|
|
505
|
-
```
|
|
506
|
-
|
|
507
|
-
#### convex/index.ts
|
|
508
|
-
|
|
509
|
-
```typescript
|
|
510
|
-
import {
|
|
511
|
-
query,
|
|
512
|
-
mutation,
|
|
513
|
-
internalQuery,
|
|
514
|
-
internalMutation,
|
|
515
|
-
internalAction,
|
|
516
|
-
} from './_generated/server';
|
|
517
|
-
import { v } from 'convex/values';
|
|
518
|
-
import OpenAI from 'openai';
|
|
519
|
-
import { internal } from './_generated/api';
|
|
520
|
-
|
|
521
|
-
/**
|
|
522
|
-
* Create a user with a given name.
|
|
523
|
-
*/
|
|
524
|
-
export const createUser = mutation({
|
|
525
|
-
args: {
|
|
526
|
-
name: v.string(),
|
|
527
|
-
},
|
|
528
|
-
returns: v.id('users'),
|
|
529
|
-
handler: async (ctx, args) => {
|
|
530
|
-
return await ctx.db.insert('users', { name: args.name });
|
|
531
|
-
},
|
|
532
|
-
});
|
|
533
|
-
|
|
534
|
-
/**
|
|
535
|
-
* Create a channel with a given name.
|
|
536
|
-
*/
|
|
537
|
-
export const createChannel = mutation({
|
|
538
|
-
args: {
|
|
539
|
-
name: v.string(),
|
|
540
|
-
},
|
|
541
|
-
returns: v.id('channels'),
|
|
542
|
-
handler: async (ctx, args) => {
|
|
543
|
-
return await ctx.db.insert('channels', { name: args.name });
|
|
544
|
-
},
|
|
545
|
-
});
|
|
546
|
-
|
|
547
|
-
/**
|
|
548
|
-
* List the 10 most recent messages from a channel in descending creation order.
|
|
549
|
-
*/
|
|
550
|
-
export const listMessages = query({
|
|
551
|
-
args: {
|
|
552
|
-
channelId: v.id('channels'),
|
|
553
|
-
},
|
|
554
|
-
returns: v.array(
|
|
555
|
-
v.object({
|
|
556
|
-
_id: v.id('messages'),
|
|
557
|
-
_creationTime: v.number(),
|
|
558
|
-
channelId: v.id('channels'),
|
|
559
|
-
authorId: v.optional(v.id('users')),
|
|
560
|
-
content: v.string(),
|
|
561
|
-
}),
|
|
562
|
-
),
|
|
563
|
-
handler: async (ctx, args) => {
|
|
564
|
-
const messages = await ctx.db
|
|
565
|
-
.query('messages')
|
|
566
|
-
.withIndex('by_channel', (q) => q.eq('channelId', args.channelId))
|
|
567
|
-
.order('desc')
|
|
568
|
-
.take(10);
|
|
569
|
-
return messages;
|
|
570
|
-
},
|
|
571
|
-
});
|
|
572
|
-
|
|
573
|
-
/**
|
|
574
|
-
* Send a message to a channel and schedule a response from the AI.
|
|
575
|
-
*/
|
|
576
|
-
export const sendMessage = mutation({
|
|
577
|
-
args: {
|
|
578
|
-
channelId: v.id('channels'),
|
|
579
|
-
authorId: v.id('users'),
|
|
580
|
-
content: v.string(),
|
|
581
|
-
},
|
|
582
|
-
returns: v.null(),
|
|
583
|
-
handler: async (ctx, args) => {
|
|
584
|
-
const channel = await ctx.db.get(args.channelId);
|
|
585
|
-
if (!channel) {
|
|
586
|
-
throw new Error('Channel not found');
|
|
587
|
-
}
|
|
588
|
-
const user = await ctx.db.get(args.authorId);
|
|
589
|
-
if (!user) {
|
|
590
|
-
throw new Error('User not found');
|
|
591
|
-
}
|
|
592
|
-
await ctx.db.insert('messages', {
|
|
593
|
-
channelId: args.channelId,
|
|
594
|
-
authorId: args.authorId,
|
|
595
|
-
content: args.content,
|
|
596
|
-
});
|
|
597
|
-
await ctx.scheduler.runAfter(0, internal.index.generateResponse, {
|
|
598
|
-
channelId: args.channelId,
|
|
599
|
-
});
|
|
600
|
-
return null;
|
|
601
|
-
},
|
|
602
|
-
});
|
|
603
|
-
|
|
604
|
-
const openai = new OpenAI();
|
|
605
|
-
|
|
606
|
-
export const generateResponse = internalAction({
|
|
607
|
-
args: {
|
|
608
|
-
channelId: v.id('channels'),
|
|
609
|
-
},
|
|
610
|
-
returns: v.null(),
|
|
611
|
-
handler: async (ctx, args) => {
|
|
612
|
-
const context = await ctx.runQuery(internal.index.loadContext, {
|
|
613
|
-
channelId: args.channelId,
|
|
614
|
-
});
|
|
615
|
-
const response = await openai.chat.completions.create({
|
|
616
|
-
model: 'gpt-4.1-nano',
|
|
617
|
-
messages: context,
|
|
618
|
-
});
|
|
619
|
-
const content = response.choices[0].message.content;
|
|
620
|
-
if (!content) {
|
|
621
|
-
throw new Error('No content in response');
|
|
622
|
-
}
|
|
623
|
-
await ctx.runMutation(internal.index.writeAgentResponse, {
|
|
624
|
-
channelId: args.channelId,
|
|
625
|
-
content,
|
|
626
|
-
});
|
|
627
|
-
return null;
|
|
628
|
-
},
|
|
629
|
-
});
|
|
630
|
-
|
|
631
|
-
export const loadContext = internalQuery({
|
|
632
|
-
args: {
|
|
633
|
-
channelId: v.id('channels'),
|
|
634
|
-
},
|
|
635
|
-
returns: v.array(
|
|
636
|
-
v.object({
|
|
637
|
-
role: v.union(v.literal('user'), v.literal('assistant')),
|
|
638
|
-
content: v.string(),
|
|
639
|
-
}),
|
|
640
|
-
),
|
|
641
|
-
handler: async (ctx, args) => {
|
|
642
|
-
const channel = await ctx.db.get(args.channelId);
|
|
643
|
-
if (!channel) {
|
|
644
|
-
throw new Error('Channel not found');
|
|
645
|
-
}
|
|
646
|
-
const messages = await ctx.db
|
|
647
|
-
.query('messages')
|
|
648
|
-
.withIndex('by_channel', (q) => q.eq('channelId', args.channelId))
|
|
649
|
-
.order('desc')
|
|
650
|
-
.take(10);
|
|
651
|
-
|
|
652
|
-
const result = [];
|
|
653
|
-
for (const message of messages) {
|
|
654
|
-
if (message.authorId) {
|
|
655
|
-
const user = await ctx.db.get(message.authorId);
|
|
656
|
-
if (!user) {
|
|
657
|
-
throw new Error('User not found');
|
|
658
|
-
}
|
|
659
|
-
result.push({
|
|
660
|
-
role: 'user' as const,
|
|
661
|
-
content: `${user.name}: ${message.content}`,
|
|
662
|
-
});
|
|
663
|
-
} else {
|
|
664
|
-
result.push({ role: 'assistant' as const, content: message.content });
|
|
665
|
-
}
|
|
666
|
-
}
|
|
667
|
-
return result;
|
|
668
|
-
},
|
|
669
|
-
});
|
|
670
|
-
|
|
671
|
-
export const writeAgentResponse = internalMutation({
|
|
672
|
-
args: {
|
|
673
|
-
channelId: v.id('channels'),
|
|
674
|
-
content: v.string(),
|
|
675
|
-
},
|
|
676
|
-
returns: v.null(),
|
|
677
|
-
handler: async (ctx, args) => {
|
|
678
|
-
await ctx.db.insert('messages', {
|
|
679
|
-
channelId: args.channelId,
|
|
680
|
-
content: args.content,
|
|
681
|
-
});
|
|
682
|
-
return null;
|
|
683
|
-
},
|
|
684
|
-
});
|
|
685
|
-
```
|
|
686
|
-
|
|
687
|
-
#### convex/schema.ts
|
|
688
|
-
|
|
689
|
-
```typescript
|
|
690
|
-
import { defineSchema, defineTable } from 'convex/server';
|
|
691
|
-
import { v } from 'convex/values';
|
|
692
|
-
|
|
693
|
-
export default defineSchema({
|
|
694
|
-
channels: defineTable({
|
|
695
|
-
name: v.string(),
|
|
696
|
-
}),
|
|
697
|
-
|
|
698
|
-
users: defineTable({
|
|
699
|
-
name: v.string(),
|
|
700
|
-
}),
|
|
701
|
-
|
|
702
|
-
messages: defineTable({
|
|
703
|
-
channelId: v.id('channels'),
|
|
704
|
-
authorId: v.optional(v.id('users')),
|
|
705
|
-
content: v.string(),
|
|
706
|
-
}).index('by_channel', ['channelId']),
|
|
707
|
-
});
|
|
708
|
-
```
|
|
709
|
-
|
|
710
|
-
**Some more rule:**
|
|
711
|
-
|
|
712
|
-
**1. Regarding Convex Function Environments:**
|
|
713
|
-
|
|
714
|
-
```markdown
|
|
715
|
-
### Convex Function Environments and Node.js Dependencies (`"use node";`)
|
|
716
|
-
|
|
717
|
-
- Convex `queries` and `mutations` execute in a secure V8 isolate environment with access to a limited set of Node.js APIs and only those npm packages that are compatible with this environment.
|
|
718
|
-
- Convex `actions` can optionally run in a full Node.js environment by including the directive `"use node";` as the absolute first line of the file. This is essential when an action needs to:
|
|
719
|
-
- Utilize npm packages that have deep Node.js system dependencies (e.g., native file system access, certain crypto libraries not available in the V8 isolate, complex image/video processing libraries).
|
|
720
|
-
- Perform long-running operations or tasks that might exceed the typical V8 isolate limits.
|
|
721
|
-
- **Carefully evaluate if `"use node";` is necessary.** While it provides greater flexibility, it may also have implications for cold start times compared to standard actions. Prefer the standard V8 action environment if your dependencies and logic are compatible.
|
|
722
|
-
- **HTTP Actions (`httpAction`):** These run in the standard Vercel V8 isolate environment and **CANNOT** use the `"use node";` directive. If an `httpAction` needs to execute logic requiring a full Node.js environment, it MUST delegate that specific part of the work by calling a separate, regular `action` (which _can_ be marked with `"use node";`).
|
|
723
|
-
```
|
|
724
|
-
|
|
725
|
-
**2. Implementing Streaming HTTP Actions in Convex (Generic Pattern):**
|
|
726
|
-
|
|
727
|
-
```markdown
|
|
728
|
-
### Implementing Streaming HTTP Actions in Convex
|
|
729
|
-
|
|
730
|
-
- To return a streaming response from a Convex `httpAction` (e.g., for Server-Sent Events, chunked JSON, or text streams):
|
|
731
|
-
1. The `httpAction` handler function (`async (ctx, request) => { ... }`) MUST return a standard `Response` object.
|
|
732
|
-
2. The `body` of this `Response` object MUST be a `ReadableStream`.
|
|
733
|
-
3. Within the `ReadableStream`'s `start(controller)` method:
|
|
734
|
-
- Iterate over your source of data chunks (e.g., from an internal process, another stream, or a generator function).
|
|
735
|
-
- For each data chunk, use `controller.enqueue(encoder.encode(chunk))` to send it to the client. An appropriate `TextEncoder` should be used for text-based streams. For binary streams, enqueue `Uint8Array` chunks directly.
|
|
736
|
-
- Call `controller.close()` when all data has been sent.
|
|
737
|
-
- Implement robust error handling within the stream's `start` method, calling `controller.error(e)` if an issue occurs during streaming.
|
|
738
|
-
4. Set appropriate HTTP headers on the `Response` object, such as `Content-Type` (e.g., `text/event-stream`, `application/octet-stream`, `text/plain; charset=utf-8`) and `Transfer-Encoding: chunked` (though `Transfer-Encoding` is often handled by the environment if a `ReadableStream` body is used).
|
|
739
|
-
- **Important:** Do NOT use `ctx.stream.write()` or `ctx.stream.close()` (which are for regular `action` streaming context) within an `httpAction` handler that returns a `Response` object with a `ReadableStream` body.
|
|
740
|
-
```
|
|
741
|
-
|
|
742
|
-
**3. Authentication for Convex HTTP Actions (Generic):**
|
|
743
|
-
|
|
744
|
-
```markdown
|
|
745
|
-
### Authentication in Convex HTTP Actions
|
|
746
|
-
|
|
747
|
-
- All Convex `httpAction`s that require user authentication MUST validate the session or incoming credentials.
|
|
748
|
-
- **Session-Based (Recommended for User-Facing Endpoints):**
|
|
749
|
-
- The client application SHOULD fetch the current Convex session token (e.g., `await convex.session?.getToken()`) and send it in the `Authorization: Bearer <TOKEN>` HTTP header.
|
|
750
|
-
- Inside the `httpAction` handler, use `const identity = await ctx.auth.getUserIdentity();` to verify the session based on the token automatically processed by Convex from the header/cookie.
|
|
751
|
-
- If `identity` is `null`, the user is unauthenticated. The `httpAction` MUST return an appropriate error `Response` (e.g., status 401 Unauthorized).
|
|
752
|
-
- **API Key Based (For Server-to-Server or Controlled Access):**
|
|
753
|
-
- If using API keys, the client MUST send the key in a designated header (e.g., `X-API-Key`).
|
|
754
|
-
- The `httpAction` MUST retrieve this header (e.g., `request.headers.get("X-API-Key")`) and validate it against securely stored API keys (e.g., in Convex environment variables).
|
|
755
|
-
- Return an appropriate error `Response` (e.g., status 403 Forbidden) if the API key is invalid or missing.
|
|
756
|
-
```
|
|
757
|
-
|
|
758
|
-
**4. Testing Convex HTTP Actions (Generic Strategy):**
|
|
759
|
-
|
|
760
|
-
```markdown
|
|
761
|
-
### Testing Convex HTTP Actions
|
|
762
|
-
|
|
763
|
-
- Direct unit testing of Convex `httpAction` handlers using `convexTest` can be challenging due to their raw `Request`/`Response` object interface and the specifics of their execution context.
|
|
764
|
-
- **Recommended Strategy:**
|
|
765
|
-
a. **Minimize Logic in Handler:** Keep the `httpAction` handler itself as thin as possible. Its primary responsibilities should be: parsing the `Request`, performing authentication/authorization checks, calling other testable Convex functions (regular `actions`, `mutations`, or `queries`) to perform the core work, and formatting the `Response` (including constructing `ReadableStream` if streaming).
|
|
766
|
-
b. **Unit Test Core Logic:** Extract all significant business logic, data processing, and interactions with external services into separate, regular Convex `actions`, `mutations`, or `queries`. Write thorough unit tests for these extracted functions using the `convexTest` framework.
|
|
767
|
-
c. **Manual/Integration Testing for HTTP Endpoint:** For the `httpAction` endpoint itself, perform manual testing using tools like `curl`, Postman, or an HTTP client library from a test script. Verify:
|
|
768
|
-
_ Correct request handling and parsing.
|
|
769
|
-
_ Authentication and authorization enforcement.
|
|
770
|
-
_ Expected response headers and status codes.
|
|
771
|
-
_ Correctness and format of the response body (including streamed content, if applicable).
|
|
772
|
-
d. **Document Manual Test Steps:** Include example `curl` commands or Postman collection details in the "Manual Verification Steps" section of the User Story that defines the `httpAction`.
|
|
773
|
-
```
|
|
774
|
-
|
|
775
|
-
**5. Convex Test Runner & Syntax (Clarification/Reinforcement):**
|
|
776
|
-
|
|
777
|
-
```markdown
|
|
778
|
-
### Convex Backend Function Testing (General)
|
|
779
|
-
|
|
780
|
-
- All Convex backend tests (typically files named `*.test.ts` within the `convex/` directory) MUST be written using **Vitest** syntax (e.g., `import { describe, test, expect, vi } from 'vitest';`).
|
|
781
|
-
- Utilize the `convexTest` utility from `convex/testing` (or the `convex-test` package if used directly by the project) to set up the Convex test environment for each test or suite. Example: `const t = convexTest(schema);`.
|
|
782
|
-
- Invoke Convex functions (queries, mutations, actions) within tests using the test environment object: `await t.mutation(api.module.myMutation, args)` or `await t.query(api.module.myQuery, args)`. For internal functions, use the `internal` API object: `await t.mutation(internal.module.myInternalMutation, args)`.
|
|
783
|
-
- The designated script for running these backend tests (e.g., `npx convex test`) MUST pass before code is considered complete.
|
|
784
|
-
- **Mocking Dependencies:** Use `vi.mock()` from Vitest for mocking module dependencies (e.g., external API client libraries, helper modules). Mocks should generally be defined at the top of the test file, before any imports of the modules that use them.
|
|
785
|
-
```
|
|
786
|
-
|
|
787
|
-
**6. Filename Conventions for Convex (Reinforcement):**
|
|
788
|
-
|
|
789
|
-
```markdown
|
|
790
|
-
### Filename Conventions (Convex Directory)
|
|
791
|
-
|
|
792
|
-
- All TypeScript files (`.ts`) located directly within the `convex/` directory (and its subdirectories, such as `convex/lib/`) MUST use **`camelCase`** naming (e.g., `myConvexFunction.ts`, `userProfileMutations.ts`).
|
|
793
|
-
- This convention is critical for Convex's file-based routing and its API generation system (`convex/_generated/api.js`).
|
|
794
|
-
- The project's ESLint configuration (`.eslintrc.js`) includes an override to enforce `camelCase` specifically for files within `convex/`, differing from the general project-wide `kebab-case` rule.
|
|
795
|
-
```
|