Saving the new documentation for the Launcher project plans. Finally moving this to a new version of Electron and pretty much starting from scratch.
This commit is contained in:
15
.ae_brief
Normal file
15
.ae_brief
Normal file
@@ -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*
|
||||
11
GEMINI.md
11
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.
|
||||
|
||||
|
||||
16
TODO.md
16
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.
|
||||
|
||||
130
documentation/NATIVE_APP_AUTOMATION_SCRIPTS.md
Normal file
130
documentation/NATIVE_APP_AUTOMATION_SCRIPTS.md
Normal file
@@ -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.
|
||||
52
documentation/NATIVE_APP_DEPLOYMENT_PLAN.md
Normal file
52
documentation/NATIVE_APP_DEPLOYMENT_PLAN.md
Normal file
@@ -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.
|
||||
53
documentation/NATIVE_APP_FUNCTIONAL_SPEC.md
Normal file
53
documentation/NATIVE_APP_FUNCTIONAL_SPEC.md
Normal file
@@ -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.
|
||||
91
documentation/NATIVE_APP_V3_API_PAYLOAD.md
Normal file
91
documentation/NATIVE_APP_V3_API_PAYLOAD.md
Normal file
@@ -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: <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`)
|
||||
72
documentation/NATIVE_APP_V3_REWRITE_PLAN.md
Normal file
72
documentation/NATIVE_APP_V3_REWRITE_PLAN.md
Normal file
@@ -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.
|
||||
74
documentation/NATIVE_BRIDGE_INTERFACE_SPEC.md
Normal file
74
documentation/NATIVE_BRIDGE_INTERFACE_SPEC.md
Normal file
@@ -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<SeedConfig>` | Returns the local `event_device_id` and `api_base_url`. |
|
||||
| `getDeviceInfo()` | `() => Promise<DeviceInfo>` | Returns OS, Arch, and unique hardware UUID. |
|
||||
| `getPermissions()`| `() => Promise<PermStatus>` | Returns status of Mic, Camera, and Accessibility. |
|
||||
| `requestAccess()` | `(type: string) => Promise<boolean>` | 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<CacheInfo>` | Checks if a file exists and is valid. |
|
||||
| `startSync()` | `(task: SyncRequest) => Promise<void>` | Begins background download of a presentation. |
|
||||
| `cancelSync()` | `(file_hash: string) => Promise<void>` | Aborts an active download. |
|
||||
| `clearCache()` | `() => Promise<void>` | 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<void>` | 1. Moves file to Temp. 2. Opens with default app. 3. Starts slideshow. |
|
||||
| `killApp()` | `(appName: string) => Promise<void>` | Closes PowerPoint/Keynote/Acrobat gracefully. |
|
||||
| `preventSleep()` | `(enable: boolean) => Promise<void>` | 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<void>` | Sets system master volume (0-100). |
|
||||
| `checkForUpdates()`| `() => Promise<UpdateStatus>` | Checks the Syncthing share for a newer version. |
|
||||
| `applyUpdate()` | `() => Promise<void>` | Triggers the `update_helper.sh` and exits. |
|
||||
| `execIntent()` | `(intent: string, args: any) => Promise<any>` | 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<void>;
|
||||
};
|
||||
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<boolean>;
|
||||
killAll: () => Promise<void>;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## 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`.
|
||||
62
documentation/PROJECT_NATIVE_ELECTRON_INTEGRATION.md
Normal file
62
documentation/PROJECT_NATIVE_ELECTRON_INTEGRATION.md
Normal file
@@ -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`
|
||||
Reference in New Issue
Block a user