Repository navigation
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a new documentation skill, 'a2ui-dart-development', to provide guidelines for Dart and Flutter development within the repository, and updates 'AGENTS.md' to include this new resource. The review feedback suggests correcting a reference to a non-existent package, adding specific guidelines for loop variable type annotations, and including a 'Common Pitfalls & Best Practices' section to improve the utility of the documentation.
| - `strict-casts`, `strict-inference` and `strict-raw-types`: a value read from | ||
| JSON is `Object?` or `dynamic`, so cast it or match it with a pattern before | ||
| using it as a narrower type. | ||
| - `lines_longer_than_80_chars`, which `dart/a2ui_cli` turns off. |
There was a problem hiding this comment.
The package 'dart/a2ui_cli' is not listed in the repository structure in 'AGENTS.md'. If this package does not exist or was renamed, please update this reference to the correct package name (e.g., 'a2ui_agent' or 'a2ui_flutter').
| - `lines_longer_than_80_chars`, which `dart/a2ui_cli` turns off. | |
| - 'lines_longer_than_80_chars', which 'dart/a2ui_agent' turns off. |
| - `specify_nonobvious_local_variable_types` and | ||
| `omit_obvious_local_variable_types`: write the type of a local variable when | ||
| its initializer does not make the type obvious, and leave it off when it | ||
| does. |
There was a problem hiding this comment.
To make this guide more comprehensive and prevent common CI failures, consider adding the repository's specific guidelines for loop variables under these linter rules. Specifically, avoid explicit type annotations on loop variables when the iterable already has an explicit type argument, but retain them when iterating over collections (like 'List.of(...)' or map entries) where the type is non-obvious.
| - `specify_nonobvious_local_variable_types` and | |
| `omit_obvious_local_variable_types`: write the type of a local variable when | |
| its initializer does not make the type obvious, and leave it off when it | |
| does. | |
| - 'specify_nonobvious_local_variable_types' and | |
| 'omit_obvious_local_variable_types': write the type of a local variable when | |
| its initializer does not make the type obvious, and leave it off when it | |
| does. For loop variables, avoid explicit type annotations if the iterable | |
| already has an explicit type argument, but retain them when iterating over | |
| collections (like List.of(...) or map entries) where the type is non-obvious. |
References
- In Dart, avoid adding explicit type annotations to loop variables when the iterable has explicit type arguments, but retain them when iterating over collections (like List.of(...) or map entries) if specify_nonobvious_local_variable_types is enabled.
| - `unawaited_futures`: await a future, or pass it to `unawaited`. | ||
|
|
There was a problem hiding this comment.
Consider adding a 'Common Pitfalls & Best Practices' subsection to document repository-specific Dart guidelines (such as map validation, safe element retrieval with 'firstOrNull', and raw string handling). This will make the skill file much more valuable for developers and automated agents.
| - `unawaited_futures`: await a future, or pass it to `unawaited`. | |
| - 'unawaited_futures': await a future, or pass it to 'unawaited'. | |
| ### Common Pitfalls & Best Practices | |
| - Map Validation: When validating map inputs that can be either 'Map<dynamic, dynamic>' (e.g., from YAML parsers) or 'Map<String, Object?>', do not check 'is Map<String, Object?>' directly. Instead, check 'is Map' and use '.cast<String, Object?>()'. Defensive validation of map keys before calling '.cast' is unnecessary if the casted map is only accessed via direct key lookups (e.g., '[]') and never iterated. | |
| - Safe Element Retrieval: Use 'firstOrNull' instead of 'first' on 'Iterable' to defensively avoid a 'StateError' if the collection is empty. | |
| - Raw Strings: Backslashes have no special meaning inside raw string literals (prefixed with 'r') and do not escape the closing quote delimiter. Raw string literals can safely end with a backslash. |
References
- In Dart, use .cast<String, Object?>() on Map instead of checking 'is Map<String, Object?>' directly, use firstOrNull instead of first to avoid StateError, and handle raw string literals correctly with trailing backslashes.
gspencergoog
left a comment
There was a problem hiding this comment.
This pull request introduces the a2ui-dart-development skill (.agents/skills/a2ui-dart-development/SKILL.md) and links it from .gemini/styleguide.md and AGENTS.md. The skill documents how each Dart package's environment: sdk: lower bound governs allowed language features and dart format styling, lists Dart 3.0 through 3.13 features and root analysis_options.yaml rules, and gives local verification commands matching CI.
All Dart language feature versions (3.0 through 3.13), analyzer rules, and relative links match the Dart 3.13.5 SDK and repository configuration, with a few minor documentation adjustments noted inline.
🤖 Agent-generated
| fails CI. In `dart/a2ui_agent`, CI also runs | ||
| `dart run tool/generate_express_parser.dart --check`, which fails when the | ||
| generated Express parser is out of date with the grammar. After editing the | ||
| grammar, run the tool without `--check` and commit its output. |
There was a problem hiding this comment.
flutter_packages_test.yml excludes dart/a2ui_agent/e2e_test and samples/client/flutter/restaurant_finder/e2e_test from flutter test, running only dart pub get, dart format, and flutter analyze --fatal-infos on them. Those e2e_test suites call live Gemini models via ./scripts/e2e_test.sh and require GEMINI_API_KEY to be set. Contributors or agents editing an e2e_test package will hit immediate GEMINI_API_KEY is not configured test failures during local verification.
| grammar, run the tool without `--check` and commit its output. | |
| grammar, run the tool without `--check` and commit its output. In `e2e_test` | |
| packages (`dart/a2ui_agent/e2e_test` and | |
| `samples/client/flutter/restaurant_finder/e2e_test`), `flutter_packages_test.yml` | |
| runs only `dart pub get`, `dart format`, and `flutter analyze --fatal-infos` | |
| because their tests require `GEMINI_API_KEY` (see `./scripts/e2e_test.sh`). |
🤖 Agent-generated
| - Do not use a feature newer than the package's language version, even when | ||
| your SDK supports it. Raising the lower bound of `environment: sdk:` drops | ||
| users of older SDKs, so it is a change of its own, with a reason and an | ||
| entry in `CHANGELOG.md`. |
There was a problem hiding this comment.
scripts/fix_format.sh passes explicit --language-version=3.10 and --language-version=3.5 flags to dart format, and presubmit-lint.yml runs ./scripts/fix_format.sh --check on every pull request. The guidance for raising environment: sdk: mentions CHANGELOG.md but omits updating the pinned version in scripts/fix_format.sh.
| entry in `CHANGELOG.md`. | |
| entry in `CHANGELOG.md`, and an update to the pinned `--language-version` in | |
| `scripts/fix_format.sh`. |
🤖 Agent-generated
| --- | ||
| name: a2ui-dart-development | ||
| description: >- | ||
| Language version, analysis, formatting and verification rules for Dart code |
There was a problem hiding this comment.
The description field opens with the noun phrase Language version, analysis, formatting and verification rules, which triggers a lint_skill.py warning. Opening with a third-person verb keeps the skill frontmatter consistent with a2ui-dart-versioning and passes lint_skill.py without warnings.
| Language version, analysis, formatting and verification rules for Dart code | |
| Defines language version, analysis, formatting, and verification rules for Dart code |
🤖 Agent-generated
Fixes http://github.com/a2ui-project/a2ui/pull/3289
Description
Adds the
a2ui-dart-developmentskill, which tells assistants that write or review Dart code in this repository which language features a package may use. It also lowers the SDK floor ofa2ui_agentfrom 3.10 to 3.8, and explains in thepubspec.yamlofa2ui_coreand ofa2ui_agentwhy their floors are lower than the floor ofa2ui_flutter.Motivation
Assistants judge Dart syntax from memory, and their training data often predates recent language features. Dart adds syntax in minor releases: null-aware elements in 3.8, dot shorthands in 3.10, primary constructors in 3.13. So an assistant can be wrong in two directions:
'catalogId': ?catalogIdas a critical compile error three times (1, 2, 3). The line is a null-aware element, valid since Dart 3.8, anda2ui_agentrequired 3.10 at the time. The fix the bot proposed,if (catalogId != null) 'catalogId': catalogId, would have failed CI on theuse_null_aware_elementslint. The author had to research and answer each comment, and an author who trusted the bot would have broken the build.flutter analyzerejects it, and the change needs another round.a2ui_coreanda2ui_agentare plain Dart. Agents and servers that do not run Flutter use both, and Flutter apps on older SDKs usea2ui_core. So their SDK floors follow what their own code needs rather than the floor ofa2ui_flutter, which follows Flutter.a2ui_coreallows 3.5 since #2819, anda2ui_agentcompiles with 3.8 without changes.Changes
.agents/skills/a2ui-dart-development/SKILL.md, the new skill, describes:pubspec.yaml, and runflutter analyze.analysis_options.yamlthat most often fail a change, including which initializers and loop iterables make a local variable's type obvious. The examples were checked with the analyzer.dart formatpicks its style from the language version, and the commands CI runs.AGENTS.mdlists the skill beside the Python and Swift development skills, and addsa2ui_clito the Dart packages in the repository structure..gemini/styleguide.mdstates the rule and links to the skill. The review bot reads the style guide, notAGENTS.md, so this is what reaches the bot that made the mistake in Implement agent 1.0. #3242.dart/a2ui_agent/pubspec.yamllowers the SDK floor from 3.10 to 3.8, the oldest version the package's code compiles with, because it uses null-aware elements.dart/a2ui_agent/CHANGELOG.mdrecords the change. Going down to 3.5, asa2ui_coredoes, would mean rewriting 4 null-aware elements and reformatting over 30 files in the styledart formatuses before 3.7. That reformatting would conflict with the open pull requests that changea2ui_agent, such as Implement agent 1.0. #3242, feat(dart/agent): add RendererState; build validatePayload on it #3276 and feat(dart/agent)!: make the Parser stateless; add ResponseStream; bind RendererState to A2uiRequestProcessor #3277.dart/a2ui_core/pubspec.yamlanddart/a2ui_agent/pubspec.yamlexplain in a comment why the floor is lower than the floor ofa2ui_flutter. The comment ina2ui_agentsays that agents on servers that do not run Flutter use the package. The comment ina2ui_corenames those agents and servers and also Flutter apps on older SDKs, and notes that 3.5 is the lowest version thatresolution: workspaceallows.Dependency limit
Neither package resolves on Dart 3.5 to 3.9 yet.
a2ui_coredepends onjson_schema_builder: ^0.1.7, and everyjson_schema_builderrelease from 0.1.5 on requires Dart 3.10. The code ofjson_schema_builder0.1.7 compiles with 3.8, so a release of it that declares>=3.8.0would let both packages resolve on Dart 3.8 with no change in this repository. No release ofjson_schema_builderallows 3.5 to 3.7.Verification
In
dart/a2ui_coreanddart/a2ui_agent,dart format --set-exit-if-changed,flutter analyze --fatal-infosandflutter testpass, and so doesdart run tool/generate_express_parser.dart --checkina2ui_agent. At language version 3.7,a2ui_agentfails to analyze with 5 errors, all from null-aware elements.🤖 Agent-generated