Skip to content

Releases: outsharked/find-anything

v0.8.4

Choose a tag to compare

@github-actions github-actions released this 23 Jul 05:17
ee35da5

Fixed

  • Markdown/RTF content rendered with forced line breaks at storage line-wrap points — the server intentionally wraps long lines at a length cap for the plain/code viewer, but the markdown renderer treated every one of those wrap points as a literal <br>, turning long sentences into jagged short forced lines. Now renders with CommonMark's default soft-break behavior instead. (#80)
  • Opening a large file in the viewer could take minutes or appear to hang — the paged file endpoint (GET /api/v1/file) fetched each line of a page with its own content-store call instead of one query for the whole range. A 2000-line page issued 2000 separate round trips; fixed by batching into a single ranged fetch. Verified against a 100K-line file: the same request dropped from 10+ minutes to ~20ms. (#81)

Full Changelog: v0.8.3...v0.8.4

v0.8.3

Choose a tag to compare

@github-actions github-actions released this 22 Jul 17:11
990e058

Fixed

  • Links inside rendered markdown/RTF content did nothing on click — SvelteKit's client-side router intercepted same-origin <a> clicks and performed a "soft" navigation via pushState that never fired popstate or a load function, so clicking a link inside a markdown doc (e.g. the demo's "About" page) changed the URL but left the view frozen. (#76)

Internal

  • CI: pinned cargo-watch/cargo-llvm-cov to fixed versions and scoped the web job's mise install to skip them, fixing intermittent crates.io index-lookup timeouts. (#77)
  • CI: fixed the Windows release build, which was downloading an HTML landing page instead of the Inno Setup installer after an upstream change to jrsoftware.org's download flow. (#79)

Full Changelog: v0.8.2...v0.8.3

v0.8.2

Choose a tag to compare

@github-actions github-actions released this 10 Jul 17:01

What's Changed

  • perf: batch phase1 SQLite commits instead of one per file by @jamietre in #60
  • fix: root_dev unused-variable warning on non-Unix builds by @jamietre in #61
  • feat: Ctrl+G go-to-line dialog, fix #L hash edits not working by @jamietre in #62
  • perf: virtualized scrolling in the file viewer (plan 092) by @jamietre in #63
  • fix: throttle tree row refresh on live index events by @jamietre in #65
  • perf: coalesce inbox requests into shared SQLite transactions (plan 093) by @jamietre in #66
  • Release 0.8.0 by @jamietre in #68
  • fix: include find-extract-dicom and find-extract-pe in release binaries by @jamietre in #70
  • fix: rescan directory when .index/.noindex control files change by @jamietre in #67
  • Release 0.8.1 by @jamietre in #71
  • docs: no Co-Authored-By Claude trailer on commits in this repo by @jamietre in #74
  • fix: image viewer Fit to viewport ignored small images by @jamietre in #72
  • fix: include find-preview-dicom in release binaries by @jamietre in #73

Full Changelog: v0.7.7...v0.8.2

v0.8.1

Choose a tag to compare

@github-actions github-actions released this 10 Jul 11:37

What's Changed

  • perf: batch phase1 SQLite commits instead of one per file by @jamietre in #60
  • fix: root_dev unused-variable warning on non-Unix builds by @jamietre in #61
  • feat: Ctrl+G go-to-line dialog, fix #L hash edits not working by @jamietre in #62
  • perf: virtualized scrolling in the file viewer (plan 092) by @jamietre in #63
  • fix: throttle tree row refresh on live index events by @jamietre in #65
  • perf: coalesce inbox requests into shared SQLite transactions (plan 093) by @jamietre in #66
  • Release 0.8.0 by @jamietre in #68
  • fix: include find-extract-dicom and find-extract-pe in release binaries by @jamietre in #70

Full Changelog: v0.7.7...v0.8.1

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 09 Jul 18:03

What's Changed

  • perf: batch phase1 SQLite commits instead of one per file by @jamietre in #60
  • fix: root_dev unused-variable warning on non-Unix builds by @jamietre in #61
  • feat: Ctrl+G go-to-line dialog, fix #L hash edits not working by @jamietre in #62
  • perf: virtualized scrolling in the file viewer (plan 092) by @jamietre in #63
  • fix: throttle tree row refresh on live index events by @jamietre in #65
  • perf: coalesce inbox requests into shared SQLite transactions (plan 093) by @jamietre in #66

Full Changelog: v0.7.7...v0.8.0

v0.7.7

Choose a tag to compare

@jamietre jamietre released this 08 Jul 15:14
d33db81

Fixed

  • cross-based ARM/Windows builds: sccache wasn't actually being usedCross.toml's volumes key was under the top-level [build] section, but cross only reads volumes/passthrough from [build.env], so the sccache binary and cache dir mounts were silently dropped (cross even warned "found unused key(s)"). Even moved to the right place, cross doesn't support Docker's host:container remap — it always mounts a volume at the same absolute path inside the container as on the host — so RUSTC_WRAPPER=sccache (a bare name) could never resolve via a PATH lookup the container doesn't have. Fixed by resolving RUSTC_WRAPPER to sccache's absolute path via which sccache in .mise.toml's build-arm/build-win task env blocks (no hardcoded paths — portable across machines), and mounting/passing it through by that same env var name in Cross.toml.

Changed

  • Silenced 5 recurring state_referenced_locally build warningsMetaDrawer, FileViewer, SearchBox, and TopBar (×2) each intentionally seed local $state from a prop once (or track a prop's previous value) and were already documented as such in surrounding comments, but Svelte's compiler can't distinguish that from a forgotten sync and warns on every build regardless. Added // svelte-ignore state_referenced_locally at each site now that the intent is confirmed correct, rather than leaving the noise to reappear on every pnpm run check/dev server start.

  • File viewer: targeted redraws for paged scrolling, plus a pagination bug the fix surfacedCodeViewer's line list was unkeyed ({#each codeLines as line, i}), so FileViewer's "load earlier lines" (prepending a page while scrolling up) shifted every existing row's index and forced Svelte to repatch the text content of every already-rendered row instead of just inserting the new ones; keyed the block by line number to fix it. Separately, FileViewer's paged mode (files over fileViewPageSize, default 2000 lines) re-ran highlight.js over the entire accumulated buffer on every loadForward/loadBackward call, making a long scroll session O(n²) in total highlighting work and blocking the main thread on each page load. Replaced with appendCodeState/prependCodeState, which highlight only the newly-loaded page and concatenate the HTML — O(page size) per call. Added highlight.test.ts asserting highlightFile always emits one output line per input line (including across a multi-line token like a block comment), since the concatenation approach depends on that invariant to keep codeLines in sync with lineOffsets.

    • The line-number key change immediately surfaced a real, pre-existing bug: forwardOffset += data.lines.length assumed the server's response always covers exactly data.lines.length raw lines, but get_file_lines_paged (crates/server/src/db/mod.rs) silently skips any raw line whose stored chunk lookup misses — e.g. blank lines between Cargo.lock [[package]] entries never got their own content chunk — so a page can return fewer lines than the raw range it actually covered. The under-counted offset made the next page re-fetch part of an already-rendered range, producing duplicate line-number keys and a hard each_key_duplicate crash that blanked the whole viewer. Fixed by advancing the offset with nextForwardOffset() (new pagination.ts helper, alongside mergePage), which mirrors the server's own min(pageSize, totalLines - offset) clamp instead of trusting the response length. loadBackward was already unaffected — its offset math derives from the requested range, not the response length.
  • Rust dependency: rand 0.9 → 0.10 in find-content-store — only used in bench.rs (the load-testing tool behind find-test, exercised by its own tests). Rng::random()/random_range() moved out of the core Rng trait into a new RngExt trait that must be imported separately; added use rand::RngExt; and dropped the now-unused use rand::Rng;.

  • Rust dependency: zip 2 → 8 in find-client's dev-dependencies — used only to build synthetic ZIP fixtures in tests (tests/scan.rs, tests/iwork.rs); find-server/find-extract-archive already depend on zip = "8" for real archive extraction, so this just aligns the test-only pin with the runtime one. The ZipWriter/SimpleFileOptions API used by those tests was unchanged across the jump — no code changes needed.

  • Rust dependency: quick-xml 0.37 → 0.41 in find-extract-epub and find-extract-office — 0.41 splits &entity;/&#nn; references out of text nodes into a new Event::GeneralRef event instead of leaving them inlined in Event::Text, and removed BytesText::unescape() in favor of a two-step decode() (charset) + escape::unescape() (entities) call. Ported both the field-metadata parsers (OPF dc:* tags, DOCX docProps/core.xml) and the paragraph walkers (XHTML, DOCX body, PPTX body) to accumulate text across Text/GeneralRef fragments and resolve GeneralRef via a small resolve_ref() helper (numeric refs via resolve_char_ref(), named entities via escape::resolve_predefined_entity()). Added regression tests for entity-escaped title/author metadata and body text in both crates — the initial fix silently truncated any field containing an entity (e.g. Q&amp;A became just Q) since the code didn't yet know about GeneralRef.

  • Rust dependency: scraper 0.21 → 0.27 in find-extract-html — no code changes needed; the Html/Selector/ElementRef API used here is unchanged across the jump. Added a regression test asserting HTML entities (&amp;, &lt;, &#65;, etc.) still decode correctly in extracted text — handled internally by html5ever at parse time, so unlike the quick-xml bump there's no separate entity-event API to worry about.

  • Rust dependency: calamine 0.26 → 0.35 in find-extract-office — no code changes needed. The existing xlsx test fixture only covered inline-string cells (t="inlineStr"), which real spreadsheet tools rarely produce — most .xlsx text goes through the shared-strings table instead. Added a second fixture (make_realistic_xlsx()) covering shared strings, plain numeric/float cells, and a cell styled with a built-in date number format (numFmtId="14"), and pinned the pre-existing behavior that date-styled cells currently come through as raw XLSX serial numbers (e.g. 45292) rather than formatted dates, since calamine's dates feature isn't enabled — unrelated to this bump, but worth knowing if that's ever revisited.

  • Rust dependency: nom-exif 2.8 → 3.6 in find-extract-media — before bumping, discovered that every existing video test only covered the magic-byte fallback path (AVI/FLV/MPEG/OGG/WMV); none exercised extract_video_nom_exif, the code that actually calls into nom-exif for MP4/MOV/MKV/WebM. Added a real MP4 fixture (testdata/tiny.mp4, generated with ffmpeg) and a test asserting resolution/duration extraction, verified against 2.8 first as a baseline. The 3.x API changes: MediaSource::file_path()MediaSource::open(); MediaParser::parse()MediaParser::parse_track() for video/audio track info; TrackInfoTag::ImageWidth/ImageHeightWidth/Height; and MediaSource::has_track() was removed since parse_track() now returns Error::TrackNotFound directly for track-less sources (handled by the existing error fallback, no behavior change).

  • Rust dependency: kamadak-exif 0.5 → 0.6 in find-extract-media — no code changes needed. Same blind spot found again before bumping: extract_image() tries kamadak-exif first and only falls back to a hand-rolled JPEG/PNG header parser if that fails, but every existing image test used a synthetic fixture (make_jpeg_sof0()) with no real EXIF segment — so all of them were silently exercising the fallback parser, never kamadak-exif itself. Generated a real JPEG with actual EXIF tags (Make/Model/Orientation/DateTime) via Pillow (testdata/exif_sample.jpg) and added a test, verified against 0.5 as a baseline before bumping.

  • Rust dependency: gray_matter 0.2 → 0.3 in find-extract-text — unlike the last three bumps, existing frontmatter tests already exercised the real parser (including nested objects), so no new fixtures were needed. Matter::parse() became fallible (Result<ParsedEntity, Error> instead of a best-effort ParsedEntity); extract_markdown_with_frontmatter now falls back to indexing the whole file as plain content with no metadata line on a parse error, matching the old best-effort behavior for malformed frontmatter.

  • Svelte runes migration (incremental, 6/6 — final)FileViewer, +page.svelte, +layout.svelte, settings/+page.svelte, v/[code]/+page.svelte converted from legacy syntax to runes, completing the migration started after the Svelte 5/Vite 8/TypeScript 6 toolchain bump. Highlights:

    • FileViewer (1514 lines, the largest/highest-risk file): all ~30 $: reactive statements split into $derived/$derived.by (pure) or $effect (side-effecting, e.g. the RTF-fetch-on-demand and live-update-banner blocks); dispatch('open'|'navigate'|'navigateDir'|'lineselect', ...) became onOpen/onNavigate/onNavigateDir/onLineSelect callback props, with FileView.svelte's <FileViewer> usage updated to match. afterUpdate (not available in runes mode) was replaced with an $effect that reads the reactive values driving visible content changes (codeLines, wordWrap, showFormatted, etc.) as a stand-in for "rerun after every update," backed by the existing ResizeObserver for layout-only changes. selection was a locally-mutated one-way prop (Svelte 4 controlled-prop pattern); like earlier groups, this became compute-and-callback only, relying on the round-trip through FileView/+page.svelte to reflect the new value back down.
    • +page.svelte: found and fixed a real bug surfaced by the fileView/selectedSources state con...
Read more

v0.7.6

Choose a tag to compare

@github-actions github-actions released this 27 Apr 16:07

What's Changed

Full Changelog: v0.7.3...v0.7.6

v0.7.5

Choose a tag to compare

@github-actions github-actions released this 24 Apr 14:25

What's Changed

Full Changelog: v0.7.3...v0.7.5

v0.7.4

Choose a tag to compare

@github-actions github-actions released this 23 Apr 21:00

What's Changed

  • fix: spurious mass reindex on Windows + memory/logging improvements by @jamietre in #25
  • feat: no_wrap_extensions — exempt file types from word-wrap by @jamietre in #26

Full Changelog: v0.7.3...v0.7.4

v0.7.3

Choose a tag to compare

@jamietre jamietre released this 14 Apr 17:21
e89d8c5

Added

  • Inbox circuit breaker — the inbox worker now tracks consecutive request processing timeouts; after inbox_timeout_circuit_breaker (default 5) consecutive timeouts it automatically pauses the inbox and optionally sends an alert email via SMTP ([alerts] config block with smtp_host, smtp_port, smtp_encryption, smtp_username, smtp_password, smtp_from, admin_email). The counter resets on any successful request or manual /api/v1/admin/inbox/resume.
  • SMTP alert emails — new [alerts] config section supports sending a notification email when the inbox circuit breaker trips; uses lettre with STARTTLS (default), TLS, or plaintext; no fallback to sendmail.
  • cross_filesystems config option[scan] cross_filesystems = false (default) prevents the walker from descending into directories on a different device than the walk root, avoiding accidental traversal of mounted backup volumes, borg archives, network shares, and bind mounts. Set to true to restore the previous behaviour of crossing filesystem boundaries.
  • No-auth server support — the web UI now attempts to connect without a token first; initialLoad() shows the token dialog only on an AuthError, so servers with no authentication configured load immediately without prompting.
  • Windows service starts immediately after installinstall_service now calls service.start() after creating the service so no reboot or manual sc start is needed; output message updated accordingly
  • Windows installer task checkboxes — "Start file watcher service" and "Run full scan now" are now proper Inno Setup [Tasks] checkboxes rather than a fixed [Run] entry, so they run in the same elevated context as the rest of the install
  • Configurable formatter timeoutsbatch_formatter_timeout_secs (default 60) and per_file_formatter_timeout_secs (default 10) added to [normalization] in server.toml; previously hardcoded constants with #[cfg(test)] overrides

Fixed

  • Inbox worker SQLite deadlockstore.get_lines() (a read from blobs.db) was called inside an open write transaction on the source DB, unnecessarily widening the write lock window; moved before the transaction opens so the two databases are never locked simultaneously
  • Timed-out inbox tasks held SQLite write locks indefinitely — a timed-out spawn_blocking Phase 1 task continued holding its connection and any write lock until it finished; fixed by passing a rusqlite::InterruptHandle via oneshot channel so interrupt() is called on timeout, causing SQLITE_INTERRUPT and immediate unblock
  • Default inbox request timeout reduced from 1800 s to 120 s — Phase 1 is pure SQLite writes; 1800 s allowed a single stuck request to block the inbox for 30 minutes before the circuit breaker could trip
  • Document mode shows all matching linesdoc: search now returns one result per matching line for each qualifying file, rather than a single representative; lines capped at 20 per file with a + badge indicating truncation
  • Server crash (OOM) on large archive batches — Phase 1 now streams the normalised BulkRequest directly into the GzEncoder instead of buffering a full Vec<u8>, halving peak memory for large 7z batches
  • Batch formatter could hang indefinitelyapply_batch_formatter now has a 60-second timeout; a hung prettier/biome run no longer blocks the inbox worker forever
  • Search result line numbers off-by-one near chunk boundaries — empty lines at chunk boundaries no longer shift subsequent line numbers by -1
  • Potential write-lock contention on startup — idempotent index creation moved from open() to check_all_sources() so it runs once at startup under no concurrency
  • Context lines carried server-internal line numbers — each ContextLine now carries its own line_number; sparse files (e.g. PDFs) no longer show wrong line positions
  • Directory renames not watched after renamefind-watch now calls register_dir for the new directory path so subsequent changes inside it are detected
  • No loading cursor while expanding tree directories — the row, arrow, and name now show cursor: wait during an in-flight expand request

What's Changed

  • fix: prevent nlp-bar pills from being squished when results overflow by @jamietre in #5
  • fix: loading spinner and error state for inline image viewer by @jamietre in #6
  • feat: native iWork extraction, image viewer UX, structured IWA parsing by @jamietre in #8
  • Release 0.7.2 by @jamietre in #10
  • fix: dim stale results while typing in Ctrl+P palette by @jamietre in #11
  • feat: make batch formatter timeouts configurable by @jamietre in #12
  • fix: context lines carry their own line_number, fix chunk boundary bug by @jamietre in #13
  • fix: move idempotent index creation from open() to check_all_sources() by @jamietre in #14
  • fix: register inotify watch on new directory after rename by @jamietre in #15
  • feat: start Windows service immediately after install by @jamietre in #16
  • chore: move DICOM plan to completed, update code-quality command by @jamietre in #18
  • fix: show wait cursor while tree directory is expanding by @jamietre in #17
  • feat: cross_filesystems option + doc mode all-lines search by @jamietre in #20
  • feat: inbox circuit breaker, SMTP alerts, and SQLite deadlock fixes by @jamietre in #21
  • fix: run integration tests sequentially to prevent CI timeout by @jamietre in #22
  • fix: skip token check on startup, show dialog only on auth error by @jamietre in #23
  • Release 0.7.3 by @jamietre in #24

New Contributors

Full Changelog: v0.7.1...v0.7.3