Skip to main content
The examples/counter_app/ directory in the Roveflow repo is a freshly-scaffolded Flutter counter app with Roveflow installed. It ships as the reference install for the roveflow init flow — if this example breaks, the CLI is broken.

Layout

examples/counter_app/
├── lib/
│   ├── main.dart                                   # counter scaffold + kDebugMode block
│   └── core/
│       ├── general_helpers/utils/
│       │   └── navigation_util.dart                # minimal navigate.pop() helper
│       └── mcp/
│           └── mcp_interaction_tools.dart          # <your_app> pre-substituted
├── docs/
│   └── roveflow/
│       └── scenarios.md                             # cold-setup + increment-counter
├── pubspec.yaml                                    # flutter + mcp_toolkit
└── README.md
Files not committed (regenerated by roveflow init on demand):
  • .claude/skills/roveflow/
  • .claude/commands/roveflow.md
  • .claude/agents/roveflow-runner.md
  • .mcp.json

Run it locally

From the Roveflow repo root:
dart pub global activate --source path packages/roveflow
cd examples/counter_app
roveflow init
flutter pub get
flutter run -d <simulator-id>
After roveflow init, edit .mcp.json to point the flutter-inspector command at your local flutter_inspector_mcp binary. Once the simulator shows the counter, in Claude Code:
/roveflow --only=cold-setup

What roveflow init wrote

  • .claude/skills/roveflow/ — the full skill (SKILL.md + 10 references).
  • .claude/commands/roveflow.md — slash command.
  • .claude/agents/roveflow-runner.md — agent body.
  • lib/core/mcp/mcp_interaction_tools.dart — MCP tools drop-in.
  • .mcp.jsonflutter-inspector config.
  • docs/roveflow/scenarios.md — starter template, overwritten in-repo with the counter-app cold-setup.

The hand-written pieces

Five files are committed in git because roveflow init cannot generate them automatically for an existing app:
  1. lib/main.dart — the standard counter scaffold plus the kDebugMode block:
    if (kDebugMode) {
      MCPToolkitBinding.instance
        ..initialize()
        ..initializeFlutterToolkit();
      await registerMcpInteractionTools();
    }
    
  2. lib/core/general_helpers/utils/navigation_util.dart — a minimal navigate.pop() helper using GlobalKey<NavigatorState>. New Flutter apps don’t ship this, and the MCP tools import it. Roveflow installs point at this exact path.
  3. lib/core/mcp/mcp_interaction_tools.dart — the bundled interaction tools, with <your_app> already substituted for this example’s package name.
  4. docs/roveflow/scenarios.md — filled with the counter app’s real cold-setup and an increment-counter extended scenario.
  5. pubspec.yaml — standard Flutter app plus the mcp_toolkit dependency.

The scenarios

id: cold-setup
criticality: critical
order: 0
goal: Reach the default Flutter counter screen from cold install.
entry: cold-install
waypoints:
  - reach_screen: "Flutter Demo Home Page"
steps_hint: |
  The default Flutter app opens directly to the counter. No login.
  Verify the app bar reads "Flutter Demo Home Page" and the counter "0"
  is visible.
pass: counter "0" visible AND floating-action-button visible
fail: screen blank, app crashes within 10s, or app bar title missing
id: increment-counter
criticality: extended
order: 1
goal: Increment the counter once by tapping the floating action button.
entry: home
waypoints:
  - tap_floating_action_button
  - counter_increments_to: "1"
steps_hint: |
  From the home screen ("Flutter Demo Home Page"), tap the floating
  action button (the "+" icon in the bottom-right). Verify the counter
  text updates from "0" to "1".
pass: counter "1" visible after tap
fail: counter stays at "0", or no floating-action-button found

Known gaps

Surfaced while dogfooding this example:
  • <your_app> placeholder substitution works for the init command, but a team copying files manually needs to substitute <your_app> by hand. The bundled template ships with the placeholder so the CLI can substitute; a manual adopter cannot read past that.
  • navigate.pop() assumption — the skill expects a top-level helper to exist. New Flutter apps don’t have one. Adopters without this helper must either create a stub (this example ships one as a reference) or adapt the MCP tool file.
Both gaps are documented in examples/counter_app/README.md and tracked for a follow-up.