chore: adopt Dart 3.9 toolchain — honest floor + tall-style reformat (T-353)

Raise the declared minimums in pubspec.yaml to what our deps already
require: Flutter >=3.35.0 / Dart >=3.9.0 (was 3.19.0 / 3.5.0). alchemist
0.12 needs Flutter 3.32; Dart 3.9 first ships in Flutter 3.35, so 3.35 is
the binding floor. Pin the exact build toolchain in .fvmrc (Flutter
3.44.1).

Moving to the Dart 3.9 language level switches `dart format` to the new
"tall" style and enables two new lints. This commit is the resulting
mechanical churn, isolated from any behaviour change:
  - whole-tree `dart format` reformat (tall style)
  - `dart fix` for unnecessary_underscores + use_null_aware_elements

No runtime behaviour change; `make test` green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-11 12:11:53 +02:00
co-authored by Claude Opus 4.8
parent bcea5f15b7
commit 6d0ebab721
444 changed files with 7587 additions and 12849 deletions
+12 -12
View File
@@ -14,16 +14,16 @@ class ProblemsExtension extends ClideExtension {
@override
List<ContributionPoint> get contributions => [
// Moved out of the sidebar into the bottom dock (D-87): no duplication,
// and the dock's width fits `severity · file:line · message` rows.
TabContribution(
id: 'problems.panel',
slot: Slots.dock,
title: 'Problems',
titleKey: 'tab.title',
i18nNamespace: id,
priority: -50,
build: (_) => const ProblemsView(),
),
];
// Moved out of the sidebar into the bottom dock (D-87): no duplication,
// and the dock's width fits `severity · file:line · message` rows.
TabContribution(
id: 'problems.panel',
slot: Slots.dock,
title: 'Problems',
titleKey: 'tab.title',
i18nNamespace: id,
priority: -50,
build: (_) => const ProblemsView(),
),
];
}
@@ -16,11 +16,7 @@ class Problem {
final String message;
final String? hint;
Map<String, Object?> toJson() => {
'source': source,
'message': message,
if (hint != null) 'hint': hint,
};
Map<String, Object?> toJson() => {'source': source, 'message': message, if (hint != null) 'hint': hint};
}
class ProblemsController extends ChangeNotifier {
@@ -47,11 +43,7 @@ class ProblemsController extends ChangeNotifier {
if (doctor.ok) {
final db = (doctor.data['db'] as Map?)?.cast<String, Object?>();
if (db != null && db['exists'] == false) {
found.add(const Problem(
source: 'pql',
message: 'pql index database not found',
hint: 'Run pql to build the index.',
));
found.add(const Problem(source: 'pql', message: 'pql index database not found', hint: 'Run pql to build the index.'));
}
final skill = (doctor.data['skill'] as Map?)?.cast<String, Object?>();
if (skill != null) {
@@ -59,37 +51,21 @@ class ProblemsController extends ChangeNotifier {
if (project != null) {
final state = project['state'] as String?;
if (state == 'stale') {
found.add(const Problem(
source: 'pql',
message: 'pql skill is stale — newer version available',
hint: 'Run: pql skill install',
));
found.add(const Problem(source: 'pql', message: 'pql skill is stale — newer version available', hint: 'Run: pql skill install'));
} else if (state == 'missing') {
found.add(const Problem(
source: 'pql',
message: 'pql skill not installed',
hint: 'Run: pql init --with-skill=yes',
));
found.add(const Problem(source: 'pql', message: 'pql skill not installed', hint: 'Run: pql init --with-skill=yes'));
}
}
}
} else {
found.add(Problem(
source: 'pql',
message: 'pql doctor failed',
hint: doctor.error?.message,
));
found.add(Problem(source: 'pql', message: 'pql doctor failed', hint: doctor.error?.message));
}
final sync = await ipc.request('pql.decisions.sync');
if (sync.ok) {
final broken = (sync.data['broken'] as num?)?.toInt() ?? 0;
if (broken > 0) {
found.add(Problem(
source: 'decisions',
message: '$broken broken cross-reference(s) in governance/',
hint: 'Run: pql decisions validate',
));
found.add(Problem(source: 'decisions', message: '$broken broken cross-reference(s) in governance/', hint: 'Run: pql decisions validate'));
}
}
+12 -23
View File
@@ -49,8 +49,9 @@ class _ProblemsViewState extends State<ProblemsView> {
explicitChildNodes: true,
child: () {
final lf = _filter.toLowerCase();
final filtered =
lf.isEmpty ? c.problems : c.problems.where((p) => p.message.toLowerCase().contains(lf) || p.source.toLowerCase().contains(lf)).toList();
final filtered = lf.isEmpty
? c.problems
: c.problems.where((p) => p.message.toLowerCase().contains(lf) || p.source.toLowerCase().contains(lf)).toList();
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
@@ -59,14 +60,18 @@ class _ProblemsViewState extends State<ProblemsView> {
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 2),
child: Row(
children: [
Expanded(child: ClideText('Problems (${filtered.length})', fontSize: clideFontCaption, color: tokens.sidebarForeground)),
Expanded(
child: ClideText('Problems (${filtered.length})', fontSize: clideFontCaption, color: tokens.sidebarForeground),
),
Semantics(
button: true,
label: 'refresh problems',
child: GestureDetector(
onTap: () => unawaited(c.refresh()),
child: MouseRegion(
cursor: SystemMouseCursors.click, child: ClideText('Refresh', fontSize: clideFontCaption, color: tokens.sidebarForeground)),
cursor: SystemMouseCursors.click,
child: ClideText('Refresh', fontSize: clideFontCaption, color: tokens.sidebarForeground),
),
),
),
],
@@ -108,31 +113,15 @@ class _ProblemRow extends StatelessWidget {
children: [
Row(
children: [
ClideText(
problem.source,
fontSize: clideFontMono,
color: tokens.statusWarning,
fontFamily: clideMonoFamily,
),
ClideText(problem.source, fontSize: clideFontMono, color: tokens.statusWarning, fontFamily: clideMonoFamily),
const SizedBox(width: 6),
Expanded(
child: ClideText(
problem.message,
color: tokens.sidebarForeground,
maxLines: 2,
),
),
Expanded(child: ClideText(problem.message, color: tokens.sidebarForeground, maxLines: 2)),
],
),
if (problem.hint != null)
Padding(
padding: const EdgeInsets.only(left: 44, top: 2),
child: ClideText(
problem.hint!,
fontSize: clideFontMono,
muted: true,
fontFamily: clideMonoFamily,
),
child: ClideText(problem.hint!, fontSize: clideFontMono, muted: true, fontFamily: clideMonoFamily),
),
],
),