Commit Graph
210 Commits
Author SHA1 Message Date
Ewald ALOEBOETOE ab4bdd41ea Match single-word searches anywhere in the file name
Typing "F" only found file names with a word starting with F (FTS5
prefix match), so the grid did not list e.g. sunflower.png or
ComfyUI_00001_.png. Single-word queries now add a filename LIKE
'%text%' branch to the global and scoped FTS queries and their counts,
ranked after FTS hits, with LIKE wildcards escaped. Multi-word and
quoted queries stay pure FTS.
2026-11-04 09:16:16 +00:00
Ewald ALOEBOETOE 03cfd018c1 Merge origin/main into feature/comfyui-integration-alignment
# Conflicts:
#	package-lock.json
#	package.json
2026-11-04 08:57:45 +00:00
Ewald ALOEBOETOE 4a19fc81a5 Fix remaining issues from the integration audits
- Watcher: a sidecar JSON created or edited next to an unchanged media
  file now invalidates that file's metadata cache and scan journal and
  forces a re-extraction; a non-incremental re-index no longer skips
  assets that already have a metadata row when the cache was cleared.
- Merge index rows that are one file under different Windows path
  spellings at startup, keeping the best rating, all tags, the stack
  cover, execution ids and the vector embedding.
- Remove deleted/removed assets from the generated feed too.
- Scope the floating viewer's single-letter shortcuts to the viewer
  (pointer, focus or pop-out) instead of the whole page.
- Take LGraph/LGraphCanvas types from comfyui-frontend-types and drop
  @comfyorg/litegraph; delete five dead frontend files.
- Fix an order-dependent test that leaked an input-directory override.
2026-11-04 08:48:26 +00:00
Ewald ALOEBOETOE 6cafe5cc42 Fix search syntax errors, sidecar JSON, workflow JSON recognition, MFV media leak
- Search: tokens were filtered down to nothing for inputs like "at-7",
  "(2)", "AND", a single letter or a lone quote, producing an empty FTS
  MATCH and "Invalid search query syntax". Fall back to the raw words,
  treat punctuation-only input as browse-all, keep non-Latin scripts and
  fold accents on Latin letters only (as FTS5 unicode61 does).
- Sidecar JSON (<file>.<ext>.json, then <stem>.json) now supplies the
  workflow/prompt/generation data of images, videos and audio when none
  is embedded; shared with the 3D extractor; BOM tolerated.
- Workflow tab: skip hidden folders (.history version snapshots were
  listed as workflows), only list UI exports, API prompts and wrappers,
  read with utf-8-sig, drop invalid JSON from the index (version 5),
  and load API-format workflows with app.loadApiJson.
- Floating viewer: release (not just pause) videos before re-rendering
  and on dispose, so Live mode no longer accumulates media players.
2026-11-04 08:26:47 +00:00
Ewald ALOEBOETOE 49bf320631 Fix asset sync for new, moved and deleted files
- Fix assets_fts triggers: the external-content FTS5 table was updated
  with plain UPDATE/DELETE, so every rename or move failed with
  "database disk image is malformed" and the watcher fell back to
  delete + re-index, losing ratings, tags and collections. Use the FTS5
  'delete' command, limit the update trigger to filename/subfolder and
  repair existing databases (plus an FTS rebuild) at startup.
- Wait for the prompt history entry before post-execution ingestion:
  ComfyUI fires on_prompt_end before task_done() stores history, so
  outputs of prompts queued from the API or another client could be
  missed.
- Scan prune only removes assets whose absence is confirmed; a stat
  error or an unreadable scan root no longer deletes user data. Report
  pruned assets instead of SQLite change counts.
- Emit mjr-assets-removed for watcher deletes and scan prunes and
  mjr-asset-updated for moves so open grids update in place.
- Annotate mjr-scan-complete with origin and needs_refresh; reload the
  grid once when live events cannot cover a change and summarise a
  finished directory scan in one ComfyUI core toast.
- Document the comparison with ComfyUI core's asset system.
2026-11-04 08:01:26 +00:00
Ewald ALOEBOETOE d0ab7d594e Resolve remaining ComfyUI integration conflicts
- Move the read-only OpenAPI compat surface from /api/v2/assets to
  /mjr/am/compat/assets so it never squats ComfyUI core's /api namespace;
  the legacy alias is opt-in via MJR_AM_LEGACY_API_V2_ASSETS=1.
- Allow Python 3.14 (requires-python <3.15) and add 3.14 to CI and tox.
- Stop wrapping api.queuePrompt: progress tracking now resolves the
  running prompt from the core Jobs API (getJobDetail), then /queue and
  /history, driven by websocket events. Remove wrapHostQueuePrompt.
- Add opt-in Majoor.Integration.HideNativeAssetsTab setting that hides
  ComfyUI's native Assets sidebar tab through the official
  getSidebarTabs/unregisterSidebarTab API and restores it when disabled.
- Fix all 913 type errors in tsconfig.test.json and type-check tests in
  CI; drop a duplicated `stubs` key in asset_card_inner test; make
  addToastHistory's type argument optional for the object form.
- Update audit report, changelog, API reference and env var docs.
2026-11-03 21:16:34 +00:00
Ewald ALOEBOETOE fdb0c5b2f1 Align host integration with current ComfyUI frontend/backend
- hostAdapter: serialize the root graph instead of calling the now-async
  graphToPrompt() synchronously (avoids exporting only the open subgraph
  and an unhandled rejection); read dirty state from the workflow store.
- Bump @comfyorg/comfyui-frontend-types to ^1.60.0: 1.57.3 was published
  without index.d.ts, so the official ComfyApp type was silently lost.
- Backend: typed aiohttp request keys (web.RequestKey when available)
  to silence NotAppKeyWarning on aiohttp >= 3.13 and avoid key clashes.
- Fix ruff import-order failures; rebuild dist bundle.
- Add docs/COMFYUI_INTEGRATION_AUDIT.md with remaining conflict risks
  and an integration roadmap.
2026-11-03 21:00:06 +00:00
copilot-swe-agent[bot]andMajoorWaldi 078433ea5a Fix quality audit by requiring patched Pillow 13
Co-authored-by: MajoorWaldi <129623145+MajoorWaldi@users.noreply.github.com>
2026-10-30 00:42:28 +00:00
copilot-swe-agent[bot]andMajoorWaldi 4dcc663796 Filter benign Florence optional custom-generation probe log
Co-authored-by: MajoorWaldi <129623145+MajoorWaldi@users.noreply.github.com>
2026-10-25 19:14:01 +00:00
copilot-swe-agent[bot]andMajoorWaldi acc5e9732b Fix Ruff import ordering in quality-gate tests
Co-authored-by: MajoorWaldi <129623145+MajoorWaldi@users.noreply.github.com>
2026-10-25 16:00:15 +00:00
copilot-swe-agent[bot]andMajoorWaldi 2154a58d5c Fix Python typecheck errors in graph links and EXR thumbnails
Co-authored-by: MajoorWaldi <129623145+MajoorWaldi@users.noreply.github.com>
2026-10-24 17:29:43 +00:00
copilot-swe-agent[bot]andMajoorWaldi 14d773f06d Fix custom Inputs indexing and expose an explicit scan button
Co-authored-by: MajoorWaldi <129623145+MajoorWaldi@users.noreply.github.com>
2026-10-24 16:46:36 +00:00
Ewald f093348cf5 fix: resolve collection exports and floating viewer input conflicts 2026-10-23 11:21:08 +02:00
Ewald b406535bf1 Stop rate limiting the local grid on the list route
Paging, prefetch and a reload per generation could exceed 50 list requests per minute and stall the grid. Loopback clients are exempt; remote clients are still throttled.
2026-10-01 13:02:04 +02:00
Ewald 30c964a7c1 Index opus, EXR, TIFF, SVG, BMP, AVI and M4V assets
Add the missing extensions to the shared classifier. EXR and TIFF are served to the viewer as a JPEG preview (EXR tone-mapped from scene-linear), ?original=1 returns the source file, and SVG is served sandboxed.
2026-10-01 12:18:20 +02:00
Ewald 39248a8f6d Fix metadata extraction for MKV, WebM, AVIF, JPEG and TIFF
Read generation time and execution ids case-insensitively from Matroska tags, read Majoor keys from AVIF/WebP EXIF text, and route JPEG and TIFF through the EXIF text reader so Prompt:/Workflow: and A1111 parameters are found.
2026-10-01 12:18:20 +02:00
Ewald 227b78cc62 Fix gen info on subgraph workflows and multi-output prompts
Resolve dict-form subgraph links, bridge subgraph inputs and outputs, expand nested subgraphs, keep linked widgets aligned with widgets_values and name widgets from the live node schema. Derive the sampler name from sampler selector classes, recognise the remaining core output nodes as sinks, accept single-node prompts, and parse gen info per producing node when a prompt writes several files.
2026-10-01 12:18:20 +02:00
Ewald 843ba2d823 Add 16-bit PNG, EXR, AVIF and AV1/WebM/MKV output to Majoor save nodes
Save Image gains format, input_color_space and crf options backed by the core Save Image (Advanced) encoders. Save Video gains mp4/mkv/webm with H.264 or AV1 and keeps the source bit depth and HDR colour space. Both nodes return their frames, and the video sidecar PNG now honours --disable-metadata.
2026-10-01 12:18:20 +02:00
Ewald 255c9a70e6 Repair ComfyUI core assets adapter against the real 0.38 API
The core-assets integration was calling module paths and function
names that don't exist in ComfyUI 0.38's app.assets system
(app.assets.database.queries.asset_reference, app.assets.database
.get_session, extract_asset_data/extract_reference_data, services
.list_assets_page), so core_assets_enabled() always returned False
and the whole integration was dead code regardless of --enable-assets.

Rewrites the adapter against the real service/query layer
(get_record_by_path_or_none, get_asset_detail, update_asset_metadata),
offloads the now-synchronous core DB calls via asyncio.to_thread, and
fixes sync_user_metadata_by_asset_id to merge onto the asset's
existing user_metadata instead of clobbering it (update_asset_metadata
replaces that field wholesale). Tests now mock the real import paths
instead of ones that never existed.
2026-09-30 16:56:16 +02:00
Ewald 990071069f Remove automatic GitHub release/update check
The frontend called checkMajoorVersion() unconditionally on startup,
and the backend /mjr/am/releases endpoint made outbound requests to
api.github.com to power it. This violates the no-internet-requests
policy for core ComfyUI code, even for update checks framed as
diagnostic or opt-out. Removes the endpoint, the frontend check, the
now-dead version-update badge dot in HeaderSection.vue, and associated
tests/docs.
2026-09-30 16:55:50 +02:00
copilot-swe-agent[bot]andMajoorWaldi aa9d28bc53 Merge remote-tracking branch 'origin/main' into fix/registry-runtime-hardening
# Conflicts:
#	dist/chunks/FloatingViewer-AB1oLZ0d.js
#	dist/chunks/FloatingViewer-BVmALIs3.js
#	dist/chunks/FloatingViewer-Cg2hGEZM.js
#	dist/chunks/LiveStreamTracker-0EQGV-lK.js
#	dist/chunks/LiveStreamTracker-BUT5H4M5.js
#	dist/chunks/LiveStreamTracker-DdMfL0ro.js
#	dist/chunks/SidebarWorkflowSection-B4wvtrtQ.js
#	dist/chunks/SidebarWorkflowSection-B_P-QZwl.js
#	dist/chunks/SidebarWorkflowSection-DckvqBNY.js
#	dist/chunks/TagsEditor-B8xpRa5e.js
#	dist/chunks/TagsEditor-BHGoWuSC.js
#	dist/chunks/TagsEditor-cUM_tRt-.js
#	dist/chunks/Viewer-DDNDTRcP.js
#	dist/chunks/Viewer-Dzb5KE6D.js
#	dist/chunks/Viewer-GH30s1No.js
#	dist/chunks/ViewerPortal-BAh1499M.js
#	dist/chunks/ViewerPortal-C-GBMubk.js
#	dist/chunks/ViewerPortal-DvYVQ32S.js
#	dist/chunks/floatingViewerManager-5-IYujSt.js
#	dist/chunks/floatingViewerManager-BVG4XDLW.js
#	dist/chunks/floatingViewerManager-Bnd82Qrd.js
#	dist/chunks/genInfo-Bq-kF66o.js
#	dist/chunks/genInfo-CV-v139t.js
#	dist/chunks/genInfo-CwY4j1FN.js
#	dist/chunks/mjr-primevue-C955bvXT.js
#	dist/chunks/mjr-primevue-DtKnnCVn.js
#	dist/chunks/mjr-primevue-n1rsQYJg.js
#	dist/chunks/mjr-vue-vendor-BU1tBlvz.js
#	dist/chunks/mjr-vue-vendor-CF0zsqr1.js
#	dist/chunks/mjr-vue-vendor-D2GeV7Qd.js
#	dist/chunks/openMajoorSettings-CHrLP8DR.js
#	dist/chunks/openMajoorSettings-DU4OegtI.js
#	dist/chunks/openMajoorSettings-JYq392b-.js
#	dist/chunks/viewerOpenRequest-C4hEgmOj.js
#	dist/chunks/viewerOpenRequest-CzyrZA71.js
#	dist/chunks/viewerOpenRequest-DQQY02Vk.js
#	dist/chunks/viewerRuntimeHosts-CIiyEfr6.js
#	dist/chunks/viewerRuntimeHosts-CuR8T4j6.js
#	dist/chunks/viewerRuntimeHosts-DC1iA_jY.js
#	dist/entry.js
#	mjr_am_backend/features/index/vector_service.py
#	mjr_am_backend/routes/core/request_json.py
#	mjr_am_backend/routes/core/security_proxies.py
#	mjr_am_backend/routes/core/security_tokens.py
#	mjr_am_shared/version.py

Co-authored-by: MajoorWaldi <129623145+MajoorWaldi@users.noreply.github.com>
2026-09-26 17:40:42 +00:00
Ewald 9c5078d174 fix: harden registry packaging and runtime boundaries
Exclude development-only content from Registry packages while retaining runtime
docs and vendor assets. Centralize environment access and media process execution,
validate filesystem inputs, and restrict nested media protocols.

Route update checks through the backend GitHub boundary and read version metadata
without spawning Git. Preserve annotated-tag priority over lightweight nightly
tags, including packed refs, with regression coverage. Rebuild the frontend bundle.

Validation: Python tests with coverage, JS tests, targeted media/version regression
tests, and the canonical Python quality gate.
2026-09-26 19:21:04 +02:00
Ewald df22cb501c fix(workflows): resolve ComfyUI root via folder_paths.base_path (GH #222)
_detect_comfy_root() located the ComfyUI install by walking up from the
output directory (or this package's own file) looking for a folder
containing both main.py and folder_paths.py side by side. Under
non-standard install layouts that heuristic can silently fail and return
None, which makes managed_workflow_root() return None too - so every
workflow path check fails with "Workflow path is not allowed" regardless
of the configured Workflow Roots setting.

Add get_base_path() to the comfy_core adapter (folder_paths.base_path,
the root ComfyUI itself resolves at startup) and try it first, falling
back to the old heuristic only when it's unavailable.
2026-09-11 12:14:10 +02:00
Ewald a0638ca4d3 fix(runtime): index output and temp prompt files under separate roots (GH #222)
A prompt that produces both an "output" file (Save Image) and a "temp" file
(e.g. a Preview Image node) was indexed with one shared base_dir computed via
commonpath across both, which walks up to their shared ComfyUI-root ancestor
and makes every subfolder wrongly include "output" or "temp" as a literal
leading segment - breaking the /view URL built from it and preventing the
grid from loading the image.

Group refs by item_type and call index_paths once per group against its own
correct root (runtime output root vs ComfyUI temp dir).
2026-09-11 11:55:58 +02:00
Ewald 094cb552c2 fix(security,ci): gate reads behind auth, harden release pipeline, fix cache-provider coupling and delete atomicity
- Require the same Comfy auth on all Majoor GET routes as on writes, closing
  a read-confidentiality gap for remote/multi-user deployments (no-op when
  Comfy auth is disabled, the default single-user setup).
- Gate nightly and stable releases on a quality job (pytest, mypy, frontend
  typecheck/build/tests, dist/ drift check) before publishing, and refresh
  the committed dist/ bundle to match a clean build.
- Pin softprops/action-gh-release and Comfy-Org/publish-node-action to
  commit SHAs.
- Resolve ComfyUI's CacheProvider through the public comfy_api.latest.Caching
  alias instead of the underscore-private _caching module.
- Make asset-delete DB cleanup atomic: a failed cleanup statement now aborts
  the transaction instead of committing a partial delete.
2026-09-04 20:53:57 +02:00
EwaldandClaude Sonnet 5 815993aae0 feat(nodes): migrate to ComfyUI Nodes V3 API
MajoorGenInfoOverride/MajoorSaveImage/MajoorSaveVideo now use
comfy_api.latest.io.ComfyNode (define_schema/execute) exposed via
comfy_entrypoint(), replacing the legacy NODE_CLASS_MAPPINGS dict style.
node_id values are unchanged so existing saved workflows keep resolving
to the same node classes.

Also bumps @comfyorg/comfyui-frontend-types to 1.54.3 (was pinned to
1.47.12) so JS typechecking matches the frontend versions ComfyUI
actually ships.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-04 19:44:28 +02:00
Ewald 0db328352a fix: close auth bypass on /api route mirror, revert PrimeVue to MIT 4.5.5
Security
--------
ComfyUI's PromptServer.add_routes() mirrors every registered route under a
second "/api" prefix, so /mjr/am/<mutation> is also served at
/api/mjr/am/<mutation>. The auth middleware matched only the canonical
prefix, so the mirrored path reached the same handler with the
authentication check skipped entirely, and without the hardening headers:

    POST /mjr/am/assets/delete      -> requires_auth = True
    POST /api/mjr/am/assets/delete  -> requires_auth = False

Replaced the prefix test with a shared _is_majoor_path() boundary covering
the canonical prefixes, ComfyUI's /api mirror, and the /api/v2/assets
compat surface. Verified it does not capture ComfyUI's own routes. CSRF,
rate limiting and safe-mode gates are per-handler and were unaffected.

Licensing
---------
PrimeVue 5 is no longer MIT: PrimeTek moved it to the commercial "PrimeUI"
license, which requires a key, shows a license notice without one, and
forbids redistributing it "as a component library or development tool"
without a separate OEM License. Dependabot had auto-merged 4.5.5 -> 5.0.1.
This project is GPL-3.0 and commits dist/ to the repo, so shipping it would
nag every user and conflict with the GPL's redistribution requirement.

Pinned back to 4.5.5 (last MIT release). The 5.x bump had touched only
package.json/package-lock.json, so no source depended on v5 APIs. The
revert drops @primeui/license-manager and its @noble/ed25519 key-signature
stack; the primevue chunk shrinks 555.70 -> 520.61 kB. Dependabot is now
configured to ignore primevue major bumps.

Correctness
-----------
- api_v2_assets: stop returning the DB's absolute filepath on this
  network-reachable surface; subfolder + root_id already convey location
  without disclosing local disk layout.
- watcher: enforce _RECENT_GENERATED_HARD_CAP after inserting a batch;
  pruning only beforehand let a large batch overshoot the cap.
- routes/registry: track registered route groups individually so a group
  failing part-way through does not re-register earlier groups on retry.
- fs_walker/scanner: apply the viewer's root check to symlinked files, so
  the scanner stops indexing symlinks whose target escapes every allowed
  root ("ghost assets" the viewer then refuses to open). Consulted only for
  actual symlinks, so ordinary scans pay no extra I/O.
- routes/registry_app: skip the redundant app.add_routes() on the live
  PromptServer app; ComfyUI adds the shared table itself after node
  loading, so every core and Majoor route was registered twice at startup.
- Result: unwrap()/unwrap_or()/map() gated on `data is not None`, treating
  a legitimate Ok(None) as failure; gate on `ok` instead.
- custom_roots: replace a leftover debug print() that wrote user file paths
  to stderr on every move request with logger.debug.
- schema: drop the redundant UNIQUE(filepath, source, root_id) index
  (migration m022). assets.filepath is already UNIQUE, so it could never
  reject a row the column constraint does not, nor narrow a lookup - it
  only cost a second B-tree write per asset on the scan hot path.

Frontend
--------
- entry.ts: app.registerExtension() throws on a duplicate name and ComfyUI
  exposes no unregisterExtension, so a live re-import threw before setup()
  ran and the reload-safe teardown never executed. Catch it and re-run
  setup() directly.
- Rebuilt dist/ so both the reload fix and the PrimeVue revert ship.

CI / tooling
------------
- frontend-compat-nightly: the types step died with a bare "cp: cannot
  stat" (upstream's build has not emitted dist/index.d.ts since Aug 26).
  Check both candidate paths and dump dist/ with an actionable message.
- package.json: lenient checks that swallowed their exit code are now
  suffixed :advisory, the plain names are strict, and quality:strict runs
  the full set.

Verified: 1841 Python tests pass (5 skipped, symlink privileges), ruff
clean; tsc --noEmit clean, 831 JS tests pass, eslint clean, build succeeds.
2026-09-04 18:41:48 +02:00
Ewald c669c03439 Improve viewer compatibility and media handling 2026-08-13 10:02:39 +02:00
Ewald 59afa1caec Fix viewer video and audio playback 2026-08-13 09:53:09 +02:00
Ewald b700104588 feat: modernize ComfyUI integration and add KJNodes previews 2026-08-12 11:16:06 +02:00
bsawang 1d974209d5 fix: add test adapters for folder-browsing browse mode and missing 'mode' field
- Add _Settings mock returning show_folders=False to 3 DB-index tests
  so they bypass the new browse mode and exercise the index path.
- Add mode='filesystem' to _build_browse_response payload for
  consistency with the filesystem-fallback path.
2026-07-29 14:09:09 +08:00
Ewald 17db2fe9d7 fix(security): harden workflow path containment and bump brace-expansion
- Resolve CodeQL py/path-injection alerts: enforce lexical containment
  (normpath + prefix check) before any filesystem access in
  list_workflow_versions, diff_workflow_versions,
  list_workflow_thumbnail_candidates and _resolve_path_under_roots,
  with post-resolve symlink re-validation. Also removes a file
  existence oracle for paths outside the allowed roots.
- npm audit fix: brace-expansion DoS (GHSA-3jxr-9vmj-r5cp, dev-only).
2026-07-24 16:16:50 +02:00
Ewald e3afb1a0d3 feat: add Collect Files (context menu + sidebar) bundling asset, workflow, traced prompt text and media inputs into a zip
- New POST /mjr/am/collect-files route (CSRF, write token, rate limit, path allowlist)
- collect_service: extracts workflow media/model refs, resolves inputs within allowed roots, builds {stem}_collected.zip next to the asset with writable-dir fallback to output/_mjr_collected
- Zip contains asset, workflow.json, prompt_graph.json, prompt.json (positive/negative traced via geninfo parser), inputs/ and collected_files.txt manifest
- comfy_core adapter: get_model_full_path helper
- Frontend: 'Collect files' grid context menu item + sidebar (D) MButton, collectFiles() API client op
- Tests: tests/features/test_collect_service.py (10 tests)
2026-07-24 15:41:48 +02:00
Ewald 10f851aaae Add metadata FTS backfill, registry logging collision fixes, i18n locales, and doc updates 2026-07-22 16:33:34 +02:00
Ewald b98edbb80f Fix viewer paths and clarify write access 2026-07-10 11:43:00 +02:00
Ewald ed8e33c5e4 Prepare 2.5.0 features and release notes 2026-07-09 11:18:28 +02:00
Ewald faf4055e08 Improve asset sidebar viewer and panel UX 2026-07-02 17:38:46 +02:00
Ewald cdd0314ad9 Fix search filter parsing and grid query typing 2026-07-01 16:16:26 +02:00
Ewald 2633e67ede Improve workflow metadata and viewer UX 2026-06-30 22:58:41 +02:00
Ewald 5fadbbbeb1 Fix metadata sidebar extraction and display 2026-06-29 18:07:21 +02:00
Ewald 6f116a3eb4 Fix generation prompt tracing 2026-06-29 08:54:20 +02:00
Ewald 30ae52d978 Integrate ComfyUI app mode and workflow UX fixes 2026-06-22 16:03:28 +02:00
Ewald 431faa8557 Fix security findings and test environment 2026-06-22 09:35:10 +02:00
Ewald b97f13d153 Optimize asset grid and viewer performance 2026-06-17 10:09:52 +02:00
Ewald bacc50000e Improve VRAM controls and settings organization 2026-06-16 17:17:19 +02:00
Ewald 5230dd43a2 Fix Python CI quality failures 2026-06-12 14:04:00 +02:00
Ewald 85d6da74fb fix: add type: ignore[index] for Result.data indexing in tests 2026-06-12 10:21:09 +02:00
Ewald 79cece3f01 fix: mypy type-ignore annotations in test_duplicates_service 2026-06-12 10:20:26 +02:00
Ewald 43a1fad285 chore: update dist, tests, and UI components 2026-06-12 10:19:33 +02:00
Ewald 5c31f29ecc Add workflow roots and fix video previews 2026-06-11 20:50:18 +02:00