Skip to content

Sandbox vault persistence via security-scoped bookmarks (#10)#18

Merged
oratis merged 2 commits into
mainfrom
mas-bookmarks
May 28, 2026
Merged

Sandbox vault persistence via security-scoped bookmarks (#10)#18
oratis merged 2 commits into
mainfrom
mas-bookmarks

Conversation

@oratis
Copy link
Copy Markdown
Owner

@oratis oratis commented May 28, 2026

Summary

Implements cross-launch vault persistence — the last MAS technical
blocker. The App Sandbox only grants folder access for the session a
user picks it; this captures a security-scoped bookmark and resolves
it on the next launch to re-acquire access. The direct-download build
gets "reopen last vault" for free (it just stores the plain path).

  • src-tauri/src/bookmark.rscreate / resolve_and_start via
    objc2-foundation NSURL (bookmarkDataWithOptions:…WithSecurityScope,
    URLByResolvingBookmarkData:…, startAccessingSecurityScopedResource).
    The resolved URL is leaked so access persists for the session. No-op
    stubs off macOS.
  • commands_vaultopen_vault persists {path, bookmark_b64} to
    app_data_dir/last-vault.json; new restore_vault command returns the
    path to open (resolving the bookmark on sandbox builds).
  • vault.rsVaultState gains a tokio open-lock so a launch-time
    restore can't race a user open on the Tantivy writer lock (this was the
    cause of the earlier "can't open vault" regression — now guarded).
  • App.tsx — on mount, restoreVault()openRecentVault(path).
  • Cargo: base64 + macOS-only objc2 / objc2-foundation.

Test plan

  • pnpm tsc --noEmit, pnpm lint, cargo check clean
  • app builds, ad-hoc sandbox-signed, launches (sandbox + bookmark
    entitlements verified)
  • On device: open a vault → ⌘Q → relaunch → vault auto-restores
    without a permission prompt (the real MAS persistence check)
  • direct build: same reopen-last-vault behaviour

🤖 Generated with Claude Code

oratis and others added 2 commits May 28, 2026 16:47
Lets the App Sandbox (MAS) build re-open the user's vault across
launches, and gives the direct build "reopen last vault" for free.

- src/bookmark.rs: create/resolve security-scoped bookmarks via
  objc2-foundation NSURL. resolve_and_start() re-grants folder
  access process-wide (startAccessingSecurityScopedResource) so our
  std::fs vault scanner works again; the resolved NSURL is leaked to
  keep access alive for the session. No-op stubs off macOS.
- commands_vault: open_vault persists {path, bookmark_b64} to
  app_data_dir/last-vault.json; new restore_vault command resolves it
  (bookmark on sandbox, plain path on direct) and returns a path to open.
- vault.rs: VaultState gains a tokio open_lock so a launch-time
  restore can't race a user-triggered open on the Tantivy writer lock
  (the cause of the earlier "can't open vault" regression).
- App.tsx: on mount, restoreVault() → openRecentVault(path).
- Cargo: base64 + macOS-only objc2 / objc2-foundation (NSURL feature).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The compositionend handler dispatched a RECOMPUTE_META transaction
synchronously, while ProseMirror was still finalizing the composed
text — it re-read the DOM and double-counted, adding a spurious
newline on every Chinese keystroke (regression shipped in v0.5.0).
Removed the dispatch; decorations refresh on the next real edit.
The store flush (read-only getMarkdown + onChange) is unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@oratis oratis merged commit c95f2f7 into main May 28, 2026
2 checks passed
@oratis oratis deleted the mas-bookmarks branch May 28, 2026 09:14
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.

1 participant