This log tracks all significant changes, updates, and versions in the PaperCache project.
Change: feat(release): bump version to 0.5.9; implement image paste support and markdown image widget; align background blur and font typography across modals and timers; extract audio recording features to external project
Details/Why:
- Version Bump: Bumped application version to 0.5.9 across
package.json,src-tauri/tauri.conf.json, andsrc-tauri/Cargo.toml. Added release notenotes/New Features in v0.5.9.md. - Image Support: Implemented image paste handler in
src/lib/editor/extensions.tswhich captures pasted images, saves them to.imagesdirectory via Taurisave_assetIPC command, and inserts markdown. Rendered inline viaImageWidgetin CodeMirror (src/lib/editor/widgets.ts,markdownPlugin.ts). - UI Consistency: Standardized background blur styling across search modal and timers menu (
TimersPage.tsx,KeybindsModal.tsx,App.css). Ensured timers menu adheres to custom app typography. - Product Scope Separation: Extracted voice memo audio recording and floating indicator features into a dedicated standalone repository at
~/Projects/Memoper user instruction.
Files changed: package.json, src-tauri/tauri.conf.json, src-tauri/Cargo.toml, src/api.ts, src/types.d.ts, src/App.css, src/components/KeybindsModal.tsx, src/components/TimersPage.tsx, src/lib/editor/extensions.ts, src/lib/editor/markdownPlugin.ts, src/lib/editor/widgets.ts, src/lib/editor/widgets.test.ts, src-tauri/src/lib.rs, src-tauri/src/commands/fs.rs, notes/New Features in v0.5.9.md [NEW], CHANGELOG.md, AUDIT_LOG.md.
Change: fix(ci): pin Linux workflow runner to ubuntu-22.04 across CI and release workflows to ensure glibc 2.35 compatibility
Details/Why:
- Linux
glibcCompatibility: GitHub Actions updatedubuntu-latestto Ubuntu 24.04 LTS, which links built Tauri binaries and AppImages againstglibc 2.38. When users on Ubuntu 22.04 LTS or Debian 12 attempted to launch the Linux AppImage or run the binary, the dynamic linker failed withversion glibc 2.38 not found. Changed runner matrix fromubuntu-latesttoubuntu-22.04and updated conditional steps (startsWith(matrix.os, 'ubuntu')) so that compiled Linux artifacts targetglibc 2.35and run seamlessly on Ubuntu 22.04 LTS and newer distros without requiring OS upgrades.
Files changed: .github/workflows/ci.yml, .github/workflows/release.yml, CHANGELOG.md, AUDIT_LOG.md.
Change: chore(release): bump version to 0.5.8; replace expr-eval with custom arithmetic evaluator; enable TypeScript strict mode; remove unused dependencies; fix any type in onEvent helper; add coverage thresholds
Details/Why:
- Version Bump: Bumped version to 0.5.8 across
package.json,package-lock.json,Cargo.toml,Cargo.lock, andtauri.conf.json. Added release notenotes/New Features in v0.5.8.md. - expr-eval Replacement:
expr-evalhad a high-severity prototype pollution vulnerability (GHSA-8gw3-rxh4-v6jx, GHSA-jc85-fpwf-qm7x) with no fix available. Replaced withsrc/lib/evaluator.ts— a ~150-line recursive descent parser supporting+,-,*,/,%,^, parentheses, unary operators, and variable scope resolution. Includes 26 unit tests covering arithmetic, precedence, variables, and error cases. Removedexpr-evalfrompackage.json. - TypeScript Strict Mode: Enabled
"strict": trueintsconfig.app.json. Codebase was already compatible — zero new type errors. - Unused Dependency Removal: Removed
@tauri-apps/plugin-fsand@tauri-apps/plugin-shellfrompackage.json— these npm packages were not imported anywhere in the JS/TS codebase and had no corresponding Rust plugin inCargo.toml. Note:@emnapi/coreand@emnapi/runtimewere initially removed but restored because they are required in the lockfile as transitive WASM fallback dependencies for Linux/Windows CI runners. - API Type Safety: Changed
onEventfrom(payload: any) => voidto generic<T>(name, callback: (payload: T) => void), removing the eslint-disable comment. - Coverage Thresholds: Added minimum coverage guardrails to
vite.config.ts(statements 65%, branches 50%, functions 55%, lines 65%).
Files changed: package.json, package-lock.json, src-tauri/Cargo.toml, src-tauri/Cargo.lock, src-tauri/tauri.conf.json, tsconfig.app.json, vite.config.ts, src/api.ts, src/lib/evaluator.ts [NEW], src/lib/evaluator.test.ts [NEW], src/lib/editor/MathEvaluator.ts, src/lib/editor/VariableScope.ts, src/hooks/useVariables.ts, notes/New Features in v0.5.8.md [NEW], CHANGELOG.md, AUDIT_LOG.md.
Change: fix(ci): sanitize TAURI_SIGNING_PRIVATE_KEY before tauri build to strip trailing terminal prompt artifacts (%) or URL encoding
Details/Why:
- Secret Key Sanitization: When copying private keys from macOS Zsh terminals without trailing newlines (
cat ~/.tauri/papercache.key), Zsh appends an inverted%symbol at EOF. When pasted into GitHub repository secrets, this trailing%causes base64 decoding errors (Invalid symbol 37, offset 348). Added a pre-build workflow step in.github/workflows/release.ymlto automatically strip trailing%symbols and decode URL encoding before runningtauri-action.
Files changed: .github/workflows/release.yml, CHANGELOG.md, AUDIT_LOG.md.
Change: chore(release): bump version to 0.5.7; feat(updater): overhaul auto-update flow with real-time UI feedback ("Checking…"), toast notification with "Restart Now" button, and manifest configuration; fix(api): update onEvent listener helper to forward payloads to callbacks fixing TS2345 strict build error
Details/Why:
- Version Bump: Bumped application version to 0.5.7 across
package.json,package-lock.json,Cargo.toml,Cargo.lock,tauri.conf.json,Settings.tsx, andsetupTests.ts, and added release notenotes/New Features in v0.5.7.md. - Auto-Update & On-Demand Checks: Overhauled Tauri updater mechanism to emit status events and prompt user for controlled restart when updates are ready. Added "Check for Updates" visual feedback in Settings.
- Build Fix: Fixed TS2345 error where
onEventdiscarded payload parameters, ensuring stricttsc -bcompilation succeeds cleanly.
Files changed: package.json, package-lock.json, src-tauri/Cargo.toml, src-tauri/Cargo.lock, src-tauri/tauri.conf.json, src/Settings.tsx, src/setupTests.ts, notes/New Features in v0.5.7.md, CHANGELOG.md, AUDIT_LOG.md.
Change: chore(ci): pin action references in release.yml to SHA digests; chore(repo): untrack build binary PaperCache_aarch64.app.tar.gz and update .gitignore; fix(rust): replace #[allow(dead_code)] with #[cfg(not(target_os = "macos"))] on debounce constants
Details/Why:
- Supply-Chain Security: Pinned
actions/checkout,actions/setup-node,dtolnay/rust-toolchain, andtauri-apps/tauri-actionin.github/workflows/release.ymlto immutable SHA digests to prevent action tag hijacking on write-privileged workflows. - Repository Hygiene: Removed 7MB untracked build archive
PaperCache_aarch64.app.tar.gzand added*.app.tar.gz,dist/, andcoverage/patterns to.gitignore. - Rust Config Gating: Gated
FOCUS_LOSS_DEBOUNCE_MSinsrc-tauri/src/lib.rswith#[cfg(not(target_os = "macos"))]so it is cleanly excluded on macOS where it is not used, eliminating dead-code warnings without blanket suppressions.
Files changed: .github/workflows/release.yml, .gitignore, src-tauri/src/lib.rs, CHANGELOG.md, AUDIT_LOG.md.
Change: refactor(shortcuts): extract helper to deduplicate global shortcut trigger logic; fix(timers): manage completion timeout lifecycle in store; test(editor): add comprehensive unit test suite for VariableScope
Details/Why:
- Shortcut Deduplication: Extracted
handle_shortcut_triggerhelper insrc-tauri/src/commands/shortcuts.rsto replace 16 lines of identical duplicate code acrossupdate_global_shortcutandresume_shortcuts. - Managed Timeout Lifecycle: Replaced unmanaged 5-second
setTimeoutinuseTimerStore.tswith a tracked Map of active timeouts aligned toCOMPLETED_TIMER_CLEANUP_MS(10s), ensuring timers cleaned up early or removed explicitly do not trigger orphan state updates. - VariableScope Unit Tests: Created
src/lib/editor/VariableScope.test.tstesting global/note scope merging and debounced regex mathematical expression parsing (/var x = ...) using fake timers.
Files changed: src-tauri/src/commands/shortcuts.rs, src/store/useTimerStore.ts, src/lib/editor/VariableScope.test.ts, AUDIT_LOG.md, CHANGELOG.md.
Change: fix(security): pin third-party GitHub Action references in release workflow to immutable SHA-1 digests, disable persisted checkout credentials, and pass stable toolchain selector; fix(updater): overhaul Tauri auto-update mechanism to emit granular status events and require user-triggered restarts
Details/Why:
- Supply-Chain & CI Security: Pinned
actions/checkout,dtolnay/rust-toolchain,actions/setup-node, andtauri-apps/tauri-actionto immutable SHA-1 commit hashes in.github/workflows/release.yml. Disabled persisted checkout credentials (persist-credentials: false) so read-only clones do not store auth tokens. Explicitly passedtoolchain: stabletorust-toolchainaction since pinned SHA references do not inherit default branch selectors. - Updater Artifact Configuration: Enabled
"createUpdaterArtifacts": "v1Compatible"intauri.conf.jsonand addedupdaterJsonPreferNsis: truetorelease.ymlto ensure manifest generation (latest.json) functions properly for both v1 and v2 clients. - Event-Driven Update Flow: Refactored
check_for_updatesinsystem.rsto emitupdate-statusevents (checking,available,downloading,ready,error,up-to-date) instead of executing opaque silent updates. Added a user-triggeredrestart_appcommand. - Contextual UI Feedback: Updated
Settings.tsxbutton to display "Checking…" visual state with disabled interaction during update checks. UpdatedApp.tsxto display a persistent toast notification when an update is downloaded and ready, featuring a prominent "Restart Now" button that callsrestart_app. - Dead Code Gate: Gated
FOCUS_LOSS_DEBOUNCE_MSconstant inlib.rswith#[cfg(not(target_os = "macos"))]to prevent unused code warnings on non-macOS targets.
Files changed: .github/workflows/release.yml, src-tauri/tauri.conf.json, src-tauri/src/lib.rs, src-tauri/src/commands/system.rs, src/types.d.ts, src/api.ts, src/store/useAppStore.ts, src/App.tsx, src/Settings.tsx, src/setupTests.ts, AUDIT_LOG.md, CHANGELOG.md.
Change: refactor: code quality cleanup — dead code, boilerplate, types, constants, AI comments; fix: address PR review findings — listener leak, type contracts, dead ref, stale guard, cfg scope, shortcut loop, timer constant
Details/Why:
- Dead Code Removal: Removed
resumeTimerno-op stub from useTimerStore; removedonSwipeGesture(ignored callback) from api.ts and types; removedthemePreset/setThemePresetfrom useAppStore (duplicated in useSettingsStore, all consumers used the latter); removedprevNotesReffrom useReminders (assigned but never read). - Boilerplate Consolidation:
useAppStore.ts— consolidated 9 setters intobooleanSetter/simpleSetterhelpers;api.ts— extracted 5×8-line identical listener patterns into sharedonEventhelper;KeybindsModal.tsx— replaced 9 paralleluseState/getShortcutcalls with data-driven config array;useSettingsStore.ts— removed 11 redundant individual setters (usesetSettingsinstead). - Rust Fixes: Fixed clippy
needless_borrows_for_generic_argsinnotifications.rs; added doc-commented[lints.rust] unexpected_cfgs = "allow"for objc crate macro warnings. - Type Safety:
any→ typedGraphControlsinterface in GraphView;Promise<unknown>→ properly typedopenAIChatresponse; replaced unsafeascasts with wrapper functions;pauseShortcuts/resumeShortcutschanged to returnPromise<void>. - Magic Numbers → Named Constants: Extracted ~25 magic numbers across the codebase (z-indices, timeouts, force params, debounce intervals, canvas dimensions, etc.).
- Comment Cleanup: Removed ~15 pedagogical/AI-generated comments.
- PR Review Fixes: Fixed
onEventlistener leak (addeddisposedflag); fixed stale-token guard inuseRemindersto gate before backend call; fixedopenAIChatresponse validation for missing content; removed deadsearchInputRef/useEffectin App.tsx; narrowedunexpected_cfgssuppression; made KeybindsModal global shortcut loop data-driven via config; aligned initial timer tick constant in TimersPage.
Files changed: src/store/useTimerStore.ts, src/api.ts, src/types.d.ts, src/setupTests.ts, src/store/useAppStore.ts, src/store/useAppStore.test.ts, src/store/useSettingsStore.ts, src/hooks/useReminders.ts, src/components/KeybindsModal.tsx, src/components/TimersPage.tsx, src/GraphView.tsx, src/App.tsx, src/lib/editor/extensions.ts, src/lib/editor/MathEvaluator.ts, src/lib/editor/VariableScope.ts, src/components/Editor.tsx, src-tauri/src/commands/notifications.rs, src-tauri/Cargo.toml, src-tauri/src/lib.rs, src-tauri/src/macos.rs, CHANGELOG.md, AUDIT_LOG.md.
2026-06-28 (v0.5.6 Release: Keybinds Modal, Shortcut Mappings, Timer Auto-Delete, and Graph Link Refinement)
Change: chore(release): bump version to 0.5.6; feat(shortcuts): add dedicated keybinds settings modal and update global hotkeys (Cmd+R for tasks, Cmd+T for timers); feat(timers): auto-delete expired timers after 5 seconds; feat(graph): support standard markdown links and wikilinks
Details/Why:
- Version Bump: Bumped application version to 0.5.6 across
package.json,Cargo.toml,tauri.conf.json, and added release notes fileNew Features in v0.5.6.md. - Keybinds Settings Panel: Created
ShortcutInput.tsxas a shared component andKeybindsModal.tsxas a dedicated settings panel for remapping shortcuts, accessible via Settings. Added new storage keys insettingsKeys.tsand updateduseGlobalHotkey.tsto dynamically match keyboard events against customizable shortcut settings. Refined UI layout so keycaps are centered horizontally and the container/buttons match the main Settings window. - Keybind Updates: Updated default shortcuts so
Cmd+Ropens Tasks/Reminders andCmd+Topens the countdown Timers panel, aligning with user navigation habits. Preserved cleared shortcuts viagetShortcuthelper distinguishingnullfrom''. Dynamically generated the shortcuts reference note (Cmd+/) and added recording guards inuseGlobalHotkey.tsandShortcutInput.tsx. Persisted toggle shortcut changes inSettings.tsx. - Timer Auto-Deletion: Updated
useTimerStore.tsandApp.tsxso that when a countdown timer completes, it schedules a targeted 5-secondsetTimeoutto callremoveTimer(id), reducing UI clutter. Moved backendtimer-completeevent listener toApp.tsxwith robust late-resolution cleanup tracking so completion notifications and auto-cleanup function globally even when the panel is closed or unmounted. - Graph View Link Parsing: Expanded regex detection in
GraphView.tsxto link notes using standard markdown links ([Title](Title.md)) and wikilinks ([[Title]], stripping aliases like[[Title|Display]]) in addition to/filelinks, and removed unusedczcentroid force values to keep layout logic consistent.
Files changed: package.json, src-tauri/Cargo.toml, src-tauri/tauri.conf.json, notes/New Features in v0.5.6.md, src/lib/settingsKeys.ts, src/components/ShortcutInput.tsx, src/components/KeybindsModal.tsx, src/store/useAppStore.ts, src/App.tsx, src/Settings.tsx, src/hooks/useGlobalHotkey.ts, src/store/useTimerStore.ts, src/components/TimersPage.tsx, src/GraphView.tsx, CHANGELOG.md, AUDIT_LOG.md.
Change: fix(ai): fix API key saving/clearing logic and macOS keychain credential updating; fix(graph): prevent fg.graphData crashes when opening or closing Graph View
Details/Why:
- API Key Persistence: When opening Settings,
apiKeystate initialized to empty string''. Clicking "Save Settings" after changing other preferences unintentionally took theelsebranch (await window.electronAPI.setApiKey('')), erasing existing keys from the OS keyring. UpdatedsaveSettingsto only save whenapiKey.trim()is non-empty, and only clear when!isApiKeySet. Added an explicit "Clear Key" UI button next to the password input field when an API key is set. - Keyring Credential Updating: In
src-tauri/src/commands/keychain.rs, callingset_passwordon an existing keychain entry could fail on macOS. Updatedset_api_keyto delete any existing credential before setting the new password. - Graph View Crash Fixes: Merged comprehensive defensive checks (
typeof fg.method === 'function') and ref caching intoGraphView.tsxto preventfg.graphData is not a functioncrashes when unmounting or toggling Graph View viaCmd+G.
Files changed: src/Settings.tsx, src-tauri/src/commands/keychain.rs, src/GraphView.tsx, CHANGELOG.md, AUDIT_LOG.md.
Change: fix(graph): prevent e.graphData is not a function crash on unmount and replace setInterval
Details/Why:
- When navigating to a note from Graph View (
onNodeClick), the unmounting sequence destroyed internalreact-force-graph-3dmethods onfgRef.currentbeforeGraphView's effect cleanup ran. Callingfg.graphData()threw a TypeError (e.graphData is not a function). Added defensivetypeof fg.graphData === 'function'verification before invocation and introducedgraphDataRefas a safe fallback cache for node positions. - Replaced the active
setIntervalloop inGraphView.tsxwith a chainedsetTimeoutpattern to comply with project timer guidelines (No setInterval in renderer or main process).
Files changed: src/GraphView.tsx, CHANGELOG.md, AUDIT_LOG.md.
Change: chore(release): bump version to 0.5.5; implement smart onboarding and release notes routing
Details/Why:
- Bumped application version from 0.5.3 to 0.5.5 across
package.json,src-tauri/Cargo.toml, andsrc-tauri/tauri.conf.json. - Implemented smart onboarding routing: detected brand new installations vs existing user upgrades in
run_onboarding(fs.rs). For new installs, release notes (New Features in v0.5.5.md) are suppressed and cleaned up so users open directly into a cleanWelcome.md. For upgrading users, the release note is copied and opened automatically on startup viacheckVersion(App.tsx). - Consolidated settings UI by removing duplicate "Check for updates" option from System settings, keeping it inside the new About menu.
- Added "Submit a Bug Report" button and About section (logo, Ko-fi link, version display).
- Fixed Windows path normalization for note IDs and internal links.
Files changed: package.json, src-tauri/Cargo.toml, src-tauri/tauri.conf.json, src/App.tsx, src/Settings.tsx, src/setupTests.ts, src-tauri/src/commands/fs.rs, src/hooks/useNoteStorage.ts, src/lib/editor/markdownPlugin.ts, src/GraphView.tsx, CHANGELOG.md, AUDIT_LOG.md.
Change: build(deps): move @emnapi WASM fallbacks to devDependencies for deterministic lockfile resolution across OS targets
Details/Why:
When @emnapi/core and @emnapi/runtime were listed under optionalDependencies in package.json, running npm install on macOS arm64 stripped their resolution metadata from package-lock.json (since npm deemed WASM fallback bindings inapplicable to macOS native architecture). However, sub-dependencies like @rolldown/binding-wasm32-wasi still referenced them, causing npm ci on Linux and Windows runners to crash with Missing: @emnapi/core@1.11.1 from lock file. Moved @emnapi/core and @emnapi/runtime to devDependencies to guarantee their resolution entries are preserved in package-lock.json across all OS targets.
Files changed: package.json, package-lock.json, AUDIT_LOG.md.
Change: fix: resolve TypeScript strict build errors in GraphView and setupTests
Details/Why:
Resolved production build (npm run tauri build / tsc -b) failures caused by strict typing mismatches:
ForceGraphMethodsTyping (GraphView.tsx) — ConfiguredForceGraphInstanceto extendForceGraphMethodsimported fromreact-force-graph-3d, enabling type-safe calls tod3Force,strength,d3ReheatSimulation, andcameraPosition.- Ref Variance (
GraphView.tsx) — Casted<ForceGraph3D>ref prop to resolve strictMutableRefObjectvariance mismatch. - Mock Contract (
setupTests.ts) — Added missingonUpdateReadymock implementation towindow.electronAPIin unit test environment setup.
Files changed: src/GraphView.tsx, src/setupTests.ts, AUDIT_LOG.md, CHANGELOG.md.
Change: fix: address audit findings — ESC logic, IPC types, update UX, mutex safety, ESLint (PR #68)
Details/Why: Full-pass code-quality audit surfaced several correctness bugs and robustness issues that were fixed in a single PR:
- ESC key logic (
useGlobalHotkey.ts) — The window was being hidden before checking whether any overlay (graph, timer panel, reminders) was open. Restructured to dismiss overlays in priority order; window hides only as final fallback. - IPC
voidtypes (types.d.ts,api.ts) —openExternal,openFile,setLaunchAtStartup,quitAppwere declared as returningvoidbut the underlyinginvoke()is async. Changed toPromise<void>;setLaunchAtStartupnow returns its promise instead of fire-and-forget. - Silent auto-restart (
system.rs) — App was callingapp.restart()immediately after an update download with no user notice. Now runs download in a background Tokio task, emitsupdate-readyto the frontend (which shows a toast), waits 3 seconds, then restarts. - Mutex
unwrap()panics (shortcuts.rs) — Two.unwrap()calls onMutex::lock()replaced with.map_err(|e| e.to_string())?for graceful error propagation. - Dead-end Pause button (
TimersPage.tsx) — Removed the ⏸ button sinceresumeTimeris an unimplemented stub; a button with no un-pause path was worse UX than no button. - macOS
AppHandlememory leak (macos.rs) — Added aSAFETYcomment documenting whyBox::into_rawis intentionally not paired withBox::from_raw. - ESLint warnings (
GraphView.tsx) — Introduced aForceGraphInstanceinterface replacing theanyref type; snapshottedfgRef.currentinside effect body to fix stale-ref cleanup warning. react/react-domdependency category (package.json) — Moved fromdevDependenciestodependencies.
Files changed: src/hooks/useGlobalHotkey.ts, src/types.d.ts, src/api.ts, src/App.tsx, src-tauri/src/commands/system.rs, src-tauri/src/commands/shortcuts.rs, src-tauri/src/macos.rs, src/components/TimersPage.tsx, src/GraphView.tsx, package.json, CHANGELOG.md.
Change: fix: switch autostart from LaunchAgent to LoginItem (AppleScript)
Details/Why:
The app was registered via MacosLauncher::LaunchAgent, creating a hidden .plist in ~/Library/LaunchAgents/ invisible to the user. Changed to MacosLauncher::AppleScript, which uses AppleScript to register via System Events — the app now appears in System Settings > General > Login Items as a user-manageable entry. The --silently flag and hide_dock_icon() still work as before.
Files changed: src-tauri/src/lib.rs, CHANGELOG.md.
Details/Why:
The v0.5.4 window-state fix incorrectly added +/-28px compensation for a supposed macOS frameless window titlebar offset in tauri-plugin-window-state. Tracing through the full stack (tauri-plugin-window-state v2.4.1 → tauri-runtime-wry → tao 0.35.3) confirmed no such offset exists for decorations: false windows — outer_position() returns the window frame origin and set_position() sets it correctly. Removed all compensation from save and restore paths.
Files changed: src-tauri/src/commands/system.rs, src-tauri/src/lib.rs, CHANGELOG.md.
Details/Why:
In the Settings global shortcuts section, the renderShortcutDisplay function grouped each key cap and the + to its right in a wrapper <span>, with the outer container using justify-content: space-evenly. This made the + appear closer to the left key cap. Fixed by flattening to <Fragment> siblings in a flex row with justify-content: center and gap: 4px.
Files changed: src/Settings.tsx, CHANGELOG.md.
Details/Why:
.settings-content and .editor-container used overflow-y: auto/overflow: auto without scrollbar-hiding rules. macOS overlay scrollbars auto-hide, but Windows/Linux show persistent scrollbars. Added scrollbar-width: none (Firefox), -ms-overflow-style: none (IE/Edge), and ::-webkit-scrollbar { display: none } (Chrome/Edge/Safari) to both containers.
Files changed: src/Settings.css, src/App.css, CHANGELOG.md.
Details/Why: Two bug fixes for window state and settings reliability:
-
Window position/size not persisting across restarts: The
tauri-plugin-window-statev2.4.1'son_window_readyfires before the macOS display server is ready, causingavailable_monitors()to return empty and the saved position to be silently discarded. Fixed with a two-pronged approach: (a)lib.rs:107-140spawns a background thread that sleeps 300ms then dispatchesrestore_state+ direct file read viarun_on_main_thread— ensures display server is ready; (b)commands/system.rs:33-73newrestore_window_statecommand reads.window-state.jsondirectly and callsset_position/set_size, bypassing the plugin's intersection check as a fallback. Both tray "Quit" and Settings "Quit" now callapp.save_window_state()explicitly beforeapp.exit(0). -
Launch-at-startup toggle desync with macOS System Settings: The toggle only read from
localStorage, so removing PaperCache from System Settings left it permanently stuck on. Fixed by addingget_launch_at_startupTauri command (system.rs:96-98) that queriesapp.autolaunch().is_enabled(), bridged to frontend viaapi.ts/types.d.ts.Settings.tsx:52-59runsgetLaunchAtStartup()on mount to sync toggle andlocalStoragewith real OS state.
Files changed: src-tauri/src/commands/system.rs, src-tauri/src/tray.rs, src-tauri/src/lib.rs, src/App.tsx:56, src/Settings.tsx:48-61, src/Settings.test.tsx, src/types.d.ts, src/api.ts, CHANGELOG.md.
Change: feat: graph view rebuilt, Windows focus-loss fix, Cmd+/ shortcuts, welcome revamp (v0.5.3)
Details/Why: Major graph view overhaul and cross-platform fixes:
-
Flat Circle Nodes with Occlusion: Replaced default 3D spheres with
CircleGeometrymeshes. Circles render in the transparent pass atrenderOrder: 1(after edges), withdepthWrite: true— edges passing through nodes are now cleanly occluded. -
Always-Visible Labels: Each node returns a
THREE.Groupcontaining the circle mesh plus a canvas-basedTHREE.Spritelabel. Labels are positioned below each circle and always visible (never fade on zoom). -
Cmd+F Fuzzy Search in Graph: Search bar with character-order fuzzy matching, arrow-key navigation, and Enter to fly the camera to the matched node.
-
Folder Clustering:
d3-forceforceX/forceYat 0.008 strength weakly attract same-folder nodes toward shared centroids on a 60-unit radius, creating subtle visual groupings. -
Cmd+Shift+N No Longer Hides Open App: Changed the Rust global shortcut handler in
shortcuts.rs— fornew-noteaction, window only shows if hidden; never hides when already visible. All other shortcuts (toggle, etc.) retaintoggle_windowbehavior. -
Windows Focus-Loss Debounce:
lib.rsfocus-loss handler now uses a 200ms debounce viaAtomicBool+std::thread::spawn. Clicking the title bar on Windows 10 briefly triggersFocused(false)— the debounce waits 200ms for a matchingFocused(true)before hiding. On macOS, hide remains immediate. -
Cmd+/ Shortcuts Reference: New shortcut opens or auto-creates
Shortcuts.mdwith all keyboard shortcuts and slash commands listed. -
Fresh Install Welcome: Version check in
App.tsxdetectsnulllast-seen-version (fresh install) and opensWelcome.mdinstead of looking for a new-features note. The Rust onboarding template (fs.rs) was revamped with a bullet-list feature overview. -
Lazy-Loaded Graph:
GraphViewdynamically imported viaReact.lazy()— Three.js bundle (~1.3 MB) loads only on first graph open. -
Doc Updates: Version bumped to 0.5.3 across all manifest files.
CHANGELOG.md,features.md,README.md,notes/New Features in v0.5.3.mdall updated.
Change: feat: native notifications, timers, DSL regex engine, WebGL graph with folder attraction
Details/Why: Implemented four major platform features as requested:
-
Native Reminder Notifications (Rust Backend): Removed the old Web Notification API +
setTimeoutpolling loop from the JS renderer. All reminder scheduling is now delegated to a newcommands/notifications.rsRust module. Usestokio::spawn+tokio::time::sleepto wait for exact due times and fires native OS notifications viatauri_plugin_notification. This ensures reminders are reliable when the app is minimized, handles OS notification permission gracefully, and eliminates renderer-side timer drift. Areminder-firedTauri event is emitted to the frontend to show an in-app toast and update localStorage. -
Timers: Added a new
useTimerStore.tsZustand store andTimersPage.tsxcomponent with a glassmorphic panel UI. Countdowns use a chainedsetTimeoutpattern (nosetInterval) for drift-corrected display. The Rust backend (schedule_timer/cancel_timercommands) fires the native OS notification and emitstimer-completeon completion — ensuring timers complete even when minimized. A "Timers" button was added toMainActionMenu, and the/timerslash command was added to the editor. -
DSL Regex Parsing Engine: Created
src/lib/editor/dslPlugin.ts— a factorycreateRegexPlugin(rules: DSLRule[])that generates CodeMirror ViewPlugins. Scans onlyview.visibleRangesper update tick (O(visible lines)), guaranteeing lag-free typing at any document size. SupportsclassNamemark decorations,widgetfactories, andonMatchcallbacks per rule. -
WebGL Graph with Folder Attraction: Replaced
react-force-graph-2d(Canvas 2D) withreact-force-graph-3d(Three.js / WebGL) lazy-loaded viaReact.Suspense. The graph is configured in 2D mode (z-axis locked). Added customd3-forceforceXandforceYforces that pull nodes toward per-folder centroid positions, creating organic cluster layouts where notes from the same folder attract each other.
Files changed: src-tauri/src/commands/notifications.rs [NEW], src-tauri/src/commands/mod.rs, src-tauri/src/lib.rs, src-tauri/Cargo.toml, src-tauri/capabilities/default.json, package.json, src/types.d.ts, src/api.ts, src/hooks/useReminders.ts, src/hooks/useReminders.test.ts, src/store/useAppStore.ts, src/store/useTimerStore.ts [NEW], src/components/TimersPage.tsx [NEW], src/components/MainActionMenu.tsx, src/lib/editor/slashCommands.ts, src/lib/editor/dslPlugin.ts [NEW], src/GraphView.tsx, src/App.tsx, src/App.css.
Change: feat: add slash command autosuggest, auto-open new features note, and tag action menu for v0.5.2
Details/Why:
Implemented a ghost-text inline autosuggest widget for slash commands to reduce friction. Added logic to auto-open New Features in v[version].md once per update, and automatically cleanup older version notes in the base directory via fs.rs. Replaced /task-done with /check to streamline UX. Added a right-click inline Tag Action Menu to allow bulk deletion and native Tauri-based export of notes containing specific tags. Fixed UI collision issues where the tag menu was inheriting .note-action-menu CSS class and spawning off-screen.
Change: fix: shift all keybinds to Alt and disable window auto-hide
Details/Why:
Changed default keybindings across the application from Ctrl/Cmd to Alt to prevent conflicts. Disabled auto-hide on focus loss in lib.rs to allow the app to be used as a persistent window, fixing Wayland shortcut issues.
Change: feat: enable auto-updates on startup and add manual check button
Details/Why:
Change: fix: remaining 5 issues from user plan
Details/Why:
Change: style: run prettier on App.css
Details/Why:
Change: fix: final v0.5.0-beta fixes and pipeline repair
Details/Why:
Change: Merge pull request #43 from VariableThe/feature/tauri-migration
Change: Merge pull request #42 from VariableThe/VariableThe-patch-4
Change: Update README.md
Details/Why:
Change: fix: ignore legacy Electron window-state.json files when loading notes
Details/Why:
Change: Merge pull request #41 from VariableThe/feature/tauri-migration
Change: chore: ignore window-state.json
Details/Why:
Change: Merge pull request #40 from VariableThe/feature/tauri-migration
Change: ci: fix Homebrew Cask auto-update logic for Tauri artifact names
Details/Why:
Change: docs: remove zoom shortcuts from README
Details/Why:
Change: Merge pull request #39 from VariableThe/feature/tauri-migration
Change: docs: add TAURI_MIGRATION.md
Details/Why:
Change: v0.5.0-beta: Tauri Migration
Details/Why:
Change: fix: shortcut input styling, prevent Escape from closing app, prevent window drift
Details/Why:
Change: fix: enable macOSPrivateApi to fix black corners on transparent windows
Details/Why:
Change: fix: remove invalid Objective-C selector call causing panic on launch
Details/Why:
Change: fix: resolve window cascading and shadow glitches, update performance audit
Details/Why:
Change: Merge pull request #38 from VariableThe/fix/ts-build-errors
Change: fix: remove beta from version to fix Windows MSI bundle error
Details/Why:
Change: Merge pull request #37 from VariableThe/fix/ts-build-errors
Change: fix: resolve TS build errors related to expr-eval and vitest
Details/Why:
Change: Merge pull request #36 from VariableThe/fix/github-action-tauri
Change: fix: add tauri script for github action
Details/Why:
Change: fix: resolve eslint and clippy warnings
Details/Why:
Change: chore: clean up orphaned files and co-locate tests
Details/Why:
Change: docs: fix stale Electron references in features.md and CONTRIBUTING.md
Details/Why:
Change: Merge pull request #35 from VariableThe/chore/tauri-docs-v0.5.0
Change: fix: regenerate package-lock.json from scratch for CI sync
Details/Why:
Change: fix: sync package-lock.json for CI
Details/Why:
Change: v0.5.0-beta: Tauri Migration
Details/Why:
Change: Merge pull request #34 from VariableThe/fix/package-lock-sync
Change: fix: synchronize package-lock for cross-platform builds
Details/Why:
Change: Merge pull request #33 from VariableThe/chore/clean-dependencies
Change: chore: clean up orphaned and unused dev dependencies
Details/Why:
Change: Merge pull request #32 from VariableThe/docs-gatekeeper-warning
Change: docs: improve macos gatekeeper warning
Details/Why:
Change: Merge pull request #31 from VariableThe/update-screenshots
Change: docs: update readme with new feature showcase screenshots
Details/Why:
Change: Merge pull request #30 from VariableThe/fix-onboarding-update
Change: fix: forcefully update markdown onboarding for existing users
Details/Why:
Change: Merge pull request #29 from VariableThe/chore-update-philosophy
Change: docs: ground philosophy and add antinote origin story
Details/Why:
Change: Merge pull request #28 from VariableThe/fix-onboarding-openrouter
Change: docs: add openrouter api key link to onboarding
Details/Why:
Change: Merge pull request #27 from VariableThe/VariableThe-patch-3
Change: Update PERFORMANCE_AUDIT.md
Details/Why:
Change: Merge pull request #26 from VariableThe/VariableThe-patch-2
Change: Update OS version in performance audit documentation
Details/Why:
Change: Merge pull request #25 from VariableThe/VariableThe-patch-1
Change: Update PERFORMANCE_AUDIT.md
Details/Why:
Change: Merge pull request #24 from VariableThe/fix-release-sync-step
Change: ci: remove unnecessary npm version sync step
Details/Why:
Change: Merge pull request #23 from VariableThe/fix-release-workflow
Change: ci: read release version strictly from package.json
Details/Why:
Change: Merge pull request #22 from VariableThe/release-0.4.0
Change: chore: regenerate package-lock.json to fix emnapi CI error
Details/Why:
Change: chore: sync package-lock.json
Details/Why:
Change: chore: release v0.4.0 with updated docs and onboarding
Details/Why:
Change: Merge pull request #21 from VariableThe/update-security-md
Change: docs: simplify security policy
Details/Why:
Change: Merge pull request #20 from VariableThe/add-llms-txt
Change: docs: add llms.txt for AI context
Details/Why:
Change: Merge pull request #19 from VariableThe/feat/shortcut-recorder
Change: ci: automate release on push to main
Details/Why:
Change: Merge pull request #18 from VariableThe/feat/shortcut-recorder
Change: feat: render shortcut keys as squircles and pause global shortcuts while recording
Details/Why:
Change: feat: use symbols for shortcut display
Details/Why:
Change: feat: replace text inputs with interactive shortcut recorder in settings
Details/Why:
Change: Merge pull request #17 from VariableThe/fix/internal-link-overwrite
Change: fix: completely remount CodeMirror on note change to prevent state overwrites
Details/Why:
Change: docs: add core philosophy
Details/Why:
Change: Merge pull request #16 from VariableThe/feat/production-hardening
Change: docs: add ko-fi support link
Details/Why:
Change: chore: final cleanup and lint fixes
Details/Why:
Change: Merge pull request #15 from VariableThe/feat/production-hardening
Change: fix: support closing Tasks and Graph view with Escape key
Details/Why:
Change: ui: normalize fonts across the app according to settings and adjust weights
Details/Why:
Change: ui: adjust Graph View font and hide node labels on zoom out
Details/Why:
Change: fix: import autoUpdater as CJS default export
Details/Why:
Change: chore: bump version to 0.2.10
Details/Why:
Change: 0.1.18
Details/Why:
Change: chore: address PR review feedback and fix dev build
Details/Why:
Change: fix: apply CodeRabbit auto-fixes
Details/Why: Fixed 5 file(s) based on 7 unresolved review comments.
Co-authored-by: CodeRabbit noreply@coderabbit.ai
Change: chore: Sync package-lock.json
Details/Why:
Change: feat: Production readiness & security hardening
Details/Why:
Change: Merge pull request #14 from VariableThe/docs/update-demo-images
Change: docs: update README with new demo images
Details/Why:
Change: Merge pull request #13 from VariableThe/fix-agent-rule-violations
Change: fix: resolve tasks toggle listener leak and rename menu button
Details/Why:
Change: fix: apply CodeRabbit auto-fixes
Details/Why: Fixed 3 file(s) based on 2 unresolved review comments.
Co-authored-by: CodeRabbit noreply@coderabbit.ai
Change: Merge pull request #12 from VariableThe/fix-agent-rule-violations
Change: fix: resolve architecture rule violations from AGENTS.md
Details/Why:
Change: Merge pull request #11 from VariableThe/feature/component-refactor-and-math-fixes
Change: Refactor release.yml to use matrix strategy, sync version, and auto-update homebrew tap
Details/Why:
Change: Merge pull request #10 from VariableThe/feature/component-refactor-and-math-fixes
Change: Fix mock view annotations in widgets.test.ts
Details/Why:
Change: Fix inline bugs and verify math evaluator stability
Details/Why:
Change: Refactor App components, fix math logic, and fix build typescript errors
Details/Why:
Change: Update LICENSE
Details/Why:
Change: Merge pull request #9 from VariableThe/perf-optimizations
Change: fix: resolve TS catch clause type and useVariables race condition
Details/Why:
Change: perf: optimize mathjs lazy loading and debouncing
Details/Why:
Change: docs: add comprehensive project rules for agents
Details/Why:
Change: chore: add agent rules to prevent direct pushes to main
Details/Why:
Change: feat: interactive hex color pills and DD-MM-YYYY date support
Details/Why:
Change: style: change default number highlighting color to pastel blue
Details/Why:
Change: fix: memory leak in power IPC listeners
Details/Why:
Change: docs: link performance audit in README
Details/Why:
Change: Update performance audit status
Details/Why:
Change: Fix performance and battery issues
Details/Why:
Change: Merge branch 'fix/settings-tests'
Details/Why:
Change: docs: refresh features list
Details/Why:
Change: Merge pull request #8 from VariableThe/fix/settings-tests
Change: test: fix broken tests after UI and safe storage updates
Details/Why:
Change: Merge pull request #7 from VariableThe/fix/openrouter-defaults-and-settings
Change: fix: updated openrouter defaults and made settings window track main window bounds
Details/Why:
Change: 0.1.17
Details/Why:
Change: Add GH_TOKEN to package script
Details/Why:
Change: 0.1.16
Details/Why:
Change: Fix final two TS errors
Details/Why:
Change: 0.1.15
Details/Why:
Change: Remove exactOptionalPropertyTypes
Details/Why:
Change: 0.1.14
Details/Why:
Change: 0.1.13
Details/Why:
Change: Disable strict mode to fix build
Details/Why:
Change: 0.1.12
Details/Why:
Change: Change npm ci to npm install
Details/Why:
Change: 0.1.11
Details/Why:
Change: Fix GH Actions node version and runner
Details/Why:
Change: 0.1.10
Details/Why:
Change: Update package-lock
Details/Why:
Change: 0.1.9
Details/Why:
Change: Refactor App.tsx, move to zustand, and update code quality (#6)
Details/Why:
Change: 0.1.8
Details/Why:
Change: 0.1.7
Details/Why:
Change: Merge pull request #5 from VariableThe/feature/tasks
Change: feat: Add Tasks feature, onboard docs, and updates
Details/Why:
Change: Merge pull request #4 from VariableThe/feature/currency-and-open-note
Change: feat: persist last open note and add currency pills
Details/Why:
Change: Merge pull request #3 from VariableThe/feature/checkbox
Change: style: fix prettier formatting issues
Details/Why:
Change: fix: add author field for linux deb build
Details/Why:
Change: feat: add interactive checkbox feature
Details/Why:
Change: Merge pull request #2 from blackfang007/add-windows-ci
Change: Apply Prettier formatting
Details/Why:
Change: Fix workflow formatting
Details/Why:
Change: Merge pull request #1 from blackfang007/fix-windows-line-endings
Change: Add Windows CI testing
Details/Why:
Change: Add .gitattributes for consistent line endings
Details/Why:
Change: Add empty line before horizontal rule demo and bump to 0.1.5
Details/Why:
Change: Add horizontal rule demo and update copy button text in intro notes
Details/Why:
Change: Fix Prettier errors in CSS
Details/Why:
Change: Fix ESLint and Prettier errors
Details/Why:
Change: Bump version to 0.1.3
Details/Why:
Change: Fix --- rendering and update commands
Details/Why:
Change: feat: shortcuts and hr support
Details/Why:
Change: chore: bump version to v0.1.1
Details/Why:
Change: fix: run prettier on markdown files to fix CI
Details/Why:
Change: fix: use new logo files for menu bar tray icon and clean up old ones
Details/Why:
Change: docs: rename screenshots, update README layout and add features doc
Details/Why:
Change: style: fix prettier formatting errors
Details/Why:
Change: chore: resize icon to 512x512 for electron-builder
Details/Why:
Change: 0.1.0
Details/Why:
Change: feat: add format and color recognition, tag support, and new logos
Details/Why:
Change: fix: use npm install instead of npm ci in github actions to avoid cross-platform lockfile mismatches
Details/Why:
Change: fix: update Node.js version in CI and sync lockfile
Details/Why:
Change: fix: vite config typescript errors
Details/Why:
Change: style: run prettier to fix formatting for CI
Details/Why:
Change: fix: relax strict ESLint rules to unblock CI
Details/Why:
Change: build: add support for Linux builds (AppImage and deb)
Details/Why:
Change: chore: implement tests, formatters, and address feedback
Details/Why:
Change: Bump version to 0.0.1
Details/Why:
Change: Enhance default tutorial notes with explicit examples and code snippets explanation
Details/Why:
Change: Add launch at startup setting
Details/Why:
Change: Auto-hide on blur and ignore dialogs
Details/Why:
Change: Permanently render window across all workspaces to fully prevent jumping
Details/Why:
Change: Fix window positioning across monitors and prevent space jumping
Details/Why:
Change: Fix export dialog import and stop window centering on focus
Details/Why:
Change: Update default toggle shortcut and improve active workspace pulling
Details/Why:
Change: Add toggle shortcut setting and fix window spawning on active workspace
Details/Why:
Change: Rename antipaper to papercache
Details/Why:
Change: updating readme
Details/Why:
Change: Update install instructions
Details/Why:
Change: Add MIT License
Details/Why:
Change: Update README.md
Details/Why:
Change: Configure mac package build and update icon
Details/Why:
Change: Initial commit of PaperCache
Details/Why: