neoagent 2.3.1-beta.57 → 2.3.1-beta.59
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/flutter_app/lib/features/onboarding/onboarding_chrome.dart +569 -0
- package/flutter_app/lib/features/onboarding/onboarding_messaging_step.dart +125 -230
- package/flutter_app/lib/features/onboarding/onboarding_model_step.dart +183 -248
- package/flutter_app/lib/features/onboarding/onboarding_shell.dart +3 -5
- package/flutter_app/lib/features/onboarding/onboarding_video_step.dart +140 -107
- package/flutter_app/lib/features/onboarding/onboarding_welcome_step.dart +32 -150
- package/flutter_app/lib/main_app_shell.dart +439 -19
- package/flutter_app/lib/main_controller.dart +12 -6
- package/flutter_app/lib/main_devices.dart +204 -109
- package/flutter_app/lib/main_settings.dart +16 -77
- package/flutter_app/lib/main_shared.dart +1 -0
- package/package.json +1 -1
- package/server/public/.last_build_id +1 -1
- package/server/public/assets/fonts/MaterialIcons-Regular.otf +0 -0
- package/server/public/flutter_bootstrap.js +1 -1
- package/server/public/main.dart.js +75022 -74341
|
@@ -443,6 +443,7 @@ class _DevicesPanelState extends State<DevicesPanel> {
|
|
|
443
443
|
if (_isDesktop) ...<Widget>[
|
|
444
444
|
const SizedBox(height: 14),
|
|
445
445
|
DropdownButtonFormField<String>(
|
|
446
|
+
isExpanded: true,
|
|
446
447
|
initialValue: selectedDesktopDevice?['deviceId']
|
|
447
448
|
?.toString(),
|
|
448
449
|
decoration: const InputDecoration(
|
|
@@ -464,7 +465,12 @@ class _DevicesPanelState extends State<DevicesPanel> {
|
|
|
464
465
|
: 'offline';
|
|
465
466
|
return DropdownMenuItem<String>(
|
|
466
467
|
value: deviceId,
|
|
467
|
-
child: Text(
|
|
468
|
+
child: Text(
|
|
469
|
+
'$label · $os · $state',
|
|
470
|
+
maxLines: 1,
|
|
471
|
+
overflow: TextOverflow.ellipsis,
|
|
472
|
+
softWrap: false,
|
|
473
|
+
),
|
|
468
474
|
);
|
|
469
475
|
}).toList(),
|
|
470
476
|
onChanged: controller.isRunningDeviceAction
|
|
@@ -652,94 +658,96 @@ class _DeviceSurfaceHeader extends StatelessWidget {
|
|
|
652
658
|
|
|
653
659
|
@override
|
|
654
660
|
Widget build(BuildContext context) {
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
661
|
+
return LayoutBuilder(
|
|
662
|
+
builder: (context, constraints) {
|
|
663
|
+
final compact = constraints.maxWidth < 720;
|
|
664
|
+
final androidStarting = androidRuntime['starting'] == true;
|
|
665
|
+
final androidVersion = _androidRuntimeVersionLabel(androidRuntime);
|
|
666
|
+
final selectedDesktop = desktopDevices
|
|
667
|
+
.where((device) => device['deviceId'] == selectedDesktopDeviceId)
|
|
668
|
+
.cast<Map<String, dynamic>?>()
|
|
669
|
+
.firstWhere((device) => device != null, orElse: () => null);
|
|
670
|
+
final desktopOnlineCount = desktopDevices
|
|
671
|
+
.where((device) => device['online'] == true)
|
|
672
|
+
.length;
|
|
673
|
+
final title = switch (surface) {
|
|
674
|
+
_DeviceSurface.browser =>
|
|
675
|
+
(browserPageInfo['title']?.toString().trim().isNotEmpty ?? false)
|
|
676
|
+
? browserPageInfo['title'].toString()
|
|
677
|
+
: 'Live Browser',
|
|
678
|
+
_DeviceSurface.android => 'Android Phone',
|
|
679
|
+
_DeviceSurface.desktop =>
|
|
680
|
+
selectedDesktop?['label']?.toString().trim().isNotEmpty == true
|
|
681
|
+
? selectedDesktop!['label'].toString()
|
|
682
|
+
: 'Desktop Companion',
|
|
683
|
+
};
|
|
684
|
+
final subtitle = switch (surface) {
|
|
685
|
+
_DeviceSurface.browser =>
|
|
686
|
+
browserExtensionPreferred && !browserExtensionActive
|
|
687
|
+
? 'No extension device is active. Using the $browserFallbackLabel browser fallback.'
|
|
688
|
+
: (browserPageInfo['url']?.toString() ??
|
|
689
|
+
'Ready for navigation'),
|
|
690
|
+
_DeviceSurface.android =>
|
|
691
|
+
androidOnline
|
|
692
|
+
? androidVersion == null
|
|
693
|
+
? 'Tap and swipe directly on the preview.'
|
|
694
|
+
: '$androidVersion · Tap and swipe directly on the preview.'
|
|
695
|
+
: androidStarting
|
|
696
|
+
? (androidRuntime['startupPhase']
|
|
697
|
+
?.toString()
|
|
698
|
+
.trim()
|
|
699
|
+
.isNotEmpty ??
|
|
700
|
+
false)
|
|
701
|
+
? androidRuntime['startupPhase'].toString()
|
|
702
|
+
: 'Starting the phone. This can take a little while.'
|
|
703
|
+
: (androidRuntime['lastLogLine']
|
|
704
|
+
?.toString()
|
|
705
|
+
.trim()
|
|
706
|
+
.isNotEmpty ??
|
|
687
707
|
false)
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
children: <Widget>[
|
|
732
|
-
Container(
|
|
733
|
-
width: 48,
|
|
734
|
-
height: 48,
|
|
735
|
-
decoration: BoxDecoration(
|
|
736
|
-
color: _accentMuted,
|
|
737
|
-
borderRadius: BorderRadius.circular(14),
|
|
738
|
-
),
|
|
739
|
-
child: Icon(surface.icon, color: _textPrimary),
|
|
740
|
-
),
|
|
741
|
-
const SizedBox(width: 14),
|
|
742
|
-
Expanded(
|
|
708
|
+
? androidRuntime['lastLogLine'].toString()
|
|
709
|
+
: androidVersion != null
|
|
710
|
+
? '$androidVersion selected. Phone is offline.'
|
|
711
|
+
: 'Phone is offline. Open or start it from below.',
|
|
712
|
+
_DeviceSurface.desktop =>
|
|
713
|
+
selectedDesktop == null
|
|
714
|
+
? desktopOnlineCount > 1
|
|
715
|
+
? 'Multiple desktop companions are online. Pick the machine you want to control.'
|
|
716
|
+
: desktopOnlineCount == 1
|
|
717
|
+
? 'One desktop companion is online. Open the surface to fetch the latest frame.'
|
|
718
|
+
: 'No desktop companion is online. Enable Companion Mode on a signed-in desktop app.'
|
|
719
|
+
: '${selectedDesktop['platform'] ?? 'desktop'} · ${selectedDesktop['hostname'] ?? 'unknown host'}',
|
|
720
|
+
};
|
|
721
|
+
final statusLabel = surface == _DeviceSurface.browser
|
|
722
|
+
? browserExtensionPreferred && !browserExtensionActive
|
|
723
|
+
? 'Fallback'
|
|
724
|
+
: browserExtensionActive
|
|
725
|
+
? 'Extension'
|
|
726
|
+
: (browserStatus['launched'] == true ? 'Live' : 'Sleeping')
|
|
727
|
+
: surface == _DeviceSurface.desktop
|
|
728
|
+
? selectedDesktop == null
|
|
729
|
+
? (desktopOnlineCount > 0 ? 'Select Device' : 'Offline')
|
|
730
|
+
: (selectedDesktop['paused'] == true
|
|
731
|
+
? 'Paused'
|
|
732
|
+
: (selectedDesktop['online'] == true
|
|
733
|
+
? 'Live'
|
|
734
|
+
: 'Offline'))
|
|
735
|
+
: (androidOnline
|
|
736
|
+
? 'Live'
|
|
737
|
+
: androidStarting
|
|
738
|
+
? 'Starting'
|
|
739
|
+
: 'Offline');
|
|
740
|
+
final statusColor = surface == _DeviceSurface.browser
|
|
741
|
+
? (browserStatus['launched'] == true ? _success : _warning)
|
|
742
|
+
: surface == _DeviceSurface.desktop
|
|
743
|
+
? (selectedDesktop?['paused'] == true
|
|
744
|
+
? _warning
|
|
745
|
+
: (selectedDesktop?['online'] == true ? _success : _warning))
|
|
746
|
+
: (androidOnline
|
|
747
|
+
? _success
|
|
748
|
+
: (androidStarting ? _accent : _warning));
|
|
749
|
+
|
|
750
|
+
final textColumn = Expanded(
|
|
743
751
|
child: Column(
|
|
744
752
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
745
753
|
children: <Widget>[
|
|
@@ -758,10 +766,59 @@ class _DeviceSurfaceHeader extends StatelessWidget {
|
|
|
758
766
|
),
|
|
759
767
|
],
|
|
760
768
|
),
|
|
761
|
-
)
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
769
|
+
);
|
|
770
|
+
|
|
771
|
+
final statusChip = Flexible(
|
|
772
|
+
child: Align(
|
|
773
|
+
alignment: compact ? Alignment.centerLeft : Alignment.centerRight,
|
|
774
|
+
child: _DotStatus(label: statusLabel, color: statusColor),
|
|
775
|
+
),
|
|
776
|
+
);
|
|
777
|
+
|
|
778
|
+
if (compact) {
|
|
779
|
+
return Column(
|
|
780
|
+
crossAxisAlignment: CrossAxisAlignment.start,
|
|
781
|
+
children: <Widget>[
|
|
782
|
+
Row(
|
|
783
|
+
crossAxisAlignment: CrossAxisAlignment.start,
|
|
784
|
+
children: <Widget>[
|
|
785
|
+
Container(
|
|
786
|
+
width: 48,
|
|
787
|
+
height: 48,
|
|
788
|
+
decoration: BoxDecoration(
|
|
789
|
+
color: _accentMuted,
|
|
790
|
+
borderRadius: BorderRadius.circular(14),
|
|
791
|
+
),
|
|
792
|
+
child: Icon(surface.icon, color: _textPrimary),
|
|
793
|
+
),
|
|
794
|
+
const SizedBox(width: 14),
|
|
795
|
+
textColumn,
|
|
796
|
+
],
|
|
797
|
+
),
|
|
798
|
+
const SizedBox(height: 12),
|
|
799
|
+
statusChip,
|
|
800
|
+
],
|
|
801
|
+
);
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
return Row(
|
|
805
|
+
children: <Widget>[
|
|
806
|
+
Container(
|
|
807
|
+
width: 48,
|
|
808
|
+
height: 48,
|
|
809
|
+
decoration: BoxDecoration(
|
|
810
|
+
color: _accentMuted,
|
|
811
|
+
borderRadius: BorderRadius.circular(14),
|
|
812
|
+
),
|
|
813
|
+
child: Icon(surface.icon, color: _textPrimary),
|
|
814
|
+
),
|
|
815
|
+
const SizedBox(width: 14),
|
|
816
|
+
textColumn,
|
|
817
|
+
const SizedBox(width: 12),
|
|
818
|
+
statusChip,
|
|
819
|
+
],
|
|
820
|
+
);
|
|
821
|
+
},
|
|
765
822
|
);
|
|
766
823
|
}
|
|
767
824
|
}
|
|
@@ -1047,31 +1104,69 @@ class _SurfaceSwitcher extends StatelessWidget {
|
|
|
1047
1104
|
|
|
1048
1105
|
@override
|
|
1049
1106
|
Widget build(BuildContext context) {
|
|
1050
|
-
return
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
onPressed: onPrevious,
|
|
1055
|
-
icon: Icon(Icons.arrow_back_ios_new_rounded),
|
|
1056
|
-
),
|
|
1057
|
-
const SizedBox(width: 14),
|
|
1058
|
-
Column(
|
|
1107
|
+
return LayoutBuilder(
|
|
1108
|
+
builder: (context, constraints) {
|
|
1109
|
+
final compact = constraints.maxWidth < 520;
|
|
1110
|
+
final labelColumn = Column(
|
|
1059
1111
|
mainAxisSize: MainAxisSize.min,
|
|
1060
1112
|
children: <Widget>[
|
|
1061
1113
|
Text(
|
|
1062
1114
|
surface.label,
|
|
1115
|
+
textAlign: TextAlign.center,
|
|
1063
1116
|
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w800),
|
|
1064
1117
|
),
|
|
1065
1118
|
const SizedBox(height: 4),
|
|
1066
|
-
Text(
|
|
1119
|
+
Text(
|
|
1120
|
+
surface.helper,
|
|
1121
|
+
textAlign: TextAlign.center,
|
|
1122
|
+
maxLines: compact ? 3 : 2,
|
|
1123
|
+
overflow: TextOverflow.ellipsis,
|
|
1124
|
+
style: TextStyle(color: _textSecondary),
|
|
1125
|
+
),
|
|
1067
1126
|
],
|
|
1068
|
-
)
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1127
|
+
);
|
|
1128
|
+
|
|
1129
|
+
if (compact) {
|
|
1130
|
+
return Column(
|
|
1131
|
+
mainAxisSize: MainAxisSize.min,
|
|
1132
|
+
children: <Widget>[
|
|
1133
|
+
Row(
|
|
1134
|
+
mainAxisAlignment: MainAxisAlignment.center,
|
|
1135
|
+
children: <Widget>[
|
|
1136
|
+
IconButton.filledTonal(
|
|
1137
|
+
onPressed: onPrevious,
|
|
1138
|
+
icon: Icon(Icons.arrow_back_ios_new_rounded),
|
|
1139
|
+
),
|
|
1140
|
+
const SizedBox(width: 14),
|
|
1141
|
+
Flexible(child: labelColumn),
|
|
1142
|
+
const SizedBox(width: 14),
|
|
1143
|
+
IconButton.filledTonal(
|
|
1144
|
+
onPressed: onNext,
|
|
1145
|
+
icon: Icon(Icons.arrow_forward_ios_rounded),
|
|
1146
|
+
),
|
|
1147
|
+
],
|
|
1148
|
+
),
|
|
1149
|
+
],
|
|
1150
|
+
);
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
return Row(
|
|
1154
|
+
mainAxisAlignment: MainAxisAlignment.center,
|
|
1155
|
+
children: <Widget>[
|
|
1156
|
+
IconButton.filledTonal(
|
|
1157
|
+
onPressed: onPrevious,
|
|
1158
|
+
icon: Icon(Icons.arrow_back_ios_new_rounded),
|
|
1159
|
+
),
|
|
1160
|
+
const SizedBox(width: 14),
|
|
1161
|
+
labelColumn,
|
|
1162
|
+
const SizedBox(width: 14),
|
|
1163
|
+
IconButton.filledTonal(
|
|
1164
|
+
onPressed: onNext,
|
|
1165
|
+
icon: Icon(Icons.arrow_forward_ios_rounded),
|
|
1166
|
+
),
|
|
1167
|
+
],
|
|
1168
|
+
);
|
|
1169
|
+
},
|
|
1075
1170
|
);
|
|
1076
1171
|
}
|
|
1077
1172
|
}
|
|
@@ -265,8 +265,6 @@ class _SettingsPanelState extends State<SettingsPanel> {
|
|
|
265
265
|
],
|
|
266
266
|
_buildSettingsOverview(controller, availableModels.length),
|
|
267
267
|
const SizedBox(height: 16),
|
|
268
|
-
_buildManagementSection(controller),
|
|
269
|
-
const SizedBox(height: 16),
|
|
270
268
|
_buildWorkspaceSection(controller),
|
|
271
269
|
const SizedBox(height: 16),
|
|
272
270
|
_buildModelsSection(
|
|
@@ -344,6 +342,22 @@ class _SettingsPanelState extends State<SettingsPanel> {
|
|
|
344
342
|
),
|
|
345
343
|
],
|
|
346
344
|
),
|
|
345
|
+
const SizedBox(height: 14),
|
|
346
|
+
Align(
|
|
347
|
+
alignment: Alignment.centerLeft,
|
|
348
|
+
child: OutlinedButton.icon(
|
|
349
|
+
onPressed: controller.reopenOnboarding,
|
|
350
|
+
style: OutlinedButton.styleFrom(
|
|
351
|
+
visualDensity: VisualDensity.compact,
|
|
352
|
+
padding: const EdgeInsets.symmetric(
|
|
353
|
+
horizontal: 12,
|
|
354
|
+
vertical: 10,
|
|
355
|
+
),
|
|
356
|
+
),
|
|
357
|
+
icon: const Icon(Icons.replay_rounded, size: 18),
|
|
358
|
+
label: const Text('Redo onboarding'),
|
|
359
|
+
),
|
|
360
|
+
),
|
|
347
361
|
],
|
|
348
362
|
),
|
|
349
363
|
),
|
|
@@ -453,81 +467,6 @@ class _SettingsPanelState extends State<SettingsPanel> {
|
|
|
453
467
|
);
|
|
454
468
|
}
|
|
455
469
|
|
|
456
|
-
Widget _buildManagementSection(NeoAgentController controller) {
|
|
457
|
-
return Card(
|
|
458
|
-
child: Padding(
|
|
459
|
-
padding: const EdgeInsets.all(20),
|
|
460
|
-
child: Column(
|
|
461
|
-
crossAxisAlignment: CrossAxisAlignment.start,
|
|
462
|
-
children: <Widget>[
|
|
463
|
-
const _SectionTitle('Subcategories'),
|
|
464
|
-
const SizedBox(height: 10),
|
|
465
|
-
Text(
|
|
466
|
-
'Open settings areas that have their own dedicated management screens.',
|
|
467
|
-
style: TextStyle(color: _textSecondary, height: 1.45),
|
|
468
|
-
),
|
|
469
|
-
const SizedBox(height: 16),
|
|
470
|
-
InkWell(
|
|
471
|
-
onTap: () => controller.setSelectedSection(AppSection.agents),
|
|
472
|
-
borderRadius: BorderRadius.circular(20),
|
|
473
|
-
child: Ink(
|
|
474
|
-
decoration: BoxDecoration(
|
|
475
|
-
color: _bgSecondary.withValues(alpha: 0.7),
|
|
476
|
-
borderRadius: BorderRadius.circular(20),
|
|
477
|
-
border: Border.all(color: _border),
|
|
478
|
-
),
|
|
479
|
-
child: Padding(
|
|
480
|
-
padding: const EdgeInsets.all(16),
|
|
481
|
-
child: Row(
|
|
482
|
-
children: <Widget>[
|
|
483
|
-
Container(
|
|
484
|
-
width: 44,
|
|
485
|
-
height: 44,
|
|
486
|
-
decoration: BoxDecoration(
|
|
487
|
-
color: _accentMuted,
|
|
488
|
-
borderRadius: BorderRadius.circular(14),
|
|
489
|
-
),
|
|
490
|
-
child: Icon(
|
|
491
|
-
Icons.smart_toy_outlined,
|
|
492
|
-
color: _accentHover,
|
|
493
|
-
),
|
|
494
|
-
),
|
|
495
|
-
const SizedBox(width: 14),
|
|
496
|
-
Expanded(
|
|
497
|
-
child: Column(
|
|
498
|
-
crossAxisAlignment: CrossAxisAlignment.start,
|
|
499
|
-
children: <Widget>[
|
|
500
|
-
Text(
|
|
501
|
-
'Agents',
|
|
502
|
-
style: TextStyle(
|
|
503
|
-
fontWeight: FontWeight.w700,
|
|
504
|
-
color: _textPrimary,
|
|
505
|
-
),
|
|
506
|
-
),
|
|
507
|
-
const SizedBox(height: 4),
|
|
508
|
-
Text(
|
|
509
|
-
'Manage specialist agents, routing roles, memory separation, and account assignment.',
|
|
510
|
-
style: TextStyle(
|
|
511
|
-
color: _textSecondary,
|
|
512
|
-
height: 1.4,
|
|
513
|
-
),
|
|
514
|
-
),
|
|
515
|
-
],
|
|
516
|
-
),
|
|
517
|
-
),
|
|
518
|
-
const SizedBox(width: 12),
|
|
519
|
-
Icon(Icons.chevron_right_rounded, color: _textSecondary),
|
|
520
|
-
],
|
|
521
|
-
),
|
|
522
|
-
),
|
|
523
|
-
),
|
|
524
|
-
),
|
|
525
|
-
],
|
|
526
|
-
),
|
|
527
|
-
),
|
|
528
|
-
);
|
|
529
|
-
}
|
|
530
|
-
|
|
531
470
|
Widget _buildModelsSection({
|
|
532
471
|
required NeoAgentController controller,
|
|
533
472
|
required List<DropdownMenuItem<String>> modelChoices,
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
154775e7dc374e782403c776404afd0b
|
|
Binary file
|
|
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"42d3d75a56efe1a2e9902f52dc8006099c45d9
|
|
|
37
37
|
|
|
38
38
|
_flutter.loader.load({
|
|
39
39
|
serviceWorkerSettings: {
|
|
40
|
-
serviceWorkerVersion: "
|
|
40
|
+
serviceWorkerVersion: "3080522326" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
|
|
41
41
|
}
|
|
42
42
|
});
|