# Stop exposing raw paths to the window Branch: `unbind-paths` → `main` PR 5 of the review fixes plan (`docs/review-fixes-plan.md`), the first of the 0.5.3 series; the version does not change in this PR. ## What changed **No bound method takes a path any more (S4).** Every exported method of the Go service can be called from the window. Before, four of them took a path, so any script running there could pass one: - `LoadPath` and `AssignSamplePath` could read any file. - `ExportFolder` and `ExportZip` could write anywhere. With overwrite set, `ExportFolder` replaced (deleted) a folder of the caller's choosing. Now: - **`LoadPath` and `AssignSamplePath` are no longer bound** (`//wails:ignore`). Go still uses them: `Load` after the open dialog, and `main.go`'s file-drop handler. The frontend never called them. - **Export goes where the dialog chose.** - `ChooseExportFolder` and `ChooseZipPath` remember the chosen target on the service. They still return it, so the frontend can tell a cancelled dialog. - `ExportFolder(overwrite)` and `ExportZip(overwrite)` use that target. With nothing chosen, they fail with "choose where to export first". - The confirm-and-overwrite call uses the same target as the first try. - **When targets are forgotten:** - after a successful export, so the next export asks again; - on New and Load, so a target chosen for one project is never used for another; - when the dialog is cancelled. - **Zip extension:** `.zip` is now added when the zip path is chosen, rather than at export, so the path shown and the path written are the same. - **Frontend:** `exportWith` in `frontend/src/lib/store.svelte.ts` passes only `overwrite`. The bindings are regenerated, and the generated `service.ts` has no method with a path parameter. **Tests.** - `TestExport` now goes through the dialogs, and checks that the target is forgotten after a successful export. - New `TestExportTarget` covers: - export with nothing chosen fails; - a cancelled dialog clears an earlier choice; - New and Load clear both targets. - Other tests use a small `exportTo` helper that chooses the folder in the fake dialog first. ## Notes - **A target survives a failed export.** It is kept if the export fails for a reason other than "already exists", for example a missing sample, so trying again after fixing the problem does not need the dialog. The plan clears it only after success and on New and Load. - **`docs/build-plan.md` is out of date here.** Its API sketch from M4 still lists `AssignSamplePath` and older export signatures. I left the build plan as the historical design. Say if it should be brought up to date. - **A GTK warning seen under Xvfb is not new.** In a headless start on the server, two `Gtk-CRITICAL` lines (`gtk_widget_get_display`, `gtk_native_get_surface`) sometimes appear before the window shows: in 3 of 12 runs of this branch and 1 of 18 runs of `main`. The app starts normally either way. This PR does not touch window code, so it looks like a Wails/GTK startup race in a headless session. It has not been seen on Windows. ## Testing **On the server, every command with `GOTOOLCHAIN=go1.27.4`:** - `go test ./...` passes. - `go vet ./...` (also with `GOOS=windows`) and `staticcheck ./...` are clean. - `govulncheck ./...`: "No vulnerabilities found." - `npm install`, `npm run check` (0 errors, 0 warnings) and `npm run build` pass. The lockfile was not committed. - `wails3 build` builds, and the app starts under Xvfb. **On the laptop (PowerShell, in the repo):** 1. `git fetch; git checkout unbind-paths` 2. `cd frontend; npm run check; cd ..`: 0 errors, 0 warnings. 3. `wails3 dev`: assign a WAV to a pad, then choose Export to folder and pick an empty folder. It exports, and the notice shows where. 4. Export to folder again into the same folder. The "Replace existing files?" prompt lists the `.xpj` and data folder. Choose Replace: it exports. Do it once more and choose Cancel: nothing changes. 5. Export zip: pick a name without `.zip`. The file is written with `.zip` added. Export zip again to the same name: it asks before replacing. 6. Cancel the folder dialog: nothing happens and no error shows. 7. Drop a WAV file onto a pad: it is assigned as before. 8. Load a project, then export it: the dialog asks for a folder again.