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
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<resources>
|
|
3
|
+
<string name="app_name">NeoAgent</string>
|
|
4
|
+
<string name="widget_description">NeoAgent AI Widget</string>
|
|
5
|
+
<string name="widget_config_title">Choose AI Widget</string>
|
|
6
|
+
<string name="widget_config_empty_state">No synced widgets are available yet. Open NeoAgent and refresh widgets first.</string>
|
|
7
|
+
<string name="voice_widget_description">NeoAgent voice assistant widget</string>
|
|
8
|
+
<string name="voice_widget_title">Voice Mode</string>
|
|
9
|
+
<string name="voice_widget_subtitle">Open the voice assistant</string>
|
|
10
|
+
<string name="widget_tasks_label">Tasks</string>
|
|
11
|
+
<string name="task_run_now">Run Now</string>
|
|
12
|
+
</resources>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<resources>
|
|
3
|
+
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
|
|
4
|
+
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
|
5
|
+
<!-- Show a splash screen on the activity. Automatically removed when
|
|
6
|
+
the Flutter engine draws its first frame -->
|
|
7
|
+
<item name="android:windowBackground">@drawable/launch_background</item>
|
|
8
|
+
</style>
|
|
9
|
+
<!-- Theme applied to the Android Window as soon as the process has started.
|
|
10
|
+
This theme determines the color of the Android Window while your
|
|
11
|
+
Flutter UI initializes, as well as behind your Flutter UI while its
|
|
12
|
+
running.
|
|
13
|
+
|
|
14
|
+
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
|
15
|
+
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
|
16
|
+
<item name="android:windowBackground">?android:colorBackground</item>
|
|
17
|
+
</style>
|
|
18
|
+
</resources>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<resources>
|
|
3
|
+
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
|
|
4
|
+
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
|
5
|
+
<!-- Show a splash screen on the activity. Automatically removed when
|
|
6
|
+
the Flutter engine draws its first frame -->
|
|
7
|
+
<item name="android:windowBackground">@drawable/launch_background</item>
|
|
8
|
+
</style>
|
|
9
|
+
<!-- Theme applied to the Android Window as soon as the process has started.
|
|
10
|
+
This theme determines the color of the Android Window while your
|
|
11
|
+
Flutter UI initializes, as well as behind your Flutter UI while its
|
|
12
|
+
running.
|
|
13
|
+
|
|
14
|
+
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
|
15
|
+
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
|
|
16
|
+
<item name="android:windowBackground">?android:colorBackground</item>
|
|
17
|
+
</style>
|
|
18
|
+
</resources>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
|
3
|
+
android:configure="com.neoagent.flutter_app.widgets.WidgetConfigActivity"
|
|
4
|
+
android:initialLayout="@layout/neoagent_ai_widget"
|
|
5
|
+
android:minHeight="120dp"
|
|
6
|
+
android:minWidth="220dp"
|
|
7
|
+
android:previewLayout="@layout/neoagent_ai_widget"
|
|
8
|
+
android:resizeMode="horizontal|vertical"
|
|
9
|
+
android:targetCellHeight="2"
|
|
10
|
+
android:targetCellWidth="3"
|
|
11
|
+
android:updatePeriodMillis="0"
|
|
12
|
+
android:widgetCategory="home_screen" />
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
|
3
|
+
android:description="@string/voice_widget_description"
|
|
4
|
+
android:initialLayout="@layout/neoagent_voice_widget"
|
|
5
|
+
android:minHeight="72dp"
|
|
6
|
+
android:minWidth="180dp"
|
|
7
|
+
android:previewLayout="@layout/neoagent_voice_widget"
|
|
8
|
+
android:resizeMode="horizontal|vertical"
|
|
9
|
+
android:targetCellHeight="1"
|
|
10
|
+
android:targetCellWidth="2"
|
|
11
|
+
android:updatePeriodMillis="0"
|
|
12
|
+
android:widgetCategory="home_screen" />
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
2
|
+
<!-- The INTERNET permission is required for development. Specifically,
|
|
3
|
+
the Flutter tool needs it to communicate with the running application
|
|
4
|
+
to allow setting breakpoints, to provide hot reload, etc.
|
|
5
|
+
-->
|
|
6
|
+
<uses-permission android:name="android.permission.INTERNET"/>
|
|
7
|
+
</manifest>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
allprojects {
|
|
2
|
+
repositories {
|
|
3
|
+
google()
|
|
4
|
+
mavenCentral()
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
val newBuildDir: Directory =
|
|
9
|
+
rootProject.layout.buildDirectory
|
|
10
|
+
.dir("../../build")
|
|
11
|
+
.get()
|
|
12
|
+
rootProject.layout.buildDirectory.value(newBuildDir)
|
|
13
|
+
|
|
14
|
+
subprojects {
|
|
15
|
+
val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
|
|
16
|
+
project.layout.buildDirectory.value(newSubprojectBuildDir)
|
|
17
|
+
}
|
|
18
|
+
subprojects {
|
|
19
|
+
project.evaluationDependsOn(":app")
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
tasks.register<Delete>("clean") {
|
|
23
|
+
delete(rootProject.layout.buildDirectory)
|
|
24
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
pluginManagement {
|
|
2
|
+
val flutterSdkPath =
|
|
3
|
+
run {
|
|
4
|
+
val properties = java.util.Properties()
|
|
5
|
+
file("local.properties").inputStream().use { properties.load(it) }
|
|
6
|
+
val flutterSdkPath = properties.getProperty("flutter.sdk")
|
|
7
|
+
require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
|
|
8
|
+
flutterSdkPath
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
|
|
12
|
+
|
|
13
|
+
repositories {
|
|
14
|
+
google()
|
|
15
|
+
mavenCentral()
|
|
16
|
+
gradlePluginPortal()
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
plugins {
|
|
21
|
+
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
|
|
22
|
+
id("com.android.application") version "8.9.1" apply false
|
|
23
|
+
id("org.jetbrains.kotlin.android") version "2.1.0" apply false
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
include(":app")
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import 'dart:convert';
|
|
2
|
+
import 'package:flutter/material.dart';
|
|
3
|
+
import 'package:geolocator/geolocator.dart';
|
|
4
|
+
import 'package:http/http.dart' as http;
|
|
5
|
+
import 'package:shared_preferences/shared_preferences.dart';
|
|
6
|
+
|
|
7
|
+
class LocationService {
|
|
8
|
+
static final LocationService _instance = LocationService._internal();
|
|
9
|
+
factory LocationService() => _instance;
|
|
10
|
+
LocationService._internal();
|
|
11
|
+
|
|
12
|
+
bool _isTracking = false;
|
|
13
|
+
|
|
14
|
+
Future<void> initialize(BuildContext context) async {
|
|
15
|
+
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
|
|
16
|
+
if (!serviceEnabled) {
|
|
17
|
+
// Location services are not enabled don't continue
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
LocationPermission permission = await Geolocator.checkPermission();
|
|
22
|
+
if (permission == LocationPermission.denied) {
|
|
23
|
+
// Ask user for permission with a nice UI
|
|
24
|
+
bool userAgreed = await _showPermissionRationale(context);
|
|
25
|
+
if (userAgreed) {
|
|
26
|
+
permission = await Geolocator.requestPermission();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (permission == LocationPermission.denied || permission == LocationPermission.deniedForever) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Now request background permission if not granted
|
|
35
|
+
if (permission == LocationPermission.whileInUse) {
|
|
36
|
+
// Background location requires a separate request
|
|
37
|
+
// We could ask again with rationale
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
Future<bool> _showPermissionRationale(BuildContext context) async {
|
|
42
|
+
return await showDialog<bool>(
|
|
43
|
+
context: context,
|
|
44
|
+
builder: (context) => AlertDialog(
|
|
45
|
+
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
|
|
46
|
+
title: const Text('Background Location Needed'),
|
|
47
|
+
content: const Text(
|
|
48
|
+
'NeoAgent uses your approximate background location to trigger geofence reminders (e.g. "Remind me to buy milk when I walk past the supermarket").\n\n'
|
|
49
|
+
'Your location is never tracked continuously or stored on our servers. We only use it locally to check against your active tasks.',
|
|
50
|
+
),
|
|
51
|
+
actions: [
|
|
52
|
+
TextButton(
|
|
53
|
+
onPressed: () => Navigator.of(context).pop(false),
|
|
54
|
+
child: const Text('Not Now'),
|
|
55
|
+
),
|
|
56
|
+
ElevatedButton(
|
|
57
|
+
style: ElevatedButton.styleFrom(
|
|
58
|
+
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
|
59
|
+
),
|
|
60
|
+
onPressed: () => Navigator.of(context).pop(true),
|
|
61
|
+
child: const Text('Allow'),
|
|
62
|
+
),
|
|
63
|
+
],
|
|
64
|
+
),
|
|
65
|
+
) ?? false;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
Future<void> startGeofenceTracking(String backendUrl, String token) async {
|
|
69
|
+
if (_isTracking) return;
|
|
70
|
+
_isTracking = true;
|
|
71
|
+
|
|
72
|
+
// This runs a periodic check. In a real app, you'd use flutter_background_service
|
|
73
|
+
// to keep this alive even when the app is swiped away.
|
|
74
|
+
// For simplicity, we just simulate a foreground loop here.
|
|
75
|
+
_trackLoop(backendUrl, token);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
void _trackLoop(String backendUrl, String token) async {
|
|
79
|
+
while (_isTracking) {
|
|
80
|
+
try {
|
|
81
|
+
Position position = await Geolocator.getCurrentPosition(
|
|
82
|
+
desiredAccuracy: LocationAccuracy.low); // low accuracy = approx position
|
|
83
|
+
|
|
84
|
+
// Here we would normally fetch active geofences from local DB or backend
|
|
85
|
+
// and calculate the distance. If inside a geofence, we trigger:
|
|
86
|
+
|
|
87
|
+
// Example logic:
|
|
88
|
+
// double distanceInMeters = Geolocator.distanceBetween(startLat, startLng, endLat, endLng);
|
|
89
|
+
// if (distanceInMeters < 100) { triggerBackend(position, label); }
|
|
90
|
+
|
|
91
|
+
} catch (e) {
|
|
92
|
+
debugPrint('Geofence tracking error: $e');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Check every 5 minutes
|
|
96
|
+
await Future.delayed(const Duration(minutes: 5));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
Future<void> _triggerBackendGeofence(String backendUrl, String token, String label) async {
|
|
101
|
+
try {
|
|
102
|
+
await http.post(
|
|
103
|
+
Uri.parse('$backendUrl/api/triggers/geofence'),
|
|
104
|
+
headers: {
|
|
105
|
+
'Content-Type': 'application/json',
|
|
106
|
+
'Cookie': token,
|
|
107
|
+
},
|
|
108
|
+
body: jsonEncode({
|
|
109
|
+
'label': label,
|
|
110
|
+
'latitude': 0, // Sending 0 to respect privacy (approx position)
|
|
111
|
+
'longitude': 0,
|
|
112
|
+
'action': 'User entered geofence: $label'
|
|
113
|
+
}),
|
|
114
|
+
);
|
|
115
|
+
} catch (e) {
|
|
116
|
+
debugPrint('Failed to trigger geofence: $e');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import 'dart:convert';
|
|
2
|
+
import 'package:flutter/material.dart';
|
|
3
|
+
import 'package:http/http.dart' as http;
|
|
4
|
+
import 'package:notification_listener_service/notification_listener_service.dart';
|
|
5
|
+
import 'package:notification_listener_service/notification_event.dart';
|
|
6
|
+
|
|
7
|
+
class NotificationInterceptor {
|
|
8
|
+
static final NotificationInterceptor _instance = NotificationInterceptor._internal();
|
|
9
|
+
factory NotificationInterceptor() => _instance;
|
|
10
|
+
NotificationInterceptor._internal();
|
|
11
|
+
|
|
12
|
+
bool _isListening = false;
|
|
13
|
+
String _backendUrl = '';
|
|
14
|
+
String _token = '';
|
|
15
|
+
|
|
16
|
+
Future<void> initialize(BuildContext context, String backendUrl, String token) async {
|
|
17
|
+
_backendUrl = backendUrl;
|
|
18
|
+
_token = token;
|
|
19
|
+
|
|
20
|
+
bool isGranted = await NotificationListenerService.isPermissionGranted();
|
|
21
|
+
if (!isGranted) {
|
|
22
|
+
bool userAgreed = await _showPermissionRationale(context);
|
|
23
|
+
if (userAgreed) {
|
|
24
|
+
await NotificationListenerService.requestPermission();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
isGranted = await NotificationListenerService.isPermissionGranted();
|
|
29
|
+
if (isGranted && !_isListening) {
|
|
30
|
+
_startListening();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
Future<bool> _showPermissionRationale(BuildContext context) async {
|
|
35
|
+
return await showDialog<bool>(
|
|
36
|
+
context: context,
|
|
37
|
+
builder: (context) => AlertDialog(
|
|
38
|
+
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
|
|
39
|
+
title: const Text('Notification Access Needed'),
|
|
40
|
+
content: const Text(
|
|
41
|
+
'NeoAgent can read your incoming notifications (like Calendar alarms or urgent messages) and proactively act on them.\n\n'
|
|
42
|
+
'For example, if you receive a reminder, NeoAgent can automatically prepare relevant context for you.',
|
|
43
|
+
),
|
|
44
|
+
actions: [
|
|
45
|
+
TextButton(
|
|
46
|
+
onPressed: () => Navigator.of(context).pop(false),
|
|
47
|
+
child: const Text('Not Now'),
|
|
48
|
+
),
|
|
49
|
+
ElevatedButton(
|
|
50
|
+
style: ElevatedButton.styleFrom(
|
|
51
|
+
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
|
|
52
|
+
),
|
|
53
|
+
onPressed: () => Navigator.of(context).pop(true),
|
|
54
|
+
child: const Text('Allow Access'),
|
|
55
|
+
),
|
|
56
|
+
],
|
|
57
|
+
),
|
|
58
|
+
) ?? false;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
void _startListening() {
|
|
62
|
+
_isListening = true;
|
|
63
|
+
NotificationListenerService.notificationsStream.listen((ServiceNotificationEvent event) {
|
|
64
|
+
// Filter out noisy system notifications or ongoing foreground services
|
|
65
|
+
if (event.packageName == null || event.packageName!.contains('android.system')) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// We only want to intercept newly posted notifications, not removed ones
|
|
70
|
+
if (event.hasRemoved == true) return;
|
|
71
|
+
|
|
72
|
+
_sendToBackend(event);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
Future<void> _sendToBackend(ServiceNotificationEvent event) async {
|
|
77
|
+
if (_backendUrl.isEmpty || _token.isEmpty) return;
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
await http.post(
|
|
81
|
+
Uri.parse('$_backendUrl/api/triggers/notification'),
|
|
82
|
+
headers: {
|
|
83
|
+
'Content-Type': 'application/json',
|
|
84
|
+
'Cookie': _token,
|
|
85
|
+
},
|
|
86
|
+
body: jsonEncode({
|
|
87
|
+
'app_package': event.packageName ?? 'unknown',
|
|
88
|
+
'title': event.title ?? '',
|
|
89
|
+
'body': event.content ?? '',
|
|
90
|
+
'action_taken': 'intercepted',
|
|
91
|
+
}),
|
|
92
|
+
);
|
|
93
|
+
} catch (e) {
|
|
94
|
+
debugPrint('Failed to send notification to backend: $e');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|