├── .cursor └── rules │ ├── ai-sdk-integration.mdc │ ├── audio-server.mdc │ ├── chatbot-integration.mdc │ ├── file-structure.mdc │ ├── file-upload-flow.mdc │ ├── mobile.mdc │ ├── plugin-development.mdc │ ├── shared-utilities.mdc │ └── web-development.mdc ├── .cursorrules ├── .dockerignore ├── .eslintignore ├── .eslintrc ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ └── bug_report.md └── workflows │ ├── build.yml │ ├── cron.yml │ └── manual-release.yml ├── .gitignore ├── .npmrc ├── .prettierrc ├── ANALYSIS.md ├── CLAUDE.md ├── Dockerfile ├── LICENSE ├── README.md ├── docker-compose.yml ├── main.css ├── manifest.json ├── memory ├── 2024-07-29-mobile-image-upload-workflow.md ├── 2024-07-30-sdk-implementation-failure-web-search.md ├── 2024-09-25-expo-run-command-directory.md └── 2024-09-25-remove-expo-share-intent.md ├── package.json ├── packages ├── audio-server │ ├── .env │ ├── .gitignore │ ├── dist │ │ ├── server.d.ts │ │ └── server.js │ ├── nixpacks.toml │ ├── package-lock.json │ ├── package.json │ ├── src │ │ └── server.ts │ └── tsconfig.json ├── landing │ ├── .cursorrules │ ├── .env.example │ ├── .gitignore │ ├── README.md │ ├── app │ │ ├── (landing) │ │ │ ├── actions.ts │ │ │ ├── components │ │ │ │ ├── beta-request-form.tsx │ │ │ │ ├── faq-section.tsx │ │ │ │ ├── grid-pattern.tsx │ │ │ │ ├── how.tsx │ │ │ │ ├── integrations-grid.tsx │ │ │ │ ├── pricing-cards.tsx │ │ │ │ ├── request-logo.tsx │ │ │ │ └── waitlist-form.tsx │ │ │ ├── data │ │ │ │ └── integrations.ts │ │ │ ├── demo │ │ │ │ ├── browser-window.tsx │ │ │ │ ├── demo.tsx │ │ │ │ └── loading-animation.tsx │ │ │ ├── error.tsx │ │ │ ├── layout.tsx │ │ │ ├── mobile │ │ │ │ └── page.tsx │ │ │ ├── not-found.tsx │ │ │ ├── opengraph-image.png │ │ │ └── page.tsx │ │ ├── PostHogPageView.tsx │ │ ├── dao │ │ │ ├── error.tsx │ │ │ ├── layout.tsx │ │ │ ├── not-found.tsx │ │ │ └── page.tsx │ │ ├── globals.css │ │ ├── layout.tsx │ │ ├── opengraph-image.png │ │ ├── privacy │ │ │ └── page.tsx │ │ ├── providers.tsx │ │ ├── terms-of-service │ │ │ └── page.tsx │ │ ├── twitter-image.png │ │ ├── types.ts │ │ └── utils │ │ │ ├── transcription.ts │ │ │ └── verifyPostal.ts │ ├── components.json │ ├── components │ │ ├── app-page.tsx │ │ ├── navbar.tsx │ │ ├── task-summary.tsx │ │ ├── theme-switcher.tsx │ │ ├── tutorial │ │ │ ├── code-block.tsx │ │ │ ├── connect-supabase-steps.tsx │ │ │ ├── fetch-data-steps.tsx │ │ │ ├── sign-up-user-steps.tsx │ │ │ └── tutorial-step.tsx │ │ ├── typography │ │ │ └── inline-code.tsx │ │ ├── ui │ │ │ ├── badge.tsx │ │ │ ├── button.tsx │ │ │ ├── card.tsx │ │ │ ├── checkbox.tsx │ │ │ ├── dialog.tsx │ │ │ ├── dropdown-menu.tsx │ │ │ ├── input.tsx │ │ │ ├── label.tsx │ │ │ ├── progress.tsx │ │ │ ├── scroll-area.tsx │ │ │ ├── select.tsx │ │ │ ├── switch.tsx │ │ │ ├── tabs.tsx │ │ │ ├── textarea.tsx │ │ │ ├── toast.tsx │ │ │ ├── toaster.tsx │ │ │ ├── tooltip.tsx │ │ │ └── use-toast.tsx │ │ └── un-30.svg │ ├── hooks │ │ └── use-toast.ts │ ├── lib │ │ └── utils.ts │ ├── middleware.ts │ ├── next.config.js │ ├── package.json │ ├── pages │ │ └── _error.js │ ├── postcss.config.js │ ├── public │ │ ├── favicon.ico │ │ ├── images │ │ │ ├── after.png │ │ │ └── before.jpg │ │ ├── note_companion_logo_bright.jpg │ │ ├── notecompanion.png │ │ └── screenpipe-logo.png │ ├── tailwind.config.ts │ ├── tsconfig.json │ ├── types │ │ └── posthog.d.ts │ └── utils │ │ ├── cn.ts │ │ ├── favi.png │ │ ├── og.png │ │ └── utils.ts ├── mobile │ ├── .env │ ├── .gitignore │ ├── Gemfile │ ├── Gemfile.lock │ ├── README.md │ ├── app.config.ts │ ├── app.json.description.txt │ ├── app │ │ ├── (auth) │ │ │ ├── _layout.tsx │ │ │ ├── index.tsx │ │ │ ├── sign-in.tsx │ │ │ ├── sign-up.tsx │ │ │ └── welcome.tsx │ │ ├── (tabs) │ │ │ ├── _layout.tsx │ │ │ ├── camera.tsx │ │ │ ├── index.tsx │ │ │ ├── notes.tsx │ │ │ ├── settings.tsx │ │ │ └── sync.tsx │ │ ├── +not-found.tsx │ │ ├── _layout.tsx │ │ ├── docs │ │ │ ├── privacy-policy.tsx │ │ │ └── terms-of-service.tsx │ │ ├── file-viewer.tsx │ │ └── shared.tsx │ ├── assets │ │ ├── big-logo.png │ │ ├── einstein-document.jpg │ │ ├── fAp56rVs5e5ZsfXD4Mmgki-1000-80.jpg │ │ ├── fonts │ │ │ └── SpaceMono-Regular.ttf │ │ ├── icon.png │ │ ├── icon_backup.png │ │ ├── images │ │ │ ├── adaptive-icon.png │ │ │ ├── app-demo.png │ │ │ ├── app-icon.png │ │ │ ├── favicon.png │ │ │ ├── icon.png │ │ │ ├── partial-react-logo.png │ │ │ ├── react-logo.png │ │ │ ├── react-logo@2x.png │ │ │ ├── react-logo@3x.png │ │ │ ├── splash-icon.png │ │ │ └── splash.png │ │ ├── splash-white.png │ │ └── splash.png │ ├── babel.config.js │ ├── components │ │ ├── Button.tsx │ │ ├── Collapsible.tsx │ │ ├── ExternalLink.tsx │ │ ├── FileCard.tsx │ │ ├── FileList.tsx │ │ ├── FilePreview.tsx │ │ ├── HapticTab.tsx │ │ ├── HelloWave.tsx │ │ ├── MarkdownPreview.tsx │ │ ├── ParallaxScrollView.tsx │ │ ├── ShareButton.tsx │ │ ├── SharedFileViewer.tsx │ │ ├── SignInWithOAuth.tsx │ │ ├── ThemedText.tsx │ │ ├── ThemedView.tsx │ │ ├── __tests__ │ │ │ ├── ThemedText-test.tsx │ │ │ └── __snapshots__ │ │ │ │ └── ThemedText-test.tsx.snap │ │ ├── file-preview.tsx │ │ ├── markdown-viewer.tsx │ │ ├── processing-status.tsx │ │ ├── text-document-viewer.tsx │ │ ├── ui │ │ │ ├── CameraTabButton.tsx │ │ │ ├── IconSymbol.ios.tsx │ │ │ ├── IconSymbol.tsx │ │ │ ├── TabBarBackground.ios.tsx │ │ │ └── TabBarBackground.tsx │ │ └── usage-status.tsx │ ├── constants │ │ ├── Colors.ts │ │ └── config.ts │ ├── converted_icon.png │ ├── docs │ │ ├── app-store │ │ │ └── apple-response.md │ │ ├── privacy-policy.md │ │ └── terms-of-service.md │ ├── eas.json │ ├── fastlane │ │ ├── Appfile │ │ └── Fastfile │ ├── favicon.ico │ ├── global.css │ ├── help.tsx │ ├── hooks │ │ ├── useColorScheme.ts │ │ ├── useColorScheme.web.ts │ │ ├── useThemeColor.ts │ │ └── useWarmUpBrowser.ts │ ├── index.ts │ ├── metro.config.js │ ├── nativewind-env.d.ts │ ├── package.json │ ├── patches │ │ ├── react-native-fabric-fix.patch │ │ ├── react-native@0.76.7.patch │ │ ├── scripts │ │ │ └── create-fabric-provider.js │ │ └── xcode+3.0.1.patch │ ├── providers │ │ └── auth.tsx │ ├── scripts │ │ └── reset-project.js │ ├── tailwind.config.ts │ ├── tsconfig.json │ └── utils │ │ ├── api.ts │ │ ├── camera-handler.ts │ │ ├── file-handler.ts │ │ ├── image-utils.ts │ │ ├── share-handler.ts │ │ └── sharing.ts ├── plugin │ ├── .gitignore │ ├── .prettierrc │ ├── apiUtils.ts │ ├── components │ │ ├── ui │ │ │ ├── alert.tsx │ │ │ ├── badge copy.tsx │ │ │ ├── badge.tsx │ │ │ ├── button.tsx │ │ │ ├── card.tsx │ │ │ ├── checkout-button.tsx │ │ │ ├── dialog.tsx │ │ │ ├── folder-selection.tsx │ │ │ ├── form.tsx │ │ │ ├── icons.tsx │ │ │ ├── input.tsx │ │ │ ├── label.tsx │ │ │ ├── logo.tsx │ │ │ ├── progress.tsx │ │ │ ├── select.tsx │ │ │ ├── separator.tsx │ │ │ ├── switch.tsx │ │ │ ├── tabs.tsx │ │ │ ├── tooltip.tsx │ │ │ └── utils.tsx │ │ ├── usage-stats.tsx │ │ └── utils.ts │ ├── constants.ts │ ├── dist │ │ └── styles.css │ ├── esbuild.config.mjs │ ├── fileUtils.ts │ ├── handlers │ │ ├── commandHandlers.ts │ │ └── eventHandlers.ts │ ├── inbox │ │ ├── constants.ts │ │ ├── index.ts │ │ ├── services │ │ │ ├── error-service.ts │ │ │ ├── id-service.ts │ │ │ ├── queue.ts │ │ │ ├── record-manager.ts │ │ │ └── youtube-service.ts │ │ ├── types.ts │ │ └── utils │ │ │ └── file.ts │ ├── index.ts │ ├── lib │ │ └── utils.ts │ ├── package.json │ ├── postcss.config.js │ ├── pre-processor.ts │ ├── services │ │ └── logger.ts │ ├── settings.ts │ ├── skeleton-loader.tsx │ ├── someUtils.ts │ ├── styles.css │ ├── tailwind.config.js │ ├── templates │ │ └── youtube_video.md │ ├── tsconfig.json │ ├── utils.ts │ ├── utils │ │ └── token-counter.ts │ ├── version-bump.mjs │ ├── versions.json │ └── views │ │ ├── assistant │ │ ├── ai-chat │ │ │ ├── ai-message-renderer.tsx │ │ │ ├── audio-recorder.tsx │ │ │ ├── avatar.tsx │ │ │ ├── button.tsx │ │ │ ├── card.tsx │ │ │ ├── chat.tsx │ │ │ ├── components │ │ │ │ ├── SourcesSection.tsx │ │ │ │ ├── append-button.tsx │ │ │ │ ├── attachment-handler.tsx │ │ │ │ ├── audio-recorder.tsx │ │ │ │ ├── clear-all-button.tsx │ │ │ │ ├── context-items.tsx │ │ │ │ ├── context-limit-indicator.tsx │ │ │ │ ├── copy-button.tsx │ │ │ │ ├── example-prompts.tsx │ │ │ │ ├── message-renderer.tsx │ │ │ │ ├── model-selector.tsx │ │ │ │ ├── search-toggle.tsx │ │ │ │ └── submit-button.tsx │ │ │ ├── container.tsx │ │ │ ├── context-limit-indicator.tsx │ │ │ ├── hooks │ │ │ │ └── use-current-file.ts │ │ │ ├── mentions.tsx │ │ │ ├── message-renderer.tsx │ │ │ ├── model-selector.tsx │ │ │ ├── selected-item.tsx │ │ │ ├── shared │ │ │ │ └── markdown-renderer.tsx │ │ │ ├── submit-button.tsx │ │ │ ├── suggestion.ts │ │ │ ├── tiptap.tsx │ │ │ ├── tool-handlers │ │ │ │ ├── add-text-handler.tsx │ │ │ │ ├── append-content-handler.tsx │ │ │ │ ├── date-range-handler.tsx │ │ │ │ ├── execute-actions-handler.tsx │ │ │ │ ├── last-modified-handler.tsx │ │ │ │ ├── modify-text-handler.tsx │ │ │ │ ├── move-files-handler.tsx │ │ │ │ ├── onboard-handler.tsx │ │ │ │ ├── rename-files-handler.tsx │ │ │ │ ├── screenpipe-handler.tsx │ │ │ │ ├── screenpipe-utils.ts │ │ │ │ ├── search-annotation-handler.tsx │ │ │ │ ├── search-handler.tsx │ │ │ │ ├── search-rename-handler.tsx │ │ │ │ ├── settings-update-handler.tsx │ │ │ │ ├── tool-invocation-handler.tsx │ │ │ │ ├── types.ts │ │ │ │ └── youtube-handler.tsx │ │ │ ├── types.ts │ │ │ ├── types │ │ │ │ ├── annotations.ts │ │ │ │ ├── attachments.ts │ │ │ │ └── grounding.ts │ │ │ ├── use-context-items.ts │ │ │ ├── use-vault-items.ts │ │ │ ├── user-message-renderer.tsx │ │ │ └── youtube-transcript.ts │ │ ├── dashboard │ │ │ ├── collapsible-section.tsx │ │ │ ├── floating-action-button.tsx │ │ │ ├── main-dashboard.tsx │ │ │ ├── onboarding-wizard.tsx │ │ │ ├── progress-bar.tsx │ │ │ └── view.tsx │ │ ├── inbox-logs.tsx │ │ ├── organizer │ │ │ ├── ai-format │ │ │ │ ├── fabric-templates.tsx │ │ │ │ ├── templates.tsx │ │ │ │ └── user-templates.tsx │ │ │ ├── chunks.tsx │ │ │ ├── components │ │ │ │ ├── empty-state.tsx │ │ │ │ ├── error-box.tsx │ │ │ │ ├── license-validator.tsx │ │ │ │ ├── refresh-button.tsx │ │ │ │ ├── skeleton-loader.tsx │ │ │ │ └── suggestion-buttons.tsx │ │ │ ├── folders │ │ │ │ ├── box.tsx │ │ │ │ └── components │ │ │ │ │ ├── error-display.tsx │ │ │ │ │ └── skeleton-loader.tsx │ │ │ ├── meetings │ │ │ │ └── meetings.tsx │ │ │ ├── organizer.tsx │ │ │ ├── tags.tsx │ │ │ ├── titles │ │ │ │ └── box.tsx │ │ │ └── transcript.tsx │ │ ├── provider.tsx │ │ ├── section-header.tsx │ │ ├── synchronizer │ │ │ ├── index.ts │ │ │ └── sync-tab.tsx │ │ └── view.tsx │ │ └── settings │ │ ├── account-data.tsx │ │ ├── advanced-tab.tsx │ │ ├── catalyst-gate.tsx │ │ ├── customization-tab.tsx │ │ ├── experiment-tab.tsx │ │ ├── fabric-prompt-manager.tsx │ │ ├── file-config-tab.tsx │ │ ├── general-tab.tsx │ │ ├── main.tsx │ │ ├── top-up-credits.tsx │ │ └── view.tsx ├── release-notes │ ├── .gitignore │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json └── web │ ├── .electronignore │ ├── .env.example │ ├── .github │ └── workflows │ │ └── update.yml │ ├── .gitignore │ ├── README.md │ ├── __mocks__ │ ├── @ai-sdk │ │ ├── google.ts │ │ └── openai.ts │ └── next │ │ └── server.ts │ ├── app │ ├── (app) │ │ └── dashboard │ │ │ └── upload-test │ │ │ └── page.tsx │ ├── actions.ts │ ├── api │ │ ├── (newai) │ │ │ ├── aiService.ts │ │ │ ├── aliases │ │ │ │ └── route.ts │ │ │ ├── chat │ │ │ │ ├── route.test.ts │ │ │ │ ├── route.ts │ │ │ │ └── tools.ts │ │ │ ├── chunks │ │ │ │ └── route.ts │ │ │ ├── classify-v2 │ │ │ │ └── route.ts │ │ │ ├── classify1 │ │ │ │ └── route.ts │ │ │ ├── concepts-and-chunks │ │ │ │ └── route.ts │ │ │ ├── concepts │ │ │ │ └── route.ts │ │ │ ├── create-folder │ │ │ │ └── route.ts │ │ │ ├── fabric-classify │ │ │ │ └── route.ts │ │ │ ├── folders │ │ │ │ ├── embeddings │ │ │ │ │ ├── bm25.ts │ │ │ │ │ └── route.ts │ │ │ │ ├── existing │ │ │ │ │ └── route.ts │ │ │ │ ├── new │ │ │ │ │ └── route.ts │ │ │ │ ├── route.ts │ │ │ │ └── v2 │ │ │ │ │ └── route.ts │ │ │ ├── format-stream │ │ │ │ └── route.ts │ │ │ ├── format │ │ │ │ ├── route.ts │ │ │ │ └── v2 │ │ │ │ │ └── route.ts │ │ │ ├── modify │ │ │ │ └── route.ts │ │ │ ├── organize-all │ │ │ │ └── route.ts │ │ │ ├── tags │ │ │ │ ├── existing │ │ │ │ │ └── route.ts │ │ │ │ ├── new │ │ │ │ │ └── route.ts │ │ │ │ ├── route.ts │ │ │ │ └── v2 │ │ │ │ │ └── route.ts │ │ │ ├── title │ │ │ │ ├── multiple-stream │ │ │ │ │ └── route.ts │ │ │ │ ├── multiple │ │ │ │ │ └── route.ts │ │ │ │ ├── route.ts │ │ │ │ └── v2 │ │ │ │ │ └── route.ts │ │ │ ├── transcribe │ │ │ │ └── route.ts │ │ │ └── vision │ │ │ │ ├── prompt.ts │ │ │ │ └── route.ts │ │ ├── (sync) │ │ │ ├── file-status │ │ │ │ └── route.ts │ │ │ ├── files │ │ │ │ ├── [id] │ │ │ │ │ └── route.ts │ │ │ │ └── route.ts │ │ │ └── upload │ │ │ │ └── route.ts │ │ ├── anon.ts │ │ ├── blob-client-upload │ │ │ └── route.ts │ │ ├── check-key │ │ │ └── route.ts │ │ ├── check-premium │ │ │ └── route.ts │ │ ├── check-tier │ │ │ └── route.ts │ │ ├── create-upload-url │ │ │ └── route.ts │ │ ├── cron │ │ │ ├── redeploy │ │ │ │ └── route.ts │ │ │ └── reset-tokens │ │ │ │ ├── route.test.ts │ │ │ │ └── route.ts │ │ ├── files │ │ │ ├── recent │ │ │ │ └── route.ts │ │ │ └── upload │ │ │ │ └── route.ts │ │ ├── get-upload-status │ │ │ └── [id] │ │ │ │ └── route.ts │ │ ├── health │ │ │ └── route.ts │ │ ├── process-file │ │ │ └── route.ts │ │ ├── process-pending-uploads │ │ │ └── route.ts │ │ ├── public-usage │ │ │ └── route.ts │ │ ├── record-upload │ │ │ └── route.ts │ │ ├── redeploy │ │ │ └── route.ts │ │ ├── sign-in │ │ │ └── route.ts │ │ ├── sign-up │ │ │ └── route.ts │ │ ├── test-ocr │ │ │ └── route.ts │ │ ├── token-usage │ │ │ └── route.ts │ │ ├── top-up │ │ │ └── route.ts │ │ ├── trigger-processing │ │ │ └── route.ts │ │ ├── upload-test │ │ │ └── route.ts │ │ ├── usage │ │ │ └── route.ts │ │ ├── user │ │ │ └── subscription-status │ │ │ │ └── route.ts │ │ └── webhook │ │ │ ├── handler-factory.ts │ │ │ ├── handlers │ │ │ ├── checkout-complete.ts │ │ │ ├── invoice-paid.ts │ │ │ ├── invoice-payment-failed.ts │ │ │ ├── payment-intent-succeeded.ts │ │ │ ├── subscription-canceled.ts │ │ │ └── subscription-updated.ts │ │ │ ├── route.ts │ │ │ ├── types.ts │ │ │ ├── utils.ts │ │ │ └── verify.ts │ ├── components │ │ └── license-form.tsx │ ├── dashboard │ │ ├── deployment │ │ │ ├── _components │ │ │ │ ├── configuration-form.tsx │ │ │ │ ├── deployment-status.tsx │ │ │ │ └── wizard-steps.tsx │ │ │ ├── actions.ts │ │ │ └── page.tsx │ │ ├── layout.tsx │ │ ├── lifetime │ │ │ ├── action.ts │ │ │ ├── automated-setup.tsx │ │ │ ├── client-component.tsx │ │ │ ├── components │ │ │ │ └── plugin-setup.tsx │ │ │ ├── legacy-setup.tsx │ │ │ └── page.tsx │ │ ├── page.tsx │ │ ├── pricing │ │ │ ├── actions.ts │ │ │ └── page.tsx │ │ ├── self-hosted │ │ │ └── page.tsx │ │ ├── settings │ │ │ └── page.tsx │ │ ├── subscribers │ │ │ ├── client-component.tsx │ │ │ └── page.tsx │ │ └── sync │ │ │ ├── _components │ │ │ ├── FileCard.tsx │ │ │ ├── FileList.tsx │ │ │ └── StatusBadge.tsx │ │ │ ├── actions.ts │ │ │ └── page.tsx │ ├── error.tsx │ ├── favicon.ico │ ├── global-error.tsx │ ├── globals.css │ ├── layout.tsx │ ├── not-found.tsx │ ├── onboarding │ │ └── page.tsx │ ├── page.tsx │ ├── posthog-page-view.tsx │ ├── providers.tsx │ ├── sign-in │ │ └── [[...rest]] │ │ │ └── page.tsx │ ├── top-up-cancelled │ │ └── page.tsx │ ├── top-up-success │ │ └── page.tsx │ └── upgrade-from-mobile │ │ └── page.tsx │ ├── components.json │ ├── components │ ├── auth-layout-wrapper.tsx │ ├── navigation-bar.tsx │ ├── pricing-cards.tsx │ ├── ui │ │ ├── alert.tsx │ │ ├── badge.tsx │ │ ├── button.tsx │ │ ├── card.tsx │ │ ├── checkout-button.tsx │ │ ├── dialog.tsx │ │ ├── dropdown-menu.tsx │ │ ├── folder-selection.tsx │ │ ├── form.tsx │ │ ├── icons.tsx │ │ ├── input.tsx │ │ ├── label.tsx │ │ ├── logo.tsx │ │ ├── progress.tsx │ │ ├── select.tsx │ │ ├── separator.tsx │ │ ├── switch.tsx │ │ ├── tabs.tsx │ │ └── utils.tsx │ └── user-management.tsx │ ├── drizzle.config.ts │ ├── drizzle │ ├── 0000_thankful_mathemanic.sql │ ├── 0001_new-hello.sql │ ├── 0001_numerous_famine.sql │ ├── 0002_tired_phantom_reporter.sql │ ├── 0003_first_phantom_reporter.sql │ ├── 0004_cool_sunspot.sql │ ├── 0005_stiff_madripoor.sql │ ├── 0006_smart_brother_voodoo.sql │ ├── 0007_slow_dracula.sql │ ├── 0008_woozy_viper.sql │ ├── 0009_fluffy_electro.sql │ ├── 0010_certain_groot.sql │ ├── 0011_lame_green_goblin.sql │ ├── 0012_same_zodiak.sql │ ├── 0013_deep_blazing_skull.sql │ ├── 0014_demonic_flatman.sql │ ├── 0015_tense_paper_doll.sql │ ├── 0016_quick_vanisher.sql │ ├── 0017_large_ser_duncan.sql │ ├── 0018_previous_catseye.sql │ ├── 0019_bizarre_night_thrasher.sql │ ├── 0020_silent_baron_zemo.sql │ ├── 0021_bouncy_shotgun.sql │ ├── envConfig.js │ ├── meta │ │ ├── 0000_snapshot.json │ │ ├── 0001_snapshot.json │ │ ├── 0002_snapshot.json │ │ ├── 0003_snapshot.json │ │ ├── 0004_snapshot.json │ │ ├── 0005_snapshot.json │ │ ├── 0006_snapshot.json │ │ ├── 0007_snapshot.json │ │ ├── 0008_snapshot.json │ │ ├── 0009_snapshot.json │ │ ├── 0010_snapshot.json │ │ ├── 0011_snapshot.json │ │ ├── 0012_snapshot.json │ │ ├── 0013_snapshot.json │ │ ├── 0014_snapshot.json │ │ ├── 0015_snapshot.json │ │ ├── 0016_snapshot.json │ │ ├── 0017_snapshot.json │ │ ├── 0018_snapshot.json │ │ ├── 0019_snapshot.json │ │ ├── 0020_snapshot.json │ │ ├── 0021_snapshot.json │ │ └── _journal.json │ ├── migrations │ │ └── reset-inactive-users.ts │ └── schema.ts │ ├── jest.config.ts │ ├── jest.env.setup.js │ ├── jest.setup.ts │ ├── lib │ ├── getUrl.ts │ ├── handleAuthorization.ts │ ├── incrementAndLogTokenUsage.ts │ ├── models.ts │ ├── posthog.ts │ ├── prompts │ │ └── chat-prompt.ts │ ├── services │ │ ├── clerk.ts │ │ └── loops.ts │ ├── subscription.ts │ ├── utils.ts │ └── youtubeTranscript.ts │ ├── middleware.ts │ ├── next.config.js │ ├── package.json │ ├── pages │ └── _error.js │ ├── postcss.config.mjs │ ├── public │ ├── big-logo.png │ ├── favicon.ico │ ├── icon.icns │ ├── lightning-logo.avif │ ├── logo.icns │ │ └── 512x512.png │ ├── next.svg │ └── vercel.svg │ ├── scripts │ ├── migrate.ts │ └── webhooks.test.ts │ ├── srm.config.ts │ ├── tailwind.config.js │ ├── tsconfig.json │ ├── types │ ├── globals.d.ts │ └── radix-ui.d.ts │ ├── uploads │ └── 9e621745-c5de-4a41-8538-e8b63b2e145e-compilation-without-summary.pdf │ └── vercel-non.json ├── patches └── xcode@3.0.1.patch ├── pipes └── file-organizer-notifications │ ├── .gitignore │ ├── README.md │ ├── bun.lockb │ ├── components.json │ ├── eslint.config.mjs │ ├── next.config.ts │ ├── package-lock.json │ ├── package.json │ ├── pipe.json │ ├── postcss.config.mjs │ ├── public │ ├── file.svg │ ├── globe.svg │ ├── next.svg │ ├── vercel.svg │ └── window.svg │ ├── src │ ├── app │ │ ├── api │ │ │ ├── check-folder │ │ │ │ └── route.ts │ │ │ ├── intelligence │ │ │ │ └── route.ts │ │ │ ├── log │ │ │ │ └── route.ts │ │ │ └── settings │ │ │ │ └── route.ts │ │ ├── favicon.ico │ │ ├── globals.css │ │ ├── layout.tsx │ │ └── page.tsx │ ├── components │ │ ├── obsidian-settings.tsx │ │ ├── ollama-models-list.tsx │ │ └── ui │ │ │ ├── accordion.tsx │ │ │ ├── badge.tsx │ │ │ ├── button.tsx │ │ │ ├── calendar.tsx │ │ │ ├── card.tsx │ │ │ ├── checkbox.tsx │ │ │ ├── codeblock.tsx │ │ │ ├── command.tsx │ │ │ ├── dialog.tsx │ │ │ ├── icons.tsx │ │ │ ├── input.tsx │ │ │ ├── label.tsx │ │ │ ├── popover.tsx │ │ │ ├── progress.tsx │ │ │ ├── select.tsx │ │ │ ├── separator.tsx │ │ │ ├── skeleton.tsx │ │ │ ├── slider.tsx │ │ │ ├── switch.tsx │ │ │ ├── tabs.tsx │ │ │ ├── toast.tsx │ │ │ ├── toaster.tsx │ │ │ ├── tooltip.tsx │ │ │ └── use-toast.ts │ ├── hooks │ │ └── use-toast.ts │ └── lib │ │ ├── actions │ │ └── video-actions.ts │ │ ├── hooks │ │ ├── use-copy-to-clipboard.tsx │ │ ├── use-debounce.tsx │ │ ├── use-health-check.tsx │ │ ├── use-settings.tsx │ │ └── use-sql-autocomplete.tsx │ │ └── utils.ts │ ├── tailwind.config.ts │ └── tsconfig.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── promptfooconfig.yaml ├── render.yaml ├── scripts └── create-fabric-provider.js ├── test-release.js ├── tsconfig.json ├── turbo.json └── tutorials ├── CommonWorkflows.md ├── ExecuteActionsHandler.md ├── LastModifiedHandler.md ├── ScreenpipeHandler.md ├── assistantSidebar.md ├── bugs.md ├── custom_folder_organization_examples.md ├── env-vars.md ├── faq.md ├── getStarted.md ├── howItWorks.md ├── images ├── assistant_sidebar.png ├── pre_processed_file.png └── processed_file.png ├── international ├── chinese ├── francais.md └── russian.md ├── lifetime-setup-v2.md ├── lifetime_faq.md ├── local-llms.md ├── mobile.md └── troubelshoot.md /.cursor/rules/audio-server.mdc: -------------------------------------------------------------------------------- 1 | --- 2 | description: Audio transcription server implementation 3 | globs: packages/audio-server/**/* 4 | --- 5 | 6 | # Audio Server Implementation Guide 7 | 8 | ## Overview 9 | Audio server code should be in `packages/audio-server/` 10 | 11 | ## Components 12 | 13 | ### 1. Transcription Service 14 | - Implement proper queue management 15 | - Handle multiple audio formats 16 | - Implement error recovery 17 | 18 | ### 2. API Integration 19 | - RESTful API endpoints 20 | - Proper authentication 21 | - Rate limiting 22 | 23 | ### 3. File Processing 24 | - Handle large files 25 | - Implement progress tracking 26 | - Proper cleanup procedures 27 | 28 | ## Best Practices 29 | 1. Implement proper audio format validation 30 | 2. Use efficient streaming methods 31 | 3. Implement proper error handling 32 | 4. Cache results when possible 33 | 5. Clean up temporary files 34 | -------------------------------------------------------------------------------- /.cursor/rules/plugin-development.mdc: -------------------------------------------------------------------------------- 1 | --- 2 | description: Guidelines for Obsidian plugin development 3 | globs: packages/plugin/**/* 4 | --- 5 | 6 | # Obsidian Plugin Development Guide 7 | 8 | ## Structure 9 | All plugin code should be in `packages/plugin/` 10 | 11 | ## Core Components 12 | 13 | ### 1. File Organization 14 | - Use TypeScript for all plugin code 15 | - Follow Obsidian's plugin architecture 16 | - Implement proper error handling 17 | 18 | ### 2. AI Integration 19 | - Use proper context management 20 | - Implement token usage tracking 21 | - Handle rate limiting 22 | 23 | ### 3. UI Components 24 | - Follow Obsidian's UI guidelines 25 | - Use native Obsidian components 26 | - Implement proper loading states 27 | 28 | ## Best Practices 29 | 1. Test all file operations thoroughly 30 | 2. Handle permissions properly 31 | 3. Implement proper error recovery 32 | 4. Cache results when possible 33 | 5. Follow Obsidian's plugin guidelines 34 | -------------------------------------------------------------------------------- /.cursor/rules/shared-utilities.mdc: -------------------------------------------------------------------------------- 1 | --- 2 | description: Shared utilities and types 3 | globs: packages/shared/**/* 4 | --- 5 | 6 | # Shared Utilities Implementation Guide 7 | 8 | ## Overview 9 | Shared code should be in `packages/shared/` 10 | 11 | ## Components 12 | 13 | ### 1. Type Definitions 14 | - Keep types consistent 15 | - Use proper TypeScript features 16 | - Document complex types 17 | 18 | ### 2. Utility Functions 19 | - Keep functions pure 20 | - Implement proper error handling 21 | - Write comprehensive tests 22 | 23 | ### 3. Constants 24 | - Use proper naming conventions 25 | - Document usage requirements 26 | - Keep organized by domain 27 | 28 | ## Best Practices 29 | 1. Document all exports 30 | 2. Write comprehensive tests 31 | 3. Keep dependencies minimal 32 | 4. Use proper versioning 33 | 5. Maintain backwards compatibility 34 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | .turbo 4 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | 3 | main.js 4 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "env": { "node": true }, 5 | "plugins": [ 6 | "@typescript-eslint" 7 | ], 8 | "extends": [ 9 | "eslint:recommended", 10 | "plugin:@typescript-eslint/eslint-recommended", 11 | "plugin:@typescript-eslint/recommended" 12 | ], 13 | "parserOptions": { 14 | "sourceType": "module" 15 | }, 16 | "rules": { 17 | "no-unused-vars": "warn", 18 | "@typescript-eslint/no-unused-vars": ["warn", { "args": "none" }], 19 | "@typescript-eslint/ban-ts-comment": "warn", 20 | "no-prototype-builtins": "warn", 21 | "@typescript-eslint/no-empty-function": "warn" 22 | } 23 | } -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 12 | polar: # Replace with a single Polar username 13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username 14 | custom: ['https://dub.sh/support-fo2k'] 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | **Describe the bug** 4 | A clear and concise description of what the bug is. 5 | 6 | **To Reproduce** 7 | Steps to reproduce the behavior: 8 | 1. Go to '...' 9 | 2. Click on '....' 10 | 3. Scroll down to '....' 11 | 4. See error 12 | 13 | **Current version of Fo2k** 14 | 15 | Screenshot 2024-11-18 at 14 01 23 16 | 17 | **Customer status: lifetime/cloud** 18 | 19 | Are you lifetime or cloud user? 20 | 21 | **Deployment method (not for cloud)** 22 | 23 | vercel/render/or self-managed 24 | 25 | **Deployment status (not for cloud)** 26 | 27 | depending on if vercel or render try to find out the latest time your service got deployed and share a screenshot. 28 | 29 | 30 | 31 | **Expected behavior** 32 | 33 | A clear and concise description of what you expected to happen. 34 | 35 | **Screenshots** 36 | 37 | A screenshots to help explain your problem. 38 | 39 | 40 | **Additional context** 41 | 42 | Add any other context about the problem here. 43 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build Obsidian Plugin 2 | 3 | on: 4 | push: 5 | paths: 6 | - 'packages/plugin/**' 7 | pull_request: 8 | paths: 9 | - 'packages/plugin/**' 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v3 17 | 18 | - name: Use Node.js 19 | uses: actions/setup-node@v3 20 | with: 21 | node-version: "18.x" 22 | 23 | - name: Install pnpm 24 | uses: pnpm/action-setup@v2 25 | with: 26 | version: 10.8.1 27 | 28 | - name: Install dependencies 29 | run: | 30 | cd packages/plugin 31 | pnpm install 32 | 33 | - name: Build plugin 34 | run: | 35 | cd packages/plugin 36 | GITHUB_ACTIONS=true pnpm build 37 | 38 | - name: Run tests 39 | run: | 40 | cd packages/plugin 41 | pnpm test -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # VSCode 2 | .vscode/ 3 | 4 | # IntelliJ 5 | *.iml 6 | .idea/ 7 | 8 | # Build directories 9 | /dist/ 10 | node_modules/ 11 | 12 | # Compiled files 13 | main.js 14 | 15 | # Source maps 16 | *.map 17 | 18 | # Obsidian 19 | data.json 20 | 21 | # macOS Finder 22 | .DS_Store 23 | 24 | # Tailwind CSS 25 | /styles.css 26 | 27 | # Turbo build cache 28 | .turbo/ 29 | **/.turbo/ 30 | .vercel 31 | .env*.local 32 | 33 | # Expo native directories 34 | /android/ 35 | /ios/ 36 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | node-linker=hoisted 2 | catalog.react=18.3.0 3 | catalog.@types/react=19.0.10 4 | catalog.@types/react-dom=19.0.4 -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "useTabs": false 4 | } 5 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Use an official Node.js runtime as the base image 2 | FROM node:20 3 | 4 | # Set the working directory in the container 5 | WORKDIR /app 6 | 7 | # Copy the rest of the application code to the working directory 8 | COPY . . 9 | 10 | # install pnpm 11 | RUN npm install -g pnpm 12 | 13 | # Set the working directory to the web package 14 | WORKDIR /app/packages/web 15 | 16 | # Install the application dependencies 17 | RUN pnpm install 18 | 19 | # Build the Next.js application 20 | RUN pnpm run build:self-host 21 | 22 | # Expose the port on which the application will run 23 | EXPOSE 3000 24 | 25 | # Set the command to run the application 26 | CMD ["pnpm", "run", "start"] 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Different AI 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | app: 3 | build: 4 | context: . 5 | dockerfile: Dockerfile 6 | ports: 7 | - "3000:3000" 8 | environment: 9 | - OPENAI_API_KEY=${OPENAI_API_KEY} 10 | - SOLO_API_KEY=${SOLO_API_KEY} 11 | - MODEL_VISION=${MODEL_VISION} 12 | - MODEL_TEXT=${MODEL_TEXT} 13 | - MODEL_NAME=${MODEL_NAME} 14 | - MODEL_CLASSIFY=${MODEL_CLASSIFY} 15 | - MODEL_TAGGING=${MODEL_TAGGING} 16 | - MODEL_FOLDERS=${MODEL_FOLDERS} 17 | 18 | - OLLAMA_API_URL=${OLLAMA_API_URL} 19 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "fileorganizer2000", 3 | "name": "Note Companion (prev. File Organizer 2000)", 4 | "version": "2.2.1", 5 | "minAppVersion": "0.15.0", 6 | "description": "An AI assistant to organize and chat with your vault", 7 | "author": "Benjamin Ashgan Shafii", 8 | "isDesktopOnly": true 9 | } -------------------------------------------------------------------------------- /memory/2024-07-30-sdk-implementation-failure-web-search.md: -------------------------------------------------------------------------------- 1 | # Memory: Use Web Search for Failed API/SDK Implementations 2 | 3 | Date: 2024-07-30 4 | 5 | ## Learning 6 | 7 | When attempting to implement functionality using an external API or SDK (like Clerk's backend client) and encountering repeated type errors or incorrect method usage despite multiple attempts based on assumed knowledge, it indicates a gap in understanding the specific API contract. 8 | 9 | ## Application 10 | 11 | In such situations, instead of looping through slightly different variations based on assumptions or linter errors alone, the next immediate step should be to **perform a targeted web search**. 12 | 13 | Example search queries: 14 | * "[Library/SDK Name] [Specific Task] example [Framework Name]" 15 | * e.g., "Clerk backend API token authentication example Next.js API route" 16 | * "[Library/SDK Name] authenticate request from header token" 17 | * Searching for the specific error message (e.g., "ClerkClient Property 'authenticateRequest' does not exist") 18 | 19 | This helps gather accurate, up-to-date documentation or community examples to correct the implementation, preventing wasted attempts and ensuring the correct API usage is found efficiently. -------------------------------------------------------------------------------- /memory/2024-09-25-expo-run-command-directory.md: -------------------------------------------------------------------------------- 1 | # Expo Run Command Directory 2 | 3 | **Learned:** Running Expo CLI commands like `expo run:ios` (aliased as `pnpm run ios` or `pnpm run dev` in `packages/mobile/package.json`) must be done from the specific package directory (`packages/mobile`) or by targeting the package from the monorepo root using `pnpm --filter note-companion run ios`. 4 | 5 | **Problem:** Running these commands from subdirectories like `packages/mobile/ios` can cause an `Error: ENOENT: no such file or directory, uv_cwd` because the Expo CLI cannot find the project root correctly. 6 | 7 | **Solution:** Always ensure the current working directory is `packages/mobile` before running `pnpm run ios` or `pnpm run dev`, or use `pnpm --filter note-companion run ...` from the monorepo root. 8 | 9 | **Related:** 10 | - `packages/mobile/package.json` (scripts `ios`, `dev`) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "file-organizer-2000-monorepo", 3 | "private": true, 4 | "devDependencies": { 5 | "@types/node": "^22.13.10", 6 | "node-gyp": "^11.1.0", 7 | "turbo": "^2.4.4", 8 | "typescript": "^5.8.2" 9 | }, 10 | "version": "1.0.0", 11 | "packageManager": "pnpm@10.8.1", 12 | "scripts": { 13 | "build": "turbo build", 14 | "dev": "turbo dev", 15 | "lint": "turbo lint", 16 | "test": "turbo test", 17 | "clean": "git clean -xdf node_modules", 18 | "android": "expo run:android", 19 | "ios": "expo run:ios" 20 | }, 21 | "dependencies": { 22 | "react-markdown": "^10.1.0", 23 | "remark-gfm": "^4.0.1", 24 | "expo": "~52.0.43", 25 | "react": "18.3.1", 26 | "react-native": "0.76.9" 27 | }, 28 | "pnpm": { 29 | "patchedDependencies": { 30 | "xcode@3.0.1": "patches/xcode@3.0.1.patch" 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/audio-server/.env: -------------------------------------------------------------------------------- 1 | 2 | PORT=3001 3 | -------------------------------------------------------------------------------- /packages/audio-server/.gitignore: -------------------------------------------------------------------------------- 1 | uploads/ 2 | 3 | # Build artifacts 4 | .turbo 5 | *.tsbuildinfo 6 | -------------------------------------------------------------------------------- /packages/audio-server/dist/server.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /packages/audio-server/nixpacks.toml: -------------------------------------------------------------------------------- 1 | [phases.setup] 2 | aptPkgs = ["ffmpeg"] 3 | -------------------------------------------------------------------------------- /packages/audio-server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@file-organizer/audio-server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "dist/server.js", 6 | "scripts": { 7 | "start": "node dist/server.js", 8 | "build": "tsc", 9 | "dev": "ts-node-dev --respawn --transpile-only src/server.ts" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "dependencies": { 15 | "@deepgram/sdk": "^3.5.0", 16 | "@unkey/api": "^0.23.0", 17 | "cors": "^2.8.5", 18 | "dotenv": "^16.4.5", 19 | "express": "^4.19.2", 20 | "morgan": "^1.10.0", 21 | "multer": "^1.4.5-lts.1", 22 | "openai": "^4.52.7" 23 | }, 24 | "devDependencies": { 25 | "@types/cors": "^2.8.13", 26 | "@types/express": "^4.17.17", 27 | "@types/morgan": "^1.9.4", 28 | "@types/multer": "^1.4.7", 29 | "@types/node": "^18.15.11", 30 | "ts-node-dev": "^2.0.0", 31 | "typescript": "^5.0.4" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/audio-server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "target": "es2018", 5 | "module": "commonjs", 6 | "outDir": "./dist", 7 | "rootDir": "./src", 8 | "composite": true 9 | }, 10 | "include": ["src/**/*"], 11 | "exclude": ["node_modules"], 12 | "references": [ 13 | { "path": "../shared" } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /packages/landing/.env.example: -------------------------------------------------------------------------------- 1 | # Update these with your Supabase details from your project settings > API 2 | # https://app.supabase.com/project/_/settings/api 3 | NEXT_PUBLIC_SUPABASE_URL=your-project-url 4 | NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key 5 | 6 | # Loops API key for newsletter and contact management 7 | LOOPS_API_KEY=your-loops-api-key 8 | -------------------------------------------------------------------------------- /packages/landing/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | .env 31 | 32 | # vercel 33 | .vercel 34 | 35 | # typescript 36 | *.tsbuildinfo 37 | next-env.d.ts 38 | -------------------------------------------------------------------------------- /packages/landing/app/(landing)/components/grid-pattern.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/landing/app/(landing)/components/request-logo.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import Image from 'next/image'; 4 | 5 | export const RequestLogo = ({ className }: { className?: string }) => ( 6 | Request Network 13 | ); -------------------------------------------------------------------------------- /packages/landing/app/(landing)/error.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { Button } from "@/components/ui/button"; 4 | import Link from "next/link"; 5 | import { useEffect } from "react"; 6 | 7 | export default function Error({ 8 | error, 9 | reset, 10 | }: { 11 | error: Error & { digest?: string }; 12 | reset: () => void; 13 | }) { 14 | useEffect(() => { 15 | console.error(error); 16 | }, [error]); 17 | 18 | return ( 19 |
20 |

Something went wrong

21 |

22 | We apologize for the inconvenience. Please try again or go back to the homepage. 23 |

24 |
25 | 28 | 29 | 30 | 31 |
32 |
33 | ); 34 | } -------------------------------------------------------------------------------- /packages/landing/app/(landing)/not-found.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { Button } from "@/components/ui/button"; 4 | import Link from "next/link"; 5 | 6 | export default function NotFound() { 7 | return ( 8 |
9 |

404 - Page Not Found

10 |

11 | Sorry, we couldn't find the page you're looking for. 12 |

13 | 14 | 15 | 16 |
17 | ); 18 | } -------------------------------------------------------------------------------- /packages/landing/app/(landing)/opengraph-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/different-ai/note-companion/91bb99d0a9492533b6331164633d73456d6fea5f/packages/landing/app/(landing)/opengraph-image.png -------------------------------------------------------------------------------- /packages/landing/app/PostHogPageView.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { usePathname, useSearchParams } from "next/navigation" 4 | import { useEffect, Suspense } from "react" 5 | import { usePostHog } from 'posthog-js/react' 6 | 7 | function PostHogPageView() { 8 | const pathname = usePathname() 9 | const searchParams = useSearchParams() 10 | const posthog = usePostHog() 11 | 12 | // Track pageviews 13 | useEffect(() => { 14 | if (pathname && posthog && typeof window !== 'undefined') { 15 | let url = window.origin + pathname 16 | if (searchParams && searchParams.toString()) { 17 | url = url + `?${searchParams.toString()}` 18 | } 19 | 20 | posthog.capture('$pageview', { 21 | '$current_url': url, 22 | path: pathname, 23 | }) 24 | } 25 | }, [pathname, searchParams, posthog]) 26 | 27 | return null 28 | } 29 | 30 | // Wrap this in Suspense to avoid the `useSearchParams` usage above 31 | // from de-opting the whole app into client-side rendering 32 | export default function SuspendedPostHogPageView() { 33 | return ( 34 | 35 | 36 | 37 | ) 38 | } -------------------------------------------------------------------------------- /packages/landing/app/dao/error.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { Button } from "@/components/ui/button"; 4 | import Link from "next/link"; 5 | import { useEffect } from "react"; 6 | 7 | export default function Error({ 8 | error, 9 | reset, 10 | }: { 11 | error: Error & { digest?: string }; 12 | reset: () => void; 13 | }) { 14 | useEffect(() => { 15 | console.error(error); 16 | }, [error]); 17 | 18 | return ( 19 |
20 |

Something went wrong

21 |

22 | We apologize for the inconvenience. Please try again or go back to the homepage. 23 |

24 |
25 | 28 | 29 | 30 | 31 |
32 |
33 | ); 34 | } -------------------------------------------------------------------------------- /packages/landing/app/dao/not-found.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { Button } from "@/components/ui/button"; 4 | import Link from "next/link"; 5 | 6 | export default function NotFound() { 7 | return ( 8 |
9 |

404 - Page Not Found

10 |

11 | Sorry, we couldn't find the page you're looking for. 12 |

13 | 14 | 15 | 16 |
17 | ); 18 | } -------------------------------------------------------------------------------- /packages/landing/app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | 6 | 7 | .tiptap p.is-editor-empty:first-child::before { 8 | color: #adb5bd; 9 | content: attr(data-placeholder); 10 | float: left; 11 | height: 0; 12 | pointer-events: none; 13 | } -------------------------------------------------------------------------------- /packages/landing/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import { GeistSans } from "geist/font/sans"; 2 | import "./globals.css"; 3 | import { Metadata } from "next"; 4 | import Providers from "./providers"; 5 | 6 | export const metadata: Metadata = { 7 | metadataBase: new URL(process.env.VERCEL_URL ? `https://${process.env.VERCEL_URL}` : "https://notecompanion.com"), 8 | title: { 9 | default: "Note Companion", 10 | template: "%s | Note Companion", 11 | }, 12 | description: "Your AI-powered assistant for Obsidian.", 13 | icons: { 14 | icon: "/favicon.ico", 15 | shortcut: "/favicon.ico", 16 | apple: "/favicon.ico", 17 | }, 18 | }; 19 | 20 | export default function RootLayout({ 21 | children, 22 | }: { 23 | children: React.ReactNode; 24 | }) { 25 | return ( 26 | 27 | 28 | {children} 29 | 30 | 31 | ); 32 | } -------------------------------------------------------------------------------- /packages/landing/app/opengraph-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/different-ai/note-companion/91bb99d0a9492533b6331164633d73456d6fea5f/packages/landing/app/opengraph-image.png -------------------------------------------------------------------------------- /packages/landing/app/twitter-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/different-ai/note-companion/91bb99d0a9492533b6331164633d73456d6fea5f/packages/landing/app/twitter-image.png -------------------------------------------------------------------------------- /packages/landing/app/types.ts: -------------------------------------------------------------------------------- 1 | export type AttentionPower = 'Squirrel' | 'Caffeinated' | 'Hyperfocus' | 'Time Lord' 2 | 3 | export type Link = { 4 | url: string; 5 | title: string; 6 | } 7 | 8 | export type SubTask = { 9 | id: number; 10 | name: string; 11 | description: string; 12 | completed: boolean; 13 | timeEstimate: number; 14 | } 15 | 16 | export type CreateTask = { 17 | name: string; 18 | description: string; 19 | detailNeeded: boolean; 20 | attentionPower: AttentionPower; 21 | timeEstimate: number; 22 | points: number; 23 | } 24 | 25 | 26 | export interface Task extends CreateTask { 27 | id?: string; 28 | name: string; 29 | description: string; 30 | detailNeeded: boolean; 31 | attentionPower: AttentionPower; 32 | timeEstimate: number; 33 | points: number; 34 | parentTaskId: string | null; 35 | details?: string; 36 | status: 'active' | 'completed' | 'archived' | 'ignored'; 37 | importance: string; 38 | rawMessage: string; 39 | links: Link[] | null; 40 | isMainTask: boolean | null; 41 | } 42 | 43 | export type UserStats = { 44 | points: number; 45 | level: number; 46 | streak: number; 47 | } 48 | 49 | export type ProcessedObject = { 50 | tasks: Task[]; 51 | 52 | }; 53 | -------------------------------------------------------------------------------- /packages/landing/app/utils/transcription.ts: -------------------------------------------------------------------------------- 1 | import { z } from 'zod'; 2 | 3 | export const transcriptionSchema = z.object({ 4 | text: z.string(), 5 | }); 6 | 7 | export type TranscriptionResponse = z.infer; 8 | 9 | export const transcribeAudio = async (blob: Blob): Promise => { 10 | const formData = new FormData(); 11 | formData.append('file', blob, 'recording.webm'); 12 | formData.append('model', 'whisper-1'); 13 | 14 | const response = await fetch('/api/transcribe', { 15 | method: 'POST', 16 | body: formData, 17 | }); 18 | 19 | const data = await response.json(); 20 | const parsed = transcriptionSchema.safeParse(data); 21 | 22 | if (!parsed.success) { 23 | throw new Error('Invalid transcription response'); 24 | } 25 | 26 | return parsed.data; 27 | }; -------------------------------------------------------------------------------- /packages/landing/components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "default", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.ts", 8 | "css": "app/globals.css", 9 | "baseColor": "neutral", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/landing/components/navbar.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import Link from 'next/link' 4 | import { usePathname } from 'next/navigation' 5 | import { Home, Settings } from 'lucide-react' 6 | 7 | export function Navbar() { 8 | const pathname = usePathname() 9 | 10 | return ( 11 | 23 | ) 24 | } -------------------------------------------------------------------------------- /packages/landing/components/tutorial/tutorial-step.tsx: -------------------------------------------------------------------------------- 1 | import { Checkbox } from "../ui/checkbox"; 2 | 3 | export function TutorialStep({ 4 | title, 5 | children, 6 | }: { 7 | title: string; 8 | children: React.ReactNode; 9 | }) { 10 | return ( 11 |
  • 12 | 17 | 28 |
  • 29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /packages/landing/components/typography/inline-code.tsx: -------------------------------------------------------------------------------- 1 | export function TypographyInlineCode() { 2 | return ( 3 | 4 | @radix-ui/react-alert-dialog 5 | 6 | ); 7 | } 8 | -------------------------------------------------------------------------------- /packages/landing/components/ui/badge.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { cva, type VariantProps } from "class-variance-authority" 3 | import { cn } from "@/lib/utils" 4 | 5 | const badgeVariants = cva( 6 | "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", 7 | { 8 | variants: { 9 | variant: { 10 | default: 11 | "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", 12 | secondary: 13 | "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", 14 | destructive: 15 | "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", 16 | outline: "text-foreground", 17 | }, 18 | }, 19 | defaultVariants: { 20 | variant: "default", 21 | }, 22 | } 23 | ) 24 | 25 | export interface BadgeProps 26 | extends React.HTMLAttributes, 27 | VariantProps {} 28 | 29 | function Badge({ className, variant, ...props }: BadgeProps) { 30 | return ( 31 |
    32 | ) 33 | } 34 | 35 | export { Badge, badgeVariants } 36 | -------------------------------------------------------------------------------- /packages/landing/components/ui/checkbox.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as CheckboxPrimitive from "@radix-ui/react-checkbox" 5 | import { Check } from "lucide-react" 6 | 7 | import { cn } from "@/lib/utils" 8 | 9 | const Checkbox = React.forwardRef< 10 | React.ElementRef, 11 | React.ComponentPropsWithoutRef 12 | >(({ className, ...props }, ref) => ( 13 | 21 | 24 | 25 | 26 | 27 | )) 28 | Checkbox.displayName = CheckboxPrimitive.Root.displayName 29 | 30 | export { Checkbox } 31 | -------------------------------------------------------------------------------- /packages/landing/components/ui/input.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | export interface InputProps 6 | extends React.InputHTMLAttributes {} 7 | 8 | const Input = React.forwardRef( 9 | ({ className, type, ...props }, ref) => { 10 | return ( 11 | 20 | ) 21 | } 22 | ) 23 | Input.displayName = "Input" 24 | 25 | export { Input } 26 | -------------------------------------------------------------------------------- /packages/landing/components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as LabelPrimitive from "@radix-ui/react-label" 5 | import { cva, type VariantProps } from "class-variance-authority" 6 | 7 | import { cn } from "@/lib/utils" 8 | 9 | const labelVariants = cva( 10 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" 11 | ) 12 | 13 | const Label = React.forwardRef< 14 | React.ElementRef, 15 | React.ComponentPropsWithoutRef & 16 | VariantProps 17 | >(({ className, ...props }, ref) => ( 18 | 23 | )) 24 | Label.displayName = LabelPrimitive.Root.displayName 25 | 26 | export { Label } 27 | -------------------------------------------------------------------------------- /packages/landing/components/ui/progress.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as ProgressPrimitive from "@radix-ui/react-progress" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const Progress = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >(({ className, value, ...props }, ref) => ( 12 | 20 | 24 | 25 | )) 26 | Progress.displayName = ProgressPrimitive.Root.displayName 27 | 28 | export { Progress } 29 | -------------------------------------------------------------------------------- /packages/landing/components/ui/switch.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import * as React from "react"; 4 | import * as SwitchPrimitives from "@radix-ui/react-switch"; 5 | import { cn } from "../../lib/utils"; 6 | 7 | const Switch = React.forwardRef< 8 | React.ElementRef, 9 | React.ComponentPropsWithoutRef 10 | >(({ className, ...props }, ref) => ( 11 | 19 | 24 | 25 | )); 26 | Switch.displayName = SwitchPrimitives.Root.displayName; 27 | 28 | export { Switch }; -------------------------------------------------------------------------------- /packages/landing/components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | export interface TextareaProps 6 | extends React.TextareaHTMLAttributes {} 7 | 8 | const Textarea = React.forwardRef( 9 | ({ className, ...props }, ref) => { 10 | return ( 11 |