diff --git a/lib/pages/store.dart b/lib/pages/store.dart index b4ac189..aa61e3c 100644 --- a/lib/pages/store.dart +++ b/lib/pages/store.dart @@ -3552,6 +3552,20 @@ class _StoreTodayHero extends StatelessWidget { : theme.colorScheme.outlineVariant, ), ), + // Textual position next to the dots: the + // ~6-px dots alone were the only position + // cue — unusable for low-vision and + // motor-impaired operators (a11y finding). + // The chevrons stay the big click targets. + Padding( + padding: const EdgeInsets.only(left: 6), + child: Text( + '${currentIndex + 1}/$totalCount', + style: theme.textTheme.labelSmall?.copyWith( + color: theme.colorScheme.onSurfaceVariant, + ), + ), + ), ], ), ), diff --git a/lib/pages/welcome.dart b/lib/pages/welcome.dart index dcd4f08..09e975b 100644 --- a/lib/pages/welcome.dart +++ b/lib/pages/welcome.dart @@ -570,6 +570,13 @@ class _TrustRow extends StatelessWidget { /// onboarding needed). const String _kChecklistDismissedKey = 'welcome.checklist.dismissed'; +/// Sticky marker for "a flow has completed at least once". The live +/// probe only sees the recent-events window (100), so a long-running +/// hub would silently untick the step once the event scrolls out — +/// the marker keeps the tick honest to its wording ("start a saved +/// flow", ever), at the cost of being Studio-local. +const String _kChecklistFlowDoneKey = 'welcome.checklist.flowCompleted'; + /// Live getting-started checklist. Probes the running hub for /// four signals that the operator has the basic loop wired up /// (System AI configured, MCP source added, text module @@ -650,13 +657,18 @@ class _OnboardingChecklistState extends State<_OnboardingChecklist> { .then((events) => events.any((e) => e.type == 'flow.completed')) .catchError((_) => false); final results = await Future.wait([ai, mcp, module, flow]); + final prefs = await SharedPreferences.getInstance(); + final flowSeen = prefs.getBool(_kChecklistFlowDoneKey) ?? false; + if (results[3] && !flowSeen) { + await prefs.setBool(_kChecklistFlowDoneKey, true); + } if (!mounted) return; setState(() { _refreshing = false; _aiOk = results[0]; _mcpOk = results[1]; _moduleOk = results[2]; - _flowOk = results[3]; + _flowOk = results[3] || flowSeen; }); }