diff --git a/.ae_brief b/.ae_brief new file mode 100644 index 00000000..555144c9 --- /dev/null +++ b/.ae_brief @@ -0,0 +1,15 @@ +# Aether Project Brief: aether_app_sveltekit +**Last Updated:** 2026-01-20 23:41:05 +**Current Agent:** mcp_agent + +## 🛠️ What I Just Did +Finalized 7 documentation files for Aether Native V3: Architecture, Functional Spec, Rewrite Plan, API Payload, Bridge Interface, Deployment Plan, and Automation Scripts. Cross-referenced and audited for data integrity. + +## 🚧 Current Blockers +None. Core specs are complete. + +## ➡️ Exact Next Steps +1. Scaffold new Electron 33+ project. 2. Implement the V3 bootstrapping/hydration logic. 3. Port the core Event Launcher IPC bridge. + +--- +*Generated by ae_brief* diff --git a/GEMINI.md b/GEMINI.md index 30935bcc..af9e609c 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -62,8 +62,13 @@ This project is the frontend UI/UX for the Aether (AE) system, built with Svelte ## 📝 Development History (Consolidated) ### Hardening & V3 Stabilization (2026-01-20) -- **IDAA Isolation:** Created specialized `qry_ae_obj_li__event_v2` for the IDAA Recovery Meetings module. It uses legacy V2 endpoints and implements search via the `default_qry_str` field to bypass current V3 stability issues. -- **Fix(Events):** Restored general `qry_ae_obj_li__event` to V3 with a robust "Body + Header" injection pattern. It uses `account_id_random` in the body for filtering (bypassing the "Integer Trap") and `x-account-id` in the headers for Auth validation. +- **IDAA Search Hardening:** Isolated IDAA Recovery Meetings to a specialized `qry_ae_obj_li__event_v2` function. Restored full 154-result capacity and implemented "Inclusive OR" location logic (Virtual/In-person). +- **System Lookups Restoration:** Fixed a `TypeError` by correctly exporting `get_ae_obj_li_for_lu` in `api.ts`. Reverted lookup endpoints to stable V2 paths to resolve V3 "Configuration error" 500s. Added Country Subdivisions card to the lookups page. +- **V3 Search Refinement:** Updated general `qry_ae_obj_li__event` to use the standardized `q` property for full-text search and robust "Body + Header" context injection. +- **Git State Resolution:** Resolved a complex 12-commit rebase conflict involving `manifest.webmanifest` and `ae_events__event.ts`. Pushed a clean, branded, and stable state to the remote repository. +- **Crash Prevention:** Hardened meeting detail views with null-checks for `contact_li_json` to handle legacy/incomplete data. + +### Hardening & V3 Stabilization (2026-01-19) - **Structured Error Handling:** Updated `api_get`, `api_post`, and `api_patch` helpers to extract rich metadata (`meta.details`) from V3 API 400/500 responses. Standard FastAPI `detail` fields are automatically wrapped for consistency. - **JWT Race Condition Fix:** Implemented "Early Injection" in `+layout.ts`. The JWT is now read directly from `localStorage` during bootstrap, ensuring the first requests of a page load are correctly authenticated. - **Archives Stability:** Resolved a critical async race condition in `load_ae_obj_li__archive` and hardened `_process_generic_props` to handle non-array API responses. @@ -73,7 +78,7 @@ This project is the frontend UI/UX for the Aether (AE) system, built with Svelte ### Hardening & Svelte 5 Modernization (2026-01-16) - **Hardening:** Improved resilience for Journals and IDAA modules against API downtime and "ghost" account fallback. -- **Commit:** Atomic refactor of 15 files focusing on type safety, Svelte 5 runes, and API robustness. +- **Commit:** Atomic refactor of 15 files focusing for type safety, Svelte 5 runes, and API robustness. - **Fixes:** Resolved download progress crashes in `api_get_object_v1` and corrected event handling in several Svelte 5 components. - **Status:** Investigating Badge Rendering issues where `badge_template_obj` fails to load despite `badge_obj` being available. diff --git a/TODO.md b/TODO.md index 437184af..d766caca 100644 --- a/TODO.md +++ b/TODO.md @@ -4,11 +4,12 @@ This is a list of tasks to be completed before the next event/show/conference. --- -## Current Priorities (Jan 8, 2026) +## Current Priorities (Jan 20, 2026) -1. **Journals Module Audit:** Begin Phase 1 (Codebase Audit & Tailwind compliance). -2. **Core UI Polish:** Finalize Person and Address/Contact management forms using unified types. -3. **Svelte 5 / Runes Migration:** Continuous refactoring. +1. **Aether Native V3 (NEW):** Technical planning complete. Ready to scaffold the new Electron 33+ shell and implement the V3 "Zero-Config" bridge. +2. **Jitsi Module Updates:** Prepare for upcoming demo. Audit `video_conferences/+page.svelte` for UI/UX improvements and stability. +3. **Journals Module Audit:** Phase 1 complete. Focus on Phase 2: UI/UX Excellence. +4. **Core UI Polish:** Restored System Lookups view with Country Subdivisions. --- @@ -29,11 +30,12 @@ This is a list of tasks to be completed before the next event/show/conference. - [x] **Error Transparency**: Update backend to return specific SQLAlchemy/Pydantic errors in `meta.details`. (Completed 2026-01-19) - [ ] **Automated Source of Truth**: Generate `V3_OBJECT_MODELS.md` automatically in `agents_sync/Aether/`. - [x] **Fix V3 Search for IDAA Recovery Meetings** - - *Resolution:* Isolated IDAA module to a specialized legacy function `qry_ae_obj_li__event_v2` for stability. - - *V3 General Status:* Refined general `qry_ae_obj_li__event` to use 'Body + Header' injection, resolving the 'Integer Trap' for Main module. + - *Resolution:* Isolated IDAA module to a specialized legacy function `qry_ae_obj_li__event_v2` for stability. Restored 154-result capacity and fixed Inclusive OR location filters. (Completed 2026-01-20) + - *V3 General Status:* Refined general `qry_ae_obj_li__event` to use 'Body + Header' injection and 'q' property, resolving the 'Integer Trap'. - [ ] Run raw CURL trace to bypass browser CORS and see full backend traceback. - [ ] Perform SQL Audit on `v_event` view types (string vs integer mismatch). - - [ ] Test reverting to `account_id` mapping vs raw `account_id_random` body injection. +- [x] **Restore System Lookups** + - *Resolution:* Reverted `get_ae_obj_li_for_lu` to stable V2 endpoints (/v2/crud/lu/.../list) and added subdivision view. (Completed 2026-01-20) - [ ] **Phase 2: UI/UX Excellence** - [x] Implement "Quick Add" for high-velocity entry. - [x] Add rapid append/prepend functionality to existing entries. diff --git a/documentation/NATIVE_APP_AUTOMATION_SCRIPTS.md b/documentation/NATIVE_APP_AUTOMATION_SCRIPTS.md new file mode 100644 index 00000000..59df7c97 --- /dev/null +++ b/documentation/NATIVE_APP_AUTOMATION_SCRIPTS.md @@ -0,0 +1,130 @@ +# 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. \ No newline at end of file diff --git a/documentation/NATIVE_APP_DEPLOYMENT_PLAN.md b/documentation/NATIVE_APP_DEPLOYMENT_PLAN.md new file mode 100644 index 00000000..4cea536a --- /dev/null +++ b/documentation/NATIVE_APP_DEPLOYMENT_PLAN.md @@ -0,0 +1,52 @@ +# Deployment & Update Plan: Aether Native V3 + +**Mechanism:** Syncthing + Admin Share +**Target:** macOS Fleet +**Primary Controller:** `admin_share` directory + +## 1. Distribution via Syncthing +We will leverage the existing Syncthing mesh to distribute binaries and configurations. + +### 1.1 Directory Structure (Admin Share) +```text +admin_share/ +├── configs/ +│ └── seed_[DEVICE_ID].json # Specific seed files for auto-provisioning +├── binaries/ +│ └── native_app/ +│ ├── version.json # Latest version metadata +│ └── Aether_Native.app/ # The macOS App Bundle (or .zip) +└── scripts/ + └── update_helper.sh # macOS script to swap binaries +``` + +## 2. Self-Update Protocol +The V3 app will monitor for updates without relying on external internet access (perfect for isolated event networks). + +### 2.1 The Update Flow +1. **Check:** On launch (and periodically), the app reads `admin_share/binaries/native_app/version.json`. +2. **Compare:** If `version.json > package.json`, the app signals the user: "Update Available". +3. **Stage:** The app copies the new `.app` bundle from the sync folder to a local `~/Library/Caches/Aether/updates/` directory. +4. **Swap:** The app launches `update_helper.sh` and exits. The script moves the new version into `/Applications/` and restarts the app. + +## 3. Provisioning (The "Seed" Strategy) +To set up a new laptop: +1. Install Syncthing and link the `admin_share`. +2. The Electron app looks for `admin_share/configs/seed_$(hostname).json`. +3. If found, it copies it to its local config path and bootstraps itself. +4. **Result:** Zero manual configuration for the onsite tech. + +## 4. macOS Specific Lifecycle +- **Gatekeeper:** Since these are distributed via Syncthing, we must handle the "App is damaged or from an unidentified developer" prompt. +- **Plan:** Include a `post-sync` script that runs `xattr -rd com.apple.quarantine` on the binary folder within the admin share (if permissions allow) or instructs the user on the first run. + +## 5. Development Workflow (Arch Linux -> Mac) +1. **Build:** On Arch Linux, run `npm run build:mac`. +2. **Package:** Use `electron-packager` to create the macOS `.app` bundle. +3. **Distribute:** Move the built `.app` into the local Syncthing `admin_share` folder. +4. **Verify:** Watch the fleet of Macs automatically pull the update via Syncthing. + +## 6. Project Document Updates +The following files have been updated to reflect this deployment strategy: +- `NATIVE_APP_V3_REWRITE_PLAN.md`: Added self-update logic requirements. +- `NATIVE_BRIDGE_INTERFACE_SPEC.md`: Added `ae_sys.checkForUpdates()` method. diff --git a/documentation/NATIVE_APP_FUNCTIONAL_SPEC.md b/documentation/NATIVE_APP_FUNCTIONAL_SPEC.md new file mode 100644 index 00000000..f2a158e3 --- /dev/null +++ b/documentation/NATIVE_APP_FUNCTIONAL_SPEC.md @@ -0,0 +1,53 @@ +# Functional Specification: Aether Native App + +**Date:** 2026-01-20 +**Status:** Legacy Documentation for Rewrite +**Source Files:** `aether_app_native/index.js`, `aether_app_native_v4.js` + +## 1. Core Objectives +The Native App acts as a high-privilege bridge for the Aether SvelteKit UI, providing: +1. **Local File Orchestration:** Managing a local cache of presentation files. +2. **Process Management:** Opening and closing third-party applications (PowerPoint, Keynote). +3. **Hardware Integration:** Accessing device metadata and AV permissions. +4. **Persistent Identity:** Maintaining a fixed device ID independent of browser cookies. + +## 2. Detailed Function Mapping + +### 2.1 Configuration Layer +| Function | Process | Description | V3 Rewrite Notes | +| --- | --- | --- | --- | +| `load_init_config` | Renderer | Reads `ae_native_app_sk_config.json` from disk. | Standardize path to `~/.config/aether/`. | +| `get_url_cfg` | Renderer | Fetches remote config via API. | Switch from `/v2/crud/` to `/v3/crud/event_device/`. | +| `import_config` | IPC | Passes config to Main process. | Use `contextBridge` for secure transfer. | + +### 2.2 File & Cache System +| Function | Process | Description | V3 Rewrite Notes | +| --- | --- | --- | --- | +| `download_file` | IPC (Main) | Downloads via Axios stream to `.tmp` then renames. | Integrate JWT in download headers. | +| `check_hash_cache`| Renderer | Checks shard subdirectories (e.g. `/cache/af/...`). | Keep sharding logic for performance. | +| `open_hash_to_temp`| IPC (Main) | Maps `hash.file` -> `OriginalName.ext` in temp dir. | Ensure auto-cleanup of temp files on exit. | +| `open_local_file` | IPC (Main) | Wrapper for Electron `shell.openPath`. | Restrict to whitelisted directories. | + +### 2.3 System Control +| Function | Process | Description | V3 Rewrite Notes | +| --- | --- | --- | --- | +| `kill_processes` | IPC (Main) | Uses `killall` (Mac) or `pkill` (Linux). | Add specialized support for Svelte 5 process tracking. | +| `run_osascript` | IPC (Main) | Executes AppleScript (macOS only). | Add a "Mock Mode" for Linux development. | +| `run_cmd` | IPC (Main) | Executes arbitrary shell commands. | **SECURITY:** Change to a whitelist of allowed commands. | + +### 2.4 Device & Environment +| Function | Process | Description | V3 Rewrite Notes | +| --- | --- | --- | --- | +| `get_device_info` | IPC (Main) | Returns OS, Arch, and Network info. | Use for V3 device heartbeat registration. | +| `sys_perms` | Main | Requests Mac AV permissions. | Move to a dedicated bootstrap module. | + +## 3. The "Arch Linux vs macOS" Strategy +To ensure the app remains developable on Arch Linux while targeting macOS: +1. **Platform Detection:** Every system call must be gated by `process.platform`. +2. **Path Placeholders:** Continue using `[home]` and `[tmp]` strings in config files, resolving them at runtime. +3. **Mocking:** Create a `mock_native.js` that logs AppleScript/Terminal commands to the console instead of trying to execute them when `platform !== 'darwin'`. + +## 4. Security Requirements (Modernization) +1. **Context Isolation:** Enable `contextIsolation: true`. +2. **No Node Integration:** Disable `nodeIntegration` in the renderer. +3. **IPC Whitelisting:** Replace `run_cmd` with specific named handlers (e.g., `native:open-powerpoint`) to prevent RCE (Remote Code Execution) vulnerabilities. diff --git a/documentation/NATIVE_APP_V3_API_PAYLOAD.md b/documentation/NATIVE_APP_V3_API_PAYLOAD.md new file mode 100644 index 00000000..69ca8cc0 --- /dev/null +++ b/documentation/NATIVE_APP_V3_API_PAYLOAD.md @@ -0,0 +1,91 @@ +# Specification: Aether V3 API Device Config Payload + +**Endpoint:** `GET /v3/crud/event_device/{id_random}?view=native_bootstrap` +**Goal:** Provide full operational context to an Electron instance with zero local configuration. + +## 1. Response Structure (Draft) + +```json +{ + "status": "success", + "data": { + "identity": { + "device_id_random": "GZvFjgIIZQg", + "device_code": "macbook_air_scott_idem", + "account_id_random": "xFP7AhU8Zlc", + "event_id_random": "UFu-gF-rZ-ws", + "location_id_random": "PFGP-37-81-80" + }, + "network": { + "api_base_url": "https://api.oneskyit.com", + "file_server_url": "https://files.oneskyit.com", + "heartbeat_interval_ms": 30000 + }, + "filesystem": { + "cache_path": "[home]/Library/Caches/OSIT/file_cache", + "temp_path": "[home]/tmp/OSIT/temp", + "use_sharding": true, + "verify_on_launch": true + }, + "launcher": { + "app_mode": "native", + "auto_start_slideshow": true, + "prevent_sleep": true, + "whitelisted_apps": ["PowerPoint", "Keynote", "Acrobat Reader"] + }, + "ui_prefs": { + "theme_name": "cerberus", + "theme_mode": "dark", + "show_clock": true, + "show_admin_tools": false + } + } +} +``` + +## 2. Key Payload Fields + +### 2.1 Identity & Scoping +- `account_id_random`: Automatically scopes all subsequent V3 API calls for the SvelteKit UI. +- `location_id_random`: Locks the UI to a specific room/podium. + +### 2.2 Filesystem Strategy +- `cache_path`: Uses the `[home]` placeholder. The Electron Main process will resolve this to the local user profile. +- `use_sharding`: Tells the Sync Engine to use the `/ab/abcdef...` directory structure. + +### 2.3 Automation Whitelist +- To prevent security risks, the `launcher` object defines exactly which applications the native shell is allowed to "Kill" or "Open". + +## 3. Telemetry & Heartbeat (Push Strategy) +To support the onsite dashboard (`src/routes/events/.../device`), the Electron app must push its status back to the server. + +### 3.1 Heartbeat Payload (`PATCH /v3/crud/event_device/{id}`) +```json +{ + "heartbeat": "2026-01-20T14:30:00Z", + "status": "Online", + "status_msg": "Presentation: 'Introduction to AE.pptx' (Slide 4/20)", + "record_status": "Idle", + "info_ip_list": "192.168.1.10, 10.0.0.5", + "meta_json": { + "cpu_usage": 12, + "memory_free_gb": 4.2, + "sync_progress": 100, + "foreground_app": "PowerPoint", + "is_fullscreen": true + } +} +``` + +## 4. The "Bootstrap Paradox" Resolution +To allow unauthenticated config fetching for new devices: +1. **Device API Key:** Each device record in the DB has an `api_secret_key`. +2. **Initial Header:** The Electron app sends `x-aether-device-key: ` in the bootstrap request. +3. **JWT Hand-off:** The response `meta` will contain a short-lived JWT that the app uses to authenticate its first "Real" V3 requests. + +## 5. Database Mapping (V3 Enriched View) +The `v_event_device` SQL view must be updated to include: +- `account_id_random` (joined from `account`) +- `event_id_random` (joined from `event`) +- `location_id_random` (joined from `event_location`) +- `theme_name` (joined from `site_cfg_json` via `account`) diff --git a/documentation/NATIVE_APP_V3_REWRITE_PLAN.md b/documentation/NATIVE_APP_V3_REWRITE_PLAN.md new file mode 100644 index 00000000..ec8dc8ad --- /dev/null +++ b/documentation/NATIVE_APP_V3_REWRITE_PLAN.md @@ -0,0 +1,72 @@ +# Project Plan: Aether Native V3 Rewrite + +**Target:** Electron 33+ +**Primary Platform:** macOS (Production) +**Development Platform:** Arch Linux +**API Version:** Aether V3 (REST + JWT) + +## 1. Minimalist Configuration Strategy +To simplify laptop deployment, we will move away from large local JSON files. + +### 1.1 The "Seed" Config +Each laptop will contain a `seed.json` located in standard OS config paths (e.g., `~/.config/aether/seed.json` or `~/Library/Application Support/Aether/`). +```json +{ + "event_device_id": "AE-LPT-01", + "api_base_url": "https://api.oneskyit.com" +} +``` + +### 1.2 The Bootstrap Flow +1. **Launch:** Electron reads the `seed.json`. +2. **Identity:** App calls `GET /v3/crud/event_device/{id}?view=full_config`. +3. **Hydrate:** API returns the full operational config (Account context, Event settings, File cache paths). +4. **Auth:** App uses its device-specific API key to exchange for a session JWT. +5. **Inject:** Config and JWT are injected into the SvelteKit frontend via the Preload script. + +## 2. macOS Hardening (Permissions) +macOS requires explicit user consent for several features. The new app will handle these during the "Splash Screen" phase. + +- **AV Access:** Use `systemPreferences.askForMediaAccess('camera')` and `microphone`. +- **Accessibility:** For remote control/automation, check `systemPreferences.isTrustedAccessibilityClient(true)`. +- **Screen Recording:** Required for the presentation tracker. We will use a "Check and Prompt" loop. + +## 3. Cross-Platform Handling +| Feature | macOS (Production) | Linux/Windows (Dev/Comp) | +| --- | --- | --- | +| **Process Kill** | `killall -INT "PowerPoint"` | `pkill -f "powerpnt.exe"` | +| **Automation** | AppleScript (`osascript`) | Mocked via logs or Shell commands. | +| **Paths** | `~/Library/Caches/Aether` | `~/.cache/aether` | +| **Window** | Frameless, Transparent support. | Standard decorated window. | + +## 4. Proposed Directory Structure +```text +aether_app_native_v3/ +├── src/ +│ ├── main/ +│ │ ├── index.ts # Window lifecycle +│ │ ├── ipc_handlers.ts # Whitelisted OS commands +│ │ ├── macos_perms.ts # Mic/Cam/Accessibility logic +│ │ └── api_client.ts # V3 Auth & Config sync +│ ├── preload/ +│ │ └── index.ts # Secure ContextBridge +│ └── shared/ +│ └── types.ts # TS Interfaces for the bridge +├── resources/ # Icons and splash screens +└── electron-builder.yml # Multi-platform build config +``` + +## 5. Security Upgrades +1. **JWT Storage:** Store the session token in Electron's `safeStorage` (OS-level encryption) rather than simple `localStorage`. +2. **Navigation Lock:** Prevent the SvelteKit UI from navigating away from the Aether domain. +3. **Command Whitelisting:** Instead of a generic `run_cmd`, implement specific handlers like `native:launch-presentation` which only accepts a file hash. + +## 6. Deployment & Self-Update +To support onsite deployment via Syncthing: +1. **Version Watcher:** Main process monitors `admin_share/binaries/native_app/version.json`. +2. **Atomic Swap:** Use a dedicated `update_helper.sh` to swap the `.app` bundle while the app is closed. +3. **Zero-Touch Provisioning:** Auto-copy `seed_[hostname].json` from the sync share if local config is missing. + +## 7. Development Tools (Arch Linux) +- Use `fakeroot` and `binutils` to package for macOS on Linux. +- Use `Xvfb` for headless testing of Electron windows in CI/CD. diff --git a/documentation/NATIVE_BRIDGE_INTERFACE_SPEC.md b/documentation/NATIVE_BRIDGE_INTERFACE_SPEC.md new file mode 100644 index 00000000..19ab5a51 --- /dev/null +++ b/documentation/NATIVE_BRIDGE_INTERFACE_SPEC.md @@ -0,0 +1,74 @@ +# Specification: Aether Native V3 Bridge Interface + +**Namespace:** `window.native_app` +**Security:** Context Isolated, Sandboxed IPC + +## 1. Device & Identity (`ae_device`) +Functions for bootstrapping the app from the `seed.json`. + +| Method | Type | Description | +| --- | --- | --- | +| `getSeed()` | `() => Promise` | Returns the local `event_device_id` and `api_base_url`. | +| `getDeviceInfo()` | `() => Promise` | Returns OS, Arch, and unique hardware UUID. | +| `getPermissions()`| `() => Promise` | Returns status of Mic, Camera, and Accessibility. | +| `requestAccess()` | `(type: string) => Promise` | Triggers macOS TCC permission prompts. | + +## 2. Sync Engine (`ae_sync`) +The Sync Engine manages the "Cold Cache" (`~/Library/Caches/Aether/`). It handles atomic downloads and hash verification. + +| Method | Type | Description | +| --- | --- | --- | +| `getCacheStatus()` | `(file_hash: string) => Promise` | Checks if a file exists and is valid. | +| `startSync()` | `(task: SyncRequest) => Promise` | Begins background download of a presentation. | +| `cancelSync()` | `(file_hash: string) => Promise` | Aborts an active download. | +| `clearCache()` | `() => Promise` | Wipes the cold cache (Maintenance). | + +### Events (Main -> Renderer) +- `sync:progress`: `{ hash, percent, speed, bytesLoaded }` +- `sync:complete`: `{ hash, success, error }` + +## 3. Launcher (`ae_launcher`) +The "Big Red Button" logic. Handles the hand-off to the OS. + +| Method | Type | Description | +| --- | --- | --- | +| `launch()` | `(req: LaunchRequest) => Promise` | 1. Moves file to Temp. 2. Opens with default app. 3. Starts slideshow. | +| `killApp()` | `(appName: string) => Promise` | Closes PowerPoint/Keynote/Acrobat gracefully. | +| `preventSleep()` | `(enable: boolean) => Promise` | Prevents the laptop from sleeping during a session. | + +## 4. System Control (`ae_sys`) +Low-level macOS/Windows/Linux wrappers. + +| Method | Type | Description | +| --- | --- | --- | +| `setVolume()` | `(level: number) => Promise` | Sets system master volume (0-100). | +| `checkForUpdates()`| `() => Promise` | Checks the Syncthing share for a newer version. | +| `applyUpdate()` | `() => Promise` | Triggers the `update_helper.sh` and exits. | +| `execIntent()` | `(intent: string, args: any) => Promise` | Executes a whitelisted command (e.g. `open-logs-folder`). | + +--- + +## 5. TypeScript Interface (Draft) + +```typescript +export interface AE_Native_Bridge { + device: { + getSeed: () => Promise<{ device_id: string; api_url: string }>; + requestPermissions: () => Promise; + }; + sync: { + getStatus: (hash: string) => Promise<{ exists: boolean; verified: boolean }>; + queueDownload: (payload: { url: string; hash: string; jwt: string }) => void; + }; + launcher: { + launch: (file: { hash: string; name: string; type: 'pptx'|'key'|'pdf' }) => Promise; + killAll: () => Promise; + }; +} +``` + +## 6. Podium Reliability Protocol +To ensure the podium never fails: +1. **Pre-Flight Check:** The SvelteKit UI will call `sync.getStatus` for every file in the session as soon as the page loads. +2. **Auto-Warmup:** If a file is missing, the UI automatically calls `sync.queueDownload` in the background. +3. **Verification:** The `launcher.launch` command will perform a final `sha256` check on the temp file *before* executing `shell.openPath`. diff --git a/documentation/PROJECT_NATIVE_ELECTRON_INTEGRATION.md b/documentation/PROJECT_NATIVE_ELECTRON_INTEGRATION.md new file mode 100644 index 00000000..5c3d91c2 --- /dev/null +++ b/documentation/PROJECT_NATIVE_ELECTRON_INTEGRATION.md @@ -0,0 +1,62 @@ +# Project: Aether Native Electron Integration + +**Status:** Planning / Documentation +**Date:** 2026-01-20 +**Target Platform:** macOS (Production), Arch Linux (Development) + +## 1. Overview +This project aims to integrate the modern SvelteKit-based Aether UI into the established Electron native shell (`aether_app_native`). This enables "Native Mode" functionality, such as local file system access, presentation management, and hardware integration, which are restricted in standard web browsers. + +## 2. Component Mapping + +### 2.1 The Shell (`aether_app_native`) +- **Main Process:** Handles window creation, lifecycle, and IPC handlers. +- **Config:** Uses `ae_native_app_sk_config.json` located in `~/OSIT/native_app/` or `~/.config/OSIT/`. +- **Preload Script:** (To be standardized) The bridge that injects functionality into the UI. + +### 2.2 The UI (`aether_app_sveltekit`) +- **Framework:** Svelte 5 / SvelteKit. +- **Detection:** Uses `+layout.svelte` to check for `window.native_app`. +- **Relay:** `src/lib/electron/electron_relay.js` acts as the frontend-side API for the native bridge. + +## 3. Development Strategy (Arch Linux) +Since production targets macOS but development happens on Linux: +1. **Mocking macOS APIs:** Any calls to `osascript` or macOS-specific shell commands must be wrapped in a platform check. +2. **Path Handling:** Use `[home]` placeholders in config files to ensure paths resolve correctly on both `/home/scott/` (Linux) and `/Users/scott/` (Mac). +3. **Packaging:** Use `electron-packager` with macOS target flags to verify build integrity on Linux. + +## 4. Implementation Plan + +### Phase 1: Bridge Standardization +- Move existing logic from `aether_app_native/app/js/aether_app_native_v4.js` into a formal `preload.js`. +- Use `contextBridge.exposeInMainWorld` to provide a secure `native_app` object. +- Standardize return types (Promises) for all IPC calls. + +### Phase 2: SvelteKit Build Integration +- Transition SvelteKit build to support relative asset paths (required for `file://` protocol). +- Update the native app's `index.js` to load the built SvelteKit `index.html` instead of a remote URL. + +### Phase 3: Feature Parity (Events Module) +- Port the "Event Launcher" logic to the new bridge. +- Implement robust file caching using the `local_file_cache_path` from the native config. +- Ensure `kill_processes` works for both `pkill` (Linux) and `killall` (Mac). + +## 5. Security Protocols +- **Context Isolation:** Must remain enabled. +- **Sandbox:** Enabled where possible. +- **IPC Whitelisting:** Only specific, pre-defined commands can be executed via `run_cmd`. + +## 6. Project Documentation Index +The following documents provide detailed specifications for the V3 Native App rebuild: + +- **[NATIVE_APP_FUNCTIONAL_SPEC.md](NATIVE_APP_FUNCTIONAL_SPEC.md)**: Detailed audit of legacy features (process management, file caching, automation) to be preserved in the rewrite. +- **[NATIVE_APP_V3_REWRITE_PLAN.md](NATIVE_APP_V3_REWRITE_PLAN.md)**: Technical strategy for Electron 33+, including the Zero-Config hydration flow and macOS permission handling. +- **[NATIVE_APP_V3_API_PAYLOAD.md](NATIVE_APP_V3_API_PAYLOAD.md)**: JSON schema definitions for the V3 bootstrap payload and the push-telemetry heartbeat logic. +- **[NATIVE_BRIDGE_INTERFACE_SPEC.md](NATIVE_BRIDGE_INTERFACE_SPEC.md)**: Definition of the `window.native_app` IPC contract and the "Podium Reliability Protocol." +- **[NATIVE_APP_DEPLOYMENT_PLAN.md](NATIVE_APP_DEPLOYMENT_PLAN.md)**: Strategy for binary distribution and self-updates using the existing Syncthing `admin_share` infrastructure. +- **[NATIVE_APP_AUTOMATION_SCRIPTS.md](NATIVE_APP_AUTOMATION_SCRIPTS.md)**: Specifications for AppleScript intents, recording lifecycle (Aperture), and Arch Linux mocking logic. + +## 7. References +- Existing Native Docs: `aether_app_native/Aether App Native setup documentation.txt` +- Electron Integration: `src/lib/electron/README.md` +- Svelte 5 Runes: `documentation/ARCHITECTURE.md`