neoagent 2.4.1-beta.19 → 2.4.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.
Files changed (55) hide show
  1. package/README.md +4 -1
  2. package/docs/getting-started.md +9 -3
  3. package/flutter_app/assets/branding/app_icon_light_1024.png +0 -0
  4. package/flutter_app/assets/branding/app_icon_light_128.png +0 -0
  5. package/flutter_app/assets/branding/app_icon_light_192.png +0 -0
  6. package/flutter_app/assets/branding/app_icon_light_256.png +0 -0
  7. package/flutter_app/assets/branding/app_icon_light_32.png +0 -0
  8. package/flutter_app/assets/branding/app_icon_light_512.png +0 -0
  9. package/flutter_app/assets/branding/app_icon_light_64.png +0 -0
  10. package/flutter_app/assets/branding/tray_icon_light_template.png +0 -0
  11. package/flutter_app/lib/features/location/location_service.dart +3 -0
  12. package/flutter_app/lib/main.dart +1 -0
  13. package/flutter_app/lib/main_account_settings.dart +9 -33
  14. package/flutter_app/lib/main_app_shell.dart +237 -197
  15. package/flutter_app/lib/main_controller.dart +0 -25
  16. package/flutter_app/lib/main_devices.dart +2 -0
  17. package/flutter_app/lib/main_models.dart +144 -0
  18. package/flutter_app/lib/main_operations.dart +150 -19
  19. package/flutter_app/lib/main_shared.dart +642 -195
  20. package/flutter_app/lib/main_theme.dart +2 -0
  21. package/flutter_app/lib/src/android_apk_drop_zone_web.dart +3 -1
  22. package/flutter_app/lib/src/security/password_strength.dart +84 -0
  23. package/flutter_app/lib/src/theme/palette.dart +15 -15
  24. package/flutter_app/pubspec.yaml +3 -0
  25. package/flutter_app/web/favicon_light.svg +3 -0
  26. package/flutter_app/web/icons/Icon-192-light.png +0 -0
  27. package/flutter_app/web/icons/Icon-512-light.png +0 -0
  28. package/flutter_app/web/icons/Icon-maskable-192-light.png +0 -0
  29. package/flutter_app/web/icons/Icon-maskable-512-light.png +0 -0
  30. package/lib/manager.js +282 -81
  31. package/package.json +17 -3
  32. package/server/config/origins.js +3 -1
  33. package/server/db/database.js +73 -0
  34. package/server/public/.last_build_id +1 -1
  35. package/server/public/assets/AssetManifest.bin +1 -1
  36. package/server/public/assets/AssetManifest.bin.json +1 -1
  37. package/server/public/assets/assets/branding/app_icon_light_256.png +0 -0
  38. package/server/public/assets/assets/branding/app_icon_light_512.png +0 -0
  39. package/server/public/assets/assets/branding/tray_icon_light_template.png +0 -0
  40. package/server/public/assets/fonts/MaterialIcons-Regular.otf +0 -0
  41. package/server/public/favicon_light.svg +3 -0
  42. package/server/public/flutter_bootstrap.js +1 -1
  43. package/server/public/icons/Icon-192-light.png +0 -0
  44. package/server/public/icons/Icon-512-light.png +0 -0
  45. package/server/public/icons/Icon-maskable-192-light.png +0 -0
  46. package/server/public/icons/Icon-maskable-512-light.png +0 -0
  47. package/server/public/main.dart.js +68769 -68268
  48. package/server/routes/agent_profiles.js +3 -0
  49. package/server/routes/memory.js +22 -1
  50. package/server/services/account/password_policy.js +6 -1
  51. package/server/services/memory/intelligence.js +181 -0
  52. package/server/services/memory/manager.js +475 -25
  53. package/server/utils/security.js +3 -0
  54. package/server/services/memory/openhuman_uplift.test.js +0 -98
  55. package/server/utils/version.test.js +0 -39
package/README.md CHANGED
@@ -36,7 +36,10 @@ npm install -g neoagent
36
36
  neoagent install
37
37
  ```
38
38
 
39
- Available at **http://localhost:3333** when complete.
39
+ `neoagent install` runs a preflight, writes a secure default config when setup
40
+ cannot prompt, installs Node dependencies, builds or uses the bundled web
41
+ client, bootstraps supported system tools where possible, and starts the
42
+ service. Available at **http://localhost:3333** when complete.
40
43
 
41
44
  ## Manage
42
45
 
@@ -7,12 +7,16 @@ Install takes about 5 minutes. The first VM boot downloads and configures an Ubu
7
7
  | | |
8
8
  |---|---|
9
9
  | Node.js | 20 or newer |
10
- | QEMU | for VM-isolated browser and Android |
10
+ | QEMU | installed automatically when supported; used for VM-isolated browser and Android |
11
11
  | AI provider key | Anthropic, OpenAI, Gemini, Grok, MiniMax, or local Ollama |
12
12
 
13
13
  No API key is required if you only use local Ollama.
14
14
 
15
- ### Install QEMU
15
+ ### Optional manual QEMU install
16
+
17
+ `neoagent install` tries to install QEMU on supported macOS and Linux package
18
+ managers. If the machine does not have a supported package manager yet, install
19
+ QEMU manually and rerun `neoagent install`.
16
20
 
17
21
  ```bash
18
22
  # macOS
@@ -29,7 +33,9 @@ npm install -g neoagent
29
33
  neoagent install
30
34
  ```
31
35
 
32
- This runs setup (if no existing config), installs dependencies, and starts the service.
36
+ This runs a preflight, creates or updates config, installs dependencies, builds
37
+ or uses the bundled web client, starts the service, and prints any remaining
38
+ machine-specific action items.
33
39
 
34
40
  Open **http://localhost:3333** in your browser when the install finishes.
35
41
 
@@ -18,6 +18,7 @@ class LocationService {
18
18
 
19
19
  LocationPermission permission = await Geolocator.checkPermission();
20
20
  if (permission == LocationPermission.denied) {
21
+ if (!context.mounted) return;
21
22
  // Ask user for permission with a nice UI
22
23
  bool userAgreed = await _showPermissionRationale(context);
23
24
  if (userAgreed) {
@@ -37,6 +38,7 @@ class LocationService {
37
38
  }
38
39
 
39
40
  Future<bool> _showPermissionRationale(BuildContext context) async {
41
+ if (!context.mounted) return false;
40
42
  return await showDialog<bool>(
41
43
  context: context,
42
44
  builder: (context) => AlertDialog(
@@ -95,6 +97,7 @@ class LocationService {
95
97
  }
96
98
  }
97
99
 
100
+ // ignore: unused_element
98
101
  Future<void> _triggerBackendGeofence(String backendUrl, String token, String label) async {
99
102
  try {
100
103
  await http.post(
@@ -39,6 +39,7 @@ import 'src/messaging_access_summary.dart';
39
39
  import 'src/oauth_launcher.dart';
40
40
  import 'src/recording_bridge.dart';
41
41
  import 'src/recording_payloads.dart';
42
+ import 'src/security/password_strength.dart';
42
43
  import 'src/stream_renderer.dart';
43
44
  import 'src/theme/palette.dart';
44
45
  import 'src/web_app_update_monitor.dart';
@@ -28,38 +28,14 @@ _PasswordStrengthInfo _passwordStrengthInfo({
28
28
  color: _borderLight,
29
29
  );
30
30
  }
31
- final lower = RegExp(r'[a-z]').hasMatch(value);
32
- final upper = RegExp(r'[A-Z]').hasMatch(value);
33
- final digits = RegExp(r'[0-9]').hasMatch(value);
34
- final symbols = RegExp(r'[^A-Za-z0-9]').hasMatch(value);
35
- final variety = <bool>[
36
- lower,
37
- upper,
38
- digits,
39
- symbols,
40
- ].where((item) => item).length;
41
- final normalized = value.toLowerCase();
42
- final userHints = <String>{
43
- username.trim().toLowerCase(),
44
- email.trim().toLowerCase(),
45
- email.trim().toLowerCase().split('@').first,
46
- }.where((item) => item.length >= 3);
47
- final containsUserInfo = userHints.any(normalized.contains);
48
- final obviousPattern =
49
- RegExp(r'(.)\1\1').hasMatch(value) ||
50
- normalized.contains('password') ||
51
- normalized.contains('1234') ||
52
- normalized.contains('qwerty');
53
-
54
- var score = 0;
55
- if (value.length >= 8) score += 1;
56
- if (value.length >= 12) score += 1;
57
- if (variety >= 3) score += 1;
58
- if (variety == 4 || value.length >= 16) score += 1;
59
- if (containsUserInfo || obviousPattern) score -= 1;
60
- score = score.clamp(0, 4);
31
+ final evaluation = evaluatePasswordStrength(
32
+ password: password,
33
+ username: username,
34
+ email: email,
35
+ );
36
+ final score = evaluation.score;
61
37
 
62
- if (value.length < 8) {
38
+ if (!evaluation.hasMinimumLength) {
63
39
  return _PasswordStrengthInfo(
64
40
  score: 1,
65
41
  label: 'Weak',
@@ -67,7 +43,7 @@ _PasswordStrengthInfo _passwordStrengthInfo({
67
43
  color: _danger,
68
44
  );
69
45
  }
70
- if (containsUserInfo) {
46
+ if (evaluation.containsUserInfo) {
71
47
  return _PasswordStrengthInfo(
72
48
  score: 2,
73
49
  label: 'Fair',
@@ -75,7 +51,7 @@ _PasswordStrengthInfo _passwordStrengthInfo({
75
51
  color: _warning,
76
52
  );
77
53
  }
78
- if (obviousPattern) {
54
+ if (evaluation.obviousPattern) {
79
55
  return _PasswordStrengthInfo(
80
56
  score: 2,
81
57
  label: 'Fair',