neoagent 2.3.1-beta.0 → 2.3.1-beta.100

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.
Files changed (406) hide show
  1. package/.env.example +63 -5
  2. package/README.md +16 -5
  3. package/com.neoagent.plist +1 -1
  4. package/docs/automation.md +82 -41
  5. package/docs/capabilities.md +85 -89
  6. package/docs/configuration.md +89 -87
  7. package/docs/getting-started.md +46 -27
  8. package/docs/hardware.md +1 -1
  9. package/docs/index.md +24 -30
  10. package/docs/integrations.md +46 -60
  11. package/docs/migration.md +41 -146
  12. package/docs/operations.md +23 -20
  13. package/docs/skills.md +20 -20
  14. package/docs/why-neoagent.md +15 -13
  15. package/extensions/chrome-browser/background.mjs +10 -2
  16. package/flutter_app/.metadata +42 -0
  17. package/flutter_app/DESIGN_SYSTEM.md +166 -0
  18. package/flutter_app/README.md +21 -0
  19. package/flutter_app/analysis_options.yaml +32 -0
  20. package/flutter_app/android/app/build.gradle.kts +111 -0
  21. package/flutter_app/android/app/src/debug/AndroidManifest.xml +7 -0
  22. package/flutter_app/android/app/src/main/AndroidManifest.xml +185 -0
  23. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/MainActivity.kt +888 -0
  24. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/auto/NeoAgentCarAppService.kt +114 -0
  25. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/health/HealthConnectGateway.kt +280 -0
  26. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/health/HealthSyncNotifications.kt +113 -0
  27. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/health/HealthSyncPayload.kt +57 -0
  28. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/health/HealthSyncScheduler.kt +78 -0
  29. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/health/HealthSyncWorker.kt +253 -0
  30. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/health/PermissionsRationaleActivity.kt +46 -0
  31. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/recording/RecordingBootReceiver.kt +21 -0
  32. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/recording/RecordingForegroundService.kt +586 -0
  33. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/recording/RecordingStateStore.kt +78 -0
  34. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/recording/RecordingUploadClient.kt +104 -0
  35. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/telecom/NeoAgentConnection.kt +118 -0
  36. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/telecom/NeoAgentConnectionService.kt +86 -0
  37. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/AiHomeWidgetProvider.kt +457 -0
  38. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/AiWidgetStore.kt +194 -0
  39. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/VoiceLaunchWidgetProvider.kt +67 -0
  40. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/WidgetConfigActivity.kt +228 -0
  41. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/WidgetSyncScheduler.kt +72 -0
  42. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/WidgetSyncWorker.kt +186 -0
  43. package/flutter_app/android/app/src/main/kotlin/com/neoagent/flutter_app/widgets/WidgetTaskRunWorker.kt +210 -0
  44. package/flutter_app/android/app/src/main/res/drawable/launch_background.xml +12 -0
  45. package/flutter_app/android/app/src/main/res/drawable/neoagent_ai_widget_bg.xml +11 -0
  46. package/flutter_app/android/app/src/main/res/drawable/neoagent_ai_widget_task_bg.xml +8 -0
  47. package/flutter_app/android/app/src/main/res/drawable-v21/launch_background.xml +12 -0
  48. package/flutter_app/android/app/src/main/res/layout/neoagent_ai_widget.xml +138 -0
  49. package/flutter_app/android/app/src/main/res/layout/neoagent_ai_widget_task_row.xml +52 -0
  50. package/flutter_app/android/app/src/main/res/layout/neoagent_voice_widget.xml +49 -0
  51. package/flutter_app/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  52. package/flutter_app/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  53. package/flutter_app/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  54. package/flutter_app/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  55. package/flutter_app/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  56. package/flutter_app/android/app/src/main/res/values/arrays.xml +8 -0
  57. package/flutter_app/android/app/src/main/res/values/strings.xml +12 -0
  58. package/flutter_app/android/app/src/main/res/values/styles.xml +18 -0
  59. package/flutter_app/android/app/src/main/res/values-night/styles.xml +18 -0
  60. package/flutter_app/android/app/src/main/res/xml/automotive_app_desc.xml +4 -0
  61. package/flutter_app/android/app/src/main/res/xml/file_paths.xml +6 -0
  62. package/flutter_app/android/app/src/main/res/xml/neoagent_ai_widget_info.xml +12 -0
  63. package/flutter_app/android/app/src/main/res/xml/neoagent_voice_widget_info.xml +12 -0
  64. package/flutter_app/android/app/src/profile/AndroidManifest.xml +7 -0
  65. package/flutter_app/android/build.gradle.kts +24 -0
  66. package/flutter_app/android/ci-release.keystore +0 -0
  67. package/flutter_app/android/gradle/wrapper/gradle-wrapper.properties +5 -0
  68. package/flutter_app/android/gradle.properties +3 -0
  69. package/flutter_app/android/key.properties +4 -0
  70. package/flutter_app/android/settings.gradle.kts +26 -0
  71. package/flutter_app/assets/branding/app_icon_1024.png +0 -0
  72. package/flutter_app/assets/branding/app_icon_128.png +0 -0
  73. package/flutter_app/assets/branding/app_icon_192.png +0 -0
  74. package/flutter_app/assets/branding/app_icon_256.png +0 -0
  75. package/flutter_app/assets/branding/app_icon_32.png +0 -0
  76. package/flutter_app/assets/branding/app_icon_512.png +0 -0
  77. package/flutter_app/assets/branding/app_icon_64.png +0 -0
  78. package/flutter_app/assets/branding/onboarding_intro.mp4 +0 -0
  79. package/flutter_app/assets/branding/tray_icon_template.png +0 -0
  80. package/flutter_app/lib/features/location/location_service.dart +117 -0
  81. package/flutter_app/lib/features/notifications/notification_interceptor.dart +73 -0
  82. package/flutter_app/lib/features/onboarding/onboarding_chrome.dart +571 -0
  83. package/flutter_app/lib/features/onboarding/onboarding_messaging_step.dart +275 -0
  84. package/flutter_app/lib/features/onboarding/onboarding_model_step.dart +366 -0
  85. package/flutter_app/lib/features/onboarding/onboarding_shell.dart +57 -0
  86. package/flutter_app/lib/features/onboarding/onboarding_video_step.dart +218 -0
  87. package/flutter_app/lib/features/onboarding/onboarding_welcome_step.dart +46 -0
  88. package/flutter_app/lib/main.dart +107 -0
  89. package/flutter_app/lib/main_account_settings.dart +1340 -0
  90. package/flutter_app/lib/main_admin.dart +900 -0
  91. package/flutter_app/lib/main_app_shell.dart +2162 -0
  92. package/flutter_app/lib/main_chat.dart +3902 -0
  93. package/flutter_app/lib/main_controller.dart +7229 -0
  94. package/flutter_app/lib/main_devices.dart +1738 -0
  95. package/flutter_app/lib/main_integrations.dart +917 -0
  96. package/flutter_app/lib/main_launcher.dart +959 -0
  97. package/flutter_app/lib/main_launcher_entry.dart +5 -0
  98. package/flutter_app/lib/main_models.dart +3807 -0
  99. package/flutter_app/lib/main_navigation.dart +206 -0
  100. package/flutter_app/lib/main_operations.dart +5249 -0
  101. package/flutter_app/lib/main_recordings.dart +920 -0
  102. package/flutter_app/lib/main_runtime.dart +869 -0
  103. package/flutter_app/lib/main_settings.dart +2288 -0
  104. package/flutter_app/lib/main_shared.dart +3393 -0
  105. package/flutter_app/lib/main_spacing.dart +33 -0
  106. package/flutter_app/lib/main_theme.dart +276 -0
  107. package/flutter_app/lib/main_unified.dart +388 -0
  108. package/flutter_app/lib/main_voice_assistant.dart +957 -0
  109. package/flutter_app/lib/src/analytics_service.dart +294 -0
  110. package/flutter_app/lib/src/android_apk_drop_zone.dart +32 -0
  111. package/flutter_app/lib/src/android_apk_drop_zone_stub.dart +16 -0
  112. package/flutter_app/lib/src/android_apk_drop_zone_web.dart +348 -0
  113. package/flutter_app/lib/src/android_app_installer.dart +22 -0
  114. package/flutter_app/lib/src/android_app_installer_io.dart +122 -0
  115. package/flutter_app/lib/src/android_app_installer_stub.dart +21 -0
  116. package/flutter_app/lib/src/android_auto_bridge.dart +59 -0
  117. package/flutter_app/lib/src/android_launcher_bridge.dart +239 -0
  118. package/flutter_app/lib/src/app_launch_bridge.dart +58 -0
  119. package/flutter_app/lib/src/app_release_updater.dart +511 -0
  120. package/flutter_app/lib/src/backend_client.dart +1870 -0
  121. package/flutter_app/lib/src/desktop_companion.dart +2 -0
  122. package/flutter_app/lib/src/desktop_companion_actions.dart +586 -0
  123. package/flutter_app/lib/src/desktop_companion_io.dart +538 -0
  124. package/flutter_app/lib/src/desktop_companion_stub.dart +59 -0
  125. package/flutter_app/lib/src/desktop_native_bridge.dart +91 -0
  126. package/flutter_app/lib/src/desktop_screen_capture.dart +21 -0
  127. package/flutter_app/lib/src/desktop_screen_capture_io.dart +142 -0
  128. package/flutter_app/lib/src/desktop_screen_capture_stub.dart +12 -0
  129. package/flutter_app/lib/src/diagnostics_logger.dart +119 -0
  130. package/flutter_app/lib/src/health_bridge.dart +136 -0
  131. package/flutter_app/lib/src/live_voice_capture.dart +85 -0
  132. package/flutter_app/lib/src/messaging_access_summary.dart +46 -0
  133. package/flutter_app/lib/src/network/app_http_client.dart +53 -0
  134. package/flutter_app/lib/src/network/app_http_client_factory.dart +6 -0
  135. package/flutter_app/lib/src/network/app_http_client_io.dart +138 -0
  136. package/flutter_app/lib/src/network/app_http_client_stub.dart +3 -0
  137. package/flutter_app/lib/src/network/app_http_client_web.dart +94 -0
  138. package/flutter_app/lib/src/oauth_launcher.dart +33 -0
  139. package/flutter_app/lib/src/oauth_launcher_io.dart +95 -0
  140. package/flutter_app/lib/src/oauth_launcher_stub.dart +33 -0
  141. package/flutter_app/lib/src/oauth_launcher_web.dart +107 -0
  142. package/flutter_app/lib/src/recording_bridge.dart +232 -0
  143. package/flutter_app/lib/src/recording_bridge_io.dart +1019 -0
  144. package/flutter_app/lib/src/recording_bridge_stub.dart +120 -0
  145. package/flutter_app/lib/src/recording_bridge_web.dart +689 -0
  146. package/flutter_app/lib/src/recording_payloads.dart +86 -0
  147. package/flutter_app/lib/src/theme/palette.dart +81 -0
  148. package/flutter_app/lib/src/web_app_update_monitor.dart +17 -0
  149. package/flutter_app/lib/src/web_app_update_monitor_stub.dart +24 -0
  150. package/flutter_app/lib/src/web_app_update_monitor_web.dart +123 -0
  151. package/flutter_app/lib/src/widget_bridge.dart +49 -0
  152. package/flutter_app/linux/CMakeLists.txt +128 -0
  153. package/flutter_app/linux/flutter/CMakeLists.txt +88 -0
  154. package/flutter_app/linux/flutter/generated_plugin_registrant.cc +47 -0
  155. package/flutter_app/linux/flutter/generated_plugin_registrant.h +15 -0
  156. package/flutter_app/linux/flutter/generated_plugins.cmake +32 -0
  157. package/flutter_app/linux/runner/CMakeLists.txt +26 -0
  158. package/flutter_app/linux/runner/main.cc +6 -0
  159. package/flutter_app/linux/runner/my_application.cc +144 -0
  160. package/flutter_app/linux/runner/my_application.h +18 -0
  161. package/flutter_app/linux/runner/resources/app_icon.png +0 -0
  162. package/flutter_app/macos/Flutter/Flutter-Debug.xcconfig +2 -0
  163. package/flutter_app/macos/Flutter/Flutter-Release.xcconfig +2 -0
  164. package/flutter_app/macos/Flutter/GeneratedPluginRegistrant.swift +48 -0
  165. package/flutter_app/macos/Podfile +42 -0
  166. package/flutter_app/macos/Podfile.lock +87 -0
  167. package/flutter_app/macos/Runner/AppDelegate.swift +576 -0
  168. package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +68 -0
  169. package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png +0 -0
  170. package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png +0 -0
  171. package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png +0 -0
  172. package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png +0 -0
  173. package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png +0 -0
  174. package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png +0 -0
  175. package/flutter_app/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png +0 -0
  176. package/flutter_app/macos/Runner/Base.lproj/MainMenu.xib +342 -0
  177. package/flutter_app/macos/Runner/Configs/AppInfo.xcconfig +14 -0
  178. package/flutter_app/macos/Runner/Configs/Debug.xcconfig +2 -0
  179. package/flutter_app/macos/Runner/Configs/Release.xcconfig +2 -0
  180. package/flutter_app/macos/Runner/Configs/Warnings.xcconfig +13 -0
  181. package/flutter_app/macos/Runner/DebugProfile.entitlements +16 -0
  182. package/flutter_app/macos/Runner/Info.plist +36 -0
  183. package/flutter_app/macos/Runner/MainFlutterWindow.swift +19 -0
  184. package/flutter_app/macos/Runner/Release.entitlements +12 -0
  185. package/flutter_app/macos/Runner.xcodeproj/project.pbxproj +801 -0
  186. package/flutter_app/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  187. package/flutter_app/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +99 -0
  188. package/flutter_app/macos/Runner.xcworkspace/contents.xcworkspacedata +10 -0
  189. package/flutter_app/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  190. package/flutter_app/macos/RunnerTests/RunnerTests.swift +12 -0
  191. package/flutter_app/patch_strings.py +12 -0
  192. package/flutter_app/pubspec.lock +1256 -0
  193. package/flutter_app/pubspec.yaml +59 -0
  194. package/flutter_app/third_party/desktop_audio_capture/LICENSE +21 -0
  195. package/flutter_app/third_party/desktop_audio_capture/README.md +262 -0
  196. package/flutter_app/third_party/desktop_audio_capture/lib/audio_capture.dart +65 -0
  197. package/flutter_app/third_party/desktop_audio_capture/lib/config/mic_audio_config.dart +153 -0
  198. package/flutter_app/third_party/desktop_audio_capture/lib/config/system_adudio_config.dart +110 -0
  199. package/flutter_app/third_party/desktop_audio_capture/lib/mic/mic_audio_capture.dart +461 -0
  200. package/flutter_app/third_party/desktop_audio_capture/lib/model/audio_status.dart +91 -0
  201. package/flutter_app/third_party/desktop_audio_capture/lib/model/decibel_data.dart +106 -0
  202. package/flutter_app/third_party/desktop_audio_capture/lib/model/input_device_type.dart +219 -0
  203. package/flutter_app/third_party/desktop_audio_capture/lib/system/system_audio_capture.dart +336 -0
  204. package/flutter_app/third_party/desktop_audio_capture/linux/CMakeLists.txt +101 -0
  205. package/flutter_app/third_party/desktop_audio_capture/linux/audio_capture_plugin.cc +692 -0
  206. package/flutter_app/third_party/desktop_audio_capture/linux/include/audio_capture/audio_capture_plugin.h +35 -0
  207. package/flutter_app/third_party/desktop_audio_capture/linux/include/audio_capture/mic_capture_plugin.h +36 -0
  208. package/flutter_app/third_party/desktop_audio_capture/linux/include/desktop_audio_capture/audio_capture_plugin.h +32 -0
  209. package/flutter_app/third_party/desktop_audio_capture/linux/include/desktop_audio_capture/mic_capture_plugin.h +32 -0
  210. package/flutter_app/third_party/desktop_audio_capture/linux/mic_capture_plugin.cc +878 -0
  211. package/flutter_app/third_party/desktop_audio_capture/macos/Classes/AudioCapturePlugin.swift +27 -0
  212. package/flutter_app/third_party/desktop_audio_capture/macos/Classes/MicCapturePlugin.swift +1172 -0
  213. package/flutter_app/third_party/desktop_audio_capture/macos/Classes/SystemCapturePlugin.swift +655 -0
  214. package/flutter_app/third_party/desktop_audio_capture/macos/Resources/PrivacyInfo.xcprivacy +12 -0
  215. package/flutter_app/third_party/desktop_audio_capture/macos/desktop_audio_capture.podspec +30 -0
  216. package/flutter_app/third_party/desktop_audio_capture/pubspec.yaml +87 -0
  217. package/flutter_app/third_party/desktop_audio_capture/windows/CMakeLists.txt +105 -0
  218. package/flutter_app/third_party/desktop_audio_capture/windows/audio_capture_plugin.cpp +80 -0
  219. package/flutter_app/third_party/desktop_audio_capture/windows/audio_capture_plugin.h +31 -0
  220. package/flutter_app/third_party/desktop_audio_capture/windows/audio_capture_plugin_c_api.cpp +12 -0
  221. package/flutter_app/third_party/desktop_audio_capture/windows/include/audio_capture/audio_capture_plugin_c_api.h +23 -0
  222. package/flutter_app/third_party/desktop_audio_capture/windows/include/desktop_audio_capture/audio_capture_plugin.h +25 -0
  223. package/flutter_app/third_party/desktop_audio_capture/windows/mic_capture_plugin.cpp +1117 -0
  224. package/flutter_app/third_party/desktop_audio_capture/windows/mic_capture_plugin.h +115 -0
  225. package/flutter_app/third_party/desktop_audio_capture/windows/system_audio_capture_plugin.cpp +777 -0
  226. package/flutter_app/third_party/desktop_audio_capture/windows/system_audio_capture_plugin.h +87 -0
  227. package/flutter_app/third_party/flutter_secure_storage_linux/linux/CMakeLists.txt +30 -0
  228. package/flutter_app/third_party/flutter_secure_storage_linux/linux/flutter_secure_storage_linux_plugin.cc +215 -0
  229. package/flutter_app/third_party/flutter_secure_storage_linux/linux/include/flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h +27 -0
  230. package/flutter_app/third_party/flutter_secure_storage_linux/pubspec.yaml +20 -0
  231. package/flutter_app/tool/generate_desktop_branding.py +219 -0
  232. package/flutter_app/web/favicon.png +0 -0
  233. package/flutter_app/web/favicon.svg +12 -0
  234. package/flutter_app/web/icons/Icon-192.png +0 -0
  235. package/flutter_app/web/icons/Icon-512.png +0 -0
  236. package/flutter_app/web/icons/Icon-maskable-192.png +0 -0
  237. package/flutter_app/web/icons/Icon-maskable-512.png +0 -0
  238. package/flutter_app/web/index.html +39 -0
  239. package/flutter_app/web/manifest.json +35 -0
  240. package/flutter_app/windows/CMakeLists.txt +108 -0
  241. package/flutter_app/windows/flutter/CMakeLists.txt +109 -0
  242. package/flutter_app/windows/flutter/generated_plugin_registrant.cc +50 -0
  243. package/flutter_app/windows/flutter/generated_plugin_registrant.h +15 -0
  244. package/flutter_app/windows/flutter/generated_plugins.cmake +36 -0
  245. package/flutter_app/windows/runner/CMakeLists.txt +41 -0
  246. package/flutter_app/windows/runner/Runner.rc +121 -0
  247. package/flutter_app/windows/runner/flutter_window.cpp +533 -0
  248. package/flutter_app/windows/runner/flutter_window.h +37 -0
  249. package/flutter_app/windows/runner/main.cpp +53 -0
  250. package/flutter_app/windows/runner/resource.h +16 -0
  251. package/flutter_app/windows/runner/resources/app_icon.ico +0 -0
  252. package/flutter_app/windows/runner/runner.exe.manifest +14 -0
  253. package/flutter_app/windows/runner/utils.cpp +65 -0
  254. package/flutter_app/windows/runner/utils.h +19 -0
  255. package/flutter_app/windows/runner/win32_window.cpp +299 -0
  256. package/flutter_app/windows/runner/win32_window.h +102 -0
  257. package/lib/install_helpers.js +31 -0
  258. package/lib/manager.js +465 -43
  259. package/package.json +11 -3
  260. package/runtime/paths.js +137 -0
  261. package/server/config/analytics.js +30 -0
  262. package/server/db/database.js +363 -21
  263. package/server/guest-agent.android.package.json +13 -0
  264. package/server/guest-agent.browser.package.json +14 -0
  265. package/server/guest_agent.js +98 -52
  266. package/server/http/middleware.js +55 -2
  267. package/server/http/routes.js +6 -1
  268. package/server/http/static.js +41 -1
  269. package/server/index.js +16 -16
  270. package/server/public/.last_build_id +1 -1
  271. package/server/public/assets/AssetManifest.bin +1 -1
  272. package/server/public/assets/AssetManifest.bin.json +1 -1
  273. package/server/public/assets/AssetManifest.json +1 -1
  274. package/server/public/assets/NOTICES +679 -129
  275. package/server/public/assets/assets/branding/onboarding_intro.mp4 +0 -0
  276. package/server/public/assets/fonts/MaterialIcons-Regular.otf +0 -0
  277. package/server/public/assets/packages/mixpanel_flutter/assets/mixpanel.js +3 -0
  278. package/server/public/canvaskit/wimp.wasm +0 -0
  279. package/server/public/flutter_bootstrap.js +2 -2
  280. package/server/public/main.dart.js +95866 -87333
  281. package/server/routes/account.js +26 -1
  282. package/server/routes/agents.js +6 -2
  283. package/server/routes/android.js +22 -6
  284. package/server/routes/auth.js +25 -5
  285. package/server/routes/browser.js +47 -13
  286. package/server/routes/integrations.js +119 -9
  287. package/server/routes/memory.js +179 -8
  288. package/server/routes/runtime.js +14 -0
  289. package/server/routes/screenHistory.js +46 -0
  290. package/server/routes/settings.js +102 -24
  291. package/server/routes/skills.js +12 -0
  292. package/server/routes/social_video.js +66 -0
  293. package/server/routes/tasks.js +22 -2
  294. package/server/routes/triggers.js +90 -0
  295. package/server/routes/wearable.js +67 -0
  296. package/server/routes/widgets.js +4 -4
  297. package/server/services/ai/capabilityHealth.js +23 -51
  298. package/server/services/ai/compaction.js +1 -1
  299. package/server/services/ai/deliverables/artifact_helpers.js +190 -0
  300. package/server/services/ai/deliverables/contracts.js +113 -0
  301. package/server/services/ai/deliverables/index.js +20 -0
  302. package/server/services/ai/deliverables/selector.js +94 -0
  303. package/server/services/ai/deliverables/validator.js +63 -0
  304. package/server/services/ai/deliverables/workflows.js +207 -0
  305. package/server/services/ai/engine.js +372 -27
  306. package/server/services/ai/hooks.js +127 -0
  307. package/server/services/ai/integrated_tools/index.js +98 -0
  308. package/server/services/ai/integrated_tools/remotion.js +373 -0
  309. package/server/services/ai/integrated_tools/shared.js +204 -0
  310. package/server/services/ai/integrated_tools/slidev.js +207 -0
  311. package/server/services/ai/loopPolicy.js +146 -0
  312. package/server/services/ai/models.js +36 -0
  313. package/server/services/ai/providers/githubCopilot.js +97 -0
  314. package/server/services/ai/providers/openai.js +2 -1
  315. package/server/services/ai/providers/openaiCodex.js +384 -0
  316. package/server/services/ai/recordingInsights.js +11 -13
  317. package/server/services/ai/runEvents.js +100 -0
  318. package/server/services/ai/settings.js +20 -0
  319. package/server/services/ai/systemPrompt.js +16 -2
  320. package/server/services/ai/taskAnalysis.js +2 -0
  321. package/server/services/ai/toolResult.js +20 -0
  322. package/server/services/ai/toolRunner.js +46 -6
  323. package/server/services/ai/toolSelector.js +54 -1
  324. package/server/services/ai/tools.js +360 -127
  325. package/server/services/android/android_bootstrap_worker.js +63 -0
  326. package/server/services/android/controller.js +442 -1760
  327. package/server/services/bootstrap_helpers.js +0 -34
  328. package/server/services/browser/controller.js +326 -52
  329. package/server/services/cli/executor.js +40 -1
  330. package/server/services/desktop/screenRecorder.js +182 -0
  331. package/server/services/integrations/env.js +10 -0
  332. package/server/services/integrations/figma/provider.js +1 -0
  333. package/server/services/integrations/github/common.js +106 -0
  334. package/server/services/integrations/github/provider.js +499 -0
  335. package/server/services/integrations/github/repos.js +1124 -0
  336. package/server/services/integrations/google/provider.js +1 -0
  337. package/server/services/integrations/manager.js +88 -12
  338. package/server/services/integrations/microsoft/provider.js +1 -0
  339. package/server/services/integrations/oauth_provider.js +25 -8
  340. package/server/services/integrations/provider_config_store.js +85 -0
  341. package/server/services/integrations/registry.js +8 -2
  342. package/server/services/integrations/spotify/provider.js +488 -0
  343. package/server/services/integrations/trello/provider.js +842 -0
  344. package/server/services/integrations/weather/provider.js +559 -0
  345. package/server/services/integrations/whatsapp/provider.js +6 -2
  346. package/server/services/manager.js +109 -154
  347. package/server/services/mcp/client.js +120 -23
  348. package/server/services/memory/llm_transfer.js +218 -0
  349. package/server/services/memory/manager.js +299 -35
  350. package/server/services/messaging/access_policy.js +10 -0
  351. package/server/services/messaging/automation.js +1 -1
  352. package/server/services/messaging/manager.js +93 -8
  353. package/server/services/messaging/meshtastic.js +277 -0
  354. package/server/services/messaging/meshtastic_env.js +40 -0
  355. package/server/services/messaging/meshtastic_protocol.js +530 -0
  356. package/server/services/messaging/meshtastic_tcp_transport.js +25 -0
  357. package/server/services/runtime/backends/local-vm.js +221 -158
  358. package/server/services/runtime/docker-vm-manager.js +392 -0
  359. package/server/services/runtime/guest_bootstrap.js +654 -0
  360. package/server/services/runtime/manager.js +85 -29
  361. package/server/services/runtime/settings.js +22 -31
  362. package/server/services/runtime/validation.js +16 -31
  363. package/server/services/skills/base_catalog.js +33 -0
  364. package/server/services/social_video/adapters/base.js +26 -0
  365. package/server/services/social_video/adapters/index.js +27 -0
  366. package/server/services/social_video/adapters/instagram.js +17 -0
  367. package/server/services/social_video/adapters/tiktok.js +17 -0
  368. package/server/services/social_video/adapters/x.js +17 -0
  369. package/server/services/social_video/adapters/youtube.js +17 -0
  370. package/server/services/social_video/captions.js +187 -0
  371. package/server/services/social_video/frame.js +42 -0
  372. package/server/services/social_video/index.js +7 -0
  373. package/server/services/social_video/metadata.js +63 -0
  374. package/server/services/social_video/result.js +63 -0
  375. package/server/services/social_video/service.js +720 -0
  376. package/server/services/social_video/url.js +83 -0
  377. package/server/services/tasks/adapters/index.js +2 -0
  378. package/server/services/tasks/adapters/manual.js +12 -0
  379. package/server/services/tasks/adapters/schedule.js +33 -5
  380. package/server/services/tasks/adapters/weather_event.js +84 -0
  381. package/server/services/tasks/integration_runtime.js +86 -1
  382. package/server/services/tasks/runtime.js +3 -3
  383. package/server/services/tasks/task_repository.js +3 -6
  384. package/server/services/voice/agentBridge.js +20 -4
  385. package/server/services/voice/message.js +3 -0
  386. package/server/services/voice/openaiClient.js +4 -1
  387. package/server/services/voice/openaiSpeech.js +6 -1
  388. package/server/services/voice/providers.js +144 -15
  389. package/server/services/voice/runtime.js +8 -8
  390. package/server/services/voice/runtimeManager.js +292 -20
  391. package/server/services/voice/turnRunner.js +29 -9
  392. package/server/services/wearable/firmware_manifest.js +353 -0
  393. package/server/services/wearable/gateway.js +350 -0
  394. package/server/services/wearable/protocol.js +45 -0
  395. package/server/services/wearable/service.js +240 -0
  396. package/server/services/websocket.js +3 -1
  397. package/server/services/widgets/focus_widget.js +137 -0
  398. package/server/services/widgets/service.js +182 -6
  399. package/server/services/workspace/manager.js +301 -0
  400. package/server/utils/deployment.js +16 -9
  401. package/server/utils/local_secrets.js +56 -0
  402. package/server/utils/logger.js +37 -9
  403. package/server/services/integrations/home_assistant/provider.js +0 -350
  404. package/server/services/messaging/access_policy.test.js +0 -228
  405. package/server/services/runtime/backends/host.js +0 -37
  406. package/server/services/runtime/qemu.js +0 -391
@@ -1,4 +1,5 @@
1
1
  const Database = require('better-sqlite3');
2
+ const fs = require('fs');
2
3
  const path = require('path');
3
4
  const { randomUUID } = require('crypto');
4
5
  const { DATA_DIR, ensureRuntimeDirs } = require('../../runtime/paths');
@@ -9,11 +10,85 @@ const {
9
10
  ensureRuntimeDirs();
10
11
 
11
12
  const DB_PATH = path.join(DATA_DIR, 'neoagent.db');
12
- const db = new Database(DB_PATH);
13
13
 
14
- db.pragma('journal_mode = WAL');
15
- db.pragma('foreign_keys = ON');
16
- db.pragma('busy_timeout = 5000');
14
+ function removeWalSidecars(dbPath) {
15
+ for (const suffix of ['-wal', '-shm']) {
16
+ try {
17
+ fs.rmSync(`${dbPath}${suffix}`, { force: true });
18
+ } catch {}
19
+ }
20
+ }
21
+
22
+ function initializeDatabase(db, dbPath) {
23
+ try {
24
+ db.pragma('journal_mode = WAL');
25
+ } catch (error) {
26
+ console.warn(
27
+ `[Database] Failed to enable WAL for ${dbPath}: ${error.message}. ` +
28
+ 'Retrying after clearing WAL sidecar files.',
29
+ );
30
+ try {
31
+ db.close();
32
+ } catch {}
33
+
34
+ removeWalSidecars(dbPath);
35
+
36
+ db = new Database(dbPath);
37
+ try {
38
+ db.pragma('journal_mode = WAL');
39
+ } catch (retryError) {
40
+ console.warn(
41
+ `[Database] WAL is unavailable for ${dbPath}: ${retryError.message}. ` +
42
+ 'Falling back to DELETE journal mode.',
43
+ );
44
+ db.pragma('journal_mode = DELETE');
45
+ }
46
+ }
47
+
48
+ db.pragma('foreign_keys = ON');
49
+ db.pragma('busy_timeout = 5000');
50
+ return db;
51
+ }
52
+
53
+ function sleepSync(ms) {
54
+ if (ms <= 0) return;
55
+ const buffer = new SharedArrayBuffer(4);
56
+ const view = new Int32Array(buffer);
57
+ Atomics.wait(view, 0, 0, ms);
58
+ }
59
+
60
+ function isSqliteBusyError(error) {
61
+ return Boolean(
62
+ error &&
63
+ (
64
+ error.code === 'SQLITE_BUSY' ||
65
+ error.code === 'SQLITE_LOCKED' ||
66
+ /database is locked|database table is locked/i.test(error.message || '')
67
+ ),
68
+ );
69
+ }
70
+
71
+ function runWithBusyRetry(action, { attempts = 5, delayMs = 50, label = 'SQLite operation' } = {}) {
72
+ let lastError = null;
73
+ for (let attempt = 1; attempt <= attempts; attempt += 1) {
74
+ try {
75
+ return action();
76
+ } catch (error) {
77
+ lastError = error;
78
+ if (!isSqliteBusyError(error) || attempt === attempts) {
79
+ throw error;
80
+ }
81
+ console.warn(
82
+ `[Database] ${label} hit a busy lock on attempt ${attempt}/${attempts}; retrying in ${delayMs}ms.`,
83
+ );
84
+ sleepSync(delayMs);
85
+ }
86
+ }
87
+ throw lastError;
88
+ }
89
+
90
+ let db = new Database(DB_PATH);
91
+ db = initializeDatabase(db, DB_PATH);
17
92
 
18
93
  db.exec(`
19
94
  CREATE TABLE IF NOT EXISTS users (
@@ -24,7 +99,8 @@ db.exec(`
24
99
  password TEXT NOT NULL,
25
100
  password_login_enabled INTEGER DEFAULT 1,
26
101
  created_at TEXT DEFAULT (datetime('now')),
27
- last_login TEXT
102
+ last_login TEXT,
103
+ has_completed_onboarding INTEGER DEFAULT 0
28
104
  );
29
105
 
30
106
  CREATE TABLE IF NOT EXISTS agents (
@@ -272,6 +348,19 @@ db.exec(`
272
348
  FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE SET NULL
273
349
  );
274
350
 
351
+ CREATE TABLE IF NOT EXISTS integration_provider_configs (
352
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
353
+ user_id INTEGER NOT NULL,
354
+ agent_id TEXT,
355
+ provider_key TEXT NOT NULL,
356
+ config_json TEXT DEFAULT '{}',
357
+ created_at TEXT DEFAULT (datetime('now')),
358
+ updated_at TEXT DEFAULT (datetime('now')),
359
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
360
+ FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE SET NULL,
361
+ UNIQUE(user_id, agent_id, provider_key)
362
+ );
363
+
275
364
  CREATE TABLE IF NOT EXISTS browser_extension_pairing_requests (
276
365
  id TEXT PRIMARY KEY,
277
366
  user_id INTEGER,
@@ -419,6 +508,7 @@ db.exec(`
419
508
  CREATE INDEX IF NOT EXISTS idx_desktop_companion_devices_user ON desktop_companion_devices(user_id, status, created_at DESC);
420
509
  CREATE INDEX IF NOT EXISTS idx_messages_user ON messages(user_id, created_at DESC);
421
510
  CREATE INDEX IF NOT EXISTS idx_messages_platform ON messages(platform, platform_chat_id);
511
+ CREATE INDEX IF NOT EXISTS idx_messages_dedup ON messages(user_id, platform, platform_msg_id) WHERE platform_msg_id IS NOT NULL;
422
512
  CREATE INDEX IF NOT EXISTS idx_conv_messages ON conversation_messages(conversation_id, created_at);
423
513
  CREATE INDEX IF NOT EXISTS idx_conversations_user ON conversations(user_id, updated_at DESC);
424
514
  CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_user ON scheduled_tasks(user_id);
@@ -428,6 +518,9 @@ db.exec(`
428
518
  user_id INTEGER NOT NULL,
429
519
  agent_id TEXT,
430
520
  name TEXT NOT NULL,
521
+ widget_kind TEXT DEFAULT 'custom',
522
+ system_key TEXT,
523
+ is_system INTEGER DEFAULT 0,
431
524
  template TEXT NOT NULL,
432
525
  layout_variant TEXT NOT NULL,
433
526
  definition_json TEXT DEFAULT '{}',
@@ -479,6 +572,13 @@ db.exec(`
479
572
  user_id INTEGER NOT NULL,
480
573
  agent_id TEXT,
481
574
  category TEXT DEFAULT 'episodic',
575
+ scope_type TEXT DEFAULT 'agent',
576
+ scope_id TEXT,
577
+ source_type TEXT,
578
+ source_id TEXT,
579
+ source_label TEXT,
580
+ stale_after_days INTEGER,
581
+ metadata_json TEXT DEFAULT '{}',
482
582
  content TEXT NOT NULL,
483
583
  importance INTEGER DEFAULT 5,
484
584
  embedding TEXT,
@@ -503,6 +603,36 @@ db.exec(`
503
603
  CREATE INDEX IF NOT EXISTS idx_memories_user ON memories(user_id, archived, updated_at DESC);
504
604
  CREATE INDEX IF NOT EXISTS idx_memories_category ON memories(user_id, category, archived);
505
605
 
606
+ CREATE TABLE IF NOT EXISTS assistant_self_state (
607
+ user_id INTEGER NOT NULL,
608
+ agent_id TEXT NOT NULL,
609
+ identity_json TEXT DEFAULT '{}',
610
+ focus_json TEXT DEFAULT '{}',
611
+ updated_at TEXT DEFAULT (datetime('now')),
612
+ PRIMARY KEY (user_id, agent_id),
613
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
614
+ FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE CASCADE
615
+ );
616
+
617
+ CREATE TABLE IF NOT EXISTS agent_run_events (
618
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
619
+ run_id TEXT NOT NULL,
620
+ user_id INTEGER NOT NULL,
621
+ agent_id TEXT,
622
+ event_type TEXT NOT NULL,
623
+ request_id TEXT,
624
+ step_id TEXT,
625
+ sequence_index INTEGER DEFAULT 0,
626
+ payload_json TEXT DEFAULT '{}',
627
+ created_at TEXT DEFAULT (datetime('now')),
628
+ FOREIGN KEY (run_id) REFERENCES agent_runs(id) ON DELETE CASCADE,
629
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
630
+ FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE SET NULL
631
+ );
632
+
633
+ CREATE INDEX IF NOT EXISTS idx_agent_run_events_run ON agent_run_events(run_id, sequence_index, id);
634
+ CREATE INDEX IF NOT EXISTS idx_agent_run_events_user ON agent_run_events(user_id, created_at DESC);
635
+
506
636
  CREATE TABLE IF NOT EXISTS agent_settings (
507
637
  id INTEGER PRIMARY KEY AUTOINCREMENT,
508
638
  user_id INTEGER NOT NULL,
@@ -651,6 +781,40 @@ db.exec(`
651
781
  CREATE INDEX IF NOT EXISTS idx_recording_chunks_source ON recording_chunks(source_id, sequence_index);
652
782
  CREATE INDEX IF NOT EXISTS idx_recording_segments_session ON recording_transcript_segments(session_id, start_ms, created_at);
653
783
 
784
+ CREATE TABLE IF NOT EXISTS screen_history (
785
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
786
+ user_id INTEGER NOT NULL,
787
+ timestamp TEXT DEFAULT (datetime('now')),
788
+ app_name TEXT,
789
+ text_content TEXT,
790
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
791
+ );
792
+
793
+ CREATE TABLE IF NOT EXISTS notification_history (
794
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
795
+ user_id INTEGER NOT NULL,
796
+ app_package TEXT,
797
+ title TEXT,
798
+ body TEXT,
799
+ timestamp TEXT DEFAULT (datetime('now')),
800
+ action_taken TEXT,
801
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
802
+ );
803
+
804
+ CREATE TABLE IF NOT EXISTS geofences (
805
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
806
+ user_id INTEGER NOT NULL,
807
+ label TEXT,
808
+ latitude REAL NOT NULL,
809
+ longitude REAL NOT NULL,
810
+ radius_meters INTEGER NOT NULL,
811
+ trigger_action TEXT,
812
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
813
+ );
814
+
815
+ CREATE INDEX IF NOT EXISTS idx_screen_history_user ON screen_history(user_id, timestamp DESC);
816
+ CREATE INDEX IF NOT EXISTS idx_notification_history_user ON notification_history(user_id, timestamp DESC);
817
+
654
818
  CREATE TABLE IF NOT EXISTS artifacts (
655
819
  id TEXT PRIMARY KEY,
656
820
  user_id INTEGER NOT NULL,
@@ -676,6 +840,29 @@ db.exec(`
676
840
 
677
841
  try {
678
842
  db.exec(`
843
+ CREATE VIRTUAL TABLE IF NOT EXISTS screen_history_fts USING fts5(
844
+ text_content,
845
+ app_name,
846
+ timestamp UNINDEXED,
847
+ user_id UNINDEXED,
848
+ tokenize = 'porter unicode61'
849
+ );
850
+
851
+ CREATE TRIGGER IF NOT EXISTS screen_history_fts_ai AFTER INSERT ON screen_history BEGIN
852
+ INSERT INTO screen_history_fts(rowid, text_content, app_name, timestamp, user_id)
853
+ VALUES (new.id, COALESCE(new.text_content, ''), COALESCE(new.app_name, ''), new.timestamp, new.user_id);
854
+ END;
855
+
856
+ CREATE TRIGGER IF NOT EXISTS screen_history_fts_ad AFTER DELETE ON screen_history BEGIN
857
+ DELETE FROM screen_history_fts WHERE rowid = old.id;
858
+ END;
859
+
860
+ CREATE TRIGGER IF NOT EXISTS screen_history_fts_au AFTER UPDATE ON screen_history BEGIN
861
+ DELETE FROM screen_history_fts WHERE rowid = old.id;
862
+ INSERT INTO screen_history_fts(rowid, text_content, app_name, timestamp, user_id)
863
+ VALUES (new.id, COALESCE(new.text_content, ''), COALESCE(new.app_name, ''), new.timestamp, new.user_id);
864
+ END;
865
+
679
866
  CREATE VIRTUAL TABLE IF NOT EXISTS conversation_history_fts USING fts5(
680
867
  content,
681
868
  role UNINDEXED,
@@ -766,6 +953,16 @@ for (const col of [
766
953
  "ALTER TABLE conversation_history ADD COLUMN agent_id TEXT",
767
954
  "ALTER TABLE memories ADD COLUMN agent_id TEXT",
768
955
  "ALTER TABLE core_memory ADD COLUMN agent_id TEXT",
956
+ "ALTER TABLE ai_widgets ADD COLUMN widget_kind TEXT DEFAULT 'custom'",
957
+ "ALTER TABLE ai_widgets ADD COLUMN system_key TEXT",
958
+ "ALTER TABLE ai_widgets ADD COLUMN is_system INTEGER DEFAULT 0",
959
+ "ALTER TABLE memories ADD COLUMN scope_type TEXT DEFAULT 'agent'",
960
+ "ALTER TABLE memories ADD COLUMN scope_id TEXT",
961
+ "ALTER TABLE memories ADD COLUMN source_type TEXT",
962
+ "ALTER TABLE memories ADD COLUMN source_id TEXT",
963
+ "ALTER TABLE memories ADD COLUMN source_label TEXT",
964
+ "ALTER TABLE memories ADD COLUMN stale_after_days INTEGER",
965
+ "ALTER TABLE memories ADD COLUMN metadata_json TEXT DEFAULT '{}'",
769
966
  "ALTER TABLE scheduled_tasks ADD COLUMN run_at TEXT",
770
967
  "ALTER TABLE scheduled_tasks ADD COLUMN one_time INTEGER DEFAULT 0",
771
968
  "ALTER TABLE scheduled_tasks ADD COLUMN execution_mode TEXT DEFAULT 'prompt'",
@@ -818,12 +1015,15 @@ function createAgentScopedIndexes() {
818
1015
  const statements = [
819
1016
  ['agent_runs', 'CREATE INDEX IF NOT EXISTS idx_agent_runs_agent ON agent_runs(user_id, agent_id, created_at DESC)'],
820
1017
  ['integration_connections', 'CREATE INDEX IF NOT EXISTS idx_integration_connections_agent ON integration_connections(user_id, agent_id, provider_key, app_key)'],
1018
+ ['integration_provider_configs', 'CREATE INDEX IF NOT EXISTS idx_integration_provider_configs_agent ON integration_provider_configs(user_id, agent_id, provider_key)'],
821
1019
  ['messages', 'CREATE INDEX IF NOT EXISTS idx_messages_agent ON messages(user_id, agent_id, created_at DESC)'],
822
1020
  ['conversations', 'CREATE INDEX IF NOT EXISTS idx_conversations_agent ON conversations(user_id, agent_id, updated_at DESC)'],
823
1021
  ['scheduled_tasks', 'CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_agent ON scheduled_tasks(user_id, agent_id)'],
824
1022
  ['conversation_history', 'CREATE INDEX IF NOT EXISTS idx_conv_history_agent ON conversation_history(user_id, agent_id, created_at DESC)'],
825
1023
  ['memories', 'CREATE INDEX IF NOT EXISTS idx_memories_agent ON memories(user_id, agent_id, archived, updated_at DESC)'],
1024
+ ['memories', 'CREATE INDEX IF NOT EXISTS idx_memories_scope ON memories(user_id, agent_id, scope_type, scope_id, archived, updated_at DESC)'],
826
1025
  ['core_memory', 'CREATE INDEX IF NOT EXISTS idx_core_memory_agent ON core_memory(user_id, agent_id, key)'],
1026
+ ['ai_widgets', 'CREATE UNIQUE INDEX IF NOT EXISTS idx_ai_widgets_system_key ON ai_widgets(user_id, agent_id, system_key) WHERE system_key IS NOT NULL'],
827
1027
  ];
828
1028
  for (const [table, statement] of statements) {
829
1029
  if (!tableHasColumn(table, 'agent_id')) continue;
@@ -865,6 +1065,7 @@ function backfillAgentIds() {
865
1065
  'platform_connections',
866
1066
  'mcp_servers',
867
1067
  'integration_connections',
1068
+ 'integration_provider_configs',
868
1069
  'integration_oauth_states',
869
1070
  'scheduled_tasks',
870
1071
  'conversations',
@@ -884,7 +1085,19 @@ function backfillAgentIds() {
884
1085
  }
885
1086
  }
886
1087
  });
887
- tx();
1088
+
1089
+ try {
1090
+ runWithBusyRetry(
1091
+ () => tx(),
1092
+ { attempts: 8, label: 'backfillAgentIds' },
1093
+ );
1094
+ } catch (error) {
1095
+ if (isSqliteBusyError(error)) {
1096
+ console.warn('[Database] Skipping backfillAgentIds because the database stayed locked.');
1097
+ return;
1098
+ }
1099
+ throw error;
1100
+ }
888
1101
  }
889
1102
 
890
1103
  function backfillAgentPolicies() {
@@ -896,21 +1109,30 @@ function backfillAgentPolicies() {
896
1109
  return;
897
1110
  }
898
1111
  try {
899
- db.prepare(
900
- `UPDATE agents
901
- SET can_delegate = COALESCE(can_delegate, 1),
902
- can_be_delegated_to = COALESCE(can_be_delegated_to, 0),
903
- delegate_targets_json = COALESCE(delegate_targets_json, '[]')
904
- WHERE slug = 'main'`
905
- ).run();
906
- db.prepare(
907
- `UPDATE agents
908
- SET can_delegate = COALESCE(can_delegate, 0),
909
- can_be_delegated_to = COALESCE(can_be_delegated_to, 1),
910
- delegate_targets_json = COALESCE(delegate_targets_json, '[]')
911
- WHERE slug != 'main'`
912
- ).run();
913
- } catch {
1112
+ runWithBusyRetry(
1113
+ () => {
1114
+ db.prepare(
1115
+ `UPDATE agents
1116
+ SET can_delegate = COALESCE(can_delegate, 1),
1117
+ can_be_delegated_to = COALESCE(can_be_delegated_to, 0),
1118
+ delegate_targets_json = COALESCE(delegate_targets_json, '[]')
1119
+ WHERE slug = 'main'`
1120
+ ).run();
1121
+ db.prepare(
1122
+ `UPDATE agents
1123
+ SET can_delegate = COALESCE(can_delegate, 0),
1124
+ can_be_delegated_to = COALESCE(can_be_delegated_to, 1),
1125
+ delegate_targets_json = COALESCE(delegate_targets_json, '[]')
1126
+ WHERE slug != 'main'`
1127
+ ).run();
1128
+ },
1129
+ { attempts: 8, label: 'backfillAgentPolicies' },
1130
+ );
1131
+ } catch (error) {
1132
+ if (isSqliteBusyError(error)) {
1133
+ console.warn('[Database] Skipping backfillAgentPolicies because the database stayed locked.');
1134
+ return;
1135
+ }
914
1136
  // Keep startup resilient for partially migrated databases.
915
1137
  }
916
1138
  }
@@ -1246,6 +1468,83 @@ function migrateIntegrationOauthStatesTable() {
1246
1468
  `);
1247
1469
  }
1248
1470
 
1471
+ function migrateIntegrationProviderConfigsTable() {
1472
+ if (
1473
+ tableHasColumn('integration_provider_configs', 'agent_id') &&
1474
+ tableHasUniqueIndex('integration_provider_configs', ['user_id', 'agent_id', 'provider_key'])
1475
+ ) {
1476
+ const users = db.prepare('SELECT id FROM users').all();
1477
+ for (const user of users) {
1478
+ const agentId = getMainAgentId(user.id);
1479
+ db.prepare(
1480
+ 'UPDATE integration_provider_configs SET agent_id = ? WHERE user_id = ? AND agent_id IS NULL'
1481
+ ).run(agentId, user.id);
1482
+ }
1483
+ return;
1484
+ }
1485
+
1486
+ const rows = db
1487
+ .prepare('SELECT * FROM integration_provider_configs ORDER BY id ASC')
1488
+ .all();
1489
+
1490
+ db.exec('BEGIN');
1491
+ try {
1492
+ db.exec(`
1493
+ ALTER TABLE integration_provider_configs RENAME TO integration_provider_configs_legacy_agent_scope;
1494
+
1495
+ CREATE TABLE integration_provider_configs (
1496
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
1497
+ user_id INTEGER NOT NULL,
1498
+ agent_id TEXT,
1499
+ provider_key TEXT NOT NULL,
1500
+ config_json TEXT DEFAULT '{}',
1501
+ created_at TEXT DEFAULT (datetime('now')),
1502
+ updated_at TEXT DEFAULT (datetime('now')),
1503
+ FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
1504
+ FOREIGN KEY (agent_id) REFERENCES agents(id) ON DELETE SET NULL,
1505
+ UNIQUE(user_id, agent_id, provider_key)
1506
+ );
1507
+ `);
1508
+ const insert = db.prepare(`
1509
+ INSERT OR REPLACE INTO integration_provider_configs (
1510
+ id,
1511
+ user_id,
1512
+ agent_id,
1513
+ provider_key,
1514
+ config_json,
1515
+ created_at,
1516
+ updated_at
1517
+ ) VALUES (?, ?, ?, ?, ?, ?, ?)
1518
+ `);
1519
+
1520
+ for (const row of rows) {
1521
+ insert.run(
1522
+ row.id,
1523
+ row.user_id,
1524
+ row.agent_id || getMainAgentId(row.user_id),
1525
+ row.provider_key,
1526
+ row.config_json,
1527
+ row.created_at,
1528
+ row.updated_at,
1529
+ );
1530
+ }
1531
+
1532
+ db.exec(`
1533
+ DROP TABLE integration_provider_configs_legacy_agent_scope;
1534
+ CREATE INDEX IF NOT EXISTS idx_integration_provider_configs_agent
1535
+ ON integration_provider_configs(user_id, agent_id, provider_key);
1536
+ `);
1537
+ db.exec('COMMIT');
1538
+ } catch (error) {
1539
+ try {
1540
+ db.exec('ROLLBACK');
1541
+ } catch {
1542
+ // Ignore rollback errors and rethrow the original migration failure.
1543
+ }
1544
+ throw error;
1545
+ }
1546
+ }
1547
+
1249
1548
  function migrateIntegrationSecretStorage() {
1250
1549
  try {
1251
1550
  const connectionRows = db
@@ -1278,6 +1577,22 @@ function migrateIntegrationSecretStorage() {
1278
1577
  } catch {
1279
1578
  // Preserve startup even if a row cannot be re-encrypted.
1280
1579
  }
1580
+
1581
+ try {
1582
+ const providerRows = db
1583
+ .prepare('SELECT id, config_json FROM integration_provider_configs')
1584
+ .all();
1585
+ const updateProviderConfig = db.prepare(
1586
+ 'UPDATE integration_provider_configs SET config_json = ? WHERE id = ?',
1587
+ );
1588
+ for (const row of providerRows) {
1589
+ const current = String(row.config_json || '');
1590
+ if (!current || isEncryptedValue(current)) continue;
1591
+ updateProviderConfig.run(encryptValue(current), row.id);
1592
+ }
1593
+ } catch {
1594
+ // Preserve startup even if a row cannot be re-encrypted.
1595
+ }
1281
1596
  }
1282
1597
 
1283
1598
  function backfillVerifiedAccountEmails() {
@@ -1351,11 +1666,38 @@ rebuildPlatformConnectionsForAgents();
1351
1666
  rebuildCoreMemoryForAgents();
1352
1667
  migrateIntegrationConnectionsTable();
1353
1668
  migrateIntegrationOauthStatesTable();
1669
+ migrateIntegrationProviderConfigsTable();
1354
1670
  createAgentScopedIndexes();
1355
1671
  migrateIntegrationSecretStorage();
1356
1672
  backfillVerifiedAccountEmails();
1357
1673
  rebuildFtsForAgents();
1358
1674
 
1675
+ function migrateUsersOnboarding() {
1676
+ try {
1677
+ const columns = db.pragma('table_info(users)');
1678
+ const hasOnboardingCol = columns.some((c) => c.name === 'has_completed_onboarding');
1679
+ if (!hasOnboardingCol) {
1680
+ db.exec('ALTER TABLE users ADD COLUMN has_completed_onboarding INTEGER DEFAULT 0');
1681
+ }
1682
+ } catch (err) {
1683
+ console.warn('Could not add has_completed_onboarding column:', err.message);
1684
+ }
1685
+ }
1686
+ migrateUsersOnboarding();
1687
+
1688
+ function migrateUsersDisplayName() {
1689
+ try {
1690
+ const columns = db.pragma('table_info(users)');
1691
+ const hasDisplayNameCol = columns.some((c) => c.name === 'display_name');
1692
+ if (!hasDisplayNameCol) {
1693
+ db.exec('ALTER TABLE users ADD COLUMN display_name TEXT');
1694
+ }
1695
+ } catch (err) {
1696
+ console.warn('Could not add display_name column:', err.message);
1697
+ }
1698
+ }
1699
+ migrateUsersDisplayName();
1700
+
1359
1701
  try {
1360
1702
  db.exec(`
1361
1703
  INSERT OR REPLACE INTO conversation_history_fts(rowid, content, role, user_id, agent_id, agent_run_id)
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "neoagent-guest-agent-android",
3
+ "private": true,
4
+ "version": "1.0.0",
5
+ "description": "Guest runtime for NeoAgent Android and CLI services",
6
+ "engines": {
7
+ "node": ">=20"
8
+ },
9
+ "dependencies": {
10
+ "express": "^4.21.2",
11
+ "proper-lockfile": "^4.1.2"
12
+ }
13
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "neoagent-guest-agent-browser",
3
+ "private": true,
4
+ "version": "1.0.0",
5
+ "description": "Guest runtime for NeoAgent browser and CLI services",
6
+ "engines": {
7
+ "node": ">=20"
8
+ },
9
+ "dependencies": {
10
+ "express": "^4.21.2",
11
+ "playwright-chromium": "^1.59.1",
12
+ "proper-lockfile": "^4.1.2"
13
+ }
14
+ }