Skip to content

Releases

v0.12.0

Choose a tag to compare

@github-actions github-actions released this 27 Oct 17:31

Added

  • Microsoft Store: the package registers the pairee command, so the Store installation starts from any terminal, and declares English and Spanish in their regional variants (en-GB, en-AU, en-CA, en-IN, es-MX, es-AR, es-CO, es-CL, es-US) for the Store listings.
  • Microsoft Store: every release is now submitted to the Store automatically, both architectures in one bundle with the "What's new" text of each language, so the Store version no longer falls behind GitHub and WinGet.

Improved

  • Connection dialog: the SFTP protocol reads "SFTP (SSH)", so connecting over SSH is easy to find.
  • Archives: RAR, ISO, CAB, WIM, ARJ, LZH, CPIO, RPM, DEB, XAR, DMG, VHD/VHDX, SquashFS, CHM, split .001 archives and single .gz/.bz2/.xz/.zst/.lzma files open as folders (view, Quick View, copy out with F5, extract) through an installed 7-Zip, which also reads the 7z archives with codecs the built-in reader lacks (Deflate64...). Without a full 7-Zip, a message says to install it.
  • Archives: Extract unpacks every selected archive (not only the one under the cursor) and says so when there is none; Test decompresses every entry instead of only listing them.

Changed

  • Pairee now uses the shared FittyAr folders on every platform. Windows: the program in %LOCALAPPDATA%\Programs\FittyAr\Pairee and the settings in %APPDATA%\FittyAr\Pairee. Linux: the program in ~/.local/lib/FittyAr/Pairee (with the pairee command still in ~/.local/bin), the settings in ~/.config/FittyAr/Pairee, the log in ~/.cache/FittyAr/Pairee and the plugin data in ~/.local/share/FittyAr/Pairee (following the XDG_* variables). macOS: ~/Library/Application Support/FittyAr/Pairee and ~/Library/Caches/FittyAr/Pairee. The folders of earlier versions are moved into place on the first start, by the installers or by the next self-update; nothing is deleted.
  • The official plugin registry is now signed, so Pairee refuses registry files without a valid signature from the first download (REGISTRY_SIGNED); before, a fresh installation only warned. The registry is re-signed weekly.
  • Plugins: child processes start with no stdin by default (they used to inherit the terminal) and Command:cwd needs write access in Secure Mode; Command:timeout is new. The Secure Mode workspace is the active panel's local folder, and the plugin data folder is plugin-data/<name> (migrated from <name>.pairee).
  • Release files no longer carry a second copy named with the Rust target triple (pairee-vX.Y.Z-x86_64-unknown-linux-musl.tar.gz and so on): only the platform names (pairee-X.Y.Z-linux-x64-musl.tar.gz) remain. 0.11.0 was the last release with both, so Pairee 0.10 or older must update to 0.11.0 (or reinstall) before it can update further. The release build jobs are named by platform too.

Fixed

  • Delete: a delete the system refuses (a folder that is read-only or belongs to root, an unreadable subfolder) says how many items were left, the first refused path and why, instead of "files could not be transferred" or the trash library's debug text; a permanent local delete then offers to delete what is left with administrator rights (sudo / UAC). An item whose folder does not let it be removed is refused before anything inside it is deleted (it used to be emptied and then kept), the folders holding a refused item are no longer reported again as "Directory not empty", and a file that could not be removed keeps its permissions.

  • Retry as administrator: renaming with administrator rights on Linux and macOS really runs elevated (it used to ask for the sudo password and then rename without the rights again).

  • sudo pairee (Linux and macOS): root keeps its settings, log, session and plugin data in its own home, ignoring the HOME and XDG_* that sudo -E or an env_keep rule carry over, so it no longer writes root-owned files into the user's folders (which then broke the user's own Pairee) or loads the user's plugins. As root, plugins always run in Secure Mode and a self-update is refused unless root owns the program.

  • Linux installer: sudo pairee works for a user installation. sudo's secure_path leaves ~/.local/bin out, so the installer offers a root-owned copy in /usr/local/lib/FittyAr/Pairee linked from /usr/local/bin/pairee (--sudo-command makes it without asking); later installs refresh it and uninstall removes it.

  • SFTP: servers whose known_hosts entry holds only some of their host keys (typically just the Ed25519 one that OpenSSH picked) no longer fail with a false "host key does NOT match" warning. Pairee now asks the server for a key type already in known_hosts, as OpenSSH does, instead of libssh2's own order (ECDSA first). When the server's key is of a type known_hosts lacks, the message says which key to add instead of warning of an attack.

  • SFTP and Git over SSH on Windows: Ed25519 and ECDSA host keys and the modern key exchanges (curve25519) work. libssh2 is now built on OpenSSL on Windows too; its Windows backend only knew RSA keys, so a server listed in known_hosts by its Ed25519 key was refused.

  • Error and info messages show their whole text, word-wrapped in a box that grows with it; long messages (a refused SSH host key, for one) used to be cut at the box's edge.

  • Linux installer: pairee starts from any new terminal right after install.sh, without exporting PATH by hand. The installer adds ~/.local/bin to the PATH in the startup files of bash, zsh, fish, ksh and tcsh (on Ubuntu the folder was only picked up at the next login), links /usr/local/bin/pairee when run as root, and uninstall undoes both.

  • Archives: copying out of a 7z (F5) or viewing one of its files failed with a checksum error when other entries of the same solid block were passed over.

  • Archives: RAR and ISO extraction failed with the 7-Zip Pairee downloads (it cannot read them); an installed 7-Zip is now used first.

  • Archives: copying out of an archive and Extract follow the conflict setting (overwrite, skip, rename, ask) instead of silently skipping files that already exist.

  • Transfers: a job that fails, or ends with files that could not be copied, shows why; before, the minimized transfer bar vanished without a word.

  • Transfers: Paste treats the panel folder as the destination, like F5: a folder pasted into a folder of the same name nests instead of merging into it (and, after Cut, deleting the source).

  • Transfers: Retry failed retries each failed file where it was going (keeping its folders) instead of flat in the destination, and remote or archive jobs keep their connection.

  • Transfers: starting a queued job (P) no longer pauses the running one, which stalled the whole queue, and really moves it ahead of the other queued jobs.

  • Copy/Move dialog: it starts from the transfer settings (conflict mode, links, attributes) instead of overriding them; "Rename" can be chosen, and the choices are labelled by what they do ("Overwrite older" read "Append", "Copy link" and "Copy target" were swapped).

  • Archives: one item copied out of or into an archive under a name typed in the dialog gets that name instead of a new folder of that name; a renamed copy never takes the name of another extracted file; copies between an archive and a remote panel are refused up front instead of failing file by file.

  • Archives: the Copy/Move dialog's filter applies when copying into or out of an archive; F6 of a folder into a zip with *.txt used to pack every file and then delete them all from disk, and now packs and deletes only the matching ones (a filtered move out of an archive likewise removes only what it extracted).

  • Transfers: F6 of a file onto itself (both panels on one folder, name kept) is skipped as "already there" instead of asking to overwrite the file with itself and then failing.

  • Transfers: progress totals match the work: moves done as instant renames no longer read "3/0", extracting a few entries counts those entries instead of the whole archive (1 file read 1/5000), and the low-disk-space warning is a log line instead of a skipped file.

  • Archives: archive jobs report real paths (the archive file and the folder written to), so the automatic transfer report is saved next to the extracted files instead of in Pairee's working folder, and the "eject" post-action finds the drive.

  • Updater: a copy installed from the Microsoft Store is recognized (WindowsApps folder) and points to the Store for updates instead of trying to replace itself in a read-only folder.

  • Plugins: Secure Mode no longer lets Command:cwd or tar/git/zip path arguments write into the config or other plugins; uninstalling clears the plugin's trust and data; an unreachable blocklist or a corrupt plugins.lock is an error instead of being ignored; installs and install_local are staged and swapped atomically; reloads cannot register a stale plugin; developer package no longer rewrites the source manifest.

  • Transfers and remotes: 7z extraction no longer hangs on stderr output, FTP/S3 paths with spaces or accents and WebDAV absolute links open correctly, SFTP write errors are reported, copying a folder into a same-named panel folder nests, descript.ion handles names with quotes, archive entries with Windows-invalid names are refused, and the admin listing asks for the sudo password.

  • Git: Enter on a stash applies it (p pops), renames show as renames, abort_merge needs a pending operation, and discarding a dangling symlink works.

  • Updater and installers: the download has an idle timeout instead of 120 s total, a second update on Linux no longer writes pairee (deleted), and the installers clear old settings only after the download is verified.

  • Updater: on macOS, a pairee started through a symlink updates the program behind the link instead of replacing the link with a copy.

  • Interface: dragging files onto the command line quotes paths correctly on Windows, the history keys no longer era...

Read more

v0.11.0

Choose a tag to compare

@github-actions github-actions released this 14 Oct 16:03

Added

  • Theme files have a [ui] table of semantic colors (accent, warning, danger, error, success, muted, ...) used by dialogs, the transfer panel, status labels and progress bars; they are also the ui_* entries of "Color groups". Themes without it keep today's colors.

  • Duplicate finder: "Follow symbolic links" option (files below linked folders are searched; a file reached twice counts once and loops are skipped).

  • Plugin API 1.3.0: positional widgets (ui.Rect, Pad, Pos, Bar, Clear, Fill, widget:area(rect), Layout:split(rect), lists of widgets from peek), pairee.cx.tabs / tasks / yanked and panel URLs, File inherits the fields of Cha, and pairee.fs on remote URLs of connections open in a panel (trusted plugins; read-only in Secure Mode).

  • pairee --help (-h) lists the options and subcommands, and pairee plugin|developer|keymap --help the commands of each, in the configured language.

  • Linux and macOS: "Copy attributes" in the Copy / Move dialog also copies extended attributes, and "Copy access control list" copies POSIX ACLs (Linux) and extended ACLs (macOS).

  • Interrupted copies to and from SSH servers resume from the part already written, like local ones.

  • Tar (plain, .gz, .bz2, .xz) and 7z archives can be changed like zip ones: copy files into them, create folders, edit and delete entries. Files and folders can also be moved into and out of zip, tar and 7z archives.

  • install.sh installs the aarch64 build on 64-bit ARM Linux, and install.ps1 the ARM64 build on ARM64 Windows.

  • Git: fetch, pull and push now work with SSH remotes (git@...), using ssh-agent or your default keys in ~/.ssh.

  • Plugins can be enabled or disabled in the Plugin Manager (e); disabled plugins are not loaded.

  • Secure Mode can be toggled in the Plugin Manager (s); trust, enable and Secure Mode changes apply at once by reloading the plugins.

  • Secure Mode can also be switched in the configuration dialog (Plugins tab); OK applies it at once, like the Plugin Manager.

  • Plugin settings can be edited in the Plugin Manager (c or Enter): a form with a checkbox or field per setting, checked against its type, applied at once.

  • Plugin previews in the Quick View can show images, styled text, lists, tables, gauges and split layouts; plugins can prepare previews ahead of time and scroll them with PgUp / PgDn.

  • Plugin API 1.2.0: clipboard, persistent plugin state, path / URL / file-information values, image helpers, theme and runtime information (see docs/api/lua/v1.md).

  • Setting "Overwritten files go to the Recycle Bin" (System tab, transfer_trash_replaced, on by default) decides whether a file replaced by a copy or move is sent to the trash first.

  • SSH preset passwords are stored in the system keyring; passwords found in config.toml are moved there automatically.

  • Plugin registry files are checked against minisign signatures made with the Pairee key pinned in the binary. Once Pairee has seen the registry signed, unsigned registry files are refused ([security] registry_require_signature, on by default; until then they only show a warning).

  • A signed plugin registry index (and blocklist) carries a serial and a signing date: Pairee refuses one older than the last it accepted (an old index replayed by a mirror) or signed more than 30 days ago (a frozen mirror). The limit is registry_max_age_days under [security] in config.toml (0 turns it off). Maintainers sign the registry with cargo xtask sign-registry.

  • The Copy / Move dialog options now work: "Copy files access mode" keeps permissions (Unix) or the access control list (Windows), "Produce sparse files" leaves runs of zeros as holes, "Use copy on write" clones the data instantly where the file system supports it (Btrfs, XFS, APFS, ReFS) and copies normally elsewhere, and "Process multiple destinations" copies to every ;-separated destination (a move copies to all and moves to the last).

  • "Process multiple names" in the Make folder dialog creates every ;-separated name.

  • Copies resume where they stopped: a copy interrupted by a crash, a power cut or a failed attempt continues from the part already written (after checking it matches the source).

  • When a copy overwrites a file, the old file goes to the trash, so undoing the copy brings it back.

  • Terminal screens of command & can be closed (F10, the close box or Delete in the screens list), their process stopped (F8), scrolled back (Shift+arrows, Shift+PageUp/PageDown, mouse wheel) and typed into.

  • Setting "Lines kept per terminal screen" (System tab) bounds the output a terminal screen keeps.

  • Command line editing: cursor keys, Home/End, Delete, Ctrl+W to delete a word and Tab to complete file and folder names.

  • A terminal smaller than 24×8 shows a "terminal too small" notice instead of a squeezed layout.

  • The viewer's key bar shows the encoding key (F8).

  • Help page with the keys of the Vi layer shared by the Neovim and yazi presets.

  • Editor: find and replace dialog (Ctrl+F7 / Ctrl+H; find stays on F7 / Ctrl+F) with case sensitive, whole words, regular expression ($1 groups in the replacement), backward and wrap-around options. Replace goes match by match and "All" replaces every match as one undo step; Alt+F7 / Shift+F3 search backward. Matches on screen are highlighted, and patterns and replacements are kept in the history (Ctrl+Up / Ctrl+Down in the dialog).

  • Syntax highlighting in the editor and the viewer, in new [syntax] theme colors, for 29 languages (Rust, C, C++, C#, Go, Java, Kotlin, Swift, JavaScript, TypeScript, Python, Ruby, PHP, Lua, shell, PowerShell, batch, HTML, CSS, XML, JSON, YAML, TOML, INI, Markdown, SQL, Makefile, Dockerfile, diff). Settings "Syntax highlighting" and "Highlight files up to" (Editor tab, 2 MiB by default) apply at once to open editors and viewers, and "Save as" with another extension switches the language. Languages are TOML files of regular expressions: put your own in the syntax folder of the configuration directory to add languages or replace built-in ones (see the help, "Syntax highlighting definitions").

  • Syntax highlighting understands nested languages and matching delimiters: HTML highlights <script> as JavaScript and <style> as CSS, PHP files are HTML with PHP inside, and Markdown code blocks use the language of their info string; heredocs (shell, PHP, Ruby), Rust raw strings, Lua long brackets and C++ raw strings end at their own delimiter; JavaScript, TypeScript and Ruby regular expressions are told apart from divisions. Definition files can do the same (${1} in end, after, include, host).

  • Your syntax definitions are reloaded when a file in the syntax folder changes, or with "Reload syntax highlighting definitions" (command palette); open editors and viewers are highlighted again, and a file with errors is reported and keeps its previous version.

  • Branch view (Ctrl+Alt+X, Ctrl+Shift+B in the Standard preset, Commands menu): every file below the current folder in one flat list with its relative path, read in the background; sorting, filters, selection and file operations work on it, and the action again (or leaving the folder) returns to the normal listing.

  • Jump to a frequent folder (Ctrl+Alt+Z, z in the yazi preset, Commands menu): visited folders ranked by frecency as zoxide does, with a fuzzy filter. z <words> on the command line jumps straight to the best match. The ranking is saved in frecency.toml only while "Save folders history" is on.

  • Compare files (Ctrl+Alt+C, Commands menu): a unified or side-by-side diff of the two selected files (or the cursor file of each panel) outside Git; binary files show whether they are identical, with their hashes.

  • Duplicate finder (Ctrl+Alt+U, Commands menu): searches the selection or the current folder (smallest size and hash algorithm to choose), groups the duplicates with their sizes and wasted space, marks every copy but the newest, oldest or first, deletes or trashes the marked files and shows a file in the panel.

  • Connection manager (Ctrl+Shift+S, Files → Connect to server...): save, edit, delete and connect SFTP, FTP, FTPS, WebDAV (HTTP / HTTPS) and S3 connections and open them in either panel. Copy and move work between any two places: local ↔ remote and remote ↔ remote (e.g. FTP → S3), with the transfer panel's progress, conflicts, retries and verification.

  • Pairee asks for a missing password or key passphrase in a prompt while connecting, instead of failing: SFTP logins, encrypted SSH keys (also for Git fetch, pull and push), and FTP / WebDAV / S3 connections without a stored password or whose password was rejected. Esc cancels.

  • FTP: file information comes from MLST when the server supports it (one request instead of listing the whole folder).

  • FTPS and WebDAV over HTTPS work with self-signed and private-authority certificates: Pairee shows the SHA-256 fingerprint of a certificate the system does not trust and, when you accept it, remembers it for that server; the TLS options of a connection can also name a trusted PEM file (ca=) or turn checks off (insecure=true, with a warning on every connection).

Improved

  • The frequent-folder list leaves out (and forgets) local folders that no longer exist when it opens, not only when one is chosen.
  • The branch view is kept in the session (a restored tab shows it again) and refreshes itself when files change in any subfolder (watched natively, or polled on network folders and SFTP).
  • When a plugin copies text of several lines to the clipboard, Pairee says so ("Plugin X copied N lines to the clipboard"), so a command hidden on a later line does not get pasted unnoticed.
  • Plugins in Secure Mode can no longer use arguments of an allowed tool to run other programs (git -c core.sshCommand=…, --upload-pack, tar --to-command, fd --exec, rg --pre, fzf --preview, ...); sed an...
Read more

v0.10.0

Choose a tag to compare

@github-actions github-actions released this 14 Oct 16:02

Added

  • pairee --version (-V) prints the installed version.
  • macOS builds (Intel and Apple silicon) on every release; the built-in updater picks them up.
  • Full mouse support where the terminal reports it: panels (click, double click, Ctrl/Shift click, right click or right drag to tag, column titles sort, wheel), drag and drop of files onto the other panel, folders, tabs or the command line, a draggable border between the panels, the menu bar and its drop-downs (a hidden bar shows when pointing at the top row), the function-key bar, and every dialog control (buttons, lists, check boxes, tabs, text fields). Dialogs move by their top border and flowing ones resize by their corner. Plugins get an on_mouse event.
  • Mouse setting Auto / On / Off (was on/off): Auto captures the mouse only where the terminal reports it. PAIREE_MOUSE=0|1 and --no-mouse override it, and the toggle_mouse_capture action hands the mouse back to the terminal to select text.

Changed

  • Release tooling: cargo xtask release replaces the PowerShell and Bash bump scripts and updates every dependency to its latest compatible version before each release. Releases are built only from commits that pass every check, every package is smoke-tested, and a draft is published after approval. A pre-push hook (cargo xtask install-hooks) runs rustfmt and the spell check locally.

Fixed

  • With the mouse setting off, Pairee still captured the mouse, so the terminal could not select text.
  • Programs started from Pairee (shell commands, file associations, sudo) received mouse escape sequences when the pointer moved.
  • The .deb package declared an invalid dependency ($default), so dpkg and apt refused to install it.
  • The Windows installer no longer asks for administrator rights: it installs for the current user, as it always did, and new terminals see the updated PATH right away.

v0.9.0

Choose a tag to compare

@github-actions github-actions released this 09 Oct 19:54

Keyboard

  • Presets for the program you come from. Four keymaps keep the keys of their programs: Norton Commander / Far (the default), Standard (Windows Explorer, VS Code, Total Commander), Neovim (Vim, vifm, oil.nvim, nvim-tree, with a Space leader) and yazi. Each says what plain letters do: type into the command line (Far), jump to a file (Explorer) or act as commands (Vim, yazi). Key sequences (g g, Ctrl+w h), the leader key and Norton's Alt+letter quick search are supported. The F1 help has a reference page per preset (generated from the presets, pairee keymap print --preset <name> --lang <code> prints it) and a "Coming from another program" guide.
  • Keyboard shortcuts list (Ctrl+K in Norton, Ctrl+K Ctrl+S in Standard, g? in Neovim, ~ in yazi, Options → Keyboard shortcuts... in the F9 menu, or Options → Configuration → Interface): every command of the panels, editor, viewer and dialog lists with its keys, searchable by name or by pressing a key. F2 rebinds, Ins adds a key, Del removes, F8 restores, Ctrl+←/→ previews another preset, F9 saves your preset. Changes apply at once. It replaces the which-key overlay; the command palette now shows each action's key.
  • New actions available in every preset: file clipboard (yank / cut / paste, paste overwriting, paste as link), recycle bin vs. permanent delete, select all, visual (range) selection, back / forward through visited folders, home and root folder, half-page moves, search in the panel with next / previous match, create a file or folder, rename the name only, copy name / folder path, focus a given panel, cycle view and sort, and Far's command-line keys (Ctrl+Enter, Ctrl+F, Ctrl+E/Ctrl+X, Ctrl+Y) and Ctrl+P / Ctrl+B.
  • Editor, viewer and dialog lists take their keys from the preset too, and help, screens, palette and the shortcuts list work over the editor and viewer with whatever key they have.
  • Plugins declare commands with suggested keys per preset ([[commands]] in manifest.toml); they join the keymap, the palette and the shortcuts list, never take a key the preset uses, and can be rebound. pairee.keymap.list() / chord_for() read the keymap and pairee.emit() runs any action.

Changed (keyboard)

  • Norton Commander / Far follows NC/Far again: F7 makes a folder, Shift+F6 renames, Ctrl+Shift+F6 is the multi-rename tool, F11 opens plugins, Ctrl+\ goes to the root, and Alt+letter is the quick search. Pairee's own keys moved to Ctrl+Alt+letter: tabs Ctrl+Alt+T/W/O, Git Ctrl+Alt+G, SSH Ctrl+Alt+R, folder sizes Ctrl+Alt+S, disk usage Ctrl+Alt+D, hotlist Ctrl+Alt+B, quick filter Ctrl+Alt+F; redo is Alt+Shift+Backspace.
  • The VSCode preset is now Standard (vscode still works as a name).
  • Alt+F3 opens the alternative viewer again.
  • The F2 user menu offers new tab (T), open in a new tab (O) and close tab (W) while usermenu.toml defines no commands of its own.

Migration

  • Your keymap is updated automatically when the files in keymaps/ are copies Pairee wrote; a copy you edited is kept and the new version is saved next to it as <name>.toml.new.
  • [custom_bindings] in keybindings.toml becomes [overrides.all]. An override now replaces the action's keys and takes the key from the action that had it, instead of being rejected.
  • Plugin [keybindings] tables keep working; [[commands]] is the new format.

Added

  • Undo and redo of file operations: Alt+Backspace / Files → Undo reverses the last rename, multi-rename, move, copy (only the new copies are deleted, never a file that overwrote another one), make folder, create link or send to trash (restored from the Recycle Bin / trash on Windows and Linux), and Ctrl+Y / Files → Redo repeats it. The menu shows the operation (Undo: Move (3 items)); a confirmation lists what will be reversed. Every entry is checked first (still there with the same size and date, original location free) and whatever changed is skipped and reported, never overwritten. Undo and redo run through the Transfer Engine and the rename executor. The journal keeps the last 50 operations in memory; permanent delete, wipe and SSH transfers are recorded as not undoable.
  • Multi-rename tool (Ctrl+Shift+F6 in Norton, Files → Multi-Rename) for the selected items: name and extension masks with [N], [N2-5], [E], [P], [C] (start, step, digits) and [Y][M][D][h][m][s] placeholders, search & replace (plain or regular expression, optional case-insensitive), case transform, and a live old → new preview that flags empty, invalid, duplicate and already-existing names. Renames are ordered so nothing is overwritten (swaps go through a temporary name) and are undone if one fails. Works on local and SSH panels.
  • Commands → Synchronize folders (Total Commander "Synchronize dirs"): compares both panel folders recursively in the background (size and modification time with the configurable tolerance, optionally file contents with the transfer hash algorithm; filter mask with include/exclude globs; hidden files can be ignored), lists every difference with an action per item (copy →, copy ←, delete, skip) and totals of files and bytes, and applies the plan as Transfer Engine copy/delete jobs. Directions: left → right, right → left, both ways (newer wins) and mirror (deletes extras on the right, after an explicit confirmation).
  • Folder shortcuts can now be assigned: Commands → Folder shortcuts lists slots Ctrl+Alt+1 … Ctrl+Alt+9; Ins/Space (or the slot digit) assigns the current folder and Del clears it. Shortcuts are saved in bookmarks.toml in the config folder.
  • The directory hotlist (Ctrl+\, also Commands → Directory hotlist) is now persistent: Ins/+ adds the current folder, Del/- removes an entry. Default entries are localized.
  • The Git panel has a key in every built-in keymap, as the menu already advertised.
  • Built-in keymaps now pick up newly shipped bindings even when an older copy of the keymap file exists in the config folder (user-defined chords always win).
  • Editor and viewer honor the "Tab size" settings when displaying tab characters.
  • Built-in editor: undo/redo (Ctrl+Z / Ctrl+Y, typing runs are one step), save as (Shift+F2), Tab key, Home/End and Ctrl+Home/Ctrl+End, horizontal scrolling for long lines, and F6 in the viewer opens the file in the editor. Line endings (LF/CRLF), the final newline and the UTF-8 BOM are preserved on save. Saving asks before overwriting a file that another program changed or an existing "save as" target. Files that are not valid UTF-8 or larger than 64 MiB are refused with an explanation instead of being corrupted.
  • Built-in editor: text selection with Shift + arrows/Home/End/PgUp/PgDn/Ctrl+Home/Ctrl+End, Ctrl+A and mouse drag (the mouse wheel scrolls); vertical block selection with Alt+Shift + arrows or Alt + drag; copy/cut/paste with Ctrl+C/Ctrl+X/Ctrl+V (also Ctrl+Insert/Shift+Delete/Shift+Insert) through the system clipboard, falling back to an internal clipboard over SSH or without a display. Typing, Backspace and Delete replace the selection, each paste or cut is one undo step, and bracketed paste inserts every pasted line. The key bar shows Shift+F2 (save as) and Shift+F7 while Shift is held, and F3 (next match).
  • Editor settings that had no effect now work and are back in Options → Configuration → Editor/Viewer: expand tabs, auto indent, show line numbers, cursor at the end, lock editing of read-only files and warn when opening read-only files.
  • Panel visibility, view mode, sort order and long-names mode from the last Save setup are the defaults of the panels when there is no session to restore.
  • Session restore (new setting Restore last session, restore_session, on by default, Options → Configuration → Interface): on exit Pairee saves every tab of both panels (folder, archive, view, sort, filter, name, lock, entry under the cursor), the shown tab per side, the focused side, panel visibility and Quick View to session.toml (atomic write, owner-only on Unix) and reopens them at startup. Missing folders open their nearest existing parent; SFTP tabs are saved by SSH preset name (never a password) and reconnect only when shown, falling back to the home folder with a notice; a damaged file is ignored with a logged warning and kept as session.toml.bak.
  • Command-line folders: pairee <left> [<right>] opens them in the shown tab of each panel (overriding the restored ones; a file opens its folder with the cursor on it). --cwd-file <file> writes the focused panel's folder on exit so a shell wrapper can cd there, and --print-cwd prints it; wrapper functions for bash, zsh, fish and PowerShell are in the user guide and README.
  • The "natural" sorting collation now sorts numbers inside names numerically.
  • pairee.fs.data_dir() returns the plugin's private data directory, the only location an untrusted plugin may write to.
  • Support for untracked files in the Git diff viewer, allowing inspection of newly added files with full contents.
  • Home and End key navigation in the unified Git diff viewer.
  • Context-sensitive empty list notifications across all Git panel tabs (Log, Branches, Stash, and Tags).
  • Full suite of unit tests for file diffs (staged, unstaged, untracked), commit diffs, and stash diffs.
  • Clipboard paste support (Ctrl+V) in the Git clone dialog to easily paste repository URLs and target directory names.
  • Detection and notice for modified and untracked binary files in the unified Git diff viewer.
  • Guard and modal error notification preventing deletion of the currently checked-out branch in the Git panel.
  • Validation guard preventing commit amend (Ctrl+A) on repositories without prior commits.
  • Protection and modal alert preventing push and pull operations while HEAD is in detached ...
Read more

v0.8.1

Choose a tag to compare

@github-actions github-actions released this 22 Sep 18:07

Added

  • Remote branch checkout support: selecting a remote branch in the Git panel now automatically creates the local branch, sets up upstream tracking, and checks it out.
  • Remote branch merging support directly from the Git branches list.
  • Granular staging support in Git panel with visual [staged] and [staged+] status indicators.
  • Keybindings in Git Status tab: a to stage all changes, A to unstage all changes, x/Delete to discard changes with confirmation dialog, i to add path to .gitignore, and X to abort in-progress merges.
  • Commit amend support (Ctrl+A toggle in commit dialog).
  • Multi-remote management dialog in Git panel (R in Branches tab) to list, add, and remove remotes.
  • Remote branch deletion directly from the Branches tab with confirmation dialog.
  • Automatic upstream tracking configuration (--set-upstream) when pushing branches without an upstream.
  • Branch creation from any selected commit in the Git Log tab (b/n).
  • Tag creation from any selected commit in the Git Log tab (t).
  • Cherry-pick and Revert operations with confirmation dialogs from the Git Log tab (c and r).
  • Clipboard copy of commit SHA in Git Log tab (y).
  • Incremental pagination and continuous loading when scrolling through commit history.
  • Stash entry diff inspection (d in Stash tab).
  • Stash clearing operation (C in Stash tab) with confirmation dialog.
  • Include untracked files toggle (Ctrl+U) in Stash Save prompt.
  • Interactive branch rebase (b in Branches tab) with confirmation dialog.
  • Ahead and behind commit counter indicators ([↑X ↓Y]) displayed for local branches.
  • Dedicated Tags tab in Git panel (git_tab_tags) displaying tags with target commit hash and annotated messages.
  • Full tag management in Git panel: create (n), delete (d/Delete), checkout (Enter), and push tags to remote (u).
  • Git repository initialization action (GitInit) accessible from top menu to initialize repositories directly in the active panel.
  • Interactive Git Clone dialog (GitClone) accessible from top menu with HTTPS/SSH credentials and auto-derived target directories.
  • Active Git branch indicator in navigation panel headers (e.g. [git: main]).
  • File Git status indicators ([M], [A], [?], [D], [!]) and status color highlighting in all file navigation panels.

Improved

  • Dynamic remote resolution: git operations (fetch, pull, push) now automatically use the branch's tracked remote instead of hardcoding origin.
  • Authentication expanded with support for id_ed25519, id_ecdsa, and standard Git Credential Manager for HTTPS.
  • Git branch list now filters out symbolic */HEAD references (such as origin/HEAD).
  • Git checkout confirmation dialog now safely returns to the Git panel upon cancellation and refreshes file explorer panels upon success.
  • Git commit prompt commits only staged files when files are explicitly staged.

Changed

Deprecated

Removed

Fixed

  • Resolved Linux and cross-platform Clippy linter warnings (collapsible_if, missing_transmute_annotations, io_other_error, let_and_return) in CI pipelines.
  • Addressed cargo deny advisory RUSTSEC-2017-0008 (unmaintained transitive dependency serial pulled by portable-pty).

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 08 Sep 23:49

Added

  • Which-key overlay (Ctrl+Shift+K) lists the live keymap chords with labels, fuzzy-filters them, and runs the selected action with Enter. While a multi-key sequence is in progress, a prefix hint shows the remaining chords (same keybinds map, not a second keymap). Esc cancels the prefix.

  • Copy path (Ctrl+Shift+C, Files menu, command palette) puts the hovered or tagged full path(s) on the OS clipboard. Command palette is bound as Ctrl+Shift+P in the shipped keymaps.

  • Short threat model (docs/THREAT_MODEL.md) for plugins, SSH presets, updates, and the elevated helper.

  • Structured tracing architecture (tracing, tracing-subscriber, tracing-appender) with rolling daily logs and environment filter control.

  • Cross-platform POSIX and Windows signal handling (SIGTERM, SIGINT, SIGHUP, SIGQUIT, and console control events) for clean TUI restoration.

  • CI test coverage workflow using cargo-llvm-cov to measure and report codebase test coverage.

  • Plugin confirm, input, and which-key dialogs are real TUI overlays (pairee.confirm / pairee.input / pairee.which); Enter/Esc (and Y/N) reply to the waiting plugin.

  • Typed File userdata (name, path, url, size, is_dir, is_symlink) and pairee.cx (cwd, hovered, selected) filled inside pairee.sync.

  • Lua File metadata: mime, mtime, is_hidden, is_exec (Lua API 1.1.0).

  • Plugin filesystem extras: mkdir, remove, rename, copy, read_dir, and file() (File userdata).

  • pairee.Command process builder with piped Child streaming (write_all, read, wait_with_output).

  • Optional feature flags in Settings → System: SSH, plugins, and image preview (Git already had a toggle). Existing configs stay enabled.

  • EN/ES translation keys are now complete and checked in CI (scripts/check_translations.py, docs/i18n.md).

  • Parser smoke-fuzz tests (globs, descript.ion, plugin manifests, settings TOML) so junk input cannot panic.

  • CI tests run on macOS as well as Linux and Windows.

  • First-run keymap onboarding (Norton / Neovim / VS Code). Existing configs skip the dialog.

  • Versioned Lua plugin API v1.1.0 (pairee._lua_api_version, docs/api/lua/).

  • CI acceptance plugins under tests/plugin_acceptance/ (surface, fs, cx/utils, Command echo).

  • pairee.emit, pairee.notify, and pairee.file_cache are callable functions (they were nested tables).

  • Improvement tracking document at docs/IMPROVEMENT_PLAN.md with phased roadmap and progress checkboxes.

  • Integration tests under tests/ cover isolated temp workspace, Settings TOML roundtrip, shipped keymap presets, packaged EN/ES keys, AppState panel roots, and zip extract.

  • Project-level rustfmt.toml and clippy.toml for consistent CI quality gates.

  • Declared MSRV (rust-version = "1.88", required by tui-scrollbar) and package metadata in Cargo.toml.

  • Transfer Strategy backends (local / ssh) under src/fs/transfer/backend/ with unified job submission.

  • Command palette (Ctrl+Shift+P) to filter and run logical actions.

  • Fractional scrollbars via tui-scrollbar (shared helper in src/ui/scrollbar.rs) on help, viewer/quickview, history lists, transfer panel, git panel, and related popups.

  • Mouse drag and jump-to-click on scrollbars (ScrollBarInteraction, hit targets registered each frame, EnableMouseCapture).

  • Unicode-aware file-name truncation helpers (unicode-width + unicode-segmentation) for panel columns.

  • Bracketed paste: pasted text lands in the CLI or the open text prompt (rename, apply command, mkdir, …) as one string instead of fake keystrokes.

  • Settings → Interface shows keymap validation (errors, warnings, bound count) and a “View keymap issues” overlay. Far-style Gray+ / Gray- / Gray* aliases are documented as mapping to Plus / - / *.

  • CI draw/resize smoke tests via ratatui TestBackend (not a substitute for a human pass on Windows Terminal / conhost / Linux).

  • CI cargo deny job checks licenses, RustSec advisories, yanked crates, and crate sources (deny.toml).

Improved

  • Complete codebase modularization under the Single Responsibility Principle (SRP), bringing all .rs files across the project strictly below 300 lines (zero files exceed 300 lines).

  • Decoupled PopupType variants into dedicated sub-structures (GitPanelState, SshConnectPromptState, ConfigurationDialogState, PluginMenuState, CopyMovePromptState) to keep overlay payloads modular, lightweight, and maintainable.

  • Background Terminal (command &) and apply-command run on a real PTY (Windows ConPTY / Unix pty), so programs that check for a TTY can emit colors and use normal line buffering.

  • Apply-command (Ctrl+G) opens the Terminal screen and shows captured stdout/stderr with ANSI colors, while the Transfer Engine still tracks progress.

  • Command palette entries come from a shared ActionDef catalogue (id + category) instead of a second hardcoded name list.

  • Native 7z extract/list uses maintained sevenz-rust2 instead of unmaintained sevenz-rust (Zip-Slip sanitization kept).

  • Command palette filters with Helix nucleo-matcher (fuzzy ranking) instead of substring contains.

  • MSRV is 1.93 (required by sevenz-rust2).

  • Clipboard writes use arboard instead of shelling out to clip / xclip / wl-copy (update “copy command” and Copy path).

  • Background Terminal screen (command &) renders ANSI SGR colors from captured stdout/stderr instead of showing raw escape codes.

  • Full-screen terminal clear runs inside the synchronized-update region, and only on resize or after a native TTY/admin restore.

  • Keyboard enhancement and focus-change sequences are enabled only when the terminal supports them (Unix query; Windows CSI push), and popped only if they were pushed.

  • File-association and CLI command lines split with POSIX shlex (quoted words) on Unix, and quote-aware tokens on Windows so "C:\\Program Files\\App\\app.exe" %f stays one program name.

  • Keybindings engine rebuilt on the keybinds crate: invalid chords are rejected, duplicate chords across actions are rejected, and Norton/Neovim/VSCode presets load from validated TOML.

  • TUI draw path uses synchronized updates and dirty-flag rendering to reduce flicker/glitches.

  • Scroll indicators use theme colors and proportional thumbs instead of ratatui’s full-cell default.

  • Clippy collapsible-if and related lint cleanups so cargo clippy -- -D warnings is green again.

  • Clippy 1.98 cleanups (useless_borrows_in_formatting, question_mark in Lua t() lookup).

  • CI check workflow now targets master/main, runs tests on Ubuntu and Windows, uses Node 24-aligned actions, and rejects crate-level clippy::all allows.

  • Documentation index (docs/README.md) lists design docs with Implemented/Partial/Planned status.

  • README (EN/ES) links corrected to help/en and help/es, project tree updated, plugin system no longer labeled as only planned.

  • Transfer worker split into focused modules (scan, delete, copy, helpers) under src/fs/transfer/worker/ using a facade orchestrator.

  • Copy, move, and delete (including SSH) now use the Transfer Engine progress UI instead of the legacy modal-only path.

  • Wipe, compress, extract, and apply-command jobs use the Transfer Engine queue and minimized panel (one consistent progress UX).

  • Cooperative cancel for archive compress/extract (native formats check cancel between entries; external 7z is killed on cancel).

  • Session state grouped into PanelPair, HistoryState, and UpdateState on AppState.

  • Split oversized UI modules (transfer panel, history lists, settings actions, plugin dev options) into focused files.

  • Internal F3 viewer split into src/ui/viewer/{state,text,hex,image}.rs.

  • Overlay PopupType paste handling and plugin widgets live in focused files under src/app/state/popup/.

  • Overlay dialogs live in src/app/state/popup/ (QuickViewDialog boxed; config settings boxed) so PopupType is no longer a huge enum payload.

  • Plugin updater, directory listing, and Settings split into focused modules.

  • Dialogs use a DialogStack (state.dialogs) with replace/push/pop instead of a single Option popup.

  • Background channels (search, SSH, terminal, updates, plugin progress) are polled in place instead of take/put-back.

Changed

  • Application logic lives in the pairee library crate; src/main.rs is a thin tokio entry so tests can use pairee.
  • Replaced inherited rustc-style .gitignore with a Pairee-specific ignore list.
  • Plugin manager core module renamed to lifecycle to avoid module-inception nesting.
  • Long-running file jobs no longer use a separate modal progress dialog.

Deprecated

Removed

  • Local temporary .tmp* workspaces and the vendored local example/ reference tree from the working tree (still ignored by git).
  • Legacy ops_worker spawn stack, progress_rx / BackgroundOpContext, and the CopyProgress modal UI.

Fixed

  • Trusted Lua plugins load again (StdLib::ALL_SAFE instead of ALL, which rejected debug under new_with).
  • Clippy is enforced without #![allow(clippy::all)] in src/main.rs.
  • Outdated status banners on transfer-engine and plugin-system design docs.

v0.7.2

Choose a tag to compare

@github-actions github-actions released this 06 Aug 20:46

Added

  • Interactive dialog for file associations enabling navigation, addition, editing, and deletion, with clear visual prompts and helper hints on keys to use.
  • Expanded Git support with comprehensive backend APIs for individual file staging, unified diffs, remote syncing (fetch, pull, push), advanced branch management, stashing, resets, merges, and repository clone/initialization.
  • New Git dashboard TUI integration with an interactive 4-tab panel (Status, Log, Branches, and Stash).
  • Unified diff viewer modal with syntax-colored lines for additions, deletions, and hunks.
  • Interactive popup dialogs for stash creation, branch creation/renaming, and safe confirm-action dialogs for resets, merges, and stashes.
  • New Spanish translation and updated English manual for Git integration reference.
  • New F7 Rename action that prompts only for the new filename (with a live collision warning if a sibling already exists).
  • Rename command added to the Top Menu Bar → Files submenu.
  • F-key shortcut bar now reads each slot from the active keybinding resolver, so the bar always shows what each F-key actually does.
  • Create folder (MkDir) action added as a default option in the User Menu (F2), bindable to key 6. The action opens the same name prompt dialog used everywhere else.

Improved

  • Alt+G Git panel initialization now populates stash data immediately on launch.
  • F2-F12 F-key shortcut bar now matches the actual action each key triggers: F2 = User Menu, F9 = Top Menu, F7 = Rename, F11 = empty (when not bound).
  • Bottom F-key bar no longer claims F11 = Plugin by default — the F11 slot now renders blank until the user explicitly rebinds the key.

Changed

  • Expanded default file association presets to support a wide range of popular formats (text, code, images, audio, video, documents, and web pages).
  • F6 dialog renamed from "Rename/Move" to "Move" only — Rename is its own modal now.
  • Make Folder and Plugin commands moved out of the F-key bar into the Top Menu Bar → Files submenu so the bar can focus on the most frequent operations.
  • The plugin system (PluginMenu action) is no longer reachable from F11. It is now accessible exclusively via Top Menu Bar (F9) → Files → Plugin commands. Power users can still rebind F11 to plugin_menu in keybindings.toml if they prefer the old layout.

Removed

  • Default keymap no longer binds F7 to MkDir or F11 to PluginMenu. MkDir lives in the User Menu (F2) and PluginMenu lives under the top menu bar (F9 → Files). Power users can still rebind the keys in keybindings.toml.

Fixed

  • Single file copy target path resolution so copying a file to a target destination path no longer creates an extra directory with the file name.
  • F-key bar in keymaps/*.toml preset files now reflects the new keymap (F7→Rename, no F7→MkDir, no F11→PluginMenu), so users upgrading keep the bar and behavior in sync.
  • Outdated doc comment on Action::MkDir that still claimed the action was bound to F7.

v0.7.1

Choose a tag to compare

@github-actions github-actions released this 20 Jul 23:53

Fixed

  • Fixed PowerShell command execution syntax in GitHub Actions workflow (.github/workflows/release.yml) during MSIX packaging.
  • Fixed directory tree removal when moving folders in the background Transfer Engine so that empty source subdirectories and root folders are completely cleaned up.

v0.7.0

Choose a tag to compare

@github-actions github-actions released this 20 Jul 23:17

Added

  • High-performance asynchronous Transfer Engine inspired by TeraCopy, enabling non-blocking background file copying, moving, and deletion.
  • Redesigned Transfer Panel with a split two-column layout featuring a vertical jobs queue sidebar, detailed job inspector, options controls, speed statistics, and logs.
  • Advanced transfer controls including queueing multiple jobs, pause/resume, file skipping, job cancellation, speed throttling, and error handling options (halt_on_error).
  • Cryptographic hash verification supporting CRC32, MD5, SHA-1, SHA-256, and BLAKE3 algorithms, with automatic HTML and CSV post-transfer report generation.
  • Multiplatform post-transfer automated actions: system shutdown, sleep, hibernate, application exit, and drive ejection.
  • Interactive file conflict resolution dialog with batch options (Overwrite All, Overwrite Older, Skip All, Rename All) and full path visibility.
  • Support for Windows Long Paths (Unicode \\?\) in direct I/O operations for filenames exceeding 260 characters.
  • Interactive TUI Plugins Manager (F11) with tabbed browsing, real-time registry search, background installation, update management, and remote blocklist filtering.
  • Dedicated TUI Developer Tools tab under the Plugins Manager featuring an interactive plugin initialization wizard, lint auditing, dynamic packaging, and test harness execution.
  • Command-line interface additions for plugin management (pairee plugin check-updates, update, and multi-plugin installation).
  • Persistent transfer folder history (transfer_history.toml) saving recent source and destination paths.

Changed

  • Pressing Enter on a file now opens it directly in Pairee's native viewer (text, image, or hex). External editor execution on Enter is now optional via the enter_use_external setting.
  • Replaced the translation backend with a portable, symmetric TOML translation engine (lang/en.toml, lang/es.toml) with local override support.

Removed

  • Removed the obsolete horizontal transfer queue tab in favor of the new vertical jobs sidebar.

Improved

  • Improved disk free space checking across platforms before starting file transfers.
  • Optimized TUI rendering performance during large-scale file transfers using a sliding display window and log cap.
  • Enhanced search experience in the Plugins Manager with instant background filtering as you type and keyboard navigation support.
  • Added dynamic color coding in the Transfer Panel to clearly distinguish job statuses (green for completed, yellow for paused, red for cancelled or failed).
  • Updated help menu (F1) to dynamically load localized documentation files (help/<locale>.md).
  • Centralized and localized all remaining hardcoded user-facing strings across application dialogs, menus, and editor screens in English and Spanish.

Fixed

  • Resolved application startup crash (STATUS_DLL_NOT_FOUND) on clean Windows installations.
  • Fixed an issue where cancelling a background transfer job could freeze or leave the engine in an un-restartable state.
  • Fixed directory deletion failures caused by leftover empty file description files (descript.ion).
  • Fixed text entry and Tab key focus traps inside the Plugins Manager search input.
  • Fixed visual display artifacts and text overflow in the TUI Transfer Panel and Developer Console.
  • Fixed plugin packaging validation and skeleton generator fallbacks when operating offline.
  • Hardened CLI system execution against command injection vulnerabilities.

v0.6.1

Choose a tag to compare

@github-actions github-actions released this 29 Jun 00:26

Added

  • A rule in .agents/AGENTS.md to enforce checking and running workspace customization skills automatically.
  • WinGet installation helper submenu to run.bat and run.sh for auto-detecting, forcing architecture installs (x64/arm64), upgrading, and uninstalling Pairee.
  • Comprehensive docs/winget-submission-guide.md documenting the manual first-time submission, PR troubleshooting, and GitHub Actions release automation.
  • Detailed docs/technical/microsoft-store-publishing.md explaining how to package and publish Pairee to the Microsoft Store as an MSIX package without a paid certificate.
  • Microsoft Store (MSIX) Developer Menu submenu in run.bat and run.sh for local packaging, test certificate generation, signing, and installation of MSIX packages.
  • MSIX manifest template (AppxManifest.xml) and asset placeholders under manifests/msix/.
  • Automatic MSIX packaging and version bumping for Windows targets integrated into the .github/workflows/release.yml release workflow.
  • Desktop shortcut creation option and Windows Control Panel uninstallation icon support in the Inno Setup installer script.
  • Custom Windows resource compilation (manifests/windows/pairee.rc) to embed the new multi-resolution icon (pairee.ico) directly inside the built pairee.exe executable.
  • Linux desktop launcher entry (manifests/linux/pairee.desktop) and SVG/PNG app icon packaging in Cargo.toml for Debian and RPM packages.

Changed

  • Updated local WinGet package manifests for v0.6.0: corrected the license to GPLv3, added the arm64 installer architecture details with valid SHA-256 hashes, and added the Spanish (es-ES) translation locale.
  • Configured Windows targets (MSVC) in Cargo to statically link the C runtime library (CRT), eliminating runtime dependencies on VCRUNTIME140.dll.

Improved

  • Enlarged the self-update popup, added line wrapping for release notes, styled markdown headers, and implemented vertical scrolling with a scrollbar.
  • Cached the installation method detection using OnceLock to prevent TUI thread freezes during self-update rendering and activation.

Fixed

  • Output duplication in scripts/extract_changelog.sh that caused duplicated release descriptions on GitHub releases.
  • WinGet validation error (STATUS_DLL_NOT_FOUND) resolved by adding VC++ Redistributable package dependencies in the manifest.
  • Syntax errors and rendering bugs in run.bat helper script resolved.