From e30fba6f1ee98d2b932ef36a86dc9951c82f5620 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Fri, 16 Oct 2026 11:29:05 -0700 Subject: [PATCH 1/2] - --- .agents/skills/a2ui-dart-development/SKILL.md | 118 ++++++++++++++++++ .gemini/styleguide.md | 6 + AGENTS.md | 1 + 3 files changed, 125 insertions(+) create mode 100644 .agents/skills/a2ui-dart-development/SKILL.md diff --git a/.agents/skills/a2ui-dart-development/SKILL.md b/.agents/skills/a2ui-dart-development/SKILL.md new file mode 100644 index 0000000000..c9c2fbcf4e --- /dev/null +++ b/.agents/skills/a2ui-dart-development/SKILL.md @@ -0,0 +1,118 @@ +--- +name: a2ui-dart-development +description: >- + Language version, analysis, formatting and verification rules for Dart code + in the A2UI repository (the packages under dart/ and the Flutter samples + under samples/client/flutter/). Use when writing, refactoring or reviewing + Dart code, and before claiming that a line of Dart does not compile. +--- + +# Dart development + +This skill is for anyone who writes or reviews Dart code in this repository: +the packages under `dart/`, such as `a2ui_core` and `a2ui_agent`, and the +Flutter samples under `samples/client/flutter/`. To record a change in a +package's `CHANGELOG.md`, see +[a2ui-dart-versioning](../a2ui-dart-versioning/SKILL.md). + +## Language version + +The lower bound of `environment: sdk:` in a package's `pubspec.yaml` is the +Dart language version of that package. Every language feature released up to +that version is valid in the package. Every later feature is a compile error, +whatever SDK is installed. The packages do not all require the same version, +so read the `pubspec.yaml` of the package you are changing. For example, +`dart/a2ui_core` requires `>=3.5.0` and `dart/a2ui_agent` requires +`>=3.10.0`, so `{'catalogId': ?catalogId}` is valid in `a2ui_agent` and a +compile error in `a2ui_core`. + +Features that assistants often misjudge, with the version that added each: + +- 3.0: records, patterns (`if (json case {'id': final String id})`, switch + expressions, destructuring), and the class modifiers `sealed`, `final`, + `base`, `interface` and `mixin class`. +- 3.3: extension types. +- 3.6: digit separators, such as `1_000_000`. +- 3.7: wildcard variables. A parameter or local named `_` declares nothing, + so several parameters of one function can each be named `_`. +- 3.8: null-aware elements. `{'key': ?value}` and `[?item]` leave the entry + out when the value is null. +- 3.10: dot shorthands. Where the context type is known, `.center` stands for + `Alignment.center` and `.new(...)` for a constructor call. +- 3.12: private named parameters, such as `A({required this._x})`. +- 3.13: primary constructors, such as `class Point(final int x, final int y);`. + +The full list is in Dart's +[language evolution](https://dart.dev/resources/language/evolution) page. + +When you write code: + +- Use the features the package's language version allows, as the code around + yours does. Do not rewrite valid code into an older form. Some lints ask for + the newer form: with `package:lints/recommended.yaml`, which the root + `analysis_options.yaml` includes, `use_null_aware_elements` flags + `if (value != null) 'key': value` in a package where `'key': ?value` works. +- 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`. + +When you review code, or before you say that a line does not compile: + +1. Find the language version that the feature needs. Your training data may + predate the feature, so check the + [language evolution](https://dart.dev/resources/language/evolution) page + rather than relying on memory. +2. Compare it with the lower bound of `environment: sdk:` in the + `pubspec.yaml` of the package that holds the file. +3. If you can run commands, run `flutter analyze` in the package. When the + feature is newer than the package allows, the error names the version + that the feature needs. + +Report a syntax error only when the feature is newer than the package's +language version or the analyzer reports one. + +## Analysis + +The root [`analysis_options.yaml`](../../../analysis_options.yaml) applies to +every package. A package's own `analysis_options.yaml`, where there is one, +includes it and adds exclusions. The settings that most often fail a change: + +- `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. +- `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. +- `prefer_relative_imports` for imports within a package's `lib/`. +- `comment_references`: a name in `[brackets]` in a doc comment must resolve. +- `unawaited_futures`: await a future, or pass it to `unawaited`. + +## Formatting + +`dart format` picks its style from the language version. From 3.7 it uses +the tall style, which places arguments and trailing commas differently, so +the same code formats differently in `a2ui_core` and in `a2ui_agent`. Run +`dart format` in the package rather than copying the layout of another +package. + +## Verification + +Run these in the directory of each package you changed, as the +[Flutter packages workflow](../../../.github/workflows/flutter_packages_test.yml) +does: + +```bash +dart pub get +dart format --output=none --set-exit-if-changed . +flutter analyze --fatal-infos +flutter test --test-randomize-ordering-seed=random +``` + +`--fatal-infos` fails on lints too, so a change that leaves any analyzer info +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. diff --git a/.gemini/styleguide.md b/.gemini/styleguide.md index abeee78644..03cefb9073 100644 --- a/.gemini/styleguide.md +++ b/.gemini/styleguide.md @@ -15,6 +15,12 @@ auto-formatter, for each language, as described in - Code should follow the guidance and principles described in [the A2UI contribution guidelines](../CONTRIBUTING.md). - If there are code changes, code should have tests. +- Dart code may use every language feature up to the lower bound of + `environment: sdk:` in its package's `pubspec.yaml`, such as null-aware + elements (`{'key': ?value}`) from Dart 3.8. Before calling Dart syntax + invalid, check that version, as + [the Dart development skill](../.agents/skills/a2ui-dart-development/SKILL.md) + describes. - PR descriptions should include the Pre-Review Checklist from [the PR template](https://github.com/flutter/genui/blob/main/.github/PULL_REQUEST_TEMPLATE.md), with all of the steps completed. diff --git a/AGENTS.md b/AGENTS.md index 88695a72a0..cea08c85c4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,6 +13,7 @@ This document is the authoritative guide for AI agents working within the A2UI r - **For implementing new SDKs in a client language:** Read [.agents/skills/a2ui-implement-new-sdks-for-client-language/SKILL.md](.agents/skills/a2ui-implement-new-sdks-for-client-language/SKILL.md) - **For developing Python code anywhere in the repository (libraries, agents, tools, scripts, best practices):** Read [.agents/skills/a2ui-python-development/SKILL.md](.agents/skills/a2ui-python-development/SKILL.md) - **For developing in the Swift codebase (core, SwiftUI, sample):** Read [.agents/skills/a2ui-swift-development/SKILL.md](.agents/skills/a2ui-swift-development/SKILL.md) +- **For writing or reviewing Dart code (`dart/`, Flutter samples):** Read [.agents/skills/a2ui-dart-development/SKILL.md](.agents/skills/a2ui-dart-development/SKILL.md) - **For recording a change in the CHANGELOG of a Dart package under `dart/`, or releasing one:** Read [.agents/skills/a2ui-dart-versioning/SKILL.md](.agents/skills/a2ui-dart-versioning/SKILL.md) --- From 3849bea817f980052a91c8f3d8ef83c631870ce4 Mon Sep 17 00:00:00 2001 From: Polina Cherkasova Date: Fri, 16 Oct 2026 14:20:01 -0700 Subject: [PATCH 2/2] - --- .agents/skills/a2ui-dart-development/SKILL.md | 9 +++++++-- AGENTS.md | 2 +- dart/a2ui_agent/CHANGELOG.md | 4 ++++ dart/a2ui_agent/pubspec.yaml | 6 +++++- dart/a2ui_core/pubspec.yaml | 4 ++++ 5 files changed, 21 insertions(+), 4 deletions(-) diff --git a/.agents/skills/a2ui-dart-development/SKILL.md b/.agents/skills/a2ui-dart-development/SKILL.md index c9c2fbcf4e..409f3d72c4 100644 --- a/.agents/skills/a2ui-dart-development/SKILL.md +++ b/.agents/skills/a2ui-dart-development/SKILL.md @@ -23,7 +23,7 @@ that version is valid in the package. Every later feature is a compile error, whatever SDK is installed. The packages do not all require the same version, so read the `pubspec.yaml` of the package you are changing. For example, `dart/a2ui_core` requires `>=3.5.0` and `dart/a2ui_agent` requires -`>=3.10.0`, so `{'catalogId': ?catalogId}` is valid in `a2ui_agent` and a +`>=3.8.0`, so `{'catalogId': ?catalogId}` is valid in `a2ui_agent` and a compile error in `a2ui_core`. Features that assistants often misjudge, with the version that added each: @@ -85,7 +85,12 @@ includes it and adds exclusions. The settings that most often fail a change: - `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. + does. A literal, such as `3` or `[]`, a constructor call with type + arguments, such as `List.of(xs)`, and a local variable or parameter + make the type obvious. A getter or method call, such as `map.entries` or + `xs.first`, does not, and neither does `List.of(xs)`. The variable of a + `for (... in ...)` loop follows the same rule, with the iterable in place of + the initializer. - `prefer_relative_imports` for imports within a package's `lib/`. - `comment_references`: a name in `[brackets]` in a doc comment must resolve. - `unawaited_futures`: await a future, or pass it to `unawaited`. diff --git a/AGENTS.md b/AGENTS.md index cea08c85c4..7f5b7b2b2f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -64,7 +64,7 @@ For a detailed explanation of the methodology, lifecycle, and workflows, read th - **`specification/`**: Versioned subdirectories (`v0_8/`, `v0_9/`, `v0_9_1/`, `v1_0/`) containing JSON schemas and human-readable guides (older versions also bundle their basic catalog). The `specification//docs/a2ui_protocol.md` file is the most important source of truth for each protocol version, and the `specification//json` directory contains the associated schemas for the protocol. - **`python/`**: Core state SDK (`a2ui_core/`), framework-agnostic agent SDK (`a2ui_agent/`), agent framework integrations for A2A (`a2ui_a2a/`) and ADK (`a2ui_adk/`), and catalog packages (`catalogs/`) for Python. - **`conformance/`**: Language-agnostic test suites (`core/`, `agent/`, `extensions/`) and test data (`test_data/`) for verifying behavioral parity across all SDK implementations. -- **`dart/`**: Dart implementations including core state model (`a2ui_core/`), agent SDK (`a2ui_agent/`), and Flutter framework adapter (`a2ui_flutter/`). +- **`dart/`**: Dart implementations including core state model (`a2ui_core/`), agent SDK (`a2ui_agent/`), Flutter framework adapter (`a2ui_flutter/`), and developer CLI (`a2ui_cli/`). - **`kotlin/`**: Legacy Kotlin agent SDK (`agent_sdk_legacy/`). - **`typescript/`**: Framework-agnostic Web Core state and protocol logic (`core/web_core/`), web framework renderers (`renderers/lit/`, `renderers/angular/`, `renderers/react/`), Markdown renderer (`renderers/markdown-it/`), TypeScript agent SDK (`agents/a2ui_agent/`), TypeScript catalog packages (`catalogs/`), and release scripts (`scripts/`). - **`samples/`**: Ready-to-run demo agents utilizing Python ADK (`agent/adk/`), MCP server (`agent/mcp/`), and sample clients (`client/lit/`, `client/angular/`, `client/react/`, `client/flutter/`). diff --git a/dart/a2ui_agent/CHANGELOG.md b/dart/a2ui_agent/CHANGELOG.md index fd247d62a9..92d0a0c633 100644 --- a/dart/a2ui_agent/CHANGELOG.md +++ b/dart/a2ui_agent/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +- Lower the SDK constraint to `>=3.8.0 <4.0.0`, the oldest version the + package's code compiles with. On Dart 3.8 and 3.9 the package resolves + once `json_schema_builder`, which `a2ui_core` depends on, publishes a + version that allows them; 0.1.7 requires Dart 3.10. - Support cross-catalog `$ref` references across peer catalogs in `resolveCatalogs`, `validatePayloads`, `DirectJsonPromptGenerator` (preserving unbundled external `$ref`s in `Catalog.toJson()` while retaining transitive diff --git a/dart/a2ui_agent/pubspec.yaml b/dart/a2ui_agent/pubspec.yaml index fca7e7f0a3..ceb7bbc4b2 100644 --- a/dart/a2ui_agent/pubspec.yaml +++ b/dart/a2ui_agent/pubspec.yaml @@ -22,7 +22,11 @@ repository: https://github.com/a2ui-project/a2ui/tree/main/dart/a2ui_agent resolution: workspace environment: - sdk: ">=3.10.0 <4.0.0" + # Lower than the bound of a2ui_flutter on purpose. a2ui_agent is plain Dart, + # used by agents on servers that do not run Flutter, so it allows every SDK + # its own code compiles with. 3.8 is the lowest one, because the code uses + # null-aware elements (`{'key': ?value}`). + sdk: ">=3.8.0 <4.0.0" dependencies: a2ui_core: ^0.3.0 diff --git a/dart/a2ui_core/pubspec.yaml b/dart/a2ui_core/pubspec.yaml index d253afe513..9d4b983351 100644 --- a/dart/a2ui_core/pubspec.yaml +++ b/dart/a2ui_core/pubspec.yaml @@ -22,6 +22,10 @@ version: 0.3.0 resolution: workspace environment: + # Lower than the bound of a2ui_flutter on purpose. a2ui_core is plain Dart, + # used outside Flutter too, such as by agents and servers, and by Flutter + # apps on older SDKs, so it allows every SDK its own code compiles with. 3.5 + # is the lowest version that `resolution: workspace` allows. sdk: ">=3.5.0 <4.0.0" dependencies: