Skip to content

Arylmera/FileFlow

Repository files navigation

FileFlow — automatic file ingest & routing for macOS

Platform: macOS Tauri 2 Rust 1.77+ React 19 License: MIT

A quiet macOS menu-bar app that moves your files where they belong — automatically, and safely.
Ingest a drive into dated folders, route one folder into another, or import straight into Apple Photos.

What it does · Safety · Install · Setup · Configure · Build · Files


What it does

FileFlow watches sources and routes new files to destinations — verified on the way, safe by default. Three flows, set up once from the control panel and then left alone:

Flow What happens
💾 Drive → folder Plug in a recognised external drive (SD card, USB stick, …) and FileFlow copies its files into a destination, organized by capture date, verifies every copy, then — optionally — wipes and ejects the drive. Moves any file type by default; filter by extension if you want.
📁 Folder → folder Watch a folder; whatever lands in it is moved into a target folder, filtered by extension.
🖼️ Folder → Photos Point a watched folder (e.g. your Lightroom exports) at an Apple Photos album, and new files are imported automatically.

A destination is any writable path — a local folder, a cloud-synced folder (OneDrive, iCloud Drive, Dropbox, Google Drive), a mounted network share (SMB/NFS, e.g. a TrueNAS dataset), or another drive — plus Apple Photos as a built-in destination.

The goal is a tool you trust to run unattended and rarely need to open.

Safety model

Your files are irreplaceable, so the destructive path — wiping a drive after ingest — is deliberately paranoid:

  • Verified copies — every file is checked (byte size) at the destination before it counts as copied.
  • All-or-nothing deletion — the drive is wiped only after every file in the set has copied and verified. Any single failure — including the destination going unreachable mid-run — aborts deletion entirely, so a partial or interrupted copy can never lose data.
  • Idempotent re-runs — identical-size files already at the destination are skipped, so running it again is safe.

Install

FileFlow is a personal utility, not an App Store download. The fastest way in — one command, nothing else to do:

curl -fsSL https://raw.githubusercontent.com/Arylmera/FileFlow/main/install.sh | sh

This grabs the latest release, drops FileFlow.app into /Applications, and launches it. macOS only quarantines files a browser downloads, so an app delivered over curl carries no quarantine flag — the unsigned build opens straight away, with no Gatekeeper prompt and no right-click ▸ Open. (Reading a script before piping it to a shell is always fair — it's install.sh.)

Prefer to do it by hand? Drag FileFlow.app into /Applications and launch it. A browser-downloaded build is quarantined, so macOS warns on first run — right-click the app ▸ Open, or clear the flag once with xattr -dr com.apple.quarantine /Applications/FileFlow.app. Building it yourself? See Build from source.

On first launch FileFlow lives in the menu bar (no Dock icon by default). Click the tray icon to open the control panel.

First-run setup

Depending on which flows you use, FileFlow needs one or two macOS permissions. It detects when either is missing and surfaces guidance in the window — you don't have to hunt for them blind.

Permission Why it's needed Where to grant it
Full Disk Access Read drive contents under /Volumes and write into protected destinations (e.g. ~/Library/CloudStorage). System Settings ▸ Privacy & Security ▸ Full Disk Access
Automation (Photos) Control Photos to import into an album — only for a Folder → Photos rule. macOS prompts on the first import. System Settings ▸ Privacy & Security ▸ Automation

Note

Ad-hoc dev builds re-prompt for these on every rebuild, because the signature changes each time. To make grants stick, sign with a stable identity — see Code signing & TCC persistence.

Configure

Open the control panel from the tray icon, then add the rules you need:

  1. Drive rule (drive → folder) — pick a drive to recognise and its destination; choose whether to verify-then-wipe-and-eject after a successful copy, and optionally restrict it to certain extensions.
  2. Folder rule (folder → folder, or folder → Photos) — point a watched folder at a target folder or an Apple Photos album, filtered by extension.
  3. Leave it running. Trigger a run manually any time, and check the activity log for what happened.

Settings live in a single config file, managed entirely from the UI — see Files & locations.

Build from source

Prerequisites: Rust ≥ 1.77, Node ≥ 18, Xcode Command Line Tools.

npm install
npm run tauri dev             # run with hot-reload
cargo test -p fileflow-core   # run the domain-logic tests

Produce a release build:

npm run tauri build      # → target/release/bundle/macos/FileFlow.app
npm run build:dmg        # also build the installer .dmg (GUI session only — see below)

The default build produces the .app only, which works headlessly. The .dmg step drives Finder via AppleScript to lay out the disk-image window and only succeeds in an interactive GUI login session — run npm run build:dmg from a logged-in desktop, or just distribute the .app.

Publishing a release

The curl | sh installer pulls the latest GitHub release's FileFlow.app.tar.gz. To cut one:

npm run tauri build                                       # → target/release/bundle/macos/FileFlow.app
APP=target/release/bundle/macos/FileFlow.app
codesign --force --deep -s - "$APP"                       # re-seal ad-hoc — the bundler can leave it unsealed
codesign --verify --deep --strict "$APP"                  # must pass, or the app launches as "damaged"
tar -czf FileFlow.app.tar.gz -C "$(dirname "$APP")" FileFlow.app
gh release create v0.1.0 FileFlow.app.tar.gz              # newest non-prerelease becomes "latest"

The re-seal matters: an unsealed bundle (no Contents/_CodeSignature) fails Gatekeeper's integrity check and is killed on launch even via curl. Re-signing keeps it ad-hoc — no Developer ID, no notarization — just valid. For later versions, bump the tag (gh release create v0.1.1 …).

Code signing & TCC persistence

The default build is ad-hoc signed, so its signature changes on every rebuild and macOS re-prompts for the permissions above each time. To make grants persist across rebuilds, sign with a stable identity (Apple Development or Developer ID) — list yours with security find-identity -v -p codesigning:

export APPLE_SIGNING_IDENTITY="Apple Development: you@example.com (TEAMID)"
npm run tauri build

(or set bundle.macOS.signingIdentity in src-tauri/tauri.conf.json). The bundle identifier com.guillaumelemer.fileflow is fixed, which TCC also keys on. The hardened-runtime entitlement needed to control Photos lives in src-tauri/entitlements.plist (com.apple.security.automation.apple-events) and is applied automatically when signing; it's inert for ad-hoc dev builds.

Files & locations

Path
Config ~/Library/Application Support/com.guillaumelemer.fileflow/config.toml — managed from the UI (Settings ▸ Open config folder).
Logs ~/Library/Logs/com.guillaumelemer.fileflow/fileflow.logSettings ▸ Open log file; verbosity via Settings ▸ Log level.

By default the app runs as a menu-bar agent (no Dock icon), reachable from the tray. Settings toggles the Dock and menu-bar icons independently — at least one stays visible so the window is always reachable. It launches at login when enabled and enforces a single instance.

Architecture

Rust + Tauri 2 + React/TypeScript. Domain logic lives in a pure, Tauri-free core crate (unit-tested); src-tauri is the shell, src the UI.

core/        pure domain logic (config, ingest, photos) — `cargo test -p fileflow-core`
src-tauri/   Tauri shell: watchers, commands, tray, state
src/         React control panel

License

MIT © 2026 Lemer Guillaume

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors