Skip to content

Use native Save As for desktop palette exports - #108

Merged
vycdev merged 3 commits into
developfrom
codex/macos-palette-export
Oct 29, 2026
Merged

vycdev merged 3 commits into
developfrom
codex/macos-palette-export

Conversation

@vycdev

@vycdev vycdev commented Oct 24, 2026 •

Copy link
Copy Markdown
Owner

🤖 This was created by Codex using the GPT-6.1-Sol model on xhigh reasoning effort, during automated macOS end-to-end testing.

Desktop palette export currently uses a Blob anchor download. On the tested macOS 27.0.1 M6 installation this twice left the released app inaccessible while its main thread waited in WebKit's download destination / sandbox extension path.

Route .kpal exports through the existing saveBlobToFile helper: Tauri uses native Save As and the filesystem plugin, while the web app retains browser downloads. Cancellation is silent, errors show localized feedback, and a later successful save clears that feedback. Add translations and localized guide notes.

Fixes #104.

Validation:

  • npm run lint: passed.
  • npm run build: passed (includes TypeScript checks).
  • npm test: 860 passed, 1 skipped, 0 failed.
  • npm run test:docs: 3 passed.
  • npx playwright test tests/e2e/palette-desktop-save.spec.ts tests/e2e/profile-desktop-save.spec.ts tests/e2e/palette-management.spec.ts: 3 passed.
  • git diff --check: passed.

The regression covers real web downloads plus mocked Tauri dialog/write/close IPC, cancellation, failure/recovery, serialized names and disabled colors. The patched native binary was not rebuilt: the QA brief requires using release DMGs and forbids a local desktop build. A Downloads/protected-location factor may contribute to the observed native hang; this change avoids that browser-download path.
Additional engine validation: PLAYWRIGHT_BROWSERS_PATH=/Users/vycdev/Desktop/kromacut-e2e/.playwright npx playwright test --config ../perf/palette-webkit.config.ts passed (1 test). The temporary external config runs this PR's palette-desktop-save.spec.ts in WebKit against its production preview; it does not change test behavior.

Repository target note: this feature branch was cut from latest main as requested by the QA brief. The repository only permits develop→main PRs, so this PR targets develop (currently the same source tree as main). Earlier Require develop into main failures are historical branch-policy checks from the initial target, not code/test failures; GitHub may still show them on this head.

@vycdev
vycdev changed the base branch from main to develop October 24, 2026 15:49
- Retry partial native writes and reject stalled writes with localized feedback
- Add regressions for saved content, cancellation, and failure cleanup
- Prevent automatic feedback dismissal from masking recovery failures
- Update the unreleased changelog
@vycdev

vycdev commented Oct 29, 2026

Copy link
Copy Markdown
Owner Author

Automated review and fixes

Pushed 53536dd to this branch.

Findings

  • ✅ Native saves can silently discard partially written bytes: Updated saveBlobToFile.ts to retry unwritten bytes and reject zero-progress writes while preserving cleanup. Added regressions for partial writes, stalled writes, failure cleanup, and cancellation.

  • ✅ Recovery test can pass without clearing export errors: Paused the feedback-dismissal timer in palette-desktop-save.spec.ts so automatic expiry cannot satisfy the recovery assertion. TypeScript and lint checks pass; Playwright was not run, as requested.

  • ➖ Suspected missing native filesystem permissions: The locked filesystem plugin's existing fs:allow-write-file permission also grants open and write. No capability changes were retained.

Verification: E2E palette-desktop-save, palette-management and profile-desktop-save pass (3/3).


Fixed by GPT 6.1 Sol

@vycdev
vycdev merged commit e28339e into develop Oct 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

macOS: palette export uses browser download and can make app inaccessible

1 participant