Skip to content

docurip v0.6.1

Latest

Choose a tag to compare

@MokuDev MokuDev released this 09 Jul 03:44

v0.6.1 (2026-07-09)

Added

  • Include patterns & path prefix filter: new includePatterns (regex list) and pathPrefix fields on CrawlConfig allow whitelisting URLs during a crawl. When any include constraint is set, only URLs matching at least one include pattern or the path prefix are enqueued. Exclude patterns still override includes. UI fields added to New Crawl view; backend validation rejects malformed regex before the crawl starts.
  • Keyboard shortcuts: Ctrl/Cmd+N opens New Crawl (or Active Crawl when running), Ctrl/Cmd+F focuses the search input, Escape closes the topmost modal or Live Console. Shortcuts suppress inside text inputs (except Escape). New useKeyboardShortcuts hook and EscapeStack context for coordinating Escape across nested modals.
  • Desktop notifications: system notifications fire when a crawl completes or fails. Gated by a new notificationsEnabled setting (default on) with a toggle in Settings → Notifications. Uses tauri-plugin-notification with permission request on first use.

Fixed

  • ResultTree focusedIndex out of range: keyboard-focused index could exceed the visible node count after filtering or collapsing a folder, causing undefined access. Now clamped via useEffect whenever visibleNodes shrinks.
  • Duplicate desktop notifications: if the backend emitted multiple terminal events for the same job (e.g. race between completed/failed), the notification fired more than once. A ref-backed Set<string> now deduplicates per jobId.
  • Notification plugin errors unhandled: sendNotification was not wrapped in try/catch — if the plugin threw after permission was granted, the rejection propagated as unhandled. Now caught and logged.
  • Whitespace-only pattern lines sent to backend: include/exclude/selector textareas split on newlines but only filtered with .filter(Boolean), so a line of spaces passed through as a non-empty (invalid) regex. Lines are now .trim()'d before filtering.
  • Keyboard shortcuts case-sensitive: Ctrl+N/Ctrl+F matched e.key === 'n'/'f' literally, so they failed with CapsLock on. Now normalized via .toLowerCase().
  • ResultTree rowProps invalidating memoization: rowProps={{}} created a fresh object every render, defeating react-window's row memoization. Hoisted to a module-level constant.
  • headlessStrategy cast to any: select onChange used as any to bypass TypeScript, hiding potential type mismatches. Now uses the proper CrawlConfig['headlessStrategy'] union type.
  • pathPrefix submitted with query/fragment: user-entered path prefixes containing ? or # would never match (the backend compares against url.path() only). Now normalized on both frontend submit and backend start_crawl: trim whitespace, strip query/fragment, enforce leading /.
  • listRef typed as any with wrong API calls: ResultTree used useRef<any> and react-window v1's scrollToItem method. Replaced with react-window v2's useListRef hook (properly typed ListImperativeAPI) and scrollToRow API. Fixes the only TypeScript error in the codebase.