{"slug": "show-hn-apple-notes-photos-and-find-my-as-native-linux-apps-omarchy-arch", "title": "Show HN: Apple Notes, Photos and Find My as Native Linux Apps (Omarchy/Arch)", "summary": "Developer ferdousbhai released icloud-for-omarchy, a signed pacman repository that brings Apple Notes, iCloud Photos and Find My to Arch Linux and Omarchy as native apps sharing one Apple sign-in. The package set includes icloud-notes (Qt/QML with two-way Markdown sync via the Rust icloud-notes-sync engine), icloud-photos and icloud-findmy (both GTK4/libadwaita), and icloud-session, a D-Bus daemon and Rust client crate handling authentication. Every window action is also exposed as a terminal command with shared --json output, one JSON error shape and one exit-code table, with docs/AGENTS.md and a Claude Code skill provided so AI agents can drive the apps.", "body_md": "iCloud apps for [Omarchy](https://omarchy.org) (and any Arch Linux), sharing\none Apple sign-in, published as one signed pacman repository.\n\n- **Notes** : your Apple Notes as a folder of Markdown files, synced both\nways. Edit, rename, move or delete them in the app, in Neovim or Obsidian,\nor with`mv` and`rm` , and iCloud follows.\n- **Photos** : browse, download, upload and delete your iCloud Photos.\n- **Find My** : your devices on a map, with play sound, Lost Mode and a\nlocation trail.\n- Every window action also works from the terminal, with `--json` output\nfor scripts and AI agents.\n\n```\ncurl -fsSL https://github.com/ferdousbhai/icloud-for-omarchy/releases/latest/download/install.sh | sudo bash\n```\n\n<sub>Screenshots use demo data.</sub>\n\n| Directory | Package | What it is | \n|---|---|---|\n| [notes/](https://github.com/ferdousbhai/icloud-for-omarchy/blob/main/notes/README.md) ,[notes-sync/](https://github.com/ferdousbhai/icloud-for-omarchy/blob/main/notes-sync/README.md) | `icloud-notes` | Apple Notes as a Qt/QML app and the `icloud-notes` command, synced with iCloud by its engine, icloud-notes-sync (notes-sync/, in Rust, originally derived from icloud-md), which the package installs off PATH. | \n| [photos/](https://github.com/ferdousbhai/icloud-for-omarchy/blob/main/photos/README.md) | `icloud-photos` | iCloud Photos in GTK4/libadwaita: browse, download, upload and delete. | \n| [findmy/](https://github.com/ferdousbhai/icloud-for-omarchy/blob/main/findmy/README.md) | `icloud-findmy` | Find My devices in GTK4/libadwaita: locate, play a sound, Lost Mode, history trail. | \n| [session/](https://github.com/ferdousbhai/icloud-for-omarchy/blob/main/session/README.md) ,[sessiond/](https://github.com/ferdousbhai/icloud-for-omarchy/blob/main/sessiond) | `icloud-session` | The shared sign-in: a D-Bus daemon, a sign-in window and a CLI (sessiond/), plus the Rust client crate every app links (session/). | \n\nThe shared sign-in's design (the daemon, its D-Bus interface, the session\nfiles) is in [session/README.md](https://github.com/ferdousbhai/icloud-for-omarchy/blob/main/session/README.md#design).\n\nEverything the windows do can be done from a terminal, or by an AI agent:\n`icloud-notes`, `icloud-photos` and `icloud-findmy` take commands\n(`icloud-notes list`, `icloud-photos download`, `icloud-findmy locate`, ...)\nand run them without a window, and `icloud-session` owns the sign-in. They\nshare `--json` output, one JSON error shape and one table of exit codes.\n\n- [docs/AGENTS.md](https://github.com/ferdousbhai/icloud-for-omarchy/blob/main/docs/AGENTS.md) : the reference to give an agent (auth,\ncommands with example JSON, safety rules, recipes).\n- [docs/skills/icloud/SKILL.md](https://github.com/ferdousbhai/icloud-for-omarchy/blob/main/docs/skills/icloud/SKILL.md) : the same as a\nClaude Code skill; copy`docs/skills/icloud` into`~/.claude/skills/` .\n- [docs/CLI.md](https://github.com/ferdousbhai/icloud-for-omarchy/blob/main/docs/CLI.md) : every GUI feature mapped to its command, the\nexit and error codes, the JSON shapes.\n\nSigning in is the one thing a person must do: Apple's page (password, 2FA)\nopens in a window from `icloud-session sign-in`.\n\n- **You sign in on Apple's own page** , password and two-factor code\nincluded, in a window opened by`icloud-session sign-in` . The apps never\nsee your password.\n- **What's kept** is the session cookies, in`~/.local/state/icloud-session/account.json` , readable only by you.\n- **Your password is stored only if you choose to** , for Find My, which asks\nfor it again from time to time:`icloud-session set-password` puts it in\nyour system keyring (the Secret Service, e.g. GNOME Keyring), and`icloud-session forget-password` removes it.\n- **The apps talk only to Apple** , plus OpenStreetMap for Find My's map\ntiles.\n- **Notes deletes are recoverable** : a note you delete goes to Recently\nDeleted in iCloud (about 30 days).\n- **It's all open source** , and the packages are signed with a key whose\nfingerprint is pinned in[install.sh](https://github.com/ferdousbhai/icloud-for-omarchy/blob/main/install.sh) .\n\n```\ncurl -fsSL https://github.com/ferdousbhai/icloud-for-omarchy/releases/latest/download/install.sh | sudo bash\n```\n\ninstalls all three apps (icloud-notes, icloud-photos, icloud-findmy), which pull in icloud-session. To install only some, name them:\n\n```\ncurl -fsSL .../install.sh | sudo bash -s -- icloud-photos icloud-findmy\n```\n\nThe script ([install.sh](https://github.com/ferdousbhai/icloud-for-omarchy/blob/main/install.sh)) trusts the package-signing key (after\nchecking it against the fingerprint pinned in the script), adds the signed\n`[icloud-for-omarchy]` repository as `/etc/pacman.d/icloud-for-omarchy.conf`\nwith an `Include` line in `/etc/pacman.conf`, installs an Omarchy\n`pre-refresh-pacman` hook that restores the repository after\n`omarchy refresh pacman`, and installs the packages in one `pacman -Syu`.\nRe-running it is safe. Updates then arrive with `omarchy update`.\n\nRather not pipe a script into `sudo bash`? These are the same steps, one\nat a time:\n\n```\n# 1. Download the package-signing key and check its fingerprint is\n#    35C47A06567940B6796B4D0F9B3C7BDF85268B31\ncurl -fsSLO https://github.com/ferdousbhai/icloud-for-omarchy/releases/latest/download/icloud-for-omarchy-signing-key.asc\ngpg --show-keys icloud-for-omarchy-signing-key.asc\n\n# 2. Let pacman trust it\nsudo pacman-key --add icloud-for-omarchy-signing-key.asc\nsudo pacman-key --lsign-key 35C47A06567940B6796B4D0F9B3C7BDF85268B31\n\n# 3. Add the signed repository\nprintf '[icloud-for-omarchy]\\nSigLevel = Required DatabaseRequired\\nServer = https://github.com/ferdousbhai/icloud-for-omarchy/releases/latest/download\\n' \\\n  | sudo tee /etc/pacman.d/icloud-for-omarchy.conf\necho 'Include = /etc/pacman.d/icloud-for-omarchy.conf' | sudo tee -a /etc/pacman.conf\n\n# 4. Install (on Omarchy: sudo pacman -Sy && omarchy-pkg-add icloud-notes icloud-photos icloud-findmy)\nsudo pacman -Syu icloud-notes icloud-photos icloud-findmy\n```\n\nOn Omarchy, `omarchy refresh pacman` rewrites `/etc/pacman.conf`; the\nscript installs a hook that adds the `Include` line back, so by hand you\nwould re-add it after a refresh.\n\nMachines set up from earlier Notes releases, which had a repository of\ntheir own (`[icloud-notes]`), are migrated: once `[icloud-for-omarchy]` is\nadded, the script removes `/etc/pacman.d/icloud-notes.conf`, its `Include`\nline and its Omarchy hook.\nThe icloud-notes-sync package of earlier releases needs nothing from the\nscript: icloud-notes now carries the engine and `replaces` it, so the next\n`omarchy update` swaps it out.\n\nEvery release also carries one installer per app, `install-notes.sh`,\n`install-photos.sh` and `install-findmy.sh`: install.sh with its default\nset to that one app, generated by `bin/make-installers`. The website (not\nin this repository) redirects its one-liners to these assets:\n`https://ferdousbhai.com/icloud/install.sh` to `install.sh`, and\n`https://ferdousbhai.com/icloud-<app>/install.sh` to that app's installer,\ne.g. `.../releases/latest/download/install-photos.sh`, so\n`curl ... | sudo bash` keeps installing just that app. The apps' page is\n[https://ferdousbhai.com/icloud](https://ferdousbhai.com/icloud).\n\nTo uninstall: `omarchy pkg drop <packages>`, then remove\n`/etc/pacman.d/icloud-for-omarchy.conf`, its `Include` line in\n`/etc/pacman.conf`, and\n`~/.config/omarchy/hooks/pre-refresh-pacman.d/icloud-for-omarchy`.\n\n```\nCargo.toml, Cargo.lock   one Cargo workspace: session, sessiond, notes-sync, photos, findmy\nsession/  sessiond/      icloud-session: client crate / daemon, sign-in window, CLI\nnotes/                   icloud-notes (qmake project, QML, tests, its own bin/build and bin/test)\nnotes-sync/              icloud-notes-sync, the sync engine the icloud-notes package ships\nphotos/  findmy/         icloud-photos, icloud-findmy\npackaging/<package>/     one PKGBUILD per package\ninstall.sh               the one installer (per-app copies are generated at release)\nbin/                     build, test, release, verify-release, make-installers; dev-install/dev-uninstall for the daemon\ntests/                   the add_signed_repo hash pin; install_test.sh, the installers against stubbed pacman\ndocs/                    the command-line reference (CLI.md, AGENTS.md, skills/)\n```\n\nEach directory kept its history: the five former repositories\n(ferdousbhai/icloud-session, icloud-notes-sync, icloud-photos, icloud-findmy\nand icloud-notes) were imported with `git filter-repo` into their\nsubdirectories and merged, so `git log --follow` on a file reaches back past\nthe move. icloud-notes' release tags `v0.1.0`...` v0.3.8` are here as\n`notes-v0.1.0`...` notes-v0.3.8`.\n\nNeeds `rust`, `sqlite`, `gtk4`, `libadwaita`, `libshumate` (findmy) and\n`webkitgtk-6.0` (the sign-in window) for the Rust crates, and `qt6-base`,\n`qt6-declarative` and `make` for Notes. The apps talk to the icloud-session\ndaemon over D-Bus; for development without the package, `bin/dev-install`\nputs a release build of it in `~/.local/bin` with a user D-Bus activation\nfile (`bin/dev-uninstall` undoes it).\n\n```\nbin/build                       # every package; or name some: bin/build icloud-photos\nbin/test                        # clippy, all Rust tests, notes/bin/test, the installer checks\ntests/install_test.sh           # the installers alone: stubbed pacman, scratch /etc in a user namespace\ncargo test -p icloud-findmy     # one crate\nnotes/bin/test                  # the Qt app's tests alone (they run on a private D-Bus)\n```\n\nRust binaries land in `target/release/`, Notes in `notes/build/`. Each app\ncan also run against a local fake of Apple's servers; its README says how.\n\nnotes-sync's recorded scenarios and golden corpora run with `cargo test`;\n`ICLOUD_NOTES_SYNC_REGEN=1 cargo test -p icloud-notes-sync` re-records them\nfrom the current code (see notes-sync/README.md).\n\nReleases are cut from a checkout with the package-signing key in its keyring, no CI involved:\n\n```\nbin/release icloud-notes 0.4.1\nbin/release icloud-session 0.3.0 icloud-notes 0.6.0   # several at once\n```\n\nVersions are per package and so are the tags: `<name>-v<version>`, where\n`<name>` is the package name without `icloud-` (`session`, `photos`,\n`findmy`, `notes`), e.g. `notes-v0.4.1`. Each PKGBUILD takes its\n`pkgver` from its own newest tag: at the tag it is the plain version, and a\nlater commit builds `<version>.r<count>.<sha>` (`0.0.0.r<count>` for a package\nnever tagged).\n\n`bin/release` runs `bin/test`, sets the named packages' versions (PKGBUILD,\nand Cargo.toml for the Rust ones), commits and tags them, and builds only\nthose packages with `makepkg` from `packaging/`, each from the committed\nHEAD via `git archive`. Every other package is downloaded from the latest\nrelease, its signature checked against the pinned key, and carried forward\nunchanged, so the new repository database, `icloud-for-omarchy.db`, always\nlists all four. It signs the database with the key whose fingerprint\n`install.sh` pins and publishes it, the packages, the public key,\n`install.sh` and the per-app installers as one GitHub release on the first\ntag named; `releases/latest/download` resolves to it.\n\nThe Notes sync engine (notes-sync/) is not released on its own: it ships\ninside icloud-notes, built from the same commit, so releasing icloud-notes\nreleases it, and its Cargo.toml version only names the engine\n(`icloud-notes-sync --version`). The `notes-sync-v*` tags are historical,\nfrom when it was the separate icloud-notes-sync package (last\n`notes-sync-v0.2.0`); the first icloud-notes that carries it must be\nreleased before any other package, and `bin/release` refuses to carry\nforward an icloud-notes that still depends on the old package.\n\nA release counts as shipped only once `bin/verify-release` has installed\neach named package in a clean Arch container, the apps through their\nper-app installers and the shared packages through `install.sh`, and found\nthat version installed; otherwise `bin/release` deletes the release and the\ntags. With `PUBLISH_CRATE=1`, releasing icloud-session also publishes its client\ncrate to crates.io after the release is verified, unless crates.io already has\nthat version; by default it does not.\n\nThe `add_signed_repo` function in `install.sh` is shared verbatim with the\nGhost installer (ferdousbhai/ghost), and both repositories pin its hash in\ntheir tests (`tests/add_signed_repo.sha256` here): change it in both places,\nand both hashes, together.\n\nOne key signs these packages and Ghost's; its fingerprint is pinned in both installers and it lives only in the releasing machine's keyring, protected by a passphrase. Losing it would break the trust chain on every machine that installed from these repositories, so keep an encrypted backup somewhere off this machine:\n\n```\ngpg --armor --export-secret-keys 35C47A06567940B6796B4D0F9B3C7BDF85268B31 \\\n  | gpg --symmetric --armor --output package-signing-key.backup.asc\n```\n\nRestoring is `gpg --decrypt package-signing-key.backup.asc | gpg --import`.\n\nTo rotate the key: generate the new one, publish one release from each\nproject signed with the old key that also ships the new public key as\n`<repository>-signing-key.asc`, update the pinned fingerprint in both\ninstallers and the tests, then sign the next releases with the new key.\nMachines that installed earlier pick up the new key by re-running the\none-liner, which is idempotent.\n\nMIT, see [LICENSE](https://github.com/ferdousbhai/icloud-for-omarchy/blob/main/LICENSE). Third-party credits (icloud-md, node-diff3,\nthe mdast/micromark utilities, yaml) are in [NOTICE](https://github.com/ferdousbhai/icloud-for-omarchy/blob/main/NOTICE).", "url": "https://wpnews.pro/news/show-hn-apple-notes-photos-and-find-my-as-native-linux-apps-omarchy-arch", "canonical_source": "https://github.com/ferdousbhai/icloud-for-omarchy", "published_at": "2026-10-06 09:22:13+00:00", "updated_at": "2026-10-06 09:49:15.857871+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools"], "entities": ["ferdousbhai", "icloud-for-omarchy", "Omarchy", "Arch Linux", "Apple", "icloud-notes", "icloud-session", "Claude Code"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/show-hn-apple-notes-photos-and-find-my-as-native-linux-apps-omarchy-arch", "markdown": "https://wpnews.pro/news/show-hn-apple-notes-photos-and-find-my-as-native-linux-apps-omarchy-arch.md", "text": "https://wpnews.pro/news/show-hn-apple-notes-photos-and-find-my-as-native-linux-apps-omarchy-arch.txt", "jsonld": "https://wpnews.pro/news/show-hn-apple-notes-photos-and-find-my-as-native-linux-apps-omarchy-arch.jsonld"}}