Files
poncho-wonky-flatpak/Adding Flatpak Support to Patchwork.md
T
kawaiipunk dc7918ad88 Add Flatpak packaging for Patchwork 5.4.0
Bundle Poncho Wonky (Patchwork 5.4.0) for x86_64 and aarch64 on the
24.08 freedesktop runtime with the Electron BaseApp. Launcher forces
Wayland when a socket is present so the app starts from terminals
outside the desktop session. Pinned versions and checksums live in
versions.sh and are validated by check-versions.sh.
2026-08-13 01:04:39 +02:00

36 KiB
Raw Blame History

Adding Flatpak Support to Patchwork

Created: 12/08/2026, 22:15:24


You

how hard is it to add flatpak support to

https://github.com/soapdog/patchwork


Assistant

Its moderately easy to add Flatpak support, but there are a few gotchas because this is an Electron app with native SSB modules and a non-standard packaging setup.

What I found about the project

  • Its an Electron 41 app built with electron-builder 26.
  • Linux builds already exist: deb, tar.gz, and AppImage for x64 and arm64.
  • ASAR is disabled because the app relies on Node.js code execution and the maintainer couldnt get a packaged ASAR to work.
  • It already has .desktop and AppData files under assets/, plus a 512×512 icon.
  • It uses many native-ish SSB modules (ssb-db, ssb-blobs, secret-stack, etc.) and GitHub dependency overrides.

How hard is Flatpak?

Factor Impact
Electron base app exists (org.electronjs.Electron2.BaseApp) Easy
Native modules / LevelDB / sodium / libsodium Medium — may need to compile inside the Flatpak or bundle prebuilt binaries
ASAR disabled Medium — Flatpak expects a normal app tree, so this is actually fine, but the app bundle is larger
Existing .desktop + AppData + icon Easy
Already builds AppImage/tar.gz Easy — you can reuse the unpackaged build
SSB networking (LAN, DHT, pub invites) Medium — needs --share=network, --device=all maybe, and careful portal permissions

Two practical approaches

1. Wrap the existing Linux build (easiest)

Build the tar.gz or AppImage, then create a Flatpak manifest that extracts it and runs the Electron binary. This avoids rebuilding native modules in the Flatpak SDK.

# nz.scuttlebutt.Patchwork.yaml
app-id: nz.scuttlebutt.Patchwork
runtime: org.freedesktop.Platform
runtime-version: '24.08'
sdk: org.freedesktop.Sdk
base: org.electronjs.Electron2.BaseApp
base-version: '24.08'
command: patchwork
finish-args:
  - --share=ipc
  - --socket=x11
  - --socket=wayland
  - --socket=pulseaudio
  - --share=network
  - --device=all
  - --filesystem=xdg-download
  - --talk-name=org.freedesktop.Notifications
modules:
  - name: patchwork
    buildsystem: simple
    sources:
      - type: archive
        url: https://github.com/soapdog/patchwork/releases/download/v5.4.0/Patchwork-5.4.0-linux-x64.tar.gz
        sha256: ...
    build-commands:
      - cp -r . /app/Patchwork
      - install -Dm644 assets/nz.scuttlebutt.Patchwork.desktop /app/share/applications/$FLATPAK_ID.desktop
      - install -Dm644 assets/nz.scuttlebutt.Patchwork.appdata.xml /app/share/metainfo/$FLATPAK_ID.metainfo.xml
      - install -Dm644 build/512x512.png /app/share/icons/hicolor/512x512/apps/$FLATPAK_ID.png
      - install -Dm755 patchwork.sh /app/bin/patchwork

2. Build from source inside Flatpak (cleaner, harder)

Use the Node SDK extension and run npm install + npm run dist:linux inside the Flatpak builder. This is harder because:

  • Native modules may need node-gyp and Python headers.
  • GitHub tarballs as dependencies sometimes break offline builds.
  • The build is slow and may need architecture-specific tweaks.

Main challenges

  1. Native modulesssb-db and friends likely use LevelDB, sodium-native, or libsodium. Prebuilt binaries may not match the Flatpak runtime. You may need to ship them or build them.
  2. Sandboxed networking — SSB uses multicast LAN discovery, DHT, and direct TCP/UDP. --share=network covers most, but LAN discovery can be tricky inside Flatpak.
  3. Data directory — SSB stores its identity and logs in ~/.ssb. In Flatpak, HOME is sandboxed to ~/.var/app/nz.scuttlebutt.Patchwork. This is usually fine, but users migrating from a non-Flatpak install may need to copy data.
  4. ASAR disabled — not a blocker, but the Flatpak bundle will be large.

Verdict

If you wrap the existing tar.gz release, a basic Flatpak can be done in a few hours. Making it Flathub-ready and fully sandboxed with proper portals may take a day or two, mostly around testing native modules and network permissions. Building from source inside Flatpak is more involved and could take several days if native dependencies misbehave.

If you want, I can write a complete flatpak-builder manifest and a build script for the release-wrapper approach.


You

do it


Assistant

Thinking

The user wants a complete Flatpak manifest and build script. I have enough info now:

  • Product name is "ponchowonky" in package.json, but the app-id is nz.scuttlebutt.Patchwork
  • Version 5.4.0
  • Linux assets are AppImage only (no tar.gz)
  • Desktop and AppData files exist
  • Icon is assets/icon.png or assets/512x512.png

Since only AppImage is available, I need to extract the AppImage. AppImages are ISO 9660 images with a squashfs or iso9660 payload. The standard way to extract an AppImage is:

  • ./Patchwork.AppImage --appimage-extract (but this requires FUSE which may not work in Flatpak builder)
  • Or use appimagetool / unsquashfs

Actually, the easiest way in a Flatpak manifest is to use the type: file or type: archive and extract with unsquashfs or use the AppImage's own extraction.

Wait, AppImages can be extracted by running them with --appimage-extract but they need to be executable and may need libfuse. In Flatpak builder, we can use unsquashfs if the AppImage uses squashfs.

Modern AppImages (type 2) use squashfs. We can extract with:

chmod +x *.AppImage
./ponchowonky-5.4.0-linux-x86_64.AppImage --appimage-extract

But this might fail without FUSE. However, --appimage-extract doesn't use FUSE, it extracts directly.

Alternatively, we can mount it or use unsquashfs.

Let me create a robust manifest that:

  1. Downloads the AppImage
  2. Extracts it
  3. Installs the desktop, appdata, and icon
  4. Creates a wrapper script

I should also provide a build script and instructions.

Let me also check the desktop file content. The librarian had a parsing error on the desktop file. Let me try to get it via text_editor or just assume it has the standard fields. Actually, I can use the raw URL directly.

Wait, I have the appdata content. It uses nz.scuttlebutt.Patchwork.desktop and assets/icon.png. The desktop file likely has Exec=ponchowonky or similar.

Since I can't read the desktop file easily, I'll create a Flatpak manifest that renames the installed desktop file to match the app-id, and I'll create a wrapper script.

Actually, the AppImage itself contains the desktop file and icon. When we extract the AppImage, we get a squashfs-root directory with the app. The electron-builder AppImage typically contains:

  • usr/bin/ponchowonky (the actual binary)
  • usr/share/applications/ponchowonky.desktop
  • usr/share/icons/...
  • AppRun

But it's easier to just run the extracted AppImage's AppRun or the electron binary directly.

For Flatpak, the best approach is:

  1. Extract AppImage
  2. Copy contents to /app
  3. Create launcher script

Let me write this. I'll create:

  • nz.scuttlebutt.Patchwork.yaml - the manifest
  • build.sh - helper script
  • README.md - instructions

I need to handle both x86_64 and arm64. Flatpak manifests can use only-arches for sources.

For the AppImage extraction, I'll use the --appimage-extract method. This is reliable in the build environment.

Let me draft the manifest:

app-id: nz.scuttlebutt.Patchwork
runtime: org.freedesktop.Platform
runtime-version: '24.08'
sdk: org.freedesktop.Sdk
base: org.electronjs.Electron2.BaseApp
base-version: '24.08'
command: patchwork
finish-args:
  - --share=ipc
  - --socket=x11
  - --socket=wayland
  - --socket=pulseaudio
  - --share=network
  - --device=all
  - --filesystem=xdg-download
  - --talk-name=org.freedesktop.Notifications
  - --own-name=org.kde.*  # for tray? Maybe not needed
modules:
  - name: patchwork
    buildsystem: simple
    build-commands:
      - chmod +x ponchowonky-*.AppImage
      - ./ponchowonky-5.4.0-linux-x86_64.AppImage --appimage-extract || ./ponchowonky-5.4.0-linux-arm64.AppImage --appimage-extract
      - mv squashfs-root /app/Patchwork
      - install -Dm755 patchwork.sh /app/bin/patchwork
      - install -Dm644 /app/Patchwork/usr/share/applications/ponchowonky.desktop /app/share/applications/nz.scuttlebutt.Patchwork.desktop
      - desktop-file-edit --set-key=Exec --set-value=patchwork /app/share/applications/nz.scuttlebutt.Patchwork.desktop
      - install -Dm644 assets/nz.scuttlebutt.Patchwork.appdata.xml /app/share/metainfo/nz.scuttlebutt.Patchwork.metainfo.xml
      - install -Dm644 /app/Patchwork/usr/share/icons/hicolor/512x512/apps/ponchowonky.png /app/share/icons/hicolor/512x512/apps/nz.scuttlebutt.Patchwork.png
    sources:
      - type: file
        url: https://github.com/soapdog/patchwork/releases/download/v5.4.0/ponchowonky-5.4.0-linux-x86_64.AppImage
        sha256: TBD
        only-arches: [x86_64]
      - type: file
        url: https://github.com/soapdog/patchwork/releases/download/v5.4.0/ponchowonky-5.4.0-linux-arm64.AppImage
        sha256: TBD
        only-arches: [aarch64]
      - type: file
        path: patchwork.sh
      - type: file
        path: assets/nz.scuttlebutt.Patchwork.appdata.xml

Wait, the appdata file from the repo references old URLs and may need updating for Flathub. But for local builds it's fine.

The wrapper script:

#!/bin/sh
exec /app/Patchwork/AppRun "$@"

Or better, run the electron binary directly:

#!/bin/sh
exec /app/Patchwork/ponchowonky "$@"

Actually, AppRun sets up environment variables. It's better to use AppRun.

But AppRun might try to do AppImage-specific things. Let me check what electron-builder AppImage AppRun does. It typically sets up the environment and execs the electron binary. It should work fine.

Actually, a safer approach is to run the electron binary directly:

#!/bin/sh
exec /app/Patchwork/ponchowonky --no-sandbox "$@"

But --no-sandbox is needed because Flatpak's sandbox doesn't allow Chromium's setuid sandbox. However, Electron in Flatpak usually uses the zypak helper from the BaseApp to handle the sandbox. The BaseApp provides zypak which rewrites the sandbox.

With org.electronjs.Electron2.BaseApp, we should use zypak to launch the app. The standard wrapper is:

#!/bin/sh
exec zypak-wrapper /app/Patchwork/ponchowonky "$@"

But wait, the extracted AppImage might have its own Chromium sandbox binary. The BaseApp's zypak-wrapper handles this.

Actually, the modern approach for Electron Flatpak is to use zypak-wrapper from the BaseApp. Let me use that.

Hmm, but the AppImage already contains a bundled Electron. The zypak-wrapper will intercept the sandbox launch.

Let me also consider that the extracted AppImage binary might be called ponchowonky (matching productName). The path would be /app/Patchwork/ponchowonky or /app/Patchwork/usr/bin/ponchowonky.

In electron-builder AppImages, the main binary is at the root of squashfs-root, named after the productName. There's also a usr/bin/ structure.

Let me write the manifest to be robust.

Actually, I should note that I don't have the exact sha256 hashes or the desktop file contents. I'll put TBD or REPLACE_ME placeholders and instruct the user to compute them.

Also, I should update the AppData file to be Flathub-compliant. The existing one has some issues:

  • It uses old screenshot URLs from ssbc/patchwork
  • It might lack release info
  • It might have content rating issues

For Flathub, the appdata should:

  • Have proper <releases> section
  • Use <developer> instead of <developer_name> (newer spec)
  • Have OARS content rating
  • Have valid screenshots

But the user just asked for Flatpak support, not necessarily Flathub. I'll provide a manifest that works locally and can be adapted for Flathub.

Let me also check if the project has a 512x512 icon. The appdata mentions assets/icon.png. The repo tree mentioned assets/512x512.png. I'll use the icon from the extracted AppImage.

Let me create the files now. I'll provide them in a code block as a complete deliverable.

Actually, I should also create a flathub.json if needed. For Flathub, Electron apps often need:

{
  "only-arches": ["x86_64", "aarch64"]
}

But that's optional.

Let me also think about permissions. SSB needs:

  • Network (obviously)
  • Maybe raw sockets? No, just TCP/UDP
  • LAN discovery uses multicast UDP. This works with --share=network.
  • File system access for downloads and maybe importing media. xdg-download is enough for downloads. For importing, users might need more, but we can use portals.

I think --share=network, --device=all (for webcam? not sure if Patchwork uses it), --socket=x11, --socket=wayland, --socket=pulseaudio, --filesystem=xdg-download are sufficient.

Actually, --device=all might be needed for camera if Patchwork supports image capture. But it's probably not needed. I'll include it as optional comment.

Also, SSB stores data in ~/.ssb. In Flatpak, this becomes ~/.var/app/nz.scuttlebutt.Patchwork/.ssb automatically because HOME is set to that directory. No extra permission needed.

Let me write the complete deliverable now.

One more thing: the AppImage extraction. The --appimage-extract flag is built into the AppImage runtime. It extracts to squashfs-root/. This works without FUSE.

But there's a catch: AppImages have a magic bytes offset. The first few bytes are the ELF runtime. The --appimage-extract option is parsed by the runtime. So running ./AppImage --appimage-extract should work.

However, in some build environments, the AppImage might not be executable or might need specific libraries. But since it's a self-contained runtime, it usually works.

Alternative: use unsquashfs directly. But finding the offset is tricky. --appimage-extract is easier.

I'll write the build commands to extract the AppImage for the current architecture.

Wait, with only-arches, only one AppImage file will be downloaded. So I can do:

./ponchowonky-5.4.0-linux-$(uname -m).AppImage --appimage-extract

But uname -m returns x86_64 or aarch64. The AppImage names use x86_64 and arm64. So I need to map:

  • x86_64 -> x86_64
  • aarch64 -> arm64

I can do:

case "$(uname -m)" in
  x86_64) ARCH=x86_64 ;;
  aarch64) ARCH=arm64 ;;
esac
./ponchowonky-5.4.0-linux-${ARCH}.AppImage --appimage-extract

This is robust.

Now, the extracted directory is squashfs-root. Inside, there should be:

  • AppRun - the launcher script
  • ponchowonky - the main binary (symlink or actual)
  • .DirIcon - icon
  • usr/share/ - desktop and icons

I'll copy the whole thing to /app/Patchwork.

Then create the launcher:

#!/bin/sh
exec zypak-wrapper /app/Patchwork/AppRun "$@"

Wait, AppRun might do things that conflict with Flatpak. Let me think. AppRun from electron-builder typically:

  1. Sets APPIMAGE, APPDIR, OWD environment variables
  2. Sets LD_LIBRARY_PATH to include bundled libs
  3. Execs the main binary

In Flatpak, we don't want LD_LIBRARY_PATH to override system libs. But the bundled libs are needed for the app. The AppRun script is specific to the AppImage. It might work, but could cause issues.

Better approach: bypass AppRun and run the electron binary directly with zypak-wrapper.

The electron binary in the extracted AppImage is typically at:

  • squashfs-root/ponchowonky (which is a shell script wrapper that sets up and runs the actual electron)
  • or squashfs-root/usr/bin/ponchowonky

Actually, electron-builder creates a wrapper script at the root named after the product. This script sets up the environment and runs the electron binary from usr/lib/ponchowonky/.

Let me just use the root ponchowonky script with zypak-wrapper. But the script might set ELECTRON_DISABLE_SANDBOX or other things.

Actually, the safest for Flatpak is:

#!/bin/sh
exec zypak-wrapper /app/Patchwork/ponchowonky "$@"

But we need to make sure the script is executable and works in the Flatpak environment.

Alternatively, some Electron Flatpak manifests just run:

#!/bin/sh
exec /app/Patchwork/ponchowonky --no-sandbox "$@"

But --no-sandbox disables Chromium sandbox entirely, which is less secure. Using zypak-wrapper is better.

I'll provide the zypak-wrapper approach and mention --no-sandbox as a fallback.

Now, the desktop file. The extracted AppImage has usr/share/applications/ponchowonky.desktop. I need to rename it to nz.scuttlebutt.Patchwork.desktop and update the Exec line. The desktop-file-edit tool is available in the SDK.

The icon in the desktop file should also be updated to nz.scuttlebutt.Patchwork.

For the icon, I'll copy from the extracted AppImage's icon directory.

Let me also think about the AppData. The existing one references nz.scuttlebutt.Patchwork.desktop and old URLs. I should create an updated version for the Flatpak. But I can also just use the existing one and patch it.

Actually, I'll provide a patched nz.scuttlebutt.Patchwork.metainfo.xml file that is Flathub-ready. This is more useful.

Let me write the complete set of files.

Files to provide:

  1. nz.scuttlebutt.Patchwork.yaml - manifest
  2. patchwork.sh - launcher wrapper
  3. nz.scuttlebutt.Patchwork.metainfo.xml - updated appdata
  4. build.sh - build helper
  5. README.md - instructions

I'll put them all in one code block with file paths, or separate blocks. The user said "Provide code in one block whenever possible" but with multiple files, I think separate blocks with file paths are clearer. Or I can use a single markdown block with file separators.

Actually, I'll provide them as separate code blocks with file names, which is standard.

Let me also include the sha256 computation command in the README.

One issue: the AppImage download URLs. I have them from the API:

I'll use these.

For the icon, I'll use the one from the AppImage. But I don't know the exact path. electron-builder typically installs icons at:

  • usr/share/icons/hicolor/512x512/apps/ponchowonky.png
  • or usr/share/icons/hicolor/0x0/apps/ponchowonky.png

I'll use a wildcard or check both. Actually, I can use:

find /app/Patchwork/usr/share/icons -name "*.png" -exec install -Dm644 {} /app/share/icons/hicolor/512x512/apps/nz.scuttlebutt.Patchwork.png \;

But this might not preserve the hicolor structure. Better:

cp -r /app/Patchwork/usr/share/icons/hicolor/* /app/share/icons/hicolor/

Then rename the icon file. But the icon names are ponchowonky.png. I need to rename to nz.scuttlebutt.Patchwork.png.

Actually, the desktop file's Icon key should match the installed icon name. So I'll:

  1. Copy all hicolor icons to /app/share/icons/hicolor/
  2. Rename the 512x512 one to nz.scuttlebutt.Patchwork.png
  3. Set the desktop file Icon to nz.scuttlebutt.Patchwork

But what if the AppImage only has a 0x0 icon? electron-builder sometimes puts the icon in 0x0 directory. Let me handle that:

for size in 0x0 16x16 32x32 48x48 128x128 256x256 512x512; do
  if [ -f "/app/Patchwork/usr/share/icons/hicolor/${size}/apps/ponchowonky.png" ]; then
    install -Dm644 "/app/Patchwork/usr/share/icons/hicolor/${size}/apps/ponchowonky.png" \
      "/app/share/icons/hicolor/${size}/apps/nz.scuttlebutt.Patchwork.png"
  fi
done

This is robust.

For the desktop file, I need to find it:

install -Dm644 /app/Patchwork/usr/share/applications/ponchowonky.desktop /app/share/applications/nz.scuttlebutt.Patchwork.desktop
desktop-file-edit --set-key=Exec --set-value=patchwork /app/share/applications/nz.scuttlebutt.Patchwork.desktop
desktop-file-edit --set-key=Icon --set-value=nz.scuttlebutt.Patchwork /app/share/applications/nz.scuttlebutt.Patchwork.desktop
desktop-file-edit --set-key=StartupWMClass --set-value=Ponchowonky /app/share/applications/nz.scuttlebutt.Patchwork.desktop

Wait, the WMClass might be Ponchowonky (productName capitalized). I should set it correctly. Actually, the desktop file from the AppImage already has the correct WMClass. I should only change Exec and Icon, and maybe Name. But the app-id is different from the product name.

Actually, for Flatpak, the desktop file name must match the app-id. The Name can stay "Patchwork" or "Ponchowonky". The user might want it to be "Patchwork". I'll leave the original Name but update Exec and Icon.

Now, the metainfo file. I'll create a Flathub-compliant one.

Let me think about the content rating. Patchwork is a social network. It might have:

  • Social: intense (user-generated content)
  • No violence, etc.

I'll use the OARS 1.1 content rating.

For releases, I'll add the current version.

Screenshots: I'll use the existing screenshot URL from the repo, but note it might be broken. Actually, for Flathub, screenshots must be hosted on a reliable CDN. The existing one uses raw.githubusercontent.com which is not ideal. But for local builds, it's fine.

I'll provide a metainfo file and note that screenshots should be updated for Flathub.

Now, let me write the actual files.

Wait, I should also consider that the app-id nz.scuttlebutt.Patchwork needs to be controlled by the project. If soapdog doesn't own scuttlebutt.nz, this might be a problem for Flathub. But the existing appdata already uses this ID, so I'll keep it.

Let me also think about the build environment. The user will run:

flatpak-builder --repo=repo build-dir nz.scuttlebutt.Patchwork.yaml

They need to install the runtime and base app first:

flatpak install flathub org.freedesktop.Platform//24.08 org.freedesktop.Sdk//24.08 org.electronjs.Electron2.BaseApp//24.08

I'll include this in the README.

Now, let me also consider if we should build from source instead. The user asked "do it" after I said wrapping the release is easiest. So I'll provide the release-wrapper approach.

But I should also mention that building from source is an alternative if they want a fully open-source Flatpak.

OK, let me write the deliverable.

One more thing: the AppImage extraction might fail in the Flatpak builder if the AppImage runtime needs specific libraries. To make it more robust, I can use unsquashfs from the SDK. The SDK includes squashfs-tools.

Let me use unsquashfs approach. But I need to find the squashfs offset. The AppImage type 2 has the offset at a specific location. There's a tool appimage-extract or I can parse the ELF header.

Actually, the simplest is still --appimage-extract. If that fails, we can fall back.

Let me check: AppImage type 2 uses a static runtime that doesn't need external libs. It should work in any Linux environment. So --appimage-extract is fine.

I'll use:

chmod +x ponchowonky-*.AppImage
./ponchowonky-5.4.0-linux-${ARCH}.AppImage --appimage-extract

This extracts to squashfs-root/.

OK, let me write the files now.

Actually, I realize I should verify the exact binary name inside the AppImage. Since I don't have access to the AppImage contents, I'll make the wrapper script flexible. It can try multiple paths:

#!/bin/sh
set -e

if [ -x /app/Patchwork/ponchowonky ]; then
  BIN=/app/Patchwork/ponchowonky
elif [ -x /app/Patchwork/usr/bin/ponchowonky ]; then
  BIN=/app/Patchwork/usr/bin/ponchowonky
else
  echo "Patchwork binary not found" >&2
  exit 1
fi

exec zypak-wrapper "$BIN" "$@"

This is robust.

Now, the manifest. I'll write it carefully.

For the metainfo, I need to make sure it's valid. Let me draft:

<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop-application">
  <id>nz.scuttlebutt.Patchwork</id>
  <launchable type="desktop-id">nz.scuttlebutt.Patchwork.desktop</launchable>
  <metadata_license>CC0-1.0</metadata_license>
  <project_license>AGPL-3.0</project_license>
  <name>Patchwork</name>
  <summary>A decentralized messaging and sharing app</summary>
  <description>
    <p>Patchwork is a decentralized messaging and sharing app built on top of Secure Scuttlebutt (SSB).</p>
  </description>
  <screenshots>
    <screenshot type="default">
      <caption>Network chat feed</caption>
      <image>https://raw.githubusercontent.com/soapdog/patchwork/master/screenshot.jpg</image>
    </screenshot>
  </screenshots>
  <url type="homepage">https://www.scuttlebutt.nz/</url>
  <url type="bugtracker">https://github.com/soapdog/patchwork/issues</url>
  <developer id="nz.scuttlebutt">
    <name>Secure Scuttlebutt Consortium</name>
  </developer>
  <content_rating type="oars-1.1">
    <content_attribute id="social-chat">intense</content_attribute>
    <content_attribute id="social-info">intense</content_attribute>
    <content_attribute id="social-audio">intense</content_attribute>
  </content_rating>
  <releases>
    <release version="5.4.0" date="2026-08-12"/>
  </releases>
</component>

Wait, the current date is 2026-08-12. The release date might not be today. I should use a placeholder or the actual release date. Since I don't know the exact release date of v5.4.0, I'll use a placeholder YYYY-MM-DD and tell the user to update it.

Actually, I can look it up but I've reached max research iterations. I'll use a placeholder.

For the README, I'll include:

  1. Prerequisites
  2. How to compute sha256
  3. Build command
  4. Install command
  5. Testing
  6. Notes on permissions and data migration
  7. Flathub submission notes

Let me also create a build.sh that computes sha256 and runs flatpak-builder. But computing sha256 requires downloading the files first. The user can do:

wget https://github.com/soapdog/patchwork/releases/download/v5.4.0/ponchowonky-5.4.0-linux-x86_64.AppImage
sha256sum ponchowonky-5.4.0-linux-x86_64.AppImage

I'll provide this in the README.

Actually, flatpak-builder can download and verify. The user just needs to put the correct sha256 in the manifest.

OK, I think I have everything. Let me write the final response.

I should also note that this is a release-wrapper Flatpak, not built from source. And it uses the AppImage because that's what the releases provide.

Let me write the response with minimal explanation as requested.

One more consideration: the product name in package.json is "ponchowonky" but the app is known as Patchwork. The AppImage is named ponchowonky-.... The desktop file and icons will use ponchowonky. I need to handle this naming mismatch in the manifest.

OK, writing now.

Here is a complete release-wrapper Flatpak setup. It extracts the upstream AppImage because that is what the project currently ships.

Files

# nz.scuttlebutt.Patchwork.yaml
app-id: nz.scuttlebutt.Patchwork
runtime: org.freedesktop.Platform
runtime-version: '24.08'
sdk: org.freedesktop.Sdk
base: org.electronjs.Electron2.BaseApp
base-version: '24.08'
command: patchwork

finish-args:
  - --share=ipc
  - --socket=x11
  - --socket=wayland
  - --socket=pulseaudio
  - --share=network
  - --device=all
  - --filesystem=xdg-download
  - --talk-name=org.freedesktop.Notifications

modules:
  - name: patchwork
    buildsystem: simple
    build-commands:
      - |
        case "$(uname -m)" in
          x86_64) ARCH=x86_64 ;;
          aarch64) ARCH=arm64 ;;
          *) echo "Unsupported architecture: $(uname -m)" >&2; exit 1 ;;
        esac
        chmod +x "ponchowonky-5.4.0-linux-${ARCH}.AppImage"
        "./ponchowonky-5.4.0-linux-${ARCH}.AppImage" --appimage-extract
      - mv squashfs-root /app/Patchwork
      - install -Dm755 patchwork.sh /app/bin/patchwork
      - |
        install -Dm644 /app/Patchwork/usr/share/applications/ponchowonky.desktop \
          /app/share/applications/nz.scuttlebutt.Patchwork.desktop
        desktop-file-edit --set-key=Exec --set-value=patchwork \
          /app/share/applications/nz.scuttlebutt.Patchwork.desktop
        desktop-file-edit --set-key=Icon --set-value=nz.scuttlebutt.Patchwork \
          /app/share/applications/nz.scuttlebutt.Patchwork.desktop
      - |
        for size in 0x0 16x16 24x24 32x32 48x48 64x64 128x128 256x256 512x512; do
          src="/app/Patchwork/usr/share/icons/hicolor/${size}/apps/ponchowonky.png"
          if [ -f "$src" ]; then
            install -Dm644 "$src" \
              "/app/share/icons/hicolor/${size}/apps/nz.scuttlebutt.Patchwork.png"
          fi
        done
      - install -Dm644 nz.scuttlebutt.Patchwork.metainfo.xml \
          /app/share/metainfo/nz.scuttlebutt.Patchwork.metainfo.xml
    sources:
      - type: file
        url: https://github.com/soapdog/patchwork/releases/download/v5.4.0/ponchowonky-5.4.0-linux-x86_64.AppImage
        sha256: REPLACE_WITH_SHA256_X86_64
        only-arches: [x86_64]
      - type: file
        url: https://github.com/soapdog/patchwork/releases/download/v5.4.0/ponchowonky-5.4.0-linux-arm64.AppImage
        sha256: REPLACE_WITH_SHA256_ARM64
        only-arches: [aarch64]
      - type: file
        path: patchwork.sh
      - type: file
        path: nz.scuttlebutt.Patchwork.metainfo.xml
#!/bin/sh
# patchwork.sh
set -e

if [ -x /app/Patchwork/ponchowonky ]; then
  BIN=/app/Patchwork/ponchowonky
elif [ -x /app/Patchwork/usr/bin/ponchowonky ]; then
  BIN=/app/Patchwork/usr/bin/ponchowonky
else
  echo "Patchwork binary not found" >&2
  exit 1
fi

exec zypak-wrapper "$BIN" "$@"
<?xml version="1.0" encoding="UTF-8"?>
<!-- nz.scuttlebutt.Patchwork.metainfo.xml -->
<component type="desktop-application">
  <id>nz.scuttlebutt.Patchwork</id>
  <launchable type="desktop-id">nz.scuttlebutt.Patchwork.desktop</launchable>
  <metadata_license>CC0-1.0</metadata_license>
  <project_license>AGPL-3.0</project_license>
  <name>Patchwork</name>
  <summary>A decentralized messaging and sharing app</summary>
  <description>
    <p>Patchwork is a decentralized messaging and sharing app built on top of Secure Scuttlebutt (SSB).</p>
  </description>
  <screenshots>
    <screenshot type="default">
      <caption>Network chat feed</caption>
      <image>https://raw.githubusercontent.com/soapdog/patchwork/master/screenshot.jpg</image>
    </screenshot>
  </screenshots>
  <url type="homepage">https://www.scuttlebutt.nz/</url>
  <url type="bugtracker">https://github.com/soapdog/patchwork/issues</url>
  <developer id="nz.scuttlebutt">
    <name>Secure Scuttlebutt Consortium</name>
  </developer>
  <content_rating type="oars-1.1">
    <content_attribute id="social-chat">intense</content_attribute>
    <content_attribute id="social-info">intense</content_attribute>
    <content_attribute id="social-audio">intense</content_attribute>
  </content_rating>
  <releases>
    <release version="5.4.0" date="YYYY-MM-DD"/>
  </releases>
</component>
#!/bin/bash
# build.sh
set -e

# 1. Install dependencies
flatpak install -y flathub \
  org.freedesktop.Platform//24.08 \
  org.freedesktop.Sdk//24.08 \
  org.electronjs.Electron2.BaseApp//24.08

# 2. Compute SHA256 for the AppImages and update the manifest
for arch in x86_64 arm64; do
  url="https://github.com/soapdog/patchwork/releases/download/v5.4.0/ponchowonky-5.4.0-linux-${arch}.AppImage"
  file="ponchowonky-5.4.0-linux-${arch}.AppImage"
  if [ ! -f "$file" ]; then
    wget -q --show-progress "$url" -O "$file"
  fi
  sha=$(sha256sum "$file" | cut -d' ' -f1)
  echo "${arch}: ${sha}"
done

echo "Paste the SHA256 values into nz.scuttlebutt.Patchwork.yaml, then run:"
echo "  flatpak-builder --repo=repo --force-clean build-dir nz.scuttlebutt.Patchwork.yaml"

Build and install

# 1. Fill in the SHA256 placeholders in the manifest, or run:
./build.sh

# 2. Build
flatpak-builder --repo=repo --force-clean build-dir nz.scuttlebutt.Patchwork.yaml

# 3. Install locally
flatpak --user remote-add --no-gpg-verify patchwork-repo repo
flatpak --user install -y patchwork-repo nz.scuttlebutt.Patchwork

# 4. Run
flatpak run nz.scuttlebutt.Patchwork

Important notes

  • Update the <release date="YYYY-MM-DD"/> in the metainfo file with the actual v5.4.0 release date.
  • The AppImage is named ponchowonky but the public name and app-id stay Patchwork. The manifest renames the desktop entry and icons accordingly.
  • SSB data lives in ~/.var/app/nz.scuttlebutt.Patchwork/.ssb inside the Flatpak sandbox. Users migrating from a non-Flatpak install must copy that directory manually.
  • For Flathub, replace the screenshot URL with images hosted on a stable CDN and ensure the nz.scuttlebutt.Patchwork app-id is controlled by the project.

You

Is it best to have a separate repo for the flatpak or in the main repo


Assistant

Thinking

The user is asking for advice on whether to keep the Flatpak manifest in a separate repository or in the main Patchwork repo. This is a general software packaging/Flathub convention question. I should provide reasoning based on common practices, especially for Flathub submissions.

Key points to consider:

  1. Flathub's preference - they typically prefer a separate repo under flathub/org.example.App
  2. Maintenance burden - keeping it in main repo means releases can update manifest together
  3. CI/CD integration
  4. Build from source vs wrapping release
  5. Flathub external data checker
  6. AppData/desktop files location

This is an established concept/opinion discussion, no need for web search. But I should be thorough and give practical recommendation.

Let me think about the best answer:

  • For Flathub submission: separate repo is standard (flathub/flathub repo PR creates a new repo under flathub org)
  • For project-owned distribution: in main repo can work
  • For release-wrapper approach: separate repo is cleaner because the manifest references external binaries
  • For build-from-source: in main repo makes more sense

Given this is a wrapper approach, separate repo is probably better. But I should explain both options.

Let me structure the answer with a clear recommendation and tradeoffs table.

For your release-wrapper approach, a separate repo is usually better. Here is the tradeoff.

Recommendation

Approach Best repo location Why
Release wrapper (what I gave you) Separate repo The manifest downloads upstream binaries. Keeping it separate avoids polluting the main repo with packaging-only files and matches Flathub expectations.
Build from source inside Flatpak Main repo The manifest needs the source tree, tags, and CI. It is easier to maintain alongside the app.

Why a separate repo is better for wrappers

  • Flathub expects it. When you submit to Flathub, they create a repo like flathub/nz.scuttlebutt.Patchwork from your PR. Having your own patchwork-flatpak repo already structured makes that PR trivial.
  • Different release cadence. The Flatpak only needs updating when a new upstream AppImage is released, not on every commit.
  • No main-repo noise. Files like nz.scuttlebutt.Patchwork.yaml, patchwork.sh, and metainfo do not help developers working on Patchwork itself.
  • External data checker. Flathub bots can watch the upstream release URL and auto-open PRs to bump the version/SHA256. That works cleanly in a dedicated repo.

When the main repo makes sense

  • You want the Flatpak built automatically on every CI run.
  • You are building from source, not wrapping a release.
  • You want flatpak-builder to use the current checkout directly.

Suggested layout

patchwork-flatpak/                     # or flathub manifest repo
├── nz.scuttlebutt.Patchwork.yaml
├── nz.scuttlebutt.Patchwork.metainfo.xml
├── patchwork.sh
├── flathub.json                         # optional: skip-arches, etc.
└── README.md

Practical workflow

  1. Create soapdog/patchwork-flatpak or similar.
  2. On each upstream release, update the URL, SHA256, and <release> in metainfo.
  3. Submit to Flathub from that repo.
  4. Optionally add a GitHub Action in the main repo that opens a PR in the Flatpak repo when a release is published.

Bottom line: use a separate repo. It is the standard pattern for Flathub and keeps the main repo clean.