35 Commits
Author SHA1 Message Date
Bear Code 40a07f8e61 fix(appimage): bundle GStreamer plugins with media libraries (#97) 2026-11-02 19:51:59 +06:00
IGECT 2ace22bc48 fix(flatpak): align PR template checkboxes with flathub submission-checker regex 2026-11-01 23:55:44 +06:00
IGECT bc5f9387e8 build(flatpak): add interactive flathub submission wizard script 2026-11-01 23:50:06 +06:00
IGECT 7c559e3be6 chore(release): update security policy automation and supported versions 2026-10-24 17:44:31 +06:00
IGECT a9f3bc0662 chore(release): bump version to v0.13.0, update changelog and documentation suite 2026-10-22 00:41:55 +06:00
IGECT c92f08963c chore(web): purge redundant landing page mirrors, legacy archives, and redirect stubs
- Remove duplicate preview.html (identical to index.html)
- Archive and remove obsolete index.legacy.html
- Remove legacy client-side redirect folders (superpowers/, why/, faq/, features/)
- Update scripts/bump-version.js, scripts/lint-ui.mjs, and AGENTS.md to reference only index.html
2026-10-20 07:49:37 +06:00
IGECT 206a05e93a chore(ui-lint): add lintapple route and docs checks 2026-10-12 22:22:53 +06:00
IGECT 903fcf5bdc fix(landing): resolve full audit findings on the main GitHub Pages page
Broken links & assets:
- omniget-cli download pointed at omniget-cli-windows-x64.zip, which
  does not exist in any release; now uses the real asset name
- All asset download buttons now pin releases/tag/v0.11.0/download/
  instead of releases/latest/download/ plus a versioned filename, so
  they keep resolving after the next release; bump-version.js updated
  to rewrite the tag and the version inside asset names in one pass
- Download menu completed against the actual v0.11.0 assets: Windows
  MSI, macOS CLI (both arches), arm64 deb, aarch64 AppImage, x86_64
  and aarch64 RPM, Linux CLI; hero OS detection now picks the right
  binary for ARM Macs and ARM Linux

Facts (source-verified):
- Course platforms: 36 everywhere (was 37; "and 29 others" -> 28)
- Tools hub: 158 tools across 25 categories (was "37 offline tools
  across 7 domains", which is the MCP tool count, and the section
  below it lists 8 domains)
- MCP bridge port range: 47720..47729 (local_bridge.rs PORT_RANGE is
  end-exclusive; was ..47730)
- MCP clients: add Claude Desktop and Codex (mcp.rs client_snippets)

SEO / structured data:
- JSON-LD downloadUrl #downloads -> GitHub releases (anchor died with
  the old SPA); FAQ /faq/ -> #faq; Release Notes -> docs/changelog/
- sitemap.xml: dead SPA fragments (#downloads, #releasenotes) replaced
  with the real pages (all 7 docs routes plus llms.txt)
- index.legacy.html: robots noindex on the orphaned legacy page

UI / accessibility:
- Mobile: nav links collapse under 48rem (the pill nav used to
  overflow on small screens)
- prefers-reduced-motion: marquee, hero ASCII ripple, scroll tilt and
  smooth scrolling are disabled for users who ask for it
- :focus-visible outlines and a skip-to-content link added
- Marquee: real contributor links are no longer aria-hidden; only the
  duplicated loop halves are (static markup and JS re-render)
- Theme toggle repaints the ASCII canvas ink; FAQ xattr command is a
  real <code> element; stale "getomniget.com" CSS comment removed

Tests:
- Tier 1 root-page checks updated to the current single-scroll
  architecture with a fresh checksum contract, so e2e_verify passes
  57/57 again after being stuck at 55/57 since the SPA rewrite
2026-10-09 07:15:12 +06:00
IGECT 50422d16f2 fix(deps,linux): support apple silicon ffmpeg and prevent appimage egl crashes
- download native aarch64 ffmpeg/ffprobe binaries on apple silicon macos

- export WEBKIT_DISABLE_COMPOSITING_MODE=1 and check WAYLAND_DISPLAY in appimage

- pre-seed patched linuxdeploy-plugin-gtk in release ci workflow
2026-10-09 02:28:01 +06:00
IGECT 3cacbd2ed7 docs: update landing page, full doc suite, and release automation for v0.11.0 2026-10-06 23:00:44 +06:00
IGECT 55fe4b3f05 docs: modernize landing page and deploy full documentation suite 2026-10-06 00:26:18 +06:00
IGECT 9150d3f6c5 feat(plugins): repoint plugin registry and repository links to OpenSelena
- Update REGISTRY_URLS in plugins.rs to OpenSelena/omniget-plugins
- Update local deploy and shot scripts to OpenSelena plugin repositories
- Update Claude plugin repository and release doctor URLs
- Update rust-toolchain.toml and Homebrew workflow references
- Update plugin links and remove dead omnidisc-server link across English, Russian, Portuguese, and Chinese READMEs
- Update GitHub issue templates security and discussion links
2026-10-04 04:59:59 +06:00
Yahya Zekry f4c2f0df37 fix(appimage): set the GStreamer env in the AppRun hook, before exec
The in-process fallback added for this in main.rs loses nondeterministically:
WebKit initializes GStreamer very early, through GLib's cached getenv, so a
set_var() after main sometimes lands too late and the plugin scan misses the
system directories again (observed as intermittent 'appsink not found' and
media that refuses to start with no request ever made). Setting the variables
in the AppRun hook — which runs before exec — is deterministic. The hook also
points GST_PLUGIN_SCANNER at the system helper, silencing the 'External plugin
loader failed' warning and enabling out-of-process scanning. User-provided
GST_PLUGIN_PATH/GST_PLUGIN_SCANNER still win.
2026-10-01 06:51:15 +03:00
IGECT d4c71a309d fix(ci): increase smoke test timeout for slow Windows runners 2026-09-29 18:49:45 +06:00
IGECT d9ea9640ec feat(opennami): port standalone engine architecture with dual-engine fallback and anti-bot hardening 2026-09-28 22:35:17 +06:00
tonhowtf 6fbdae1e93 Merge pull request #304 from YahyaZekry/fix/appimage-gearlever
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.
2026-09-10 08:45:37 -03:00
tonhowtf 7a905ddf3c feat: 0.9.1 — Tools section, Apple-first UI, download engine rework, League on by default
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.
2026-09-05 11:46:51 -03:00
Yahya Zekry f4b7e0478e fix(pr): address review comments - license header, cache docs, readme 2026-09-03 16:20:56 +03:00
Yahya ZekryandClaude Opus 5 57b2095b92 fix(build): keep the patched AppImage plugin inside the project
Review feedback on #304.

The vendored linuxdeploy-plugin-gtk.sh carried no provenance, so nobody could
tell what was ours or rebase it onto a newer upstream. It now names the source
repo, the commit it was copied at, the MIT notice, and the three local hunks.

Copying it into ~/.cache/tauri also pinned our patched copy for every Tauri
project on the machine, forever, because the bundler only downloads the plugin
when the file is missing. Turning on bundle.useLocalToolsDir moves the tool
cache into src-tauri/target/.tauri instead, so the build touches nothing
outside the repo and `cargo clean` undoes it. The command grew past what
belongs in a package.json string, so it lives in scripts/linux/appimage.sh now
and says which plugin it installed.

README documents `pnpm tauri:appimage` next to the existing from-source build
flag rather than in a second place that would drift from it.

Also gates NO_STRIP on ubuntu, matching LDAI_UPDATE_INFORMATION right above it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-30 08:33:26 +03:00
Yahya Zekry a33f898451 fix(build): make AppImages installable via Gear Lever, fix bundling on Arch
- bump @tauri-apps/cli to ^2.11.4: tauri-bundler <=2.10 created absolute
  .desktop/.DirIcon symlinks in the AppDir; Gear Lever extracts with 7z,
  which turns absolute symlinks into dangling ones, finds no desktop
  entry and crashes on install (upstream fix: tauri#15596)
- add src-tauri/desktop.template (Categories=Network;FileTransfer;) and
  wire it for deb/rpm so the AppImage desktop entry is no longer missing
  Categories (AppImage bundling reuses the deb data generator)
- set NO_STRIP=1 when running linuxdeploy: its bundled strip predates
  .relr.dyn relocations and any strip failure aborts bundling on modern
  toolchains; also set it in release.yml for CI
- vendor a patched linuxdeploy-plugin-gtk.sh: skip copy_tree sources
  that don't exist and mkdir -p before writing loaders.cache — Arch's
  gdk-pixbuf pkg-config paths are stale (loaders built in), which made
  the GTK plugin exit 1 under set -e. Synced into ~/.cache/tauri/ by
  the new pnpm tauri:appimage script
2026-08-30 08:27:05 +03:00
tonhowtf 123fbaf70a feat(omnidisc): native chat, voice and screen share
Adds OmniDisc, a self-hosted chat/voice/screen-share surface inside OmniGet,
behind the `omnidisc.enabled` setting (off by default). The server it talks to
lives in its own repo; the wire contract is the new `omnidisc-proto` crate.

Client crates:
- `omnidisc-proto`: snowflakes with 10-day buckets, 64-bit permission bitfield
  and its resolution order, gateway opcodes and dispatch events, streaming
  policy, REST bodies. Shared verbatim with the server.
- `omnidisc-media`: the whole media path in Rust, because WKWebView has no
  getDisplayMedia and a webview cannot own the audio graph without stuttering.
  cpal capture/playback with a lock-free mic path, RNNoise, VAD, a mixer with
  per-participant gain and ducking, LiveKit as the SFU, ScreenCaptureKit
  capture feeding our own VideoToolbox session published pre-encoded, and a
  wgpu viewer in a pop-out window. Windows and Linux compile to typed
  "unsupported yet" stubs.
- `omnidisc-mls`: MLS (RFC 9420) via openmls for direct messages, per-file
  XChaCha20-Poly1305 in 1 MiB chunks, and the voice room key derived from the
  group epoch — never minted by the server.

App: 89 Tauri commands across auth, gateway, chat, voice, streaming, uploads,
devices and MLS; session tokens in the OS keyring and never exposed to the
webview; the `/omnidisc` route with a virtualized message list, composer,
friends, profiles, guild settings, search, pins and per-device fingerprints.

Also carries the settings and shell work that was already in progress in the
tree: the grouped settings sidebar, the platform-aware chrome, and the
i18n keys those introduced.
2026-08-27 22:40:40 -03:00
antonio 6ea785576f feat(B32): fila como write-ahead log, com migracao do recovery.json (#230)
Fecha o que ficou aberto na #217. Aquela PR entregava o modulo sem ligar nada;
o bloqueio declarado era "mudar todos os call sites e decidir a migracao".

Nenhum call site mudou. A API publica do recovery.rs continua igual
(init_from_disk, persist, remove, list, clear_all) e so o armazenamento por
baixo trocou. Era o caminho mais seguro e nao tinha sido tentado.

O formato anterior reescrevia o arquivo inteiro a cada mudanca, entao um crash
no meio da escrita podia levar a fila toda. Agora anexa uma linha com fsync por
registro: um crash so pode corromper o ultimo, e o decode_log descarta a linha
truncada e mantem o resto. Verificado com SIGKILL de verdade pelo
scripts/wal-kill9.py: 202 registros integros, exatamente 1 truncado.

Achado que so apareceu ao ligar: o Enqueued do WAL nao tinha `referer`, que
existe no RecoveryItem desde sempre. Migrar como estava teria descartado o
campo em silencio, e o download so falharia depois, no site que exige o header.
Campo adicionado em 6 pontos, com teste que reprova se ele parar de propagar.

A migracao do recovery.json roda uma vez, ordena por id (o JSON nao guardava
posicao, e inventar ordem embaralharia a fila de quem atualiza) e renomeia o
original para .json.migrated em vez de apagar.

A producao chama a mesma funcao que o teste exercita. Na primeira versao o
json_para_registros era usado so no teste e o codigo real reparseava por fora —
o portao de clippy pegou como dead_code, e o teste estaria provando algo que
ninguem executa.

609 testes, 0 falhando. Clippy 92, nenhum novo.
2026-07-29 16:06:07 -03:00
antonio 1df5f0e69f feat(B55): smoke test que sobe o app — a #209 automatizada (#224)
* feat(B55): smoke test que sobe o app, e teste de migracao do settings

O CI compilava nas quatro plataformas e nunca abriu o app uma vez. Foi por
essa fresta que a #209 entrou em `main`: o modo portatil do Windows foi
mergeado sem nunca ter criado uma janela. "Compila" e "abre" sao perguntas
diferentes, e so uma estava sendo feita.

scripts/smoke-test.mjs sobe o binario de verdade e exige a linha de janela
criada. Novo job `smoke` no CI em windows-latest e ubuntu-latest (xvfb), nos
dois modos: padrao e portatil.

O modo portatil e a #209 caso 1 automatizada: portable.txt ao lado do exe,
perfil de usuario limpo, e a exigencia de que nada apareca fora do diretorio
do app — mais <app>/data/webview no Windows.

Para isso o lib.rs ganhou duas coisas: a linha "[startup] main window
created" (a unica prova de que a janela subiu) e o OMNIGET_SMOKE_EXIT_MS,
que faz o app sair sozinho com 0 depois de provar que abriu.

Criterio de aceite verificado, nao presumido: com o set_var do OMNIGET_DATA_DIR
removido, o smoke reprova com "modo portatil escreveu no perfil do usuario" e
o caminho vazado no texto. Restaurado, volta verde nos dois modos.

Junto, o teste de migracao que a #220 nao trouxe: ela adicionou `accessibility`
ao AppSettings sem cobrir que um settings.json anterior ainda abre. O teste
serializa o default e remove a chave — a forma exata de um arquivo gravado
antes de o campo existir. Removendo o serde(default), ele reprova.

Workspace em 584 testes. Clippy: 92 warnings, nenhum novo.

* fix: modo portatil tambem vazava para o perfil no Linux

Achado pelo smoke test deste PR, na primeira vez que ele rodou. Em modo
portatil no Linux o app criava XDG_DATA_HOME/wtf.tonho.omniget no perfil do
usuario — a mesma #209, fora do Windows.

A causa: o redirecionamento do webview do B49 estava atras de cfg(windows).
O `data_directory` do Tauri nao tem cfg nenhum, e no wry ele alimenta
base_data_directory, base_cache_directory e o caminho dos cookies do
WebKitGTK. Sem ele, o WebKit escrevia no perfil mesmo com todo o resto do app
apontado para <app>/data.

macOS fica de fora de proposito: o wry nao le data_directory no WKWebView, e
incluir daria a impressao de cobrir um caso que nao esta coberto. Por isso o
smoke passava no macOS e reprovava no Linux.
2026-07-29 11:35:21 -03:00
antonio fd5632c412 feat: ligar o painel de causa raiz e as preferências de acessibilidade ao frontend (#220)
O motor de diagnóstico da onda C (root_cause.rs) existia sem nenhum chamador:
o comando diagnose_download_error o expõe e RootCauseHint traduz cada falha
em causa + botão de ação (importar cookies, tentar de novo, atualizar yt-dlp,
guia de PO token) nos itens com erro da fila.

O bloco accessibility existia no tipo TS e era lido no layout, mas não tinha
campo no Rust, UI nem efeito: agora persiste (AccessibilitySettings com serde
default, merge profundo preservado), tem toggles em Appearance e age via
tokens (reduce motion zera durações e converte spinners em pulso de opacidade;
reduce transparency remove o material translúcido).

De carona: labels sem controle no TelegramUploadModal viraram radiogroups com
aria-label (2 warnings a menos que a main), e o parser de --routes do harness
cortava valores com '=' (o shot do deep-link de settings saía errado).

13 chaves i18n novas propagadas nos 11 locales; disable_haptics ficou fora da
UI por não ter consumidor (honest settings).
2026-07-29 10:56:21 -03:00
antonio f6bd65aa51 B50-b: deduplicate the clippy baseline, one file per platform (#207)
* ci: deduplicate the clippy baseline and give every platform its own

B50-b. Two problems with the baseline that shipped yesterday.

Scope. The frozen number was 177 while the previously reported figure was
34/42/8/1 = 85, and that gap needed reconciling before trusting the gate. It is
not 90 extra warnings being blessed: 1+1+34+8+8+37+42+46 = 177 exactly, because
--all-targets compiles lib and lib-test and the same warning is emitted once per
target. Self-consistent, but the number lied and a single new warning showed up
as +2, which makes the report unreadable.

Warnings are now deduplicated by origin — file, line, column, lint — before
being tallied per crate and lint. 177 becomes 92 real warnings, and the injected
regression now reports ptr_arg 1 -> 2 instead of 2 -> 4.

Platform. One baseline covered Linux while the rust job runs on three operating
systems, so everything behind cfg(target_os = ...) was born outside the gate —
including all of portable mode, which is the next item. There is now one file
per platform and the check runs on all three legs. Linux and darwin turn out
identical, which is expected: almost all conditional code here is Windows-only,
and that is exactly where a single baseline would have hidden things.

A platform with no baseline yet does not fail. Failing someone over a file
nobody generated would be punishing the wrong person; instead the step prints
the exact JSON to commit, so the CI log is the source. The Windows baseline is
generated that way in this PR.

Gate re-proved after the change: injecting a &Vec<String> exits 1 naming the
lint, reverting exits 0.

Note for the record: pnpm check is at 109 warnings, not the 107 recorded
yesterday. The two new ones are a11y warnings in TelegramUploadModal.svelte from
#197, merged an hour ago. This branch touches no frontend file.

* ci: add the Windows clippy baseline, generated by this PR's own CI run

Produced by the windows-latest leg of run 30435429086, which printed it because
no baseline existed for win32 yet — the mechanism working as designed rather
than failing someone over a missing file.

It comes out identical to Linux and darwin: 92 warnings across 51 lints, zero
lints differing. Worth stating plainly, because it is not the result the item
predicted. Today the three platforms agree, and the per-platform split earns
nothing yet. It earns something the moment B49 lands, since portable mode is
entirely Windows-only code that a single Linux baseline would never have
covered.
2026-07-29 05:36:16 -03:00
antonio f46391c06a Wave 1: clippy baseline gate, Website field, Smart Speed and Voice Boost (#205)
* ci: turn clippy into a real gate via a committed baseline

B50. Clippy has been informational since CI landed, because the workspace
carries 177 inherited warnings and `-D warnings` would have failed every pull
request on day one. A gate that is red on day one is a gate everyone learns to
ignore, so it was left as log output only.

The baseline freezes what exists today and fails only on what is new. The
comparison key is `crate|lint`, deliberately without file or line: moving code
must not fail CI, only introducing a warning may.

Two things the first attempt got wrong, both now handled:

- The baseline is platform-specific. `#[cfg(target_os)]` means clippy sees
  different code on each OS, so a single file cannot describe all three. It is
  generated on Linux, the check runs on the ubuntu leg only, and the script
  refuses to compare across platforms rather than failing someone for a warning
  that only exists on their OS. Per-OS baselines are possible and are recorded
  as debt.
- My first baseline was generated on macOS and labelled linux by hand. The
  script now records `process.platform` itself, so that mistake cannot repeat.

Proved rather than assumed: injecting a `&Vec<String>` argument makes the check
fail naming `omniget_lib: clippy::ptr_arg 2 -> 4`, and reverting returns it to
`177 warnings, none new`. Both runs in a Debian container, matching CI.

* docs: put the Discord invite in the READMEs before it leaves the Website field

B51. The repository Website field points at a Discord invite. A Discord link
earns no search visibility and passes no authority, so the field is worth more
elsewhere — but the invite existed *only* there. All three READMEs mention
Discord solely as a feature (Discord presence, downloading a Discord link),
never as a way to reach the community.

Removing it from the field first would have deleted the community's entry
point. So it lands in the Contribute section of all three READMEs here, and the
field itself is repointed separately once this is on main.

There is no GitHub Pages site to point at, so the field goes to the releases
page: no SEO win is available without a real site, and sending visitors to the
download is the most useful thing left.

* feat(video): Smart Speed and Voice Boost for recorded lectures

B36. A two-hour recorded class carries twenty minutes of silence, and modules
recorded on different setups arrive at different volumes. Both are fixed with
filters ffmpeg already ships.

Voice Boost normalises to EBU R128 (-16 LUFS, -1.5 dBTP), the target podcast
apps use for speech, and copies the video stream untouched.

Smart Speed outputs *audio*, and that is a real constraint rather than a
shortcut. `silenceremove` drops audio samples without touching video PTS, so
applying it to an mp4 desynchronises picture and sound. Cutting both streams at
the same points needs `select`/`aselect` expressions, which is a different
order of magnitude — and the use case this comes from (Overcast) consumes
lectures as audio anyway. A test locks that decision in place so nobody
'improves' it into an mp4 later.

There is a preview before committing to a conversion: silencedetect measures
how much silence exists without writing a file, so the user sees the expected
saving and decides. The probe deliberately does not pass through the ffmpeg
allowlist — it needs `-f null`, and allowing `-f` would let the AI path pick an
arbitrary muxer to gain nothing. The probe is built entirely by the app from
constant arguments, and a test asserts both halves of that reasoning.

Inspired by Overcast (proprietary, no code read or copied — only the published
description of what Smart Speed and Voice Boost do).

7 new tests. 6 i18n keys across all 10 locales, translated.
2026-07-29 04:21:39 -03:00
tonhowtf a6522bba9e feat(remake): fase E — motion/espacamento/duracao tokenizados, foco visível no .btn corrigido, reduce sem transform, alvos no mínimo macOS, previews de tema atualizados 2026-07-28 21:23:19 -03:00
tonhowtf 88bd537401 feat(remake): primitivos v2 — camada compartilhada + rota /_kitchen-sink com todos os estados 2026-07-28 21:16:35 -03:00
tonhowtf 2bd663dc28 feat(remake): design system v2 — tokens HIG, accent único, tipografia System, AA nos 14 temas 2026-07-28 21:16:35 -03:00
tonhowtf 88fa504c60 chore(remake): baseline e harness de captura 2026-07-28 21:14:51 -03:00
Tonho f605e25a9c feat: implement cookie summary and blocklist management, enhance media detection and sniffer functionality 2026-04-13 23:03:03 -03:00
Tonho 905e23f653 feat: implement omniget scheme URL handling and deep link configuration 2026-04-13 16:03:44 -03:00
Tonho f288acaa83 feat: add version bumping script and i18n key generator 2026-04-13 15:39:10 -03:00
Tonho 36b7f1f197 feat: remove Flatpak validation workflow and preflight script 2026-02-20 09:16:48 -03:00
Tonho 07e50e0f40 feat: add Flatpak preflight validation script for build checks 2026-02-19 23:37:47 -03:00