@elizaos/ui 2.0.0-alpha.385 → 2.0.0-alpha.392
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/app-companion/src/components/companion/CompanionAppView.d.ts.map +1 -1
- package/apps/app-companion/src/components/companion/CompanionAppView.js +6 -4
- package/apps/app-companion/src/components/companion/CompanionView.d.ts.map +1 -1
- package/apps/app-companion/src/components/companion/CompanionView.js +6 -4
- package/apps/app-lifeops/src/api/client-lifeops.js +6 -0
- package/apps/app-lifeops/src/components/AppBlockerSettingsCard.d.ts +3 -0
- package/apps/app-lifeops/src/components/AppBlockerSettingsCard.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/AppBlockerSettingsCard.js +189 -0
- package/apps/app-lifeops/src/components/BrowserBridgeSetupPanel.d.ts +2 -0
- package/apps/app-lifeops/src/components/BrowserBridgeSetupPanel.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/BrowserBridgeSetupPanel.js +1065 -0
- package/apps/app-lifeops/src/components/BrowserBridgeStatusChip.d.ts +7 -0
- package/apps/app-lifeops/src/components/BrowserBridgeStatusChip.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/BrowserBridgeStatusChip.js +71 -0
- package/apps/app-lifeops/src/components/DataSourcesStrip.d.ts +14 -0
- package/apps/app-lifeops/src/components/DataSourcesStrip.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/DataSourcesStrip.js +36 -0
- package/apps/app-lifeops/src/components/EventEditorDrawer.d.ts +23 -0
- package/apps/app-lifeops/src/components/EventEditorDrawer.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/EventEditorDrawer.js +514 -0
- package/apps/app-lifeops/src/components/LifeOpsActivitySignalsEffect.d.ts +2 -0
- package/apps/app-lifeops/src/components/LifeOpsActivitySignalsEffect.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/LifeOpsActivitySignalsEffect.js +10 -0
- package/apps/app-lifeops/src/components/LifeOpsCalendarSection.d.ts +15 -0
- package/apps/app-lifeops/src/components/LifeOpsCalendarSection.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/LifeOpsCalendarSection.js +515 -0
- package/apps/app-lifeops/src/components/LifeOpsChatAdapter.d.ts +34 -0
- package/apps/app-lifeops/src/components/LifeOpsChatAdapter.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/LifeOpsChatAdapter.js +175 -0
- package/apps/app-lifeops/src/components/LifeOpsFeatureTogglesSection.d.ts +2 -0
- package/apps/app-lifeops/src/components/LifeOpsFeatureTogglesSection.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/LifeOpsFeatureTogglesSection.js +99 -0
- package/apps/app-lifeops/src/components/LifeOpsHabitVisuals.d.ts +37 -0
- package/apps/app-lifeops/src/components/LifeOpsHabitVisuals.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/LifeOpsHabitVisuals.js +88 -0
- package/apps/app-lifeops/src/components/LifeOpsInboxSection.d.ts +13 -0
- package/apps/app-lifeops/src/components/LifeOpsInboxSection.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/LifeOpsInboxSection.js +490 -0
- package/apps/app-lifeops/src/components/LifeOpsLinkBankButton.d.ts +12 -0
- package/apps/app-lifeops/src/components/LifeOpsLinkBankButton.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/LifeOpsLinkBankButton.js +92 -0
- package/apps/app-lifeops/src/components/LifeOpsLinkPaypalButton.d.ts +12 -0
- package/apps/app-lifeops/src/components/LifeOpsLinkPaypalButton.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/LifeOpsLinkPaypalButton.js +160 -0
- package/apps/app-lifeops/src/components/LifeOpsMoneySection.d.ts +3 -0
- package/apps/app-lifeops/src/components/LifeOpsMoneySection.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/LifeOpsMoneySection.js +373 -0
- package/apps/app-lifeops/src/components/LifeOpsNavRail.d.ts +9 -0
- package/apps/app-lifeops/src/components/LifeOpsNavRail.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/LifeOpsNavRail.js +93 -0
- package/apps/app-lifeops/src/components/LifeOpsOperationalPanels.d.ts +4 -0
- package/apps/app-lifeops/src/components/LifeOpsOperationalPanels.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/LifeOpsOperationalPanels.js +274 -0
- package/apps/app-lifeops/src/components/LifeOpsOverviewSection.d.ts +7 -0
- package/apps/app-lifeops/src/components/LifeOpsOverviewSection.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/LifeOpsOverviewSection.js +657 -0
- package/apps/app-lifeops/src/components/LifeOpsPageSections.d.ts +42 -0
- package/apps/app-lifeops/src/components/LifeOpsPageSections.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/LifeOpsPageSections.js +166 -0
- package/apps/app-lifeops/src/components/LifeOpsPageView.d.ts +2 -0
- package/apps/app-lifeops/src/components/LifeOpsPageView.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/LifeOpsPageView.js +566 -0
- package/apps/app-lifeops/src/components/LifeOpsRemindersSection.d.ts +2 -0
- package/apps/app-lifeops/src/components/LifeOpsRemindersSection.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/LifeOpsRemindersSection.js +749 -0
- package/apps/app-lifeops/src/components/LifeOpsResizableSidebar.d.ts +27 -0
- package/apps/app-lifeops/src/components/LifeOpsResizableSidebar.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/LifeOpsResizableSidebar.js +106 -0
- package/apps/app-lifeops/src/components/LifeOpsScreenTimeSection.d.ts +2 -0
- package/apps/app-lifeops/src/components/LifeOpsScreenTimeSection.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/LifeOpsScreenTimeSection.js +373 -0
- package/apps/app-lifeops/src/components/LifeOpsSectionContent.d.ts +10 -0
- package/apps/app-lifeops/src/components/LifeOpsSectionContent.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/LifeOpsSectionContent.js +30 -0
- package/apps/app-lifeops/src/components/LifeOpsSelectionContext.d.ts +21 -0
- package/apps/app-lifeops/src/components/LifeOpsSelectionContext.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/LifeOpsSelectionContext.js +30 -0
- package/apps/app-lifeops/src/components/LifeOpsSettingsSection.d.ts +20 -0
- package/apps/app-lifeops/src/components/LifeOpsSettingsSection.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/LifeOpsSettingsSection.js +597 -0
- package/apps/app-lifeops/src/components/LifeOpsSetupGate.d.ts +13 -0
- package/apps/app-lifeops/src/components/LifeOpsSetupGate.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/LifeOpsSetupGate.js +134 -0
- package/apps/app-lifeops/src/components/LifeOpsSleepSection.d.ts +10 -0
- package/apps/app-lifeops/src/components/LifeOpsSleepSection.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/LifeOpsSleepSection.js +425 -0
- package/apps/app-lifeops/src/components/LifeOpsWorkspaceShell.d.ts +11 -0
- package/apps/app-lifeops/src/components/LifeOpsWorkspaceShell.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/LifeOpsWorkspaceShell.js +49 -0
- package/apps/app-lifeops/src/components/LifeOpsWorkspaceView.d.ts +2 -0
- package/apps/app-lifeops/src/components/LifeOpsWorkspaceView.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/LifeOpsWorkspaceView.js +1041 -0
- package/apps/app-lifeops/src/components/MessagingConnectorCards.d.ts +7 -0
- package/apps/app-lifeops/src/components/MessagingConnectorCards.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/MessagingConnectorCards.js +643 -0
- package/apps/app-lifeops/src/components/MissingSourceCard.d.ts +9 -0
- package/apps/app-lifeops/src/components/MissingSourceCard.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/MissingSourceCard.js +5 -0
- package/apps/app-lifeops/src/components/MobileSignalsSetupCard.d.ts +2 -0
- package/apps/app-lifeops/src/components/MobileSignalsSetupCard.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/MobileSignalsSetupCard.js +163 -0
- package/apps/app-lifeops/src/components/SleepInspectionPanel.d.ts +8 -0
- package/apps/app-lifeops/src/components/SleepInspectionPanel.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/SleepInspectionPanel.js +59 -0
- package/apps/app-lifeops/src/components/WebsiteBlockerSettingsCard.d.ts +3 -0
- package/apps/app-lifeops/src/components/WebsiteBlockerSettingsCard.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/WebsiteBlockerSettingsCard.js +75 -0
- package/apps/app-lifeops/src/components/WhatsAppQrOverlay.d.ts +8 -0
- package/apps/app-lifeops/src/components/WhatsAppQrOverlay.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/WhatsAppQrOverlay.js +48 -0
- package/apps/app-lifeops/src/components/lifeops-labels.d.ts +2 -0
- package/apps/app-lifeops/src/components/lifeops-labels.d.ts.map +1 -0
- package/apps/app-lifeops/src/components/lifeops-labels.js +5 -0
- package/apps/app-lifeops/src/events/index.d.ts +34 -0
- package/apps/app-lifeops/src/events/index.d.ts.map +1 -0
- package/apps/app-lifeops/src/events/index.js +23 -0
- package/apps/app-lifeops/src/hooks/useCalendarWeek.d.ts +28 -0
- package/apps/app-lifeops/src/hooks/useCalendarWeek.d.ts.map +1 -0
- package/apps/app-lifeops/src/hooks/useCalendarWeek.js +93 -0
- package/apps/app-lifeops/src/hooks/useDiscordConnector.d.ts +14 -0
- package/apps/app-lifeops/src/hooks/useDiscordConnector.d.ts.map +1 -0
- package/apps/app-lifeops/src/hooks/useDiscordConnector.js +126 -0
- package/apps/app-lifeops/src/hooks/useGoogleLifeOpsConnector.d.ts +29 -0
- package/apps/app-lifeops/src/hooks/useGoogleLifeOpsConnector.d.ts.map +1 -0
- package/apps/app-lifeops/src/hooks/useGoogleLifeOpsConnector.js +481 -0
- package/apps/app-lifeops/src/hooks/useIMessageConnector.d.ts +10 -0
- package/apps/app-lifeops/src/hooks/useIMessageConnector.d.ts.map +1 -0
- package/apps/app-lifeops/src/hooks/useIMessageConnector.js +50 -0
- package/apps/app-lifeops/src/hooks/useInbox.d.ts +34 -0
- package/apps/app-lifeops/src/hooks/useInbox.d.ts.map +1 -0
- package/apps/app-lifeops/src/hooks/useInbox.js +98 -0
- package/apps/app-lifeops/src/hooks/useLifeOpsActivitySignals.d.ts +2 -0
- package/apps/app-lifeops/src/hooks/useLifeOpsActivitySignals.d.ts.map +1 -0
- package/apps/app-lifeops/src/hooks/useLifeOpsActivitySignals.js +383 -0
- package/apps/app-lifeops/src/hooks/useLifeOpsAppState.d.ts +9 -0
- package/apps/app-lifeops/src/hooks/useLifeOpsAppState.d.ts.map +1 -0
- package/apps/app-lifeops/src/hooks/useLifeOpsAppState.js +83 -0
- package/apps/app-lifeops/src/hooks/useLifeOpsCapabilitiesStatus.d.ts +8 -0
- package/apps/app-lifeops/src/hooks/useLifeOpsCapabilitiesStatus.d.ts.map +1 -0
- package/apps/app-lifeops/src/hooks/useLifeOpsCapabilitiesStatus.js +60 -0
- package/apps/app-lifeops/src/hooks/useLifeOpsScheduleInspection.d.ts +18 -0
- package/apps/app-lifeops/src/hooks/useLifeOpsScheduleInspection.d.ts.map +1 -0
- package/apps/app-lifeops/src/hooks/useLifeOpsScheduleInspection.js +66 -0
- package/apps/app-lifeops/src/hooks/useLifeOpsScheduleState.d.ts +14 -0
- package/apps/app-lifeops/src/hooks/useLifeOpsScheduleState.d.ts.map +1 -0
- package/apps/app-lifeops/src/hooks/useLifeOpsScheduleState.js +79 -0
- package/apps/app-lifeops/src/hooks/useLifeOpsSection.d.ts +18 -0
- package/apps/app-lifeops/src/hooks/useLifeOpsSection.d.ts.map +1 -0
- package/apps/app-lifeops/src/hooks/useLifeOpsSection.js +78 -0
- package/apps/app-lifeops/src/hooks/useLifeOpsXConnector.d.ts +14 -0
- package/apps/app-lifeops/src/hooks/useLifeOpsXConnector.d.ts.map +1 -0
- package/apps/app-lifeops/src/hooks/useLifeOpsXConnector.js +160 -0
- package/apps/app-lifeops/src/hooks/useSignalConnector.d.ts +16 -0
- package/apps/app-lifeops/src/hooks/useSignalConnector.d.ts.map +1 -0
- package/apps/app-lifeops/src/hooks/useSignalConnector.js +198 -0
- package/apps/app-lifeops/src/hooks/useTelegramConnector.d.ts +21 -0
- package/apps/app-lifeops/src/hooks/useTelegramConnector.d.ts.map +1 -0
- package/apps/app-lifeops/src/hooks/useTelegramConnector.js +177 -0
- package/apps/app-lifeops/src/hooks/useWhatsAppConnector.d.ts +8 -0
- package/apps/app-lifeops/src/hooks/useWhatsAppConnector.d.ts.map +1 -0
- package/apps/app-lifeops/src/hooks/useWhatsAppConnector.js +58 -0
- package/apps/app-lifeops/src/hooks/useWhatsAppPairing.d.ts +12 -0
- package/apps/app-lifeops/src/hooks/useWhatsAppPairing.d.ts.map +1 -0
- package/apps/app-lifeops/src/hooks/useWhatsAppPairing.js +152 -0
- package/apps/app-lifeops/src/lifeops/discord-browser-scraper.js +1 -1
- package/apps/app-lifeops/src/lifeops/google-gmail.d.ts.map +1 -1
- package/apps/app-lifeops/src/lifeops/google-gmail.js +74 -26
- package/apps/app-lifeops/src/lifeops/google-managed-client.d.ts.map +1 -1
- package/apps/app-lifeops/src/lifeops/google-managed-client.js +4 -5
- package/apps/app-lifeops/src/lifeops/google-oauth.d.ts.map +1 -1
- package/apps/app-lifeops/src/lifeops/google-oauth.js +2 -2
- package/apps/app-lifeops/src/lifeops/owner-profile.d.ts.map +1 -1
- package/apps/app-lifeops/src/lifeops/owner-profile.js +1 -1
- package/apps/app-lifeops/src/lifeops/paypal-managed-client.d.ts.map +1 -1
- package/apps/app-lifeops/src/lifeops/paypal-managed-client.js +4 -5
- package/apps/app-lifeops/src/lifeops/plaid-managed-client.d.ts.map +1 -1
- package/apps/app-lifeops/src/lifeops/plaid-managed-client.js +4 -5
- package/apps/app-lifeops/src/lifeops/schedule-sync-client.js +2 -2
- package/apps/app-lifeops/src/lifeops/service-constants.d.ts +1 -0
- package/apps/app-lifeops/src/lifeops/service-constants.d.ts.map +1 -1
- package/apps/app-lifeops/src/lifeops/service-constants.js +1 -0
- package/apps/app-lifeops/src/lifeops/service-mixin-core.d.ts +1 -1
- package/apps/app-lifeops/src/lifeops/service-mixin-core.d.ts.map +1 -1
- package/apps/app-lifeops/src/lifeops/service-mixin-core.js +2 -1
- package/apps/app-lifeops/src/lifeops/service-mixin-imessage.js +1 -1
- package/apps/app-lifeops/src/lifeops/service-mixin-inbox.d.ts +3 -1
- package/apps/app-lifeops/src/lifeops/service-mixin-inbox.d.ts.map +1 -1
- package/apps/app-lifeops/src/lifeops/service-mixin-inbox.js +42 -13
- package/apps/app-lifeops/src/lifeops/service-mixin-reminders.d.ts.map +1 -1
- package/apps/app-lifeops/src/lifeops/service-mixin-reminders.js +3 -2
- package/apps/app-lifeops/src/lifeops/service-mixin-workflows.d.ts.map +1 -1
- package/apps/app-lifeops/src/lifeops/service-mixin-workflows.js +1 -1
- package/apps/app-lifeops/src/lifeops/service-normalize-calendar.d.ts.map +1 -1
- package/apps/app-lifeops/src/lifeops/service-normalize-calendar.js +3 -3
- package/apps/app-lifeops/src/lifeops/service-normalize-connector.d.ts +1 -1
- package/apps/app-lifeops/src/lifeops/service-normalize-connector.d.ts.map +1 -1
- package/apps/app-lifeops/src/lifeops/service-normalize-connector.js +2 -2
- package/apps/app-lifeops/src/lifeops/signal-auth.d.ts.map +1 -1
- package/apps/app-lifeops/src/lifeops/signal-auth.js +6 -3
- package/apps/app-lifeops/src/lifeops/telegram-auth.js +1 -1
- package/apps/app-lifeops/src/lifeops/travel-adapters/duffel.d.ts.map +1 -1
- package/apps/app-lifeops/src/lifeops/travel-adapters/duffel.js +31 -6
- package/apps/app-lifeops/src/lifeops/twilio.js +1 -1
- package/apps/app-lifeops/src/lifeops/x-poster.d.ts.map +1 -1
- package/apps/app-lifeops/src/lifeops/x-poster.js +13 -3
- package/apps/app-lifeops/src/lifeops-route.d.ts +74 -0
- package/apps/app-lifeops/src/lifeops-route.d.ts.map +1 -0
- package/apps/app-lifeops/src/lifeops-route.js +204 -0
- package/apps/app-lifeops/src/platform/lifeops-github.d.ts +15 -0
- package/apps/app-lifeops/src/platform/lifeops-github.d.ts.map +1 -0
- package/apps/app-lifeops/src/platform/lifeops-github.js +135 -0
- package/apps/app-lifeops/src/routes/cloud-features-routes.d.ts +2 -2
- package/apps/app-lifeops/src/routes/cloud-features-routes.d.ts.map +1 -1
- package/apps/app-lifeops/src/routes/cloud-features-routes.js +5 -3
- package/apps/app-lifeops/src/routes/lifeops-routes.d.ts.map +1 -1
- package/apps/app-lifeops/src/routes/lifeops-routes.js +15 -3
- package/apps/app-lifeops/src/routes/plugin.d.ts.map +1 -1
- package/apps/app-lifeops/src/routes/plugin.js +10 -1
- package/apps/app-lifeops/src/routes/travel-provider-relay-routes.d.ts +1 -1
- package/apps/app-lifeops/src/routes/travel-provider-relay-routes.d.ts.map +1 -1
- package/apps/app-lifeops/src/routes/travel-provider-relay-routes.js +4 -2
- package/apps/app-lifeops/src/routes/website-blocker-routes.d.ts +1 -1
- package/apps/app-lifeops/src/routes/website-blocker-routes.d.ts.map +1 -1
- package/apps/app-lifeops/src/ui.d.ts +11 -0
- package/apps/app-lifeops/src/ui.d.ts.map +1 -0
- package/apps/app-lifeops/src/ui.js +9 -0
- package/apps/app-lifeops/src/utils/lifeops-url.d.ts +5 -0
- package/apps/app-lifeops/src/utils/lifeops-url.d.ts.map +1 -0
- package/apps/app-lifeops/src/utils/lifeops-url.js +35 -0
- package/apps/app-lifeops/src/website-blocker/access.d.ts.map +1 -1
- package/apps/app-lifeops/src/website-blocker/access.js +1 -1
- package/apps/app-steward/src/routes/steward-compat-routes.d.ts +1 -1
- package/apps/app-steward/src/routes/steward-compat-routes.d.ts.map +1 -1
- package/apps/app-steward/src/routes/steward-compat-routes.js +3 -1
- package/apps/app-steward/src/routes/wallet-browser-compat-routes.d.ts +1 -1
- package/apps/app-steward/src/routes/wallet-browser-compat-routes.d.ts.map +1 -1
- package/apps/app-steward/src/routes/wallet-browser-compat-routes.js +3 -1
- package/apps/app-steward/src/routes/wallet-bsc-core-routes.d.ts.map +1 -1
- package/apps/app-steward/src/routes/wallet-bsc-core-routes.js +2 -1
- package/apps/app-steward/src/routes/wallet-compat-routes.d.ts +1 -1
- package/apps/app-steward/src/routes/wallet-compat-routes.d.ts.map +1 -1
- package/apps/app-steward/src/routes/wallet-compat-routes.js +3 -1
- package/apps/app-steward/src/routes/wallet-core-routes.d.ts.map +1 -1
- package/apps/app-steward/src/routes/wallet-core-routes.js +2 -1
- package/apps/app-steward/src/routes/wallet-trade-compat-routes.d.ts +1 -1
- package/apps/app-steward/src/routes/wallet-trade-compat-routes.d.ts.map +1 -1
- package/apps/app-steward/src/routes/wallet-trade-compat-routes.js +3 -1
- package/apps/app-training/src/core/dataset-generator.d.ts +1 -1
- package/apps/app-training/src/core/dataset-generator.d.ts.map +1 -1
- package/apps/app-training/src/core/roleplay-executor.d.ts +1 -1
- package/apps/app-training/src/core/roleplay-executor.d.ts.map +1 -1
- package/apps/app-training/src/core/trajectory-task-datasets.d.ts +1 -1
- package/apps/app-training/src/core/trajectory-task-datasets.d.ts.map +1 -1
- package/apps/app-training/src/index.d.ts +1 -2
- package/apps/app-training/src/index.d.ts.map +1 -1
- package/apps/app-training/src/index.js +1 -2
- package/apps/app-training/src/routes/training-routes.d.ts +1 -1
- package/apps/app-training/src/routes/training-routes.d.ts.map +1 -1
- package/apps/app-training/src/routes/training-routes.js +1 -1
- package/apps/app-training/src/routes/trajectory-routes.d.ts +1 -1
- package/apps/app-training/src/routes/trajectory-routes.d.ts.map +1 -1
- package/apps/app-training/src/routes/trajectory-routes.js +3 -1
- package/apps/app-training/src/services/training-service-like.d.ts +1 -1
- package/apps/app-training/src/services/training-service-like.d.ts.map +1 -1
- package/apps/app-training/src/services/training-service.d.ts +1 -1
- package/apps/app-training/src/services/training-service.d.ts.map +1 -1
- package/package.json +1 -1
- package/packages/agent/src/api/provider-switch-config.js +1 -1
- package/packages/agent/src/api/server-helpers-auth.d.ts.map +1 -1
- package/packages/agent/src/api/server-helpers-auth.js +5 -4
- package/packages/agent/src/providers/media-provider.d.ts +1 -1
- package/packages/agent/src/providers/media-provider.d.ts.map +1 -1
- package/packages/app-core/src/App.d.ts.map +1 -1
- package/packages/app-core/src/App.js +20 -12
- package/packages/app-core/src/api/auth.d.ts.map +1 -1
- package/packages/app-core/src/api/auth.js +5 -5
- package/packages/app-core/src/api/client-types-experience.d.ts +7 -0
- package/packages/app-core/src/api/client-types-experience.d.ts.map +1 -1
- package/packages/app-core/src/components/apps/helpers.d.ts +1 -1
- package/packages/app-core/src/components/apps/helpers.d.ts.map +1 -1
- package/packages/app-core/src/components/apps/helpers.js +1 -0
- package/packages/app-core/src/components/apps/internal-tool-apps.d.ts +11 -0
- package/packages/app-core/src/components/apps/internal-tool-apps.d.ts.map +1 -1
- package/packages/app-core/src/components/apps/internal-tool-apps.js +31 -0
- package/packages/app-core/src/components/apps/launch-history.d.ts +16 -0
- package/packages/app-core/src/components/apps/launch-history.d.ts.map +1 -0
- package/packages/app-core/src/components/apps/launch-history.js +77 -0
- package/packages/app-core/src/components/apps/per-app-config.d.ts +19 -0
- package/packages/app-core/src/components/apps/per-app-config.d.ts.map +1 -0
- package/packages/app-core/src/components/apps/per-app-config.js +99 -0
- package/packages/app-core/src/components/apps/useRegistryCatalog.d.ts +14 -0
- package/packages/app-core/src/components/apps/useRegistryCatalog.d.ts.map +1 -0
- package/packages/app-core/src/components/apps/useRegistryCatalog.js +52 -0
- package/packages/app-core/src/components/auth/LoginView.d.ts +1 -19
- package/packages/app-core/src/components/auth/LoginView.d.ts.map +1 -1
- package/packages/app-core/src/components/auth/LoginView.js +4 -99
- package/packages/app-core/src/components/character/CharacterExperienceWorkspace.d.ts.map +1 -1
- package/packages/app-core/src/components/character/CharacterExperienceWorkspace.js +14 -2
- package/packages/app-core/src/components/character/character-hub-helpers.d.ts.map +1 -1
- package/packages/app-core/src/components/character/character-hub-helpers.js +7 -0
- package/packages/app-core/src/components/character/character-hub-types.d.ts +7 -0
- package/packages/app-core/src/components/character/character-hub-types.d.ts.map +1 -1
- package/packages/app-core/src/components/onboarding/BootstrapStep.d.ts.map +1 -1
- package/packages/app-core/src/components/onboarding/BootstrapStep.js +3 -2
- package/packages/app-core/src/components/pages/AppDetailsView.d.ts +36 -0
- package/packages/app-core/src/components/pages/AppDetailsView.d.ts.map +1 -0
- package/packages/app-core/src/components/pages/AppDetailsView.js +289 -0
- package/packages/app-core/src/components/pages/AppsView.d.ts.map +1 -1
- package/packages/app-core/src/components/pages/AppsView.js +134 -42
- package/packages/app-core/src/components/shell/StartupShell.d.ts.map +1 -1
- package/packages/app-core/src/components/shell/StartupShell.js +2 -5
- package/packages/app-core/src/i18n/locales/en.json +256 -205
- package/packages/app-core/src/i18n/locales/es.json +256 -205
- package/packages/app-core/src/i18n/locales/ko.json +256 -205
- package/packages/app-core/src/i18n/locales/pt.json +256 -205
- package/packages/app-core/src/i18n/locales/tl.json +256 -205
- package/packages/app-core/src/i18n/locales/vi.json +256 -205
- package/packages/app-core/src/i18n/locales/zh-CN.json +256 -205
- package/packages/app-core/src/navigation/index.d.ts.map +1 -1
- package/packages/app-core/src/navigation/index.js +6 -0
- package/packages/app-core/src/shell/AppWindowRenderer.d.ts +17 -0
- package/packages/app-core/src/shell/AppWindowRenderer.d.ts.map +1 -0
- package/packages/app-core/src/shell/AppWindowRenderer.js +337 -0
- package/packages/app-core/src/shell/DetachedShellRoot.js +4 -1
- package/packages/app-core/src/shell/index.d.ts +1 -0
- package/packages/app-core/src/shell/index.d.ts.map +1 -1
- package/packages/app-core/src/shell/index.js +1 -0
- package/packages/app-core/src/state/startup-coordinator.d.ts.map +1 -1
- package/packages/app-core/src/state/startup-coordinator.js +0 -3
- package/packages/app-core/src/state/startup-phase-poll.d.ts.map +1 -1
- package/packages/app-core/src/state/startup-phase-poll.js +2 -4
- package/packages/app-core/src/state/usePluginsSkillsState.d.ts +6 -6
- package/packages/native-plugins/mobile-signals/src/definitions.d.ts +162 -0
- package/packages/native-plugins/mobile-signals/src/definitions.d.ts.map +1 -0
- package/packages/native-plugins/mobile-signals/src/definitions.js +1 -0
- package/packages/native-plugins/mobile-signals/src/index.d.ts +4 -0
- package/packages/native-plugins/mobile-signals/src/index.d.ts.map +1 -0
- package/packages/native-plugins/mobile-signals/src/index.js +6 -0
- package/packages/native-plugins/mobile-signals/src/web.d.ts +29 -0
- package/packages/native-plugins/mobile-signals/src/web.d.ts.map +1 -0
- package/packages/native-plugins/mobile-signals/src/web.js +269 -0
- package/packages/shared/src/app-hero-art.d.ts.map +1 -1
- package/packages/shared/src/app-hero-art.js +13 -0
- package/packages/shared/src/contracts/lifeops.d.ts +10 -0
- package/packages/shared/src/contracts/lifeops.d.ts.map +1 -1
- package/packages/shared/src/contracts/lifeops.js +5 -0
- package/packages/typescript/src/features/advanced-capabilities/experience/actions/record-experience.d.ts.map +1 -1
- package/packages/typescript/src/features/advanced-capabilities/experience/actions/record-experience.js +46 -4
- package/packages/typescript/src/features/advanced-capabilities/experience/evaluators/experienceEvaluator.d.ts.map +1 -1
- package/packages/typescript/src/features/advanced-capabilities/experience/evaluators/experienceEvaluator.js +34 -124
- package/packages/typescript/src/features/advanced-capabilities/experience/service.d.ts.map +1 -1
- package/packages/typescript/src/features/advanced-capabilities/experience/service.js +56 -0
- package/packages/typescript/src/features/advanced-capabilities/experience/types.d.ts +7 -0
- package/packages/typescript/src/features/advanced-capabilities/experience/types.d.ts.map +1 -1
- package/packages/typescript/src/features/advanced-capabilities/experience/utils/experienceText.d.ts +7 -0
- package/packages/typescript/src/features/advanced-capabilities/experience/utils/experienceText.d.ts.map +1 -0
- package/packages/typescript/src/features/advanced-capabilities/experience/utils/experienceText.js +123 -0
- package/apps/app-training/src/ui/FineTuningView.d.ts +0 -5
- package/apps/app-training/src/ui/FineTuningView.d.ts.map +0 -1
- package/apps/app-training/src/ui/FineTuningView.js +0 -388
- package/apps/app-training/src/ui/fine-tuning-panels.d.ts +0 -111
- package/apps/app-training/src/ui/fine-tuning-panels.d.ts.map +0 -1
- package/apps/app-training/src/ui/fine-tuning-panels.js +0 -130
- package/apps/app-training/src/ui/index.d.ts +0 -3
- package/apps/app-training/src/ui/index.d.ts.map +0 -1
- package/apps/app-training/src/ui/index.js +0 -2
- package/packages/app-core/src/api/trusted-local-request.d.ts +0 -4
- package/packages/app-core/src/api/trusted-local-request.d.ts.map +0 -1
- package/packages/app-core/src/api/trusted-local-request.js +0 -176
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* LifeOpsSetupGate — first-run setup panel.
|
|
4
|
+
*
|
|
5
|
+
* Replaces Dashboard content only (nav + other sections remain visible).
|
|
6
|
+
* Dismissed permanently when: profile has name+timezone AND at least one of
|
|
7
|
+
* {calendar provider, messaging provider, or explicit skip}.
|
|
8
|
+
*
|
|
9
|
+
* Dismiss flag is persisted via localStorage under
|
|
10
|
+
* LIFEOPS_SETUP_GATE_DISMISSED_KEY.
|
|
11
|
+
*/
|
|
12
|
+
import { Button, Input, isCloudStatusAuthenticated, useApp, } from "@elizaos/app-core";
|
|
13
|
+
import { CalendarDays, MessageCircle, SkipForward } from "lucide-react";
|
|
14
|
+
import { useCallback, useState } from "react";
|
|
15
|
+
import { useGoogleLifeOpsConnector } from "../hooks/useGoogleLifeOpsConnector.js";
|
|
16
|
+
import { useLifeOpsXConnector } from "../hooks/useLifeOpsXConnector.js";
|
|
17
|
+
export const LIFEOPS_SETUP_GATE_DISMISSED_KEY = "eliza:lifeops-setup-gate-dismissed";
|
|
18
|
+
function loadDismissed() {
|
|
19
|
+
try {
|
|
20
|
+
return localStorage.getItem(LIFEOPS_SETUP_GATE_DISMISSED_KEY) === "1";
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function saveDismissed() {
|
|
27
|
+
try {
|
|
28
|
+
localStorage.setItem(LIFEOPS_SETUP_GATE_DISMISSED_KEY, "1");
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// ignore
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function clearLifeOpsSetupGateDismissed() {
|
|
35
|
+
try {
|
|
36
|
+
localStorage.removeItem(LIFEOPS_SETUP_GATE_DISMISSED_KEY);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// ignore
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export function useLifeOpsSetupGate() {
|
|
43
|
+
const [dismissed, setDismissed] = useState(loadDismissed);
|
|
44
|
+
const dismiss = useCallback(() => {
|
|
45
|
+
saveDismissed();
|
|
46
|
+
setDismissed(true);
|
|
47
|
+
}, []);
|
|
48
|
+
const reset = useCallback(() => {
|
|
49
|
+
clearLifeOpsSetupGateDismissed();
|
|
50
|
+
setDismissed(false);
|
|
51
|
+
}, []);
|
|
52
|
+
return { dismissed, dismiss, reset };
|
|
53
|
+
}
|
|
54
|
+
export function LifeOpsSetupGate({ onDismiss }) {
|
|
55
|
+
const { elizaCloudConnected, elizaCloudLoginBusy, elizaCloudStatusReason, handleCloudLogin, t, } = useApp();
|
|
56
|
+
const ownerConnector = useGoogleLifeOpsConnector({
|
|
57
|
+
includeAccounts: false,
|
|
58
|
+
side: "owner",
|
|
59
|
+
});
|
|
60
|
+
const xConnector = useLifeOpsXConnector();
|
|
61
|
+
const [name, setName] = useState("");
|
|
62
|
+
const [timezone, setTimezone] = useState(() => Intl.DateTimeFormat().resolvedOptions().timeZone ?? "");
|
|
63
|
+
const [skipped, setSkipped] = useState(false);
|
|
64
|
+
const calendarConnected = ownerConnector.status?.connected === true;
|
|
65
|
+
const xConnected = xConnector.status?.connected === true;
|
|
66
|
+
const cloudAuthenticated = isCloudStatusAuthenticated(elizaCloudConnected, elizaCloudStatusReason);
|
|
67
|
+
const canContinue = name.trim().length > 0 &&
|
|
68
|
+
timezone.trim().length > 0 &&
|
|
69
|
+
(calendarConnected || xConnected || skipped);
|
|
70
|
+
const handleConnectCalendar = useCallback(() => {
|
|
71
|
+
void ownerConnector.connect();
|
|
72
|
+
}, [ownerConnector]);
|
|
73
|
+
const handleConnectX = useCallback(() => {
|
|
74
|
+
if (!cloudAuthenticated) {
|
|
75
|
+
void handleCloudLogin();
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
void xConnector.connect("cloud_managed");
|
|
79
|
+
}, [cloudAuthenticated, handleCloudLogin, xConnector]);
|
|
80
|
+
const handleSkip = useCallback(() => {
|
|
81
|
+
setSkipped(true);
|
|
82
|
+
}, []);
|
|
83
|
+
return (_jsxs("div", { className: "space-y-6 px-1 py-2", "data-testid": "lifeops-setup-gate", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx("h2", { className: "text-base font-semibold text-txt", children: t("lifeopssetup.title", {
|
|
84
|
+
defaultValue: "Set up LifeOps",
|
|
85
|
+
}) }), _jsx("p", { className: "text-sm leading-relaxed text-muted", children: t("lifeopssetup.description", {
|
|
86
|
+
defaultValue: "Tell the agent a bit about you, then connect your calendar or a messaging account to get started.",
|
|
87
|
+
}) })] }), _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "grid gap-4 sm:grid-cols-2", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { htmlFor: "lifeops-setup-name", className: "text-xs font-medium text-muted", children: t("lifeopssetup.yourName", {
|
|
88
|
+
defaultValue: "Your name",
|
|
89
|
+
}) }), _jsx(Input, { id: "lifeops-setup-name", placeholder: t("lifeopssetup.namePlaceholder", {
|
|
90
|
+
defaultValue: "e.g. Alex",
|
|
91
|
+
}), value: name, onChange: (e) => setName(e.target.value), className: "h-9 rounded-xl text-sm" })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { htmlFor: "lifeops-setup-timezone", className: "text-xs font-medium text-muted", children: t("lifeopssetup.timezone", {
|
|
92
|
+
defaultValue: "Timezone",
|
|
93
|
+
}) }), _jsx(Input, { id: "lifeops-setup-timezone", placeholder: "America/New_York", value: timezone, onChange: (e) => setTimezone(e.target.value), className: "h-9 rounded-xl text-sm" })] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx("div", { className: "text-xs font-medium text-muted", children: t("lifeopssetup.connectProvider", {
|
|
94
|
+
defaultValue: "Connect a provider (or skip for now)",
|
|
95
|
+
}) }), _jsxs("div", { className: "grid gap-3 sm:grid-cols-2", children: [_jsxs("button", { type: "button", onClick: handleConnectCalendar, disabled: ownerConnector.actionPending, className: [
|
|
96
|
+
"flex items-start gap-3 rounded-2xl border px-4 py-3 text-left transition-colors",
|
|
97
|
+
calendarConnected
|
|
98
|
+
? "border-ok/40 bg-ok/8 text-txt"
|
|
99
|
+
: "border-border/16 bg-card/18 hover:bg-card/30 text-txt",
|
|
100
|
+
].join(" "), children: [_jsx(CalendarDays, { className: "mt-0.5 h-4 w-4 shrink-0 text-muted" }), _jsxs("div", { children: [_jsx("div", { className: "text-sm font-medium", children: t("lifeopssetup.calendarTitle", {
|
|
101
|
+
defaultValue: "Google Calendar",
|
|
102
|
+
}) }), _jsx("div", { className: "text-xs text-muted", children: calendarConnected
|
|
103
|
+
? t("lifeopssetup.connected", {
|
|
104
|
+
defaultValue: "Connected",
|
|
105
|
+
})
|
|
106
|
+
: t("lifeopssetup.calendarHint", {
|
|
107
|
+
defaultValue: "Read events, manage your schedule",
|
|
108
|
+
}) })] })] }), _jsxs("button", { type: "button", onClick: handleConnectX, disabled: xConnector.actionPending || elizaCloudLoginBusy, className: [
|
|
109
|
+
"flex items-start gap-3 rounded-2xl border px-4 py-3 text-left transition-colors",
|
|
110
|
+
xConnected
|
|
111
|
+
? "border-ok/40 bg-ok/8 text-txt"
|
|
112
|
+
: "border-border/16 bg-card/18 hover:bg-card/30 text-txt",
|
|
113
|
+
].join(" "), children: [_jsx(MessageCircle, { className: "mt-0.5 h-4 w-4 shrink-0 text-muted" }), _jsxs("div", { children: [_jsx("div", { className: "text-sm font-medium", children: t("lifeopssetup.messagingTitle", {
|
|
114
|
+
defaultValue: "X DMs",
|
|
115
|
+
}) }), _jsx("div", { className: "text-xs text-muted", children: xConnected
|
|
116
|
+
? t("lifeopssetup.connected", {
|
|
117
|
+
defaultValue: "Connected",
|
|
118
|
+
})
|
|
119
|
+
: !elizaCloudConnected
|
|
120
|
+
? t("lifeopssetup.cloudRequired", {
|
|
121
|
+
defaultValue: "Connect Eliza Cloud first",
|
|
122
|
+
})
|
|
123
|
+
: t("lifeopssetup.messagingHint", {
|
|
124
|
+
defaultValue: "Read and reply to incoming DMs",
|
|
125
|
+
}) })] })] })] }), xConnector.pendingAuthUrl ? (_jsx("a", { href: xConnector.pendingAuthUrl, target: "_blank", rel: "noreferrer", className: "text-xs text-accent hover:underline", children: t("lifeopssetup.openXAuth", {
|
|
126
|
+
defaultValue: "Open X authorization",
|
|
127
|
+
}) })) : null, !calendarConnected && !xConnected && !skipped ? (_jsxs("button", { type: "button", onClick: handleSkip, className: "flex items-center gap-1.5 text-xs text-muted hover:text-txt", children: [_jsx(SkipForward, { className: "h-3.5 w-3.5" }), t("lifeopssetup.skipProviders", {
|
|
128
|
+
defaultValue: "Skip for now",
|
|
129
|
+
})] })) : null] })] }), _jsxs("div", { className: "flex items-center gap-3 pt-1", children: [_jsx(Button, { size: "sm", disabled: !canContinue, onClick: onDismiss, className: "rounded-full px-5 py-2 text-xs-tight font-semibold", children: t("lifeopssetup.continue", {
|
|
130
|
+
defaultValue: "Continue",
|
|
131
|
+
}) }), !canContinue && (_jsx("span", { className: "text-xs text-muted", children: t("lifeopssetup.continueHint", {
|
|
132
|
+
defaultValue: "Fill in your name and timezone to continue.",
|
|
133
|
+
}) }))] })] }));
|
|
134
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format a numeric local hour in [0..36) into a 12h time string.
|
|
3
|
+
* Hours >=24 wrap to the next day. Examples:
|
|
4
|
+
* 23.5 -> "11:30 PM"
|
|
5
|
+
* 7.25 -> "7:15 AM"
|
|
6
|
+
* 24.5 -> "12:30 AM"
|
|
7
|
+
*/
|
|
8
|
+
export declare function formatLocalHour(h: number): string;
|
|
9
|
+
export declare function LifeOpsSleepSection(): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
//# sourceMappingURL=LifeOpsSleepSection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LifeOpsSleepSection.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-lifeops/src/components/LifeOpsSleepSection.tsx"],"names":[],"mappings":"AA2EA;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAYjD;AA2qBD,wBAAgB,mBAAmB,4CA4MlC"}
|
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { client } from "@elizaos/app-core";
|
|
3
|
+
import { Activity, AlarmClock, Heart, Loader2, Moon, RefreshCw, Sunrise, } from "lucide-react";
|
|
4
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
5
|
+
import { formatClockTime, formatDurationSeconds, HabitPanel, MetricTile, } from "./LifeOpsHabitVisuals.js";
|
|
6
|
+
const HISTORY_WINDOWS = [30, 90, 365];
|
|
7
|
+
const DEFAULT_WINDOW = 365;
|
|
8
|
+
function sleepStatusLabel(schedule) {
|
|
9
|
+
if (!schedule)
|
|
10
|
+
return "No signal";
|
|
11
|
+
switch (schedule.sleepStatus) {
|
|
12
|
+
case "sleeping_now":
|
|
13
|
+
return "Sleeping";
|
|
14
|
+
case "slept":
|
|
15
|
+
return "Slept";
|
|
16
|
+
case "likely_missed":
|
|
17
|
+
return "Likely missed";
|
|
18
|
+
case "unknown":
|
|
19
|
+
return "Unknown";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function minutesFromDayStart(iso) {
|
|
23
|
+
if (!iso)
|
|
24
|
+
return null;
|
|
25
|
+
const date = new Date(iso);
|
|
26
|
+
const parsed = date.getTime();
|
|
27
|
+
if (!Number.isFinite(parsed))
|
|
28
|
+
return null;
|
|
29
|
+
return date.getHours() * 60 + date.getMinutes();
|
|
30
|
+
}
|
|
31
|
+
function markerStyle(iso) {
|
|
32
|
+
const minutes = minutesFromDayStart(iso);
|
|
33
|
+
if (minutes === null)
|
|
34
|
+
return undefined;
|
|
35
|
+
return { left: `${Math.min(100, Math.max(0, (minutes / 1440) * 100))}%` };
|
|
36
|
+
}
|
|
37
|
+
function sleepDurationSeconds(schedule) {
|
|
38
|
+
if (typeof schedule?.lastSleepDurationMinutes !== "number") {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
return Math.max(0, schedule.lastSleepDurationMinutes * 60);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Format a numeric local hour in [0..36) into a 12h time string.
|
|
45
|
+
* Hours >=24 wrap to the next day. Examples:
|
|
46
|
+
* 23.5 -> "11:30 PM"
|
|
47
|
+
* 7.25 -> "7:15 AM"
|
|
48
|
+
* 24.5 -> "12:30 AM"
|
|
49
|
+
*/
|
|
50
|
+
export function formatLocalHour(h) {
|
|
51
|
+
if (!Number.isFinite(h))
|
|
52
|
+
return "—";
|
|
53
|
+
const wrapped = ((h % 24) + 24) % 24;
|
|
54
|
+
const hourFloat = wrapped;
|
|
55
|
+
const hour = Math.floor(hourFloat);
|
|
56
|
+
const minute = Math.round((hourFloat - hour) * 60);
|
|
57
|
+
const minuteWrap = minute === 60 ? 0 : minute;
|
|
58
|
+
const hourWrap = minute === 60 ? (hour + 1) % 24 : hour;
|
|
59
|
+
const period = hourWrap >= 12 ? "PM" : "AM";
|
|
60
|
+
const displayHour = hourWrap % 12 === 0 ? 12 : hourWrap % 12;
|
|
61
|
+
const minuteStr = String(minuteWrap).padStart(2, "0");
|
|
62
|
+
return `${displayHour}:${minuteStr} ${period}`;
|
|
63
|
+
}
|
|
64
|
+
function formatDurationMinutes(minutes) {
|
|
65
|
+
if (typeof minutes !== "number" || !Number.isFinite(minutes))
|
|
66
|
+
return "—";
|
|
67
|
+
return formatDurationSeconds(minutes * 60) || "—";
|
|
68
|
+
}
|
|
69
|
+
function historyWindowLabel(days) {
|
|
70
|
+
return days === 365 ? "All year" : `${days} days`;
|
|
71
|
+
}
|
|
72
|
+
function formatStddev(stddevMin) {
|
|
73
|
+
if (typeof stddevMin !== "number" || !Number.isFinite(stddevMin))
|
|
74
|
+
return "";
|
|
75
|
+
return `±${Math.round(stddevMin)} min`;
|
|
76
|
+
}
|
|
77
|
+
function formatEpisodeDateLabel(iso) {
|
|
78
|
+
const ts = Date.parse(iso);
|
|
79
|
+
if (!Number.isFinite(ts))
|
|
80
|
+
return "—";
|
|
81
|
+
return new Intl.DateTimeFormat(undefined, {
|
|
82
|
+
weekday: "short",
|
|
83
|
+
month: "short",
|
|
84
|
+
day: "numeric",
|
|
85
|
+
}).format(new Date(ts));
|
|
86
|
+
}
|
|
87
|
+
function cycleTypeLabel(type) {
|
|
88
|
+
switch (type) {
|
|
89
|
+
case "overnight":
|
|
90
|
+
return "Overnight";
|
|
91
|
+
case "nap":
|
|
92
|
+
return "Nap";
|
|
93
|
+
case "unknown":
|
|
94
|
+
return "Unknown";
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function cycleTypeBadgeClass(type) {
|
|
98
|
+
switch (type) {
|
|
99
|
+
case "overnight":
|
|
100
|
+
return "border-indigo-500/30 bg-indigo-500/10 text-indigo-200";
|
|
101
|
+
case "nap":
|
|
102
|
+
return "border-amber-400/30 bg-amber-400/10 text-amber-200";
|
|
103
|
+
case "unknown":
|
|
104
|
+
return "border-border/20 bg-bg/30 text-muted";
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function sourceMeta(source) {
|
|
108
|
+
switch (source) {
|
|
109
|
+
case "health":
|
|
110
|
+
return { label: "Health sensor", short: "Sensor", icon: Heart };
|
|
111
|
+
case "activity_gap":
|
|
112
|
+
return {
|
|
113
|
+
label: "Inferred from activity gap",
|
|
114
|
+
short: "Inferred",
|
|
115
|
+
icon: Activity,
|
|
116
|
+
};
|
|
117
|
+
case "manual":
|
|
118
|
+
return { label: "Manual entry", short: "Manual", icon: AlarmClock };
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function confidenceTier(value) {
|
|
122
|
+
if (value >= 0.8)
|
|
123
|
+
return "high";
|
|
124
|
+
if (value >= 0.6)
|
|
125
|
+
return "med";
|
|
126
|
+
return "low";
|
|
127
|
+
}
|
|
128
|
+
function confidenceDotClass(tier) {
|
|
129
|
+
switch (tier) {
|
|
130
|
+
case "high":
|
|
131
|
+
return "bg-emerald-400";
|
|
132
|
+
case "med":
|
|
133
|
+
return "bg-amber-300";
|
|
134
|
+
case "low":
|
|
135
|
+
return "bg-rose-400";
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function confidenceLabel(tier, value) {
|
|
139
|
+
const pct = Math.round(value * 100);
|
|
140
|
+
switch (tier) {
|
|
141
|
+
case "high":
|
|
142
|
+
return `High confidence (${pct}%)`;
|
|
143
|
+
case "med":
|
|
144
|
+
return `Medium confidence (${pct}%)`;
|
|
145
|
+
case "low":
|
|
146
|
+
return `Low confidence (${pct}%)`;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function classificationLabel(c) {
|
|
150
|
+
switch (c) {
|
|
151
|
+
case "very_regular":
|
|
152
|
+
return "Very regular";
|
|
153
|
+
case "regular":
|
|
154
|
+
return "Regular";
|
|
155
|
+
case "irregular":
|
|
156
|
+
return "Irregular";
|
|
157
|
+
case "very_irregular":
|
|
158
|
+
return "Very irregular";
|
|
159
|
+
case "insufficient_data":
|
|
160
|
+
return "Not enough data yet";
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
function regularityTone(c) {
|
|
164
|
+
switch (c) {
|
|
165
|
+
case "very_regular":
|
|
166
|
+
return {
|
|
167
|
+
ring: "ring-emerald-400/40",
|
|
168
|
+
text: "text-emerald-300",
|
|
169
|
+
bg: "bg-emerald-500/10",
|
|
170
|
+
};
|
|
171
|
+
case "regular":
|
|
172
|
+
return {
|
|
173
|
+
ring: "ring-green-400/40",
|
|
174
|
+
text: "text-green-300",
|
|
175
|
+
bg: "bg-green-500/10",
|
|
176
|
+
};
|
|
177
|
+
case "irregular":
|
|
178
|
+
return {
|
|
179
|
+
ring: "ring-amber-400/40",
|
|
180
|
+
text: "text-amber-300",
|
|
181
|
+
bg: "bg-amber-500/10",
|
|
182
|
+
};
|
|
183
|
+
case "very_irregular":
|
|
184
|
+
return {
|
|
185
|
+
ring: "ring-rose-400/40",
|
|
186
|
+
text: "text-rose-300",
|
|
187
|
+
bg: "bg-rose-500/10",
|
|
188
|
+
};
|
|
189
|
+
case "insufficient_data":
|
|
190
|
+
return {
|
|
191
|
+
ring: "ring-border/30",
|
|
192
|
+
text: "text-muted",
|
|
193
|
+
bg: "bg-bg/30",
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
function TabButton({ active, label, onClick, }) {
|
|
198
|
+
return (_jsx("button", { type: "button", role: "tab", "aria-selected": active, onClick: onClick, className: [
|
|
199
|
+
"rounded-md px-3 py-1.5 text-xs font-medium transition-colors",
|
|
200
|
+
active
|
|
201
|
+
? "bg-accent/20 text-txt"
|
|
202
|
+
: "text-muted hover:bg-bg/30 hover:text-txt",
|
|
203
|
+
].join(" "), children: label }));
|
|
204
|
+
}
|
|
205
|
+
function NapToggle({ value, onChange, }) {
|
|
206
|
+
return (_jsxs("label", { className: "inline-flex items-center gap-2 text-xs text-muted", children: [_jsx("span", { children: "Show naps" }), _jsx("button", { type: "button", role: "switch", "aria-checked": value, onClick: () => onChange(!value), className: [
|
|
207
|
+
"relative inline-flex h-5 w-9 shrink-0 items-center rounded-full transition-colors",
|
|
208
|
+
value ? "bg-accent/60" : "bg-border/30",
|
|
209
|
+
].join(" "), children: _jsx("span", { className: [
|
|
210
|
+
"inline-block h-4 w-4 transform rounded-full bg-white transition-transform",
|
|
211
|
+
value ? "translate-x-4" : "translate-x-0.5",
|
|
212
|
+
].join(" ") }) })] }));
|
|
213
|
+
}
|
|
214
|
+
function TonightTab({ schedule }) {
|
|
215
|
+
const durationSeconds = sleepDurationSeconds(schedule);
|
|
216
|
+
const bedtime = schedule?.relativeTime.bedtimeTargetAt ?? null;
|
|
217
|
+
const wake = schedule?.wakeAt ?? schedule?.relativeTime.wakeAnchorAt ?? null;
|
|
218
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "grid gap-3 sm:grid-cols-2 xl:grid-cols-4", children: [_jsx(MetricTile, { icon: _jsx(Moon, {}), value: sleepStatusLabel(schedule), label: "Now" }), _jsx(MetricTile, { icon: _jsx(Moon, {}), value: formatDurationSeconds(durationSeconds) || "-", label: "Last Sleep" }), _jsx(MetricTile, { icon: _jsx(AlarmClock, {}), value: formatClockTime(bedtime) || "-", label: "Bed" }), _jsx(MetricTile, { icon: _jsx(Sunrise, {}), value: formatClockTime(wake) || "-", label: "Wake" })] }), _jsx(HabitPanel, { title: "Cycle", icon: _jsx(Moon, {}), children: _jsxs("div", { className: "relative h-24 rounded-lg border border-border/12 bg-bg/24 p-4", children: [_jsx("div", { className: "absolute left-4 right-4 top-1/2 h-2 -translate-y-1/2 rounded-full bg-gradient-to-r from-indigo-500/70 via-blue-400/50 to-amber-300/70" }), markerStyle(bedtime) ? (_jsx("div", { className: "absolute top-5 h-14 w-px bg-blue-300", style: markerStyle(bedtime), title: "Bed" })) : null, markerStyle(wake) ? (_jsx("div", { className: "absolute top-5 h-14 w-px bg-amber-300", style: markerStyle(wake), title: "Wake" })) : null, _jsx("div", { className: "absolute bottom-3 left-4 text-[10px] font-medium text-muted", children: "12a" }), _jsx("div", { className: "absolute bottom-3 left-1/2 -translate-x-1/2 text-[10px] font-medium text-muted", children: "12p" }), _jsx("div", { className: "absolute bottom-3 right-4 text-[10px] font-medium text-muted", children: "12a" })] }) })] }));
|
|
219
|
+
}
|
|
220
|
+
function HistoryEpisodeRow({ episode, }) {
|
|
221
|
+
const meta = sourceMeta(episode.source);
|
|
222
|
+
const SourceIcon = meta.icon;
|
|
223
|
+
const tier = confidenceTier(episode.confidence);
|
|
224
|
+
const dotClass = confidenceDotClass(tier);
|
|
225
|
+
const dotTitle = confidenceLabel(tier, episode.confidence);
|
|
226
|
+
const dateLabel = formatEpisodeDateLabel(episode.startedAt);
|
|
227
|
+
const startClock = formatClockTime(episode.startedAt) || "—";
|
|
228
|
+
const endClock = episode.endedAt ? formatClockTime(episode.endedAt) : "—";
|
|
229
|
+
const durationLabel = formatDurationMinutes(episode.durationMin);
|
|
230
|
+
const typeLabel = cycleTypeLabel(episode.cycleType);
|
|
231
|
+
const typeBadge = cycleTypeBadgeClass(episode.cycleType);
|
|
232
|
+
const durationPct = typeof episode.durationMin === "number" && Number.isFinite(episode.durationMin)
|
|
233
|
+
? Math.min(100, Math.max(6, (episode.durationMin / 600) * 100))
|
|
234
|
+
: 0;
|
|
235
|
+
return (_jsxs("li", { className: "flex items-center gap-3 rounded-lg border border-border/12 bg-bg/24 px-3 py-2.5", "data-testid": "sleep-history-row", children: [_jsx("span", { className: `h-2 w-2 shrink-0 rounded-full ${dotClass}`, title: dotTitle, role: "img", "aria-label": dotTitle }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center gap-2 text-xs font-medium text-txt", children: [_jsx("span", { className: "truncate", children: dateLabel }), _jsx("span", { className: `shrink-0 rounded-full border px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide ${typeBadge}`, children: typeLabel })] }), _jsxs("div", { className: "mt-0.5 truncate text-[11px] text-muted", children: [startClock, " \u2192 ", endClock] }), durationPct > 0 ? (_jsx("div", { className: "mt-2 h-1.5 overflow-hidden rounded-full bg-bg-muted/40", children: _jsx("div", { className: [
|
|
236
|
+
"h-full rounded-full",
|
|
237
|
+
episode.cycleType === "nap"
|
|
238
|
+
? "bg-amber-300/80"
|
|
239
|
+
: episode.cycleType === "overnight"
|
|
240
|
+
? "bg-indigo-300/80"
|
|
241
|
+
: "bg-muted/60",
|
|
242
|
+
].join(" "), style: { width: `${durationPct}%` } }) })) : null] }), _jsxs("div", { className: "shrink-0 text-right", children: [_jsx("div", { className: "text-sm font-semibold tabular-nums text-txt", children: durationLabel }), _jsxs("div", { className: "mt-0.5 inline-flex items-center gap-1 text-[10px] text-muted", title: meta.label, children: [_jsx(SourceIcon, { className: "h-3 w-3", "aria-hidden": true }), _jsx("span", { children: meta.short })] })] })] }));
|
|
243
|
+
}
|
|
244
|
+
function HistorySummaryStrip({ episodes, }) {
|
|
245
|
+
const summary = useMemo(() => {
|
|
246
|
+
let totalDuration = 0;
|
|
247
|
+
let durationCount = 0;
|
|
248
|
+
let overnightCount = 0;
|
|
249
|
+
let napCount = 0;
|
|
250
|
+
let openCount = 0;
|
|
251
|
+
for (const episode of episodes) {
|
|
252
|
+
if (episode.cycleType === "overnight")
|
|
253
|
+
overnightCount += 1;
|
|
254
|
+
if (episode.cycleType === "nap")
|
|
255
|
+
napCount += 1;
|
|
256
|
+
if (!episode.endedAt)
|
|
257
|
+
openCount += 1;
|
|
258
|
+
if (typeof episode.durationMin === "number" &&
|
|
259
|
+
Number.isFinite(episode.durationMin)) {
|
|
260
|
+
totalDuration += episode.durationMin;
|
|
261
|
+
durationCount += 1;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return {
|
|
265
|
+
averageMin: durationCount > 0 ? totalDuration / durationCount : null,
|
|
266
|
+
overnightCount,
|
|
267
|
+
napCount,
|
|
268
|
+
openCount,
|
|
269
|
+
};
|
|
270
|
+
}, [episodes]);
|
|
271
|
+
return (_jsxs("div", { className: "grid gap-2 sm:grid-cols-4", "data-testid": "sleep-history-summary", children: [_jsx(MetricTile, { icon: _jsx(Moon, {}), value: String(episodes.length), label: "Cycles" }), _jsx(MetricTile, { icon: _jsx(Moon, {}), value: formatDurationMinutes(summary.averageMin), label: "Avg" }), _jsx(MetricTile, { icon: _jsx(Activity, {}), value: `${summary.overnightCount}/${summary.napCount}`, label: "Night/Nap" }), _jsx(MetricTile, { icon: _jsx(AlarmClock, {}), value: String(summary.openCount), label: "Open" })] }));
|
|
272
|
+
}
|
|
273
|
+
function HistoryCycleMap({ episodes, }) {
|
|
274
|
+
const visible = episodes.slice(0, 42).reverse();
|
|
275
|
+
if (visible.length === 0)
|
|
276
|
+
return null;
|
|
277
|
+
return (_jsx("div", { className: "grid min-h-16 grid-cols-[repeat(auto-fit,minmax(8px,1fr))] items-end gap-1 rounded-lg border border-border/12 bg-bg/24 px-3 py-3", "data-testid": "sleep-history-cycle-map", children: visible.map((episode) => {
|
|
278
|
+
const height = typeof episode.durationMin === "number" &&
|
|
279
|
+
Number.isFinite(episode.durationMin)
|
|
280
|
+
? Math.min(100, Math.max(16, (episode.durationMin / 600) * 100))
|
|
281
|
+
: 16;
|
|
282
|
+
const tone = episode.cycleType === "nap"
|
|
283
|
+
? "bg-amber-300/75"
|
|
284
|
+
: episode.cycleType === "overnight"
|
|
285
|
+
? "bg-indigo-300/80"
|
|
286
|
+
: "bg-muted/60";
|
|
287
|
+
return (_jsx("span", { className: `block rounded-sm ${tone}`, style: { height: `${height}%` }, title: `${formatEpisodeDateLabel(episode.startedAt)} · ${formatDurationMinutes(episode.durationMin)}` }, episode.id));
|
|
288
|
+
}) }));
|
|
289
|
+
}
|
|
290
|
+
function HistoryTab({ data, loading, error, windowDays, onWindowChange, }) {
|
|
291
|
+
const sortedEpisodes = useMemo(() => {
|
|
292
|
+
if (!data)
|
|
293
|
+
return [];
|
|
294
|
+
return [...data.episodes].sort((a, b) => {
|
|
295
|
+
const aTs = Date.parse(a.startedAt);
|
|
296
|
+
const bTs = Date.parse(b.startedAt);
|
|
297
|
+
return ((Number.isFinite(bTs) ? bTs : 0) - (Number.isFinite(aTs) ? aTs : 0));
|
|
298
|
+
});
|
|
299
|
+
}, [data]);
|
|
300
|
+
return (_jsxs("div", { className: "space-y-3", children: [_jsx("div", { className: "flex items-center gap-1.5", children: HISTORY_WINDOWS.map((w) => (_jsx("button", { type: "button", onClick: () => onWindowChange(w), className: [
|
|
301
|
+
"rounded-md border px-2.5 py-1 text-[11px] font-medium transition-colors",
|
|
302
|
+
w === windowDays
|
|
303
|
+
? "border-accent/40 bg-accent/10 text-txt"
|
|
304
|
+
: "border-border/20 bg-bg/30 text-muted hover:border-accent/30 hover:text-txt",
|
|
305
|
+
].join(" "), "aria-pressed": w === windowDays, children: historyWindowLabel(w) }, w))) }), error ? (_jsx("div", { className: "rounded-lg border border-rose-500/30 bg-rose-500/10 px-3 py-2 text-xs text-rose-300", children: error })) : null, loading && !data ? (_jsxs("div", { className: "flex items-center gap-2 py-4 text-xs text-muted", children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin", "aria-hidden": true }), "Loading history..."] })) : null, !loading && data && sortedEpisodes.length === 0 ? (_jsxs("div", { className: "rounded-lg border border-border/20 bg-bg/24 px-3 py-6 text-center text-xs text-muted", children: ["No sleep data in the last ", windowDays, " days. Connect a health source from Settings."] })) : null, sortedEpisodes.length > 0 ? (_jsxs(_Fragment, { children: [_jsx(HistorySummaryStrip, { episodes: sortedEpisodes }), _jsx(HistoryCycleMap, { episodes: sortedEpisodes }), _jsx("ul", { className: "space-y-2", "data-testid": "sleep-history-list", children: sortedEpisodes.map((ep) => (_jsx(HistoryEpisodeRow, { episode: ep }, ep.id))) })] })) : null] }));
|
|
306
|
+
}
|
|
307
|
+
function SriGauge({ sri, classification, }) {
|
|
308
|
+
const tone = regularityTone(classification);
|
|
309
|
+
const display = Number.isFinite(sri) ? Math.round(sri) : 0;
|
|
310
|
+
const pct = Math.max(0, Math.min(100, display));
|
|
311
|
+
const radius = 52;
|
|
312
|
+
const circumference = 2 * Math.PI * radius;
|
|
313
|
+
const offset = circumference * (1 - pct / 100);
|
|
314
|
+
return (_jsxs("div", { className: `flex items-center gap-4 rounded-lg ${tone.bg} p-4`, children: [_jsxs("div", { className: `relative h-32 w-32 shrink-0 ring-2 ${tone.ring} rounded-full`, children: [_jsxs("svg", { viewBox: "0 0 120 120", className: "h-full w-full -rotate-90", role: "img", "aria-label": `Sleep Regularity Index ${classification === "insufficient_data" ? "unavailable" : display}`, children: [_jsx("title", { children: "Sleep Regularity Index" }), _jsx("circle", { cx: "60", cy: "60", r: radius, fill: "none", stroke: "currentColor", strokeWidth: "10", className: "text-bg-muted/40" }), _jsx("circle", { cx: "60", cy: "60", r: radius, fill: "none", stroke: "currentColor", strokeWidth: "10", strokeLinecap: "round", className: tone.text, strokeDasharray: circumference, strokeDashoffset: offset })] }), _jsxs("div", { className: "absolute inset-0 flex flex-col items-center justify-center", children: [_jsx("div", { className: `text-3xl font-semibold leading-none ${tone.text}`, children: classification === "insufficient_data" ? "—" : display }), _jsx("div", { className: "mt-1 text-[10px] font-medium uppercase tracking-wide text-muted", children: "SRI" })] })] }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: `text-base font-semibold ${tone.text}`, children: classificationLabel(classification) }), _jsx("div", { className: "mt-1 text-xs text-muted", children: "Sleep Regularity Index measures how consistent your bedtime and wake time are night to night." })] })] }));
|
|
315
|
+
}
|
|
316
|
+
function PatternTab({ regularity, baseline, loading, error, }) {
|
|
317
|
+
const noBaseline = !baseline ||
|
|
318
|
+
(baseline.medianBedtimeLocalHour === null &&
|
|
319
|
+
baseline.medianWakeLocalHour === null &&
|
|
320
|
+
baseline.medianSleepDurationMin === null);
|
|
321
|
+
return (_jsxs("div", { className: "space-y-4", children: [error ? (_jsx("div", { className: "rounded-lg border border-rose-500/30 bg-rose-500/10 px-3 py-2 text-xs text-rose-300", children: error })) : null, loading && !regularity && !baseline ? (_jsxs("div", { className: "flex items-center gap-2 py-4 text-xs text-muted", children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin", "aria-hidden": true }), "Loading pattern..."] })) : null, regularity ? (_jsx(SriGauge, { sri: regularity.sri, classification: regularity.classification })) : null, noBaseline ? (_jsx("div", { className: "rounded-lg border border-border/20 bg-bg/24 px-3 py-6 text-center text-xs text-muted", children: "Not enough data yet \u2014 keep tracking sleep for a week to see your pattern." })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "grid gap-3 sm:grid-cols-3", children: [_jsx(MetricTile, { icon: _jsx(AlarmClock, {}), value: baseline.medianBedtimeLocalHour !== null
|
|
322
|
+
? `${formatLocalHour(baseline.medianBedtimeLocalHour)} ${formatStddev(baseline.bedtimeStddevMin)}`.trim()
|
|
323
|
+
: "—", label: "Typical bedtime" }), _jsx(MetricTile, { icon: _jsx(Sunrise, {}), value: baseline.medianWakeLocalHour !== null
|
|
324
|
+
? `${formatLocalHour(baseline.medianWakeLocalHour)} ${formatStddev(baseline.wakeStddevMin)}`.trim()
|
|
325
|
+
: "—", label: "Typical wake" }), _jsx(MetricTile, { icon: _jsx(Moon, {}), value: formatDurationMinutes(baseline.medianSleepDurationMin), label: "Typical duration" })] }), _jsxs("div", { className: "text-[11px] text-muted", children: ["Based on ", baseline.sampleSize, " ", baseline.sampleSize === 1 ? "night" : "nights", " over the last", " ", baseline.windowDays, " days", regularity && regularity.sampleSize !== baseline.sampleSize
|
|
326
|
+
? ` (regularity from ${regularity.sampleSize} ${regularity.sampleSize === 1 ? "night" : "nights"})`
|
|
327
|
+
: "", "."] })] }))] }));
|
|
328
|
+
}
|
|
329
|
+
export function LifeOpsSleepSection() {
|
|
330
|
+
const [tab, setTab] = useState("tonight");
|
|
331
|
+
const [includeNaps, setIncludeNaps] = useState(false);
|
|
332
|
+
const [historyWindow, setHistoryWindow] = useState(DEFAULT_WINDOW);
|
|
333
|
+
const [overview, setOverview] = useState(null);
|
|
334
|
+
const [tonightLoading, setTonightLoading] = useState(false);
|
|
335
|
+
const [tonightError, setTonightError] = useState(null);
|
|
336
|
+
const [history, setHistory] = useState(null);
|
|
337
|
+
const [historyLoading, setHistoryLoading] = useState(false);
|
|
338
|
+
const [historyError, setHistoryError] = useState(null);
|
|
339
|
+
const [regularity, setRegularity] = useState(null);
|
|
340
|
+
const [baseline, setBaseline] = useState(null);
|
|
341
|
+
const [patternLoading, setPatternLoading] = useState(false);
|
|
342
|
+
const [patternError, setPatternError] = useState(null);
|
|
343
|
+
const loadTonight = useCallback(async () => {
|
|
344
|
+
setTonightLoading(true);
|
|
345
|
+
setTonightError(null);
|
|
346
|
+
try {
|
|
347
|
+
setOverview(await client.getLifeOpsOverview());
|
|
348
|
+
}
|
|
349
|
+
catch (cause) {
|
|
350
|
+
setTonightError(cause instanceof Error && cause.message.trim().length > 0
|
|
351
|
+
? cause.message.trim()
|
|
352
|
+
: "Sleep failed to load.");
|
|
353
|
+
}
|
|
354
|
+
finally {
|
|
355
|
+
setTonightLoading(false);
|
|
356
|
+
}
|
|
357
|
+
}, []);
|
|
358
|
+
const loadHistory = useCallback(async (windowDays, naps) => {
|
|
359
|
+
setHistoryLoading(true);
|
|
360
|
+
setHistoryError(null);
|
|
361
|
+
try {
|
|
362
|
+
setHistory(await client.getLifeOpsSleepHistory({
|
|
363
|
+
windowDays,
|
|
364
|
+
includeNaps: naps,
|
|
365
|
+
}));
|
|
366
|
+
}
|
|
367
|
+
catch (cause) {
|
|
368
|
+
setHistoryError(cause instanceof Error && cause.message.trim().length > 0
|
|
369
|
+
? cause.message.trim()
|
|
370
|
+
: "Sleep history failed to load.");
|
|
371
|
+
}
|
|
372
|
+
finally {
|
|
373
|
+
setHistoryLoading(false);
|
|
374
|
+
}
|
|
375
|
+
}, []);
|
|
376
|
+
const loadPattern = useCallback(async (naps) => {
|
|
377
|
+
setPatternLoading(true);
|
|
378
|
+
setPatternError(null);
|
|
379
|
+
try {
|
|
380
|
+
const [reg, base] = await Promise.all([
|
|
381
|
+
client.getLifeOpsSleepRegularity({ includeNaps: naps }),
|
|
382
|
+
client.getLifeOpsPersonalBaseline(),
|
|
383
|
+
]);
|
|
384
|
+
setRegularity(reg);
|
|
385
|
+
setBaseline(base);
|
|
386
|
+
}
|
|
387
|
+
catch (cause) {
|
|
388
|
+
setPatternError(cause instanceof Error && cause.message.trim().length > 0
|
|
389
|
+
? cause.message.trim()
|
|
390
|
+
: "Sleep pattern failed to load.");
|
|
391
|
+
}
|
|
392
|
+
finally {
|
|
393
|
+
setPatternLoading(false);
|
|
394
|
+
}
|
|
395
|
+
}, []);
|
|
396
|
+
useEffect(() => {
|
|
397
|
+
void loadTonight();
|
|
398
|
+
}, [loadTonight]);
|
|
399
|
+
useEffect(() => {
|
|
400
|
+
if (tab === "history") {
|
|
401
|
+
void loadHistory(historyWindow, includeNaps);
|
|
402
|
+
}
|
|
403
|
+
}, [tab, historyWindow, includeNaps, loadHistory]);
|
|
404
|
+
useEffect(() => {
|
|
405
|
+
if (tab === "pattern") {
|
|
406
|
+
void loadPattern(includeNaps);
|
|
407
|
+
}
|
|
408
|
+
}, [tab, includeNaps, loadPattern]);
|
|
409
|
+
const refreshActiveTab = useCallback(() => {
|
|
410
|
+
if (tab === "tonight") {
|
|
411
|
+
void loadTonight();
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
if (tab === "history") {
|
|
415
|
+
void loadHistory(historyWindow, includeNaps);
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
void loadPattern(includeNaps);
|
|
419
|
+
}, [tab, historyWindow, includeNaps, loadTonight, loadHistory, loadPattern]);
|
|
420
|
+
const refreshing = (tab === "tonight" && tonightLoading) ||
|
|
421
|
+
(tab === "history" && historyLoading) ||
|
|
422
|
+
(tab === "pattern" && patternLoading);
|
|
423
|
+
const schedule = overview?.schedule ?? null;
|
|
424
|
+
return (_jsxs("div", { className: "space-y-4", "data-testid": "lifeops-sleep-section", children: [_jsxs("header", { className: "flex flex-wrap items-center justify-between gap-3 border-b border-border/20 pb-4", children: [_jsx("div", { className: "min-w-0", children: _jsx("h1", { className: "truncate text-2xl font-semibold tracking-tight text-txt", children: "Sleep" }) }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx(NapToggle, { value: includeNaps, onChange: setIncludeNaps }), _jsx("button", { type: "button", "aria-label": "Refresh sleep", title: "Refresh", className: "inline-flex h-9 w-9 items-center justify-center rounded-lg border border-border/20 bg-bg/30 text-muted transition-colors hover:border-accent/30 hover:text-txt disabled:opacity-40", onClick: refreshActiveTab, disabled: refreshing, children: _jsx(RefreshCw, { className: `h-3.5 w-3.5 ${refreshing ? "animate-spin" : ""}`, "aria-hidden": true }) })] })] }), _jsxs("div", { className: "inline-flex items-center gap-1 rounded-lg border border-border/20 bg-bg/30 p-1", role: "tablist", "aria-label": "Sleep view", children: [_jsx(TabButton, { active: tab === "tonight", label: "Tonight", onClick: () => setTab("tonight") }), _jsx(TabButton, { active: tab === "history", label: "History", onClick: () => setTab("history") }), _jsx(TabButton, { active: tab === "pattern", label: "Pattern", onClick: () => setTab("pattern") })] }), tab === "tonight" ? (_jsxs(_Fragment, { children: [tonightError ? (_jsx("div", { className: "rounded-lg border border-rose-500/30 bg-rose-500/10 px-3 py-2 text-xs text-rose-300", children: tonightError })) : null, tonightLoading && !overview ? (_jsxs("div", { className: "flex items-center gap-2 py-4 text-xs text-muted", children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin", "aria-hidden": true }), "Loading sleep..."] })) : null, _jsx(TonightTab, { schedule: schedule })] })) : null, tab === "history" ? (_jsx(HistoryTab, { data: history, loading: historyLoading, error: historyError, windowDays: historyWindow, onWindowChange: setHistoryWindow })) : null, tab === "pattern" ? (_jsx(PatternTab, { regularity: regularity, baseline: baseline, loading: patternLoading, error: patternError })) : null] }));
|
|
425
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { LifeOpsSection } from "../hooks/useLifeOpsSection.js";
|
|
3
|
+
interface LifeOpsWorkspaceShellProps {
|
|
4
|
+
compactLayout: boolean;
|
|
5
|
+
section: LifeOpsSection;
|
|
6
|
+
navigate: (section: LifeOpsSection) => void;
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
}
|
|
9
|
+
export declare function LifeOpsWorkspaceShell({ compactLayout, section, navigate, children, }: LifeOpsWorkspaceShellProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=LifeOpsWorkspaceShell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LifeOpsWorkspaceShell.d.ts","sourceRoot":"","sources":["../../../../../../../apps/app-lifeops/src/components/LifeOpsWorkspaceShell.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,SAAS,EAA+B,MAAM,OAAO,CAAC;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAIpE,UAAU,0BAA0B;IAClC,aAAa,EAAE,OAAO,CAAC;IACvB,OAAO,EAAE,cAAc,CAAC;IACxB,QAAQ,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;IAC5C,QAAQ,EAAE,SAAS,CAAC;CACrB;AAKD,wBAAgB,qBAAqB,CAAC,EACpC,aAAa,EACb,OAAO,EACP,QAAQ,EACR,QAAQ,GACT,EAAE,0BAA0B,2CAkH5B"}
|