Help
A practical guide to the app: install it, connect hosts, move files, work with ZFS, and understand every plan before it runs.
What pālana is#
pālana is a two-pane file manager for people with servers. Either pane can address any machine you can reach over SSH: your NAS on the left, your media host on the right, or your Mac in either pane. Browse, copy, move, and rename across those hosts from one window.
Its central rule: nothing runs until you've seen it. Press the copy key and pālana doesn't copy—it shows you the plan: what it's about to do in plain words, and the exact command underneath. Press Enter, and it runs precisely that, with live output. Press Esc, and nothing happened.
If you can use SSH, you can use pālana. Terminal users will recognize the vim keys; everyone else can start with the window, labeled.
Install it#
- Download the
.dmgfrom the releases page. It is signed and notarized for macOS. - Drag pālana to Applications and open it. macOS 14 or later.
- That's the install. Nothing goes on your servers —
pālana uses the
sshandrsyncthey already have.
Free and open source, GPL-3.0. Currently v0.4-beta; expect rough edges. Report broken or missing behavior in the issue tracker.
Connect your machines#
There's no account and no server list to fill in. pālana reads
~/.ssh/config—the file on your Mac that already knows your
machines. If you can type ssh koan in a terminal and land on
koan, then koan is already in pālana's menus. That's the whole model: your
SSH setup is the setup.
Never touched that file? Open Settings (⌘,) and click Add a host. It asks five small questions—a nickname, the address, your username—shows you the exact lines it will write, backs the file up, and writes them. If you don't have an SSH key yet, it shows you the two commands that make one and install it. It never runs them for you; your keys stay yours.
Two things worth knowing on day one:
local is a host. Point a pane at
local:~ and pālana is a regular file manager for your Mac —
useful long before you have a rack.
~ means the server's home, not your Mac's.
koan:~ resolves to the home directory for the user your config
uses on koan.
Get around#
Click the address at the top of a pane and type host:path —
or press ⇧⌘G for the same thing as a dialog. The ▾ at
the pane's corner lists every host you have. After that, it's a file
manager:
| ↑ ↓ or j k | move the cursor—arrows and vim keys are both first-class |
| ⏎ | enter a folder, or open a file in its Mac app |
| ← / h | up to the parent |
| tab | switch panes |
| / | jump—type a few letters, the cursor finds the file |
| space | select, and move to the next row |
| 8 | star a folder—* opens your favorites |
For the complete key map, see the keyboard. ? opens the same reference inside the app.
Copy & move#
Select files with space. Press y to copy them to the other pane, or m to move them. The panel at the bottom opens and shows the plan; nothing has run yet:
⏎ press enter to run this plan · esc dismisses it move · move to another machine 1 entry · 41.3 GB jodo:/tank/media/camera → koan:/rpool/cold how: rsync, run host-to-host · using the forwarded ssh key $ rsync -a -s --partial --info=progress2 /tank/media/camera/archive-2025 koan:/rpool/cold/ runs only after the copy above is verified: $ rm -rf /tank/media/camera/archive-2025
Read the plan top to bottom. The first line classifies the operation; here, it is a move to another machine. A same-disk move is marked instant. A move that requires copying and deleting is named as such. The middle lines show size, destination conflicts, route, and transport. The final line is the exact command that will run.
Press ⏎ and it runs right there, output streaming, progress bar
moving, ending with done—every step ran and checked out. Press
esc and it's as if you never asked.
Between two servers, the fast path is server to server. Your Mac issues the command; it is not in the byte path. For a 41 GB folder, that can be the difference between minutes and an afternoon.
Notice the last line of the plan too: on a move, the delete half is gated. pālana copies, then counts files on both ends, and only deletes the originals when the counts agree. You watch all of it happen — the counting is two visible commands, not a spinner. If you're interested in why plans work this way, read the plan is the product.
Delete, rename, create#
Same rhythm, different letters—every one shows its plan first.
d deletes the selection—the plan shows the
exact rm before Enter releases it. r
renames the file under the cursor: a name field opens, you
type, ⏎ —and the composed command checks the new name first, so
a rename can never overwrite an existing file. a
creates: type a name for a file, end with / for
a folder. t touches—bumps the modification time,
for when a tool downstream cares.
Drag & drop#
Dragging works the way your hands expect, with one pālana twist: a drop never acts by itself—it composes the same plan the keys do, and waits for your Enter.
Drag between panes to copy; hold ⌥ to move instead. Drop onto a folder row and the files land inside that folder. Drag in from Finder; drag out of a local pane to anywhere on your Mac—Mail, a browser upload, the Desktop.
Edit a remote file#
Press ⏎ on a config file sitting on a server, and it opens in whatever app you'd normally use. pālana notes, in one line, that it's watching: save the file, and it offers to send your edit back to the server — as a plan, naturally. Prefer zero friction? Flip one setting and save just means save: edits go back on their own.
The exception that never changes: if the file changed on the server while you were editing, pālana always stops and asks before your version overwrites theirs.
Preview & the shell#
v turns the right pane into a preview that follows your cursor in the left—text files, images, PDFs. Remote text is fetched frugally (a bounded read, not the whole file); remote binaries stay a facts card instead of a surprise download.
⌘` opens a real terminal on the focused host, right under your
panes—your actual ssh, one live session per host, kept warm. The footer
always tells you who has the keyboard, and ⌘` hands it back. For
quick questions without a shell, ` arms the read keys:
d z s p drop df,
zfs list, zpool status, zpool list
into the panel.
See the whole field#
Press f and the map appears: every machine, its pools and
datasets, what it can do (zfs? rsync? sudo?), and
when you last looked—reachable · 2 days ago. Pick a node,
press ⏎, and a pane is there. Press r on any host to
re-probe it fresh. F floats a deeper version—every mount on
every machine—that you can park on a second display.
pālana shows cached facts with their age and refreshes only when you ask. There is no polling or daemon. When pālana is closed, it has no background process. More on the field →
Datasets & snapshots#
If your servers run ZFS, pālana speaks it natively. In a normal pane, a filled drive mark on a folder means it's a dataset's mountpoint—which is why pālana always knows whether your "move" is instant or actually a 40 GB copy, and says so in the plan.
Press Z and the pane becomes the host's dataset tree. Ten keys
cover the lifecycle—c create, n snapshot,
b roll back, x destroy, mountpoints, mount/unmount —
and every one composes a plan you read first. Destroy asks you to type the
word. The pool root is off limits, period. And when you move a whole
dataset between ZFS machines, the plan upgrades itself to
zfs send | ssh | zfs receive—block-level, dramatically faster
than file-by-file.
Two pointers: the full ZFS page for the details, and the mount grant—the one narrow sudoers line that unlocks mount/unmount, and why everything else needs no root at all.
Refusals & fixes#
When an operation cannot run, pālana states the reason and, where possible, the fix.
no usable ssh key | the host wants a key you don't have installed—pālana shows the two commands (ssh-keygen, ssh-copy-id) and waits |
unreachable | if ssh <host> fails in your terminal, it fails here identically—same ssh, same reason |
mounting needs root | mount/unmount are the one thing needing sudo—the refusal includes the exact line to grant: the mount grant |
won't work—kind mismatch | a file here, a folder there—named before the transfer, not after it half-runs |
probe came back unreadable | an exotic userland answered strangely; stripped-down BusyBox boxes are supported, some vendor firmware refuses |
A host missing from a menu? reload hosts in the ▾ menu re-reads your config. A stale-looking map? r re-probes. More in the FAQ page.
Under the hood#
Implementation details for people who want to inspect the commands before they run.
It's your ssh, verbatim. No embedded SSH library. pālana
spawns the system ssh binary, so your config, keys, agent,
ProxyJump, everything, behave exactly as in your terminal—and
holds one ControlMaster session per host, so after the first connection,
commands run with near-zero overhead. Remote browsing uses the same SSH
configuration, keys, and agent as your terminal.
The plan engine is a pure function. Facts in, plan out, no I/O—which makes it the most tested object in the codebase (the headless core sits above 97% line coverage). The GUI renders state and forwards intent; it is architecturally incapable of composing a shell command. What runs is what the engine planned, byte for byte.
Transfers use standard tools. rsync -a -s
--partial --info=progress2 host-to-host with agent forwarding when the
probe proved it; a tar stream when one end lacks rsync; zfs send -R
… | zfs receive -u for whole datasets (the -u is
deliberate—mounting is root's on Linux, and a receive that auto-mounts
returns an exit code that lies). Deletes gate on verification:
find | wc -l on both ends, or dataset existence for receives,
before anything destructive runs.
State is five plain files in
~/Library/Application Support/palana/—topology cache,
session, settings, favorites, and an append-only operations log. No database.
Delete the cache whenever; the hosts are the system of record.
No daemon. There is no component that can outlive the
window. Swift 6, strict concurrency, SwiftPM; GPL-3.0; and the entire design
record—every architectural decision with its reasoning—is public in the
repo's ho-process/. Full tour:
how it works.
FAQ#
Is it free?
The beta is free—a signed, notarized download, no App Store, no account, no telemetry. At 1.0 the signed build becomes a one-time $29 purchase; the source stays GPL-3.0 and free to compile, forever. File a real issue during the beta and your 1.0 license is on me. The license, plainly →
Mac only?
Yes—pālana is a native Mac app, deliberately. The servers can be anything you can ssh into: Linux, BSD, even BusyBox firmware boxes.
Do I need ZFS?
No. pālana is a full SSH file manager on any host. The ZFS surfaces light up only where a host has ZFS—without it, you simply never see them.
Does it install anything on my servers?
No. It runs the ssh, rsync,
and (if present) zfs your servers already have. Nothing to
deploy, nothing to update, nothing listening.
Is it watching my machines?
No. It runs when you open it and stops when you close it—no daemon, no polling. The map shows cached facts with the date of their last probe.
Do transfers go through my Mac?
Between two servers, no—the fast path runs
server-to-server and your Mac only orchestrates. When the route
does pass through your Mac (a fallback, or you're one end), the
plan's how: line says so. You always know.
SMB? SFTP-only hosts? Docker?
No, no, and no—on purpose. SSH is the only transport, and pālana manages files and datasets, not containers. It is for hosts you administer, not arbitrary remote connections.
Where's my data about pālana itself?
~/Library/Application Support/palana/ —
plain JSON and a plain-text log, human-readable, safe to delete (except
your favorites, which you'd presumably miss).
What's coming next?
An operations queue (today, one plan runs at a time), then more Workbench tools. The build is public—watch the repo.