# Specification: Aether Native Host Automation & Scripting **Target OS:** macOS (Primary), Linux/Windows (Secondary) **Languages:** AppleScript (`osascript`), Bash (`sh`), Node.js `child_process` ## 1. Presentation Control (AppleScript) To provide a seamless "Podium Experience," the app uses AppleScript to control third-party presentation software. ### 1.1 Microsoft PowerPoint * **Intent:** `powerpoint:start` * **Script:** ```applescript tell application "Microsoft PowerPoint" activate open (POSIX file "[FILE_PATH]") run slide show settings of active presentation end tell ``` * **Intent:** `powerpoint:quit` * **Script:** `quit application "Microsoft PowerPoint" saving no` ### 1.2 Apple Keynote * **Intent:** `keynote:start` * **Script:** ```applescript tell application "Keynote" activate open (POSIX file "[FILE_PATH]") start (front document) end tell ``` ### 1.3 Adobe Acrobat (PDF) * **Intent:** `acrobat:fullscreen` * **Script:** ```applescript tell application "Adobe Acrobat Reader" activate -- Acrobat doesn't have a direct "Start Slideshow" AppleScript command -- We use system events to trigger Cmd+L (Full Screen) tell application "System Events" to keystroke "l" using {command down} end tell ``` ## 2. Process Management (Bash/Node) The app must ensure that only one presentation is "Active" to prevent audio overlap or confusion. | Action | macOS Command | Linux/Windows Mock | | --- | --- | --- | | **Kill Office** | `killall -INT "Microsoft PowerPoint"` | `pkill -f powerpnt` | | **Kill Keynote**| `killall -INT "Keynote"` | `echo "Keynote Not Supported"` | | **Kill Acrobat**| `killall -9 "Acrobat Reader"` | `pkill -f acroread` | | **Kill Parallels**| `pkill -i -f '(Parallels).*(PowerPoint)'` | `N/A` | ## 3. Recording Lifecycle (`aperture_wrapper`) The app manages high-quality screen and audio recording using the `aperture` CLI or a custom wrapper. ### 3.1 Start Recording * **Intent:** `record:start` * **Action:** Launch `aperture` as a child process. * **Command Pattern:** ```bash aperture --fps 30 --highlight-clicks --audio-device "[DEVICE_ID]" --output "[PATH]/[SESSION_ID].mp4" ``` * **Telemetry:** Push `record_status: "Recording"` and the PID to the V3 API. ### 3.2 Stop Recording * **Intent:** `record:stop` * **Action:** 1. Send `SIGINT` (Interrupt) to the recorded process. 2. Wait for file finalization. 3. Verify file existence and minimum size. 4. Push `record_status: "Idle"` to the V3 API. ## 4. Host Hardening & "Odd Stuff" Specialized scripts to ensure the Mac laptop behaves as a dedicated podium. ### 4.1 Podium Lockdown (macOS) * **Prevent Sleep:** `caffeinate -dis &` (Stores PID). * **Volume Enforce:** `osascript -e "set volume output volume 100"` * **Timezone Sync:** Force `America/New_York` (ET) for all device status pushes to ensure dashboard consistency. * **Hide Menu Bar/Dock:** (Optional) Use `System Events` AppleScript to toggle auto-hide. ### 4.2 Digital Poster Screen Saver To prevent screen burn-in and provide branding when the podium is idle: * **Idle Detection:** Uses `svelte-idle` to track user activity. * **Action:** Automatically rotates through a random list of `event_file` objects marked as "poster". * **Override:** Any mouse movement or click immediately kills the screen saver modal. ### 4.3 WebSocket Remote Control (The "Tech Bridge") Allows onsite staff to manage the podium without physical access. * **Intents:** * `ae_refresh:now`: Triggers a full page reload. * `ae_native:cmd`: Executes a whitelisted shell command. * `ae_open:event_file`: Remotely opens a specific presentation or image. * `ae_record:start/stop`: Remotely toggles the Aperture wrapper. ## 5. Accessibility & Permissions (macOS TCC) Since this is a specialized app, we must handle Apple's TCC (Transparency, Consent, and Control) layer: - **AV Access:** Use `systemPreferences.askForMediaAccess('camera')` and `microphone`. - **Accessibility:** For remote control/automation, check `systemPreferences.isTrustedAccessibilityClient(true)`. - **Screen Recording:** Triggered by the first `aperture` call; the app should provide a UI guide to help the user enable it in System Settings. - **Check Command:** `osascript -e 'tell application "System Events" to get UI elements enabled'` ## 6. Automation Strategy (The "Intent" Pattern) To keep the bridge secure, we do **not** send raw scripts from the UI. Instead, we send an "Intent." **Renderer Call:** ```javascript native_app.launcher.execIntent('presentation:start', { path: '/tmp/my_deck.pptx' }); ``` **Main Process Handler:** 1. Verify the file path is within the allowed `[tmp]` directory. 2. Identify the file extension (`.pptx`). 3. Select the corresponding AppleScript template. 4. Replace `[FILE_PATH]` and execute via `child_process.exec`. ## 7. Linux Development Mocking Since development happens on Arch Linux, the `execIntent` handler will check `process.platform`: - If `darwin`: Execute `osascript` or `sh`. - If `linux`: Write the intended command to a log file at `~/OSIT/automation_debug.log` and simulate a "Success" return. - **Recording Mock:** Use `ffmpeg` or generate a fake `.mp4` file to test the sync/upload logic. ## 8. Refresh & Sync Loops Decoupled polling to balance performance and responsiveness: - **Session Loop (30s):** High frequency for active podium changes. - **Location Loop (2m):** Medium frequency for room configuration. - **Device Loop (5m):** Low frequency for background heartbeat and telemetry. - **Sync Loop (15m):** Background file warming for upcoming presentations.