Skip to content

Foxl v0.2.23

Choose a tag to compare

@foxl-bot foxl-bot released this 05 May 01:41
· 12 commits to main since this release

Notifications: actions, deep-links, and a working Install Now

  • Action buttons on every notification type. Native macOS banners now carry "Open Agent / View / Reply / Dismiss" for agent done/failed, schedule done/failed, chat/channel message, and feed events. Previously only the update-ready toast had actions; everything else rendered as an unactionable banner that did nothing when clicked.
  • Notification body-click navigates to the event page AND deep-links to the specific resource. Clicking a "Schedule: daily-briefing" banner now opens /schedules#{scheduleId}, an "Agent Done" banner opens /agents/{sessionId}, a Slack channel message opens /chat/{conversationId}, and a feed alert opens /activities. Before, body-click only focused the window and dropped the user on the default page.
  • Action button clicks carry meta through the full stack. Server broadcast → WS → renderer → Electron main → back to renderer — the originating event's sessionId / conversationId / scheduleId is preserved end-to-end so deep-link navigation works for both the body click AND the action button.
  • Install Now on the update-ready toast actually installs. autoUpdater.quitAndInstall is now scheduled on the next tick (was racing with the notification dismiss on macOS, which is why the button looked like it did nothing), explicitly sets autoInstallOnAppQuit = true as a belt, and falls back to app.quit() if the native call throws.
  • Bell popover and native toast are consistent. The in-app bell popover shows the same action buttons as the OS toast, so the experience is uniform on Windows/Linux where native actions aren't available.
  • Server-side meta added to every emission site. subagent.ts now attaches {agentId, sessionId, conversationId} to completion notifications. server.ts schedule emissions carry {scheduleId, scheduleName}. Channel message emissions carry {conversationId, channel, channelId}. Single-agent start/goal endpoints carry {sessionId: 'default'}.

Notifications Settings cleanup

  • Settings test picker now goes through the real server broadcast path. The picker was using a CustomEvent shortcut that bypassed the WebSocket round-trip, which meant it could pass locally while production was broken. It now hits POST /api/test/notification which broadcasts over WS the same way production agents do, so clicking "Send test" exercises the exact same pipeline as a real event.
  • Settings test scenarios now mirror actual server emissions. Added channel_message_whatsapp and channel_message_web pickers (missing before). Dropped pet_expedition_return / pet_item_drop scenarios — no code ever emitted those types, so the pickers were dead UI. Also removed the matching pet toggles from the settings schema.
  • Test picker resolves deep-link IDs from the server. When you test an agent notification, the picker fetches your most recent agent session and uses its ID as meta.sessionId so the click actually lands on a concrete row instead of the bare list. Same for schedules and conversations.

Agents page

  • Active agents now render in the list. The header "N active" badge read in-memory team state, but the list below it only showed DB-persisted sessions — so chat-driven runs and not-yet-persisted agents appeared in the badge count but were missing from the list entirely. Live members are now merged as synthetic rows in a pinned "Active" group at the top, and running sessions bypass the Today / 7 Days / 30 Days time filter so a long-running agent stays visible even when the selected window excludes its start time.

Tests

  • notifications-e2e.spec.ts gained 17 new tests: meta propagation (5), Settings scenarios mirror server emissions (11, one per real type), subagent completion shape (1, skipped when no provider configured).
  • New notification-actions-ui-e2e.spec.ts covers the UI half: Settings picker hits the real endpoint, bell popover renders action buttons, each action's pushState observed via a history.pushState spy for race-free deep-link verification.