From e37fd1ddbbcafce7c24de62bb602ae416cf08485 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Wed, 20 May 2026 15:39:27 -0400 Subject: [PATCH] docs: sync README and list_tools() to current handler reality MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit README: correct set_display_layout (auto-detection default, configStr optional); update set_wallpaper signature ({path?,url?,url_external?,display?,api_key?, account_id?}); remove stale note on launch_presentation -e flag (hardened 2026-05-11). list_tools(): expand from 13 entries to 22 — adds copy_from_cache_to_temp, set_wallpaper, set_display_layout, window_control, power_control, manage_recording, update_app, open_external, get_device_config; updates launch_from_cache params (adds native_template); adds category comments; improves all descriptions to reflect current behavior. Co-Authored-By: Claude Sonnet 4.6 --- README.md | 6 +-- src/main/shell_handlers.ts | 98 ++++++++++++++++++++++++++++---------- 2 files changed, 77 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 34d12dc..7a8fab8 100644 --- a/README.md +++ b/README.md @@ -284,7 +284,7 @@ to change. | Method | Description | | --- | --- | -| `launch_presentation({path, app?, os?})` | Platform-aware launcher. Resolves `[home]`/`[tmp]` placeholders. **Note:** uses legacy `-e` flag for AppleScript; prefer `copy_from_cache_to_temp` + `run_osascript` for new flows. | +| `launch_presentation({path, app?, os?})` | Platform-aware launcher. Resolves `[home]`/`[tmp]` placeholders. Hardened (2026-05-11): AppleScript written to temp `.scpt` file, same as `run_osascript`. For new flows prefer `copy_from_cache_to_temp` + `run_osascript` for full control. | | `control_presentation({app, action})` | Slide navigation (`next`/`prev`/`start`/`stop`) for PowerPoint or Keynote via AppleScript. macOS only. | ### System Management (Phase 5) @@ -294,9 +294,9 @@ to change. | `get_device_config()` | Returns hydrated device config injected at startup from `seed.json` + API. | | `get_device_info()` | Returns OS metadata: platform, hostname, IPs, CPU count, free RAM, home/tmp paths. | | `window_control({action, value?})` | Electron window: maximize, minimize, restore, close, fullscreen, kiosk, devtools, reload. | -| `set_wallpaper({path})` | Sets desktop wallpaper. macOS (AppleScript) + Linux (gsettings/Gnome). | +| `set_wallpaper({path?, url?, url_external?, display?, api_key?, account_id?})` | Sets desktop wallpaper. Accepts a local `path` or downloads from `url` (cached to `~/Library/Caches/OSIT/wallpaper/`). `url_external` sets a separate image on the projector/second display. `display`: `'all'` (default) \| `'primary'` \| `'external'`. macOS only in production; Linux returns a dev-mode preview payload without applying. | | `power_control({action})` | Shutdown, reboot, or sleep. macOS + Linux. Requires sudo for shutdown/reboot. | -| `set_display_layout({mode, configStr?})` | Mirror/extend displays via bundled `displayplacer` binary. macOS only. `configStr` is the output of `displayplacer list` for that machine, stored in `event_device.data_json.displayplacer_config_mirror` / `displayplacer_config_extend`. Required — silently no-ops without it. | +| `set_display_layout({mode, configStr?})` | Mirror/extend displays via bundled `displayplacer` binary. macOS only. Auto-detects connected displays via `displayplacer list` when no `configStr` is given — no manual config needed. `configStr` is an optional manual override (the full `displayplacer` config string) stored in `event_device.data_json` if per-device tuning is needed. | | `manage_recording({action, options?})` | Screen recording via bundled `aperture` binary. macOS only. | | `update_app(args)` | **Stub.** Downloads update package but does not install. Not functional. | | `list_tools()` | Returns a self-describing manifest of all available bridge functions. | diff --git a/src/main/shell_handlers.ts b/src/main/shell_handlers.ts index 1dbeadb..eed355d 100644 --- a/src/main/shell_handlers.ts +++ b/src/main/shell_handlers.ts @@ -171,65 +171,115 @@ end tell ipcMain.handle('native:list-tools', async () => { return [ + // --- Config & Info --- + { + name: 'get_device_config', + description: 'Returns hydrated device config injected at startup from seed.json + API.', + params: {} + }, + { + name: 'get_device_info', + description: 'Returns OS metadata: platform, hostname, IPs, CPU count, free RAM, home/tmp paths.', + params: {} + }, + // --- File Cache --- + { + name: 'check_cache', + description: 'Checks if a file exists in the hashed cache. verify_hash:true re-hashes to confirm integrity.', + params: { cache_root: 'string', hash: 'string', hash_prefix_length: 'number (optional, default 2)', verify_hash: 'boolean (optional)' } + }, + { + name: 'download_to_cache', + description: 'Streams a file from the API into the hashed cache with SHA-256 integrity check. Cleans stale .tmp files older than 5 min.', + params: { url: 'string', cache_root: 'string', hash: 'string', api_key: 'string', account_id: 'string', hash_prefix_length: 'number (optional, default 2)' } + }, + { + name: 'copy_from_cache_to_temp', + description: 'Preferred primitive. Copies a cached file to temp with its original filename. Returns { success, path }. Caller decides what to do next.', + params: { cache_root: 'string', hash: 'string', temp_root: 'string', filename: 'string', hash_prefix_length: 'number (optional, default 2)' } + }, + { + name: 'launch_from_cache', + description: 'Combines copy_from_cache_to_temp + execute. Runs native_template after copying — AppleScript string with {{path}} placeholder, or "shell:" prefix. Returns error if native_template is null.', + params: { cache_root: 'string', hash: 'string', temp_root: 'string', filename: 'string', hash_prefix_length: 'number (optional)', native_template: 'string | null' } + }, + // --- Shell & OS --- { name: 'open_folder', - description: 'Opens a directory in the OS file explorer (Finder/Files/Explorer).', + description: 'Opens a directory in the OS file explorer (Finder on macOS).', params: { path: 'string' } }, { name: 'run_cmd', - description: 'Executes an asynchronous shell command with a timeout.', - params: { cmd: 'string', timeout: 'number (optional)' } + description: 'Async shell command execution with timeout.', + params: { cmd: 'string', timeout: 'number (optional, default 30000ms)' } }, { name: 'run_cmd_sync', - description: 'Executes a synchronous shell command.', + description: 'Synchronous shell command execution.', params: { cmd: 'string' } }, { name: 'run_osascript', - description: 'Executes a raw AppleScript string (macOS only).', + description: 'Hardened AppleScript executor — writes to temp .scpt file, handles multi-line scripts and paths with special characters. macOS only.', params: { script: 'string' } }, { name: 'kill_processes', - description: 'Forcefully terminates processes by name.', + description: 'Terminates processes by name. macOS/Linux: pkill -f. Windows: taskkill /F.', params: { process_name_li: 'string[]' } }, { name: 'open_local_file_v2', - description: 'Opens a local file using the default OS handler.', - params: { filePath: 'string' } + description: 'Opens a file with its default OS application via shell.openPath.', + params: { path: 'string' } }, + { + name: 'open_external', + description: 'Opens a URL in Chrome, Firefox, or the system default browser.', + params: { url: 'string', app: 'chrome | firefox | default (optional)' } + }, + // --- Presentations --- { name: 'launch_presentation', - description: 'Phase 5: Specialized launcher for PowerPoint, Keynote, and LibreOffice with auto-focus.', - params: { path: 'string', app: 'default|powerpoint|keynote' } + description: 'Platform-aware launcher for PowerPoint, Keynote, LibreOffice. Resolves [home]/[tmp] placeholders. Hardened AppleScript (2026-05-11). Prefer copy_from_cache_to_temp + run_osascript for new flows.', + params: { path: 'string', app: 'default | powerpoint | keynote (optional)', os_platform: 'string (optional)' } }, { name: 'control_presentation', - description: 'Phase 5: Remote navigation for active slideshows.', - params: { app: 'powerpoint|keynote', action: 'next|prev|start|stop' } + description: 'Slide navigation for active PowerPoint or Keynote via AppleScript. macOS only.', + params: { app: 'powerpoint | keynote', action: 'next | prev | start | stop' } + }, + // --- System Management --- + { + name: 'set_wallpaper', + description: 'Sets desktop wallpaper. Downloads from url (cached to ~/Library/Caches/OSIT/wallpaper/) or applies local path. url_external targets projector/second display separately. macOS only in production.', + params: { path: 'string (optional)', url: 'string (optional)', url_external: 'string (optional)', display: 'all | primary | external (optional, default all)', api_key: 'string (optional)', account_id: 'string (optional)' } }, { - name: 'check_cache', - description: 'Checks if a file exists in the local organized cache.', - params: { cache_root: 'string', hash: 'string', hash_prefix_length: 'number' } + name: 'set_display_layout', + description: 'Mirror or extend displays via bundled displayplacer. macOS only. Auto-detects displays when no configStr given; configStr is an optional manual override.', + params: { mode: 'mirror | extend', configStr: 'string (optional)' } }, { - name: 'download_to_cache', - description: 'Downloads a file from the API directly into the native cache.', - params: { url: 'string', cache_root: 'string', hash: 'string', api_key: 'string', account_id: 'string' } + name: 'window_control', + description: 'Electron window management.', + params: { action: 'maximize | unmaximize | minimize | restore | close | fullscreen | kiosk | devtools | reload', value: 'boolean (optional, used by fullscreen/kiosk/devtools)' } }, { - name: 'launch_from_cache', - description: 'Atomic operation: Copies file from cache to temp with original name and launches via specialized handler.', - params: { cache_root: 'string', hash: 'string', temp_root: 'string', filename: 'string' } + name: 'power_control', + description: 'Shutdown, reboot, or sleep the host machine. macOS + Linux. May require sudo for shutdown/reboot.', + params: { action: 'shutdown | reboot | sleep' } }, { - name: 'get_device_info', - description: 'Returns hardware and OS metadata (CPUs, RAM, IP addresses, Hostname).', - params: {} + name: 'manage_recording', + description: 'Screen recording via bundled aperture binary. macOS only.', + params: { action: 'start | stop | status', options: '{ fps?, audioDeviceId?, output? } (optional)' } + }, + { + name: 'update_app', + description: 'STUB: Downloads update package but does not install. Not functional.', + params: { source: 'url | file', url: 'string (optional)', path: 'string (optional)' } } ]; });