neoagent 2.3.1-beta.65 → 2.3.1-beta.66

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.
@@ -2484,6 +2484,9 @@ class _AiWidgetInfoPane extends StatelessWidget {
2484
2484
  hasUsefulRows ||
2485
2485
  chips.isNotEmpty ||
2486
2486
  body.trim().isNotEmpty;
2487
+ final displayName = _widgetDisplayName(item.name);
2488
+ final titleIsDuplicate =
2489
+ _widgetSanitizedText(title).toLowerCase() == displayName.toLowerCase();
2487
2490
  return Column(
2488
2491
  crossAxisAlignment: CrossAxisAlignment.start,
2489
2492
  children: <Widget>[
@@ -2499,15 +2502,16 @@ class _AiWidgetInfoPane extends StatelessWidget {
2499
2502
  ),
2500
2503
  const SizedBox(height: 10),
2501
2504
  ],
2502
- Text(
2503
- title,
2504
- style: TextStyle(
2505
- fontSize: 18,
2506
- fontWeight: FontWeight.w700,
2507
- height: 1.1,
2508
- letterSpacing: -0.4,
2505
+ if (!titleIsDuplicate)
2506
+ Text(
2507
+ title,
2508
+ style: TextStyle(
2509
+ fontSize: 18,
2510
+ fontWeight: FontWeight.w700,
2511
+ height: 1.1,
2512
+ letterSpacing: -0.4,
2513
+ ),
2509
2514
  ),
2510
- ),
2511
2515
  if (subtitle.trim().isNotEmpty) ...<Widget>[
2512
2516
  const SizedBox(height: 8),
2513
2517
  Text(
@@ -2599,11 +2603,39 @@ class _AiWidgetInfoPane extends StatelessWidget {
2599
2603
  ],
2600
2604
  if (body.trim().isNotEmpty) ...<Widget>[
2601
2605
  const SizedBox(height: 10),
2602
- Text(
2603
- body,
2604
- maxLines: 4,
2605
- overflow: TextOverflow.ellipsis,
2606
- style: TextStyle(color: _textPrimary, height: 1.5, fontSize: 15),
2606
+ MarkdownBody(
2607
+ data: body,
2608
+ selectable: false,
2609
+ styleSheet: MarkdownStyleSheet.fromTheme(Theme.of(context))
2610
+ .copyWith(
2611
+ p: TextStyle(color: _textPrimary, height: 1.5, fontSize: 15),
2612
+ h1: TextStyle(
2613
+ color: _textPrimary,
2614
+ height: 1.3,
2615
+ fontSize: 18,
2616
+ fontWeight: FontWeight.w700,
2617
+ ),
2618
+ h2: TextStyle(
2619
+ color: _textPrimary,
2620
+ height: 1.3,
2621
+ fontSize: 17,
2622
+ fontWeight: FontWeight.w700,
2623
+ ),
2624
+ h3: TextStyle(
2625
+ color: _textPrimary,
2626
+ height: 1.3,
2627
+ fontSize: 16,
2628
+ fontWeight: FontWeight.w700,
2629
+ ),
2630
+ listBullet: TextStyle(color: _textSecondary, height: 1.4),
2631
+ blockquoteDecoration: BoxDecoration(
2632
+ color: Colors.white.withValues(alpha: 0.04),
2633
+ borderRadius: BorderRadius.circular(12),
2634
+ border: Border.all(
2635
+ color: Colors.white.withValues(alpha: 0.08),
2636
+ ),
2637
+ ),
2638
+ ),
2607
2639
  ),
2608
2640
  ],
2609
2641
  if (hasUsefulRows) ...<Widget>[
@@ -2808,6 +2840,7 @@ class _AiWidgetAndroidPreview extends StatelessWidget {
2808
2840
  Expanded(
2809
2841
  child: switch (item.template) {
2810
2842
  'list' => _AiWidgetPreviewList(
2843
+ displayName: displayName,
2811
2844
  title: title,
2812
2845
  subtitle: subtitle,
2813
2846
  rows: rows,
@@ -2817,6 +2850,7 @@ class _AiWidgetAndroidPreview extends StatelessWidget {
2817
2850
  compact: compact,
2818
2851
  ),
2819
2852
  'summary' => _AiWidgetPreviewSummary(
2853
+ displayName: displayName,
2820
2854
  title: title,
2821
2855
  subtitle: subtitle,
2822
2856
  body: body,
@@ -2827,6 +2861,7 @@ class _AiWidgetAndroidPreview extends StatelessWidget {
2827
2861
  compact: compact,
2828
2862
  ),
2829
2863
  _ => _AiWidgetPreviewStat(
2864
+ displayName: displayName,
2830
2865
  title: title,
2831
2866
  subtitle: subtitle,
2832
2867
  metric: metric,
@@ -2853,6 +2888,7 @@ class _AiWidgetAndroidPreview extends StatelessWidget {
2853
2888
 
2854
2889
  class _AiWidgetPreviewStat extends StatelessWidget {
2855
2890
  const _AiWidgetPreviewStat({
2891
+ required this.displayName,
2856
2892
  required this.title,
2857
2893
  required this.subtitle,
2858
2894
  required this.metric,
@@ -2868,6 +2904,7 @@ class _AiWidgetPreviewStat extends StatelessWidget {
2868
2904
  required this.compact,
2869
2905
  });
2870
2906
 
2907
+ final String displayName;
2871
2908
  final String title;
2872
2909
  final String subtitle;
2873
2910
  final String metric;
@@ -2884,6 +2921,8 @@ class _AiWidgetPreviewStat extends StatelessWidget {
2884
2921
 
2885
2922
  @override
2886
2923
  Widget build(BuildContext context) {
2924
+ final titleIsDuplicate =
2925
+ _widgetSanitizedText(title).toLowerCase() == displayName.toLowerCase();
2887
2926
  final values = rows
2888
2927
  .where(
2889
2928
  (row) =>
@@ -2915,17 +2954,18 @@ class _AiWidgetPreviewStat extends StatelessWidget {
2915
2954
  ),
2916
2955
  ),
2917
2956
  SizedBox(height: dense ? 6 : 8),
2918
- Text(
2919
- title.trim().isNotEmpty ? title : 'Waiting for first update',
2920
- maxLines: 1,
2921
- overflow: TextOverflow.ellipsis,
2922
- style: TextStyle(
2923
- color: palette.foreground,
2924
- fontSize: dense ? 15 : (compact ? 16 : 18),
2925
- fontWeight: FontWeight.w600,
2926
- letterSpacing: -0.35,
2957
+ if (!titleIsDuplicate)
2958
+ Text(
2959
+ title.trim().isNotEmpty ? title : 'Waiting for first update',
2960
+ maxLines: 1,
2961
+ overflow: TextOverflow.ellipsis,
2962
+ style: TextStyle(
2963
+ color: palette.foreground,
2964
+ fontSize: dense ? 15 : (compact ? 16 : 18),
2965
+ fontWeight: FontWeight.w600,
2966
+ letterSpacing: -0.35,
2967
+ ),
2927
2968
  ),
2928
- ),
2929
2969
  SizedBox(height: dense ? 8 : 10),
2930
2970
  Text(
2931
2971
  hasMetric ? metric : 'Waiting for first update',
@@ -3049,6 +3089,7 @@ class _AiWidgetPreviewStat extends StatelessWidget {
3049
3089
 
3050
3090
  class _AiWidgetPreviewSummary extends StatelessWidget {
3051
3091
  const _AiWidgetPreviewSummary({
3092
+ required this.displayName,
3052
3093
  required this.title,
3053
3094
  required this.subtitle,
3054
3095
  required this.body,
@@ -3059,6 +3100,7 @@ class _AiWidgetPreviewSummary extends StatelessWidget {
3059
3100
  required this.compact,
3060
3101
  });
3061
3102
 
3103
+ final String displayName;
3062
3104
  final String title;
3063
3105
  final String subtitle;
3064
3106
  final String body;
@@ -3074,6 +3116,9 @@ class _AiWidgetPreviewSummary extends StatelessWidget {
3074
3116
  final headline = title.trim().isNotEmpty
3075
3117
  ? title
3076
3118
  : 'Waiting for first update';
3119
+ final headlineIsDuplicate =
3120
+ _widgetSanitizedText(headline).toLowerCase() ==
3121
+ displayName.toLowerCase();
3077
3122
  final copy = body.trim().isNotEmpty ? body : headline;
3078
3123
  return Column(
3079
3124
  crossAxisAlignment: CrossAxisAlignment.start,
@@ -3085,30 +3130,60 @@ class _AiWidgetPreviewSummary extends StatelessWidget {
3085
3130
  style: TextStyle(color: palette.muted, fontSize: compact ? 11 : 12),
3086
3131
  ),
3087
3132
  const SizedBox(height: 10),
3088
- Text(
3089
- headline,
3090
- maxLines: compact ? 3 : 4,
3091
- overflow: TextOverflow.ellipsis,
3092
- style: TextStyle(
3093
- color: palette.foreground,
3094
- fontSize: compact ? 20 : 24,
3095
- height: 1.12,
3096
- fontWeight: FontWeight.w600,
3097
- letterSpacing: -0.6,
3098
- ),
3099
- ),
3100
- if (copy != headline) ...<Widget>[
3101
- const SizedBox(height: 10),
3133
+ if (!headlineIsDuplicate)
3102
3134
  Text(
3103
- copy,
3135
+ headline,
3104
3136
  maxLines: compact ? 3 : 4,
3105
3137
  overflow: TextOverflow.ellipsis,
3106
3138
  style: TextStyle(
3107
- color: palette.foreground.withValues(alpha: 0.86),
3108
- fontSize: compact ? 13 : 14,
3109
- height: 1.34,
3139
+ color: palette.foreground,
3140
+ fontSize: compact ? 20 : 24,
3141
+ height: 1.12,
3142
+ fontWeight: FontWeight.w600,
3143
+ letterSpacing: -0.6,
3110
3144
  ),
3111
3145
  ),
3146
+ if (copy != headline) ...<Widget>[
3147
+ const SizedBox(height: 10),
3148
+ MarkdownBody(
3149
+ data: copy,
3150
+ selectable: false,
3151
+ styleSheet: MarkdownStyleSheet.fromTheme(Theme.of(context))
3152
+ .copyWith(
3153
+ p: TextStyle(
3154
+ color: palette.foreground.withValues(alpha: 0.86),
3155
+ fontSize: compact ? 13 : 14,
3156
+ height: 1.34,
3157
+ ),
3158
+ h1: TextStyle(
3159
+ color: palette.foreground.withValues(alpha: 0.92),
3160
+ fontSize: compact ? 16 : 17,
3161
+ height: 1.18,
3162
+ fontWeight: FontWeight.w700,
3163
+ ),
3164
+ h2: TextStyle(
3165
+ color: palette.foreground.withValues(alpha: 0.92),
3166
+ fontSize: compact ? 15 : 16,
3167
+ height: 1.18,
3168
+ fontWeight: FontWeight.w700,
3169
+ ),
3170
+ h3: TextStyle(
3171
+ color: palette.foreground.withValues(alpha: 0.92),
3172
+ fontSize: compact ? 14 : 15,
3173
+ height: 1.18,
3174
+ fontWeight: FontWeight.w700,
3175
+ ),
3176
+ listBullet: TextStyle(
3177
+ color: palette.muted,
3178
+ fontSize: compact ? 12 : 13,
3179
+ height: 1.28,
3180
+ ),
3181
+ blockquoteDecoration: BoxDecoration(
3182
+ color: palette.chip,
3183
+ borderRadius: BorderRadius.circular(10),
3184
+ ),
3185
+ ),
3186
+ ),
3112
3187
  ],
3113
3188
  if (metric.isNotEmpty) ...<Widget>[
3114
3189
  const Spacer(),
@@ -3149,6 +3224,7 @@ class _AiWidgetPreviewSummary extends StatelessWidget {
3149
3224
 
3150
3225
  class _AiWidgetPreviewList extends StatelessWidget {
3151
3226
  const _AiWidgetPreviewList({
3227
+ required this.displayName,
3152
3228
  required this.title,
3153
3229
  required this.subtitle,
3154
3230
  required this.rows,
@@ -3158,6 +3234,7 @@ class _AiWidgetPreviewList extends StatelessWidget {
3158
3234
  required this.compact,
3159
3235
  });
3160
3236
 
3237
+ final String displayName;
3161
3238
  final String title;
3162
3239
  final String subtitle;
3163
3240
  final List<Map<String, dynamic>> rows;
@@ -3168,6 +3245,8 @@ class _AiWidgetPreviewList extends StatelessWidget {
3168
3245
 
3169
3246
  @override
3170
3247
  Widget build(BuildContext context) {
3248
+ final titleIsDuplicate =
3249
+ _widgetSanitizedText(title).toLowerCase() == displayName.toLowerCase();
3171
3250
  final entries = rows.isEmpty
3172
3251
  ? chips
3173
3252
  .map((chip) => <String, dynamic>{'label': chip, 'value': ''})
@@ -3192,7 +3271,7 @@ class _AiWidgetPreviewList extends StatelessWidget {
3192
3271
  overflow: TextOverflow.ellipsis,
3193
3272
  style: TextStyle(color: palette.muted, fontSize: compact ? 11 : 12),
3194
3273
  ),
3195
- if (title.trim().isNotEmpty) ...<Widget>[
3274
+ if (!titleIsDuplicate && title.trim().isNotEmpty) ...<Widget>[
3196
3275
  const SizedBox(height: 6),
3197
3276
  Text(
3198
3277
  title,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neoagent",
3
- "version": "2.3.1-beta.65",
3
+ "version": "2.3.1-beta.66",
4
4
  "description": "Proactive personal AI agent with no limits",
5
5
  "license": "MIT",
6
6
  "main": "server/index.js",
@@ -1 +1 @@
1
- f5b685e19d2bcb3cb22b0f5b5df858c9
1
+ 03e50077364c472b1caef378bca9ddc5
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"42d3d75a56efe1a2e9902f52dc8006099c45d9
37
37
 
38
38
  _flutter.loader.load({
39
39
  serviceWorkerSettings: {
40
- serviceWorkerVersion: "1598577597" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
40
+ serviceWorkerVersion: "167614730" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
41
41
  }
42
42
  });