| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* feat: add customizable tag styles
* add tag lang setting
* ui settings cleanup
* fix migration
* change look of the field
* more fixes
* fix tests
|
| |
|
|
|
|
|
|
|
|
|
| |
* Matter import
* use zod
* fix date parsing
---------
Co-authored-by: Mohamed Bassem <me@mbassem.com>
|
| |
|
|
|
|
|
|
|
|
|
| |
* feat: support archiving as pdf
* add supprot for manually triggering pdf downloads
* fix submenu
* menu cleanup
* fix store pdf
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
client (#2231)
* Add OPENAI_PROXY_URL configuration and support for proxy in OpenAIInferenceClient
* docs: add OPENAI_PROXY_URL configuration for proxy support in OpenAI API requests
* format
---------
Co-authored-by: Mohamed Bassem <me@mbassem.com>
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* fix: preserve retry count when rate-limited jobs are rescheduled
Previously, when a domain was rate-limited in the crawler worker,
the job would be re-enqueued as a new job, which reset the failure
count. This meant rate-limited jobs could retry indefinitely without
respecting the max retry limit.
This commit introduces a RateLimitRetryError exception that signals
the queue system to retry the job after a delay without counting it
as a failed attempt. The job is retried within the same invocation,
preserving the original retry count.
Changes:
- Add RateLimitRetryError class to shared/queueing.ts
- Update crawler worker to throw RateLimitRetryError instead of re-enqueuing
- Update Restate queue service to handle RateLimitRetryError with delay
- Update Liteque queue wrapper to handle RateLimitRetryError with delay
This ensures that rate-limited jobs respect the configured retry limits
while still allowing for delayed retries when domains are rate-limited.
* refactor: use liteque's native RetryAfterError for rate limiting
Instead of manually handling retries in a while loop, translate
RateLimitRetryError to liteque's native RetryAfterError. This is
cleaner and lets liteque handle the retry logic using its built-in
mechanism.
* test: add tests for RateLimitRetryError handling in restate queue
Added comprehensive tests to verify that:
1. RateLimitRetryError delays retry appropriately
2. Rate-limited retries don't count against the retry limit
3. Jobs can be rate-limited more times than the retry limit
4. Regular errors still respect the retry limit
These tests ensure the queue correctly handles rate limiting
without exhausting retry attempts.
* lint & format
* fix: prevent onError callback for RateLimitRetryError
Fixed two issues with RateLimitRetryError handling in restate queue:
1. RateLimitRetryError now doesn't trigger the onError callback since
it's not a real error - it's an expected rate limiting behavior
2. Check for RateLimitRetryError in runWorkerLogic before calling onError,
ensuring the instanceof check works correctly before the error gets
further wrapped by restate
Updated tests to verify onError is not called for rate limit retries.
* fix: catch RateLimitRetryError before ctx.run wraps it
Changed approach to use a discriminated union instead of throwing
and catching RateLimitRetryError. Now we catch the error inside the
ctx.run callback before it gets wrapped by restate's TerminalError,
and return a RunResult type that indicates success, rate limit, or error.
This fixes the issue where instanceof checks would fail because
ctx.run wraps all errors in TerminalError.
* more fixes
* rename error name
---------
Co-authored-by: Claude <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* feat: Add owner icon to bookmarks in shared lists
Display a small icon showing the bookmark owner's name and email on hover when viewing bookmarks from other users in shared lists. The icon appears in the top-right corner of bookmark cards across all layout types (grid, list, compact).
Changes:
- Add user field to ZBookmark type to include owner name and email
- Update bookmark queries to fetch user information via join
- Create BookmarkOwnerIcon component with tooltip showing owner details
- Integrate owner indicator into BookmarkLayoutAdaptingCard for all layouts
- Only show icon for bookmarks not owned by current user
* use icons in more places
* remove tooltip providers
* fix non list context
---------
Co-authored-by: Claude <noreply@anthropic.com>
|
| | |
|
| |
|
|
|
| |
* refactor: move assets to their own model
* move asset privacy checks to the model
|
| |
|
|
|
|
|
|
|
|
|
| |
* feat: add support for user avatars
* more fixes
* more fixes
* more fixes
* more fixes
|
| |
|
|
|
|
|
|
|
| |
When importing bookmarks from an HTML file, empty H3 tags (folder names)
are now replaced with "Unnamed" to prevent import failures.
Fixes #2299
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Mohamed Bassem <MohamedBassem@users.noreply.github.com>
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* feat: Add per-user settings to disable auto-tagging and auto-summarization
This commit adds user-level controls for AI features when they are enabled
on the server. Users can now toggle auto-tagging and auto-summarization
on/off from the AI Settings page.
Changes:
- Added autoTaggingEnabled and autoSummarizationEnabled fields to user table
- Updated user settings schemas and API endpoints to handle new fields
- Modified inference workers to check user preferences before processing
- Added toggle switches to AI Settings page (only visible when server has features enabled)
- Generated database migration for new fields
- Exposed enableAutoTagging and enableAutoSummarization in client config
The settings default to null (use server default). When explicitly set to false,
the user's bookmarks will skip the respective AI processing.
* revert migration
* i18n
---------
Co-authored-by: Claude <noreply@anthropic.com>
|
| | |
|
| |
|
|
|
|
|
|
|
| |
* fix: optimize tagging db queries
* review
* parallel queries
* refactoring
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
| |
timeout"
This reverts commit 6db14ac492cd5d9e26d0d986513771f14faa7fd0.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* Add initial impl
* fix some format inconsistencies, add indicator in user settings when local is out of sync
* Fix sliders in user settings, unify constants and formatting
* address CodeRabbit suggestions
* add mobile implementation
* address coderabbit nitpicks
* fix responsiveness of the reader settings popover
* Move more of the web UI strings to i18n
* update translations for more coverage
* remove duplicate logic/definitions
* fix android font family
* add shared reading setting hook between web and mobile
* unify reader settings context for both web and mobile
* remove unused export
* address coderabbit suggestions
* fix tests
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
| |
- Added ASSET_PREPROCESSING_JOB_TIMEOUT_SEC environment variable with default of 60 seconds (increased from hardcoded 30 seconds)
- Updated worker to use the configurable timeout from serverConfig
- Added documentation for the new configuration option
|
| | |
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* feat: check import quota before importing bookmarks
Add quota validation before bookmark import to prevent users from
exceeding their bookmark limits. The implementation includes:
- New QuotaService.canImportBookmarks() method to check if user can import N bookmarks
- New tRPC checkImportQuota procedure for client-side quota validation
- Updated useBookmarkImport hook to parse files and check quota before import
- Added error banner in ImportExport component to display quota errors
- Optimized file parsing to avoid reading the file twice
The quota check displays remaining bookmarks and provides clear error
messages when the import would exceed the user's quota.
* fix
* some fixes
---------
Co-authored-by: Claude <noreply@anthropic.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add a new search qualifier `is:broken` that allows users to filter bookmarks
with broken or failed links. This matches the functionality on the broken links
settings page, where a link is considered broken if:
- crawlStatus is "failure"
- crawlStatusCode is less than 200
- crawlStatusCode is greater than 299
The qualifier supports negation with `-is:broken` to find working links.
Changes:
- Add brokenLinks matcher type definition
- Update search query parser to handle is:broken qualifier
- Implement query execution logic for broken links filtering
- Add autocomplete support with translations
- Add parser tests
- Update search query language documentation
Co-authored-by: Claude <noreply@anthropic.com>
|
| | |
|
| |
|
|
|
|
|
|
|
| |
* chore: add benchmarks
* upgrade deps
* fixes
* lint
|
| | |
|
| | |
|
| |
|
|
|
| |
* fix: Add restate queued idempotency
* return on failed to acquire
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* feat: Add automated bookmark backup system
Implements a comprehensive automated backup feature for user bookmarks with the following capabilities:
Database Schema:
- Add backupSettings table to store user backup preferences (enabled, frequency, retention)
- Add backups table to track backup records with status and metadata
- Add BACKUP asset type for storing compressed backup files
- Add migration 0066_add_backup_tables.sql
Background Workers:
- Implement BackupSchedulingWorker cron job (runs daily at midnight UTC)
- Create BackupWorker to process individual backup jobs
- Deterministic scheduling spreads backup jobs across 24 hours based on user ID hash
- Support for daily and weekly backup frequencies
- Automated retention cleanup to delete old backups based on user settings
Export & Compression:
- Reuse existing export functionality for bookmark data
- Compress exports using Node.js built-in zlib (gzip level 9)
- Store compressed backups as assets with proper metadata
- Track backup size and bookmark count for statistics
tRPC API:
- backups.getSettings - Retrieve user backup configuration
- backups.updateSettings - Update backup preferences
- backups.list - List all user backups with metadata
- backups.get - Get specific backup details
- backups.delete - Delete a backup
- backups.download - Download backup file (base64 encoded)
- backups.triggerBackup - Manually trigger backup creation
UI Components:
- BackupSettings component with configuration form
- Enable/disable automatic backups toggle
- Frequency selection (daily/weekly)
- Retention period configuration (1-365 days)
- Backup list table with download and delete actions
- Manual backup trigger button
- Display backup stats (size, bookmark count, status)
- Added backups page to settings navigation
Technical Details:
- Uses Restate queue system for distributed job processing
- Implements idempotency keys to prevent duplicate backups
- Background worker concurrency: 2 jobs at a time
- 10-minute timeout for large backup exports
- Proper error handling and logging throughout
- Type-safe implementation with Zod schemas
* refactor: simplify backup settings and asset handling
- Move backup settings from separate table to user table columns
- Update BackupSettings model to use static methods with users table
- Remove download mutation in favor of direct asset links
- Implement proper quota checks using QuotaService.checkStorageQuota
- Update UI to use new property names and direct asset downloads
- Update shared types to match new schema
Key changes:
- backupSettingsTable removed, settings now in users table
- Backup downloads use direct /api/assets/{id} links
- Quota properly validated before creating backup assets
- Cleaner separation of concerns in tRPC models
* migration
* use zip instead of gzip
* fix drizzle
* fix settings
* streaming json
* remove more dead code
* add e2e tests
* return backup
* poll for backups
* more fixes
* more fixes
* fix test
* fix UI
* fix delete asset
* fix ui
* redirect for backup download
* cleanups
* fix idempotency
* fix tests
* add ratelimit
* add error handling for background backups
* i18n
* model changes
---------
Co-authored-by: Claude <noreply@anthropic.com>
|
| | |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* feat: lazy load tiktoken to reduce memory footprint
The js-tiktoken module loads a large encoding dictionary into memory
immediately on import. This change defers the loading of the encoding
until it's actually needed by using a lazy getter pattern.
This reduces memory usage for processes that import this module but
don't actually use the token encoding functions.
* fix: use createRequire for lazy tiktoken import in ES module
The previous implementation used bare require() which fails at runtime
in ES modules (ReferenceError: require is not defined). This fixes it
by using createRequire from Node's 'module' package, which creates a
require function that works in ES module contexts.
* refactor: convert tiktoken lazy loading to async dynamic imports
Changed from createRequire to async import() for lazy loading tiktoken,
making buildTextPrompt and buildSummaryPrompt async. This is cleaner for
ES modules and properly defers the large tiktoken encoding data until
it's actually needed.
Updated all callers to await these async functions:
- packages/trpc/routers/bookmarks.ts
- apps/workers/workers/inference/tagging.ts
- apps/workers/workers/inference/summarize.ts
- apps/web/components/settings/AISettings.tsx (converted to useEffect)
* feat: add untruncated prompt builders for UI previews
Added buildTextPromptUntruncated and buildSummaryPromptUntruncated
functions that don't require token counting or truncation. These are
synchronous and don't load tiktoken, making them perfect for UI
previews where exact token limits aren't needed.
Updated AISettings.tsx to use these untruncated versions, eliminating
the need for useEffect/useState and avoiding unnecessary tiktoken
loading in the browser.
* fix
* fix
---------
Co-authored-by: Claude <noreply@anthropic.com>
|
| |
|
|
|
| |
* fix: Propagate group ids
* fix tests
|
| |
|
|
|
|
|
| |
* feat: Introduce groupId in restate queue
* add group ids to the interface
* use last served timestamp
|
| | |
|
| | |
|
| |
|
|
|
|
|
|
|
| |
Implements a new API endpoint that returns the server version from serverConfig.
This will be used for Home Assistant integration to check for updates.
Fixes #2148
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Mohamed Bassem <MohamedBassem@users.noreply.github.com>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* feat: Add note-taking functionality to highlights
This commit adds the ability to add and edit notes on highlights, allowing users to capture their thoughts alongside highlighted text.
Changes:
- Updated zUpdateHighlightSchema to include optional note field
- Modified Highlight.update() method to persist notes to database
- Added note button (MessageSquare icon) beside color picker in highlight menu
- Implemented note dialog with textarea for adding/editing notes
- Updated Highlight interface to include optional note field
- Modified ReaderView to pass notes through create and update operations
- Enhanced HighlightCard to display notes below highlighted text
The note button appears alongside the color picker for both new and existing highlights. Notes are displayed in a smaller, muted font below the highlighted text in the HighlightCard component.
* refactor: Convert highlight UI to inline form
Changed the highlight creation/editing interface from a modal dialog to an inline form for a more streamlined user experience.
Changes:
- Replaced ColorPickerMenu and Dialog with a unified HighlightForm component
- Form now displays color selector and note textarea together inline
- Added labels for "Color" and "Note" sections
- Textarea is now optional and inline (placeholder: "Add a note (optional)...")
- Consolidated Save and Cancel buttons in the form
- Delete button appears only for existing highlights
- Removed MessageSquare icon - notes are now always visible in the form
- Simplified state management by removing separate dialog state
The form appears in a popover when text is selected or an existing highlight is clicked, showing both color options and note input in a single 320px wide form.
* fixes
---------
Co-authored-by: Claude <noreply@anthropic.com>
|