An opinionated dual-pane file manager for macOS, forked from fman.
Python 3.9 or later is required (tested up to Python 3.14).This is a personal rework targeting macOS as the primary platform. While the cross-platform codebase (Windows, Linux) is preserved, development and testing focus on macOS with Python 3.14.
pip install -Ur requirements/mac.txt # macOS
pip install -Ur requirements/ubuntu.txt # Ubuntu/Debian
pip install -Ur requirements/arch.txt # Arch Linux
pip install -Ur requirements/fedora.txt # Fedora
pip install -Ur requirements/windows.txt # Windows### New features
- Settings panel (Cmd+,) — centralized preferences replacing scattered dialog popups. Font family, font size, hidden files toggle, parent directory entry, and external tool configuration in one place.
- Theme editor — visual color customization with 21 color pickers, live preview, save/load named themes, import/export
.fman-themefiles. Integrates with FmanAlternativeColors plugin for seamless theme switching. - File preview (F3 / Cmd+Y) — preview text, images (PNG, JPG, GIF, BMP, SVG, WEBP, AVIF), PDFs, and directory stats in the opposite pane. Live updates as you navigate.
- Parent directory entry (..) — toggleable
..entry at the top of every directory listing. - PanelManager — unified panel system in core. Settings, theme editor, and file preview all use a single API (
window.activate_panel/window.deactivate_panel). Opening one panel auto-closes another. No more duplicated splitter-swap code across plugins.
- macOS 26 crash fix — upgraded pyobjc-core (7.1 → 12.1) to fix SIGSEGV in
PyObjCClass_NewMetaClass - Python 3.14 compatibility — fixed float-to-int rejection in Qt calls, removed private
traceback._some_strusage, fixed read-onlyTracebackException.exc_type - PyInstaller 6.x — upgraded from 4.4 to 6.19.0, fixed
sys._MEIPASSpath change - macOS TCC compliance — ad-hoc codesigning + NS*UsageDescription keys for folder access
- GoTo performance — cached CoreServices framework load (800ms → 6ms)
- Bundle size — stripped unused Qt frameworks and boto3 from frozen app
- Security — Apple credentials moved to environment variables
- Filter robustness —
remove_filterno longer crashes on missing filter;..entries immune to all filters at model level
- Core Python package renamed from
fmantovitraj - DATA_DIRECTORY:
~/Library/Application Support/vitraj(Mac) - Bundle identifier:
io.vitraj.vitraj - New plugin icons generated from custom SVG
- Python 3.9+ (tested with 3.14)
- macOS (primary target)
- Xcode Command Line Tools (
xcode-select --install)
# Clone the repo
git clone https://github.com/usqr/fman.git vitraj
cd vitraj
# Create a virtual environment
python3 -m venv .venv
source .venv/bin/activate
# Install dependencies
pip install -Ur requirements/mac.txt# Run from source (development mode)
python build.py run
# Run tests (expect 461 tests, 2 pre-existing failures in test_zip.py)
python build.py test
# Compile standalone macOS app
python build.py clean && python build.py freeze
# Output: target/vitraj.app (ad-hoc signed)
# Launch the compiled app
open target/vitraj.app# Windows
pip install -Ur requirements/windows.txt
python build.py freeze
# Ubuntu/Debian
pip install -Ur requirements/ubuntu.txt
python build.py freeze
# Arch Linux
pip install -Ur requirements/arch.txt
python build.py freeze
# Fedora
pip install -Ur requirements/fedora.txt
python build.py freezeTagged commits auto-build the macOS app and DMG via GitHub Actions
(.github/workflows/release.yml):
git tag v1.7.5
git push fork v1.7.5The workflow runs on macos-latest with Python 3.14, freezes the app, builds
the branded DMG, and uploads it to a GitHub Release with auto-generated
notes. The tag is the version source of truth — version in
src/build/settings/base.json is rewritten in-memory for the build, so no
version-bump commit is required before tagging. The workflow also accepts
workflow_dispatch with an explicit tag for re-runs.
The DMG installer carries the full vitraj wordmark logo
(src/main/icons/src/logo.svg, recoloured for the dark background) above a
drag-to-Applications layout. Rebuild it manually with:
python src/build/dmg_background.py # writes target/dmg_background.png
python src/build/create_dmg.py # writes target/vitraj.dmgReleases are ad-hoc signed (TCC-compliant but unnotarized). Apple Developer
ID signing + notarization is already implemented in build_impl/mac.py
(sign() / _notarize() via altool) and can be wired into the workflow
once APPLE_CERTIFICATE_P12, APPLE_ID, APPLE_TEAM_ID, and
APPLE_APP_PASSWORD are added as GitHub secrets. See AGENTS.md for the
remaining release-pipeline work.
| Package | Purpose | Install |
|---|---|---|
| PyMuPDF | PDF preview | pip install PyMuPDF |
| Pillow | AVIF image preview | pip install Pillow |
Both are included in requirements/base.txt. The app works without them — preview falls back gracefully.
| Shortcut | Action |
|---|---|
| F3 / Cmd+Y | Toggle file preview |
| Cmd+, | Open settings |
| Cmd+P | Go to directory |
| Cmd+Shift+P | Command palette |
| Cmd+. | Toggle hidden files |
| Tab | Switch panes |
| F5 | Copy |
| F6 | Move |
| F7 | Create directory |
| F8 | Move to trash |
| Escape | Close active panel |
| Package | Version | Notes |
|---|---|---|
| PyQt5 | 5.15.11 | GUI framework |
| PyInstaller | 6.19.0 | App freezing/compilation |
| pyobjc-core | 12.1 | macOS Objective-C bridge |
| fbs | 0.9.4 | Build system |
See requirements/ for the full list per platform.| PyMuPDF | 1.27.2.2 | PDF preview (optional) |
| Pillow | 11.2.1 | AVIF support (optional) |
| pyobjc-core | 12.1 | macOS Objective-C bridge |
| fbs | 0.9.4 | Build system |
See requirements/ for the full per-platform list.
vitraj supports the same plugin system as fman. Plugins are auto-discovered from:
src/main/resources/base/Plugins/(shipped)~/Library/Application Support/vitraj/Plugins/Third-party/(installed)~/Library/Application Support/vitraj/Plugins/User/(user)
Existing fman plugins should work — just update imports from fman to vitraj if they import core modules directly.
See AGENTS.md for guidance when working on this codebase with AI agents.
This is a fork of fman by Michael Herrmann. See the original repository for license terms.