Skip to content

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 29 Aug 08:35
· 197 commits to main since this release

Before you double-click

This build is not signed or 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.

Only the first launch asks.

The assistant is split in two. What ran on your Mac was a chat that could not read a file: measured
against Apple Intelligence, the thirty-two tools it offered the model cost 3442 of the model's 4096
tokens, leaving 473 for your question, the file and the answer together — so it answered in the wrong
language, mistook folders for files, and died on the second message telling you to start a new chat,
which changed nothing. That was the default every new reader landed on.

Added

  • Macros: a named sequence of file actions, and the quickest way to one is to do it once. A macro
    creates a folder, moves your selection into it, tags what is left — and then repeats that from a
    button. It is not a scripting language and does not try to be: there are no conditions and no loops,
    because the plan you are asked to approve has to be a list you can read. Configuration ▸ Macro
    from Recent Actions…
    builds one out of what has already happened — files you copied, moved,
    renamed or deleted in the panels, and anything the assistant did, in one list with each row saying
    which. Configuration ▸ Edit Macros… opens macros.json for the rest, seeded with eight worked
    examples: today's folder, filing the selection by month, a dated backup, pictures into a subfolder,
    merging CSVs and opening the result, marking the file under the cursor as reviewed, filing into a
    folder you name, and temporary files to the Trash. A file, not a form — the same answer the Start
    menu gets, because a macro is a list of tool calls and that is what JSON is.

    A recorded macro repeats that copy: the paths are the ones that actually ran, which is honest and
    is usually not what you want the second time. Follow the panels instead of these exact files
    rewrites them — files that all came from one folder become the selection, a folder that is one of
    the two panels becomes that panel — and the rows change as you tick it, so you can see what you are
    about to save rather than take it on trust.

    A macro can ask you for a value. %{ask:Folder name=Archive} puts the question to you when the
    macro runs, which is what makes "move the selection into a folder I name" expressible at all without
    wiring the folder in. You are asked before the plan appears and the answers are already in it, so
    the rows say "Move the selection into “Rechnungen”" and not "into whatever you are about to type";
    cancelling the question cancels the macro. The same question written twice is asked once.

    Every macro becomes a command called mc_<id>, so it turns up by itself in the Command Browser, the
    shortcut editor, the button bar's command picker, your .mnu file and the assistant. Nothing had to
    be taught about macros for any of that; they all read the same command table. Two of those routes did
    not work for plugin commands either, and now do: a button or a usercmd.ini entry naming an id that
    was not cm_ or em_ used to be looked up as a file name and silently do nothing.

    Configuration ▸ Manage Macros… is the list — what each one is called, its command name, how many
    steps it has, and what it will ask permission for, so "this one deletes" is visible before you put it
    on a key. Rename, duplicate, reorder, delete; deleting offers to take its buttons with it. The steps
    themselves stay in the file, and Edit File… hands over for that.

    What a macro is allowed to do is decided by the most demanding thing in it, and decided before the
    first step rather than four steps in — a macro ending in a permanent delete is gated like a permanent
    delete, and one holding a shell step is refused whole on a machine where you have not turned the shell
    on. A step that runs a command is judged by what that command does, not by the fact that it is a
    command. Confirmation happens once, for the whole macro, and the rows are resolved against your panels
    and shown in your language, so you read "Move one.pdf, two.pdf into “2026-08”" rather than
    move destination=%T/%{date:yyyy-MM}. Strike out a row and that step is skipped — along with the
    steps that cannot do without it, because a macro is a sequence and striking out the step that creates
    the folder leaves the step that fills it aimed at nothing. Each step is logged and undoable on its own,
    which also means undo after a macro takes back its last step and not the whole thing — several
    tools have no inverse at all, and a button offering a macro-wide undo would be lying about those.

    Three things had to change underneath. The panel state is read again before every step, not once at
    the start: with one snapshot, a macro that selected its own files as step one still saw the old
    selection at step three and reported "nothing is selected" about files it had just marked. A step whose
    %S came out empty used to succeed: measured, a
    macro run with nothing selected created the destination folder, reported both steps ok, and moved
    nothing. An empty expansion is a step that lost its subject, and it now stops the macro. And the
    action log had to start keeping each action's arguments verbatim, because the line it kept for a human
    reader clips every value at sixty characters — half a path is not a path, and the recorder was reading
    it.

  • AppleScript and JavaScript can now be run by Peach Commander, not just used to drive it. The app
    has been scriptable for a while; this is the other direction. Put a .applescript or .jxa file in
    scripts/ inside your configuration folder and it becomes a command you can put on a menu, a button
    or a key. The panel state arrives in the environment — PC_ACTIVE_DIR, PC_TARGET_DIR,
    PC_CURSOR_NAME, and a file listing the selection — so the ordinary script needs no Apple events and
    never triggers the automation permission prompt. Anything beyond that talks to the application itself,
    through the dictionary that was already there.

    It is a separate plugin and it ships switched off, with its own permission switch in Settings ▸
    AI
    next to the shell's. Running a program of your choosing can do everything the rest of the app can
    and several things none of it covers, and that is not a capability to meet for the first time in a
    dialog. Scripting and the shell are two switches, not one: an AppleScript reaches other applications
    through Apple events, which "run a program" does not describe, and wanting a file-filing script is not
    wanting an arbitrary shell.

    A script runs as a separate process by default, which is the only arrangement that can carry a real
    time limit — thirty seconds unless you say otherwise, and a script that overruns is stopped and says
    so instead of freezing the window. A script can opt into running inside the app for a structured
    return value and a compiled script kept between runs, and then there is no time limit; the choice is
    yours to make per script, and the trade is stated where you make it. The assistant gains
    run_applescript, run_jxa and check_script when the setting is on — each showing you the exact
    script and waiting — and none of the three is ever offered to an external agent over MCP.

  • The side panel's pages can be switched off, and it now ships showing Info alone. Activities and
    Log — the two transfer lists — were on for everyone, so a strip of three tabs sat above the preview
    all day for pages most work never asks about. Each of the three is a switch now, in Settings ▸
    Layout
    , by right-clicking the tab strip, or as View ▸ Side Panel: Info / Activities / Log. With
    one page left the panel drops the tab strip altogether, which is what an Info-only panel should have
    looked like from the start. Every page can go, Info included — worth having if you keep the terminal
    or a plugin view there instead — and a panel with nothing left says so rather than opening blank.
    Pages a plugin contributes are untouched by this: those come and go with the plugin, and switching one
    off is what the Plugins page is for. The View menu entries are not a third route for the sake of it:
    once every page is off there is no tab strip left to right-click, and they are the way back.
    View ▸ Reset Layout puts the pages back with the rest of the window's furniture.

    The setting was the easy half. The panel decided which page it was showing from the segment index —
    three cases numbered 0, 1, 2, read straight out of the switcher — so removing a page in front of the
    selected one handed you a different page under the right label: with Log showing, switching Info off
    used to show you Activities. Which tab is selected is now kept by identity, nothing in that file
    counts tabs any more, and the case is asserted rather than described.

  • AI On-Device — five actions that do the work instead of talking about it. Right-click a file and
    Summarize, Explain, Suggest a name or Suggest a comment; right-click the panel
    background and Organize this folder. Each one reads what it needs, shows you exactly what it
    proposes, and lets you untick anything you want left alone before a single file is touched. Nothing
    opens a chat, and the model is offered no tools at all — which is what leaves the whole context
    window for your file instead of for a list of things the model may call.

    Suggest a name and Organize this folder go through the same confirm-then-apply path as any
    other change, so both land in the assistant's action log and Undo last change takes them back.
    Renaming a marked selection is one step and one undo, not one per file. Organising asks once what
    folders the set needs and then sorts into those, because sorting file by file produced a folder
    named after the first file with everything else in it.

    It is a plugin and it arrives switched off, alongside the chat and the AI Column. If you had the
    assistant switched on and no cloud model configured, it is switched on for you once, with a note
    saying why.

  • Find by meaning. Right-click the panel background and AI ▸ Find by meaning, describe what
    you are after — "the invoice about the roof" — and the folder is ranked by how close each file is
    to that. No model is involved: it compares meaning with on-device sentence embeddings, so it
    answers instantly and cannot invent a file that is not there. Pick a match to jump to it.

    It ranks, and it does not judge: ask a folder of invoices about football and you still get the
    folder back, closest first. That is why the list is headed Closest matches — the top of it is
    the answer when there is one, and it is not a claim that there is.

  • Organize works on what you marked. Mark a few files and it tidies up those; mark nothing and
    it takes the folder, as before.

  • Suggested comments now set real Finder tags. The tags were being glued onto the end of the
    comment text, where nothing could search or colour them. They are now the tags Finder and
    Spotlight see, added to whatever tags the file already had — and Undo last change puts the
    old set back, because the previous tags are recorded with the change.

  • Classify, and rename by what a file is. Mark a few files and AI ▸ Classify: each one gets
    a topic, the date it actually states, and a category worked out across the whole selection — so an
    invoice and a receipt land in one category rather than each in its own. The answers fill three new
    panel columns, AI Kind, AI Topic and AI Date, and they are usable in a multi-rename
    mask: [=ai_column.ai_topic]-[Y]-[M].[E] renames a folder of dokument1.pdf files by what they
    are. Nothing new was built for that — the rename mask has always resolved [=provider.field]
    through the column system, so classifying once is what makes it work.

    A date is only taken when the document states a full one. Asked about "Reisenotizen Kreta, Sommer
    2023" the model offered 12 July 2023; a date invented in a file name outlives every chance of
    noticing it, so the text now has to contain the day and the year or the field stays empty.

  • Make a table works without a chat, and saves. Put the cursor on a log, a measurement series
    or a badly exported CSV and pick AI ▸ Make a table: the columns come from the data's own
    names, the rows from the data, and Save as CSV… writes it beside the file — through the same
    confirmed, logged path as any other change. A decimal comma is quoted, so a German file survives
    being opened again as a spreadsheet.

    It reads the beginning of the file, not all of it, and the sheet says so when there is more. A
    few dozen rows is what fits; a database export is not what this is for.

  • Scans and screenshots are readable. Apple Intelligence cannot see a picture — it takes text
    and nothing else — so the words are read off the image first, on your Mac, and the assistant works
    from those. Nothing new to learn: Suggest a name turns scan_0042.png into
    rechnung_meier_2024_03_12.png, Classify files it with the invoices rather than the photos,
    and Make a table reads a screenshot of a table back into columns. For a photograph with no
    words on it, what the picture appears to show is used instead.

  • The chat can hand you its answer. "Copy the folder names to the clipboard" was the second
    half of the dialogue that started all of this, and it had no answer: there was no tool for the
    clipboard at all, in either assistant. There is now, and it takes text — a list of names, a table,
    a path — ready to paste anywhere. To put the files on the clipboard instead, select them and use
    Copy to clipboard as before.

  • Classify can file the files, not just label them. It ends with File into folders…, which
    proposes a destination for every file it has just read — a folder named after its kind, and a year
    below that when the document itself states a date — and moves nothing until you approve the list.
    Untick any row you want left alone, as with every other plan. It costs no further reading: the
    kind and the date are already worked out, which is why this is a button on the result rather than
    a second command that would run the model again. Each row also shows the topic it found, so a
    kind that came out too broad — everything as "Documents" — is visible before anything moves. A
    file whose kind came back empty stays where it is, and the sheet says how many did.

  • Explain stopped being a second name for Summarize. Summarize reads the whole file and
    folds it, which is right for prose; Explain reads the opening and answers "what is this and what
    would I use it for", which is the right question for a config file, a script or a data dump.

Changed

  • The AI Assistant chat now needs a cloud model — any OpenAI-compatible endpoint, which includes a
    local server such as Ollama or LM Studio, not only a paid service. The on-device chat is gone rather
    than fixed: it is the on-device actions that work, and pretending otherwise cost people their first
    impression of the feature. The Settings ▸ AI page now says which setting belongs to which half.

Fixed

  • "Select these files" was in the assistant's tool list and did nothing but throw. set_selection
    had been declared in the catalogue all along and was never implemented, while the identical operation
    had been available to AppleScript since 0.6 — one call away in the same file. The cost was not the
    missing tool: it was what it made macros. A macro could only ever act on files you had already
    marked, so "select every PDF and file it away" was not expressible at all. It works now, and it
    replaces the selection rather than adding to it, because a macro that starts by selecting has to
    do the same thing whatever was marked when it began. A mask that matches nothing fails and clears the
    selection instead of leaving the old one standing — otherwise the next step would have moved whatever
    the cursor happened to be on, which is not what you asked for.
  • Moving files into a folder that does not exist destroyed them and reported success. Found while
    testing macros, but nothing to do with macros: the assistant, an external agent over MCP, or anything
    else naming a destination as text could ask for a move into a path that was not there, and get ok
    back with the files gone from where they had been and nowhere else. Two files, one call, no way back —
    the log even recorded an undo that could not have restored them. Copy and move now refuse a
    destination that is missing, or that is a file rather than a folder, and say which folder to create
    first. The guard sits where an arbitrary destination string arrives, because the panels' own F5 and
    F6 cannot produce one: their destination is a folder they are displaying.
  • The assistant's own action list was always empty. list_recent_actions returned nothing however
    much had been done, while the log on disk was complete and correct — so the one tool for "what did you
    just do to my files" answered as if the answer were none. The cause is the same trap a comment two
    methods away already warns about: the method was written without async while the protocol requires
    it, which compiles, and then the await at the call site picks the protocol's default implementation
    instead. Which returns an empty list. Nothing caught it because the tests exercised the log directly
    and never the tool; there is now one that goes through the tool.
  • A plugin that could not be loaded contributed nothing and said nothing about it. It appeared
    enabled in the Plugins window and was absent from every menu, with no message anywhere — which is a
    long way to look for a plugin whose real problem was one line of build configuration. The failure is
    now logged with its reason.
  • The AI Summary column never showed anything, for anyone. The column and the assistant each
    worked out their own key for a file and disagreed on both halves of it — one counted seconds from
    2001 and the other from 1970, and they rounded the number differently — so no file ever matched.
    They now share one definition, and the summary appears as soon as an action has read the file.
  • Unticking a line in the assistant's plan did nothing. 0.7.3 said you could agree to part of a
    plan; the ticks were drawn and collected and then thrown away, so everything ran regardless. They
    are now passed on, which is what that release promised.
  • The AI panel columns had English headers in every language. The AI Column plugin never told
    the app what to call its columns in your language — it was the only content plugin that did not,
    and the only one shipping no translations at all — so the panel said "AI Summary" while the
    translated manuals named a column that did not exist. The headers are translated now. What you
    write in a rename mask is unchanged and stays English: [=ai_column.ai_topic] keeps working, and
    so does every saved column set, because those are keyed by a name that does not move with the
    interface language.
  • Find by meaning ranked the wrong files first. Asked for "die Rechnung über das Dach" in a
    folder holding exactly that invoice, it put the invoice last and a web-server config first — and
    the same for a bare "Rechnung". Two causes, both measured: the file's opening was compared as a
    block of running text, which averages every document into the middle, and the file name was then
    given a further advantage over it. Both sides of the comparison are now reduced to their content
    words — "die Rechnung über das Dach" is three filler words and two real ones — and the name
    competes with the content on equal terms, its extension included — cut off, a search for "log"
    could not find app.log, because the word is nowhere else in that file. Over the same folder,
    seven queries out of seven put the right file first where one did before.
  • A short search phrase could return nothing at all. Two words are not enough to place a
    language: "Webserver Konfiguration" was read as Danish, which has no on-device sentence model, so
    the search quietly fell back to literal word matching and found nothing. It now falls back to the
    language you are running the app in — which you chose, where the guess had not.
  • Classify could give a file the wrong month. An invoice reading "Rechnungsdatum: 12.03.2024"
    was dated 2024-08-12. The check that is supposed to keep the model from inventing dates required
    the year and the day to appear in the document but never looked at the month. It does now, and a
    date written out in words — "1. April 2019" — is still recognised.
  • Explain answered in the file's language, not yours. On a German Mac it explained an
    nginx.conf in English, because the file is English. Summarize hands back what the document says
    and stays in its language; Explain answers a question you asked, and now answers it in yours.
  • Organize put unrelated files into one folder. Asked to tidy a folder of invoices and meeting
    minutes, the model sometimes answered with a single vague category — "Documents", "Projekte" — and
    everything was then filed under it. That is not a tidy-up: the new folder is the one the files were
    already in, one level down, and its name describes none of them. A folder holding every file is
    now refused the same way a folder holding one file always was, and the action says plainly that
    nothing here groups. Measured over eight runs, this happened in two of them.
  • Organize left files behind. About one file in five came back unfiled even when the right folder
    was among the ones it had just been offered — so the folder was half tidied and the rest stayed put.
    When the name itself settles it against exactly one of the folders, the file goes there; when two
    folders would fit, it is left alone, because a file where you put it costs a second run and a file
    in the wrong folder costs a search.
  • The tidy-up sheet said "this folder" when it was tidying a selection. It has always tidied only
    what you marked; only the title claimed otherwise, so approving four marked files out of two hundred
    looked like approving all two hundred.
  • The tests that use the real on-device model had never run. The documented way to switch them on
    set a variable the test process could not see, so six checks reported as skipped in every run since
    they were written — including the one that would have caught the defect above.