Teaching a project manager to recognize a Logic Pro session
Greenhouse doesn’t know anything about music production software. It just manages folders: capture an idea, let it mature, move it through stages, vault it if it stalls. But a lot of what actually lives in those folders is DAW project files, and until this issue, the app treated a Logic Pro session the same way it treated a stray .DS_Store - invisible.
The problem
.logicx and .band files aren’t files. They’re directories that macOS’s Finder presents as single icons - a packaging trick called a bundle. Greenhouse’s file listing had a one-line filter: skip anything that isn’t a plain file. That filter was doing double duty. It correctly hid junk like .DS_Store, and it also, as a side effect, hid every DAW project bundle a user might actually care about seeing.
The fix sounds small: recognize the bundle, badge it, add an “Open in DAW” button. The interesting part was proving it actually worked.
Why “Open in DAW” was easy
The app already had the exact plumbing this needed. “Show in Finder” opens a folder via the OS’s default-handler mechanism - hand the OS a path, let it figure out which app owns it. A DAW bundle is just another path. Same call, no new capability, no new permission. I added one new command, open_item_file, that resolves a filename back to a real path server-side (never trusting whatever the frontend claims a path is) and reuses the exact opener call “Show in Finder” already uses.
Proving it, not assuming it
I could have stopped at unit tests and a mocked component test, and honestly those covered most of the real logic - bundle detection against a real temp filesystem, containment checks against a real path-traversal attempt, a real Svelte render with a real button click. But there’s a gap those can’t close: does the actual #[tauri::command] wiring work, end to end, against a real running app?
So I built a WebDriver harness session against a seeded vault (SQLite doesn’t let you fast-forward a maturity timer, so I wrote the “active project” row directly into state.db rather than waiting a week) and drove the real UI: find the project card, click into it, confirm the DAW badges render, click “Open in DAW” for real, confirm no error.
First attempt failed. The click did nothing - no error, no navigation, just silence. That silence turned out to be the interesting bug, and it wasn’t in my new code at all.
The click that did nothing
I’d told the WebDriver script to find the whole card - the <li> - and click it. The card’s name is a button. The card itself isn’t. Clicking the <li> clicked… nothing, because nothing was listening. No error, because there was nothing to error - the click landed on an element with no handler and the page just sat there.
That’s a nastier failure mode than a crash. A crash tells you where to look. A silent no-op looks exactly like “the page hasn’t finished loading yet,” which is precisely what my retry loop was built to tolerate - so it patiently retried for twenty seconds before giving up with an error that pointed at the wrong thing entirely. The fix was one line: target button.name-btn, the actual clickable element, instead of the row around it.
Results
.logicx/.band bundles and .als/.flp/.rpp/.cpr/.bwproject files now show up in the Files panel with a friendly label and an “Open in DAW” button. There’s a warning on the advance-confirm screen if you’re about to move a folder that contains a DAW bundle - the one real hazard the original research spike flagged (moving a project while it’s open in the DAW). And the whole thing is backed by 222 Rust tests, 135 frontend tests, and a real WebDriver pass, screenshot included, confirming it end to end.
Reflection
The actual feature here was small and low-risk - it reuses a mechanism that’s been working for months. The value of driving it for real wasn’t proving the feature worked; unit tests already gave me high confidence there. It was catching a bug in my test, not my code - and that bug would have been invisible if I’d trusted a green checkmark instead of watching what the click actually did. A test that passes because it’s testing the wrong thing is worse than no test, because it looks exactly like coverage.
Related reading
Adding a native macOS menu to Greenhouse broke Cmd+Q, and my test harness couldn't press Cmd+N either
set_menu replaces the default menu, it doesn't extend it - taking Quit, Hide, and every Edit shortcut with it. Then the WebDriver actions endpoint turned out unable to press a key.
The fix I talked myself out of
A 'don't build this' recommendation built on two unverified assumptions, and the one-line Tauri activation-policy fix that was sitting there the whole time.
Two notes nobody ever saw
Greenhouse saved a capture note and a handoff note faithfully, and showed neither: one had no field in the wire type, the other had a working command nobody called.