v0.9.2
Two one-time steps
This build is not signed with an Apple Developer ID and not notarized, so macOS blocks
the first launch. Allow it once:
- macOS 15 Sequoia and later β double-click, dismiss the warning, then open
System Settings βΈ Privacy & Security and click Open Anyway. Apple removed the
Control-click shortcut for unsigned apps in macOS 15, so right-clicking does not help.- macOS 13β14 β right-click the app βΈ Open, then confirm.
Then answer the folder prompts once β macOS asks separately for Desktop, Documents and
Downloads the first time the app looks at them. Allow them and it stays quiet from then on.
Named workspaces, a keyboard that works the same in every view β and the packaging defect behind
"it keeps asking for folder permissions".
A workspace is a named work context now rather than a saved layout: both panels, every tab, the
marks, the filter, the tree and the window's whole arrangement switch together, and switching back
restores what you left. The panel's keyboard vocabulary, which only ever worked in the details view,
now works in Brief, Icons and Gallery as well, and those views draw what is marked. The quick search
and the quick filter lost the last of the places where the list and the count disagreed.
And the app bundle is sealed at last. It never was: codesign --verify answered "code object is
not signed at all", because the plugin build wrote its incremental stamps into
Contents/PlugIns/.build-stamps and codesign refuses a bundle carrying a directory it does not
recognise β with or without a certificate. macOS 26 kept honouring permissions granted to an unsealed
bundle; macOS 27 will not grant new ones, which is why a fresh install asked for Desktop, Documents
and Downloads over and over and forgot every answer. Measured on 27.0: 27 prompts before, three
after β one per folder, remembered, and nothing at all on the next launch. This is an ad-hoc seal,
not a Developer ID: the first launch still goes through System Settings.
Changed
-
Workspaces are named work contexts now, not saved layouts (F-499). A workspace β "clean up
backups", "sort applicant documents" β remembers both panels, every tab, the active side, the view
mode, the folder tree and the back/forward history, and switching restores the other one exactly as
it was left. It never asks whether to save, because a workspace never ends; what the old feature
did on every load β "anything you had open but did not save is not kept" β was the reason it was
worth rebuilding rather than extending.The whole window switches, not just the folders: both panels and their tabs, the view mode, the
folder tree, the back/forward history, which files you had marked, the quick filter, the cursor,
and the window's arrangement β the side panel, the dock and which plugin view it shows, every bar,
the panel layout and where the divider sits. Change any of those and you have changed this
workspace, not a global setting.The terminal and the assistant follow too, and nothing running dies. The tabs of the workspace
you leave are set aside with their shells alive rather than closed β amakeor anrsyncstarted
in one workspace keeps running while you work in another, and is still there when you come back. The
assistant keeps a separate conversation per workspace; an answer still arriving when you switch away
finishes and is waiting for you. Chats from before this existed belong to no workspace and appear
everywhere, so nothing is hidden by the upgrade.And a basket per workspace, for what actually happens while tidying up. Three folders deep in the
backups you find something that belongs to an entirely different job: drag it onto that job's chip
and it lands in its stash. You do not switch, nothing is copied or moved, the chip's counter goes
up and you carry on. β₯ copies into that workspace's folder instead and β moves; Ctrl+Cmd+A adds the
selection to the current one; the Stash page in the side panel shows what is in it; and Copy/Move
Stash to Other Panel does the whole basket in one operation, through the same background transfer,
overwrite handling and undo as every other copy. Files deleted in the meantime are shown as missing
rather than dropped, and a bulk operation offers to skip them or take them out first.A workspace can also be limited to a folder, which is the safety net for a tool that deletes.
Right-click its chip, Limit to Folder, and choose whether operations outside it are allowed, asked
about, or refused β "clean up backups" covering/Volumes/Backupthen asks before F8 takes something
from your Desktop. Checked before a delete, a copy, a move, a rename or a new folder reaches outside,
and asked before the delete confirmation rather than after it. Navigating is never restricted
(ADR-013): a file manager that refuses to show you a folder is broken, and a guard that gets in the
way while you are only looking is one people switch off before the moment it was built for.And each workspace keeps a journal β folders visited, operations carried out, shell lines run,
and anything the folder limit refused. Workspace ⸠Journal⦠shows it newest day first, with a
Problems filter for everything that failed or was stopped; the refusals are recorded nowhere
else in the application. Return repeats a row under the history's rule β only a copy or a move goes
with one keystroke, a shell line is filled into the command line rather than run. It is a log rather
than a filter over the global history, because that one ranks by frequency and collapses repeats,
and "what did I do here" needs the order and the whole of it. Deleted with its workspace, kept
indefinitely otherwise, and switchable off in Settings ⸠Tabs.And a workspace is a file you can hand over. Workspace ⸠Export Workspace⦠writes a
.pcworkspace; Import Workspaceβ¦, or a double-click in the Finder, reads one back. The storage
format is the export format, so there is no second schema to drift apart from it, and paths inside
your home are written shortened so the file opens in the other person's home. What travels is the
workspace's saved starting point, with its name, colour, folder limit and stash. What deliberately
does not: anything that could be a credential β a tab on a connection or a mounted plugin drive
is removed rather than cleaned up, and counted in the report, so there is nothing about a connection
in the file to leak β and the journal, which records what you did and names folders on your
machine. An import always adds a workspace and never switches by itself; a file somebody sent should
not move the window you are working in. Folders that are not on this Mac open at the nearest one
that is, stash entries keep their paths and show greyed, and a folder limit set to refuse whose
folder is missing is kept but asks instead β a refusal nobody can act on is worse than a question.Each chip carries a β at its right-hand end, so putting a workspace away does not mean finding
a context menu first. It leads into the same confirmation as everywhere else, because a workspace is
deleted rather than closed and its stash and journal go with it; the last remaining one has no β at
all, and a chip too narrow to spare the room keeps its name instead.Marked files are the part worth stating plainly: come back to a workspace two days later and the
forty files you had ticked are still ticked. Anything deleted in the meantime is quietly no longer
in the selection rather than a phantom entry. Undo is per workspace too, but only while the app is
running β an undo step carries the action that reverses it, and that cannot be written to disk.Switch from a strip of coloured chips across the top of the window, from the Workspace menu, or with
Ctrl+1β¦Ctrl+9. Each workspace also keeps the arrangement it was set up as, so Cmd+Ctrl+S ("save the
layout" in the old feature) now means "make this the state I reset to", and Reset to Saved State
goes back there.None of it is visible until you make a second workspace: no chip strip, no menu, no shortcuts β
and the whole feature can be switched off in Settings βΈ Tabs, which also takes the two Go entries
away. Switching it off keeps your workspaces; they come back unchanged.Upgrading loses nothing: workspaces saved with the old feature become chips, the session you were in
becomes the first one, andworkspaces.iniis kept asworkspaces.ini.migrated. Each workspace is
now its ownworkspaces/<id>.json, so one unreadable file costs only itself and a workspace can be
handed to somebody else. -
The arrow keys step between the quick search's matches (F-060). Typing letters in a panel jumps
the cursor to the first name that starts with them; β and β now walk backwards and forwards through
the rest of the hits, wrapping at both ends, for as long as theβ re 2/3indicator is on screen.
Repeating the same single letter still cycles too, but that only ever worked forwards and only for a
one-letter prefix β past the first hit of "re" there was nothing to press. Only the bare arrows are
taken: Shift+Arrow still extends the selection, Alt+Down is still the history dropdown, and once the
indicator has timed out Up and Down move one row again. -
A filtered list cycles, and keeps its cursor while you narrow it (F-395). The quick filter hides
what does not match, so β and β already walked only over hits β but they stopped at the ends, and
every keystroke threw the cursor back to the first row. Now the arrows wrap (..is part of the
cycle: in filter mode Backspace edits the mask, so the parent row is reachable by arrow and by
nothing else), and refining a mask leaves the cursor on the item you were aiming at for as long as
the narrower mask keeps it. Clearing the filter keeps it too β you filter to find one file and press
Esc to see it among its neighbours. Marking is deliberately left alone: Shift+Arrow and Insert still
stop at the ends, because a mark run that wrapped would come back round and untoggle what it had
just set.
Fixed
-
macOS kept asking for the same folder permission and never remembered the answer (#3). The app
bundle carried no code seal:Tools/build-all-plugins.shwrote its incremental stamps to
$OUT_DIR/.build-stamps, which for a packaged build is the app'sContents/PlugIns, andcodesign
refuses an entire bundle over a directory no bundle format knows β "bundle format unrecognized,
invalid, or unsuitable. In subcomponent: Contents/PlugIns/.build-stamps".Tools/codesign-app.sh
then returned early whenever no signing identity was configured, so no build was ever sealed and the
first defect stayed invisible. Stamps now live outside the target, and the app is sealed ad-hoc when
no identity is given.macOS 26 went on honouring permissions that had been granted earlier, so this only showed on a
machine without them β a new install, or macOS 27, which refuses to store one for an unsealed
bundle at all. Measured on 27.0 (26A428): 27 prompts, every one answered, none recorded; after the
fix three prompts, one per folder, each recorded, and a restart asks nothing. Full Disk Access is
not a workaround for the old build and never was. -
The build stopped compiling under Xcode 27. Swift 6.4 will not choose between
Data.append(Data)andData.append(UInt8)for a bare$0inside an array literal, where earlier
compilers took the type from the literal. Two places, the same four lines copied once:
Sources/PCFoundation/TextPipe.swiftandPlugins/SDK/PluginDecompiler.swift. -
The quick filter's count was one keystroke behind its text (F-395).
applyFilterLivereported
to the indicator before rebuilding the list, soπ rep 7/1217showed the new mask beside the
previous mask's number β and a mask that had just narrowed to nothing still claimed the hits it no
longer had. Counted after the rebuild now. -
The panel's keyboard now works in Brief, Icons and Gallery too, and those views draw marks
(F-021, F-060, F-395).IconGridViewanswered the arrows and Enter and dropped every other key, so
in three of the five view modes there was no quick search, no quick filter, no Space or Insert
marking, and Backspace did not go up a folder β whilesyncGridCursor's own comment said the
type-ahead was meant to reach the grid. Every key the grid does not own is handed to the list that
implements it; the arrows and Enter stay with the grid, because there they are about cells rather
than rows. Marks are drawn in the theme's marked colour, the same colour and the same meaning as in
the list, and they follow every change without rebuilding a cell.Page Up and Page Down belong to the grid too, because a page there is a screenful of cells:
handed to the list they asked a table that is not on screen how tall it was, and its answer covered
the whole folder β so one press went to the last file rather than down a screen. Measured on a
500-file folder: 52 cells per page in Brief, 20 in Icons at that window size, the same step on
every press and the exact inverse going up. Home and End keep going to the list, which needs no
geometry to answer them. -
A grid mode answered Shift+Arrow, Alt+Down and Ctrl+PageDown as if they were bare keys (F-021).
IconGridView.keyDownswitched on the key code and never looked at the modifiers, so marking a
range, opening the history dropdown and "enter the item under the cursor" all arrived as a plain
arrow: the cursor moved and nothing else happened. Only bare keys belong to the grid now β anything
carrying a modifier goes to the panel. Measured in Icons view: Shift+Down marks notes.txt, again
marks report-1.txt beside it, and the grid draws both. -
A quick search that had already expired kept Backspace (F-060). The typed prefix outlives its
indicator by design β the next keystroke's window check is what clears it β but the keys went on
belonging to a search nobody could see: measured, 2.6 s after one letter the indicator was empty and
Backspace still edited the invisible prefix instead of going to the parent folder, and it stayed
that way until some other keystroke happened to clear the buffer. An expired search now owns
nothing, which is the same rule the arrows got when they learned to step between matches. -
The quick filter and the Brief/Icons/Gallery view disagreed about which files exist (F-021,
F-395). Those three modes draw an icon grid that mirrors the panel's visible entries, and the
quick filter is the one thing that changes that set without a new listing β so nothing rebuilt the
grid when a mask was applied or cleared while one of them was showing. Filter in Details view,
switch to Brief, clear the filter from the View menu, and the grid went on drawing the matches of a
mask no longer in force, with the folder's other files simply absent. Worse than stale: the grid
maps a click or Enter through its own index into the panel's list, so the file that opened was
not the file under the highlight β measured,gridName=report-2.txtagainst
tableCursor=report-1.txt. The grid is rebuilt on every filter change now, and a newgriddump
verb reports what it is drawing beside the panel's own cursor, with anagree=line, so the VM
gate can see the two part company. -
Ctrl+S in the middle of a quick search left the search's prefix behind. The filter took the
keyboard while the type-ahead's buffer and its indicator stayed up for the rest of the two-second
window β and since the arrows now step between a search's matches, they would have been taken from
a list that prefix no longer describes. Entering the filter ends the search. -
A tab's cursor position survived loading a saved workspace but not restarting the app: the session
and the workspace format had drifted apart, and only one of them wrote it down. There is one
serializer now, and it does (F-499).