neoagent 2.3.1-beta.2 → 2.3.1-beta.21
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/.env.example +39 -0
- package/README.md +2 -0
- package/docs/capabilities.md +2 -2
- package/docs/configuration.md +13 -5
- package/docs/integrations.md +4 -1
- package/flutter_app/.metadata +42 -0
- package/flutter_app/README.md +21 -0
- package/flutter_app/analysis_options.yaml +32 -0
- package/flutter_app/android/app/build.gradle.kts +109 -0
- package/flutter_app/android/app/src/debug/AndroidManifest.xml +7 -0
- package/flutter_app/android/app/src/main/AndroidManifest.xml +147 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/MainActivity.kt +747 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/health/HealthConnectGateway.kt +280 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/health/HealthSyncNotifications.kt +113 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/health/HealthSyncPayload.kt +57 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/health/HealthSyncScheduler.kt +78 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/health/HealthSyncWorker.kt +253 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/health/PermissionsRationaleActivity.kt +46 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/recording/RecordingBootReceiver.kt +21 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/recording/RecordingForegroundService.kt +586 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/recording/RecordingStateStore.kt +78 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/recording/RecordingUploadClient.kt +104 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/AiHomeWidgetProvider.kt +457 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/AiWidgetStore.kt +194 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/VoiceLaunchWidgetProvider.kt +67 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/WidgetConfigActivity.kt +228 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/WidgetSyncScheduler.kt +72 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/WidgetSyncWorker.kt +186 -0
- package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/WidgetTaskRunWorker.kt +210 -0
- package/flutter_app/android/app/src/main/res/drawable/launch_background.xml +12 -0
- package/flutter_app/android/app/src/main/res/drawable/neoagent_ai_widget_bg.xml +11 -0
- package/flutter_app/android/app/src/main/res/drawable/neoagent_ai_widget_task_bg.xml +8 -0
- package/flutter_app/android/app/src/main/res/drawable-v21/launch_background.xml +12 -0
- package/flutter_app/android/app/src/main/res/layout/neoagent_ai_widget.xml +138 -0
- package/flutter_app/android/app/src/main/res/layout/neoagent_ai_widget_task_row.xml +52 -0
- package/flutter_app/android/app/src/main/res/layout/neoagent_voice_widget.xml +49 -0
- package/flutter_app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/flutter_app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/flutter_app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/flutter_app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/flutter_app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/flutter_app/android/app/src/main/res/values/strings.xml +12 -0
- package/flutter_app/android/app/src/main/res/values/styles.xml +18 -0
- package/flutter_app/android/app/src/main/res/values-night/styles.xml +18 -0
- package/flutter_app/android/app/src/main/res/xml/file_paths.xml +6 -0
- package/flutter_app/android/app/src/main/res/xml/neoagent_ai_widget_info.xml +12 -0
- package/flutter_app/android/app/src/main/res/xml/neoagent_voice_widget_info.xml +12 -0
- package/flutter_app/android/app/src/profile/AndroidManifest.xml +7 -0
- package/flutter_app/android/build.gradle.kts +24 -0
- package/flutter_app/android/ci-release.keystore +0 -0
- package/flutter_app/android/gradle/wrapper/gradle-wrapper.properties +5 -0
- package/flutter_app/android/gradle.properties +3 -0
- package/flutter_app/android/key.properties +4 -0
- package/flutter_app/android/settings.gradle.kts +26 -0
- package/flutter_app/assets/branding/app_icon_1024.png +0 -0
- package/flutter_app/assets/branding/app_icon_128.png +0 -0
- package/flutter_app/assets/branding/app_icon_192.png +0 -0
- package/flutter_app/assets/branding/app_icon_256.png +0 -0
- package/flutter_app/assets/branding/app_icon_32.png +0 -0
- package/flutter_app/assets/branding/app_icon_512.png +0 -0
- package/flutter_app/assets/branding/app_icon_64.png +0 -0
- package/flutter_app/assets/branding/tray_icon_template.png +0 -0
- package/flutter_app/lib/features/location/location_service.dart +119 -0
- package/flutter_app/lib/features/notifications/notification_interceptor.dart +97 -0
- package/flutter_app/lib/main.dart +23057 -0
- package/flutter_app/lib/main_app_shell.dart +1682 -0
- package/flutter_app/lib/main_integrations.dart +931 -0
- package/flutter_app/lib/main_launcher.dart +959 -0
- package/flutter_app/lib/main_launcher_entry.dart +5 -0
- package/flutter_app/lib/main_models.dart +3473 -0
- package/flutter_app/lib/main_shared.dart +2861 -0
- package/flutter_app/lib/main_theme.dart +204 -0
- package/flutter_app/lib/main_voice_assistant.dart +831 -0
- package/flutter_app/lib/src/android_apk_drop_zone.dart +32 -0
- package/flutter_app/lib/src/android_apk_drop_zone_stub.dart +16 -0
- package/flutter_app/lib/src/android_apk_drop_zone_web.dart +348 -0
- package/flutter_app/lib/src/android_app_installer.dart +22 -0
- package/flutter_app/lib/src/android_app_installer_io.dart +122 -0
- package/flutter_app/lib/src/android_app_installer_stub.dart +21 -0
- package/flutter_app/lib/src/android_launcher_bridge.dart +239 -0
- package/flutter_app/lib/src/app_launch_bridge.dart +29 -0
- package/flutter_app/lib/src/app_release_updater.dart +511 -0
- package/flutter_app/lib/src/backend_client.dart +1833 -0
- package/flutter_app/lib/src/desktop_companion.dart +2 -0
- package/flutter_app/lib/src/desktop_companion_actions.dart +586 -0
- package/flutter_app/lib/src/desktop_companion_io.dart +538 -0
- package/flutter_app/lib/src/desktop_companion_stub.dart +59 -0
- package/flutter_app/lib/src/desktop_native_bridge.dart +91 -0
- package/flutter_app/lib/src/desktop_screen_capture.dart +21 -0
- package/flutter_app/lib/src/desktop_screen_capture_io.dart +142 -0
- package/flutter_app/lib/src/desktop_screen_capture_stub.dart +12 -0
- package/flutter_app/lib/src/diagnostics_logger.dart +119 -0
- package/flutter_app/lib/src/health_bridge.dart +136 -0
- package/flutter_app/lib/src/live_voice_capture.dart +85 -0
- package/flutter_app/lib/src/messaging_access_summary.dart +46 -0
- package/flutter_app/lib/src/network/app_http_client.dart +53 -0
- package/flutter_app/lib/src/network/app_http_client_factory.dart +6 -0
- package/flutter_app/lib/src/network/app_http_client_io.dart +138 -0
- package/flutter_app/lib/src/network/app_http_client_stub.dart +3 -0
- package/flutter_app/lib/src/network/app_http_client_web.dart +94 -0
- package/flutter_app/lib/src/oauth_launcher.dart +33 -0
- package/flutter_app/lib/src/oauth_launcher_io.dart +77 -0
- package/flutter_app/lib/src/oauth_launcher_stub.dart +33 -0
- package/flutter_app/lib/src/oauth_launcher_web.dart +107 -0
- package/flutter_app/lib/src/recording_bridge.dart +232 -0
- package/flutter_app/lib/src/recording_bridge_io.dart +1019 -0
- package/flutter_app/lib/src/recording_bridge_stub.dart +120 -0
- package/flutter_app/lib/src/recording_bridge_web.dart +689 -0
- package/flutter_app/lib/src/recording_payloads.dart +86 -0
- package/flutter_app/lib/src/theme/palette.dart +81 -0
- package/flutter_app/lib/src/widget_bridge.dart +49 -0
- package/flutter_app/linux/CMakeLists.txt +128 -0
- package/flutter_app/linux/flutter/CMakeLists.txt +88 -0
- package/flutter_app/linux/flutter/generated_plugin_registrant.cc +43 -0
- package/flutter_app/linux/flutter/generated_plugin_registrant.h +15 -0
- package/flutter_app/linux/flutter/generated_plugins.cmake +31 -0
- package/flutter_app/linux/runner/CMakeLists.txt +26 -0
- package/flutter_app/linux/runner/main.cc +6 -0
- package/flutter_app/linux/runner/my_application.cc +144 -0
- package/flutter_app/linux/runner/my_application.h +18 -0
- package/flutter_app/linux/runner/resources/app_icon.png +0 -0
- package/flutter_app/macos/Flutter/Flutter-Debug.xcconfig +2 -0
- package/flutter_app/macos/Flutter/Flutter-Release.xcconfig +2 -0
- package/flutter_app/macos/Flutter/GeneratedPluginRegistrant.swift +40 -0
- package/flutter_app/macos/Podfile +42 -0
- package/flutter_app/macos/Podfile.lock +87 -0
- package/flutter_app/macos/Runner/AppDelegate.swift +576 -0
- package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +68 -0
- package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png +0 -0
- package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png +0 -0
- package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png +0 -0
- package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png +0 -0
- package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png +0 -0
- package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png +0 -0
- package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png +0 -0
- package/flutter_app/macos/Runner/Base.lproj/MainMenu.xib +342 -0
- package/flutter_app/macos/Runner/Configs/AppInfo.xcconfig +14 -0
- package/flutter_app/macos/Runner/Configs/Debug.xcconfig +2 -0
- package/flutter_app/macos/Runner/Configs/Release.xcconfig +2 -0
- package/flutter_app/macos/Runner/Configs/Warnings.xcconfig +13 -0
- package/flutter_app/macos/Runner/DebugProfile.entitlements +16 -0
- package/flutter_app/macos/Runner/Info.plist +36 -0
- package/flutter_app/macos/Runner/MainFlutterWindow.swift +19 -0
- package/flutter_app/macos/Runner/Release.entitlements +12 -0
- package/flutter_app/macos/Runner.xcodeproj/project.pbxproj +801 -0
- package/flutter_app/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/flutter_app/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +99 -0
- package/flutter_app/macos/Runner.xcworkspace/contents.xcworkspacedata +10 -0
- package/flutter_app/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/flutter_app/macos/RunnerTests/RunnerTests.swift +12 -0
- package/flutter_app/patch_strings.py +12 -0
- package/flutter_app/pubspec.lock +1088 -0
- package/flutter_app/pubspec.yaml +53 -0
- package/flutter_app/test/messaging_access_summary_test.dart +22 -0
- package/flutter_app/test/recording_payloads_test.dart +53 -0
- package/flutter_app/third_party/desktop_audio_capture/LICENSE +21 -0
- package/flutter_app/third_party/desktop_audio_capture/README.md +262 -0
- package/flutter_app/third_party/desktop_audio_capture/lib/audio_capture.dart +65 -0
- package/flutter_app/third_party/desktop_audio_capture/lib/config/mic_audio_config.dart +153 -0
- package/flutter_app/third_party/desktop_audio_capture/lib/config/system_adudio_config.dart +110 -0
- package/flutter_app/third_party/desktop_audio_capture/lib/mic/mic_audio_capture.dart +461 -0
- package/flutter_app/third_party/desktop_audio_capture/lib/model/audio_status.dart +91 -0
- package/flutter_app/third_party/desktop_audio_capture/lib/model/decibel_data.dart +106 -0
- package/flutter_app/third_party/desktop_audio_capture/lib/model/input_device_type.dart +219 -0
- package/flutter_app/third_party/desktop_audio_capture/lib/system/system_audio_capture.dart +336 -0
- package/flutter_app/third_party/desktop_audio_capture/linux/CMakeLists.txt +101 -0
- package/flutter_app/third_party/desktop_audio_capture/linux/audio_capture_plugin.cc +692 -0
- package/flutter_app/third_party/desktop_audio_capture/linux/include/audio_capture/audio_capture_plugin.h +35 -0
- package/flutter_app/third_party/desktop_audio_capture/linux/include/audio_capture/mic_capture_plugin.h +36 -0
- package/flutter_app/third_party/desktop_audio_capture/linux/include/desktop_audio_capture/audio_capture_plugin.h +32 -0
- package/flutter_app/third_party/desktop_audio_capture/linux/include/desktop_audio_capture/mic_capture_plugin.h +32 -0
- package/flutter_app/third_party/desktop_audio_capture/linux/mic_capture_plugin.cc +878 -0
- package/flutter_app/third_party/desktop_audio_capture/macos/Classes/AudioCapturePlugin.swift +27 -0
- package/flutter_app/third_party/desktop_audio_capture/macos/Classes/MicCapturePlugin.swift +1172 -0
- package/flutter_app/third_party/desktop_audio_capture/macos/Classes/SystemCapturePlugin.swift +655 -0
- package/flutter_app/third_party/desktop_audio_capture/macos/Resources/PrivacyInfo.xcprivacy +12 -0
- package/flutter_app/third_party/desktop_audio_capture/macos/desktop_audio_capture.podspec +30 -0
- package/flutter_app/third_party/desktop_audio_capture/pubspec.yaml +87 -0
- package/flutter_app/third_party/desktop_audio_capture/windows/CMakeLists.txt +105 -0
- package/flutter_app/third_party/desktop_audio_capture/windows/audio_capture_plugin.cpp +80 -0
- package/flutter_app/third_party/desktop_audio_capture/windows/audio_capture_plugin.h +31 -0
- package/flutter_app/third_party/desktop_audio_capture/windows/audio_capture_plugin_c_api.cpp +12 -0
- package/flutter_app/third_party/desktop_audio_capture/windows/include/audio_capture/audio_capture_plugin_c_api.h +23 -0
- package/flutter_app/third_party/desktop_audio_capture/windows/include/desktop_audio_capture/audio_capture_plugin.h +25 -0
- package/flutter_app/third_party/desktop_audio_capture/windows/mic_capture_plugin.cpp +1117 -0
- package/flutter_app/third_party/desktop_audio_capture/windows/mic_capture_plugin.h +115 -0
- package/flutter_app/third_party/desktop_audio_capture/windows/system_audio_capture_plugin.cpp +777 -0
- package/flutter_app/third_party/desktop_audio_capture/windows/system_audio_capture_plugin.h +87 -0
- package/flutter_app/third_party/flutter_secure_storage_linux/linux/CMakeLists.txt +30 -0
- package/flutter_app/third_party/flutter_secure_storage_linux/linux/flutter_secure_storage_linux_plugin.cc +215 -0
- package/flutter_app/third_party/flutter_secure_storage_linux/linux/include/flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h +27 -0
- package/flutter_app/third_party/flutter_secure_storage_linux/pubspec.yaml +20 -0
- package/flutter_app/tool/generate_desktop_branding.py +219 -0
- package/flutter_app/web/favicon.png +0 -0
- package/flutter_app/web/favicon.svg +12 -0
- package/flutter_app/web/icons/Icon-192.png +0 -0
- package/flutter_app/web/icons/Icon-512.png +0 -0
- package/flutter_app/web/icons/Icon-maskable-192.png +0 -0
- package/flutter_app/web/icons/Icon-maskable-512.png +0 -0
- package/flutter_app/web/index.html +39 -0
- package/flutter_app/web/manifest.json +35 -0
- package/flutter_app/windows/CMakeLists.txt +108 -0
- package/flutter_app/windows/flutter/CMakeLists.txt +109 -0
- package/flutter_app/windows/flutter/generated_plugin_registrant.cc +47 -0
- package/flutter_app/windows/flutter/generated_plugin_registrant.h +15 -0
- package/flutter_app/windows/flutter/generated_plugins.cmake +35 -0
- package/flutter_app/windows/runner/CMakeLists.txt +41 -0
- package/flutter_app/windows/runner/Runner.rc +121 -0
- package/flutter_app/windows/runner/flutter_window.cpp +533 -0
- package/flutter_app/windows/runner/flutter_window.h +37 -0
- package/flutter_app/windows/runner/main.cpp +53 -0
- package/flutter_app/windows/runner/resource.h +16 -0
- package/flutter_app/windows/runner/resources/app_icon.ico +0 -0
- package/flutter_app/windows/runner/runner.exe.manifest +14 -0
- package/flutter_app/windows/runner/utils.cpp +65 -0
- package/flutter_app/windows/runner/utils.h +19 -0
- package/flutter_app/windows/runner/win32_window.cpp +299 -0
- package/flutter_app/windows/runner/win32_window.h +102 -0
- package/lib/manager.js +231 -7
- package/package.json +3 -1
- package/server/db/database.js +68 -0
- package/server/http/middleware.js +50 -0
- package/server/http/routes.js +3 -1
- package/server/index.js +1 -0
- package/server/public/.last_build_id +1 -1
- package/server/public/assets/NOTICES +61 -0
- package/server/public/assets/fonts/MaterialIcons-Regular.otf +0 -0
- package/server/public/flutter_bootstrap.js +1 -1
- package/server/public/main.dart.js +65262 -64422
- package/server/routes/integrations.js +86 -0
- package/server/routes/memory.js +11 -2
- package/server/routes/screenHistory.js +46 -0
- package/server/routes/triggers.js +81 -0
- package/server/services/ai/models.js +30 -0
- package/server/services/ai/providers/githubCopilot.js +97 -0
- package/server/services/ai/providers/openai.js +2 -1
- package/server/services/ai/providers/openaiCodex.js +31 -0
- package/server/services/ai/settings.js +20 -0
- package/server/services/ai/systemPrompt.js +1 -1
- package/server/services/ai/tools.js +35 -6
- package/server/services/browser/controller.js +47 -3
- package/server/services/desktop/screenRecorder.js +172 -0
- package/server/services/integrations/env.js +5 -0
- package/server/services/integrations/github/common.js +106 -0
- package/server/services/integrations/github/provider.js +499 -0
- package/server/services/integrations/github/repos.js +1124 -0
- package/server/services/integrations/home_assistant/provider.js +306 -26
- package/server/services/integrations/manager.js +63 -7
- package/server/services/integrations/oauth_provider.js +13 -6
- package/server/services/integrations/provider_config_store.js +76 -0
- package/server/services/integrations/registry.js +4 -0
- package/server/services/integrations/trello/provider.js +744 -0
- package/server/services/integrations/whatsapp/provider.js +6 -2
- package/server/services/manager.js +22 -0
- package/server/services/memory/manager.js +39 -2
- package/server/services/skills/base_catalog.js +33 -0
- package/server/services/tasks/adapters/index.js +1 -0
- package/server/services/tasks/adapters/manual.js +12 -0
- package/server/services/tasks/runtime.js +1 -1
- package/server/services/voice/openaiClient.js +4 -1
- package/server/services/voice/providers.js +2 -1
- package/server/services/widgets/service.js +49 -4
- package/server/utils/local_secrets.js +56 -0
- package/server/utils/logger.js +37 -9
package/lib/manager.js
CHANGED
|
@@ -542,6 +542,40 @@ async function cmdSetup() {
|
|
|
542
542
|
const normalizedDeploymentMode = parseDeploymentMode(deploymentMode);
|
|
543
543
|
const normalizedReleaseChannel = parseReleaseChannel(releaseChannel) || 'stable';
|
|
544
544
|
|
|
545
|
+
const githubOauthClientId = await askSecret(
|
|
546
|
+
'GitHub OAuth client ID',
|
|
547
|
+
current.GITHUB_OAUTH_CLIENT_ID || ''
|
|
548
|
+
);
|
|
549
|
+
const githubOauthClientSecret = await askSecret(
|
|
550
|
+
'GitHub OAuth client secret',
|
|
551
|
+
current.GITHUB_OAUTH_CLIENT_SECRET || ''
|
|
552
|
+
);
|
|
553
|
+
const githubOauthRedirectUri = await ask(
|
|
554
|
+
'GitHub OAuth redirect URI',
|
|
555
|
+
current.GITHUB_OAUTH_REDIRECT_URI || ''
|
|
556
|
+
);
|
|
557
|
+
|
|
558
|
+
const homeAssistantOauthClientId = await askSecret(
|
|
559
|
+
'Home Assistant OAuth client ID',
|
|
560
|
+
current.HOME_ASSISTANT_OAUTH_CLIENT_ID || ''
|
|
561
|
+
);
|
|
562
|
+
const homeAssistantOauthClientSecret = await askSecret(
|
|
563
|
+
'Home Assistant OAuth client secret',
|
|
564
|
+
current.HOME_ASSISTANT_OAUTH_CLIENT_SECRET || ''
|
|
565
|
+
);
|
|
566
|
+
const homeAssistantOauthRedirectUri = await ask(
|
|
567
|
+
'Home Assistant OAuth redirect URI',
|
|
568
|
+
current.HOME_ASSISTANT_OAUTH_REDIRECT_URI || ''
|
|
569
|
+
);
|
|
570
|
+
const homeAssistantBaseUrl = await ask(
|
|
571
|
+
'Home Assistant base URL (e.g., https://ha.example.com)',
|
|
572
|
+
current.HOME_ASSISTANT_BASE_URL || ''
|
|
573
|
+
);
|
|
574
|
+
const homeAssistantAllowPrivateUrl = current.HOME_ASSISTANT_ALLOW_PRIVATE_BASE_URL === '1' ? 'true' : await ask(
|
|
575
|
+
'Allow local/private Home Assistant base URLs? (true/false)',
|
|
576
|
+
'false'
|
|
577
|
+
);
|
|
578
|
+
|
|
545
579
|
const lines = [
|
|
546
580
|
`NODE_ENV=production`,
|
|
547
581
|
`PORT=${port}`,
|
|
@@ -576,6 +610,14 @@ async function cmdSetup() {
|
|
|
576
610
|
figmaOauthClientId ? `FIGMA_OAUTH_CLIENT_ID=${figmaOauthClientId}` : '',
|
|
577
611
|
figmaOauthClientSecret ? `FIGMA_OAUTH_CLIENT_SECRET=${figmaOauthClientSecret}` : '',
|
|
578
612
|
figmaOauthRedirectUri ? `FIGMA_OAUTH_REDIRECT_URI=${figmaOauthRedirectUri}` : '',
|
|
613
|
+
githubOauthClientId ? `GITHUB_OAUTH_CLIENT_ID=${githubOauthClientId}` : '',
|
|
614
|
+
githubOauthClientSecret ? `GITHUB_OAUTH_CLIENT_SECRET=${githubOauthClientSecret}` : '',
|
|
615
|
+
githubOauthRedirectUri ? `GITHUB_OAUTH_REDIRECT_URI=${githubOauthRedirectUri}` : '',
|
|
616
|
+
homeAssistantOauthClientId ? `HOME_ASSISTANT_OAUTH_CLIENT_ID=${homeAssistantOauthClientId}` : '',
|
|
617
|
+
homeAssistantOauthClientSecret ? `HOME_ASSISTANT_OAUTH_CLIENT_SECRET=${homeAssistantOauthClientSecret}` : '',
|
|
618
|
+
homeAssistantOauthRedirectUri ? `HOME_ASSISTANT_OAUTH_REDIRECT_URI=${homeAssistantOauthRedirectUri}` : '',
|
|
619
|
+
homeAssistantBaseUrl ? `HOME_ASSISTANT_BASE_URL=${homeAssistantBaseUrl}` : '',
|
|
620
|
+
String(homeAssistantAllowPrivateUrl || '').trim().toLowerCase() === 'true' ? `HOME_ASSISTANT_ALLOW_PRIVATE_BASE_URL=1` : '',
|
|
579
621
|
deepgramApiKey ? `DEEPGRAM_API_KEY=${deepgramApiKey}` : '',
|
|
580
622
|
deepgramBaseUrl ? `DEEPGRAM_BASE_URL=${deepgramBaseUrl}` : '',
|
|
581
623
|
deepgramModel ? `DEEPGRAM_MODEL=${deepgramModel}` : '',
|
|
@@ -674,6 +716,172 @@ async function cmdMigrate(args = []) {
|
|
|
674
716
|
});
|
|
675
717
|
}
|
|
676
718
|
|
|
719
|
+
async function cmdLogin(args = []) {
|
|
720
|
+
const provider = args[0];
|
|
721
|
+
if (provider !== 'github-copilot' && provider !== 'openai-codex') {
|
|
722
|
+
throw new Error(`Unsupported login provider: ${provider || 'none'}. Available: github-copilot, openai-codex`);
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
if (provider === 'github-copilot') {
|
|
726
|
+
heading('GitHub Copilot Login');
|
|
727
|
+
const clientId = '01ab8ac9400c4e429b23';
|
|
728
|
+
logInfo('Requesting device code from GitHub...');
|
|
729
|
+
|
|
730
|
+
const reqRes = await fetch('https://github.com/login/device/code', {
|
|
731
|
+
method: 'POST',
|
|
732
|
+
headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
|
|
733
|
+
body: JSON.stringify({ client_id: clientId, scope: 'user:email' })
|
|
734
|
+
});
|
|
735
|
+
|
|
736
|
+
if (!reqRes.ok) {
|
|
737
|
+
throw new Error(`Failed to request device code: HTTP ${reqRes.status}`);
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
const { device_code, user_code, verification_uri, interval } = await reqRes.json();
|
|
741
|
+
|
|
742
|
+
console.log(`\n ${COLORS.cyan}Please visit:${COLORS.reset} ${verification_uri}`);
|
|
743
|
+
console.log(` ${COLORS.cyan}And enter the code:${COLORS.reset} ${COLORS.bold}${user_code}${COLORS.reset}\n`);
|
|
744
|
+
|
|
745
|
+
logInfo('Waiting for authorization (timeout in 15m)...');
|
|
746
|
+
const startTime = Date.now();
|
|
747
|
+
const timeoutMs = 15 * 60 * 1000;
|
|
748
|
+
let currentPollInterval = (interval || 5) * 1000;
|
|
749
|
+
|
|
750
|
+
while (Date.now() - startTime < timeoutMs) {
|
|
751
|
+
await new Promise((r) => setTimeout(r, currentPollInterval));
|
|
752
|
+
const tokenRes = await fetch('https://github.com/login/oauth/access_token', {
|
|
753
|
+
method: 'POST',
|
|
754
|
+
headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
|
|
755
|
+
body: JSON.stringify({
|
|
756
|
+
client_id: clientId,
|
|
757
|
+
device_code,
|
|
758
|
+
grant_type: 'urn:ietf:params:oauth:grant-type:device_code'
|
|
759
|
+
})
|
|
760
|
+
});
|
|
761
|
+
|
|
762
|
+
if (!tokenRes.ok) {
|
|
763
|
+
const errorText = await tokenRes.text().catch(() => 'Unknown error');
|
|
764
|
+
throw new Error(`GitHub token request failed: HTTP ${tokenRes.status} - ${errorText}`);
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
const data = await tokenRes.json();
|
|
768
|
+
if (data.access_token) {
|
|
769
|
+
upsertEnvValue('GITHUB_COPILOT_ACCESS_TOKEN', data.access_token);
|
|
770
|
+
logOk('Successfully authenticated and saved GitHub Copilot access token to .env');
|
|
771
|
+
logInfo('Applying updated provider credentials by restarting NeoAgent...');
|
|
772
|
+
cmdRestart();
|
|
773
|
+
return;
|
|
774
|
+
} else if (data.error === 'authorization_pending') {
|
|
775
|
+
// Continue polling
|
|
776
|
+
} else if (data.error === 'slow_down') {
|
|
777
|
+
currentPollInterval += 5000;
|
|
778
|
+
} else if (data.error) {
|
|
779
|
+
throw new Error(`Authentication failed: ${data.error_description || data.error}`);
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
throw new Error('GitHub authentication timed out after 15 minutes.');
|
|
783
|
+
} else if (provider === 'openai-codex') {
|
|
784
|
+
heading('OpenAI Codex Login');
|
|
785
|
+
const clientId = 'app_EMoamEEZ73f0CkXaXp7hrann';
|
|
786
|
+
logInfo('Requesting device code from OpenAI...');
|
|
787
|
+
|
|
788
|
+
const reqRes = await fetch('https://auth.openai.com/api/accounts/deviceauth/usercode', {
|
|
789
|
+
method: 'POST',
|
|
790
|
+
headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
|
|
791
|
+
body: JSON.stringify({ client_id: clientId, scope: 'openid profile email offline_access model.request model.read model.create' })
|
|
792
|
+
});
|
|
793
|
+
|
|
794
|
+
if (!reqRes.ok) {
|
|
795
|
+
throw new Error(`Failed to request device code: HTTP ${reqRes.status}`);
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
const data = await reqRes.json();
|
|
799
|
+
const { device_auth_id, interval } = data;
|
|
800
|
+
const user_code = data.user_code || data.usercode;
|
|
801
|
+
const verification_uri = 'https://auth.openai.com/codex/device';
|
|
802
|
+
|
|
803
|
+
console.log(`\n ${COLORS.cyan}Please visit:${COLORS.reset} ${verification_uri}`);
|
|
804
|
+
console.log(` ${COLORS.cyan}And enter the code:${COLORS.reset} ${COLORS.bold}${user_code}${COLORS.reset}\n`);
|
|
805
|
+
|
|
806
|
+
logInfo('Waiting for authorization (timeout in 15m)...');
|
|
807
|
+
const startTime = Date.now();
|
|
808
|
+
const timeoutMs = 15 * 60 * 1000;
|
|
809
|
+
let currentPollInterval = (interval || 5) * 1000;
|
|
810
|
+
let authorizationCode = null;
|
|
811
|
+
let codeVerifier = null;
|
|
812
|
+
|
|
813
|
+
while (Date.now() - startTime < timeoutMs) {
|
|
814
|
+
await new Promise((r) => setTimeout(r, currentPollInterval));
|
|
815
|
+
const tokenRes = await fetch('https://auth.openai.com/api/accounts/deviceauth/token', {
|
|
816
|
+
method: 'POST',
|
|
817
|
+
headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' },
|
|
818
|
+
body: JSON.stringify({
|
|
819
|
+
device_auth_id: device_auth_id,
|
|
820
|
+
user_code: user_code
|
|
821
|
+
})
|
|
822
|
+
});
|
|
823
|
+
|
|
824
|
+
if (tokenRes.status === 403 || tokenRes.status === 404) {
|
|
825
|
+
// These statuses are returned by OpenAI while authorization is pending
|
|
826
|
+
continue;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
if (!tokenRes.ok) {
|
|
830
|
+
const errorText = await tokenRes.text().catch(() => 'Unknown error');
|
|
831
|
+
throw new Error(`OpenAI token request failed: HTTP ${tokenRes.status} - ${errorText}`);
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
const pollData = await tokenRes.json();
|
|
835
|
+
if (pollData.authorization_code && pollData.code_verifier) {
|
|
836
|
+
authorizationCode = pollData.authorization_code;
|
|
837
|
+
codeVerifier = pollData.code_verifier;
|
|
838
|
+
break;
|
|
839
|
+
} else if (pollData.error === 'authorization_pending') {
|
|
840
|
+
// Continue polling
|
|
841
|
+
} else if (pollData.error === 'slow_down') {
|
|
842
|
+
currentPollInterval += 5000;
|
|
843
|
+
} else if (pollData.error) {
|
|
844
|
+
throw new Error(`Authentication failed: ${pollData.error_description || pollData.error}`);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
if (!authorizationCode || !codeVerifier) {
|
|
849
|
+
throw new Error('OpenAI authentication timed out after 15 minutes.');
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
logInfo('Exchanging authorization code for access token...');
|
|
853
|
+
const exchangeRes = await fetch('https://auth.openai.com/oauth/token', {
|
|
854
|
+
method: 'POST',
|
|
855
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
856
|
+
body: new URLSearchParams({
|
|
857
|
+
grant_type: 'authorization_code',
|
|
858
|
+
code: authorizationCode,
|
|
859
|
+
redirect_uri: 'https://auth.openai.com/deviceauth/callback',
|
|
860
|
+
client_id: clientId,
|
|
861
|
+
code_verifier: codeVerifier
|
|
862
|
+
})
|
|
863
|
+
});
|
|
864
|
+
|
|
865
|
+
if (!exchangeRes.ok) {
|
|
866
|
+
const errorText = await exchangeRes.text().catch(() => 'Unknown error');
|
|
867
|
+
throw new Error(`OpenAI token exchange failed: HTTP ${exchangeRes.status} - ${errorText}`);
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
const exchangeData = await exchangeRes.json();
|
|
871
|
+
if (exchangeData.access_token) {
|
|
872
|
+
upsertEnvValue('OPENAI_CODEX_ACCESS_TOKEN', exchangeData.access_token);
|
|
873
|
+
if (exchangeData.refresh_token) {
|
|
874
|
+
upsertEnvValue('OPENAI_CODEX_REFRESH_TOKEN', exchangeData.refresh_token);
|
|
875
|
+
}
|
|
876
|
+
logOk('Successfully authenticated and saved OpenAI Codex tokens to .env');
|
|
877
|
+
logInfo('Applying updated provider credentials by restarting NeoAgent...');
|
|
878
|
+
cmdRestart();
|
|
879
|
+
} else {
|
|
880
|
+
throw new Error('OpenAI token exchange succeeded but did not return an access token.');
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
|
|
677
885
|
function installDependencies() {
|
|
678
886
|
heading('Dependencies');
|
|
679
887
|
runOrThrow('npm', ['install', '--omit=dev', '--no-audit', '--no-fund'], {
|
|
@@ -864,7 +1072,15 @@ function cmdRestart() {
|
|
|
864
1072
|
heading(`Restart ${APP_NAME}`);
|
|
865
1073
|
buildBundledWebClientIfPossible();
|
|
866
1074
|
cmdStop();
|
|
867
|
-
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
async function cmdRebuildWeb() {
|
|
1078
|
+
heading(`Rebuild Flutter Web Client`);
|
|
1079
|
+
if (fs.existsSync(WEB_CLIENT_DIR)) {
|
|
1080
|
+
fs.rmSync(WEB_CLIENT_DIR, { recursive: true, force: true });
|
|
1081
|
+
logOk('Removed old web client build');
|
|
1082
|
+
}
|
|
1083
|
+
buildBundledWebClientIfPossible();
|
|
868
1084
|
}
|
|
869
1085
|
|
|
870
1086
|
function cmdUninstall() {
|
|
@@ -962,6 +1178,8 @@ function cmdUpdate(args = []) {
|
|
|
962
1178
|
}
|
|
963
1179
|
const versionBefore = currentInstalledVersionLabel();
|
|
964
1180
|
let versionAfter = versionBefore;
|
|
1181
|
+
const githubInstallRef = releaseChannel === 'beta' ? '#beta' : '';
|
|
1182
|
+
const githubInstallSpec = `git+https://github.com/NeoLabs-Systems/NeoAgent.git${githubInstallRef}`;
|
|
965
1183
|
|
|
966
1184
|
if (fs.existsSync(path.join(APP_DIR, '.git')) && commandExists('git')) {
|
|
967
1185
|
const current = runQuiet('git', ['rev-parse', '--short', 'HEAD']);
|
|
@@ -982,17 +1200,16 @@ function cmdUpdate(args = []) {
|
|
|
982
1200
|
buildBundledWebClientIfPossible();
|
|
983
1201
|
}
|
|
984
1202
|
} else {
|
|
985
|
-
|
|
986
|
-
logWarn(`No git repo detected; attempting npm global update from ${npmTag}.`);
|
|
1203
|
+
logWarn(`No git repo detected; attempting npm global update from ${githubInstallSpec}.`);
|
|
987
1204
|
if (commandExists('npm')) {
|
|
988
1205
|
try {
|
|
989
1206
|
backupRuntimeData();
|
|
990
|
-
runOrThrow('npm', ['install', '-g',
|
|
1207
|
+
runOrThrow('npm', ['install', '-g', githubInstallSpec, '--force'], {
|
|
991
1208
|
env: withInstallEnv()
|
|
992
1209
|
});
|
|
993
|
-
logOk('npm global update completed (forced reinstall)');
|
|
1210
|
+
logOk('npm global update completed (forced reinstall from GitHub)');
|
|
994
1211
|
} catch {
|
|
995
|
-
logWarn(`npm global update failed. Run: npm install -g
|
|
1212
|
+
logWarn(`npm global update failed. Run: npm install -g ${githubInstallSpec} --force`);
|
|
996
1213
|
}
|
|
997
1214
|
} else {
|
|
998
1215
|
logWarn('npm not found. Cannot perform global update.');
|
|
@@ -1062,7 +1279,8 @@ async function cmdEnv(args = []) {
|
|
|
1062
1279
|
function printHelp() {
|
|
1063
1280
|
console.log(`${APP_NAME} manager`);
|
|
1064
1281
|
console.log('Usage: neoagent <command>');
|
|
1065
|
-
console.log('Commands: install | setup | env | channel | update | restart | start | stop | status | logs | uninstall | migrate');
|
|
1282
|
+
console.log('Commands: install | setup | env | channel | update | restart | rebuild-web | start | stop | status | logs | uninstall | migrate | login');
|
|
1283
|
+
console.log('Login usage: neoagent login github-copilot | neoagent login openai-codex');
|
|
1066
1284
|
console.log('Channel usage: neoagent channel | neoagent channel stable | neoagent channel beta');
|
|
1067
1285
|
console.log('Update usage: neoagent update | neoagent update stable | neoagent update beta');
|
|
1068
1286
|
console.log('Env usage: neoagent env list | neoagent env get PORT | neoagent env set PORT 3333 | neoagent env unset PORT');
|
|
@@ -1094,6 +1312,9 @@ async function runCLI(argv) {
|
|
|
1094
1312
|
case 'restart':
|
|
1095
1313
|
cmdRestart();
|
|
1096
1314
|
break;
|
|
1315
|
+
case 'rebuild-web':
|
|
1316
|
+
await cmdRebuildWeb();
|
|
1317
|
+
break;
|
|
1097
1318
|
case 'start':
|
|
1098
1319
|
cmdStart();
|
|
1099
1320
|
break;
|
|
@@ -1112,6 +1333,9 @@ async function runCLI(argv) {
|
|
|
1112
1333
|
case 'migrate':
|
|
1113
1334
|
await cmdMigrate(argv.slice(1));
|
|
1114
1335
|
break;
|
|
1336
|
+
case 'login':
|
|
1337
|
+
await cmdLogin(argv.slice(1));
|
|
1338
|
+
break;
|
|
1115
1339
|
case 'help':
|
|
1116
1340
|
case '--help':
|
|
1117
1341
|
case '-h':
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "neoagent",
|
|
3
|
-
"version": "2.3.1-beta.
|
|
3
|
+
"version": "2.3.1-beta.21",
|
|
4
4
|
"description": "Proactive personal AI agent with no limits",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "server/index.js",
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"runtime",
|
|
17
17
|
"server",
|
|
18
18
|
"extensions",
|
|
19
|
+
"flutter_app",
|
|
19
20
|
"docs",
|
|
20
21
|
"com.neoagent.plist",
|
|
21
22
|
"LICENSE",
|
|
@@ -80,6 +81,7 @@
|
|
|
80
81
|
"socket.io": "^4.8.1",
|
|
81
82
|
"telegraf": "^4.16.3",
|
|
82
83
|
"telnyx": "^5.51.0",
|
|
84
|
+
"tesseract.js": "^7.0.0",
|
|
83
85
|
"uuid": "^11.1.0",
|
|
84
86
|
"ws": "^8.19.0"
|
|
85
87
|
},
|
package/server/db/database.js
CHANGED
|
@@ -272,6 +272,17 @@ db.exec(`
|
|
|
272
272
|
FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE SET NULL
|
|
273
273
|
);
|
|
274
274
|
|
|
275
|
+
CREATE TABLE IF NOT EXISTS integration_provider_configs (
|
|
276
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
277
|
+
user_id INTEGER NOT NULL,
|
|
278
|
+
provider_key TEXT NOT NULL,
|
|
279
|
+
config_json TEXT DEFAULT '{}',
|
|
280
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
281
|
+
updated_at TEXT DEFAULT (datetime('now')),
|
|
282
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
|
283
|
+
UNIQUE(user_id, provider_key)
|
|
284
|
+
);
|
|
285
|
+
|
|
275
286
|
CREATE TABLE IF NOT EXISTS browser_extension_pairing_requests (
|
|
276
287
|
id TEXT PRIMARY KEY,
|
|
277
288
|
user_id INTEGER,
|
|
@@ -651,6 +662,40 @@ db.exec(`
|
|
|
651
662
|
CREATE INDEX IF NOT EXISTS idx_recording_chunks_source ON recording_chunks(source_id, sequence_index);
|
|
652
663
|
CREATE INDEX IF NOT EXISTS idx_recording_segments_session ON recording_transcript_segments(session_id, start_ms, created_at);
|
|
653
664
|
|
|
665
|
+
CREATE TABLE IF NOT EXISTS screen_history (
|
|
666
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
667
|
+
user_id INTEGER NOT NULL,
|
|
668
|
+
timestamp TEXT DEFAULT (datetime('now')),
|
|
669
|
+
app_name TEXT,
|
|
670
|
+
text_content TEXT,
|
|
671
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
672
|
+
);
|
|
673
|
+
|
|
674
|
+
CREATE TABLE IF NOT EXISTS notification_history (
|
|
675
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
676
|
+
user_id INTEGER NOT NULL,
|
|
677
|
+
app_package TEXT,
|
|
678
|
+
title TEXT,
|
|
679
|
+
body TEXT,
|
|
680
|
+
timestamp TEXT DEFAULT (datetime('now')),
|
|
681
|
+
action_taken TEXT,
|
|
682
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
683
|
+
);
|
|
684
|
+
|
|
685
|
+
CREATE TABLE IF NOT EXISTS geofences (
|
|
686
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
687
|
+
user_id INTEGER NOT NULL,
|
|
688
|
+
label TEXT,
|
|
689
|
+
latitude REAL NOT NULL,
|
|
690
|
+
longitude REAL NOT NULL,
|
|
691
|
+
radius_meters INTEGER NOT NULL,
|
|
692
|
+
trigger_action TEXT,
|
|
693
|
+
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
|
694
|
+
);
|
|
695
|
+
|
|
696
|
+
CREATE INDEX IF NOT EXISTS idx_screen_history_user ON screen_history(user_id, timestamp DESC);
|
|
697
|
+
CREATE INDEX IF NOT EXISTS idx_notification_history_user ON notification_history(user_id, timestamp DESC);
|
|
698
|
+
|
|
654
699
|
CREATE TABLE IF NOT EXISTS artifacts (
|
|
655
700
|
id TEXT PRIMARY KEY,
|
|
656
701
|
user_id INTEGER NOT NULL,
|
|
@@ -676,6 +721,29 @@ db.exec(`
|
|
|
676
721
|
|
|
677
722
|
try {
|
|
678
723
|
db.exec(`
|
|
724
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS screen_history_fts USING fts5(
|
|
725
|
+
text_content,
|
|
726
|
+
app_name,
|
|
727
|
+
timestamp UNINDEXED,
|
|
728
|
+
user_id UNINDEXED,
|
|
729
|
+
tokenize = 'porter unicode61'
|
|
730
|
+
);
|
|
731
|
+
|
|
732
|
+
CREATE TRIGGER IF NOT EXISTS screen_history_fts_ai AFTER INSERT ON screen_history BEGIN
|
|
733
|
+
INSERT INTO screen_history_fts(rowid, text_content, app_name, timestamp, user_id)
|
|
734
|
+
VALUES (new.id, COALESCE(new.text_content, ''), COALESCE(new.app_name, ''), new.timestamp, new.user_id);
|
|
735
|
+
END;
|
|
736
|
+
|
|
737
|
+
CREATE TRIGGER IF NOT EXISTS screen_history_fts_ad AFTER DELETE ON screen_history BEGIN
|
|
738
|
+
DELETE FROM screen_history_fts WHERE rowid = old.id;
|
|
739
|
+
END;
|
|
740
|
+
|
|
741
|
+
CREATE TRIGGER IF NOT EXISTS screen_history_fts_au AFTER UPDATE ON screen_history BEGIN
|
|
742
|
+
DELETE FROM screen_history_fts WHERE rowid = old.id;
|
|
743
|
+
INSERT INTO screen_history_fts(rowid, text_content, app_name, timestamp, user_id)
|
|
744
|
+
VALUES (new.id, COALESCE(new.text_content, ''), COALESCE(new.app_name, ''), new.timestamp, new.user_id);
|
|
745
|
+
END;
|
|
746
|
+
|
|
679
747
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversation_history_fts USING fts5(
|
|
680
748
|
content,
|
|
681
749
|
role UNINDEXED,
|
|
@@ -88,7 +88,18 @@ function buildHelmetOptions({ secureCookies }) {
|
|
|
88
88
|
return {
|
|
89
89
|
strictTransportSecurity: false,
|
|
90
90
|
crossOriginOpenerPolicy: false,
|
|
91
|
+
crossOriginResourcePolicy: { policy: 'same-site' },
|
|
91
92
|
originAgentCluster: false,
|
|
93
|
+
referrerPolicy: { policy: 'strict-origin-when-cross-origin' },
|
|
94
|
+
permissionsPolicy: {
|
|
95
|
+
features: {
|
|
96
|
+
camera: ['self'],
|
|
97
|
+
geolocation: ['self'],
|
|
98
|
+
microphone: ['self'],
|
|
99
|
+
payment: [],
|
|
100
|
+
usb: [],
|
|
101
|
+
},
|
|
102
|
+
},
|
|
92
103
|
contentSecurityPolicy: {
|
|
93
104
|
directives: {
|
|
94
105
|
defaultSrc: ["'self'"],
|
|
@@ -154,6 +165,16 @@ function applyHttpMiddleware(app, { secureCookies, trustProxy, sessionMiddleware
|
|
|
154
165
|
const path = `${value}`.split('?')[0];
|
|
155
166
|
return path === '/socket.io/' || path === '/socket.io' || path.startsWith('/socket.io/');
|
|
156
167
|
};
|
|
168
|
+
const isStateChangingMethod = (method = '') => ['POST', 'PUT', 'PATCH', 'DELETE'].includes(String(method).toUpperCase());
|
|
169
|
+
const extractOriginFromReferer = (referer = '') => {
|
|
170
|
+
const value = String(referer || '').trim();
|
|
171
|
+
if (!value) return '';
|
|
172
|
+
try {
|
|
173
|
+
return new URL(value).origin;
|
|
174
|
+
} catch {
|
|
175
|
+
return '';
|
|
176
|
+
}
|
|
177
|
+
};
|
|
157
178
|
const requestPath = (req) => req.originalUrl || req.url || req.path || '';
|
|
158
179
|
const applyOnlyToRecordingChunk = (handler) => (req, res, next) => (
|
|
159
180
|
isRecordingChunkPath(requestPath(req)) ? handler(req, res, next) : next()
|
|
@@ -187,6 +208,35 @@ function applyHttpMiddleware(app, { secureCookies, trustProxy, sessionMiddleware
|
|
|
187
208
|
});
|
|
188
209
|
})
|
|
189
210
|
);
|
|
211
|
+
app.use((req, res, next) => {
|
|
212
|
+
const path = `${req.originalUrl || req.url || req.path || ''}`.split('?')[0];
|
|
213
|
+
if (path.startsWith('/api/')) {
|
|
214
|
+
res.setHeader('Cache-Control', 'no-store, max-age=0');
|
|
215
|
+
res.setHeader('Pragma', 'no-cache');
|
|
216
|
+
res.setHeader('Expires', '0');
|
|
217
|
+
}
|
|
218
|
+
next();
|
|
219
|
+
});
|
|
220
|
+
app.use((req, res, next) => {
|
|
221
|
+
const path = `${req.originalUrl || req.url || req.path || ''}`.split('?')[0];
|
|
222
|
+
if (!path.startsWith('/api/')) return next();
|
|
223
|
+
if (!isStateChangingMethod(req.method)) return next();
|
|
224
|
+
|
|
225
|
+
const origin = String(req.get('origin') || '').trim() || extractOriginFromReferer(req.get('referer'));
|
|
226
|
+
if (!origin) return next();
|
|
227
|
+
|
|
228
|
+
const allowBrowserExtensionOrigin = isBrowserExtensionCorsPath(path);
|
|
229
|
+
return validateOrigin(origin, (error) => {
|
|
230
|
+
if (error) {
|
|
231
|
+
logRequestSummary('warn', req, 'blocked state-changing request due to invalid origin', { origin });
|
|
232
|
+
return res.status(403).json({ error: 'Origin not allowed' });
|
|
233
|
+
}
|
|
234
|
+
return next();
|
|
235
|
+
}, {
|
|
236
|
+
allowChromeExtension: allowBrowserExtensionOrigin,
|
|
237
|
+
allowMissingOrigin: false,
|
|
238
|
+
});
|
|
239
|
+
});
|
|
190
240
|
app.use((req, res, next) => {
|
|
191
241
|
const startedAt = Date.now();
|
|
192
242
|
|
package/server/http/routes.js
CHANGED
|
@@ -26,7 +26,9 @@ const routeRegistry = [
|
|
|
26
26
|
{ basePath: '/api/desktop', modulePath: '../routes/desktop' },
|
|
27
27
|
{ basePath: '/api/recordings', modulePath: '../routes/recordings' },
|
|
28
28
|
{ basePath: '/api/voice-assistant', modulePath: '../routes/voice_assistant' },
|
|
29
|
-
{ basePath: '/api/mobile/health', modulePath: '../routes/mobile-health' }
|
|
29
|
+
{ basePath: '/api/mobile/health', modulePath: '../routes/mobile-health' },
|
|
30
|
+
{ basePath: '/api/screen-history', modulePath: '../routes/screenHistory' },
|
|
31
|
+
{ basePath: '/api/triggers', modulePath: '../routes/triggers' }
|
|
30
32
|
];
|
|
31
33
|
|
|
32
34
|
function registerApiRoutes(app) {
|
package/server/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
6a766d17dbfd039c552814519add74f6
|
|
@@ -5535,6 +5535,19 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
5535
5535
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
5536
5536
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
5537
5537
|
--------------------------------------------------------------------------------
|
|
5538
|
+
flutter_background_service
|
|
5539
|
+
flutter_background_service_android
|
|
5540
|
+
flutter_background_service_ios
|
|
5541
|
+
flutter_background_service_platform_interface
|
|
5542
|
+
|
|
5543
|
+
Copyright 2022 Eka Setiawan Saputra
|
|
5544
|
+
|
|
5545
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
5546
|
+
|
|
5547
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
5548
|
+
|
|
5549
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
5550
|
+
--------------------------------------------------------------------------------
|
|
5538
5551
|
flutter_lints
|
|
5539
5552
|
flutter_markdown
|
|
5540
5553
|
path_provider
|
|
@@ -7093,6 +7106,35 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
7093
7106
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
7094
7107
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
7095
7108
|
--------------------------------------------------------------------------------
|
|
7109
|
+
geolocator
|
|
7110
|
+
geolocator_android
|
|
7111
|
+
geolocator_apple
|
|
7112
|
+
geolocator_platform_interface
|
|
7113
|
+
geolocator_web
|
|
7114
|
+
geolocator_windows
|
|
7115
|
+
|
|
7116
|
+
MIT License
|
|
7117
|
+
|
|
7118
|
+
Copyright (c) 2018 Baseflow
|
|
7119
|
+
|
|
7120
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7121
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7122
|
+
in the Software without restriction, including without limitation the rights
|
|
7123
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7124
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
7125
|
+
furnished to do so, subject to the following conditions:
|
|
7126
|
+
|
|
7127
|
+
The above copyright notice and this permission notice shall be included in all
|
|
7128
|
+
copies or substantial portions of the Software.
|
|
7129
|
+
|
|
7130
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
7131
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
7132
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
7133
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
7134
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
7135
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
7136
|
+
SOFTWARE.
|
|
7137
|
+
--------------------------------------------------------------------------------
|
|
7096
7138
|
glfw
|
|
7097
7139
|
|
|
7098
7140
|
|
|
@@ -24797,6 +24839,25 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
24797
24839
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
24798
24840
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
24799
24841
|
--------------------------------------------------------------------------------
|
|
24842
|
+
notification_listener_service
|
|
24843
|
+
|
|
24844
|
+
Copyright (c) 2022 Iheb Briki
|
|
24845
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
24846
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
24847
|
+
in the Software without restriction, including without limitation the rights
|
|
24848
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
24849
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
24850
|
+
furnished to do so, subject to the following conditions:
|
|
24851
|
+
The above copyright notice and this permission notice shall be included in all
|
|
24852
|
+
copies or substantial portions of the Software.
|
|
24853
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
24854
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24855
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24856
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24857
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
24858
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
24859
|
+
SOFTWARE.
|
|
24860
|
+
--------------------------------------------------------------------------------
|
|
24800
24861
|
perfetto
|
|
24801
24862
|
|
|
24802
24863
|
Apache License
|
|
Binary file
|
|
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"59aa584fdf100e6c78c785d8a5b565d1de4b48
|
|
|
37
37
|
|
|
38
38
|
_flutter.loader.load({
|
|
39
39
|
serviceWorkerSettings: {
|
|
40
|
-
serviceWorkerVersion: "
|
|
40
|
+
serviceWorkerVersion: "61545030" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
|
|
41
41
|
}
|
|
42
42
|
});
|