docs(launcher): sync native integration doc with current Electron implementation

- Bootstrap lifecycle now reflects actual two-step flow (event_device → site_domain/search).
  Removes stale /v3/data_store/code reference and corrects the JWT claim — auth is
  x-aether-api-key + x-account-id throughout; no JWT is issued or used.
- check_hash_file_cache corrected to check_cache (actual method name in preload bridge).
- cleanup_tmp_files removed from relay list — stale .tmp cleanup is handled inline inside
  download_to_cache, not via a standalone IPC channel.
- Known Issue section replaced: all AppleScript handlers are now hardened (launch_presentation
  converted to temp-.scpt approach in the companion Electron commit ca4fddd).
- Markdown lint fixes: blank lines around tables, table pipe spacing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-05-11 17:16:01 -04:00
parent c5c5292715
commit f72454f379

View File

@@ -9,6 +9,7 @@
The Aether Events Launcher utilizes an Electron-based "Native Shell" to provide OS-level capabilities that are normally restricted by browser sandboxing. This enables persistent file caching, direct control of presentation software (Keynote, PowerPoint), and hardware telemetry. The Aether Events Launcher utilizes an Electron-based "Native Shell" to provide OS-level capabilities that are normally restricted by browser sandboxing. This enables persistent file caching, direct control of presentation software (Keynote, PowerPoint), and hardware telemetry.
### Operational Modes ### Operational Modes
| Mode | Purpose | File Handling | | Mode | Purpose | File Handling |
| :--- | :--- | :--- | | :--- | :--- | :--- |
| **Default** | Standard web browser access. | Direct downloads; no local caching. | | **Default** | Standard web browser access. | Direct downloads; no local caching. |
@@ -49,9 +50,9 @@ The integration is built on a decoupled three-layer communication model to ensur
To support rapid onsite deployment, the native app requires zero manual setup. To support rapid onsite deployment, the native app requires zero manual setup.
1. **Seed:** On launch, the Main process reads a local `seed.json` (Device ID + API Key). 1. **Seed:** On launch, the Main process reads a local `seed.json` (Device ID + API Key).
2. **Identity:** Calls `GET /v3/data_store/code/{device_code}` or `GET /v3/crud/event_device/{id}` to pull operational context. 2. **Identity:** Calls `GET /v3/crud/event_device/{id}` to pull device config and extract `app_base_url` (the event FQDN) and `account_id`.
3. **Hydrate:** Authenticates with the Aether V3 API and injects the **JWT** and **Device Config** into the UI environment. 3. **Site Context:** POSTs to `/v3/crud/site_domain/search?limit=1` with the FQDN to resolve the correct site. No JWT — auth is `x-aether-api-key` + `x-account-id` throughout.
4. **Launch:** Navigates the SvelteKit frontend directly to the assigned Event Launcher route. 4. **Launch:** Navigates the SvelteKit frontend directly to the assigned Event Launcher route (`/events/{eventId}/launcher/{locationId}`).
--- ---
@@ -85,11 +86,12 @@ When a user clicks "Open", the system follows a non-destructive sequence:
The native shell provides specialized handlers for controlling the "Podium Experience." The native shell provides specialized handlers for controlling the "Podium Experience."
### 5.1 Presentation Acts ### 5.1 Presentation Acts
| Action | Handler | Actuator (macOS) | | Action | Handler | Actuator (macOS) |
| :--- | :--- | :--- | | :--- | :--- | :--- |
| **Launch** | `launch_presentation` | `open` or `osascript` (slideshow start) | | **Launch** | `launch_presentation` | `open` or `osascript` (slideshow start) |
| **Control** | `control_presentation` | `osascript` (next/prev slide) | | **Control** | `control_presentation` | `osascript` (next/prev slide) |
| **Clean Up**| `kill_processes` | `killall -INT` (graceful exit) | | **Clean Up** | `kill_processes` | `killall -INT` (graceful exit) |
### 5.2 System Management ### 5.2 System Management
- **Telemetry:** Pushes `cpu_usage`, `memory_free_gb`, and `foreground_app` via heartbeats using the `get_device_info` relay. - **Telemetry:** Pushes `cpu_usage`, `memory_free_gb`, and `foreground_app` via heartbeats using the `get_device_info` relay.
@@ -142,11 +144,10 @@ no-op when `window.aetherNative` is not present (i.e., in browser/non-native mod
- `get_device_info()` — Returns OS metadata, IP list, hostname, and path placeholders (`[home]`, `[tmp]`). - `get_device_info()` — Returns OS metadata, IP list, hostname, and path placeholders (`[home]`, `[tmp]`).
### File Cache ### File Cache
- `check_hash_file_cache({cache_root, hash, hash_prefix_length?})` — Verifies a file exists in the local hashed cache. - `check_cache({cache_root, hash, hash_prefix_length?, verify_hash?})` — Verifies a file exists in the local hashed cache. `verify_hash: true` re-hashes to confirm integrity.
- `download_to_cache({url, cache_root, hash, api_key, account_id, hash_prefix_length?})` — Streams a file download to the hashed cache with SHA-256 integrity check. - `download_to_cache({url, cache_root, hash, api_key, account_id, hash_prefix_length?})` — Streams a file download to the hashed cache with SHA-256 integrity check. Stale `.tmp` files (older than 5 min) from crashed downloads are cleaned up automatically on each call.
- `copy_from_cache_to_temp({cache_root, hash, temp_root, filename, hash_prefix_length?})`**Preferred primitive.** Copies a cached file to temp and returns `{ success, path }`. The Svelte caller decides what to do next (run a script, open it, etc.). - `copy_from_cache_to_temp({cache_root, hash, temp_root, filename, hash_prefix_length?})`**Preferred primitive.** Copies a cached file to temp and returns `{ success, path }`. The Svelte caller decides what to do next (run a script, open it, etc.).
- `launch_from_cache({cache_root, hash, temp_root, filename, hash_prefix_length?, script_template?})` — Combines copy + launch in one call. Uses `script_template` if provided, otherwise falls back to hardcoded extension logic. See **Configurable Launch Scripts** below. - `launch_from_cache({cache_root, hash, temp_root, filename, hash_prefix_length?, script_template?})` — Combines copy + launch in one call. Uses `script_template` if provided, otherwise falls back to hardcoded extension logic. See **Configurable Launch Scripts** below.
- `cleanup_tmp_files({cache_root, max_age_minutes?})` — Removes stale `*.tmp` download artifacts. Default: 1440 min (24h). Called at launcher startup.
> `hash_prefix_length` defaults to `2` throughout. Do not change without coordinating all devices — mismatched values create orphaned cache subdirectories. > `hash_prefix_length` defaults to `2` throughout. Do not change without coordinating all devices — mismatched values create orphaned cache subdirectories.
@@ -225,16 +226,18 @@ unrecognised extensions.
} }
``` ```
### Known Issue: `launch_presentation` vs `launch_from_cache` Inconsistency ### AppleScript Execution — All Handlers Hardened (2026-05-11)
`shell_handlers.ts` `native:launch-presentation` still uses the old `osascript -e "<inline>"` approach All AppleScript execution in the native shell now writes scripts to a temp `.scpt` file and
for its AppleScript execution. `file_handlers.ts` `native:launch-from-cache` uses the hardened runs `osascript "<path>"` rather than the old `osascript -e "<inline>"` approach.
temp-`.scpt`-file approach. These two handlers behave differently for identical file types.
- **`launch_from_cache`** (used by the "Open" button in the Launcher file list) — hardened, correct. - **`run_osascript`** — hardened (2026-05-11, earlier batch)
- **`launch_presentation`** (used by `electron_relay.launch_presentation`) — legacy `-e` flag, fragile on paths with spaces or special characters. - **`launch_from_cache`** — hardened (same batch)
- **`launch_presentation`** — hardened (2026-05-11, follow-up fix; was the last handler still using `-e`)
- **`control_presentation`** — uses single-line scripts with no path interpolation; `-e` is safe here and retained for simplicity
**Recommendation:** `launch_presentation` should be updated to use the temp-`.scpt` approach in a future Electron build. It is not used in the primary file-open flow today, so this is not blocking. The `-e` approach breaks on (1) multi-line scripts and (2) file paths containing spaces,
quotes, or parentheses — common in conference presentation filenames.
### Not Exposed via Relay (intentional) ### Not Exposed via Relay (intentional)
- `get_seed_config` / `get_jwt` — Exposed in the preload but not relayed to the UI. The JWT and seed are injected into the environment at startup; components should not call these directly. - `get_seed_config` / `get_jwt` — Exposed in the preload but not relayed to the UI. The JWT and seed are injected into the environment at startup; components should not call these directly.