Files
OSIT-AE-App-Svelte/documentation/NATIVE_APP_AUTOMATION_SCRIPTS.md
Scott Idem 7a8871c51f docs: update native app specifications and TODO for Phase 5 completion
- Synchronize Functional Spec with new system handlers (Wallpaper, Power, Recording, Displays).
- Update Automation Scripts with finalized AppleScript handlers for PowerPoint and Keynote.
- Mark IDAA and Phase 5 automation tasks as completed in TODO.md.
2026-01-30 11:35:01 -05:00

146 lines
6.6 KiB
Markdown

# Specification: Aether Native Host Automation & Scripting
**Target OS:** macOS (Primary), Linux/Windows (Secondary)
**Languages:** AppleScript (`osascript`), Bash (`sh`), Node.js `child_process`
**Implementation:** `src/main/shell_handlers.ts` (Electron App)
## 1. Presentation Launch & Control (AppleScript)
To provide a seamless "Podium Experience," the app uses AppleScript to control third-party presentation software.
### 1.1 Microsoft PowerPoint
* **Launch:** `powerpoint:launch`
```applescript
tell application "Microsoft PowerPoint"
activate
open (POSIX file "[FILE_PATH]")
delay 1
run slide show of active presentation
end tell
```
* **Control:**
* **Next:** `tell application "Microsoft PowerPoint" to next slide of slide show view of active presentation`
* **Prev:** `tell application "Microsoft PowerPoint" to previous slide of slide show view of active presentation`
* **Start:** `tell application "Microsoft PowerPoint" to run slide show of active presentation`
* **Stop:** `tell application "Microsoft PowerPoint" to stop slide show of active presentation`
* **Quit:** `quit application "Microsoft PowerPoint" saving no`
### 1.2 Apple Keynote
* **Launch:** `keynote:launch`
```applescript
tell application "Keynote"
activate
open (POSIX file "[FILE_PATH]")
delay 1
start (front document)
end tell
```
* **Control:**
* **Next:** `tell application "Keynote" to show next`
* **Prev:** `tell application "Keynote" to show previous`
* **Start:** `tell application "Keynote" to start (front document)`
* **Stop:** `tell application "Keynote" to stop`
### 1.3 Adobe Acrobat (PDF)
* **Launch:** `acrobat:fullscreen`
```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
```
### 1.4 LibreOffice (Linux Testing)
* **Launch:** `libreoffice:launch`
```bash
libreoffice --impress "[FILE_PATH]"
```
* **Note:** LibreOffice control on Linux is currently limited to launch-only.
## 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
window.aetherNative.launch_presentation({ path: '/tmp/my_deck.pptx', app: 'powerpoint' });
window.aetherNative.control_presentation({ app: 'powerpoint', action: 'next' });
```
**Main Process Handler (`src/main/shell_handlers.ts`):**
1. Verify the file path is within the allowed `[tmp]` directory.
2. Select the corresponding AppleScript template based on `app` and `action`.
3. 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`.
- If `linux`: Use `libreoffice` for launch, or log intent for control commands.
- **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.