.claude-plugin/marketplace.json now lives at the repository root, so the
plugin installs straight from GitHub with
`/plugin marketplace add tonhowtf/omniget` and
`/plugin install omniget@omniget`. The nested claude-plugin marketplace
is gone (one source), and the READMEs, llms-full.txt and the plugin docs
use the new commands.
server.json describes OmniGet for the official MCP Registry as
io.github.tonhowtf/omniget, with one mcpb package. The Release workflow
now bundles omniget-mcp for macOS (universal), Windows and Linux x86_64
into a single omniget-mcp.mcpb (the manifest picks the binary per OS),
and uploads it with a server.json that carries its real sha256, ready
for mcp-publisher. bump-version.js keeps both files on the app version.
omniget-mcp no longer exits when OMNIGET_MCP_TOKEN is unset. Without a
token, or while the desktop is closed, it answers initialize (same
protocol negotiation as the app), ping and tools/list from a catalog
snapshot, and every tool call returns an isError result with
TOKEN_MISSING or APP_NOT_RUNNING and how to fix it.
The snapshot (omniget-cli/mcp-catalog.json) is written and checked by an
app test, so it cannot drift from the desktop's catalog.
Add a clickable banner of Loop pointing at getomniget.com, followed by
the address in large type and one line saying it's the easiest way to
download OmniGet, for people who don't know their way around GitHub.
Same block in all four READMEs; llms-full.txt regenerated.
Add five illustrations in the new Loop sticker style (MCP downloads, the
downloader, agents, the World house, support) to all four READMEs, and
drop the two old-style images they replace.
Apply the positioning keywords: "open source video downloader" in the
subtitle, "let Claude Code download videos" in the MCP section, "yt-dlp
GUI and download manager" in the downloader section, and "a desktop app
for Claude Code, Codex and Gemini CLI" as the agents heading.
getomniget.com is now the project website in package.json, Cargo.toml,
funding.json, the AppStream metainfo, llms.txt, the media kit and a
README badge. The metainfo loses the course keywords.
scripts/mcp/README.md documents the local MCP endpoint: transports,
idempotent mutations, diagnostics, the experimental gateway and the
confined worker. art/world/craft-v1/README.md describes the craft-v1
art set and how to rebuild its atlas. Both had paths that no longer
exist; they now point at LLM → MCP → Your endpoint and art/world.
Dead code, two passes:
- Rust: the omnidisc-proto and omnidisc-mls crates, the torrent
streaming module that was never wired to a screen, livechat,
subtitle_ws, PDFium, commands and pub fns with no caller, the unused
get_download_command, and the download_attachments setting that no
code read.
- Frontend: OmniboxInput, BatchDownload, gl1.ts, unused exports, and
about 130 unused i18n keys across all locales.
- static/: icons, mascots and tiles nothing referenced. Source art moves
from static/ to art/, so it no longer ships in the bundle.
- Extension: action-click, action-title and media-signature, plus the
Hotmart/Udemy/course cases.
- scripts/: orphaned scripts.
- Dependencies: tauri-plugin-fs, hls.js, plugin-opener, zip, open,
kamadak-exif and image.
Texts that still named removed features now describe the app as it is:
onboarding, settings, the MCP error message, a tool description and the
extension's invalid-page hint.
Permissions: drop the protocol-asset feature and the assetProtocol
scope that let the webview read any file, five capabilities the
frontend never used, and the microphone, camera and ALSA leftovers from
OmniDisc.
Usage monitor: the usage report no longer rereads the whole CLI history
on every refresh, which froze the app. Logs untouched before the window
are skipped and the scan runs off the async runtime. Also pace and 100%
alerts, a deduplicated tray paint, and `omniget-cli usage`.
LLM: thinking orbs (libraries.dev) in the streaming message header, the
connection wizard and the MCP test button, after a 2 s wait.
Fixes: the worker test helper no longer uses std::os::unix on Windows
(broke `cargo clippy` there), the about/debug page is no longer
gitignored, and a few clippy warnings.
Adds scripts/dead-code-scan.mjs, which lists dead-code candidates.
Rewrite the README around what the app does today, in this order: the
MCP server (Claude Code queuing downloads), the downloader, the LLM
section and its command line, the World, and a short note that Tools
are being rebuilt. Courses, plugins, Telegram, the 156 tools and other
removed features are gone from the text.
Fix claims that were wrong: the MCP server exposes up to 41 tools, its
tabs are "Your endpoint" and "Servers you use", the CLI binary is
omniget-cli, the extension lives in Settings → Network, and the .deb
and .rpm do not pull the GStreamer plugins. Video spots are HTML
comments until the new visual identity is ready.
Translate the new README into Portuguese, Russian and Simplified
Chinese, rewrite llms.txt and regenerate llms-full.txt, and add
MEDIA-KIT.md with the facts, the claims to avoid and post templates for
anyone (or any agent) writing about OmniGet. Update funding.json and
the AppStream description, and drop README images of removed features.
* feat(city): decorate and publish your home, beds from the server clock, tinted ground
- Home editor in the city: catalogue, place/move/rotate/remove, undo/redo,
draft kept per home in localStorage, publish with base revision, package
hash and idempotency key; conflicts keep the draft and offer a reload.
- Beds panel driven by the server (stage, water, next stage, inventory),
actions with an op id; pictures attached to the home (upload, visibility,
report, detach).
- Versioned per-cell tint layer on the map (visual only, outside the hash),
applied by the WebGL and Canvas 2D bakers; renderer backend override.
- Dev probes for the city canvas (pixel, objects, camera).
* refactor!: remove the plugin system
Delete the native plugin loader, the plugin host, the plugin commands,
the host queue bridge and the omniget-plugin-sdk crate, with the
plugins-bootstrap thread that installed and updated them.
Delete the frontend of every plugin: Study (reader, music, Anki, notes,
focus, progress), Courses, Telegram, Convert and the Marketplace, with
their bridges, stores and listeners. The sidebar loses the plugins
section, the queue loses the plugin-only item kinds and the external
item flag, and the download page loses the course rows and the Open in
Study buttons. The markdown renderer the LLM chat used moves into
$lib/llm/markdown and QueueKindBadge into the download components.
BREAKING CHANGE: installed plugins are no longer loaded.
* refactor!: drop the course platforms
Remove Hotmart and Udemy from the Platform enum, the URL parser and the
download entry points, along with the course platform names the
detector kept for the Study shelves and course_utils. A course URL now
goes through the generic flow like any other site.
* feat(menu): Loop mascot icon set for the sidebar
Ten sticker icons, each pairing Loop with the action it stands for:
home, downloads, llm, help, world, tools, superpowers, settings,
about and league. 1024 px masters in assets/icons/menu, runtime
sizes (32, 64, 128) as WebP in static/icons/menu.
* feat(menu): Superpowers hub, Loop icons and an icon-only sidebar
- Sidebar items use the Loop sticker art (26 px, 36 px rows); plugins
and ids without art keep the colour tile.
- Marketplace leaves the menu: route, palette entry, toolbar title and
the LLM rail link are gone; plugin guard links now open
Settings > Plugins.
- New Superpowers hub (/superpowers) holds League of Legends as a card;
/league keeps the Superpowers item lit and still honours
league.enabled.
- The sidebar collapses to a 64 px rail: own tooltip, aria-label on
every item, section headers turn into dividers, downloads badge into
a dot. State lives in settings.appearance.sidebar_collapsed and
toggles with Ctrl+Cmd+S (Ctrl+Shift+S elsewhere) or the footer button.
- Downloads badge count was never passed to the sidebar; it is now.
- i18n: nav.superpowers, collapse/expand strings and the hub copy in all
locales; unused nav.marketplace and llm.rail.marketplace removed.
* refactor(i18n): drop the translations of the removed features
Remove 3,613 keys from every locale: the whole Study, tracking,
notifications, Telegram, Convert, Courses, Udemy, Hotmart, Marketplace
and plugin utilities namespaces, plus the plugin, course and Open in
Study strings left in the navigation, omnibox, downloads, toasts and
settings. The Settings category that was labelled Plugins only held the
browser extension and the dependencies, so it becomes Dependencies.
* refactor: delete dead code
- Unregister and delete 86 Tauri commands nothing invokes: the OmniDisc
chat, voice, screen share, upload, MLS and device commands (the
client that called them is gone), and leftovers in League, Bilibili
SMS login, the LLM local-server and conversation history, World
tiers and a few tools.
- Delete the OmniDisc gateway, voice, stream, upload, MLS, device and
ducking modules, the push-to-talk hotkey and the omnidisc-media crate,
which also drops the PipeWire capture feature and the
--no-default-features workaround in CI.
- Delete 13 platform files under src-tauri/src/platforms that no module
declared anymore (ported to omniget-core long ago), and the unused
core magnet copy.
- Delete 24 tool components the Tools page never mounts and the
Bilibili session banner nobody renders.
- Delete the private and crate-internal functions, types and constants
the compiler reports as unused and that nothing in the repository
references.
* refactor: delete the dead code the first pass missed
- omniget-core: delete 18 modules nothing references (the blog, Tumblr,
arXiv, audio tag, PDF form/redact/table, background removal, token
counter, YouTube chapters and TikTok sound tools whose screens were
never mounted, the LLM templates, fs_paths and the Bilibili SMS and
captcha login).
- Frontend: drop 687 OmniDisc chat, voice and stream strings from every
locale, the Courses and ERR_PLUGIN_OUTDATED error mappings, the stream
popout and hidden-sidebar branches of the layout, 25 icons and emoji
only plugin screens used, and 35 npm packages the Study editor and
player needed (tiptap, mermaid, katex, markmap, cytoscape, abcjs,
vidstack, highlight.js, the PlantUML and Graphviz WASM builds and the
Vite WASM plugins, and four font packages).
- Rust: drop libloading, tar, xz2, filetime, m3u8-rs, lofty, htmd,
rust_xlsxwriter and ndarray, and the unused CLI reporter.
- Messages and comments that still pointed at plugins now point at the
Dependencies tab.
* refactor!: remove the Tools section
Delete every tool: the Tools hub and its 24 categories, the tool
screens, the catalog, the file clip page, the Tools tab of the Downloads
page with its subtitle workshop, the Spicetify manager and the global
hotkeys the desktop tools registered. Their Tauri commands go with them,
and so do 67 of the 73 omniget-core tool modules and the app's second
copy of the Bilibili downloader, which only the danmaku tool still used.
The agent and the MCP server lose the 30 tools that came from the
section (PDF, OCR, Whisper, TTS, X, Instagram, disk, cleanup, SponsorBlock
and the rest); they keep help, coding, knowledge base, delegation and
downloads, 26 in all. The AI keys, usage report and MCP switch the LLM
screens call move to commands/llm/keys.rs, and core/tools keeps only the
plumbing the LLM layer needs: keys, usage, pricing, Ollama, ONNX and
GitHub downloads.
Also drop 2,470 translation keys, the brand and app icon folders, 66
other unused icons, and the Rust dependencies nothing uses anymore.
BREAKING CHANGE: the Tools section and the agent and MCP tools it backed
are gone.
* feat(home): redesigned home with drop overlay, more menu and friendly errors
* feat: benchmark-driven download fixes, cheaper agent jobs and `omniget claude`
Downloads (MCP worker):
- rustls in every client, so native platforms stop failing with "bad certificate format" under the sandbox
- yt-dlp onedir on macOS (0.4 s start instead of 13-25 s) and a single extraction via --load-info-json
- native variants respect the height ceiling before downloading, falling back to yt-dlp
- error classifier: no "age" substring match, HTTP status kept, 412 -> BLOCKED_BY_PLATFORM, EGRESS_FAILED, SERVER_ERROR, LIMIT_* codes
- the redacted yt-dlp command and worker timings reach the operator log
- direct downloads resume with Range, segment files above 20 MB, idle timeouts; HLS EXT-X-MAP/BYTERANGE and stall watchdog
- Bluesky resolves handles to DIDs and fetches the original blob; Instagram, Reddit, Pinterest, Twitch fixes
- youtube: DASH preferred over HLS with formats=dashy, full selectors pass intact and merge to mp4
Agents:
- cache tokens weighted in budgets (read 0.1x, write 1.25x), no double counting
- Anthropic prompt caching on by default; lean project jobs (--tools, --strict-mcp-config, --effort low)
CLI: `omniget claude [account] [-- args]` opens Claude Code on an app account.
Tooling: scripts/mcp gates and benchmark fixes, scripts/llm/missions_eval.py, scripts/test-fast.mjs.
* test(missions): split fake token fixtures so secret scanners do not flag them
* fix: drop the Study reader picker from reading journeys and count Superpowers in the nav
* feat(city): decorate and publish your home, beds from the server clock, tinted ground
- Home editor in the city: catalogue, place/move/rotate/remove, undo/redo,
draft kept per home in localStorage, publish with base revision, package
hash and idempotency key; conflicts keep the draft and offer a reload.
- Beds panel driven by the server (stage, water, next stage, inventory),
actions with an op id; pictures attached to the home (upload, visibility,
report, detach).
- Versioned per-cell tint layer on the map (visual only, outside the hash),
applied by the WebGL and Canvas 2D bakers; renderer backend override.
- Dev probes for the city canvas (pixel, objects, camera).
* feat(menu): Loop mascot icon set for the sidebar
Ten sticker icons, each pairing Loop with the action it stands for:
home, downloads, llm, help, world, tools, superpowers, settings,
about and league. 1024 px masters in assets/icons/menu, runtime
sizes (32, 64, 128) as WebP in static/icons/menu.
* feat(menu): Superpowers hub, Loop icons and an icon-only sidebar
- Sidebar items use the Loop sticker art (26 px, 36 px rows); plugins
and ids without art keep the colour tile.
- Marketplace leaves the menu: route, palette entry, toolbar title and
the LLM rail link are gone; plugin guard links now open
Settings > Plugins.
- New Superpowers hub (/superpowers) holds League of Legends as a card;
/league keeps the Superpowers item lit and still honours
league.enabled.
- The sidebar collapses to a 64 px rail: own tooltip, aria-label on
every item, section headers turn into dividers, downloads badge into
a dot. State lives in settings.appearance.sidebar_collapsed and
toggles with Ctrl+Cmd+S (Ctrl+Shift+S elsewhere) or the footer button.
- Downloads badge count was never passed to the sidebar; it is now.
- i18n: nav.superpowers, collapse/expand strings and the hub copy in all
locales; unused nav.marketplace and llm.rail.marketplace removed.
* feat: benchmark-driven download fixes, cheaper agent jobs and `omniget claude`
Downloads (MCP worker):
- rustls in every client, so native platforms stop failing with "bad certificate format" under the sandbox
- yt-dlp onedir on macOS (0.4 s start instead of 13-25 s) and a single extraction via --load-info-json
- native variants respect the height ceiling before downloading, falling back to yt-dlp
- error classifier: no "age" substring match, HTTP status kept, 412 -> BLOCKED_BY_PLATFORM, EGRESS_FAILED, SERVER_ERROR, LIMIT_* codes
- the redacted yt-dlp command and worker timings reach the operator log
- direct downloads resume with Range, segment files above 20 MB, idle timeouts; HLS EXT-X-MAP/BYTERANGE and stall watchdog
- Bluesky resolves handles to DIDs and fetches the original blob; Instagram, Reddit, Pinterest, Twitch fixes
- youtube: DASH preferred over HLS with formats=dashy, full selectors pass intact and merge to mp4
Agents:
- cache tokens weighted in budgets (read 0.1x, write 1.25x), no double counting
- Anthropic prompt caching on by default; lean project jobs (--tools, --strict-mcp-config, --effort low)
CLI: `omniget claude [account] [-- args]` opens Claude Code on an app account.
Tooling: scripts/mcp gates and benchmark fixes, scripts/llm/missions_eval.py, scripts/test-fast.mjs.
* test(missions): split fake token fixtures so secret scanners do not flag them
* build: write an empty worker sidecar placeholder when it is missing so CI can compile
* test(missions): octal permission literal for clippy
- Home editor in the city: catalogue, place/move/rotate/remove, undo/redo,
draft kept per home in localStorage, publish with base revision, package
hash and idempotency key; conflicts keep the draft and offer a reload.
- Beds panel driven by the server (stage, water, next stage, inventory),
actions with an op id; pictures attached to the home (upload, visibility,
report, detach).
- Versioned per-cell tint layer on the map (visual only, outside the hash),
applied by the WebGL and Canvas 2D bakers; renderer backend override.
- Dev probes for the city canvas (pixel, objects, camera).
Drop Kiwify from the README in every language, add a Notice to platform
owners section to each one and restore the notice as PLATFORM-OWNERS.md,
with the removal process and the current opt-out list.
Sites whose owners asked OmniGet not to support them are refused at every
download entry point: the download commands, platform detection, format and
metadata prefetch, external URLs (hotkey, deep link, MCP, channel poller)
and the browser extension bridge. The refusal is translated in every
locale. Kiwify is the first entry, covering kiwify.com.br, kiwify.com,
kiwify.app and their subdomains.
Drop Kiwify from llms.txt, llms-full.txt, the flatpak metainfo, the
screenshot mocks, the course platform list, the Study shelf labels, the
platform detector and the Hotmart external-course hint in every locale.
The city canvas merges the house furniture atlas (craft-v1) with the
workshop's town art (vale-v1: ground, houses, props, crop stages), generated
from the offline export with a tile entry per frame. A click on a bed waters,
harvests, clears or plants it (the server decides who may and what grows);
the panel shows the harvest in the house and picks the crop to plant.
city_* commands: sign in or create an account on the instance (token in the OS store), join /world/v1 with reconnection and backoff, inputs with acks, interest, chat, resync and an authenticated proxy to /api/world/*. CityCanvas keeps one replica per region (the avatar's block plus the eight around it), bakes every exterior block into the same chunk space and swaps to the interior on entering a home. CityPanel: enter, claim a plot, go home, proximity chat. Settings: world.city_server.
World::checkpoint() / World::from_checkpoint() carry everything a snapshot leaves out (paths, intents, routines, per-agent RNG, mailbox), so a server can restart a region and replay its input log to the same fingerprint. Input and the internal state types derive serde.
The anonymous CORS mode is what lets the thumbnail and SponsorBlock overlays read frames on the other webviews; WebKitGTK is the one that refuses to load a local file with it.
Help ships offline guides and an assistant that cites bundled docs.
Connection wizard, surface guides, usage monitor and workspace appearance
land with the Agents UX pass; the shared tool table gains seven help tools.
Co-authored-by: Cursor <cursoragent@cursor.com>
procps on Linux does not read a negative argument the way the BSD kill does;
a misread group id takes every process of the user with it, which on CI is the
runner itself ("lost communication" with no log).
Two world tests move the clock by hand while the live tick thread was
still running, so a slow runner settled the state back under them. The
Test step now has a 30 minute ceiling: the Ubuntu job hung silently and a
cancelled job leaves no log.
The 0.10 section moves to the top and covers the coding harness,
permissions and rules, undo, jobs, loops, triggers, the CLI, bring your
own agents, delegation, project memory, pruning receipts, the World and
visits. Counts follow the shipped catalog: 156 tools in 24 categories,
49 on the MCP server.
The skill fixtures are SKILL.md files and the repository ignores every
.md, so CI never had them: they are now tracked as .md.fixture and the
tests copy them to a scratch folder under their real names. A hung
scanner is killed with its whole process group and the timeout no longer
waits for readers that a grandchild keeps open. On Windows/MSVC the
Common Controls v6 manifest is linked into every target, so the unit
test executable loads.
Clippy on Linux and Windows flagged a large enum variant in the MCP
client and five imports only the unix-gated tests use. The open-house
tick-rate test asked for 13 ticks in 1.5 s and a loaded macOS runner
delivered 10; the bar is now what separates an active house from a
dozing one.
LLM section with a native coding harness (workspace-bound tools, macOS
seatbelt, permission asks with Always rules, undo of files and of the
turn's messages), jobs, Loops with a check command, cron and webhook
triggers, `omniget agent` in the CLI, ACP and CLI agents, agent_delegate,
project knowledge base, skills from owner/repo, context pruning with
measured receipts, and the coding tools on the embedded MCP server.
The World: a house for the roster (three default agents, one post each,
tool balloons, activity panel, demo mode, yard preview), open house and
visits by code through omniworld-server, with the host as the authority.
Retires the experimental OmniDisc chat. OMNIGET_DATA_DIR now gives a
second profile its own settings, bridge port and instance.
New illustrations (animated hero, workflow strip, extension pairing, Tools, Study,
privacy, AI agents, League), fresh screenshots of the 25-category hub, and sections
for the categories added in 0.9.2 (Audio, Facebook, Reddit, Twitch, Bilibili, Music,
LinkedIn, Games, CTF) plus the new Video, PDF, Images, Files and System tools.
Adds the MCP server and Claude Code plugin section, the extension deep search
paragraph, and mirrors the counts in llms.txt. Translated READMEs only re-point
at the new image files.
Tools: 108 -> 156 tools, 16 -> 24 categories, all 48 new ones ready.
New categories: Audio, CTF, Twitch, Music, Reddit, Bilibili, Games and
LinkedIn. Video compresses to a target size in two passes, makes GIF/WebP,
cuts silences, converts, burns and resyncs subtitles, restores (deflicker,
denoise, deband), stabilizes and makes stickers. Audio normalizes loudness
and removes noise. PDF repairs, password-protects, watermarks, crops,
builds outlines, exports Markdown and audits redactions on lopdf. Images
read and strip EXIF, build icon packs, compress, find duplicates, handle
spritesheets and stitch screenshots. Files shreds, System blocks hosts.
Twitch emotes and chat replay, Reddit post/thread/data export, LRCLIB
lyrics, playlist mirroring and Spotify history, LinkedIn export reader,
ProtonDB, Switch album and clip organizer, Bilibili danmaku export and burn.
Extension: deep search watches the page's player APIs for playlists that
never cross the network, HLS size estimates, video/audio track pairing,
media signature check against HTML error pages, editable capture rules,
header allowlist instead of blocklist, and an installed-extensions backup
behind an optional management permission. Portions adapted from cat-catch
(GPL-3.0).
Also in the tree, compiled but not wired to the catalog yet: the
in-progress TikTok, Tumblr, Vimeo, blogs, lists, arXiv, token cost,
YouTube archive/chapters/notes, background removal (ort, load-dynamic),
audio tags (lofty) and PDF form/table/redact modules.
New crates: kamadak-exif, sha1, lopdf, lofty, htmd, rust_xlsxwriter, ort,
ndarray; image gains the ico feature.
Fix: clippy manual_pattern_char_comparison in ai_tokens wanted_exts.
feat(skill): OmniGet Claude Code plugin (fetch, caption, transcript)
Adds claude-plugin/ — two skills, five commands and the shell/Python that
back them. Nothing under src/, src-tauri/ or the workflows is touched, so
the build is unaffected.
The repo ignores *.md, which would have swallowed every SKILL.md and
command file, so .gitignore now carries an exception for claude-plugin/:
here a .md is the delivered artifact, not a note.
Verified locally since CI never ran on the fork's first PR: bash -n on all
11 scripts, py_compile on the 4 Python files, both JSON manifests parse,
and the two Python test suites pass (9 + 6 tests).
fix(build): make AppImages installable via Gear Lever, fix bundling on Arch
Bumps @tauri-apps/cli to 2.11.4 so the AppDir symlinks are relative again
(Gear Lever's 7z extraction turns absolute ones into dangling paths), sets
NO_STRIP on the ubuntu runners because linuxdeploy's bundled strip aborts
on .relr.dyn, vendors a patched linuxdeploy-plugin-gtk.sh with full MIT
provenance, and adds a desktop template so deb/rpm carry the same
Categories/Keywords as the flatpak entry.
The branch's README hunk is dropped — ours diverged in 0.9.1 and stays as
it is.
`installable` was a hardcoded `true` and `copy_recursive` treated a missing
source as success. The Windows portable build is the bare `omniget.exe`
with no `resources/` folder beside it, so Settings → Plugins offered
"Update / Install", copied nothing, and pointed the user at an empty
`browser-extension/firefox/` folder.
The status now asks the bundle whether the extension is actually there, the
export fails with a reason instead of an empty directory, and Firefox
carries its AMO link so the UI has somewhere to send people when the files
are absent.
Refs #310
Bilibili moved collections from `/channel/collectiondetail?sid=N` to
`/lists/N`, and only the old form was in `is_playlist_or_series`. The
omnibox still listed the collection — that preview goes through the native
API and `url_kind::detect`, which knows the new link — but the download
took the single-video path, handed yt-dlp the listing page and came back
"Failed to access the page".
yt-dlp's collection and series extractors both accept `/lists/N`, so the
playlist path resolves it to one BV URL per video, which is what
`download_playlist` needs. Also covers `bilibili.com/list/<id>`, and leaves
the bare `/lists` index alone since it expands to nothing.
Closes#311
A batch pasted into the omnibox fires one `download_from_url` per URL at
once. Each call read the current millisecond as the id, released the queue
lock to resolve the downloader, and only then enqueued — so every call in
the batch got the same number and pushed an item with it. Everything
downstream finds an item with `find(|i| i.id == id)`, which stops at the
first match: the first URL was downloaded once per duplicate and the rest
of the batch never started.
`next_available_id` now takes `&mut self` and remembers the last id it
handed out, so the reservation happens inside the same lock as the lookup.
Closes#313
precise_sleep asserted a 20 ms upper bound that macOS CI runners miss under
load; the lower bound is the contract, the upper bound now only catches a
sleep that never wakes. On Windows the cfg blocks in file_search::backend and
win_tweaks::status are the function's tail, so clippy flagged their explicit
returns against the win32 baseline; they are expressions now, like the other
platform branches.
The Tools, League, downloads and courses work of the last two days landed
without rustfmt, so CI's Format step rejected the 0.9.1 commit before Clippy
and the tests could run. Formatting only; no code change.
Tools: a new sidebar section with 108 single-purpose tools in 16 categories
(79 ready, 27 beta), each an isolated Rust command with JSON in and out.
Instagram (24), X (10) and Pinterest (10) run on the user's own web session
captured by the extension; speech tools wrap whisper.cpp, Edge TTS,
translation and dubbing; PDF tools drive the managed PDFium; System tools
clean caches, map the disk and manage startup and uninstall, with
Windows-only debloat, registry, privacy and hardening; AI tools compare
prices, track spending, manage Ollama, keep an API key vault and expose
everything over an MCP server on the local bridge.
Interface: Apple-first remake with one amber accent, glass sidebar, colored
tile icons, a new app icon, promise-first home, three-step onboarding, 14
themes rebuilt on tokens, humanized download errors, Fluent 3D empty states.
Downloads: yt-dlp as a zipapp on a system Python when available, dashy
formats and adaptive per-host concurrency, HEAD content-length fix so direct
files segment, direct-file probe, terminal errors stop blind retries, global
connection budget, command record with edit-and-retry, new download card.
Courses: section picker with DRM count, saved-cookie login, Hotmart OIDC and
Rocketseat fixes surfaced in the app, Meta-Analysis Academy platform.
Extension 0.4.1: cookies bucketed by registrable domain (.com.br and other
two-label suffixes), Rocketseat host, Force H.264 toggle, cookie-capture tests.
League of Legends: on by default; Profile tab, skin/chroma/ward roulette,
champion and lane raffle, random pick, SGP match history and replay download,
AI coach. Fixes: English embedded as i18n fallback so WebKit never renders an
empty UI, settings load retried, kdeconnect runner mapped, nav test count.
Housekeeping: misc plugin frontend removed, Markdown notes and study folders
dropped from the repo and ignored, issue templates and Homebrew tap workflow
added, version bumped to 0.9.1 with the metainfo release entry.
Brings the AI-readable summary in line with the rewritten README: the 108
tools by category, the four plugins, OmniDisc and League as opt-in, install
paths including Homebrew and the extension pairing, and what OmniGet does not do.
New English README with the full Tools catalog (108 tools in 16 categories,
status marked), the four plugins, the browser extension install in three
levels, comparison table, FAQ and the 20 GitHub topics. Portuguese (BR),
Russian and Simplified Chinese versions follow the same structure and credit
the contributors who started each translation (@alvarorichard #280,
@xJaroslav69 #130, @Tan665565 #154).
Screenshots regenerated from the mocked harness into assets/readme/ plus
three hand-made SVG illustrations; the old assets/screenshot-*.png and
assets/readme/en/ are removed.
The Tauri CLI rejects --no-default-features unless it comes after --, which it
then forwards to cargo. Verified by dependency tree: without the app's default
feature the Linux target pulls zero pipewire/ashpd crates, and rnnoise stays on
because the dependency asks for it by name.
`libspa` generates its bindings from the system headers, and PipeWire 0.3.48 —
what Ubuntu 22.04 ships — has no `flags` field on `spa_video_info_raw` and types
`modifier` as `i64`, so the crate does not compile there at all. The x86_64
release job stays on 22.04 deliberately: it is what keeps the AppImage's glibc
floor low enough for older distros.
So capture becomes a feature, on by default and off for that one job. Nothing
else in the client changes, and the loss is reported rather than hidden:
`MediaCapabilities.screen_share` now answers from the compiled backend instead
of from the operating system name, and the share button already knows how to
say a platform cannot do this.
arm64 Linux, built on 24.04, keeps the full feature.
An unprivileged Wayland client cannot enumerate windows, so the source grid on
Linux would be a grid of one placeholder. The dialog now says the desktop will
ask, which is what actually happens.
Linux screen capture links libpipewire, so the Debian and Ubuntu jobs need its
development package and clang for bindgen; without them the Linux build fails
at the first compile of omnidisc-media rather than at a test.
The Flatpak needs the audio sockets for voice and for screen-share audio, which
reads the default sink's monitor because the ScreenCast portal carries no audio
of its own. Video needs no new permission: the portal hands back a file
descriptor, which is exactly why capture goes through it.
Chat ships enabled and pre-connected, so the first screen is register/login
rather than a server address. Everyone who signs up lands in a community
server with per-language channels.
Screen sharing reaches viewers again. Discovery depended entirely on the
gateway relaying self_stream, and the LiveKit TrackPublished event never left
the media engine — against a server that predates that relay nobody saw the
stream and the watch button never appeared. Screenshare tracks now raise an
engine notification of their own, the sharer sees a preview of their own
screen, and the pop-out viewer got the Tauri capability it was missing, so
fullscreen and close work and closing it no longer leaks the viewer and blocks
re-watching that person.
The macOS microphone works. The app never declared NSMicrophoneUsageDescription
and never asked for TCC authorisation, so CoreAudio started successfully and
delivered digital silence forever: connected, inaudible, no error anywhere.
Permission is requested through AVFoundation before the input opens, and a
microphone that delivers only zeros is now reported instead of showing a level
meter that cannot move.
Calls and screen sharing work on Linux, X11 and Wayland alike, through
xdg-desktop-portal ScreenCast and PipeWire. The portal's dialog is the picker,
because an unprivileged Wayland client cannot enumerate windows; the restore
token is kept so the second share skips it. VAAPI or NVENC is requested when
libwebrtc reports it and the inspector names the backend actually chosen.
Files are temporary by policy. Attachments are deleted from the server after
thirty minutes, leaving a tombstone so a message says the file expired instead
of offering a dead link, and the media endpoint answers 410. Until then they
are encrypted at rest in XChaCha20-Poly1305 frames keyed per blob, so a stolen
disk or a copied backup yields nothing. There is no per-user quota: the volume
is the budget, people are warned at 80% and everything stored is deleted at
95%, announced over the gateway rather than happening silently. Uploads are
rate limited by request and by byte.
Animations and the share preview stop while the window is unfocused, so a chat
sitting behind a game costs as little as it can.
Remux concatenated HLS transport streams into a real MP4 so QuickTime can open them (#300), suspend yt-dlp on Windows via NtSuspendProcess (#307), add Persian with RTL (#279), and run AppImages through XWayland when the session is Wayland (#199). Unknown plugin commands now tell the user to update from the Marketplace, and a winget workflow submits the manifest when a draft release is published.
Co-authored-by: Cursor <cursoragent@cursor.com>
They create real accounts, so pointing them at the live server littered it with
throwaway users — which is what happened. OMNIDISC_TEST_ALLOW_REMOTE=1 opts back
in deliberately.
The server rail scrolls, so it hides horizontal overflow, and its + menu was
positioned absolutely outside the rail's 64px width: the click opened a menu the
browser then erased. Reported as the + button not working.
The message list is worse. VirtualList sets contain: layout paint on every row,
which makes each row a containing block for fixed positioning too, so leaving
the flow is not enough — the node has to leave the subtree. The message
more-menu and the reaction picker were cut off for anything in the lower half of
the list, and the image lightbox resolved inset: 0 against a 60px row and opened
as a sliver instead of full screen.
Menus are now measured from their trigger and portaled out, flipping above when
the bottom edge would cut them and clamping to the viewport. They dismiss on
outside pointerdown, Escape, resize and scroll, and hand focus back to the
trigger — a portaled menu is no longer in the tab order by position.
Two problems, one root: development builds cannot hold a keychain grant. tauri
dev produces an unsigned binary that changes on every rebuild, and macOS binds
Always Allow to the binary's identity, so the grant is void the next time you
press run — the prompt returned on every launch and every read no matter how
many times it was answered. Debug builds now use the encrypted file store and
only signed release builds touch the keyring; OMNIGET_OMNIDISC_KEYRING=1 forces
the keyring back on. Secrets are also cached per process, so one launch asks the
OS once per secret instead of once per gateway reconnect and request. The cache
key carries the store it came from, because the tests run two identities in one
process by switching session directories.
The live tests also registered real accounts using a password written in the
repository, which is a working credential for every account they leave behind.
It is now random per run.
Starting system audio corrupted the heap. The PROPVARIANT carrying the process
loopback parameters was left to drop, and PropVariantClear hands a VT_BLOB's
pBlobData to the COM allocator — but that pointer is the stack local holding the
AUDIOCLIENT_ACTIVATION_PARAMS. The variant only borrows those params for the
duration of the call, so it must never be cleared.
Opening the share picker twice crashed the app with an access violation. The
capture paths wrapped each call in CoInitializeEx/CoUninitialize, but tearing
the apartment down does not invalidate the WinRT activation factories the
windows crate caches, so the second GraphicsCaptureSession::IsSupported read
freed memory. CoIncrementMTAUsage exists for this: an implicit MTA that outlives
every call, with the cookie deliberately never released. The worker threads stop
initialising their own apartments for the same reason.
Found by the capture self-test on the Windows CI job, which is why it exists.
The self-test dies with an access violation the moment thumbnails are asked
for, and the enumeration without them is clean. GDI and DWM can fault on a
window the compositor is tearing down, so the only way to know which source and
which call did it — here or on a user's machine — is a checkpoint on the wire
before each call, behind OMNIDISC_CAPTURE_TRACE.
The first CI run aborted with STATUS_HEAP_CORRUPTION and told us nothing else,
because libtest buffers a test's output and drops it when the process dies.
Running without the harness puts every checkpoint on the wire before the next
call, so the log names the step, and keeps the sequence on one thread so an
apartment-threading bug is not mistaken for a memory one.
The field is title, not name, and SourceId is Clone but not Copy — I wrote the
test against a guessed shape and the Windows job caught it. Formatting too: the
file compiles to nothing off Windows, so rustfmt was the only local gate and I
had skipped it.