TreeMap
무료 오픈소스 디스크 사용량 시각화 도구로, 사각형 트리맵·중복 파일 탐색·디스크 가득 예측·정리 시 파일을 휴지통으로만 이동한다
Procyon은 오픈소스 듀얼 팬 파일 관리자다
Procyon is an open-source dual-pane file manager. Rust operation engine, keyboard-first controls, SFTP and SSH terminal, archives, plugins — one place for every file.
생산성Rust · TypeScriptGitHub @erikvullings온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
A modern dual-pane file manager
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗A fast, keyboard-first dual-pane file manager for local, remote, and cloud storage.
Procyon combines a Rust operation engine with a shared Mithril interface for the desktop and browser. Browse large directories, move files between providers, inspect documents, open remote shells, and automate repetitive work without leaving the file manager. Its name comes from the raccoon genus: a gatherer of things from many places, much like the collection basket gathers files across folders and providers.
| Capability | Highlights |
|---|---|
| Navigate quickly | Dual panes, tabs, breadcrumbs, history, favourites, a directory tree, quick filtering, recursive search, and a command palette |
| Handle large collections | Virtualized lists tested with one million entries, grid view, thumbnails, folder grouping, sorting, Git status, and disk-usage treemaps |
| Move data safely | Cancellable and resumable copy, move, rename, duplicate, trash, archive, and synchronization jobs with explicit conflict handling |
| Work across providers | Local files, SFTP, FTP/FTPS, WebDAV, S3-compatible storage, OneDrive, archives, and mounted network volumes |
| Inspect files in place | Fast text with syntax highlighting for 40+ languages, hex dumps of binary files, SQLite databases (browse, search, filter, read-only SQL), image, video, PDF, archive, CSV/TSV, JSON, Excel, DOCX, and PPTX previews plus an integrated text editor |
| Search by meaning and ask | Optional local-only semantic search, enabled with consent per folder and powered by multilingual E5 by default. Knowledge search finds relevant passages; Ask produces retrieval-augmented answers with page-level citations. EmbeddingGemma 2 is an opt-in alternative for image, audio, and video indexing; the v0.6.0 release is risk-accepted, not five-gate qualified, and CPU-only PDF page-image indexing is capped and slow. |
| Adapt the workflow | Configurable shortcuts, light and dark themes, native platform actions, an optional separate viewer window, and resource-limited Lua and JavaScript plugins |
Procyon never implements file mutations in the frontend. Every operation goes through the same typed Rust engine, whether the app is running through Tauri, Axum, or the in-process mock client.
The badge beside Operations shows active file operations and semantic indexing. Open it for per-job progress and shortcuts to the Operations Centre or Semantic settings. A total or percentage appears only when the job knows one; permanent deletion instead reports items already removed. A folder being moved or deleted remains navigable and shows its current state until the operation finishes.
Quitting the desktop app while work is active prompts for confirmation. File operations stop and are shown as interrupted after restart; partial changes, including permanently deleted items, are not rolled back or resumed automatically. Enrolled semantic folders are reconciled again on desktop startup. Closing a browser tab does not stop work in a separately running server, but restarting that server interrupts its file operations.
| Embedded terminal | Document preview |
|---|---|
New to Procyon? Start with the task-based walkthroughs for a two-pane copy, finding files, remote connections, workspaces, and optional semantic features. They are also available in the app's Help panel.
The default development runtime uses built-in mock data, so it does not need a Rust server.
git clone https://github.com/erikvullings/procyon.git
cd procyon
corepack enable
pnpm install
pnpm dev
Open http://127.0.0.1:5180.
| Runtime | Command | Backend |
|---|---|---|
| Mock | pnpm dev | In-process fixtures; no Rust process required |
| HTTP | pnpm dev:server and pnpm dev:http in separate terminals | Axum REST API and SSE on port 8787 |
| Desktop | pnpm dev:tauri | Tauri commands and event channels |
The HTTP development server disables authentication only on loopback. Production server mode requires a session token and should be placed behind TLS. See Server-mode security for deployment guidance.
| Tool | Version | Purpose |
|---|---|---|
| Rust | 1.98.1 | Pinned by rust-toolchain.toml; includes the macOS 27 Mach-O LINKEDIT alignment fix |
| Node.js | 22 LTS | Frontend and repository scripts |
| pnpm | 12 | Pinned by packageManager in package.json |
| cargo-watch | Latest | Automatic Axum rebuilds during HTTP development |
| cargo-nextest | Latest | Rust test runner used by CI |
Install the two Cargo tools when you need the HTTP development loop or the Rust test suite:
cargo install cargo-watch
cargo install cargo-nextest --locked
Install Xcode Command Line Tools:
xcode-select --install
Install Microsoft C++ Build Tools for Visual Studio 2022 and the WebView2 Runtime. WebView2 is included with Windows 11.
Install the WebKitGTK 4.1 development libraries and Tauri's system dependencies for your distribution. The package names commonly include:
webkit2gtk-4.1 build-essential curl wget file libssl-dev
libayatana-appindicator3-dev librsvg2-dev
See the Tauri prerequisites guide for current distribution-specific commands.
Run commands from the repository root.
| Command | Purpose |
|---|---|
pnpm dev | Start Vite with the mock client |
pnpm dev:http | Start Vite against the Axum backend |
pnpm dev:server | Start the Axum backend with automatic rebuilds |
pnpm dev:tauri | Launch the Tauri desktop app |
pnpm dev:tauri:semantic:gemma | Launch a local desktop with the optional Gemma development catalog |
pnpm test | Run Rust, frontend, and script tests |
pnpm test:rust | Run the Rust suite and doctests |
pnpm test:frontend | Run Vitest |
pnpm lint | Run Rust and frontend formatting and lint checks |
pnpm build | Build the production Rust and frontend targets |
pnpm build:tauri | Package the desktop application |
pnpm api:check | Verify the OpenAPI document and generated client are current |
Run pnpm dev:tauri:semantic:gemma from the repository root on macOS arm64
(the locally verified target; other platforms are not yet qualified). The command verifies the
pinned E5 and EmbeddingGemma 2 files, builds an optimized native Gemma worker,
and launches the development desktop with a development-key-signed, local
installation catalog. It needs about 1.5 GiB for the Gemma checkpoint plus
space for the catalog and installed copies; the UI discloses an 8 GiB RAM
estimate. The model download may require access to Google's gated Hugging Face
repository. To build the bundle without launching Tauri, run
pnpm semantic:bundle:dev --gemma.
On macOS arm64, pnpm dev:tauri:semantic:gemma:metal instead compiles the
experimental image-only Metal path; the worker selects Metal automatically
when a device is available and falls back to CPU for unavailable devices or
mixed image/audio/video libraries. Audio and video are CPU-only.
EmbeddingGemma 2 ships in v0.6.0 as an opt-in, risk-accepted package. It has
not passed the repository's five-gate installed-app qualification; see the
release risk and limitations.
E5 remains the default. On CPU-only machines, PDF page-image indexing is capped
and slow; PDF text remains indexed.
In the desktop, open Settings → Semantic components, choose EmbeddingGemma
2 (optional), select 128/256/512/768 dimensions and the desired image, audio,
and video checkboxes, acknowledge the fresh index, then select Accept and install.
The signed offer loads automatically; individual artifact files are available under
Technical details if needed. Installation retains the existing E5 library and
activates the separately initialized Gemma library. Open the folder
you want to compare in a pane; in Settings → Semantic library, review its
inclusion and choose Include and index folder. Once indexing progresses,
search or Ask within the indexed folder. The selected embedding dimension is
locked for that Gemma library; image, audio, and video consent can be changed
later in Settings, with explicit confirmation before removing indexed data.
Existing E5 data is not deleted; no migration or representative quality result
is implied by this development bundle. Gemma is opt-in in the macOS, Linux
x86-64, and Windows x86-64 desktop packages. After v0.6.0 the Gemma macOS
package is universal; Intel Macs run it without semantic search, as with the
E5 build. Gemma does not replace the regular E5 build. Windows GPU behavior and CPU
performance have not been qualified; report issues with platform and hardware
details.
Standard release builds remain Gemma-disabled unless the release owner records
the required risk acceptance and approves a new, signed Gemma candidate.
The desktop release compiles semantic-gemma and fetches that candidate's
reviewed, signed target catalog. E5 stays the default, and Gemma search quality
is not established. Included
folders can be removed directly from Settings → Semantic library, even when
their sources are unavailable; confirm the displayed cleanup inventory to
remove their local index data without deleting original files. Moving, deleting,
or temporarily disconnecting an included root does not automatically purge its
index, so remove it explicitly if it should no longer appear in search.
To make scanned PDFs searchable, install OCRmyPDF 16.x or 17.x on the desktop,
then open Settings → Make scanned PDFs searchable and allow OCRmyPDF.
Procyon runs it only for reported PDFs you explicitly select, without replacing
the original PDF. The development launcher (including
pnpm dev:tauri:semantic:ocr) follows this Settings consent; its former
--ocr environment opt-in does not override it. If an installed OCRmyPDF is
not found, launch the desktop from a shell where ocrmypdf is on PATH.
Run the server and frontend in separate terminals:
# Terminal 1
pnpm dev:server
# Terminal 2
pnpm dev:http
Vite proxies /api/* to http://127.0.0.1:8787, including the unbuffered SSE event stream.
Swagger UI is available at http://127.0.0.1:8787/api/v1/docs.
On Windows, the repository commands above work in PowerShell because environment variables are
set through cross-env.
Procyon uses Cmd as the primary modifier on macOS and Ctrl on Windows and Linux.
| Action | Shortcut |
|---|---|
| View / edit | F3 / F4 |
| Copy / move | F5 / F6 |
| New folder | F7 |
| Trash | F8 or Delete |
| Rename | F2 |
| Command palette | Cmd/Ctrl+P |
| Edit location path | Cmd/Ctrl+L or double-click the breadcrumb |
| Quick filter | Cmd/Ctrl+F |
| Find files | Option/Alt+F7 |
| Toggle directory tree | Option/Alt+F10 |
| Disk usage | Cmd/Ctrl+Shift+L |
| Embedded terminal | Ctrl+Backtick or F12 |
| Shortcut reference | F1 |
The quick filter matches plain text anywhere in a name. Use * and ? for a glob that must match
the whole name, and ; to combine masks, such as *.jpg;*.png. Press Esc or the clear button to
remove the filter. While the filter box has focus, Cmd/Ctrl+C and Cmd/Ctrl+X copy or cut the
selected files when no filter text is selected.
The sliders button in the filter box opens an advanced filter: name or glob, type (files, folders,
symlinks), minimum and maximum size (such as 10 MB), modified within or more than N days ago,
hidden state, and executable status. Active criteria show as chips with a one-click clear. Filters
apply to the loaded entries of the current folder only (further pages are not fetched, and the
panel says so); criteria a provider cannot answer (missing size or modified time) are explained
rather than ignored. "Executable" is judged by file extension because listings carry no permission
bits. Save the current criteria under a unique name, then load, rename, or delete it from either
pane; saved filters persist in the settings file.
The location editor accepts absolute paths, ~ or ~/... for your home folder, and a file path
(which opens its folder). Pasted paths are cleaned up: surrounding whitespace, backticks or code
fences, and single or double quotes are removed, and a Markdown-escaped \~ is read as ~.
Disk usage scans the active directory in a transient tab in the other pane. Selecting a treemap folder opens it in the original pane while zooming the treemap; selecting a file reveals it in its parent directory there. Closing the treemap tab restores the other pane's previous tab.
Directory-tree folders can be dragged onto another tree folder, a pane directory, or a tab; table entries can also be dropped onto tree folders. A valid target is outlined. Drops move by default; hold Command or Option on macOS, or Control on Windows/Linux, to copy instead. The ordinary operation confirmation and conflict handling still apply. Use Cut/Copy and Paste for the keyboard equivalent.
In the desktop app, Cmd/Ctrl+C and Cmd/Ctrl+X on local files also put them on the system
clipboard, so they can be pasted in Finder, Explorer or a Linux file manager (best effort, X11).
A cut is offered to other applications as a copy; only Procyon's own paste moves the files.
Remote or archive entries stay on Procyon's internal clipboard and are never downloaded. Files
copied in the system file manager can be pasted into a pane with Cmd/Ctrl+V, which runs a
normal copy job with the usual conflict handling. The browser host cannot access file references
on the system clipboard, so there copy and paste work within Procyon only.
The in-app F1 reference is the authoritative list. Browser-reserved shortcuts may only be
available in the desktop app. The
Total Commander parity audit records design
decisions and intentionally unsupported bindings.
Run the Synchronization profiles… action (command palette) to keep named folder pairs. A profile
stores two provider-neutral roots (local or remote, never credentials), the direction (two-way
newer-wins, or mirror either way), how to compare, include and exclude patterns (*, **, ?;
exclusions win), whether to include hidden files, and the conflict default for files that already
exist. Create, edit, duplicate, delete, and run profiles from the dialog; "Use left/right pane
folder" fills a root from the open panes.
Running a profile always starts a fresh comparison of both roots and shows the usual sync-plan review first; nothing changes until you press Apply. An unreachable root or missing connection, a destination that became read-only, a comparison that times out, and a plan older than 15 minutes (or no longer held by the backend) each stop with a message that names the side and the next step. The last run is saved on the profile. Profiles are stored in the settings file.
An optional schedule (every 5 minutes to 7 days) is off until you enable it. It only runs while Procyon is open, prepares an inspectable plan, and by default waits for you to review it. The alternative policy applies only copies of entries missing on the other side; overwrites and deletions always wait for you.
Select entries in any folder, tab, or provider and use the shopping-basket toolbar button to add them. Open the basket with the adjacent toolbar button; it appears as a tab in the active pane. While that tab is visible, F5 or Add to basket collects the selection from the directory pane (including when the basket pane has focus). When the basket is closed, F5 is Copy as usual. Adding an entry again updates its reference rather than duplicating it. The basket does not cut files or replace the clipboard. The workspace basket is saved locally and its references are checked when opened and again before every action. Its status bar shows file and folder counts, the size of available files and recursively measured folders, the checked subset, and unavailable references. Folder sizes are calculated when the basket opens (and when a folder is added); until then the displayed size is a partial total.
Check individual entries or use the icon buttons (with localized tooltips) to Select all before running an action. The clipboard buttons copy checked, available filenames or full paths as newline-separated text without changing the basket. Deselect all leaves the collection intact; Empty basket removes its references. The Name/Location divider can be dragged or adjusted with arrow keys. Copy, move, and archive target the directory in the other pane; checksums and delete use their existing flows. Actions are unavailable when nothing is checked, and Copy and Move show the normal operation confirmation before starting. Folders can be collected: adding a folder removes any already collected children, while adding an item inside an already collected folder is blocked. Removed children's checkmarks are cleared; the new folder is not checked automatically. Overlapping entries restored from older baskets cannot be acted on together until one is removed. Unavailable entries are excluded from actions. The basket survives navigation and restarts. For remote providers with path-based identities, the recheck also compares known size and modification time; a replacement with identical metadata cannot be distinguished.
Mithril frontend
|
+-- mock client
+-- generated HTTP client + SSE
+-- Tauri commands + channels
|
FileManagerClient
|
fm-application services
|
VFS providers + operation engine
The frontend depends only on FileManagerClient. Axum and Tauri remain thin adapters around the
same application services, while filesystem access stays behind provider-neutral VFS traits.
| Path | Responsibility |
|---|---|
apps/fm-server | Axum API and SSE host |
apps/fm-desktop | Tauri desktop shell |
crates/fm-application | Host-facing capability services |
crates/fm-operations | Job scheduling, progress, cancellation, and conflicts |
crates/fm-vfs-* | Local and remote filesystem providers |
crates/fm-semantic-* | Optional semantic worker, conversion, and library services |
frontend | Shared Mithril and TypeScript interface |
plugins | Bundled Lua, JavaScript action, SPA panel, and icon-theme plugins |
docs | Architecture, security, and design decisions |
TASKS | Detailed implementation contracts and status |
Do not hand-edit generated files under frontend/src/api, frontend/openapi/openapi.json, or the
Rust protobuf output. Use pnpm api:export and pnpm api:generate for HTTP artifacts.
Download packaged builds from GitHub Releases. macOS and x86_64 Linux users can also install through Homebrew:
brew install --cask erikvullings/tap/procyon
Windows packages are published to Chocolatey after community moderation:
choco install procyon
macOS releases are signed and notarized. Windows releases are currently unsigned and can trigger a
Microsoft Defender SmartScreen warning. Desktop builds verify signed update artifacts before
installation. Automatic checks can be disabled in Settings; checks never download, install, or
restart without user confirmation, and a manual Check now action remains available.
The v0.6.0 opt-in Gemma macOS package is Apple Silicon (arm64) only. Later
Gemma macOS packages are universal: Intel Macs run Procyon and receive updates,
but semantic search is unavailable on them. Gemma is also available in the
Linux x86-64 and Windows x86-64 installers. All builds use the
updater-latest channel unless beta releases are enabled. The Gemma package is downloaded directly from its GitHub
Release and does not replace the stable cask or Chocolatey package. E5 remains
the default. This risk-accepted release is not five-gate qualified; CPU
resource ceilings, CPU fallback, Windows GPU behavior, cross-host citation
parity, and upgrade/rollback remain unverified. Use E5 if Gemma does not meet
your needs and report reproducible issues.
The workspace version in Cargo.toml is the source for desktop tags named v<version>.
.github/workflows/release-desktop.yml builds the Developer ID Application-signed and notarized
macOS DMG, unsigned Windows MSI/NSIS installers and Linux .deb and AppImage packages.
Releases move through two channels. A pushed v<version> tag is built as a beta: it is
published as a GitHub pre-release titled "(beta)" and offered only through the updater-beta
update channel, to installs that enabled Settings → Updates → Also check for beta releases. It
does not touch Homebrew or Chocolatey (which has human reviewers). After smoke-testing the beta,
approve it by running the Promote desktop release workflow with the tag: it publishes the very
assets that were tested to updater-latest (and updater-beta), updates Homebrew, and submits
Chocolatey, without rebuilding. To skip the beta step, run release-desktop.yml manually for an
existing tag with channel: stable. Stable builds poll updater-latest; beta builds poll
updater-beta, which also receives every stable release so beta users never lag behind.
Release notes and a manual smoke pass are required before promoting a beta. Protected release
configuration includes APPLE_CERTIFICATE, APPLE_API_KEY_P8, HOMEBREW_TAP_TOKEN, and
CHOCOLATEY_API_KEY. Updater bundles are independently signed on every platform with
TAURI_SIGNING_PRIVATE_KEY and its optional TAURI_SIGNING_PRIVATE_KEY_PASSWORD; the public key
is compiled into the desktop app. The release workflow publishes versioned signed artifacts and
atomically replaces the latest.json asset on the managed updater-latest (stable) and
updater-beta prereleases. Every build, including Gemma release modes, polls one of those two.
Builds up to v0.6.0
polled retired updater-gemma* channels, so the workflow also refreshes any of those that still exist
until existing installs have moved to an updater-latest build.
Optional semantic workers, native runtimes, models, and signed catalogs use the independent
.github/workflows/release-semantic-components.yml flow and immutable semantic-v* releases.
Qualification emits a reviewed fingerprint lock; publication reuses the exact retained artifacts.
Desktop releases only fetch catalogs named by that lock, so semantic component failures do not
block base application packaging and application failures do not rebuild component assets.
The separately opt-in qualify_pdf_vision input runs a read-only installed Gemma worker test on
an eight-page deterministic synthetic scan when paired with qualify_installed_gemma and an exact
retained signed candidate. It runs on all four worker targets, reports per-page throughput and
measured worker peaks, and cannot publish a release; its candidate-bound report explicitly remains
no-go without host/VFS, resource-ceiling, fallback, and quality evidence.
The five-gate-qualified Gemma publication check separately requires reviewed four-target
installed PDF evidence from a successful exact-source qualification run; merely adding signed
PDFium payloads or a worker-only synthetic report cannot satisfy that gate. The distinct
risk-accepted path records the release owner's acceptance of the outstanding risks and does not
represent missing qualification evidence as passing.
The read-only PDF qualification also runs a separate one-page enrolled-host smoke through
the installed worker, replaces that synthetic file with a two-page scan, and checks that
the edited source's two page citations replace the old generation before checking deletion.
That smoke is not full-scan current-content coverage or release approval.
A distinct read-only qualify_pdf_host_sample workflow input runs the same
eight-page synthetic scan through the enrolled host, then replaces it with a
two-page scan and verifies current page citations and deletion. Its report
includes per-page throughput and sampled host/worker RSS; it does not claim a
hard peak or temporary-disk ceiling. A previous full 354-page scan remains
supplementary macOS evidence; full-scan CPU throughput is documented as a
known limitation, not a release gate. Anonymous temporary-disk peak,
cross-host navigation, fallback, rollback, and release resource ceilings
remain unqualified, so these reports do not approve a release.
Pull requests run formatting, lint, tests, architecture checks, and unsigned desktop package
smoke tests through .github/workflows/ci.yml. A push to main reuses the pull-request result
when its tree is identical to the tree a fully green pull-request run tested (for example an
up-to-date squash merge); otherwise it runs the full suite. Release workflows run only from their
documented tag or manual qualification boundaries and always sign and notarize from source.
Procyon is under active development. Native SMB and external remote-desktop launch remain planned; provider, platform, and milestone status is tracked in:
Architecture and operational references:
Before changing an area, read its matching file in TASKS/; it defines the contract and module
boundaries, not only the implementation history. Keep browser and desktop behavior equivalent,
route mutations through the operation engine, and preserve the VFS abstraction.
Before opening a pull request:
pnpm lint
pnpm test
If an external drive reports Unable to show. Denied permissions, macOS privacy controls may be
blocking removable-volume access even when Finder can open it.
Cmd+Q, then reopen it.Some macOS versions expose a separate Removable Volumes permission in the same settings area.
See LICENSE.