aboutsummaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* fix: add a way to allowlist all domains from ip validationMohamed Bassem2025-11-222-6/+10
|
* fix: use kbd for editor cardMohamed Bassem2025-11-225-36/+58
|
* fix: drop journal retention for sempahore and id providersMohamed Bassem2025-11-172-0/+2
|
* refactor: remove the PrivacyAware interfaceMohamed Bassem2025-11-1710-104/+9
|
* feat: Add collaborative lists (#2146)Mohamed Bassem2025-11-1740-596/+6705
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * feat: Add collaborative lists backend implementation This commit implements the core backend functionality for collaborative lists, allowing multiple users to share and interact with bookmark lists. Database changes: - Add listCollaborators table to track users with access to lists and their roles (viewer/editor) - Add addedBy field to bookmarksInLists to track who added bookmarks - Add relations for collaborative list functionality Access control updates: - Update List model to support role-based access (owner/editor/viewer) - Add methods to check and enforce permissions for list operations - Update Bookmark model to allow access through collaborative lists - Modify bookmark queries to include bookmarks from collaborative lists List collaboration features: - Add/remove/update collaborators - Get list of collaborators - Get lists shared with current user - Only manual lists can have collaborators tRPC procedures: - addCollaborator: Add a user as a collaborator to a list - removeCollaborator: Remove a collaborator from a list - updateCollaboratorRole: Change a collaborator's role - getCollaborators: Get all collaborators for a list - getSharedWithMe: Get all lists shared with the current user - cloneBookmark: Clone a bookmark to the current user's collection Implementation notes: - Editors can add/remove bookmarks from the list (must own the bookmark) - Viewers can only view bookmarks in the list - Only the list owner can manage collaborators and list metadata - Smart lists cannot have collaborators (only manual lists) - Users cannot edit bookmarks they don't own, even in shared lists * feat: Add collaborative lists frontend UI This commit implements the frontend user interface for collaborative lists, allowing users to view shared bookmarks and manage list collaborators. New pages: - /dashboard/shared: Shows bookmarks from lists shared with the user - Displays bookmarks from all collaborative lists - Uses SharedBookmarks component - Shows empty state when no lists are shared Navigation: - Added "Shared with you" link to sidebar with Users icon - Positioned after "Home" in main navigation - Available in both desktop and mobile sidebar Collaborator management: - ManageCollaboratorsModal component for managing list collaborators - Add collaborators by user ID with viewer/editor role - View current collaborators with their roles - Update collaborator roles inline - Remove collaborators - Shows empty state when no collaborators - Integrated into ListOptions dropdown menu - Accessible via "Manage Collaborators" menu item Components created: - SharedBookmarks.tsx: Server component fetching shared lists/bookmarks - ManageCollaboratorsModal.tsx: Client component with tRPC mutations - /dashboard/shared/page.tsx: Route for shared bookmarks page UI features: - Role selector for viewer/editor permissions - Real-time collaborator list updates - Toast notifications for success/error states - Loading states for async operations - Responsive design matching existing UI patterns Implementation notes: - Uses existing tRPC endpoints (getSharedWithMe, getCollaborators, etc.) - Follows established modal patterns from ShareListModal - Integrates seamlessly with existing list UI - Currently uses user ID for adding collaborators (email lookup TBD) * fix typecheck * add collaborator by email * add shared list in the sidebar * fix perm issue * hide UI components from non list owners * list leaving * fix shared bookmarks showing up in homepage * fix getBookmark access check * e2e tests * hide user specific fields from shared lists * simplify bookmark perm checks * disable editable fields in bookmark preview * hide lists if they don't have options * fix list ownership * fix highlights * move tests to trpc * fix alignment of leave list * make tag lists unclickable * allow editors to remove from list * add a badge for shared lists * remove bookmarks of user when they're removed from a list * fix tests * show owner in the manage collab modal * fix hasCollab * drop shared with you * i18n * beta badge * correctly invalidate caches on collab change * reduce unnecessary changes * Add ratelimits * stop manually removing bookmarks on remove * some fixes * fixes * remove unused function * improve tests --------- Co-authored-by: Claude <noreply@anthropic.com>
* deps: upgrade hono and playwrightMohamed Bassem2025-11-163-153/+160
|
* deps: Upgrade typescript to 5.9Mohamed Bassem2025-11-167-161/+161
|
* build: Improve docker caching (#2140)Mohamed Bassem2025-11-165-10/+100
| | | | | * build: Improve docker caching * more fixes
* fix: fix hydration error in admin user listMohamed Bassem2025-11-151-7/+9
|
* feat: import from mymind (#2138)Mohamed Bassem2025-11-154-1/+163
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | * feat: add mymind importer support This commit adds support for importing bookmarks from mymind CSV exports. Changes: - Added mymind to ImportSource type in parsers.ts - Implemented parseMymindBookmarkFile() to parse mymind CSV format - Added mymind case to parseImportFile() switch statement - Added mymind import card to ImportExport UI component - Added English translation for mymind import description - Added comprehensive test for mymind CSV parsing The mymind CSV format includes: - WebPages (URLs with optional notes) - Notes (text content without URLs) - Tags (comma-separated) - Created timestamps (ISO format) Fixes #654 * format * use zod for parsing --------- Co-authored-by: Claude <noreply@anthropic.com>
* feat: add Prometheus counter for HTTP status codes (#2117)Mohamed Bassem2025-11-152-1/+13
| | | | | | | | | | | | | | | | | | | | | | | | | * feat: add Prometheus counter for crawler status codes Add a new Prometheus metric to track HTTP status codes encountered during crawling operations. This helps monitor crawler health and identify patterns in response codes (e.g., 200 OK, 404 Not Found, etc.). Changes: - Add crawlerStatusCodeCounter in metrics.ts with status_code label - Instrument crawlerWorker.ts to track status codes after page crawling - Counter increments for each crawl with the corresponding HTTP status code The metric is exposed at the /metrics endpoint and follows the naming convention: karakeep_crawler_status_codes_total * fix: update counter name to follow Prometheus conventions Change metric name from "karakeep_crawler_status_codes" to "karakeep_crawler_status_codes_total" to comply with Prometheus naming best practices for counter metrics. --------- Co-authored-by: Claude <noreply@anthropic.com>
* fix(mobile): upgrade react-native-pdf to v7 to fix page alignmentMohamedBassem2025-11-153-66/+9
|
* fix(mobile): fix app memory page size compatibility (#2135)Mohamed Bassem2025-11-154-398/+351
| | | | | | | | | | | | | | | | | | | | | | | | | | | * fix(mobile): Add 16KB memory page size support for Android Updates to support Google Play's requirement for 16KB memory page sizes: - Update Expo SDK from 53.0.11 to 53.0.19 - Update expo-image from 2.2.0 to 2.4.0 - Update React Native from 0.79.3 to 0.79.5 - Configure expo-build-properties with: - compileSdkVersion: 35 - targetSdkVersion: 35 - buildToolsVersion: 34.0.0 - ndkVersion: 27.1.12297006 (r27 with 16KB support) These changes ensure all native libraries are compiled with proper alignment for 16KB page sizes as required by Android 15+ devices. Fixes Google Play rejection: "Your app does not support 16 KB memory page sizes" * some fixes * more fixes --------- Co-authored-by: Claude <noreply@anthropic.com>
* release(mobile): Bump mobile version to 1.8.2Mohamed Bassem2025-11-141-3/+3
|
* fix: remove incorrect array destructuring in mobile search (#2124)Mohamed Bassem2025-11-141-1/+1
| | | | | | | | | | | | | The search was crashing because of incorrect array destructuring on the useDebounce hook return value. useDebounce returns a string, not an array, so using `const [query] = useDebounce(...)` caused query to be undefined when the search string was empty. This resulted in passing { text: undefined } to the tRPC endpoint, which failed Zod validation expecting a string. Fixed by removing the array destructuring: const query = useDebounce(...) Co-authored-by: Claude <noreply@anthropic.com>
* feat: correct default prom metrics from web and worker containersMohamed Bassem2025-11-102-0/+2
|
* fix: stop retrying indefinitely in restate queuesMohamed Bassem2025-11-101-0/+9
|
* fix: fix crash in crawler on invalid URL in matchesNoProxyMohamed Bassem2025-11-101-3/+9
|
* feat: add crawler domain rate limiting (#2115)Mohamed Bassem2025-11-095-32/+121
|
* refactor: Allow runner functions to return results to onCompleteMohamed Bassem2025-11-098-36/+32
|
* refactor: Extract ratelimiter into separate plugin (#2112)Mohamed Bassem2025-11-0912-75/+451
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * refactor(trpc): extract rate limiter into dedicated plugin Move the rate limiting middleware from the trpc package to the centralized plugins package. This improves code organization by consolidating all plugins in a single location. Changes: - Created packages/plugins/trpc-ratelimit/ plugin - Moved rate limiter from packages/trpc/rateLimit.ts to packages/plugins/trpc-ratelimit/src/index.ts - Added trpc-ratelimit export to plugins package.json - Added @trpc/server dependency to plugins package - Updated trpc package to import from @karakeep/plugins/trpc-ratelimit - Added @karakeep/plugins dependency to trpc package - Removed packages/trpc/plugins/ directory * refactor(plugins): decouple rate limiter from tRPC Refactor the rate limiting plugin to be framework-agnostic, allowing it to be used outside of tRPC contexts. The plugin now has a generic core with a tRPC-specific adapter. Changes: - Renamed trpc-ratelimit to ratelimit plugin - Created generic RateLimiter class with framework-agnostic API - Added checkRateLimit() method that returns allow/deny results - Created separate tRPC adapter (src/trpc.ts) that uses the generic core - Exported both generic (RateLimiter, globalRateLimiter) and tRPC-specific (createRateLimitMiddleware) APIs - Updated trpc package to import from @karakeep/plugins/ratelimit - Updated plugins package.json exports Benefits: - Rate limiter can now be used in any context (HTTP handlers, WebSocket, etc.) - Cleaner separation of concerns - Easy to create adapters for other frameworks - Generic API allows for custom error handling * refactor(plugins): integrate rate limiter with plugin registry Refactor the rate limiting plugin to use the centralized plugin system with PluginManager, making it consistent with other plugins like queue and search providers. Changes: - Added RateLimit plugin type to PluginType enum - Created RateLimitClient interface in packages/shared/ratelimiting.ts - Created RateLimitProvider class implementing PluginProvider - Updated plugin to auto-register with PluginManager on import - Updated tRPC adapter to use getRateLimitClient() from PluginManager - Added ratelimit plugin to loadAllPlugins() in shared-server - Updated shared/plugins.ts with RateLimit type mapping Benefits: - Consistent plugin architecture across the codebase - Rate limiter can be swapped with alternative implementations - Centralized plugin management and logging - Better separation of concerns - Framework-agnostic core with tRPC adapter pattern * refactor(trpc): move rate limit middleware to trpc package Move the tRPC-specific rate limiting middleware from the plugins package to the trpc package, making the plugins package framework-agnostic. Changes: - Moved packages/plugins/ratelimit/src/trpc.ts to packages/trpc/lib/rateLimit.ts - Updated packages/trpc/index.ts to import from local lib/rateLimit - Removed tRPC export from packages/plugins/ratelimit/index.ts - Removed @trpc/server dependency from packages/plugins/package.json Benefits: - plugins package is now framework-agnostic - tRPC-specific code lives in the trpc package where it belongs - Cleaner separation of concerns - Rate limiter plugin can be used in any context without tRPC * refactor(plugins): rename to ratelimit-memory and add tests Rename the rate limiting plugin from "ratelimit" to "ratelimit-memory" to better indicate it's an in-memory implementation. This naming leaves room for future implementations like ratelimit-redis. Also added comprehensive test coverage. Changes: - Renamed packages/plugins/ratelimit to ratelimit-memory - Updated package.json export from ./ratelimit to ./ratelimit-memory - Updated shared-server to import @karakeep/plugins/ratelimit-memory - Added comprehensive unit tests (index.test.ts): - Rate limit enforcement tests - Window expiration tests - Identifier and path isolation tests - Reset functionality tests - Cleanup mechanism tests - Added provider integration tests (provider.test.ts): - PluginProvider interface compliance - Client singleton behavior - End-to-end rate limiting functionality Benefits: - More descriptive plugin name indicating the storage mechanism - Better test coverage ensuring reliability - Easier to add alternative implementations (Redis, etc.) * change the api to only take the key * move the serverConfig check to the trpc * fix lockfile * get rid of the timer --------- Co-authored-by: Claude <noreply@anthropic.com>
* feat(extension): Add custom header support for extension (#2111)Mohamed Bassem2025-11-096-7/+204
| | | Fixes #1287
* feat: Add bookmark sources statistics section (#2110)Mohamed Bassem2025-11-095-1/+146
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * feat: add bookmark sources statistics to usage stats page Add a new section to the usage statistics page that displays stats about bookmark sources (mobile, extension, web, API, CLI, etc). Changes: - Add bookmarksBySource field to user stats response schema - Implement backend query to fetch bookmarks grouped by source - Add new "Bookmark Sources" card to stats page UI - Add helper function to format source names for display * refactor: use stricter enum type for bookmark sources in stats API Replace generic string type with zBookmarkSourceSchema enum for better type safety and autocomplete. This ensures the API contract matches the database schema definition. Changes: - Import and use zBookmarkSourceSchema in user stats response - Define BookmarkSource type alias in frontend - Update formatSourceName to use stricter type and return non-nullable - Remove fallback case since all enum values are now handled * refactor: use shared BookmarkSource type and add i18n support - Replace local BookmarkSource type with canonical type from shared package using z.infer<typeof zBookmarkSourceSchema> - Add translation support for "Bookmark Sources" title and empty state - Add bookmark_sources.title and bookmark_sources.empty keys to English locale file This ensures type consistency across the codebase and prepares for future localization of the bookmark sources feature. * fix icons --------- Co-authored-by: Claude <noreply@anthropic.com>
* feat: Add page titles (#2109)Mohamed Bassem2025-11-0920-0/+247
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * feat: add Next.js metadata titles to dynamic and settings pages Add page titles using Next.js metadata API for better SEO and user experience: - List pages: Show list name in format "<name> | Karakeep" - Tag pages: Show tag name in format "<name> | Karakeep" - Admin pages: Add titles for overview, users, and background jobs pages - Settings pages: Add titles for all settings pages (API keys, AI, feeds, import, info, webhooks, subscription, rules, stats, assets, broken links) For client components (rules, stats, assets, broken-links), created layout.tsx files to export metadata since metadata can only be exported from server components. * feat: add Next.js metadata titles to dashboard pages Add page titles using Next.js metadata API to archive, favourites, highlights, and all tags pages: - Archive page: Show "Archive | Karakeep" - Favourites page: Show "Favourites | Karakeep" - Highlights page: Show "Highlights | Karakeep" - All Tags page: Show "All Tags | Karakeep" Improves SEO and user experience across all dashboard browsing pages. * refactor: use i18n translations for dashboard page titles Convert hardcoded page titles to use translations via generateMetadata: - Archive page: Uses common.archive translation - Favourites page: Uses lists.favourites translation - Highlights page: Uses common.highlights translation - All Tags page: Uses tags.all_tags translation Improves localization support across dashboard pages. * feat: add i18n translations to admin and settings page titles Convert hardcoded page titles to use translations via generateMetadata: - Admin Overview: Uses admin.admin_settings translation - AI Settings: Uses settings.ai.ai_settings translation - API Keys: Uses settings.api_keys.api_keys translation - Feed Settings: Uses settings.feeds.rss_subscriptions translation - Import/Export: Uses settings.import.import_export translation - Account Info: Uses settings.info.user_info translation - Subscription: Uses settings.subscription.subscription translation - Webhooks: Uses settings.webhooks.webhooks translation Improves localization support across admin and settings pages. * revert accidental commit * more translations * more fixes --------- Co-authored-by: Claude <noreply@anthropic.com>
* feat: add failed_permanent metric for worker monitoring (#2107)Mohamed Bassem2025-11-099-0/+32
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * feat: add last failure timestamp metric for worker monitoring Add a Prometheus Gauge metric to track the timestamp of the last failure for each worker. This complements the existing failed job counter by providing visibility into when failures last occurred for monitoring and alerting purposes. Changes: - Added workerLastFailureGauge metric in metrics.ts - Updated all 9 workers to set the gauge on failure: - crawler, feed, webhook, assetPreProcessing - inference, adminMaintenance, ruleEngine - video, search * refactor: track both all failures and permanent failures with counter Remove the gauge metric and use the existing counter to track both: - All failures (including retry attempts): status="failed" - Permanent failures (retries exhausted): status="failed_permanent" This provides better visibility into retry behavior and permanent vs temporary failures without adding a separate metric. Changes: - Removed workerLastFailureGauge from metrics.ts - Updated all 9 workers to track failed_permanent when numRetriesLeft == 0 - Maintained existing failed counter for all failure attempts * style: format worker files with prettier --------- Co-authored-by: Claude <noreply@anthropic.com>
* release(docs): release the 0.28 docsMohamed Bassem2025-11-0888-23/+5308
|
* release(extension): Release version 1.7.1Mohamed Bassem2025-11-081-1/+1
|
* release(mobile): Bump mobile version to 1.8.1Mohamed Bassem2025-11-081-3/+3
|
* fix: standardize US English translations to professional toneMohamed Bassem2025-11-081-24/+24
| | | | | | Remove informal/casual language ('wanna', 'mate', 'dude', 'ain't', 'lil') and replace with standard professional English. This maintains consistency with other language variants and the overall professional tone of the application.
* i18n: Sync weblate translationsHosted Weblate2025-11-0831-205/+3808
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Co-authored-by: Aindriú Mac Giolla Eoin <aindriu80@gmail.com> Co-authored-by: Hamid Jamali <hamid1375jamali@gmail.com> Co-authored-by: Hosted Weblate <hosted@weblate.org> Co-authored-by: Kachelkaiser <kachelkaiser@htpst.de> Co-authored-by: OpenAI <noreply-mt-openai@weblate.org> Co-authored-by: Thomas K <t.kristner@gmail.com> Co-authored-by: hb k <hbk0424@gmail.com> Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/ar/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/cs/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/da/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/de/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/el/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/en_US/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/es/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/fa/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/fi/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/fr/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/ga/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/gl/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/hr/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/hu/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/it/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/ja/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/ko/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/nb_NO/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/nl/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/pl/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/pt/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/pt_BR/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/ru/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/sk/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/sl/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/sv/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/tr/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/uk/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/vi/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/zh_Hans/ Translate-URL: https://hosted.weblate.org/projects/karakeep/karakeep/zh_Hant/ Translation: Karakeep/Karakeep
* tests: fix crawling and search e2e tests (#2105)Mohamed Bassem2025-11-088-42/+114
| | | | | | | * tests: Attempt to fix flaky tests * fix internal address * fix assets tests
* feat(extension): Allow writing notes directly in the extension (#2104)Mohamed Bassem2025-11-083-0/+132
| | | | | | | | | | | | | | | | | | | | | | * feat(extension): add notes editor to bookmark hoarded screen Adds the ability to directly add and edit notes for bookmarks in the browser extension's hoarded screen (the page shown after saving a bookmark). Changes: - Created Textarea UI component for the browser extension - Created NoteEditor component that uses useUpdateBookmark hook - Added Notes section to BookmarkSavedPage, displayed between the header and tags - Notes auto-save when the user clicks away from the textarea (onBlur) - Shows saving state and error messages to the user This brings feature parity with the web app's notes functionality. * add explicit button * more fixes --------- Co-authored-by: Claude <noreply@anthropic.com>
* fix(mobile): fix default address not correctly stored in settingsMohamedBassem2025-11-082-3/+3
|
* feat(mobile): add custom headers configuration in sign-in screen (#2103)Mohamed Bassem2025-11-088-5/+252
| | | | | | | | | | | | | | | | | | | | | | | | * feat(mobile): add custom headers configuration in sign-in screen Add ability for mobile app users to configure custom HTTP headers that are sent with every API request. This enables users to add authentication headers, proxy headers, or other custom headers required by their server setup. Changes: - Add customHeaders field to mobile app settings schema - Create CustomHeadersModal component for managing headers - Update sign-in screen with link to configure custom headers - Modify tRPC provider to merge custom headers with Authorization header The custom headers are stored securely in the app settings and persist across sessions. * fix keyboard * add custom headers to other callsites --------- Co-authored-by: Claude <noreply@anthropic.com>
* tests: Fix failing testMohamed Bassem2025-11-081-12/+16
|
* feat: Add what's new modal in the sidebar (#2099)Mohamed Bassem2025-11-083-13/+262
| | | | | | | * Refactor sidebar release modal to use React Query * fixes * fix manual server override
* feat: Add support for user uploaded files (#2100)Mohamed Bassem2025-11-0810-31/+101
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * feat: add user file upload support for bookmarks Add a new "user-uploaded" asset type that allows users to upload and attach their own files to bookmarks from the attachment box in the bookmark preview page. Changes: - Add USER_UPLOADED asset type to database schema - Add userUploaded to zAssetTypesSchema for type safety - Update attachment permissions to allow attaching/detaching user files - Add fileName field to asset schema for displaying custom filenames - Add "Upload File" button in AttachmentBox component - Display actual filename for user-uploaded files - Allow any file type for user uploads (respects existing upload limits) - Add Upload icon for user-uploaded files Fixes #1863 related asset attachment improvements * fix: ensure fileName is returned and remove edit button for user uploads - Fix attachAsset mutation to fetch and return complete asset with fileName instead of just returning the input (which lacks fileName) - Remove replace/edit button for user-uploaded files - users can only delete and re-upload instead - This ensures the filename displays correctly in the UI immediately after upload Fixes fileName propagation issue for user-uploaded assets * fix asset file name * remove filename from attach asset api --------- Co-authored-by: Claude <noreply@anthropic.com>
* refactor: consolidate multiple karakeep plugins into one package (#2101)Mohamed Bassem2025-11-0829-182/+33
| | | | | | | | | | | | | | | | | | | | | | | | * refactor: consolidate plugin packages into single plugins directory - Create new `packages/plugins` directory with consolidated package.json - Move queue-liteque, queue-restate, and search-meilisearch to subdirectories - Update imports in packages/shared-server/src/plugins.ts - Remove individual plugin package directories - Update shared-server dependency to use @karakeep/plugins This reduces overhead of maintaining multiple separate packages for plugins. * refactor: consolidate plugin config files to root level - Move .oxlintrc.json to packages/plugins root - Move vitest.config.ts to packages/plugins root - Update vitest config paths to work from root - Remove individual config files from plugin subdirectories This reduces configuration duplication across plugin subdirectories. --------- Co-authored-by: Claude <noreply@anthropic.com>
* fix: metascraper logo to go through proxy if one configured. fixes #1863Mohamed Bassem2025-11-031-1/+14
|
* feat(extension): add tab bookmark badge indicator (#1745)qixing-jk2025-11-0314-142/+827
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * feat: add tab bookmark count badge indicator - implement getApiClient function to create and cache TRPC client - add tab activation listener to check bookmark count - display badge with count and appropriate color based on results - handle errors by showing error indicator in badge * feat: add show count badge setting to extension - Add showCountBadge setting to settings schema and default values - Implement toggle button in OptionsPage for count badge visibility - Modify background script to respect showCountBadge setting - Add logging for archive count check in background script Closes #486 * feat(background): refactor tab badge update logic - Extract badge setting logic into reusable `setBadge` function - Create `getTabCount` function to fetch bookmark count and existence - Implement `checkAndUpdateIcon` function to centralize icon update logic - Add support for tab updates via `chrome.tabs.onUpdated` listener - Improve error handling with consistent badge display * feat(background): implement badge caching system - Add badge cache initialization and periodic cleanup - Implement cache get/set operations for badge status - Update setBadge function to use cached values when available - Modify badge display logic to check cache before making API calls * feat(badgeCache): add debug logging for cache operations - Add console logs to track cache initialization, purging, and operations - Move debug log in checkAndUpdateIcon to better position * feat: add badge refresh on bookmark creation and deletion - implement message types for badge refresh communication - update background script to handle REFRESH_BADGE messages - modify SavePage to send message on successful bookmark creation - modify BookmarkSavedPage to send message on successful deletion - add clearBadgeStatusSWR utility function import and usage * perf(badge-cache): decrease purge alarm interval The badge cache purge alarm was previously set to run every 60 minutes. This change reduces the interval to 10 minutes to ensure more frequent cache cleanup and better memory management. * feat(background): clean up API client and badge cache on invalid settings - add cleanupApiClient function to trpc utils - modify checkSettingsState to handle async operations - clear API client and badge status when settings are invalid - update settings subscription to handle async operations * feat: reset settings to include showCountBadge flag when logout When deleting API key, ensure showCountBadge is also reset to false to maintain consistent state in the options page configuration. * refactor: use BOOKMARK_REFRESH_BADGE instead of separate created/deleted types * perf(badgeCache): replace alarm-based purge with on-demand expiration check - Remove periodic alarm system for cache purging - Add lastPurgeTimestamp tracking for efficient cache maintenance - Update manifest to remove unnecessary alarms permission - Modify background script to use new on-demand purge mechanism - Clean up related alarm listener and initialization code * feat: Replace count badge button with toggle switch - add new Switch component based on Radix UI - update OptionsPage to use Switch for count badge setting * feat: Add horizontal rule separator in options page - Add `<hr />` element between sections for better visual separation - Improve UI organization in the OptionsPage component * feat(badgeCache): implement persistent last purge timestamp storage - Replace in-memory timestamp with chrome.storage persistence - Add getter/setter functions for last purge timestamp - Update checkAndPurgeIfNeeded to use persistent storage * refactor(badgeCache): Improve type safety and storage utilities - Add BadgeCacheEntry and BadgeCacheStorage types - Extract storage operations to dedicated utility functions - Improve code organization and documentation - Enhance type safety throughout badge cache operations * feat(extension): add context menu options to clear cache - introduce new context menu items for cache management - add clear current site cache functionality - add clear all cache functionality - conditionally show cache menu items based on showCountBadge setting - pass settings to context menu registration/removal functions * feat(extension): add configurable badge cache expiration time - introduce `badgeCacheExpireMs` setting with 1-hour default - update settings schema and default values - add input field in OptionsPage for cache time configuration - modify badgeCache to use dynamic expiration time from settings - improve cache logging for better debugging visibility * Revert "feat: reset settings to include showCountBadge flag when logout" This reverts commit cf071e9dd50f1a1ac0a8dd3b68a4359ecc30c783. # Conflicts: # apps/browser-extension/src/OptionsPage.tsx * refactor(extension): extract badge cache expiration constant Extract DEFAULT_BADGE_CACHE_EXPIRE_MS constant to central location in settings.ts and reuse it across badgeCache.ts and OptionsPage.tsx. Remove duplicate constant definitions and ensure consistent default value usage. * refactor(extension): standardize showCountBadge default via shared constant - introduce DEFAULT_SHOW_COUNT_BADGE in settings schema - replace hardcoded defaults with constant in schema and OptionsPage - maintain backward compatibility with existing boolean type * feat(extension): simplify context menu removal logic - remove redundant `settings` parameter from `removeContextMenus` - replace selective menu removal with `chrome.contextMenus.removeAll()` - update function call to match new signature * refactor(extension): rename site-related cache terms to page for clarity - update context menu title from "Clear Current Site Cache" to "Clear Current Page Cache" - rename `clearCurrentSiteCache()` to `clearCurrentPageCache()` - adjust related comments, logs, and docstrings for consistency * refactor(extension): improve tab event handler parameter naming - rename `activeInfo` to `tabActiveInfo` in `onActivated` listener - rename `changeInfo` to `tabId` in `onUpdated` listener * refactor(extension): add isHttpUrl utility and refactor server address validation - introduce reusable `isHttpUrl` function in new `url.ts` utility module - replace inline protocol check with utility call in NotConfiguredPage * feat(extension): filter out non-HTTP URLs from badge count updates - add `isHttpUrl` import and check in badge update validation - skip badge updates for non-HTTP URLs to prevent invalid requests * feat(extension): filter out non-HTTP URLs from bookmark creation Add validation using isHttpUrl utility to ensure only HTTP/HTTPS URLs are processed when creating bookmarks from current tab. * chore: remove .ts extension from internal import statements * feat(extension): validate and trim server address input in NotConfiguredPage - use trimmed input for validation and state updates - ensure consistent handling of trailing slashes in server address * feat(extension): prevent non-HTTP(S) URL bookmark creation with validation - Add URL validation in background script to filter out non-HTTP(S) URLs before creating link-type bookmarks, logging warnings for invalid URLs. - Enhance SavePage component with explicit error messages for: - Missing tab URLs - Unsupported URL schemes (non-HTTP(S)) - Improve error display by rendering messages immediately when errors occur instead of waiting for status changes. * feat(extension): clear existing context menus before registration This ensures no duplicate menu items are created when the extension reinitializes or settings are updated. * feat(extension): display "+" suffix for default bookmarks per page count Add logic to append "+" suffix when badge count matches DEFAULT_NUM_BOOKMARKS_PER_PAGE to indicate potential overflow. * fix(extension): ensure API client cleanup on settings state change Clean up API client before handling settings state to prevent stale connections when address or API key is missing. * fix(extension): clear badge text when tab is invalid or incomplete Ensure badge is reset when URL is non-HTTP or tab status is not complete. * feat(extension): improve badge revalidation for stale cached data - simplify badge setting from cached data - add background revalidation for non-fresh cache - ensure badge updates when stale cache is detected * feat(extension): refresh active tab badges after cache clearance Added logic to update badge icons for all active tabs when clearing the badge status cache, ensuring UI consistency across the extension. * feat: add null checks for tab URL and ID in REFRESH_BADGE handler Add defensive programming to prevent runtime errors when processing REFRESH_BADGE messages with missing or invalid tab properties. * feat(extension): replace badge status SWR clear with full cache refresh Replace selective SWR badge status clearing with a complete cache refresh to ensure consistent badge state across all active tabs. Updates the `clearBadgeStatusSWR()` call to use the more comprehensive `clearAllCache()` method and improves related documentation. * feat(extension): add validation & error handling for API client - add null check and error throw in `getTabCount` when API client fails - ensure badge is cleared when API client is unavailable - refactor `getApiClient` to use destructured settings - fix potential undefined access in TRPC client initialization * feat(extension): replace isExisted with exactMatch for precise bookmark info - modify getTabCount to return exactMatch instead of isExisted - update BadgeCacheEntry type to use ZBookmark|null for exactMatch - adjust setBadge and setBadgeStatusSWR to handle new exactMatch format - ensure backward compatibility by converting exactMatch to boolean * refactor(background): rename getTabCount to getBookmarkStatusForUrl - improve function naming to better reflect return value - update JSDoc to clarify return object structure - adjust all function calls to use new name * feat(extension): add "View page in Karakeep" context menu option - introduce new `VIEW_PAGE_IN_KARAKEEP` menu item for extension action - extend `handleContextMenuClick` to support optional tab parameter - add `searchCurrentUrl` function to handle URL-based searches - implement exact match and search fallback logic with proper URL encoding - ensure error handling and validation for invalid URLs * feat(extension): reorder menu items and extend page context support - Move 'Add to Karakeep' menu creation before conditional block - Add 'page' context to 'View this page in Karakeep' menu item * feat(extension): add toggle to enable/disable badge caching - introduce `useBadgeCache` setting in schema and defaults - add switch control in OptionsPage to toggle cache usage - conditionally render cache expire time input based on toggle - make badge cache operations respect the toggle setting - hide cache-related context menu items when caching disabled - skip cache operations in background when disabled - prevent cache checks and purges when caching is off * fix(extension): handle cache miss in bookmark search flow Previously, the search flow would silently fail (no-op) when the cache missed. Now, it falls back to fetching the bookmark status directly from the server when no cached data is available. Also refactored to avoid redundant settings fetch and improve code readability. * refactor(badge): implement generic cache utility and refactor badge cache * Remove dedicated cache type definitions in favor of generic solution * Create reusable cache utility with L1/L2 (memory/storage) support * Simplify badge cache implementation using new generic cache * Remove redundant SWR-specific functions and consolidate logic * Improve type safety and error handling in cache operations * Eliminate deprecated cache management functions and types * refactor(extension): replace custom cache with TanStack Query for badge status - Remove custom SWR cache implementation - Add TanStack Query persistence with Chrome storage - Update badge status logic to use QueryClient - Add storage persister utility for Chrome - Update TRPC client initialization with QueryClient - Add required TanStack Query persistence dependencies * fix(extension): add missing `useBadgeCache` config and refactor cache logic - restore accidentally removed `useBadgeCache` setting from refactor - update cache invalidation logic to include `useBadgeCache` changes - modify QueryClient config to respect `useBadgeCache` toggle - improve settings comparison logic for better reuse detection * fix(extension): use dynamic key for TanStack query cache persistence Previously used hardcoded string 'TANSTACK_QUERY_CACHE_KEY' instead of the defined constant, which could lead to inconsistent storage access. * fix(cache): propagate fetch errors to avoid caching failed badge status Previously, API errors would return an empty status, causing cache to store invalid results. Now errors are thrown so the cache treats them as misses. * fix(extension): guard chrome storage and respect cache disable setting - use `globalThis.chrome` to avoid runtime errors in non-extension contexts - skip persistence when `useBadgeCache=false` and clear existing cache - add `maxAge` and `buster` to prevent stale/incompatible data restoration * refactor(badgeCache): remove redundant null check for searchBookmarks data Remove unnecessary if (!data) guard since searchBookmarks query is guaranteed to return a non-nullable response due to its Zod schema. Use direct access to data.bookmarks and simplify empty state check with bookmarksLength. * fix(badgeCache): throw error on misconfiguration instead of caching empty Prevent cache poisoning by throwing when API client is not configured. This ensures setup errors are visible rather than silently cached as 0. * fix(badgeCache): add fallback to fetchBadgeStatus when QueryClient missing Prevents null returns by falling back to direct fetch when QueryClient is unavailable, ensuring badge remains responsive. * feat(extension): add yellow badge for URLs ignoring anchor and trailing slash - implement partial URL matching logic in badge status calculation - introduce `BadgeMatchType` enum for different match scenarios - update badge color scheme (green=exact, yellow=partial, red=none) - refactor badge status interface and setBadge function signature - handle edge cases for null badge status in error scenarios * feat: support partial bookmark matches in badge status check - use partial match fallback when exact match is unavailable - update target URL generation to handle both match types - ensure consistent bookmark ID reference in preview URL * refactor: improve error handling and badge status logic * wrap `removeContextMenus()` in try-catch block to prevent crashes when context menus API fails * simplify badge setting logic by removing redundant status check * fix `getBadgeStatus()` return type to always resolve with `BadgeStatus` * update import path for `urlsMatchIgnoringAnchorAndTrailingSlash` * clarify comments for URL matching logic and edge cases * perf: parallelize active-tab badge refresh after cache clear Avoid serial waits across windows/tabs by using Promise.all to process active tab IDs concurrently. Replaces nested loops with flatMap and filter for cleaner extraction of active tab IDs. * fix(badge): isolate cache config to badge queries only Move cache time configuration from global QueryClient to badge-specific queries to prevent unintended caching in other query operations. * fix: Invalid configuration check should verify if either field is missing. Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix(trpc): include address in cache buster to isolate persisted caches Prevents restoring stale data from a different server after switching address by scoping the cache buster to the current backend address. * feat(trpc): ensure proper client cleanup on config changes - add client removal from persistent storage when address/apiKey invalid - ensure cache wipe when switching context with address/apiKey changes - simplify persister creation by using default chrome.storage.local - make storage parameter optional in createChromeStorage * fix bad merge * simplify badge by dropping the count * more fixes * more fix --------- Co-authored-by: Mohamed Bassem <me@mbassem.com>
* fix: restore image size in grid layoutMohamed Bassem2025-11-031-2/+2
|
* deps: Upgrade react-query to 5.90MohamedBassem2025-11-0212-93/+93
|
* feat: Support inline toggling for todos. fixes #1931 (#1933)Cédric2025-11-023-1/+85
| | | | | | | | | | | | * [1931] Can now chain the creation of todos from the quick add form * [1931] Can now toggle todos from the masonry view + added a custom renderer for inputs of type checkbox (required to remove the readonly default attribute) * handle nested lists and case --------- Co-authored-by: Cédric <cedric.marinot@elosi.com> Co-authored-by: Mohamed Bassem <me@mbassem.com>
* fix: fix monolith to respect crawler proxyMohamed Bassem2025-11-021-0/+9
|
* feat(rss): Add import tags from RSS feed categories (#2031)Mohamed Bassem2025-11-028-0/+2596
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * feat(feeds): Add import tags from RSS feed categories - Add importTags boolean field to rssFeedsTable schema (default: false) - Create database migration 0063_add_import_tags_to_feeds.sql - Update zod schemas (zFeedSchema, zNewFeedSchema, zUpdateFeedSchema) to include importTags - Update Feed model to handle importTags in create and update methods - Update feedWorker to: - Read title and categories from RSS parser - Attach categories as tags to bookmarks when importTags is enabled - Log warnings if tag attachment fails Resolves #1996 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Mohamed Bassem <MohamedBassem@users.noreply.github.com> * feat(web): Add importTags option to feed settings UI - Add importTags toggle to FeedsEditorDialog (create feed) - Add importTags toggle to EditFeedDialog (edit feed) - Display as a bordered switch control with descriptive text - Defaults to false for new feeds Co-authored-by: Mohamed Bassem <MohamedBassem@users.noreply.github.com> * fix migration * remove extra migration --------- Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: Mohamed Bassem <MohamedBassem@users.noreply.github.com>
* fix: fix crash in search input when query contains a percent. fixes #1941Mohamed Bassem2025-11-021-1/+1
|
* feat: Add view options to show tag/title and control image fit. Fixes #1960Mohamed Bassem2025-11-026-29/+214
|
* refactor: improve the userLocalSetting server functionsMohamed Bassem2025-11-021-27/+14
|
* feat: Make search job timeout configurableMohamed Bassem2025-11-024-3/+8
|
* feat: display notes on bookmark card (#2083)xuatz2025-11-0213-25/+268
| | | | | | | | | | | | | | | | | | | | | | | | | * feat: display notes on bookmark card * apply styling * include mobile impl * apply pr comments * add display options menu into PR * put it under app setting * cleanup * address pr comments * change the default for show notes to false * make the in-card note font lighter --------- Co-authored-by: Mohamed Bassem <me@mbassem.com>