The handler was a stub that required an explicit configStr — the Svelte
caller never provides one, so mirror/extend silently failed every launch.
Now auto-detects connected displays:
- mirror: parses displayplacer list output, adds mirror:<primary_id> to
secondary display(s); removes any existing mirror key first.
- extend: re-applies current layout if already extended; otherwise strips
mirror keys and computes side-by-side origins from each display's width.
- configStr still takes priority when provided (manual per-device override).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
macOS invalidates Accessibility permission whenever the app binary
changes (code signature shifts on each build). New --fix-accessibility
flag runs tccutil reset + a sudo sqlite3 TCC grant via SSH after the
.app is synced. Falls back gracefully if sqlite3 grant fails (SIP or
missing sudoers), logging a warning with a pointer to the manual steps.
README documents the symptom, manual fix, sudoers one-time setup,
and bundle ID (com.electron.aetherlauncher).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
copy_from_cache_to_temp IPC handler was registered in file_handlers.ts
but never added to the preload bridge, making it unreachable from Svelte
despite being the documented preferred primitive for custom launch flows.
launch_presentation was the last handler still using osascript -e with
inline path injection. Converted to the temp-.scpt-file approach already
used by run_osascript and launch_from_cache — prevents breakage on
presentation filenames with spaces, quotes, or parentheses.
Also adds a pre-copy existence check to launch_from_cache so a missing
cache entry returns a meaningful error instead of a raw ENOENT.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Packaging was silently hanging forever because yauzl 2.10.0 read streams
emit no data events under Node 26, causing extract-zip to block indefinitely
inside @electron/packager 20. Fix: postinstall script patches
@electron/packager/dist/unzip.js to use bsdtar (libarchive) instead.
bsdtar was chosen over 7z because 7z refuses chained symlinks in macOS
.app framework bundles. Both package:linux and package:mac now produce
correct output.
Also corrects the V3 API bootstrap contract in api_client.ts:
- SearchQuery body was wrapped in an extra {search_query: ...} layer — removed
- x-no-account-id header standardised to 'bypass'
- Redundant x-no-account-id removed from file download headers
- Smoke test rewritten to validate the real two-step bootstrap path
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace unreliable AppleScript PowerPoint API (run slide show of settings)
with System Events keystroke approach, matching proven behavior from the
old MasterKey app. Opens the file, waits 3s for load, then sends Cmd+Return
to start the slideshow from slide 1.
- Use app_base_url from the device record directly instead of always
falling back to localhost; use https for real domains and http for
localhost dev URLs only.
- Suppress DevTools in packaged .app builds (app.isPackaged check)
so they only open during development.
The -e flag approach breaks on multi-line AppleScript and on file paths
containing spaces or quote characters. Write the script to a temp file
in os.tmpdir() and invoke osascript with the file path instead. The
temp file is cleaned up after execution.
Add electron-packager as a dev dependency and a package:mac npm script
that compiles TypeScript and packages dual-arch (x64, arm64) macOS builds
into builds/ using the OSIT icon.
file_handlers.ts had AI-generated escaped backticks (\`) and template
literal dollar signs (\${) throughout, causing TypeScript compile errors
("Invalid character", "Unterminated template literal"). Fixed all 15
affected lines.
README updated: corrected seed config path from resources/seed_config.json
to ~/seed.json (external to app bundle by design), added explanation of
why it's kept external (no re-signing needed per device), and documented
the 2-char hash prefix cache layout with consistency warning.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Added .tmp -> .file download pattern with integrity checks.\n- Implemented auto-purge for stale temp files (>5 mins).\n- Added verify_hash support to check-cache handler.\n- Improved error handling for network interruptions.
- Upgraded launch_from_cache to automatically trigger LibreOffice/AppleScript launchers after file copy.
- Hardened expandPath to resolve [home] and [tmp] placeholders anywhere in strings via global regex.
- Enhanced get-device-info telemetry to provide absolute home and tmp paths to the UI.
- Exposed native:launch-presentation in preload and implemented explicit LibreOffice (--impress) support on Linux.
- Implemented get_device_info for OS/Network telemetry.
- Added run_cmd_sync using execSync for blocking-style commands.
- Implemented kill_processes (plural) to support multiple process termination.
- Standardized open_local_file_v2 and all bridge methods to snake_case.
- Synchronized preload and main handlers with SvelteKit relay expectations.
- Refactored all IPC methods and parameters to snake_case for consistency with SvelteKit.
- Implemented exhaustive background caching engine with download locking.
- Reverted to legacy-proven flat hash storage pattern (hash.file).
- Added axios for reliable stream-based binary downloads.
- Updated preload and main handlers to support recursive room data fetching.
- Added logic to construct launcher URL based on hydrated device context.
- Implemented dev/production host fallback for demo.localhost.
- Restored missing package.json with proper start and build scripts.
- Finalized IPC handlers for seed and device configuration.