Foldee: my own Open and Save dialog app for macOS

A native agent I built with Claude Code to replace Default Folder X: a default folder per app, a strip of folders next to every Open and Save dialog, and a ⌘J palette.

The Foldee app icon: a white Save dialog and a folder strip with a red edelweiss on a red gradient square, with the name Foldee under it

25 Oct 2026

Foldee makes every Open and Save dialog on my Mac open in the right place and jump anywhere in 1 key. It replaces Default Folder X, which I ran from Setapp for 2 years. Foldee is 1 small process that sits beside Apple's own dialog and never touches its buttons.

I built it with Claude Code on 24th October 2026: a usage review, 41 questions, 2 spikes, a council review, then the build and the QA. I switched Default Folder X off the same evening. The name fits the -ee family, next to Filee: my own file manager for macOS and Lastee: my own recent-files app for macOS, which feed Foldee its folders and files.

The screenshots and examples in this note use dummy test folders, files and apps from Foldee's QA, not my own data.

The Foldee strip in light mode on QA test data: the current folder name and path at the top with 3 buttons, then sections for the Filee panes, favourites with their parent paths, a '+12 more' row, the newest files with their age, and a footer with the shortcuts

Why I replaced Default Folder X

Default Folder X did a good job for years. Then my Mac changed around it: Filee replaced Finder, Lastee took over recent files, and macOS Tahoe kept breaking it.

The numbers said the job got small

Default Folder X keeps lifetime counters but no dates. I compared 2 snapshots of its counters, 4.5 days apart:

Feature Lifetime (742 days) Last 4.5 days
Automatic jump to last folder 2,911, 3.9 a day 13
Picks from its menus 1,678, 2.3 a day 3
⌥↑ / ⌥↓ recent folders 147 0
Click a Finder window to jump 117 0
Tags on save 78 0
Default folder per app 1 -

Use dropped when Filee arrived. Click-a-Finder-window died with Finder windows. What was left was 1 automatic job (open the dialog where I was last time) and a few picks a day.

The cost didn't drop with it

Resource Default Folder X
Processes 5: the main app plus 4 Finder Sync extensions
Memory About 250 MB (150 MB main, about 100 MB for the rest)
CPU at idle About 0.3%
Permissions Accessibility and Screen Recording
Licence Part of my Setapp subscription

Tahoe broke it 3 times

St. Clair Software shipped 3 fixes for macOS 26 (their Tahoe notes): the Accessibility API stopped reporting that a window had gone, column view opened scrolled to the left, and audio and video previews crashed the host app. A tool that works on other apps' windows breaks whenever Apple changes those windows.

Foldee is also 1 step towards leaving Setapp altogether, see Setapp: macOS app subsciption.

What Foldee does

Default folders, done the way macOS does them

I pin a folder once, and that app's dialogs open there. The trick: macOS stores the folder each app's dialog opens in, under the app's NSOSPLastRootDirectory preference. Foldee writes it there. The next dialog opens in the right folder, with no visible jump and no keys sent.

Some apps pick their own folder and ignore that preference. For those, Foldee moves the dialog with keys, once, and only if I haven't typed, clicked or scrolled since the dialog opened. In a Save As dialog for an existing document, it does nothing.

Apps without a default keep macOS's own behaviour: the dialog opens in the last folder I used in that app.

02 Nov 2026 1 default for all apps. I can now set 1 folder for every app, below each app's own default. The strip shows where the dialog will open in a muted line, "Opens in Downloads · all apps ▾", and its menu sets or removes the app's default or the all-apps default, each with an Undo. Settings has a table of every default, with app names and icons.

The strip

A narrow panel sits right of the dialog, at the dialog's height, and follows it when it moves. 1 click sends the dialog there.

  • Header: the current folder in bold, its path under it, and 3 buttons: copy the path, open the folder in Filee, and the pin that makes it the app's default. 02 Nov 2026 The header now has a fixed height, so the rows never move under the pointer. The path line also carries the messages: "Going to Work…", "Didn't go to Work · path copied · Retry". The pin made way for the defaults line, and a star and a ⋯ menu took the buttons' place.
  • Filee: the folders open in Filee's 2 panes right now. This is the row I click most.
  • Favourites: Filee's favourites, as the same tree as Filee's sidebar. 25 Oct 2026 Each favourite sits under the closest favourite that contains it, and a folder that holds 2 or more favourites shows as a muted row, for example Dropbox/Work. The strip folds where I folded the tree in Filee. Only the top rows show a path: the folder above them.
  • Recent: the last 6 folders I used in any dialog.
  • Newest files: in Open dialogs only, the 5 newest PDFs, Office files, images and videos from Lastee. A click goes to the file's folder.

The Favourites section with dummy folders, Code folded in Filee:

FAVOURITES
⌄ 📁 Home              /Users
     📁 Downloads
   › 📁 Code
   ⌄ 📁 Dropbox          (muted: holds 2 favourites)
        📁 Family
        📁 Work
  📁 Archive           /Volumes

The strip never scrolls. When the rows don't fit, Foldee shortens the sections and adds a "+N more · ⌘J" row. It never takes the focus from the dialog, and it stays off the screen I share in calls.

02 Nov 2026 On 30th October, 5 UX expert agents reviewed Foldee and scored it 4 out of 10. The strip got most of their changes:

  • 1 layout for every row: the name on the left, muted context on the right, then the row's Filee jump key in its own column.
  • "here" marks the folder the dialog already shows. That row is dimmed and does nothing.
  • Right-click any row for Go Here, Always Open here (this app or all apps), Favourites, Copy Path, Open in Filee and Reveal in Finder. ⌥-click copies the path. Drag a row onto the dialog to go there, or a file onto a web page to attach it.
  • "14 more favourites ▾" is now a menu of the hidden rows, and a Favourites tree too long to fit shows flat, so every row is a target.
  • Favourites from the dialog. ⌥⌘B or the star adds the file or folder selected in the dialog to the strip's favourites. Pressed again, it removes it.

The strip screenshot in this note shows the first version, before these changes.

The palette

⌘J opens a palette over the dialog. I type a few letters, or paste a path, and press ↩. Filee's jump keys work there too, so ⌘J, K, ↩ goes where K goes in Filee.

02 Nov 2026 The palette now starts in jump mode: ⌘J, then K, goes at once, with no ↩. Space switches to search. ⌘P makes the selected row this app's default, ⇧⌘P the default for all apps.

The Foldee palette in dark mode on QA test data: the query 'always open' at the top and 1 red selected row reading 'Always open TestHost here' with the key ⌘1, and a footer listing the palette keys

Keys

Key Where Does
⌘J Any dialog Opens or closes the palette
⌥↑ / ⌥↓ Any dialog Steps back and forward through the folders I visited
⌥⌘B Any dialog Adds the selection, or the folder, to favourites
⌥⌘O Filee Sends the folder, or the selected file, to the dialog
↩, ⌘1-⌘9 Palette Goes to the selected row, or row 1 to 9
⌘P Palette Always open this app here
⇧⌘P Palette Always open all apps here
⇧⌘D Palette Copies the selected row's path
⌘O Palette Opens the selected row in Filee

⌥⌘O from Filee is the move I didn't have before: I browse in Filee, find the folder, press 1 key, and the dialog in the other app is already there.

When a jump can't happen safely, Foldee says why in a small card ("You typed, so Foldee stopped") and puts the path on the clipboard, so ⇧⌘G and paste finish the job by hand.

02 Nov 2026 Honest jump results. Some dialogs can't say which folder they show. Foldee used to count those jumps as failed. It now reports them as "unconfirmed", and "failed" only when it can see that the dialog stayed where it was. foldee stats lists arrived, unconfirmed and failed jumps per app, so I know which apps need work.

What I left out

Quick Search outside dialogs (Filee and my launcher do that), the file actions inside dialogs (rename, trash, info), folder sets, the Finder toolbar buttons, tags on save, and a menu bar icon. None of them had a use worth the code.

All features

Default folders

  • A default per app. Foldee writes the folder where macOS looks, so the dialog opens there with no jump.
  • 1 default for all apps. Below each app's own default.
  • Defaults line. "Opens in Downloads · TextEdit ▾" in the strip sets, changes or removes a default, with an Undo.
  • Settings table. Every default, with the app's name and icon, Change and Add App.
  • Fallback move. For apps that ignore the preference, 1 move with keys, only if I haven't typed, clicked or scrolled.
  • Import. foldee import-dfx reads the defaults from a Default Folder X backup.

The strip

  • Beside every dialog. At the dialog's height. It follows the dialog when it moves or resizes.
  • Sections. Filee's 2 panes, Filee's favourites as a tree, the last 6 folders, and in Open dialogs the 5 newest files from Lastee.
  • Fixed header. Folder name, star, ⋯ menu, a path line that carries the messages, and the defaults line.
  • Rows. Click to go, ⌥-click to copy the path, right-click for a menu, drag onto the dialog.
  • "here". The current folder is dimmed and marked.
  • Overflow. No scrolling: a "+N more" menu, and a flat Favourites list when the tree doesn't fit.
  • Favourites from the dialog. ⌥⌘B or the star adds or removes the selected file or folder.
  • Never in the way. It never takes the focus, and it stays off the screen I share in calls.

Jumps

  • Palette. ⌘J over the dialog: a Filee jump key goes at once, Space searches names and paths.
  • Defaults from the palette. ⌘P for this app, ⇧⌘P for all apps.
  • Step through folders. ⌥↑ and ⌥↓ go back and forward through the folders I visited.
  • Send from Filee. ⌥⌘O in Filee sends the folder or the selected file to the open dialog.
  • Safe jumps. The dialog's own Go to Folder, 1 ↩, checked before every key. Foldee never presses Save or Open.
  • Honest results. Arrived, unconfirmed or failed, with Retry and the path on the clipboard when a jump fails.

Safety and agents

  • Input guard. Any key, click or scroll from me stops a jump.
  • Crash-loop breaker. 3 bad starts in 5 minutes start safe mode: the strip only.
  • Kill switch. foldee off stops every key and preference write within 1 s.
  • No fights. No keys while Default Folder X runs.
  • Agent interface. A foldee command line with JSON output: status, go to a folder, recent folders, defaults, stats, on and off.

The numbers

Metric Foldee, measured Default Folder X
Dialog event to dialog recognised p50 9 to 12 ms Not measured
Dialog recognised to strip drawn p50 9 ms, p95 14 to 16 ms Not measured
⌘J to palette on screen Under 50 ms No equivalent
Jump in an Open dialog Median about 490 ms Not measured
Jump in a Save dialog 400 to 411 ms Not measured
Jumps that arrived (interactive QA) 24 of 24 -
Memory 29 MB installed (54 MB on day 1) About 250 MB
CPU at idle 0.0% About 0.3%
Processes 1 5
Opening in a default folder 0 ms: macOS opens the dialog there -

Most of a jump's time is Apple's, not mine:

Step of 1 jump Who Time
Click to row lit Foldee Under 16 ms
Send ⇧⌘G (Go to Folder) Foldee 12 ms
The Go to Folder field appears Apple 89 to 382 ms
Set the path, send ↩ Foldee Under 20 ms
The dialog loads the folder Apple About 450 ms

A faster language would change nothing. That's why the default folder goes through the preference: the fastest jump is the one that never happens.

How it works

The dialog isn't in the app

On macOS 26, every Open and Save dialog runs in a separate system process, openAndSavePanelService, even for apps that aren't sandboxed. The first spike found the consequence: keys sent to the app never reach the dialog. Foldee must find the right service process and send its keys there.

That's the risky part, so Foldee is strict about it:

  • It recognises a dialog by its Accessibility identifier, open-panel or save-panel, in 1 batched call. It never walks the dialog's element tree: 1 walk of a sandboxed Save dialog stalled the spike for 17 to 28 s.
  • It picks the service by 2 tests: the service's responsible process is the host app, and its focused window has the dialog's exact frame. If not exactly 1 service passes, Foldee sends no keys.
  • It jumps with the dialog's own Go to Folder: ⇧⌘G, set the path field, 1 ↩. Before that ↩, a fresh read must show the path field focused with exactly the target path. Foldee never sends a 2nd ↩, never Esc, and never presses Save or Open.

The safety rules

Foldee works on other apps' windows, so its failures must stay inside Foldee. If it's slow, wrong or crashed, the dialog works exactly as macOS made it.

  • The main thread never makes an Accessibility call and never touches the disk. Every Accessibility call has a timeout: 250 ms, and 50 ms for the first read.
  • An input guard watches me, not itself. Before each key, Foldee checks macOS's idle counters for my keys, clicks and scrolls. Keys Foldee sends don't reset those counters, so it sees only my input, without an event tap.
  • A crash-loop breaker. 3 abnormal starts in 5 minutes start safe mode: the strip only, no keys, no preference writes.
  • A kill switch. foldee off stops every key and every preference write within 1 s.
  • No keys while Default Folder X runs, so 2 apps never fight over 1 dialog.

Stack

  • Swift 6.3 and AppKit, frame-based layout, no third-party code. 1 agent process, no App Sandbox (Accessibility writes don't work in one), a LaunchAgent inside the bundle. The app is 1.4 MB.
  • About 6,500 lines of Swift, with the logic in a FoldeeCore package that has no AppKit and runs under unit tests.
  • SQLite holds recent folders, defaults and a silent usage log. Settings are a JSONC file that reloads live.
  • Code copied, not shared from my other apps: the fuzzy matcher from Lastee, the SQLite wrapper from Hifee, and the panel and hotkeys from Clipee, see Clipee: my own clipboard history for macOS.

Agent interface

A Python CLI wraps the app, with --json on every command, so my NicAI agents can drive it inside a task:

foldee status --json                                     # running, permissions, safe mode, the open dialog
foldee goto ~/Downloads --json                           # send the open dialog there, confirmed by the app
foldee default set com.apple.TextEdit ~/Documents --json # a default folder for 1 app
foldee recent -n 10 --json                               # the 10 folders used last in dialogs
foldee off --json                                        # kill switch

Writes go through a foldee:// URL with a request id. The app echoes the id back in a state file, so the CLI reports confirmed: true only once the app has acted.

What I learned

  • Keep the panel on screen and hide it by transparency. Ordering the strip in while the host app animated its dialog cost 2 to 50 ms. With the panel always ordered in at alpha 0, dialog to strip drawn fell from 30 ms to 9 ms.
  • Send a key down, wait 12 ms, then the key up. Without the gap, AppKit drops the key.
  • QA must never see a real dialog. On the first day, a QA run sent a jump into a TextEdit dialog I had open. QA now watches only its own test windows, and fails if it sees any other dialog.
  • Draw small icons from small images. 25 Oct 2026 The strip showed the system folder icon, which carries images up to 1024 pixels, and each row kept about 4 MB of it. A 36-pixel copy took Foldee from 54 MB to 29 MB installed. I found it only because the Favourites tree added rows and pushed memory over the budget.
  • Don't trust the dialog's own API across processes. On macOS 26.5, an out-of-process dialog's directoryURL doesn't update. Foldee checks the folder name the dialog shows instead.
  • 02 Nov 2026 Out-of-process dialogs don't say when they resize. The strip stayed where the dialog had been. Foldee now checks the dialog's frame every 200 ms.
  • 02 Nov 2026 Ask the window server, not only Accessibility. A sheet in Microsoft Edge closed without telling Accessibility, and the strip stayed on screen. Foldee now matches the dialog's window in the window server and ends the session when that window is gone. The same bug hid a 2nd one: 2 timers were freed as soon as they started, so they never ran.
  • 02 Nov 2026 The installed app must not see QA either. With a default for all apps, my installed Foldee moved the QA's test dialogs during a run. It now ignores the QA's test apps.

How I built it

Claude Code built Foldee in 1 day, on 24th October 2026, through my usual app process:

  1. Usage review. It read Default Folder X's counters and preferences, my Filee and Lastee settings and my Hammerspoon keys, and wrote 41 questions in 2 rounds, each with a recommendation.
  2. 2 spikes on macOS 26.5. Small test programs drove real Open, Save and Choose Folder dialogs, plain and sandboxed, to answer 3 questions before any app code: how to detect a dialog, where its keys must go, and whether the preference write steers the next dialog.
  3. Council review. 5 expert agents (speed, reliability, Accessibility, keyboard, build readiness) scored the spec in 2 rounds and raised 34 blocking issues. The spec went to version 1.2.
  4. Build and QA. 11 commits between 17:11 and 22:52. 24 unit tests, 127 background checks that never take the focus, and 30 interactive checks with 24 real jumps. The interactive run takes the screen, so it runs only when I start it, and it stops the moment I touch the keyboard or mouse.
  5. Independent review. A separate agent found 21 issues (5 high, 9 medium, 7 low). All fixed.
  6. 02 Nov 2026 UX council, 6 days later. 5 UX expert agents reviewed Foldee and scored it 4 out of 10. Their plan became 1 commit on 30th October: a header with a fixed height, the defaults line instead of the pin, menus on every row, jump mode in the palette and honest jump results.

The estimate was about 60% of 1 week of my Claude Max allowance.

What's next

  • Real-app checks. The jumps in Chrome, Office and a sandboxed real app, 10 trials each. An app that fails goes on a list where a jump copies the path only.
  • 2 faster paths to measure: the dialog's own Go keys (Home, Desktop, Downloads) and selecting a sidebar row. Each one stays off unless it beats Go to Folder by 150 ms in 20 of 20 trials.
  • Select the last file again, once file selection proves safe.
  • Uninstall Default Folder X after 1 week.

Further reading

The app Foldee replaces:

Apple's dialog, and why it runs in its own process:

The tool I built it with:

NicAI
Written by NicAI, Nic's AI assistant, for his personal knowledge base. Researched and drafted by the model, not hand-written by Nic. Verify anything you plan to act on.