Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .claude/skills/agent-eval/corpus.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@
{ "name": "grpc", "repo": "https://github.com/grpc/grpc", "size": "Large", "files": "~3000", "question": "How does gRPC dispatch an incoming RPC to its handler?" }
],
"Dart": [
{ "name": "navigation_and_routing", "repo": "https://github.com/flutter/samples", "subdir": "navigation_and_routing", "size": "Small", "files": "~17", "question": "How does navigating to /books/popular show the BooksScreen?" },
{ "name": "compass_app", "repo": "https://github.com/flutter/samples", "subdir": "compass_app/app", "size": "Medium", "files": "~129", "question": "How does the booking flow reach BookingScreen from the home tab?" },
{ "name": "flutter", "repo": "https://github.com/flutter/flutter", "size": "Large", "files": "~6000", "question": "How does Flutter build and lay out a widget tree?" }
],
"Svelte": [
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
- The IDE shares `GEMINI.md` with Gemini CLI, so the two targets compose naturally when both are installed; the antigravity target deliberately doesn't touch `GEMINI.md` so uninstalling Antigravity alone leaves CLI instructions intact.

Both targets are tested on the same parameterized contract as the existing five agents (idempotent install, sibling preservation, install/uninstall round-trip), with extra coverage for migration-marker detection, legacy β†’ unified entry migration, sibling `disabled` field preservation, and the cross-target case where Gemini CLI and Antigravity IDE coexist in the same `~/.gemini/`. Closes #399.
- **Flutter framework-aware resolution for Dart projects.** Three new resolvers in `src/resolution/frameworks/flutter.ts` recognize Flutter-specific patterns on top of the existing Dart language extraction, so widget trees, navigation, and state-management dispatches resolve end-to-end instead of falling back to generic name matching:
- **`flutterResolver`** β€” widgets. Detected via `pubspec.yaml`'s `flutter: sdk: flutter` block or any `.dart` file importing `package:flutter/*`. `StatelessWidget`/`StatefulWidget`/`ConsumerWidget`/`HookWidget` subclasses become `component` nodes; `_FooState extends State<Foo>` is paired back to its widget; `runApp(MyApp())` emits an app entry node. PascalCase user-widget references resolve to their class/component, preferring `/lib/widgets/` and `/lib/screens/`. ~140 common Material / Cupertino / Widgets-library built-ins (`Scaffold`, `Container`, `Row`, `MaterialApp`, …) and `package:flutter/*` / `dart:ui` imports short-circuit as framework-provided (1.0) so the name resolver doesn't waste cycles on them.
- **`flutterRouterResolver`** β€” navigation. Extracts `MaterialApp(routes: { '/foo': (ctx) => FooScreen() })` named routes and `GoRoute(path:, builder:)` / `ShellRoute(...)` trees (parent-prefix joined via a stack-based scanner). Matches real-world idioms: block-body builders (`builder: (c, s) { return Screen(); }`, the dominant form), generic-typed page wrappers (`pageBuilder: …{ return FadeTransitionPage<dynamic>(child: Screen()); }`), and constant-reference paths (`path: Routes.login` β€” common when apps centralize paths in a `class Routes`). Route β†’ handler refs resolve to screen classes preferring `/lib/screens/` and `/lib/pages/`. Activates on either `go_router` in `pubspec.yaml` or an inline routes map / GoRoute call.
- **`flutterStateResolver`** β€” Provider / Riverpod / Bloc / GetX. Per-package detection from `pubspec.yaml`. Framework dispatch shapes (`context.read`, `ref.watch`, `BlocProvider.of`, `Get.find`, …) short-circuit as framework-provided so they don't fuzzy-match to unrelated symbols; `*Provider`, `*Bloc`/`*Cubit`, and `*Controller` names resolve preferring their conventional directories.

Also adds `'dart'` to the `CommentLang` set in `strip-comments.ts` so the Flutter extractors can scan comment-stripped source (`//` and `/* */`, Dart-flavoured). Validated end-to-end per the dynamic-dispatch-coverage-playbook: deterministic β€” `flutter/samples/navigation_and_routing` (17 .dart files, 306 nodes) emits all 10 GoRoute paths with correct handlers, `compass_app/app` (129 .dart files, 1873 nodes) emits all 7 GoRoute paths through `Routes.X` constant-reference paths, express control unchanged (990 nodes, 266 routes); agent A/B (n=2 per arm, Opus headless via Claude Code) on the same two repos shows codegraph cuts agent **Read 3.0 β†’ 0.5 (βˆ’83%), duration 40s β†’ 24.5s (βˆ’39%), tool calls βˆ’46%**. Codified as `scripts/agent-eval/validate-flutter.sh` (deterministic half β€” re-runs as a 12-second quality gate). 25 new test cases in `__tests__/frameworks.test.ts` cover detect/resolve/extract for each resolver including the four real-world router idioms above. Closes #420.

## [0.9.5] - 2026-05-25

Expand Down
Loading