Commit Graph

2442 Commits

Author SHA1 Message Date
Scott Idem
182a066d38 fix(pres_mgmt): use tmp_sort_2 for presentation sort in Pres Mgmt and Launcher
Compute presentation-specific tmp_sort_1/tmp_sort_2 in specific_processor,
overriding the generic values from _process_generic_props which had two bugs:
- priority encoded as 0/1 ASC (backwards — true should sort first)
- sort stored as unpadded string ("10" < "2" lexicographically)
- start_datetime and code not included (presentation-specific fields)

New encoding: priority(inv)_sort(8-padded)_start_datetime_code[_name]
Both liveQueries (Pres Mgmt session page, Launcher session view) now use
.sortBy('tmp_sort_2') — cleaner and uses the indexed field.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 20:20:50 -04:00
Scott Idem
35fed53e2a fix(launcher): sort presentations by priority > sort > start_datetime > code > name
Replaced single-field sortBy() (poster→name, oral→start_datetime) with
toArray() + JS comparator matching the same sort chain as Pres Mgmt.
Removes the sort_by branch since the comparator handles both session types.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 20:11:14 -04:00
Scott Idem
322abc2691 fix(pres_mgmt): sort presentations by priority > sort > start_datetime > code > name
Replaced single-field sortBy('name') with toArray() + JS comparator to
implement the full desired sort chain. Dexie's sortBy() only supports a
single indexed field, so multi-field ordering requires a JS sort pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-28 13:38:13 -04:00
Scott Idem
cfaf687717 fix(events): event location file load on mount + launcher pruning scope fix + remove legacy launcher btn
- Location page now calls load_ae_obj_li__event_file on mount so files
  appear immediately without requiring a manual Refresh press.
- _load_event_location_sub_data (Launcher 60s sync) now uses hidden='all'
  with default limit (100) instead of hidden='not_hidden'/limit=25, which
  was pruning valid Dexie records when Pres Mgmt and Launcher were both
  open on the same location simultaneously.
- Removed the legacy launcher button (Send icon, /event/ path) from the
  Locations list; removed unused Send icon import.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 21:41:32 -04:00
Scott Idem
e7620a1c06 fix(events): replace db_events.file.clear() with targeted reload in refresh button
Same nuclear cache-clearing bug as the upload component fix. Clicking "Refresh
files" for one Location was wiping every event_file record from Dexie, leaving
all other Locations and Presenters with no files until their own background
syncs fired.

Now does a targeted load for the specific object only — same pattern as the
upload component commit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 21:07:00 -04:00
Scott Idem
e4e2174c97 fix(upload): replace db_events.file.clear() with targeted per-object reload
db_events.file.clear() after every upload was nuking the entire Dexie file
table. Every liveQuery watching any file list (Launcher, other locations,
sessions, presenters) would immediately show 0 results. Only the uploaded-to
object's files were reloaded; all others remained empty until their own
background syncs fired — intermittent disappearance that depended on timing.

Fix: targeted load_ae_obj_li__event_file for only the current link_to_id,
which uses the SWR pattern (returns cache + background refresh that includes
the newly created file). Other objects' file caches are untouched.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 20:33:12 -04:00
Scott Idem
d3bf314c62 fix(launcher): refresh file lists periodically to prune deleted/hidden files
The Launcher's background sync never called load_ae_obj_li__event_file for
presenter/session files. That function contains stale-record pruning that
removes deleted or hidden files from Dexie; without it, the Launcher's IDB
retained stale file records indefinitely until manually cleared.

Changes:
- refresh_presenter_data: add inc_file_li=true so presenter files are pruned
  every 120s via the existing presenter loop
- refresh_current_session_files(): new function that fetches/prunes session-
  level file lists for the selected session
- timer__file_list: 60s interval for refresh_current_session_files
- $effect on event_session_id: fires refresh_current_session_files immediately
  on session switch (no wait for next timer tick)

Propagation time: deleted/hidden files visible on remote Launchers within
~60s (session files) or ~120s (presenter files) automatically.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 20:12:10 -04:00
Scott Idem
d32355a1a2 docs(launcher): add cfg menu inventory and v3.1 design docs
MODULE__AE_Events_Launcher_Config_Menu.md — v3.0 inventory of the
3-tab drawer layout (now superseded but kept as reference baseline).
MODULE__AE_Events_Launcher_Config_Menu_new.md — v3.1 unified design
spec that drove the sidebar tab migration.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 22:17:07 -04:00
Scott Idem
213eabd8c1 feat(launcher): migrate cfg menu to 7-tab sidebar layout (v3.1)
Replaces the 3-tab horizontal bar (Setup / Device / Dev) with a vertical
sidebar navigation matching the v3.1 design spec. New tab structure:

  General       — App Modes, Screen Saver (operator-facing)
  Connectivity  — Remote Controller & WebSocket
  Sync & Health — Sync Timers, System Health
  Native OS     — OS controls (native or edit_mode preview)
  Wallpaper     — Desktop wallpaper settings
  Advanced      — Launch Timing, Updates (edit_mode only)
  Maintenance   — Local Resets, Debug Panel (edit_mode only)

Layout changes:
- Sidebar nav (w-48) + scrollable main content area replace inline tab bar
- Tab header shows label + description subtitle
- Technical Mode toggle is now a labeled button (not hidden icon)
- Footer shows Account/Device context; Reload moved to header
- {#key active_tab} wrapper ensures clean component remount on tab switch
- Remove unused icons (SlidersHorizontal, HeartPulse, Timer, CloudDownload)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 22:14:52 -04:00
Scott Idem
872291b0a0 fix(launcher): replace Flowbite Modal with custom overlay for cfg panel
Two problems with the Flowbite <Modal> approach:
1. Built-in dismissable CloseButton rendered with no functional dismiss path
   (no title/form), appearing centered in the panel.
2. size="xl" (max-w-7xl) left no backdrop area on typical laptop screens,
   making outsideclose impossible to trigger.

Replace with a simple custom overlay: full-screen backdrop div that closes
on click, inner panel with stopPropagation. Matches the original Drawer
pattern. close_cfg() writes to store immediately on backdrop click for
reliable persistence independent of effect timing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 22:04:34 -04:00
Scott Idem
25d17841e4 fix(launcher): fix cfg modal default-open and outside-click persistence
Two bugs in the Launcher Config Modal after the Drawer→Modal migration:
1. Pre-existing persisted configs (missing hide_drawer__cfg field) caused
   !undefined = true, opening the modal on every fresh load. Fixed by adding
   a field-level initialization guard after the full-object guard.
2. $-syntax writes inside untrack() were suppressed by svelte-persisted-store,
   so outside-click closure was never persisted. Fixed by using events_loc.update()
   directly to ensure the write reaches localStorage serialization. Added equality
   guard to effect 1 to prevent spurious modal flicker from whole-store re-fires.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 21:36:01 -04:00
Scott Idem
6282fb167f fix(launcher): use $derived.by for session liveQueries to fix stale presentation/presenter data
When switching sessions within the same location, presentations and presenters
were not updating. The root cause: plain $derived(liveQuery(...)) never recreates
the Observable when slct__event_session_id changes, because liveQuery's async
callback runs in Dexie's zone where Svelte tracking is off. Dexie's range-level
change detection then ignores new session data (it arrives under a different
event_session_id index value, outside the originally observed range).

Replaced all four liveQuery declarations with $derived.by(() => { const id = ...;
return liveQuery(...id...); }) — the same pattern already used in +layout.svelte
for location-dependent queries. Svelte tracks the id read in the outer closure
and recreates the Observable on every session change.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 19:55:17 -04:00
Scott Idem
a90572bcb8 fix(idaa): ensure breakout links preserve site access key and uuid
Proactively re-injects 'key' (site access key) and 'uuid' (Novi token)
into 'Open Externally' and 'Copy Link' URLs on the Video Conferences
page. This prevents authentication failures when members open meetings
in a new browser tab after SvelteKit internal navigation has dropped
the bootstrap parameters.

Updated CLIENT__IDAA_and_customized_mods.md to document the requirement
for these keys in breakout URLs.
2026-05-23 11:31:10 -04:00
Scott Idem
194c89f6d1 style(launcher): layout and Tailwind class adjustments
+layout.svelte: add lg:min-h-8/12 and max-h-screen to main content area.
launcher_background_sync.svelte: reposition sync monitor panel (bottom-15,
left-2, z-10 — was bottom-20, left-4, z-9999).
launcher_menu.svelte: reorder Tailwind classes for readability, no change
to applied styles.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 19:09:08 -04:00
Scott Idem
469729ce22 revert(help_tech): restore ae_loc preservation in Clear & Reload button
Reverts the change from d1f5d0e2f that removed ae_loc preservation.
The tech help component is used across non-Launcher contexts where
users are authenticated normally and should not be signed out.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 19:06:56 -04:00
Scott Idem
d1f5d0e2fd fix(launcher): clear ae_loc in cache cleanup; align tech help Clear & Reload
menu_launcher_controls: handle_cache_cleanup now removes both ae_events_loc
and ae_loc from localStorage, giving a true clean slate on reload.

e_app_help_tech: Clear & Reload button no longer silently re-saves ae_loc
after clearing — if edit mode wipes localStorage, ae_loc goes with it.
Updated confirm message and title tooltip to say "you will be signed out"
instead of the previous misleading "sign-in will be preserved."

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 19:05:16 -04:00
Scott Idem
9c83567430 feat(launcher): add Clear Cache and Reload Launcher buttons to controls bar
Fills in two new buttons added to menu_launcher_controls.svelte:
- Clear Cache: removes 'ae_events_loc' from localStorage and deletes the
  ae_events_db IndexedDB database, then reloads — clears stale launch state
  without touching downloaded file cache or user prefs (theme/font size).
- Reload Launcher: calls native.window_control({ action: 'reload' }) in
  Electron, falls back to window.location.reload() in browser mode.

Also fixes a stray 'lucide-svelte' import (merged Recycle into '@lucide/svelte')
and separates cache_status from reset_apps_status so button labels stay correct
when multiple actions fire.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 19:02:26 -04:00
Scott Idem
b4d0d82141 fix(launcher): fix VLC stopping 10-15 seconds after open on macOS
Root cause: run_cmd uses exec() which blocks until the child exits. The
direct VLC binary forks its GUI process and exits — exec returns and the
post_script begins. The old post_script polled for VLC focus (up to 10s)
then sent Cmd+F, which fired mid-playback and stopped the video.

Fix 1 — nohup + &: detaches VLC from exec immediately so run_cmd returns
in ~0ms. This decouples the launcher flow from VLC's lifecycle.

Fix 2 — --fullscreen flag: VLC opens fullscreen directly via CLI option.
Eliminates the Cmd+F keystroke that was the proximate cause of the stop.

Fix 3 — > /dev/null 2>&1: silences VLC's verbose logging to prevent
exec's 1MB stdout buffer from overflowing and killing the process.

post_script simplified to a single `tell application "VLC" activate`
to bring VLC to the foreground after the 3s startup delay.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 18:10:37 -04:00
Scott Idem
15bfe6d5d6 feat(launcher): move Reset Apps to always-visible controls bar
Adds a presenter-accessible "Reset Apps" button to menu_launcher_controls
that is always visible (no edit mode required). Kills presentation apps
(PowerPoint, Keynote, Acrobat, VLC, soffice) — critical recovery path for
presenters stuck on stage with a frozen app.

Also: warning colors on All Files / All Sessions when showing non-default
(hidden) content, and state-aware tooltips on the Display Mode toggle that
describe current state and what pressing will do.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 18:02:22 -04:00
Scott Idem
dddf4b6170 feat(launcher): restore Kill Apps button in Native OS config
Kills the standard conference presentation app set between sessions:
Microsoft PowerPoint, Keynote, Adobe Acrobat Reader DC, VLC, soffice.

- Calls native.kill_processes({ process_name_li }) via existing relay
- Process list overridable per device via event_device.other_json.launcher.kill_process_li
- Button lives in Native OS config > System Actions (edit mode only)
- Reuses system_status for feedback — shows which apps are being killed
- Original list recovered from git history of legacy architecture docs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 16:43:42 -04:00
Scott Idem
587b815446 docs(todo): mark composable flow + slide scripts done; add event_file cfg_json backend task
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 15:58:38 -04:00
Scott Idem
ca51a82dae feat(launcher): richer tooltip on file download button
Tooltip now shows file size, created/updated timestamps, and open_in_os
setting alongside the existing SHA256 and hosted ID info.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 15:58:35 -04:00
Scott Idem
a38320c7f5 fix(launcher): monospace font for session list date/time column
Datetime values align cleanly across rows when rendered in font-mono.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 15:58:31 -04:00
Scott Idem
c76fb8f2b5 fix(launcher): open_in_os win routing, display override, and onsite ext fix
- open_in_os='win' now routes to Windows launch profiles (pptxwin/pptwin/odpwin/pdfwin)
  via WIN_EXTENSION_MAP in get_launch_profile() — was silently ignored before
- Display override migrated from non-existent cfg_json backend field to localStorage
  ($events_loc.launcher.file_display_overrides) — only visible in edit mode; TODO added
  for proper backend column when event_file gains cfg_json
- Onsite mode WIN extension rename now covers all 4 types (pptx, ppt, odp, pdf)
  instead of only pptx/ppt
- open_in_os button shows LoaderCircle spinner during API call
- Remove cfg_json from properties_to_save (column does not exist on event_file table)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 15:58:27 -04:00
Scott Idem
a26ea8b49c fix(launcher): optimistic update for display override button
Without this, the button depended on the liveQuery round-trip to show
the new state — invisible on stale IDB caches that predate the cfg_json
properties_to_save fix. Now mutates event_file_obj locally on click so
the button reflects the new state immediately, with the background
refresh as confirmation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 14:18:58 -04:00
Scott Idem
21fad1a698 fix(launcher): restore open_in_os win routing, fix cfg_json in IDB, fix display state
open_in_os = 'win': get_launch_profile() now maps pptx→pptxwin, ppt→pptwin,
odp→odpwin, pdf→pdfwin when open_in_os is 'win', routing to the Windows-variant
launch profiles (Parallels/CrossOver). Was never wired in native mode — feature
was silently lost in the MasterKey→Launcher port.

cfg_json missing from properties_to_save: the per-file display override was
always read as undefined from Dexie because cfg_json was never saved. Added
cfg_json to properties_to_save so display_override and any other cfg fields
persist correctly. NOTE: IDB_CONTENT_VERSIONS for event_file is not yet wired;
existing devices need a manual cache clear to pick up the new field.

Display override button: removed $ae_loc.is_native gate — must be configurable
from any device ahead of the event, not only on the podium Mac.

Display toggle persistence: quick_display_mode now reads from and writes to
$events_loc.launcher.display_mode so the last-set state survives page reloads
instead of always defaulting to 'extend'.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 14:12:12 -04:00
Scott Idem
33e9eeef78 fix(launcher): retry activate in post-script loop to beat macOS focus-stealing
All app post-scripts called activate once before the poll loop, then only
checked `frontmost` passively. When Electron retains focus (common when the
app is spawned via run_cmd), macOS focus-stealing prevention blocks the one-
shot activate and VLC/PowerPoint/etc. never come to front. The poll loop
times out and fires the keystroke at Electron instead.

Fix: move activate inside the repeat loop so it re-fires every 0.5s until
macOS yields focus. Also bumped VLC post_delay_ms 1000→2000 and iterations
15→20 for slow conference machines.

Affected profiles: VLC (mac), PowerPoint (mac), LibreOffice (mac+win),
Acrobat (mac+win).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 13:51:53 -04:00
Scott Idem
172ea994c7 refactor(launcher): consolidate menu controls and anchor to bottom
- Combine Extend/Mirror into a single toggle button, moved behind edit_mode
- All edit-mode controls (All Files, All Sessions, Display) now share consistent preset-tonal-tertiary styling
- Remove the always-visible display row and its non-native-mode disclaimer
- Wrap Menu_launcher_controls in mt-auto to keep it pinned to the bottom of the sidebar regardless of session count
- Add min-w-20 to file size chip to prevent collapse on narrow sessions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 13:48:53 -04:00
Scott Idem
17b549a75c docs/refactor: finalize V3 cleanup and archive badge config project
- Moved PROJECT__AE_Events_Badges_Config_Cleanup.md to archive.
- Updated PROJECT__Use_AE_API_V3_CRUD_upgrade.md with latest audit and migration status.
- Migrated ae_comp__event_presenter_form_agree.svelte to modern V3 update_ae_obj helper.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 23:04:07 -04:00
Scott Idem
3de01af1a1 docs: cleanup and archive agent TODO list
Archived completed May 2026 tasks and streamlined the active list to
focus on upcoming events and the final V3 API surgical cleanup.

- Created TODO__Agents__ARCHIVE_2026-05.md with completed items.
- Streamlined TODO__Agents.md for active show support (CMSC, Axonius).
- Added V3 CRUD migration tracking for core site and utility helpers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 23:02:25 -04:00
Scott Idem
518a450b91 docs(events): reorganize badges and leads documentation
Standardized documentation structure for Badges and Leads modules into
focused technical references and practical onsite guides.

- Refined MODULE__AE_Events_Badges.md (Core data integrity & sync logic)
- Renamed MODULE__AE_Events_Exhibitor_Leads.md to MODULE__AE_Events_Leads.md
- Renamed MODULE__AE_Events_Badges_Onsite.md to GUIDE__AE_Events_Badges_Onsite.md
- Expanded GUIDE__AE_Events_Onsite_Runbook.md with Badge and Leads sections.
- Maintained all critical business logic, including the 'Override Fields' pattern.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 22:40:06 -04:00
Scott Idem
cb767ed115 docs(events): reorganize presentation and launcher documentation
Split the monolithic MODULE__AE_Events_PressMgmt_Launcher.md into focused,
granular modules to improve maintainability and onsite utility.

- Created MODULE__AE_Events_Presentation_Management.md (Back-office focus)
- Created MODULE__AE_Events_Launcher.md (Podium display focus)
- Created GUIDE__AE_Events_Onsite_Runbook.md (SRR and onsite workflows)
- Promoted PROJECT__AE_Events_Launcher_Native_integration.md to
  MODULE__AE_Events_Launcher_Native.md (Permanent technical reference)
- Renamed 'Press Mgmt' references to 'Presentation Management' for clarity.
- Removed redundant README.md in launcher route.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 22:36:00 -04:00
Scott Idem
86201f0fc1 feat(launcher): implement force-sync and chronological download priority
Onsite operators can now manually trigger a full pre-sync of all location
materials via a "Force Sync Location" button in the Launcher config.
This ensures podium Macs have all content cached before an event starts.

- Added trigger__force_location_sync to launcher session store.
- Implemented force_location_sync() in background sync engine to perform
  recursive metadata fetches for all sessions in a location.
- Optimized download queue with a 4-tier chronological sort:
  1. Event/Location assets (Global)
  2. Sessions by start time (Earliest first)
  3. Presentations by start time (Sequential order)
  4. File creation date (First-in fairness for on-time uploads)
- Updated module and native integration documentation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 22:29:13 -04:00
Scott Idem
60e3fc539e docs(devops): add Nginx caching investigation task for app version pickup issue
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 18:31:51 -04:00
Scott Idem
b3029a4d27 docs: update TODO and add BOOTSTRAP mistake #13 for API retry regression
TODO__Agents.md:
- Added the two additional fixes from the review pass to the PATCH/DELETE
  retry hardening entry: default timeout 60s→20s, and DELETE missing
  ae_auth_error banner on 401/403.

BOOTSTRAP__AI_Agent_Quickstart.md:
- Added mistake #13: breaking the API retry loop by returning errors from
  the TypeError/AbortError block instead of throwing them. Documents the
  Jan 2026 regression (commit a10accfaa), the three retry classes that must
  be preserved, and a quick verification method.
- Filled the gap at item #7 (was missing, causing off-by-one numbering
  from item 8 onward). Items renumbered 8-14 → 7-13.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 18:21:01 -04:00
Scott Idem
ea765d8ad2 fix(api): lower patch/delete timeout to 20s and add delete auth error banner
Two gaps found during review of the recent retry-hardening commits:

1. api_patch_object.ts and api_delete_object.ts still defaulted to 60s
   timeout while GET/POST were lowered to 20s. No callers set an explicit
   timeout, so the default was the only value used. With retry_count=5 and
   the new backoff policy, 60s per attempt = 5+ minutes worst-case wait.
   Lowered to 20s to match GET/POST and keep worst-case under ~2 minutes.

2. api_delete_object.ts had no ae_auth_error import and no session-expired
   banner on 401/403. A stale-session DELETE would silently return false
   with no user feedback. Added browser + ae_auth_error imports and the
   ae_auth_error.set() call matching the pattern in GET/POST/PATCH.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 18:11:32 -04:00
Scott Idem
db5acdd30a docs: align API retry hardening status with implemented helpers 2026-05-21 18:04:06 -04:00
Scott Idem
a000e07647 api: harden delete retry classification and backoff 2026-05-21 17:58:59 -04:00
Scott Idem
7f9368589a api: harden patch retry classification and backoff 2026-05-21 17:53:30 -04:00
Scott Idem
55d3d49595 test: add v3 latency probe and modernize api coverage 2026-05-21 17:48:00 -04:00
Scott Idem
f5cf1ef398 api: separate timeout abort retries from intentional aborts 2026-05-21 15:46:30 -04:00
Scott Idem
d5d552a029 Badge layout fix for Axonius 2026-05-21 15:19:48 -04:00
Scott Idem
689bb326cb fix(api): restore network-error retry and add backoff in get/post_object
The Jan 2026 "offline-first fast-paths" commit (a10accfaa) inadvertently
broke retries for transient network failures (ERR_NETWORK_CHANGED, WiFi
roam events, etc.). The original code's .catch() returned undefined, which
fell through to the `if (!response) throw` path and correctly entered the
retry loop. After a10accfaa, .catch() returned the error as a value, and
the subsequent `instanceof Error` check returned false immediately —
bypassing all retries for the most common failure mode in
hotel/conference environments.

Changes:
- TypeError now throws into the retry loop instead of returning false
- AbortError still returns false immediately (intentional cancel, no retry)
- Per-attempt AbortController: moved inside the loop in both files so each
  retry gets its own independent timeout (previously GET retries had no
  timeout at all after the first attempt's clearTimeout ran)
- clearTimeout() added to catch block so timer is always cancelled on error
- Exponential backoff added: 2s→4s→6s→8s (capped) between attempts;
  rapid retries on a flaky network accomplish nothing without a delay
- Default timeout lowered: 90s → 20s (generous for search/GET but avoids
  the 90s worst-case hang that amplified ERR_NETWORK_CHANGED exposure)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 13:44:12 -04:00
Scott Idem
e6db2b4d6a fix(idaa): add Clear Cache & Reload escape hatch to recovery meetings server error state
"Try Again" resets auto_retry_count but reuses the same localStorage state — if
ae_loc or ae_idaa_loc holds a stale account_id or api_secret_key, every retry
fails identically and the user is stuck in an infinite error loop.

New button clears ae_loc + ae_idaa_loc from localStorage and db_events.event
from IDB, then reloads via the sessionStorage-preserved UUID URL (same logic as
the IDAA layout's Clear Cache & Reload). Forces a fresh FQDN handshake and
re-derives correct auth state. Guidance text shown so users know to try it when
Try Again keeps failing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 12:30:53 -04:00
Scott Idem
cfc5d237c7 docs(todo): add launcher wallpaper drift hotplug follow-up
Track projector/display unplug-replug wallpaper reset behavior and evaluate loop/check/event-driven strategies.
2026-05-20 19:30:37 -04:00
Scott Idem
a56f520d4e feat(launcher): add quick mirror/extend toggle in left menu
Always visible in launcher menu, disabled outside native mode, with title text and preview-note messaging.
2026-05-20 19:28:46 -04:00
Scott Idem
c0f828ec2c feat: Add platform-specific VLC launch profiles (macOS working; Linux deferred)
- macOS: Uses direct binary path (/Applications/VLC.app/Contents/MacOS/VLC)
  with --no-play-and-exit --play-and-pause flags and AppleScript fullscreen toggle.
  Confirmed working: pause on last frame, stays in window.

- Linux: Uses shell command (vlc --no-play-and-exit --play-and-pause).
  Known issue: not going fullscreen, not pausing on end. Deferred for later
  investigation of flag interpretation vs launcher execution layer.

- Created separate profile constants: VLC_MIRROR_MAC_PROFILE and
  VLC_MIRROR_LINUX_PROFILE in ae_launcher__default_launch_profiles.ts

- Updated TODO__Agents.md with Linux VLC issue for future debugging

Files: ae_launcher__default_launch_profiles.ts, documentation/TODO__Agents.md
2026-05-20 19:09:15 -04:00
Scott Idem
5bb06c4904 feat(display): expose list_display_modes and set_display_mode in relay
Svelte callers can now enumerate all display modes and set resolution/
refresh/HiDPI per display through the native bridge.
2026-05-20 18:16:43 -04:00
Scott Idem
7621e044b4 docs(launcher): update display layout doc — display_control replaces displayplacer as primary
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 16:48:25 -04:00
Scott Idem
76569a872f feat(launcher): add display mode toggle; fix silent display layout failures
- Add Extend/Mirror toggle to Native OS config section (always visible,
  no Technical Mode required). Default: Extend. State updates on success.
- Replace .catch(() => {}) swallowing with console.warn logging on both
  set_display_layout call sites so failures appear in the Electron console
- Remove old edit-mode-only Extend button (replaced by new toggle)
- Update PROJECT doc: displayplacer install note, binary lookup order, GitHub link
- Clean up TODO__Agents.md: resolve stale items, add new low-priority Electron items

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 16:33:33 -04:00