From 0ede8491b0b4ee9dd78c319fe60b58697154f2fb Mon Sep 17 00:00:00 2001 From: Dmitry Beskov <43372966+besdar@users.noreply.github.com> Date: Wed, 6 May 2026 23:28:41 +0300 Subject: [PATCH 1/2] Add AI skill for Flatpak packaging --- README.rst | 9 + docs/tips-and-tricks.rst | 9 + skills/flatpak-packaging/SKILL.md | 86 ++++++++ .../references/build-debug.md | 155 ++++++++++++++ .../distribution-and-repositories.md | 139 +++++++++++++ .../references/extensions.md | 156 ++++++++++++++ .../references/framework-notes.md | 181 ++++++++++++++++ .../references/manifest-and-sources.md | 127 ++++++++++++ .../references/runtimes-and-conventions.md | 144 +++++++++++++ .../references/sandbox-permissions.md | 194 ++++++++++++++++++ 10 files changed, 1200 insertions(+) create mode 100644 skills/flatpak-packaging/SKILL.md create mode 100644 skills/flatpak-packaging/references/build-debug.md create mode 100644 skills/flatpak-packaging/references/distribution-and-repositories.md create mode 100644 skills/flatpak-packaging/references/extensions.md create mode 100644 skills/flatpak-packaging/references/framework-notes.md create mode 100644 skills/flatpak-packaging/references/manifest-and-sources.md create mode 100644 skills/flatpak-packaging/references/runtimes-and-conventions.md create mode 100644 skills/flatpak-packaging/references/sandbox-permissions.md diff --git a/README.rst b/README.rst index c1db3400..d64f2d20 100644 --- a/README.rst +++ b/README.rst @@ -21,6 +21,15 @@ Then install the dependencies with **pip**:: pip install -r requirements.txt +AI Assistant Skill +------------------ + +This repository also includes optional AI assistant guidance for Flatpak +packaging in ``skills/flatpak-packaging``. Compatible assistants can use it to +help draft manifests, choose runtimes, review sandbox permissions, and debug +packaging issues. It is assistant metadata only; Flatpak and the documentation +build do not require it. + Build the Documentation ----------------------- diff --git a/docs/tips-and-tricks.rst b/docs/tips-and-tricks.rst index cae3e3e0..6573a958 100644 --- a/docs/tips-and-tricks.rst +++ b/docs/tips-and-tricks.rst @@ -191,3 +191,12 @@ with contents like:: Then after a ``systemctl --user daemon-reload``, those ``systemd.resource-control(5)`` parameters will apply to all instances of that app. + +Flatpak packaging AI assistant skill +------------------------------------ + +You can also find the optional AI assistant guidance for Flatpak packaging in +https://github.com/flatpak/flatpak-docs/tree/master/skills. Compatible assistants +can use it as context for tasks such as writing manifests, choosing runtimes, +reviewing sandbox permissions, and debugging packaging issues. It is assistant +metadata only; Flatpak itself does not read or require it. diff --git a/skills/flatpak-packaging/SKILL.md b/skills/flatpak-packaging/SKILL.md new file mode 100644 index 00000000..2b554eba --- /dev/null +++ b/skills/flatpak-packaging/SKILL.md @@ -0,0 +1,86 @@ +--- +name: flatpak-packaging +description: Build, configure, debug, and publish Flatpak applications with flatpak-builder manifests. Use this skill when the user asks you to create or edit Flatpak YAML/JSON manifests, choose runtimes and SDKs, configure finish-args sandbox permissions, add module sources or dependencies, package Python/Electron/.NET/Qt apps, build/install/test with flatpak-builder, inspect or debug sandboxes, create bundles or repositories, write .flatpakref/.flatpakrepo files, or advise on Flatpak app IDs, desktop files, AppStream metadata, extensions, and Flathub-style packaging. +--- + +# Flatpak Packaging + +## Overview + +Use this skill to turn an application into a Flatpak package or to maintain an existing Flatpak manifest. Prefer the project's own build system and upstream metadata, keep sandbox permissions minimal, and verify with `flatpak-builder` whenever the local environment has Flatpak tooling installed. + +## First Moves + +1. Inspect the project before writing a manifest: application ID, build system, runtime/toolkit, executable command, desktop file, MetaInfo/AppStream file, icons, network/filesystem/device needs, and distribution target. +2. Check for an existing manifest such as `*.yml`, `*.yaml`, `*.json`, or Flathub packaging. Preserve local style unless it conflicts with Flatpak requirements. +3. Choose the narrowest runtime that already contains the app's major toolkit. Use Freedesktop for generic apps, GNOME for GNOME/GTK apps, KDE for Qt/KDE apps, and matching SDK branches for builds. +4. Put the main app module last unless a frequently changing independent module should intentionally be last to improve cache reuse. +5. Pin downloaded sources with checksums and Git sources with exact commits. Avoid branch-only Git sources for reproducible builds. +6. Prefer portals and XDG base directories over broad filesystem or D-Bus permissions. + +## Reference Routing + +- Read `references/manifest-and-sources.md` when creating or changing manifest structure, modules, build systems, cleanup, source types, or bundled dependencies. +- Read `references/runtimes-and-conventions.md` when choosing runtime/SDK branches or checking app IDs, desktop files, icons, MetaInfo, exported files, D-Bus service files, MIME files, and XDG paths. +- Read `references/sandbox-permissions.md` when deciding `finish-args`, reducing permissions, using portals, debugging D-Bus access, granting filesystem/device access, or using conditional permissions. +- Read `references/build-debug.md` when building, installing locally, entering a sandbox, using GDB/strace/valgrind/perf, auditing bus traffic, testing portal permissions, or troubleshooting a failed build/run. +- Read `references/framework-notes.md` for Python, Electron, .NET, or Qt-specific manifest patterns and generator tooling. +- Read `references/distribution-and-repositories.md` when creating bundles, repositories, `.flatpakref` or `.flatpakrepo` files, signing, hosting, or publishing updates. +- Read `references/extensions.md` when defining extension points, consuming SDK/runtime extensions, building app plugins/add-ons, or using bundled extensions. + +## Core Workflow + +1. Create or edit the manifest: + +```yaml +id: org.example.App +runtime: org.freedesktop.Platform +runtime-version: '25.08' +sdk: org.freedesktop.Sdk +command: app-command +finish-args: + - --share=ipc + - --socket=fallback-x11 + - --socket=wayland + - --device=dri +modules: + - name: app + buildsystem: meson + sources: + - type: git + url: https://example.org/app.git + tag: v1.0.0 + commit: 0123456789abcdef0123456789abcdef01234567 +``` + +2. Build and install locally: + +```bash +flatpak remote-add --if-not-exists --user flathub https://dl.flathub.org/repo/flathub.flatpakrepo +flatpak-builder --force-clean --user --install-deps-from=flathub --repo=repo --install builddir org.example.App.yml +flatpak run org.example.App +``` + +3. Validate exported desktop metadata: + +```bash +desktop-file-validate path/to/org.example.App.desktop +appstreamcli validate --explain path/to/org.example.App.metainfo.xml +``` + +4. Debug inside the sandbox when runtime behavior differs from the host: + +```bash +flatpak run --command=sh --devel --filesystem="$(pwd)" org.example.App +flatpak-builder --run builddir org.example.App.yml sh +flatpak run --log-session-bus org.example.App +``` + +5. Package for distribution only after the app installs, launches, and has correct metadata. Repositories are preferred for updates; single-file bundles are for direct sharing or removable media. + +## Permission Stance + +- Treat `finish-args` as static packaging policy; variables are not expanded inside these arguments. +- Avoid `--filesystem=home`, `--filesystem=host`, `--socket=session-bus`, `--socket=system-bus`, and `--device=all` unless the app is a development/system tool or no narrower permission works. +- For GUI apps that support Wayland, use `--socket=wayland` plus `--socket=fallback-x11`; for X11-only apps, use `--socket=x11` and usually `--share=ipc`. +- Use `:ro` for read-only filesystem needs, XDG directory grants for specific user folders, and `--persist=DIR` for legacy hardcoded dot-directories. diff --git a/skills/flatpak-packaging/references/build-debug.md b/skills/flatpak-packaging/references/build-debug.md new file mode 100644 index 00000000..50a834a2 --- /dev/null +++ b/skills/flatpak-packaging/references/build-debug.md @@ -0,0 +1,155 @@ +# Build and Debug + +Related public docs: [Building your first Flatpak](https://docs.flatpak.org/en/latest/first-build.html), [Building Introduction](https://docs.flatpak.org/en/latest/building-introduction.html), [Flatpak Builder](https://docs.flatpak.org/en/latest/flatpak-builder.html), [Debugging](https://docs.flatpak.org/en/latest/debugging.html), [Tips and Tricks](https://docs.flatpak.org/en/latest/tips-and-tricks.html), [Using Flatpak](https://docs.flatpak.org/en/latest/using-flatpak.html). + +## Setup and build + +Install `flatpak` and `flatpak-builder` from the distribution or from Flathub. For development, add Flathub user-wide: + +```bash +flatpak remote-add --if-not-exists --user flathub https://dl.flathub.org/repo/flathub.flatpakrepo +``` + +Build and install a manifest locally: + +```bash +flatpak-builder --force-clean --user --install-deps-from=flathub --repo=repo --install builddir org.example.App.yml +flatpak run org.example.App +``` + +What `flatpak-builder` does: + +- Creates the build directory. +- Downloads and verifies module sources. +- Builds and installs each module into the app prefix. +- Applies finish/sandbox metadata. +- Exports the result to a repository when `--repo` is used. + +Useful variants: + +```bash +# Export to a local repo without installing. +flatpak-builder --force-clean --user --install-deps-from=flathub --repo=repo builddir org.example.App.yml + +# Install directly without a separate repo step. +flatpak-builder --user --install builddir org.example.App.yml + +# Sign exported commits. +flatpak-builder --gpg-sign= --repo=repo builddir org.example.App.yml +``` + +Use `--gpg-homedir` if the signing key lives outside the default GPG home. + +## Run commands inside the sandbox + +Use an installed app sandbox: + +```bash +flatpak run --command=sh --devel --filesystem="$(pwd)" org.example.App +``` + +Use an uninstalled build tree: + +```bash +flatpak-builder --run builddir org.example.App.yml sh +flatpak-builder --run builddir org.example.App.yml /app/bin/app-command +``` + +`--devel` uses the SDK as runtime and adjusts sandbox setup for debugging. + +## Debug symbols and tools + +Install debug materials first: + +```bash +flatpak install --include-sdk --include-debug org.example.App +``` + +For graphics stack crashes, identify the runtime branch and install GL debug extensions: + +```bash +flatpak info --show-runtime org.example.App +flatpak install org.freedesktop.Platform.{GL,GL32}.Debug.default//24.08 +``` + +Inside a debug shell: + +```bash +gdb /app/bin/app-command +gdb --args /app/bin/app-command --some-arg +valgrind --leak-check=full --track-origins=yes --show-leak-kinds=all --log-file=valgrind.log /app/bin/app-command +strace -e trace=openat,read -o strace.log -f /app/bin/app-command +``` + +For `perf`, grant `/sys` and a writable output path: + +```bash +flatpak run --command=perf --filesystem=/sys --filesystem="$(pwd)" --devel org.example.App record -v -- +``` + +## Coredumps + +If systemd coredumps are enabled: + +```bash +coredumpctl list +flatpak-coredumpctl -m org.example.App +(gdb) bt full +``` + +## Multiple shells in one sandbox + +List running sandbox instances and enter one: + +```bash +flatpak ps +flatpak enter /bin/bash +``` + +Use this when one shell runs the app and another shell attaches a debugger. + +## Permissions while debugging + +Temporarily add runtime permissions to a debug run rather than broadening the manifest: + +```bash +flatpak run --devel --command=sh --system-talk-name=org.freedesktop.login1 org.example.App +``` + +Inspect and reset portal permissions: + +```bash +flatpak permission-show org.example.App +flatpak permission-reset org.example.App +``` + +See running apps and stop one: + +```bash +flatpak ps +flatpak kill org.example.App +``` + +## D-Bus audit + +Do not grant `--socket=session-bus` or `--socket=system-bus` when auditing; those disable the useful filtering. + +```bash +flatpak run --log-session-bus org.example.App +flatpak run --log-session-bus org.example.App | grep '(required 1)' +flatpak run --log-system-bus --system-talk-name=org.example.Placeholder org.example.App +``` + +Translate observed names into narrow `--talk-name=` or `--system-talk-name=` grants only when a portal is not appropriate. + +## Test against runtimes + +For testing only: + +```bash +flatpak run --runtime-version=master org.example.App +flatpak run --runtime=org.gnome.Sdk org.example.App +flatpak run -d org.example.App +``` + +Do not treat success on an ABI-incompatible runtime as supported behavior. diff --git a/skills/flatpak-packaging/references/distribution-and-repositories.md b/skills/flatpak-packaging/references/distribution-and-repositories.md new file mode 100644 index 00000000..50baf38c --- /dev/null +++ b/skills/flatpak-packaging/references/distribution-and-repositories.md @@ -0,0 +1,139 @@ +# Distribution and Repositories + +Related public docs: [Publishing](https://docs.flatpak.org/en/latest/publishing.html), [Repositories](https://docs.flatpak.org/en/latest/repositories.html), [Hosting a repository](https://docs.flatpak.org/en/latest/hosting-a-repository.html), [Single-file bundles](https://docs.flatpak.org/en/latest/single-file-bundles.html), [Flatpak Builder](https://docs.flatpak.org/en/latest/flatpak-builder.html). + +## Choose distribution mode + +Prefer a Flatpak repository for normal distribution because repositories support updates and deltas. Use single-file bundles for direct downloads, removable media, email attachments, or testing. + +Flathub is the common public hosting route. Self-hosted repositories are possible but require signing, HTTP hosting, summary updates, and operational care. + +## Export to a repository + +```bash +flatpak-builder --force-clean --user --install-deps-from=flathub --repo=repo builddir org.example.App.yml +``` + +If `repo` does not exist, `flatpak-builder` creates it. Reusing the same `--repo` path adds new commits/versions and can host multiple refs. + +Sign repository commits: + +```bash +flatpak-builder --gpg-sign= --repo=repo builddir org.example.App.yml +flatpak build-update-repo --gpg-sign= --generate-static-deltas repo +``` + +Every commit in a production repository should be signed. Avoid unsigned repositories; if unavoidable for local testing, adding them needs `--no-gpg-verify`. + +Generate static deltas to improve download speed: + +```bash +flatpak build-update-repo --generate-static-deltas repo +``` + +Use HTTP keep-alive when hosting because repositories can require many HTTP requests. + +## Add and test a local repository + +```bash +flatpak remote-add --user --no-gpg-verify local-test repo +flatpak install --user local-test org.example.App +flatpak run org.example.App +flatpak update +``` + +For signed repos, omit `--no-gpg-verify` and provide the GPG key through repo metadata. + +## .flatpakrepo + +A `.flatpakrepo` file lets users add a repository: + +```ini +[Flatpak Repo] +Title=Example Repo +Url=https://example.org/repo/ +Homepage=https://example.org/ +Comment=Example Flatpak repository +Description=Example Flatpak repository +Icon=https://example.org/logo.svg +GPGKey= +``` + +Generate the base64 GPG key: + +```bash +base64 --wrap=0 < key.gpg +``` + +Users can add it: + +```bash +flatpak remote-add --if-not-exists example https://example.org/example.flatpakrepo +``` + +## .flatpakref + +A `.flatpakref` file points to one app in a repository and can install the remote if needed: + +```ini +[Flatpak Ref] +Name=org.example.App +Branch=stable +Title=Example App +Url=https://example.org/repo/ +RuntimeRepo=https://dl.flathub.org/repo/flathub.flatpakrepo +IsRuntime=false +GPGKey= +``` + +Install: + +```bash +flatpak install https://example.org/org.example.App.flatpakref +flatpak install org.example.App.flatpakref +``` + +## Single-file bundles + +Create a bundle from a repository: + +```bash +flatpak build-bundle repo example.flatpak org.example.App --runtime-repo=https://flathub.org/repo/flathub.flatpakrepo +``` + +Install directly: + +```bash +flatpak install example.flatpak +``` + +Import into another repository: + +```bash +flatpak build-import-bundle other-repo example.flatpak +``` + +Bundles do not include dependencies or AppStream data. For offline distribution of apps plus dependencies, prefer Flatpak's USB/export workflows over standalone bundles. + +## Publishing updates + +Adding a new version to a repository makes it available to users. GUI software centers can check automatically; CLI users run: + +```bash +flatpak update +``` + +Repositories store version history efficiently, so clients download only changed data when deltas are available. + +## Hosting notes + +For static hosting such as GitLab/GitHub Pages: + +- Build in CI with a Flatpak-capable image. +- Add Flathub or another runtime remote before building. +- Import/sign GPG keys in CI securely. +- Run `flatpak-builder` with `--repo=repo`. +- Run `flatpak build-update-repo --generate-static-deltas --prune repo`. +- Publish the `repo/` directory as static site content. + +Flathub uses `flat-manager`; self-hosting does not have to, but large production repositories benefit from purpose-built tooling. diff --git a/skills/flatpak-packaging/references/extensions.md b/skills/flatpak-packaging/references/extensions.md new file mode 100644 index 00000000..5aefaafd --- /dev/null +++ b/skills/flatpak-packaging/references/extensions.md @@ -0,0 +1,156 @@ +# Extensions + +Related public docs: [Dependencies](https://docs.flatpak.org/en/latest/dependencies.html), [Extensions](https://docs.flatpak.org/en/latest/extension.html), [Available Runtimes](https://docs.flatpak.org/en/latest/available-runtimes.html), [Requirements & Conventions](https://docs.flatpak.org/en/latest/conventions.html). + +## When to use extensions + +Extensions let runtimes or apps define mount points for optional content. Use them for plugins, add-ons, themes, debug symbols, locales, sources, graphics drivers, SDK toolchains, or optional app functionality. + +Flatpak Builder automatically creates `.Debug` and `.Locale` extensions unless disabled. `.Sources` is produced when using `--bundle-sources`; do not define these manually for ordinary apps. + +## Define an app extension point + +Use `add-extensions` in the app manifest. Extension IDs must start with the extension point prefix. + +```yaml +id: org.example.App +runtime: org.gnome.Platform +runtime-version: '48' +sdk: org.gnome.Sdk +command: app +add-extensions: + org.example.App.Plugin: + version: '1.0' + directory: plugins + add-ld-path: lib + merge-dirs: plug-ins;help + subdirectories: true + no-autodownload: true + autodelete: true +cleanup-commands: + - mkdir -p ${FLATPAK_DEST}/plugins +``` + +Important properties: + +- `version`: branch used for matching extension packages; use `versions` for multiple accepted branches. +- `directory`: path relative to `/app` for app extension points or `/usr` for runtime extension points. +- `subdirectories: true`: mount multiple extensions under the same directory. +- `add-ld-path`: add extension library path. +- `merge-dirs`: merge named subdirectories across extensions. +- `no-autodownload: true`: avoid installing every extension automatically. +- `autodelete: true`: remove extensions when the parent app is removed. + +Ensure the target directory exists in the final app, often with `cleanup-commands` or `post-install`. + +There is no extension property that extends `PATH`; set wrappers or environment/build options explicitly. + +## Load existing runtime or SDK extensions + +Some extensions are provided by runtimes, such as ffmpeg, GL, i386 compatibility, TeXLive, Java, Go, Node, or .NET SDK extensions. Match extension branch to the base runtime branch. + +Find base branch for derived runtimes: + +```bash +flatpak remote-info flathub -m org.kde.Platform//5.15-24.08 | grep -A 5 -F '[Extension org.freedesktop.Platform.GL]' +flatpak remote-info flathub -m org.gnome.Sdk//48 | grep -A 5 -F '[Extension org.freedesktop.Sdk.Extension]' +``` + +Load an existing runtime extension at app runtime: + +```yaml +add-extensions: + org.freedesktop.Platform.ffmpeg-full: + version: '24.08' + directory: lib/ffmpeg + add-ld-path: . +cleanup-commands: + - mkdir -p ${FLATPAK_DEST}/lib/ffmpeg +``` + +Use `inherit-extensions` to inherit extension points or extensions from a parent runtime or base: + +```yaml +inherit-extensions: + - org.freedesktop.Platform.GL32 + - org.freedesktop.Platform.ffmpeg-full +``` + +Use `sdk-extensions` for build-time SDK extensions: + +```yaml +sdk-extensions: + - org.freedesktop.Sdk.Extension.node18 +build-options: + append-path: /usr/lib/sdk/node18/bin +``` + +Use `add-build-extensions` when a build dependency is itself available as an extension point in the runtime. + +## Build an extension manifest + +For a separately shipped plugin/add-on: + +```yaml +id: org.example.App.Plugin.Foo +branch: '1.0' +runtime: org.example.App +runtime-version: stable +sdk: org.gnome.Sdk//48 +build-extension: true +separate-locales: false +build-options: + prefix: /app/plugins/foo + prepend-path: /app/plugins/foo/bin + prepend-pkg-config-path: /app/plugins/foo/lib/pkgconfig + prepend-ld-library-path: /app/plugins/foo/lib +modules: + - name: foo + buildsystem: simple + build-commands: + - install -Dm644 org.example.App.Plugin.Foo.metainfo.xml -t ${FLATPAK_DEST}/share/metainfo + - + sources: + - type: archive + url: https://example.org/foo.tar.gz + sha256: +``` + +Rules: + +- `id` must use the extension point prefix. +- `branch` must match the extension point `version`. +- `runtime` is the app/runtime that defines the extension point. +- `runtime-version` is the parent branch, often `stable` or `beta` for apps. +- `sdk` should match the SDK used to build the parent runtime/app. +- Use `build-extension: true`. +- Provide MetaInfo with component type `addon` for store discoverability. + +## Bundled extensions + +Use `bundle: true` to export an extension from the app manifest itself: + +```yaml +add-extensions: + org.example.App.Codecs: + directory: extensions/codecs + subdirectories: true + no-autodownload: true + autodelete: true + org.example.App.Codecs.Pack1: + directory: extensions/codecs/pack1 + bundle: true + no-autodownload: true + autodelete: true +``` + +The contents of each `directory` are exported into that extension. + +## Inspect loaded extensions + +Inside a running Flatpak, inspect `/.flatpak-info` and look at the `Instance` group keys: + +- `app-extensions` +- `runtime-extensions` + +Use this when an extension is installed but not mounted; check branch, extension point name, directory existence, conditionals, and ID prefix. diff --git a/skills/flatpak-packaging/references/framework-notes.md b/skills/flatpak-packaging/references/framework-notes.md new file mode 100644 index 00000000..d72f178e --- /dev/null +++ b/skills/flatpak-packaging/references/framework-notes.md @@ -0,0 +1,181 @@ +# Framework Notes + +Related public docs: [Python](https://docs.flatpak.org/en/latest/python.html), [Electron](https://docs.flatpak.org/en/latest/electron.html), [Dotnet](https://docs.flatpak.org/en/latest/dotnet.html), [Qt](https://docs.flatpak.org/en/latest/qt.html). + +## Python + +If the project uses Meson, CMake, or Autotools, use the normal buildsystem. For Setuptools/pip-style projects, use `buildsystem: simple`: + +```yaml +- name: python-dep + buildsystem: simple + build-commands: + - pip3 install --prefix=/app --no-deps . + sources: + - type: archive + url: https://files.pythonhosted.org/packages/source/p/pkg/pkg-1.0.tar.gz + sha256: +``` + +Use `--prefix=/app`; otherwise pip may try to install under read-only `/usr`. + +For multiple Python dependencies, prefer `flatpak-pip-generator` from `flatpak-builder-tools`: + +```bash +python3 flatpak-pip-generator requests +python3 flatpak-pip-generator --requirements-file=requirements.txt +``` + +Include the generated JSON in the manifest: + +```yaml +modules: + - python3-requests.json + - name: app + buildsystem: meson + sources: [...] +``` + +## Electron + +Use Freedesktop runtime/SDK and the Electron BaseApp unless there is a specific reason not to: + +```yaml +id: org.example.ElectronApp +runtime: org.freedesktop.Platform +runtime-version: '24.08' +sdk: org.freedesktop.Sdk +base: org.electronjs.Electron2.BaseApp +base-version: '24.08' +sdk-extensions: + - org.freedesktop.Sdk.Extension.node18 +build-options: + append-path: /usr/lib/sdk/node18/bin +command: run.sh +``` + +Common Electron permissions: + +```yaml +finish-args: + - --share=ipc + - --device=dri + - --socket=x11 + - --socket=pulseaudio + - --share=network + - --env=ELECTRON_TRASH=gio +``` + +Wayland support can be enabled with `--socket=wayland` and `--socket=fallback-x11`, but the docs treat native Electron Wayland as experimental; default to X11/Xwayland unless the app and Electron version are known to be stable on Wayland. + +Set the desktop file name in `package.json`: + +```json +{ + "desktopName": "org.example.ElectronApp.desktop" +} +``` + +For binary repacks, use the BaseApp's `patch-desktop-filename` on `resources/app.asar`. + +Bundle NPM/Yarn dependencies with the Node generator from `flatpak-builder-tools`. It requires `package-lock.json` or `yarn.lock`: + +```bash +npm install --package-lock-only +flatpak-node-generator npm package-lock.json +``` + +Then include the generated source file: + +```yaml +sources: + - generated-sources.json +``` + +Typical wrapper: + +```yaml +- type: script + dest-filename: run.sh + commands: + - zypak-wrapper /app/main/electron-app "$@" +``` + +Build offline by setting cache paths and `npm_config_offline: 'true'`. If `electron-builder` tries to fetch AppImage or other Linux targets, prefer a build-time `jq` edit to set target `dir`. + +Electron notifications use libnotify; modern libnotify uses the notification portal, so `--talk-name=org.freedesktop.Notifications` is often unnecessary. + +## .NET + +Use a Linux-compatible desktop framework such as Avalonia UI, Uno Platform, Eto, GTKSharp, or Gir.Core. Use the .NET SDK extension and generator from `flatpak-builder-tools`. + +Skeleton: + +```yaml +id: org.example.DotnetApp +runtime: org.freedesktop.Platform +runtime-version: '24.08' +sdk: org.freedesktop.Sdk +sdk-extensions: + - org.freedesktop.Sdk.Extension.dotnet8 +build-options: + prepend-path: /usr/lib/sdk/dotnet8/bin + append-ld-library-path: /usr/lib/sdk/dotnet8/lib + prepend-pkg-config-path: /usr/lib/sdk/dotnet8/lib/pkgconfig +command: ExampleApp +finish-args: + - --device=dri + - --socket=x11 + - --share=ipc + - --env=DOTNET_ROOT=/app/lib/dotnet +modules: + - name: dotnet + buildsystem: simple + build-commands: + - /usr/lib/sdk/dotnet8/bin/install.sh + - name: app + buildsystem: simple + sources: + - type: git + url: https://example.org/app.git + - ./nuget-sources.json + build-commands: + - dotnet publish ExampleApp.csproj -c Release --no-self-contained --source ./nuget-sources + - mkdir -p ${FLATPAK_DEST}/bin + - cp -r bin/Release/net8.0/publish/* ${FLATPAK_DEST}/bin +``` + +Generate NuGet sources after downloading build deps: + +```bash +flatpak-builder build-dir --user --install-deps-from=flathub --download-only org.example.DotnetApp.yml +python3 flatpak-dotnet-generator.py --dotnet 8 --freedesktop 24.08 nuget-sources.json app/ExampleApp.csproj +``` + +## Qt + +Use KDE runtime/SDK for most Qt/KDE apps: + +```yaml +id: org.example.QtApp +runtime: org.kde.Platform +runtime-version: '6.9' +sdk: org.kde.Sdk +command: qt-app +finish-args: + - --share=ipc + - --socket=fallback-x11 + - --socket=wayland + - --device=dri +modules: + - name: qt-app + buildsystem: cmake-ninja + config-opts: + - -DCMAKE_BUILD_TYPE=RelWithDebInfo + sources: + - type: archive + url: https://example.org/qt-app.tar.gz + sha256: +``` + +If the KDE runtime is too broad or missing needed pieces, use Freedesktop as a base and bundle the Qt parts explicitly, but prefer KDE runtime for ordinary Qt apps. diff --git a/skills/flatpak-packaging/references/manifest-and-sources.md b/skills/flatpak-packaging/references/manifest-and-sources.md new file mode 100644 index 00000000..85beb0bb --- /dev/null +++ b/skills/flatpak-packaging/references/manifest-and-sources.md @@ -0,0 +1,127 @@ +# Manifest and Sources + +Related public docs: [Manifests](https://docs.flatpak.org/en/latest/manifests.html), [Module Sources](https://docs.flatpak.org/en/latest/module-sources.html), [Dependencies](https://docs.flatpak.org/en/latest/dependencies.html), [Building your first Flatpak](https://docs.flatpak.org/en/latest/first-build.html). + +## Manifest essentials + +A Flatpak manifest is JSON or YAML consumed by `flatpak-builder`. Name the file after the app ID, for example `org.example.App.yml`. + +Required or common top-level keys: + +- `id`: unique app ID in reverse-DNS style. +- `runtime`: runtime ID, such as `org.freedesktop.Platform`, `org.gnome.Platform`, or `org.kde.Platform`. +- `runtime-version`: branch of the runtime, quoted when numeric-looking. +- `sdk`: matching SDK, usually the runtime ID with `.Sdk`. +- `command`: executable in `/app/bin` (or otherwise on PATH inside the sandbox). +- `finish-args`: sandbox permissions applied during build finish. +- `modules`: ordered list of dependencies and the app itself. +- `sdk-extensions`, `build-options`, `cleanup`, `cleanup-commands`, `rename-*`, `add-extensions`: common optional keys. + +Minimal example: + +```yaml +id: org.example.App +runtime: org.freedesktop.Platform +runtime-version: '25.08' +sdk: org.freedesktop.Sdk +command: app +modules: + - name: app + buildsystem: simple + build-commands: + - install -Dm755 app.sh /app/bin/app + sources: + - type: script + dest-filename: app.sh + commands: + - echo "Hello from a sandbox" +``` + +## Modules + +Modules are built in manifest order. If a module changes, that module and later modules are rebuilt from cache. Put stable dependencies first and the main app module last unless a frequently changing independent module should be last. + +Use the native `buildsystem` when available: + +- `meson`: prefer for Meson projects; add `builddir: true` when needed. +- `cmake-ninja`: prefer over hand-written CMake commands. +- `cmake`, `autotools`, `qmake`: use when the upstream build system matches. +- `simple`: use for custom installs, binary repackaging, wrapper scripts, generated sources, or build systems not covered by flatpak-builder. + +Avoid replacing a supported build system with `simple` unless the project genuinely needs custom commands. The supported build systems set prefixes, libdirs, build/install commands, and test hooks correctly. + +Common module keys: + +- `name`: local module name. +- `buildsystem`: build driver. +- `config-opts`: build configuration options. +- `build-commands`: shell commands for `simple` modules. +- `make-args`, `make-install-args`, `no-autogen`, `builddir`, `subdir`: build customization. +- `sources`: sources applied before build. +- `modules`: nested modules, useful when representing dependency structure. +- `cleanup`: module-level cleanup; `'*'` removes all artifacts from that module, useful for build-only helpers. + +## Sources + +Most source types support `path` for local files relative to the manifest root and `url` for remote downloads. Remote `url` sources generally require `sha256` or `sha512`. + +Common source keys: + +- `only-arches` and `skip-arches`: download/build source only for selected architectures. +- `dest`: place a source under a subdirectory in the build source tree. +- `dest-filename`: set a predictable downloaded/copied filename. + +Use these source types: + +- `archive`: tar/zip/rpm/7z archives. Include `url`, checksum, optional `mirror-urls`, `strip-components`, `dest-filename`, and `archive-type` if suffix detection fails. +- `git`: Git repository. Include `url` and exact `commit`; `tag` is fine with `commit`. Avoid branch-only sources for reproducibility. `path` can point to a local Git repo. `disable-shallow-clone` and `disable-submodules` alter defaults. +- `file`: copy a local or remote file unchanged. Often paired with `simple` commands and `dest-filename`. +- `dir`: copy a local directory. Useful in CI/local builds, but avoid for store submissions because it bypasses source caching and reproducibility. +- `patch`: apply patch files. Use `path` or `paths`; default is `patch -p 1`; `strip-components`, `options`, `use-git`, and `use-git-am` adjust behavior. +- `shell`: run shell commands during source extraction for small fail-safe tweaks. Use patches for complex changes. +- `script`: generate a `/bin/sh` script source with `commands` and `dest-filename`, commonly for app wrappers. +- `extra-data`: download proprietary or very large data at install time. Requires `url`, `sha256`, `size`, and `filename`, plus an installed `/app/bin/apply_extra` script. + +## Dependencies + +Prefer dependencies already in the chosen runtime. Bundle only what the runtime lacks, what must be a different version, what needs patches, or app-specific data/resources. + +Before hand-writing many modules, check for: + +- Flathub shared modules for common native dependencies. +- `flatpak-builder-tools` generators for ecosystems such as Python, Node/Electron, and .NET. +- BaseApps for large frameworks, especially Electron. +- SDK extensions for build-time tools such as Node.js, Go, Java, or .NET. + +## Cleanup + +Use top-level `cleanup` for files produced anywhere in the manifest and module-level `cleanup` for files produced by one module. Paths beginning with `/` are relative to `/app`, so `/include` removes `/app/include`. Prefer configuring builds to not produce docs, static libs, or headers instead of cleaning them afterwards. + +Common cleanup: + +```yaml +cleanup: + - /include + - /share/man + - '*.a' +``` + +## Exported files and renaming + +Desktop files, icons, and MetaInfo files exported to the host should be named with the app ID. Prefer fixing names in upstream source. If that is not possible, `flatpak-builder` can rename: + +```yaml +rename-icon: old-icon-name +rename-desktop-file: old.desktop +rename-appdata-file: old.appdata.xml +``` + +Use renaming as a compatibility escape hatch; direct app-ID filenames are more reliable. + +## Useful build variables + +- `$FLATPAK_ID`: app ID. +- `$FLATPAK_DEST`: install prefix, usually `/app` for apps. +- `$FLATPAK_BUILDER_N_JOBS`: parallel job count for build commands. + +Do not assume these variables exist at runtime or inside `apply_extra`; they are build-time variables. diff --git a/skills/flatpak-packaging/references/runtimes-and-conventions.md b/skills/flatpak-packaging/references/runtimes-and-conventions.md new file mode 100644 index 00000000..43d7bf0c --- /dev/null +++ b/skills/flatpak-packaging/references/runtimes-and-conventions.md @@ -0,0 +1,144 @@ +# Runtimes and Conventions + +Related public docs: [Available Runtimes](https://docs.flatpak.org/en/latest/available-runtimes.html), [Basic concepts](https://docs.flatpak.org/en/latest/basic-concepts.html), [Dependencies](https://docs.flatpak.org/en/latest/dependencies.html), [Requirements & Conventions](https://docs.flatpak.org/en/latest/conventions.html), [Desktop Integration](https://docs.flatpak.org/en/latest/desktop-integration.html). + +## Runtime choice + +Every app needs a runtime and matching SDK. The runtime is the app's stable cross-distribution base; the SDK is the build environment with compilers, headers, tools, and debuggers. + +Main runtimes: + +- Freedesktop: `org.freedesktop.Platform` and `org.freedesktop.Sdk`. Generic base for any app, graphics/toolchain stack, parent of GNOME and KDE runtimes, strict ABI/API stability within a major branch. +- GNOME: `org.gnome.Platform` and `org.gnome.Sdk`. Use for GNOME/GTK apps when the GNOME platform provides needed libraries. +- KDE: `org.kde.Platform` and `org.kde.Sdk`. Use for Qt/KDE apps; includes Qt and KDE Frameworks. +- elementary: `io.elementary.Platform` and `io.elementary.Sdk`. Use for elementary AppCenter targets. + +Prefer an existing runtime over creating a custom runtime. Bundle dependencies missing from the chosen runtime, but keep bundled modules minimal. + +Check runtime contents: + +```bash +flatpak run --command=cat org.gnome.Platform//47 /usr/manifest.json | jq -r '."modules"|.[]|."name"' | sed -E 's#.*/(.*)\.bst#\1#' | sort -u +flatpak run --command=pkg-config org.freedesktop.Sdk//24.08 --modversion appstream +flatpak run --command=ldconfig org.freedesktop.Platform//24.08 -p | awk '/\.so/ {print $1}' +``` + +## Application IDs + +Use a unique reverse-DNS ID such as `org.example.App`. The domain portion must be lowercase. Avoid: + +- IDs ending in `.desktop`. +- Bare hosting namespaces such as `io.github.foo`; prefer `io.github.foo.foo`. +- `com.github.*` or `com.gitlab.*` for projects not controlling those domains. +- Dashes in invalid D-Bus name components; use underscores when needed. +- Capitalized domain portions such as `Org.Example.App`. + +The same ID should be used for manifest filename, desktop file, icon name, MetaInfo ID, exported service names, and app namespace where possible. + +## MetaInfo/AppStream + +Install MetaInfo to: + +```text +/app/share/metainfo/org.example.App.metainfo.xml +``` + +Validate: + +```bash +appstreamcli validate --explain org.example.App.metainfo.xml +``` + +Flatpak Builder composes metadata with AppStream during build. App stores can impose additional requirements. + +## Icons + +Install icons named with the app ID: + +```text +/app/share/icons/hicolor/128x128/apps/org.example.App.png +/app/share/icons/hicolor/scalable/apps/org.example.App.svg +``` + +Icons must be square. PNG and SVG are accepted. Flatpak exports `$FLATPAK_ID`, `$FLATPAK_ID.foo`, and `$FLATPAK_ID-foo` icon patterns. + +## Desktop files + +Install desktop file: + +```text +/app/share/applications/org.example.App.desktop +``` + +Minimal shape: + +```ini +[Desktop Entry] +Name=Example App +Exec=app-command +Type=Application +Icon=org.example.App +Categories=Utility; +``` + +Validate: + +```bash +desktop-file-validate org.example.App.desktop +``` + +Flatpak rewrites `Exec` at install time to invoke `flatpak run --command=...`. + +## D-Bus service files + +Install service files to: + +```text +/app/share/dbus-1/services/org.example.App.service +``` + +The filename before `.service` must match `$FLATPAK_ID` or a subname. The `Name=` key must match exactly. + +## Search providers, Krunner, and MIME + +GNOME Shell search provider: + +```text +/app/share/gnome-shell/search-providers/org.example.App-search-provider.ini +``` + +Krunner D-Bus plugin: + +```text +/app/share/krunner/dbusplugins/org.example.App.desktop +``` + +MIME package: + +```text +/app/share/mime/packages/org.example.App-mime.xml +``` + +Flatpak may disable or rewrite some exported integration files for safety. + +## XDG base directories + +Inside the sandbox, Flatpak sets: + +- `XDG_CONFIG_HOME`: `~/.var/app//config` +- `XDG_DATA_HOME`: `~/.var/app//data` +- `XDG_CACHE_HOME`: `~/.var/app//cache` +- `XDG_STATE_HOME`: `~/.var/app//.local/state` on Flatpak 1.13+ + +Host values may be exposed as `HOST_XDG_CONFIG_HOME`, `HOST_XDG_DATA_HOME`, `HOST_XDG_CACHE_HOME`, and `HOST_XDG_STATE_HOME`. + +Prefer toolkit APIs such as GLib XDG helpers, Qt `QStandardPaths`, or Electron `app.getPath`. + +## Desktop integration notes + +- Portals are the preferred path for files, URIs, printing, notifications, screenshots, and similar host integration. +- Avoid relying on tray/status icons as the only control surface; some Linux desktops do not show them. +- StatusNotifier may need `--talk-name=org.kde.StatusNotifierWatcher` and, for old implementations, `--own-name=org.kde.*`; current Electron, Chromium, KNotifications, and libappindicator usually avoid ownership permissions. +- Host themes are not directly available from `/usr`. Prefer runtime theme extensions and portal/XSettings support over filesystem access to host theme directories. +- Host icons are exposed under `/run/host/share/icons` and `/run/host/user-share/icons`. +- Host fonts are exposed under `/run/host/fonts`, `/run/host/local-fonts`, and `/run/host/user-fonts`; host fontconfig files are not exposed. diff --git a/skills/flatpak-packaging/references/sandbox-permissions.md b/skills/flatpak-packaging/references/sandbox-permissions.md new file mode 100644 index 00000000..2407210c --- /dev/null +++ b/skills/flatpak-packaging/references/sandbox-permissions.md @@ -0,0 +1,194 @@ +# Sandbox Permissions + +Related public docs: [Sandbox Permissions](https://docs.flatpak.org/en/latest/sandbox-permissions.html), [Portal support](https://docs.flatpak.org/en/latest/portals.html), [Desktop Integration](https://docs.flatpak.org/en/latest/desktop-integration.html), [Debugging](https://docs.flatpak.org/en/latest/debugging.html). + +## Default sandbox + +By default, a Flatpak app cannot access host files except its runtime, its app files, `~/.var/app/$FLATPAK_ID`, and `$XDG_RUNTIME_DIR/app/$FLATPAK_ID`; only the latter two are writable. It also lacks network, device nodes, host processes, unrestricted syscalls, unfiltered D-Bus, X11, system D-Bus, and PulseAudio unless permissions are added. + +Configure app permissions in manifest `finish-args`. These arguments are static; do not expect variable expansion or substitution. + +## Prefer portals + +Use portals before static permissions when the app needs user-mediated access to files, URIs, printing, screenshots, notifications, network status, inhibit, and related desktop services. GTK and Qt/KDE can use many portals transparently. Apps without toolkit support can call xdg-desktop-portal directly. + +Portal use often avoids broad grants such as `--filesystem=home` or `--talk-name=org.freedesktop.Notifications`. + +## Standard GUI permissions + +Common GUI set for Wayland-capable apps: + +```yaml +finish-args: + - --share=ipc + - --socket=fallback-x11 + - --socket=wayland + - --device=dri +``` + +X11-only apps: + +```yaml +finish-args: + - --share=ipc + - --socket=x11 + - --device=dri +``` + +Add only when required: + +- `--share=network`: network access. +- `--socket=pulseaudio`: audio playback/input, MIDI, ALSA sound devices. +- `--socket=cups`: CUPS printing access. +- `--allow=bluetooth`: Bluetooth sockets. +- `--socket=ssh-auth`: SSH agent, usually for Git/SSH clients. +- `--socket=gpg-agent`: GPG agent, usually for mail or GPG frontends. + +`--socket=inherit-wayland-socket` is sensitive and should be rare. + +## D-Bus + +Session bus access is filtered by default. The app can own and talk within its own `$FLATPAK_ID` namespace, `org.mpris.MediaPlayer2.$FLATPAK_ID`, `org.freedesktop.DBus`, and portal APIs. + +Avoid: + +- `--socket=session-bus` +- `--socket=system-bus` + +They disable filtering and are security risks except for development/system tools. + +Prefer narrow permissions: + +```yaml +finish-args: + - --talk-name=org.example.Service + - --system-talk-name=org.example.SystemService + - --own-name=org.example.App.Helper +``` + +Find needed names with: + +```bash +flatpak run --log-session-bus org.example.App +flatpak run --log-session-bus org.example.App | grep '(required 1)' +``` + +## Filesystem + +Prefer XDG app data paths and portals. If static access is necessary: + +- Add `:ro` for read-only access. +- Use specific XDG directories such as `xdg-documents`, `xdg-download`, `xdg-music`, or `xdg-pictures`. +- Use subpaths, for example `--filesystem=xdg-documents/MyApp`. +- Avoid `home` and `host` unless the application is a file manager, editor, IDE, backup tool, or similar app where broad access is intrinsic. + +Examples: + +```yaml +finish-args: + - --filesystem=xdg-documents:ro + - --filesystem=xdg-download/MyApp:create +``` + +Special filesystem grants include: + +- `home`: home directory except `~/.var/app`. +- `host`: most top-level host paths except reserved paths. +- `host-os`: host OS paths mounted under `/run/host`. +- `host-etc`: host `/etc` mounted under `/run/host/etc`. +- `host-root`: complete host OS at `/run/host/root` on Flatpak 1.17.0+. +- `xdg-config`, `xdg-cache`, `xdg-data`, `xdg-run/path`: XDG locations. + +Reserved paths do not work with `--filesystem`: `/app`, `/bin`, `/dev`, `/etc`, `/lib`, `/lib32`, `/lib64`, `/proc`, `/run/flatpak`, `/run/host`, `/sbin`, `/usr`, and most of `/run`. + +Use `--persist=DIR` when an app hardcodes a home-relative directory and you want persistence without full home access: + +```yaml +finish-args: + - --persist=.myapp +``` + +This maps sandbox `~/.myapp` to `~/.var/app/$FLATPAK_ID/.myapp` on the host. + +## Devices + +Narrow device permissions: + +- `--device=dri`: GPU/GL. +- `--device=kvm`: `/dev/kvm`. +- `--device=shm`: shared memory in `/dev/shm`. +- `--device=input`: input devices, including game controllers, Flatpak 1.15.6+. +- `--device=usb`: raw USB bus, Flatpak 1.15.11+. + +Avoid `--device=all` unless no narrower permission is available, for example some webcam or optical drive use cases. + +## USB portal + +For libusb-style raw USB access on Flatpak 1.15.11+, prefer the USB portal when feasible. Use `--usb=` to enumerate allowed devices and `--nousb=` to hide exceptions. Opening still requires a portal permission request. + +Examples: + +```yaml +finish-args: + - --usb=vnd:1234 + - --usb=vnd:1234+dev:3456 + - --usb=cls:06:* + - --nousb=vnd:1234+dev:9999 +``` + +Use `--usb-list` or `--usb-list-file` for long lists. + +## DConf and GVfs + +Modern GLib and xdg-desktop-portal usually avoid direct DConf access. For migration from older apps: + +```yaml +finish-args: + - --metadata=X-DConf=migrate-path=/org/example/foo/ +``` + +Direct DConf access for old runtimes: + +```yaml +finish-args: + - --filesystem=xdg-run/dconf + - --filesystem=~/.config/dconf:ro + - --talk-name=ca.desrt.dconf + - --env=DCONF_USER_CONFIG_DIR=.config/dconf +``` + +For GVfs: + +- GTK/GNOME apps typically need `--talk-name=org.gtk.vfs.*` plus `--filesystem=xdg-run/gvfsd`. +- Legacy/non-GIO apps typically need `--filesystem=xdg-run/gvfs`. +- Do not use `--talk-name=org.gtk.vfs`; use the wildcard form. + +## External drives + +Common mounts: + +```yaml +finish-args: + - --filesystem=/media + - --filesystem=/run/media + - --filesystem=/mnt +``` + +Avoid subpaths unless they are predictable across systems. + +## Conditional permissions + +Flatpak 1.17.0+ supports conditional permissions: + +```yaml +finish-args: + - --socket=x11 + - --socket-if=x11:!has-wayland + - --device=all + - --device-if=all:!has-input-device + - --device=input +``` + +Available conditional forms: `--socket-if=`, `--device-if=`, `--share-if=`, `--allow-if=`. Conditions include `true`, `false`, `has-input-device`, and `has-wayland`; prefix `!` to negate. + +Use `--nosocket=NAME`, `--unshare=NAME`, and similar denies to remove inherited grants from runtime metadata or overrides. From dafa75e863ca273f54c72f16e76c6ba275628fb5 Mon Sep 17 00:00:00 2001 From: Dmitry Beskov <43372966+besdar@users.noreply.github.com> Date: Wed, 6 May 2026 23:41:33 +0300 Subject: [PATCH 2/2] Clarify AI assistant guidance wording in documentation --- README.rst | 2 +- docs/tips-and-tricks.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index d64f2d20..4ca4be3d 100644 --- a/README.rst +++ b/README.rst @@ -25,7 +25,7 @@ AI Assistant Skill ------------------ This repository also includes optional AI assistant guidance for Flatpak -packaging in ``skills/flatpak-packaging``. Compatible assistants can use it to +packaging in ``skills/flatpak-packaging``. AI assistants can use it to help draft manifests, choose runtimes, review sandbox permissions, and debug packaging issues. It is assistant metadata only; Flatpak and the documentation build do not require it. diff --git a/docs/tips-and-tricks.rst b/docs/tips-and-tricks.rst index 6573a958..812bea8b 100644 --- a/docs/tips-and-tricks.rst +++ b/docs/tips-and-tricks.rst @@ -196,7 +196,7 @@ Flatpak packaging AI assistant skill ------------------------------------ You can also find the optional AI assistant guidance for Flatpak packaging in -https://github.com/flatpak/flatpak-docs/tree/master/skills. Compatible assistants +https://github.com/flatpak/flatpak-docs/tree/master/skills. AI assistants can use it as context for tasks such as writing manifests, choosing runtimes, reviewing sandbox permissions, and debugging packaging issues. It is assistant metadata only; Flatpak itself does not read or require it.