Skip to content

feat(web): Add persistence to unified instance filter in sidebar - #1560

Merged
s0up4200 merged 6 commits into
autobrr:developfrom
drtaru:feat/remember_unified_instance_filter
Mar 8, 2026
Merged

feat(web): Add persistence to unified instance filter in sidebar#1560
s0up4200 merged 6 commits into
autobrr:developfrom
drtaru:feat/remember_unified_instance_filter

Conversation

@drtaru

@drtaru drtaru commented Mar 7, 2026

Copy link
Copy Markdown
Contributor

Persist unified instance scope filter across navigation

Saves the selected unified instance scope to localStorage (qui-unified-instance-filter) so it is restored when navigating back to the unified view after switching elsewhere in the sidebar.

Clicking "All active" clears the saved filter and resets to all instances.

Sidebar badge: Changed from two separate badges [3 active] [2/3] to a single combined [2/3 active] badge. The badge remains visible even when a single instance is selected, so the filter state is always visible without needing to be on the unified view.

Input needed:

It might make sense to remove the word "active" to prevent confusion, however the individual instance statuses are displayed just below with a connectivity dot so that may not matter.
Happy to include that modification in this PR if it makes sense.

Summary by CodeRabbit

  • New Features

    • Unified instance selections are now persisted in browser storage and automatically restored across Header, Sidebar, Mobile navigation and Torrents views.
  • Bug Fixes / UX

    • UI elements (checkboxes, counts, links, dropdowns) consistently reflect the persisted scope with sensible fallbacks; applying a scope saves it for future sessions and no longer encodes scope into the URL.
  • Chores

    • Removed legacy URL search param and updated related search payload shapes to rely on the persisted filter.

@coderabbitai

coderabbitai Bot commented Mar 7, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Replaces route-encoded unified instance scope with a persisted localStorage-backed hook. Adds usePersistedUnifiedInstanceFilter, integrates it into Header, Sidebar, MobileFooterNav, Torrents and routes, removes URL instanceIds handling and the exported resolveUnifiedInstanceIds/search param constant, and updates UI and navigation to use the persisted normalized IDs.

Changes

Cohort / File(s) Summary
Persistence Hook
web/src/hooks/usePersistedUnifiedInstanceFilter.ts
New hook using useSyncExternalStore + localStorage key "qui-unified-instance-filter", parse/encode helpers, change-event dispatch, safe read/write and saveFilter callback.
Layout: Header
web/src/components/layout/Header.tsx
Wires in persisted filter, computes effective unified IDs from persisted state (fallback to activeInstanceIds), persists on apply, removes route-encoded param usage and encoding/decoding logic, updates deps.
Layout: Mobile Footer Nav
web/src/components/layout/MobileFooterNav.tsx
Reads persisted filter for effective IDs, saves normalized IDs on apply, stops encoding unified IDs into route search, updates checkbox/label UI logic.
Layout: Sidebar
web/src/components/layout/Sidebar.tsx
Uses persisted filter (fallback to active IDs) for displayed unified IDs, saves on apply, removes URL-encoded unified-id logic and some inline badge rendering, updates dropdown checkbox states and active-count text.
Pages: Torrents
web/src/pages/Torrents.tsx
Removes instanceIds from TorrentsProps search/onSearchChange, consumes persisted unified filter for unified scope, adjusts deep-link fetch to use activeInstanceIds when cross-instance, simplifies some title-speed logic.
Routes: Instances pages
web/src/routes/_authenticated/instances.$instanceId.tsx, web/src/routes/_authenticated/instances.index.tsx
Removed instanceIds from search schemas and handler types; no other control-flow changes.
Lib: instances
web/src/lib/instances.ts
Removed exported UNIFIED_INSTANCE_IDS_SEARCH_PARAM constant and resolveUnifiedInstanceIds function; retained parse/normalize/encode helpers.

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant UI as Header/Sidebar/MobileFooterNav
    participant Hook as usePersistedUnifiedInstanceFilter
    participant Storage as localStorage
    Note over UI,Hook: User selects or applies a unified scope
    User->>UI: select scope / apply
    UI->>Hook: saveFilter(normalizedIds)
    Hook->>Storage: write key "qui-unified-instance-filter"
    Hook->>Hook: dispatch "qui-unified-instance-filter-changed"
    Hook->>UI: useSyncExternalStore notifies subscribers (snapshot)
    UI->>UI: recompute displayedUnifiedInstanceIds and update UI
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

enhancement, web, area/frontend, mobile

Poem

🐰 I hopped through keys and stored each chosen id,
In burrows of JSON where tiny bytes hid.
I tuck your scope safe, then give it back at dawn,
A nibble, a hop — your filters carry on. 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main change: adding persistence to the unified instance filter. This matches the primary objective and the core modifications across Header, MobileFooterNav, Sidebar, and the new usePersistedUnifiedInstanceFilter hook.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@web/src/components/layout/Sidebar.tsx`:
- Around line 152-156: Introduce a displayedUnifiedInstanceIds derived value
that returns the persistedUnifiedFilter-derived normalized IDs
(persistedNormalizedIds) when no URL scope exists, otherwise returns
effectiveUnifiedInstanceIds, and replace uses of effectiveUnifiedInstanceIds in
checkbox checked state and in toggleUnifiedScopeInstance baseline logic so the
scope menu and badge share the same source of truth; update Sidebar.tsx (and
mirror the same change in Header.tsx and MobileFooterNav.tsx) so the badge
counting, the checkbox state, and the toggleUnifiedScopeInstance function all
use displayedUnifiedInstanceIds instead of effectiveUnifiedInstanceIds.

In `@web/src/hooks/usePersistedUnifiedInstanceFilter.ts`:
- Around line 15-36: The hook usePersistedUnifiedInstanceFilter currently uses
per-component useState (persistedIds) so updates in one component don't
propagate to others; replace the local state with a shared subscription using
useSyncExternalStore: implement a getSnapshot that reads STORAGE_KEY and returns
parseUnifiedInstanceIds(localStorage.getItem(STORAGE_KEY)) (or []), implement a
subscribe function that listens to the window "storage" event and a custom
same-tab event (e.g. "unified-instance-filter-changed") and returns an
unsubscribe, then change saveFilter to write encodeUnifiedInstanceIds to
localStorage (or removeItem), and dispatch the same-tab custom event so
subscribers (via useSyncExternalStore) see immediate updates; keep
parseUnifiedInstanceIds, encodeUnifiedInstanceIds, STORAGE_KEY,
usePersistedUnifiedInstanceFilter, and saveFilter names to locate the code.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: f0946ade-73f1-42b2-a5a1-71a94200a40e

📥 Commits

Reviewing files that changed from the base of the PR and between 8713667 and 041e7c1.

📒 Files selected for processing (4)
  • web/src/components/layout/Header.tsx
  • web/src/components/layout/MobileFooterNav.tsx
  • web/src/components/layout/Sidebar.tsx
  • web/src/hooks/usePersistedUnifiedInstanceFilter.ts

Comment thread web/src/components/layout/Sidebar.tsx Outdated
Comment thread web/src/hooks/usePersistedUnifiedInstanceFilter.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
web/src/components/layout/Header.tsx (1)

111-120: Consider extracting shared persistence logic into the hook.

All three layout components (Header, Sidebar, MobileFooterNav) duplicate the same derived state pattern:

const persistedNormalizedIds = useMemo(
  () => normalizeUnifiedInstanceIds(persistedUnifiedFilter, activeInstanceIds),
  [persistedUnifiedFilter, activeInstanceIds]
)
const displayedUnifiedInstanceIds = hasCustomUnifiedScope
  ? effectiveUnifiedInstanceIds
  : persistedNormalizedIds.length > 0
    ? persistedNormalizedIds
    : effectiveUnifiedInstanceIds

This could be encapsulated in the hook by passing activeInstanceIds and the URL-derived scope, returning both persistedIds and displayedIds. However, this is a nice-to-have for future cleanup.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/components/layout/Header.tsx` around lines 111 - 120, The layout
components (Header, Sidebar, MobileFooterNav) duplicate logic that computes
persistedNormalizedIds and displayedUnifiedInstanceIds; move this derived-state
into the usePersistedUnifiedInstanceFilter hook by accepting activeInstanceIds
and the URL-derived scope (hasCustomUnifiedScope/effectiveUnifiedInstanceIds)
and returning both persistedIds (result of normalizeUnifiedInstanceIds) and
displayedIds (the conditional choosing between persistedIds and
effectiveUnifiedInstanceIds). Update callers to replace local
persistedNormalizedIds and displayedUnifiedInstanceIds with the hook's returned
values to eliminate duplication and centralize normalization logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@web/src/hooks/usePersistedUnifiedInstanceFilter.ts`:
- Around line 43-55: The event dispatch is outside the try/catch so CHANGE_EVENT
is fired even when localStorage write/remove fails; move
window.dispatchEvent(new Event(CHANGE_EVENT)) inside the try block in the
saveFilter callback (the function named saveFilter in
usePersistedUnifiedInstanceFilter.ts) so the change event is only emitted after
successful encodeUnifiedInstanceIds and localStorage.setItem/removeItem, and
keep the catch to log the error without dispatching the event.

---

Nitpick comments:
In `@web/src/components/layout/Header.tsx`:
- Around line 111-120: The layout components (Header, Sidebar, MobileFooterNav)
duplicate logic that computes persistedNormalizedIds and
displayedUnifiedInstanceIds; move this derived-state into the
usePersistedUnifiedInstanceFilter hook by accepting activeInstanceIds and the
URL-derived scope (hasCustomUnifiedScope/effectiveUnifiedInstanceIds) and
returning both persistedIds (result of normalizeUnifiedInstanceIds) and
displayedIds (the conditional choosing between persistedIds and
effectiveUnifiedInstanceIds). Update callers to replace local
persistedNormalizedIds and displayedUnifiedInstanceIds with the hook's returned
values to eliminate duplication and centralize normalization logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 14b47286-896d-4f23-9a6a-e4de865f0a73

📥 Commits

Reviewing files that changed from the base of the PR and between 041e7c1 and 044e612.

📒 Files selected for processing (4)
  • web/src/components/layout/Header.tsx
  • web/src/components/layout/MobileFooterNav.tsx
  • web/src/components/layout/Sidebar.tsx
  • web/src/hooks/usePersistedUnifiedInstanceFilter.ts

Comment thread web/src/hooks/usePersistedUnifiedInstanceFilter.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
web/src/components/layout/Sidebar.tsx (1)

135-165: Consider extracting the unified-scope state into a shared hook.

This normalize/fallback/apply/toggle flow now lives here, in web/src/components/layout/MobileFooterNav.tsx, and in Header.tsx. Pulling it into one hook/helper would make future scope/badge changes land once and reduce drift between the three menus.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/components/layout/Sidebar.tsx` around lines 135 - 165, Extract the
unified-scope logic duplicated across Sidebar.tsx, MobileFooterNav.tsx, and
Header.tsx into a shared hook (e.g., useUnifiedScope) that encapsulates state
and helpers: usePersistedUnifiedInstanceFilter usage,
normalizeUnifiedInstanceIds fallback logic, effectiveUnifiedInstanceIds
calculation, hasCustomUnifiedScope, unifiedScopeSummary, applyUnifiedScope
(navigate+saveUnifiedFilter behavior) and toggleUnifiedScopeInstance; replace
the in-component implementations in Sidebar (functions/variables:
usePersistedUnifiedInstanceFilter, normalizeUnifiedInstanceIds,
effectiveUnifiedInstanceIds, applyUnifiedScope, toggleUnifiedScopeInstance) with
calls to the new hook so all three components consume the same centralized logic
and reduce duplication.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@web/src/pages/Torrents.tsx`:
- Around line 125-152: The deep-link lookup in fetchTorrentByHash is incorrectly
limited to unifiedScopeInstanceIds, causing /instances?torrent=... to fail when
the owning instance isn't in saved scope; change the logic so that when
resolving a hash (in fetchTorrentByHash / isAllInstances branch using
api.getCrossInstanceTorrents) you query across all active instances (e.g., use
activeInstanceIds or omit instanceIds to search globally) or perform a fallback
unscoped cross-instance lookup if the first scoped call returns null, and only
then clear search params; ensure to reference api.getCrossInstanceTorrents,
unifiedScopeInstanceIds, isAllInstances and the fallback to
api.getTorrents(instanceId, ...) so the code will resolve deep links regardless
of the saved unified scope.

---

Nitpick comments:
In `@web/src/components/layout/Sidebar.tsx`:
- Around line 135-165: Extract the unified-scope logic duplicated across
Sidebar.tsx, MobileFooterNav.tsx, and Header.tsx into a shared hook (e.g.,
useUnifiedScope) that encapsulates state and helpers:
usePersistedUnifiedInstanceFilter usage, normalizeUnifiedInstanceIds fallback
logic, effectiveUnifiedInstanceIds calculation, hasCustomUnifiedScope,
unifiedScopeSummary, applyUnifiedScope (navigate+saveUnifiedFilter behavior) and
toggleUnifiedScopeInstance; replace the in-component implementations in Sidebar
(functions/variables: usePersistedUnifiedInstanceFilter,
normalizeUnifiedInstanceIds, effectiveUnifiedInstanceIds, applyUnifiedScope,
toggleUnifiedScopeInstance) with calls to the new hook so all three components
consume the same centralized logic and reduce duplication.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 09da2d23-6369-4c09-91da-48138c871ff7

📥 Commits

Reviewing files that changed from the base of the PR and between 3f1ff03 and 85c2d28.

📒 Files selected for processing (7)
  • web/src/components/layout/Header.tsx
  • web/src/components/layout/MobileFooterNav.tsx
  • web/src/components/layout/Sidebar.tsx
  • web/src/lib/instances.ts
  • web/src/pages/Torrents.tsx
  • web/src/routes/_authenticated/instances.$instanceId.tsx
  • web/src/routes/_authenticated/instances.index.tsx
💤 Files with no reviewable changes (3)
  • web/src/routes/_authenticated/instances.$instanceId.tsx
  • web/src/lib/instances.ts
  • web/src/routes/_authenticated/instances.index.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • web/src/components/layout/Header.tsx

Comment thread web/src/pages/Torrents.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web/src/pages/Torrents.tsx (1)

53-60: ⚠️ Potential issue | 🟠 Major

Reset unified-view state when the persisted scope changes.

unifiedScopeInstanceIds can now change without a route change, but this component still treats instanceId as the only page identity. In /instances, switching the saved scope can keep the details panel open for a torrent whose instance is no longer in scope, and the sidebar counts stay marked as fresh until new data lands. Please treat the normalized unified scope as part of this page's identity as well, preferably with a key or render-time exclusion instead of an Effect.

As per coding guidelines, "To reset state in React, prefer a key or render-time adjustments instead of Effects".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/src/pages/Torrents.tsx` around lines 53 - 60, The page must treat the
normalized unified scope as part of its identity so state resets when
persistedUnifiedFilter changes: compute unifiedScopeInstanceIds (using
normalizeUnifiedInstanceIds with persistedUnifiedFilter and activeInstanceIds)
as you already do, then include that value in the component tree key (e.g., the
root/wrapper component rendered by Torrents.tsx) so React remounts when
unifiedScopeInstanceIds changes; use a stable serialization (JSON.stringify or
join) of unifiedScopeInstanceIds combined with instanceId/isAllInstances to form
the key and remove any Effect-based state reset logic that attempted to watch
persistedUnifiedFilter.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@web/src/pages/Torrents.tsx`:
- Around line 125-140: The deep-link fetch (fetchTorrentByHash / the
cross-instance branch in the useEffect that reads search.torrent) must be gated
until useInstances has finished loading: check the isLoading flag (from
useInstances) and do not execute the cross-instance API call when isLoading is
true (or when activeInstanceIds is empty while loading); this prevents sending
instanceIds: undefined and consuming the deep link prematurely—either skip the
fetch while isLoading and let the effect re-run when instances resolve, or
retain search.torrent and explicitly retry when activeInstanceIds changes after
isLoading becomes false.

---

Outside diff comments:
In `@web/src/pages/Torrents.tsx`:
- Around line 53-60: The page must treat the normalized unified scope as part of
its identity so state resets when persistedUnifiedFilter changes: compute
unifiedScopeInstanceIds (using normalizeUnifiedInstanceIds with
persistedUnifiedFilter and activeInstanceIds) as you already do, then include
that value in the component tree key (e.g., the root/wrapper component rendered
by Torrents.tsx) so React remounts when unifiedScopeInstanceIds changes; use a
stable serialization (JSON.stringify or join) of unifiedScopeInstanceIds
combined with instanceId/isAllInstances to form the key and remove any
Effect-based state reset logic that attempted to watch persistedUnifiedFilter.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 7a762306-140c-4f19-a61a-6c5c46609973

📥 Commits

Reviewing files that changed from the base of the PR and between 85c2d28 and 4d4dbfe.

📒 Files selected for processing (1)
  • web/src/pages/Torrents.tsx

Comment thread web/src/pages/Torrents.tsx
@s0up4200
s0up4200 merged commit 8eb8903 into autobrr:develop Mar 8, 2026
15 checks passed
@drtaru
drtaru deleted the feat/remember_unified_instance_filter branch March 8, 2026 16:24
alexlebens pushed a commit to alexlebens/infrastructure that referenced this pull request Mar 20, 2026
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [ghcr.io/autobrr/qui](https://github.com/autobrr/qui) | minor | `v1.14.1` → `v1.15.0` |

---

> ⚠️ **Warning**
>
> Some dependencies could not be looked up. Check the [Dependency Dashboard](issues/2) for more information.

---

### Release Notes

<details>
<summary>autobrr/qui (ghcr.io/autobrr/qui)</summary>

### [`v1.15.0`](https://github.com/autobrr/qui/releases/tag/v1.15.0)

[Compare Source](autobrr/qui@v1.14.1...v1.15.0)

#### Changelog

##### Breaking change

CORS is disabled by default; enable by setting QUI\_\_CORS\_ALLOWED\_ORIGINS with explicit origins (http(s)://host\[:port]). See <https://getqui.com/docs/advanced/sso-proxy-cors>

##### New Features

- [`93786a2`](autobrr/qui@93786a2): feat(automations): add configurable processing priority/sorting ([#&#8203;1235](autobrr/qui#1235)) ([@&#8203;Oscariremma](https://github.com/Oscariremma))
- [`45eaf1f`](autobrr/qui@45eaf1f): feat(database): add postgres and sqlite migration CLI ([#&#8203;1530](autobrr/qui#1530)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`430f5d1`](autobrr/qui@430f5d1): feat(torrents): mediaInfo dialog ([#&#8203;1537](autobrr/qui#1537)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`8eb8903`](autobrr/qui@8eb8903): feat(web): Add persistence to unified instance filter in sidebar ([#&#8203;1560](autobrr/qui#1560)) ([@&#8203;drtaru](https://github.com/drtaru))
- [`7aadde7`](autobrr/qui@7aadde7): feat(web): add path autocomplete to set location dialog ([#&#8203;1432](autobrr/qui#1432)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`077f32c`](autobrr/qui@077f32c): feat: add mediainfo api endpoint ([#&#8203;1545](autobrr/qui#1545)) ([@&#8203;Audionut](https://github.com/Audionut))
- [`99cf695`](autobrr/qui@99cf695): feat: endpoint to trigger directory scans from external tools ([#&#8203;1559](autobrr/qui#1559)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`8956f9b`](autobrr/qui@8956f9b): feat: unify bulk tag editor ([#&#8203;1571](autobrr/qui#1571)) ([@&#8203;s0up4200](https://github.com/s0up4200))

##### Bug Fixes

- [`552d617`](autobrr/qui@552d617): fix(api): align add torrent OpenAPI field ([#&#8203;1617](autobrr/qui#1617)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`424f7a0`](autobrr/qui@424f7a0): fix(api): restrict CORS to explicit allowlist ([#&#8203;1551](autobrr/qui#1551)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`38991d8`](autobrr/qui@38991d8): fix(auth): allow loopback health probes ([#&#8203;1621](autobrr/qui#1621)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`4ae88c9`](autobrr/qui@4ae88c9): fix(automations): align include-cross-seeds category apply ([#&#8203;1517](autobrr/qui#1517)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`6a127a8`](autobrr/qui@6a127a8): fix(automations): scope skipWithin to only deleted action ([#&#8203;1538](autobrr/qui#1538)) ([@&#8203;jabloink](https://github.com/jabloink))
- [`c776189`](autobrr/qui@c776189): fix(crossseed): avoid completion timeout misses on non-Gazelle torrents ([#&#8203;1536](autobrr/qui#1536)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`b1338a7`](autobrr/qui@b1338a7): fix(crossseed): handle missing webhook collection tags ([#&#8203;1610](autobrr/qui#1610)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`eacbb68`](autobrr/qui@eacbb68): fix(crossseed): normalize hdr aliases ([#&#8203;1572](autobrr/qui#1572)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`537ad46`](autobrr/qui@537ad46): fix(crossseed): queue completion searches and retry rate-limit waits ([#&#8203;1523](autobrr/qui#1523)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`4fc550f`](autobrr/qui@4fc550f): fix(crossseed): use autobrr indexer ids for webhooks ([#&#8203;1614](autobrr/qui#1614)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`08029ad`](autobrr/qui@08029ad): fix(crossseed): valid partial matches being rejected ([#&#8203;1291](autobrr/qui#1291)) ([@&#8203;rybertm](https://github.com/rybertm))
- [`77eedd9`](autobrr/qui@77eedd9): fix(database): avoid postgres temp-table statement caching ([#&#8203;1581](autobrr/qui#1581)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`25daa17`](autobrr/qui@25daa17): fix(dirscan): honor canceled queued webhook runs ([#&#8203;1612](autobrr/qui#1612)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`56995f1`](autobrr/qui@56995f1): fix(dirscan): queue webhook scans and tighten age filtering ([#&#8203;1603](autobrr/qui#1603)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`444d07b`](autobrr/qui@444d07b): fix(dirscan): select concrete hardlink base dir ([#&#8203;1606](autobrr/qui#1606)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`c35bea0`](autobrr/qui@c35bea0): fix(instances): improve settings dialog scrolling ([#&#8203;1569](autobrr/qui#1569)) ([@&#8203;nuxencs](https://github.com/nuxencs))
- [`dc501a0`](autobrr/qui@dc501a0): fix(proxy): reauth qbit passthrough requests ([#&#8203;1582](autobrr/qui#1582)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`7950d1d`](autobrr/qui@7950d1d): fix(proxy): search endpoint handling ([#&#8203;1524](autobrr/qui#1524)) ([@&#8203;Audionut](https://github.com/Audionut))
- [`1076eea`](autobrr/qui@1076eea): fix(qbit): prune empty managed dirs after delete\_with\_files ([#&#8203;1604](autobrr/qui#1604)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`5a3114b`](autobrr/qui@5a3114b): fix(qbittorrent): stop reboot torrent\_completed spam ([#&#8203;1515](autobrr/qui#1515)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`1d02e6c`](autobrr/qui@1d02e6c): fix(settings): contain settings tab scrolling ([#&#8203;1567](autobrr/qui#1567)) ([@&#8203;nuxencs](https://github.com/nuxencs))
- [`f5d69f3`](autobrr/qui@f5d69f3): fix(settings): smoother gradient ([#&#8203;1570](autobrr/qui#1570)) ([@&#8203;nuxencs](https://github.com/nuxencs))
- [`1c0c3bc`](autobrr/qui@1c0c3bc): fix(torrents): copy MediaInfo summary without brackets ([#&#8203;1540](autobrr/qui#1540)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`3ec913a`](autobrr/qui@3ec913a): fix(web): auto-append slash on path autocomplete selection ([#&#8203;1431](autobrr/qui#1431)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`aa2f3da`](autobrr/qui@aa2f3da): fix(web): check field.state.value type in AddTorrentDialog ([#&#8203;1613](autobrr/qui#1613)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`1abfc5e`](autobrr/qui@1abfc5e): fix(web): handle SSO proxy redirect to /index.html ([#&#8203;1600](autobrr/qui#1600)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`1991f90`](autobrr/qui@1991f90): fix(web): warn before enabling reannounce ([#&#8203;1583](autobrr/qui#1583)) ([@&#8203;s0up4200](https://github.com/s0up4200))

##### Other Changes

- [`4069492`](autobrr/qui@4069492): chore(deps): bump the github group with 3 updates ([#&#8203;1535](autobrr/qui#1535)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`a02e9e8`](autobrr/qui@a02e9e8): chore(deps): bump the github group with 7 updates ([#&#8203;1558](autobrr/qui#1558)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`8713667`](autobrr/qui@8713667): chore(deps): bump the golang group with 15 updates ([#&#8203;1543](autobrr/qui#1543)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`420607e`](autobrr/qui@420607e): chore(go,ci): adopt go fix, bump to 1.26, and speed up PR checks ([#&#8203;1480](autobrr/qui#1480)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`0d0df45`](autobrr/qui@0d0df45): docs: add password reset section to CLI commands ([#&#8203;1598](autobrr/qui#1598)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`9ef56a2`](autobrr/qui@9ef56a2): refactor(makefile): windows support ([#&#8203;1546](autobrr/qui#1546)) ([@&#8203;Audionut](https://github.com/Audionut))
- [`7899cc8`](autobrr/qui@7899cc8): refactor(reflinking): add windows ReFS filesystem support ([#&#8203;1576](autobrr/qui#1576)) ([@&#8203;Audionut](https://github.com/Audionut))
- [`51d34ab`](autobrr/qui@51d34ab): refactor(releases): share hdr normalization helpers ([#&#8203;1586](autobrr/qui#1586)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`c7f4e3d`](autobrr/qui@c7f4e3d): refactor(web): tighten unified scope navigation ([#&#8203;1618](autobrr/qui#1618)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`4b05177`](autobrr/qui@4b05177): test(handlers): cover tag baseline field requests ([@&#8203;s0up4200](https://github.com/s0up4200))

**Full Changelog**: <autobrr/qui@v1.14.1...v1.15.0>

#### Docker images

- `docker pull ghcr.io/autobrr/qui:v1.15.0`
- `docker pull ghcr.io/autobrr/qui:latest`

#### What to do next?

- Join our [Discord server](https://discord.autobrr.com/qui)

Thank you for using qui!

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My41OS4yIiwidXBkYXRlZEluVmVyIjoiNDMuNTkuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiaW1hZ2UiXX0=-->

Reviewed-on: https://gitea.alexlebens.dev/alexlebens/infrastructure/pulls/4884
Co-authored-by: Renovate Bot <renovate-bot@alexlebens.net>
Co-committed-by: Renovate Bot <renovate-bot@alexlebens.net>
hbjydev pushed a commit to hbjydev/phoebe that referenced this pull request May 29, 2026
… ) (#12)

This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [ghcr.io/autobrr/qui](https://github.com/autobrr/qui) | minor | `v1.14.1` → `v1.19.0` |

---

### Release Notes

<details>
<summary>autobrr/qui (ghcr.io/autobrr/qui)</summary>

### [`v1.19.0`](https://github.com/autobrr/qui/releases/tag/v1.19.0)

[Compare Source](autobrr/qui@v1.18.0...v1.19.0)

##### Changelog

##### New Features

- [`e26bd6b`](autobrr/qui@e26bd6b): feat(actions): include web-dist in release artifacts ([#&#8203;1801](autobrr/qui#1801)) ([@&#8203;turtletowerz](https://github.com/turtletowerz))
- [`2fabce1`](autobrr/qui@2fabce1): feat(automations): add export to instance action ([#&#8203;1736](autobrr/qui#1736)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`3fca808`](autobrr/qui@3fca808): feat(instances): api key authentication ([#&#8203;1854](autobrr/qui#1854)) ([@&#8203;martylukyy](https://github.com/martylukyy))
- [`4ab1a75`](autobrr/qui@4ab1a75): feat(qbittorrent): show process uptime ([#&#8203;1849](autobrr/qui#1849)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`292ef70`](autobrr/qui@292ef70): feat(torrents): hide filter icon when not active or hovering over ([#&#8203;1869](autobrr/qui#1869)) ([@&#8203;martylukyy](https://github.com/martylukyy))
- [`3c5cf3b`](autobrr/qui@3c5cf3b): feat(torrents): implement auto-fit width for columns on double-click ([#&#8203;1867](autobrr/qui#1867)) ([@&#8203;martylukyy](https://github.com/martylukyy))
- [`5a9c538`](autobrr/qui@5a9c538): feat(torrents): set comment ([#&#8203;1928](autobrr/qui#1928)) ([@&#8203;martylukyy](https://github.com/martylukyy))
- [`754f642`](autobrr/qui@754f642): feat(torrents): support new share limit parameters ([#&#8203;1872](autobrr/qui#1872)) ([@&#8203;martylukyy](https://github.com/martylukyy))
- [`06a5fb6`](autobrr/qui@06a5fb6): feat(torrents): update AddTorrent methods for qbit 5.2.x support ([#&#8203;1902](autobrr/qui#1902)) ([@&#8203;zze0s](https://github.com/zze0s))
- [`45e3adc`](autobrr/qui@45e3adc): feat: add support for monitored folders ([#&#8203;1847](autobrr/qui#1847)) ([@&#8203;martylukyy](https://github.com/martylukyy))

##### Bug Fixes

- [`77c7ae8`](autobrr/qui@77c7ae8): fix(automations): discard add torrent response ([#&#8203;1904](autobrr/qui#1904)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`7a368f1`](autobrr/qui@7a368f1): fix(ci): repair docs and release builds ([#&#8203;1932](autobrr/qui#1932)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`8bd114e`](autobrr/qui@8bd114e): fix(crossseed): normalize empty qbit metadata ([#&#8203;1887](autobrr/qui#1887)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`92d66f9`](autobrr/qui@92d66f9): fix(crossseed): reuse shared string normalizer to stop goroutine leak ([#&#8203;1909](autobrr/qui#1909)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`3c5d32a`](autobrr/qui@3c5d32a): fix(crossseed): run external programs after link-mode injection ([#&#8203;1874](autobrr/qui#1874)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`b02d2a9`](autobrr/qui@b02d2a9): fix(qbittorrent): handle forced subcategories ([#&#8203;1863](autobrr/qui#1863)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`83cdb01`](autobrr/qui@83cdb01): fix(qbittorrent): handle new tracker statuses ([#&#8203;1879](autobrr/qui#1879)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`b358ab4`](autobrr/qui@b358ab4): fix(rss): mirror torrentParams to legacy flat fields for qBit < 5.0 compat ([#&#8203;1846](autobrr/qui#1846)) ([@&#8203;frrad](https://github.com/frrad))
- [`5bcf648`](autobrr/qui@5bcf648): fix(seasonpacker): windows path handling ([#&#8203;1910](autobrr/qui#1910)) ([@&#8203;Audionut](https://github.com/Audionut))
- [`7de10c4`](autobrr/qui@7de10c4): fix(torrents): clear filters in unified-view empty state ([#&#8203;1898](autobrr/qui#1898)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`38f7bd3`](autobrr/qui@38f7bd3): fix(web): Show collapsed folders when searching torrent contents ([#&#8203;1850](autobrr/qui#1850)) ([@&#8203;ewenjo](https://github.com/ewenjo))
- [`d70d0bb`](autobrr/qui@d70d0bb): fix(web): keep showing torrent column filter icons on touch devices ([#&#8203;1881](autobrr/qui#1881)) ([@&#8203;martylukyy](https://github.com/martylukyy))
- [`cecbad7`](autobrr/qui@cecbad7): fix(web): select-all bulk actions delete more torrents than visible when filters are stacked ([#&#8203;1926](autobrr/qui#1926)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`780c4aa`](autobrr/qui@780c4aa): fix(web): sidebar element collisions ([#&#8203;1876](autobrr/qui#1876)) ([@&#8203;martylukyy](https://github.com/martylukyy))
- [`b621973`](autobrr/qui@b621973): fix(web): use unique keys for duplicate search results ([#&#8203;1886](autobrr/qui#1886)) ([@&#8203;GtwoK](https://github.com/GtwoK))

##### Other Changes

- [`ffda071`](autobrr/qui@ffda071): chore(deps): bump [@&#8203;babel/plugin-transform-modules-systemjs](https://github.com/babel/plugin-transform-modules-systemjs) from 7.28.5 to 7.29.4 in /documentation ([#&#8203;1889](autobrr/qui#1889)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`89ab1c8`](autobrr/qui@89ab1c8): chore(deps): bump [@&#8203;babel/plugin-transform-modules-systemjs](https://github.com/babel/plugin-transform-modules-systemjs) from 7.29.0 to 7.29.4 in /web ([#&#8203;1888](autobrr/qui#1888)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`c420bb2`](autobrr/qui@c420bb2): chore(deps): bump follow-redirects from 1.15.11 to 1.16.0 in /documentation ([#&#8203;1903](autobrr/qui#1903)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`28e4bf9`](autobrr/qui@28e4bf9): chore(deps): bump the github group with 2 updates ([#&#8203;1894](autobrr/qui#1894)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`9b241de`](autobrr/qui@9b241de): chore(deps): bump the github group with 3 updates ([#&#8203;1861](autobrr/qui#1861)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`4872577`](autobrr/qui@4872577): chore(deps): bump webpack-dev-server from 5.2.2 to 5.2.4 in /documentation ([#&#8203;1908](autobrr/qui#1908)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`3e3ec8b`](autobrr/qui@3e3ec8b): chore(deps): bump ws from 8.18.3 to 8.20.1 in /documentation ([#&#8203;1907](autobrr/qui#1907)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`25cf511`](autobrr/qui@25cf511): chore(web): migrate to pnpm 11 ([#&#8203;1883](autobrr/qui#1883)) ([@&#8203;martylukyy](https://github.com/martylukyy))
- [`4b6dce1`](autobrr/qui@4b6dce1): docs: add shared agent instructions symlink ([#&#8203;1911](autobrr/qui#1911)) ([@&#8203;Audionut](https://github.com/Audionut))
- [`97df42c`](autobrr/qui@97df42c): other(docs): resolve 5 Dependabot security alerts on Docs Site ([#&#8203;1906](autobrr/qui#1906)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`5068a4d`](autobrr/qui@5068a4d): refactor(crossseed): gather all results for matching and refine TV based searching ([#&#8203;1871](autobrr/qui#1871)) ([@&#8203;Audionut](https://github.com/Audionut))
- [`9d3e245`](autobrr/qui@9d3e245): refactor(crossseed): improve anime/AKA handling ([#&#8203;1882](autobrr/qui#1882)) ([@&#8203;Audionut](https://github.com/Audionut))
- [`6f2b94c`](autobrr/qui@6f2b94c): refactor(torrents): drop unused rename props from TorrentContextMenu ([#&#8203;1900](autobrr/qui#1900)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`3ec0605`](autobrr/qui@3ec0605): refactor(web): clean up 180 multiline-ternary warnings repo-wide ([#&#8203;1905](autobrr/qui#1905)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))

**Full Changelog**: <autobrr/qui@v1.18.0...v1.19.0>

##### Docker images

- `docker pull ghcr.io/autobrr/qui:v1.19.0`
- `docker pull ghcr.io/autobrr/qui:latest`

##### What to do next?

- Join our [Discord server](https://discord.autobrr.com/qui)

Thank you for using qui!

### [`v1.18.0`](https://github.com/autobrr/qui/releases/tag/v1.18.0)

[Compare Source](autobrr/qui@v1.17.0...v1.18.0)

##### Changelog

##### New Features

- [`b708bc8`](autobrr/qui@b708bc8): feat(automations): add UPLOADED\_OVER\_SIZE condition field ([#&#8203;1830](autobrr/qui#1830)) ([@&#8203;com6056](https://github.com/com6056))
- [`565731e`](autobrr/qui@565731e): feat(automations): cross-instance HARDLINK\_SCOPE\_CROSS ([#&#8203;1810](autobrr/qui#1810)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`a284860`](autobrr/qui@a284860): feat(dirscan): add webhook download client filters ([#&#8203;1751](autobrr/qui#1751)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`fd54124`](autobrr/qui@fd54124): feat(web): Add option to copy magnet link from the context menu ([#&#8203;1835](autobrr/qui#1835)) ([@&#8203;pietrocaselani](https://github.com/pietrocaselani))

##### Bug Fixes

- [`ea33304`](autobrr/qui@ea33304): fix(crossseed): broaden TV/movie torznab categories and skip year on TV ([#&#8203;1822](autobrr/qui#1822)) ([@&#8203;imSp4rky](https://github.com/imSp4rky))
- [`3c3f944`](autobrr/qui@3c3f944): fix(license): unblock stale polar license migration ([#&#8203;1799](autobrr/qui#1799)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`941cf42`](autobrr/qui@941cf42): fix(qbit): stop serving stale maindata to the status bar ([#&#8203;1785](autobrr/qui#1785)) ([@&#8203;Zariel](https://github.com/Zariel))
- [`ca7590a`](autobrr/qui@ca7590a): fix(rss): populate legacy assignedCategory for qBittorrent < 5.0 comp… ([#&#8203;1836](autobrr/qui#1836)) ([@&#8203;frrad](https://github.com/frrad))
- [`278441a`](autobrr/qui@278441a): fix(settings): explain disabled API keys ([#&#8203;1826](autobrr/qui#1826)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`0f4eb52`](autobrr/qui@0f4eb52): fix(web): remove deprecated tsconfig baseUrl ([#&#8203;1840](autobrr/qui#1840)) ([@&#8203;s0up4200](https://github.com/s0up4200))

##### Other Changes

- [`c6dbf9a`](autobrr/qui@c6dbf9a): chore(deps): bump postcss from 8.5.6 to 8.5.10 in /documentation ([#&#8203;1837](autobrr/qui#1837)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`053c171`](autobrr/qui@053c171): chore(deps): bump the github group across 1 directory with 3 updates ([#&#8203;1834](autobrr/qui#1834)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`4cbedac`](autobrr/qui@4cbedac): chore(deps): bump the golang group with 15 updates ([#&#8203;1832](autobrr/qui#1832)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`dd661e8`](autobrr/qui@dd661e8): chore(deps): bump the npm group in /web with 20 updates ([#&#8203;1833](autobrr/qui#1833)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`82029d6`](autobrr/qui@82029d6): chore(deps): update go-qbittorrent for new qbt 5.2.x webAPI version ([#&#8203;1841](autobrr/qui#1841)) ([@&#8203;martylukyy](https://github.com/martylukyy))
- [`6b5b82e`](autobrr/qui@6b5b82e): refactor(time): use seconds and cleanup ([#&#8203;1823](autobrr/qui#1823)) ([@&#8203;Audionut](https://github.com/Audionut))
- [`f5cb0c1`](autobrr/qui@f5cb0c1): refactor: O(n²) cross-seed lookups in automations preview and execution paths ([#&#8203;1829](autobrr/qui#1829)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))

**Full Changelog**: <autobrr/qui@v1.17.0...v1.18.0>

##### Docker images

- `docker pull ghcr.io/autobrr/qui:v1.18.0`
- `docker pull ghcr.io/autobrr/qui:latest`

##### What to do next?

- Join our [Discord server](https://discord.autobrr.com/qui)

Thank you for using qui!

### [`v1.17.0`](https://github.com/autobrr/qui/releases/tag/v1.17.0)

[Compare Source](autobrr/qui@v1.16.1...v1.17.0)

##### Changelog

##### Bug Fixes

- [`52c5e73`](autobrr/qui@52c5e73): fix(automations): clarify cross-seed condition labels ([#&#8203;1763](autobrr/qui#1763)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`70e0032`](autobrr/qui@70e0032): fix(crossseed): skip link-mode category path warnings ([#&#8203;1753](autobrr/qui#1753)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`85df3e7`](autobrr/qui@85df3e7): fix(orphanscan): align content path root detection ([#&#8203;1771](autobrr/qui#1771)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`117d617`](autobrr/qui@117d617): fix(orphanscan): ignore qBittorrent incomplete files ([#&#8203;1761](autobrr/qui#1761)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`388415e`](autobrr/qui@388415e): fix(web): fix add torrent/magnet urls ([#&#8203;1762](autobrr/qui#1762)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))

##### Other Changes

- [`845599a`](autobrr/qui@845599a): chore(ci): speed up CI pipeline (9.3 min → 4.3 min for PRs) ([#&#8203;1750](autobrr/qui#1750)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`2b09cf3`](autobrr/qui@2b09cf3): chore: trim embedded web assets and Docker build context ([#&#8203;1723](autobrr/qui#1723)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`5262f7c`](autobrr/qui@5262f7c): docs: add migration PR guidance ([#&#8203;1748](autobrr/qui#1748)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`65c7046`](autobrr/qui@65c7046): refactor(search): table & cards cleanup ([#&#8203;1768](autobrr/qui#1768)) ([@&#8203;nuxencs](https://github.com/nuxencs))

**Full Changelog**: <autobrr/qui@v1.16.1...v1.17.0>

##### Docker images

- `docker pull ghcr.io/autobrr/qui:v1.17.0`
- `docker pull ghcr.io/autobrr/qui:latest`

##### What to do next?

- Join our [Discord server](https://discord.autobrr.com/qui)

Thank you for using qui!

### [`v1.16.1`](https://github.com/autobrr/qui/releases/tag/v1.16.1)

[Compare Source](autobrr/qui@v1.16.0...v1.16.1)

##### Changelog

##### Bug Fixes

- [`e177ad9`](autobrr/qui@e177ad9): fix(auth): harden OIDC PKCE flow ([#&#8203;1746](autobrr/qui#1746)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`393e2b7`](autobrr/qui@393e2b7): fix(dirscan): tighten flexible matching and improve diagnostics ([#&#8203;1742](autobrr/qui#1742)) ([@&#8203;s0up4200](https://github.com/s0up4200))

**Full Changelog**: <autobrr/qui@v1.16.0...v1.16.1>

##### Docker images

- `docker pull ghcr.io/autobrr/qui:v1.16.1`
- `docker pull ghcr.io/autobrr/qui:latest`

##### What to do next?

- Join our [Discord server](https://discord.autobrr.com/qui)

Thank you for using qui!

### [`v1.16.0`](https://github.com/autobrr/qui/releases/tag/v1.16.0)

[Compare Source](autobrr/qui@v1.15.0...v1.16.0)

##### Changelog

##### Highlights

- Automations got a major upgrade: rules can now match across instances, use system time, control AutoTMM, and opt out of notifications per workflow.
- Cross-seed is more reliable during state changes. Completion searches now wait for torrents to finish checking or moving, disabled instances are skipped cleanly, and hardlink/reflink save-path handling is more accurate.
- Dir Scan works better with real media libraries, with improved partial season-pack handling in link-tree mode, support for downloading missing files when needed, and better progress retention across restarts.
- Managing torrents in the unified view is smoother, with more accurate tracker health, quicker instance-level actions, and more stable category and tag editing dialogs.
- OIDC and backups both got practical quality-of-life improvements: OIDC now supports PKCE, backup settings can be applied across instances, and backup export handling is safer for tricky torrent layouts.

##### New Features

- [`2b92c7b`](autobrr/qui@2b92c7b): feat(auth): add PKCE support to OIDC implementation ([#&#8203;1737](autobrr/qui#1737)) ([@&#8203;oynqr](https://github.com/oynqr))
- [`ba3d5d9`](autobrr/qui@ba3d5d9): feat(automations): add AutoTMM condition and action ([#&#8203;1698](autobrr/qui#1698)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`702e808`](autobrr/qui@702e808): feat(automations): add system time to query builder ([#&#8203;1677](autobrr/qui#1677)) ([@&#8203;wastaken7](https://github.com/wastaken7))
- [`e6493b3`](autobrr/qui@e6493b3): feat(automations): allow disable of notifications ([#&#8203;1652](autobrr/qui#1652)) ([@&#8203;heathlarsen](https://github.com/heathlarsen))
- [`565ac2d`](autobrr/qui@565ac2d): feat(automations): cross instance condition ([#&#8203;1648](autobrr/qui#1648)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`7e12a02`](autobrr/qui@7e12a02): feat(update): verify self-updates with signed release checksums ([#&#8203;1665](autobrr/qui#1665)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`3778c7b`](autobrr/qui@3778c7b): feat(web): Add action buttons to unified instance. ([#&#8203;1637](autobrr/qui#1637)) ([@&#8203;drtaru](https://github.com/drtaru))
- [`bf9eaba`](autobrr/qui@bf9eaba): feat(web): Clarify dashboard quick links ([#&#8203;1636](autobrr/qui#1636)) ([@&#8203;drtaru](https://github.com/drtaru))
- [`b930530`](autobrr/qui@b930530): feat(web): add "Save changes to all instances" button to backup settings ([#&#8203;1651](autobrr/qui#1651)) ([@&#8203;drtaru](https://github.com/drtaru))
- [`5975c34`](autobrr/qui@5975c34): feat(web): add Discord perk section to license manager ([#&#8203;1656](autobrr/qui#1656)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`d8ad0d6`](autobrr/qui@d8ad0d6): feat(web): unify tab styling and animations ([#&#8203;1632](autobrr/qui#1632)) ([@&#8203;nuxencs](https://github.com/nuxencs))

##### Bug Fixes

- [`44596b9`](autobrr/qui@44596b9): fix(automations): add AutoTMM to condition validation ([#&#8203;1726](autobrr/qui#1726)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`8f757b2`](autobrr/qui@8f757b2): fix(automations): hardlink signature grouping ([#&#8203;1670](autobrr/qui#1670)) ([@&#8203;aulterego](https://github.com/aulterego))
- [`d242f0c`](autobrr/qui@d242f0c): fix(automations): include AutoManagement in delete standalone check ([#&#8203;1731](autobrr/qui#1731)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`744bdb8`](autobrr/qui@744bdb8): fix(backups): adaptive export throttle ([#&#8203;1630](autobrr/qui#1630)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`d1dbb81`](autobrr/qui@d1dbb81): fix(backups): gate bulk save on resolved instance capabilities ([#&#8203;1682](autobrr/qui#1682)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`2eea961`](autobrr/qui@2eea961): fix(backups): skip live export for hybrid torrents ([#&#8203;1669](autobrr/qui#1669)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`2cac32d`](autobrr/qui@2cac32d): fix(crossseed): skip disabled instances ([#&#8203;1635](autobrr/qui#1635)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`ebbba8e`](autobrr/qui@ebbba8e): fix(crossseed): tone down async cache reuse log ([#&#8203;1686](autobrr/qui#1686)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`fd382b7`](autobrr/qui@fd382b7): fix(dirscan): link plan size tolerance + partial season pack injection in link tree mode ([#&#8203;1695](autobrr/qui#1695)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`5131092`](autobrr/qui@5131092): fix(dirscan): retain recent runs and clarify restart behavior ([#&#8203;1564](autobrr/qui#1564)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`3fbcc7a`](autobrr/qui@3fbcc7a): fix(openapi): document dirscan downloadMissingFiles ([#&#8203;1727](autobrr/qui#1727)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`d16fee2`](autobrr/qui@d16fee2): fix(orphanscan): use content\_path to prevent false positives when Auto TMM changes save\_path ([#&#8203;1712](autobrr/qui#1712)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`e74bf02`](autobrr/qui@e74bf02): fix(qbittorrent): avoid tracker health URL false positives ([#&#8203;1738](autobrr/qui#1738)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`632fc54`](autobrr/qui@632fc54): fix(torrents): honor tracker health in unified view ([#&#8203;1668](autobrr/qui#1668)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`76fddc4`](autobrr/qui@76fddc4): fix(torrents): stabilize tag and category dialogs ([#&#8203;1638](autobrr/qui#1638)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`c758b6d`](autobrr/qui@c758b6d): fix(torrents): validate creator output path ([#&#8203;1739](autobrr/qui#1739)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`6c23f0e`](autobrr/qui@6c23f0e): fix(web): cross-seed warning in unified view ([#&#8203;1692](autobrr/qui#1692)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`57822c0`](autobrr/qui@57822c0): fix(web): improve duplicate torrent state and check another field.state.value type in AddTorrentDialog ([#&#8203;1679](autobrr/qui#1679)) ([@&#8203;keatonhasse](https://github.com/keatonhasse))
- [`246c8f6`](autobrr/qui@246c8f6): fix(web): migrate vite chunk splitting config ([@&#8203;s0up4200](https://github.com/s0up4200))

##### Other Changes

- [`263b0bd`](autobrr/qui@263b0bd): build(deps): add cooldown to dependabot config ([#&#8203;1691](autobrr/qui#1691)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`a394157`](autobrr/qui@a394157): chore(deps): bump github.com/go-jose/go-jose/v4 from 4.1.3 to 4.1.4 ([#&#8203;1713](autobrr/qui#1713)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`10612a7`](autobrr/qui@10612a7): chore(deps): bump golang.org/x/image from 0.36.0 to 0.38.0 ([#&#8203;1685](autobrr/qui#1685)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`16019dd`](autobrr/qui@16019dd): chore(deps): bump pnpm/action-setup from 4 to 5 in the github group ([#&#8203;1634](autobrr/qui#1634)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`fbb25fc`](autobrr/qui@fbb25fc): chore(deps): bump the golang group with 11 updates ([#&#8203;1693](autobrr/qui#1693)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`cbb9594`](autobrr/qui@cbb9594): chore(deps): bump the golang group with 3 updates ([#&#8203;1701](autobrr/qui#1701)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`805ab74`](autobrr/qui@805ab74): chore(deps): bump the npm group in /web with 25 updates ([#&#8203;1694](autobrr/qui#1694)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`e3f839c`](autobrr/qui@e3f839c): chore(deps): bump the npm group in /web with 5 updates ([#&#8203;1702](autobrr/qui#1702)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`b076ad4`](autobrr/qui@b076ad4): docs(dirscan): clarify re-identification after torrent removal ([#&#8203;1720](autobrr/qui#1720)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`340f343`](autobrr/qui@340f343): docs: add license management page with deactivation guide ([#&#8203;1706](autobrr/qui#1706)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`5d148be`](autobrr/qui@5d148be): docs: fix link in issue triage template ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`0b64237`](autobrr/qui@0b64237): docs: update release follow-up docs ([#&#8203;1741](autobrr/qui#1741)) ([@&#8203;s0up4200](https://github.com/s0up4200))

**Full Changelog**: <autobrr/qui@v1.15.0...v1.16.0>

##### Docker images

- `docker pull ghcr.io/autobrr/qui:v1.16.0`
- `docker pull ghcr.io/autobrr/qui:latest`

##### What to do next?

- Join our [Discord server](https://discord.autobrr.com/qui)

Thank you for using qui!

### [`v1.15.0`](https://github.com/autobrr/qui/releases/tag/v1.15.0)

[Compare Source](autobrr/qui@v1.14.1...v1.15.0)

##### Changelog

##### Breaking change

CORS is disabled by default; enable by setting QUI\_\_CORS\_ALLOWED\_ORIGINS with explicit origins (http(s)://host\[:port]). See <https://getqui.com/docs/advanced/sso-proxy-cors>

##### New Features

- [`93786a2`](autobrr/qui@93786a2): feat(automations): add configurable processing priority/sorting ([#&#8203;1235](autobrr/qui#1235)) ([@&#8203;Oscariremma](https://github.com/Oscariremma))
- [`45eaf1f`](autobrr/qui@45eaf1f): feat(database): add postgres and sqlite migration CLI ([#&#8203;1530](autobrr/qui#1530)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`430f5d1`](autobrr/qui@430f5d1): feat(torrents): mediaInfo dialog ([#&#8203;1537](autobrr/qui#1537)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`8eb8903`](autobrr/qui@8eb8903): feat(web): Add persistence to unified instance filter in sidebar ([#&#8203;1560](autobrr/qui#1560)) ([@&#8203;drtaru](https://github.com/drtaru))
- [`7aadde7`](autobrr/qui@7aadde7): feat(web): add path autocomplete to set location dialog ([#&#8203;1432](autobrr/qui#1432)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`077f32c`](autobrr/qui@077f32c): feat: add mediainfo api endpoint ([#&#8203;1545](autobrr/qui#1545)) ([@&#8203;Audionut](https://github.com/Audionut))
- [`99cf695`](autobrr/qui@99cf695): feat: endpoint to trigger directory scans from external tools ([#&#8203;1559](autobrr/qui#1559)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`8956f9b`](autobrr/qui@8956f9b): feat: unify bulk tag editor ([#&#8203;1571](autobrr/qui#1571)) ([@&#8203;s0up4200](https://github.com/s0up4200))

##### Bug Fixes

- [`552d617`](autobrr/qui@552d617): fix(api): align add torrent OpenAPI field ([#&#8203;1617](autobrr/qui#1617)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`424f7a0`](autobrr/qui@424f7a0): fix(api): restrict CORS to explicit allowlist ([#&#8203;1551](autobrr/qui#1551)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`38991d8`](autobrr/qui@38991d8): fix(auth): allow loopback health probes ([#&#8203;1621](autobrr/qui#1621)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`4ae88c9`](autobrr/qui@4ae88c9): fix(automations): align include-cross-seeds category apply ([#&#8203;1517](autobrr/qui#1517)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`6a127a8`](autobrr/qui@6a127a8): fix(automations): scope skipWithin to only deleted action ([#&#8203;1538](autobrr/qui#1538)) ([@&#8203;jabloink](https://github.com/jabloink))
- [`c776189`](autobrr/qui@c776189): fix(crossseed): avoid completion timeout misses on non-Gazelle torrents ([#&#8203;1536](autobrr/qui#1536)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`b1338a7`](autobrr/qui@b1338a7): fix(crossseed): handle missing webhook collection tags ([#&#8203;1610](autobrr/qui#1610)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`eacbb68`](autobrr/qui@eacbb68): fix(crossseed): normalize hdr aliases ([#&#8203;1572](autobrr/qui#1572)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`537ad46`](autobrr/qui@537ad46): fix(crossseed): queue completion searches and retry rate-limit waits ([#&#8203;1523](autobrr/qui#1523)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`4fc550f`](autobrr/qui@4fc550f): fix(crossseed): use autobrr indexer ids for webhooks ([#&#8203;1614](autobrr/qui#1614)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`08029ad`](autobrr/qui@08029ad): fix(crossseed): valid partial matches being rejected ([#&#8203;1291](autobrr/qui#1291)) ([@&#8203;rybertm](https://github.com/rybertm))
- [`77eedd9`](autobrr/qui@77eedd9): fix(database): avoid postgres temp-table statement caching ([#&#8203;1581](autobrr/qui#1581)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`25daa17`](autobrr/qui@25daa17): fix(dirscan): honor canceled queued webhook runs ([#&#8203;1612](autobrr/qui#1612)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`56995f1`](autobrr/qui@56995f1): fix(dirscan): queue webhook scans and tighten age filtering ([#&#8203;1603](autobrr/qui#1603)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`444d07b`](autobrr/qui@444d07b): fix(dirscan): select concrete hardlink base dir ([#&#8203;1606](autobrr/qui#1606)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`c35bea0`](autobrr/qui@c35bea0): fix(instances): improve settings dialog scrolling ([#&#8203;1569](autobrr/qui#1569)) ([@&#8203;nuxencs](https://github.com/nuxencs))
- [`dc501a0`](autobrr/qui@dc501a0): fix(proxy): reauth qbit passthrough requests ([#&#8203;1582](autobrr/qui#1582)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`7950d1d`](autobrr/qui@7950d1d): fix(proxy): search endpoint handling ([#&#8203;1524](autobrr/qui#1524)) ([@&#8203;Audionut](https://github.com/Audionut))
- [`1076eea`](autobrr/qui@1076eea): fix(qbit): prune empty managed dirs after delete\_with\_files ([#&#8203;1604](autobrr/qui#1604)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`5a3114b`](autobrr/qui@5a3114b): fix(qbittorrent): stop reboot torrent\_completed spam ([#&#8203;1515](autobrr/qui#1515)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`1d02e6c`](autobrr/qui@1d02e6c): fix(settings): contain settings tab scrolling ([#&#8203;1567](autobrr/qui#1567)) ([@&#8203;nuxencs](https://github.com/nuxencs))
- [`f5d69f3`](autobrr/qui@f5d69f3): fix(settings): smoother gradient ([#&#8203;1570](autobrr/qui#1570)) ([@&#8203;nuxencs](https://github.com/nuxencs))
- [`1c0c3bc`](autobrr/qui@1c0c3bc): fix(torrents): copy MediaInfo summary without brackets ([#&#8203;1540](autobrr/qui#1540)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`3ec913a`](autobrr/qui@3ec913a): fix(web): auto-append slash on path autocomplete selection ([#&#8203;1431](autobrr/qui#1431)) ([@&#8203;nitrobass24](https://github.com/nitrobass24))
- [`aa2f3da`](autobrr/qui@aa2f3da): fix(web): check field.state.value type in AddTorrentDialog ([#&#8203;1613](autobrr/qui#1613)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`1abfc5e`](autobrr/qui@1abfc5e): fix(web): handle SSO proxy redirect to /index.html ([#&#8203;1600](autobrr/qui#1600)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`1991f90`](autobrr/qui@1991f90): fix(web): warn before enabling reannounce ([#&#8203;1583](autobrr/qui#1583)) ([@&#8203;s0up4200](https://github.com/s0up4200))

##### Other Changes

- [`4069492`](autobrr/qui@4069492): chore(deps): bump the github group with 3 updates ([#&#8203;1535](autobrr/qui#1535)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`a02e9e8`](autobrr/qui@a02e9e8): chore(deps): bump the github group with 7 updates ([#&#8203;1558](autobrr/qui#1558)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`8713667`](autobrr/qui@8713667): chore(deps): bump the golang group with 15 updates ([#&#8203;1543](autobrr/qui#1543)) ([@&#8203;dependabot](https://github.com/dependabot)\[bot])
- [`420607e`](autobrr/qui@420607e): chore(go,ci): adopt go fix, bump to 1.26, and speed up PR checks ([#&#8203;1480](autobrr/qui#1480)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`0d0df45`](autobrr/qui@0d0df45): docs: add password reset section to CLI commands ([#&#8203;1598](autobrr/qui#1598)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`9ef56a2`](autobrr/qui@9ef56a2): refactor(makefile): windows support ([#&#8203;1546](autobrr/qui#1546)) ([@&#8203;Audionut](https://github.com/Audionut))
- [`7899cc8`](autobrr/qui@7899cc8): refactor(reflinking): add windows ReFS filesystem support ([#&#8203;1576](autobrr/qui#1576)) ([@&#8203;Audionut](https://github.com/Audionut))
- [`51d34ab`](autobrr/qui@51d34ab): refactor(releases): share hdr normalization helpers ([#&#8203;1586](autobrr/qui#1586)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`c7f4e3d`](autobrr/qui@c7f4e3d): refactor(web): tighten unified scope navigation ([#&#8203;1618](autobrr/qui#1618)) ([@&#8203;s0up4200](https://github.com/s0up4200))
- [`4b05177`](autobrr/qui@4b05177): test(handlers): cover tag baseline field requests ([@&#8203;s0up4200](https://github.com/s0up4200))

**Full Changelog**: <autobrr/qui@v1.14.1...v1.15.0>

##### Docker images

- `docker pull ghcr.io/autobrr/qui:v1.15.0`
- `docker pull ghcr.io/autobrr/qui:latest`

##### What to do next?

- Join our [Discord server](https://discord.autobrr.com/qui)

Thank you for using qui!

</details>

---

### Configuration

📅 **Schedule**: (in timezone Europe/London)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xOTUuMSIsInVwZGF0ZWRJblZlciI6IjQzLjE5NS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL21pbm9yIl19-->

Reviewed-on: https://forgejo.hayden.moe/hayden/phoebe/pulls/12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants