Examples

Examples are Flutter projects offered as templates on the prompt page. The frontend serves them from TAR files in packages/frontend/web/examples/.

Most examples also have checked-in source directories under examples/. Very large examples may be checked in as a prebuilt TAR only, with their local source directory intentionally ignored.

Table of Contents

Structure

examples/
├── examples.yaml                    # Source of truth for the template list
├── simple_counter/                  # Normal checked-in example source
   ├── pubspec.yaml
   └── lib/
       ├── main.dart
       └── counter.dart
├── overflow_debug/
   ├── pubspec.yaml
   └── lib/
       └── main.dart
├── rebuild_weather_app/
   ├── pubspec.yaml
   └── weather_app_screenshot.jpg   # Image attached to the prompt
└── flutter-wonderous-app/           # Local-only, ignored; TAR is checked in

packages/frontend/web/examples/
├── examples.json                    # Generated manifest served by frontend
├── simple_counter.tar
├── overflow_debug.tar
├── rebuild_weather_app.tar
└── flutter-wonderous-app.tar        # Prebundled Wonderous template

YAML Manifest

The template list is defined in examples/examples.yaml. Each entry defines:

FieldRequiredDescription
idTemplate id. For source-backed examples this matches examples/<id>/; for prebundled examples it matches packages/frontend/web/examples/<id>.tar.
titleDisplay name shown on the prompt page.
promptOptional prompt pre-filled in the agent composer.
imageOptional image file name inside the example TAR.
examples:
  - id: simple_counter
    title: Counter Template

  - id: overflow_debug
    title: Overflow Debug
    prompt: >-
      My profile screen doesn't look right — some content seems to be cut off
      or missing. Can you take a screenshot and help me figure out what's wrong?

  - id: rebuild_weather_app
    title: Rebuild Weather App
    prompt: >-
      Rebuild this weather app and verify your result with screenshots comparing it against the attached image.
      Generate background images for the different weather conditions. Use mocks for the weather data.
    image: weather_app_screenshot.jpg

  - id: flutter-wonderous-app
    title: Wonderous App

Template behavior based on fields

The editor and agent panel are visible for every template. Optional manifest fields only control composer prefill:

Has prompt?Has image?Behavior
Opens the editor and agent panel. If lib/main.dart exists, the preview starts automatically after pub get.
Same as above, with the prompt pre-filled in the composer.
Same as above, with the prompt and image thumbnail pre-filled in the composer.

The user reviews any pre-filled prompt and hits Send manually. Selecting a template does not automatically start an agent run.

Bundling

The script tool/bundle_examples.dart reads examples.yaml and:

  1. Generates examples.json in packages/frontend/web/examples/ with id, title, optional prompt, and optional image metadata (imageMimeType, imageFileName).
  2. Creates TAR files for examples whose source directories exist locally.
  3. Keeps checked-in TARs for prebundled examples whose source directories are intentionally absent.
  4. Tracks checksums in .checksums.json; unchanged source-backed examples are not re-bundled.
dart run tool/bundle_examples.dart

The generated files under packages/frontend/web/examples/ are checked in.

If an example appears in examples.yaml but has neither a local source directory nor an existing checked-in TAR, bundling fails. This protects normal examples from silently disappearing while still allowing large prebundled templates such as Wonderous.

The bundler skips generated local Flutter artifacts (build/, .dart_tool/, .flutter-plugins*, and pubspec.lock) so local flutter pub get, flutter analyze, or generator output does not accidentally bloat a template TAR.

Runtime Behavior

On startup the frontend fetches examples/examples.json and displays the templates on the prompt page. When a template is selected:

  1. The corresponding TAR (examples/<id>.tar) is fetched and extracted into the workspace.
  2. The project session opens with the editor and agent panel visible.
  3. If the template has a prompt and/or image, those are pre-filled in the agent composer.
  4. The frontend runs pub get.
  5. If lib/main.dart exists, the preview starts automatically with initial preview validation skipped. This avoids blocking startup on stale LSP diagnostics while the imported workspace is still settling.

Adding a New Example

Code template with checked-in source

  1. Create examples/<id>/ with a pubspec.yaml and usually lib/main.dart.
  2. Add an entry to examples/examples.yaml:
    - id: my_example
      title: My Example
    
  3. Run dart run tool/bundle_examples.dart.
  4. Check in both the source directory and the generated files under packages/frontend/web/examples/.

Prompt-driven template

  1. Create examples/<id>/ with at least a pubspec.yaml.
  2. Optionally add code in lib/ and/or an image file.
  3. Add an entry to examples/examples.yaml:
    - id: my_example
      title: My Example
      prompt: >-
        Describe what the agent should do...
      image: screenshot.png # optional
    
  4. Run dart run tool/bundle_examples.dart.

Large prebundled template

Use this for templates that are too large to check in as source, such as Wonderous.

  1. Create the source directory locally at examples/<id>/.
  2. Add an entry to examples/examples.yaml.
  3. Add the source directory to .gitignore.
  4. Run dart run tool/bundle_examples.dart.
  5. Check in the generated TAR, examples.json, and .checksums.json, but not the local source directory.

After that, other developers can run dart run tool/bundle_examples.dart without having the large local source directory. The script will keep using the checked-in TAR.


Counter App

A minimal Flutter counter app. Demonstrates basic StatefulWidget usage with setState.

Overflow Debug

A Flutter profile screen with intentional overflow and layout issues. The pre-filled prompt asks the agent to take screenshots, diagnose the problems, and fix them iteratively.

Rebuild Weather App

An empty project with a screenshot of a weather app UI. The agent is asked to rebuild the app from the screenshot and generate background images for different weather conditions.

Wonderous App

The Wonderous App by gskinner is the most complex example. It is intentionally checked in as packages/frontend/web/examples/flutter-wonderous-app.tar; the local source directory examples/flutter-wonderous-app/ is ignored because it is large.

Assets

The preview sandbox serves project assets through a custom DefaultAssetBundle that forwards asset keys to the host workspace. Wonderous previously decoded illustration image dimensions with:

rootBundle.load(imgPath)

That bypassed the sandbox bundle and made Flutter Web fall back to HTTP requests such as flutter/assets/assets/images/..., which 404 against the static SDK asset directory. lib/ui/wonder_illustrations/common/illustration_piece.dart now uses:

DefaultAssetBundle.of(context).load(imgPath)

This keeps those manual image loads on the same sandbox asset path as Image.asset(...).

Why plugins do not auto-register in the sandbox

In a normal flutter build web, Flutter auto-generates generated_plugin_registrant.dart which registers web plugins. The preview sandbox skips the Flutter build step and compiles raw Dart through DDC (Dart Dev Compiler). Federated web plugins therefore need manual registration with the same registerWith pattern.

DDC also does not tree-shake unreachable imports in the same way a release dart2js build does. For this template, web-only and native-only code needs to be separated with conditional imports such as if (dart.library.js_interop), not just runtime kIsWeb checks.

Plugin registration

Registration happens in lib/register_plugins_web.dart, loaded via conditional import in main.dart:

// main.dart
import 'package:wonders/register_plugins_stub.dart'
    if (dart.library.js_interop) 'package:wonders/register_plugins_web.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  registerWebPlugins(); // no-op on native, registers on web
  // ...
}
// register_plugins_web.dart
void registerWebPlugins() {
  final registrar = webPluginRegistrar;
  SharedPreferencesPlugin.registerWith(registrar);
  UrlLauncherPlugin.registerWith(registrar);
  registrar.registerMessageHandler();
}
// register_plugins_stub.dart
void registerWebPlugins() {} // no-op on native

Problematic packages and fixes

shared_preferences — fixed via registerWith

Detail
ProblemMissingPluginException because the web plugin is not auto-registered in the sandbox.
Root causeMissing generated plugin registrant.
FixSharedPreferencesPlugin.registerWith(registrar) in register_plugins_web.dart.
Web behaviorUses browser localStorage through shared_preferences_web.

url_launcher — fixed via registerWith and iframe sandbox flags

Detail
ProblemMissingPluginException, then links did not open.
Root causeMissing plugin registration plus the preview iframe blocking window.open().
FixUrlLauncherPlugin.registerWith(registrar) and allow-popups on the preview iframe sandbox attribute in sandbox.dart.

youtube_player_iframe — currently bypassed on web

Detail
ProblemThe WebView-backed YouTube path can hit createPlatformNavigationDelegate is not implemented on the current platform in the sandbox if the wrong WebView platform implementation is registered or compiled into the web path.
Current fixfullscreen_video_viewer.dart uses a conditional import. Web loads video_player_web.dart, which embeds YouTube directly with HtmlElementView.fromTagName('iframe'); native loads video_player_stub.dart, which keeps the original YoutubePlayer widget.
Why this is safeA YouTube embed is just an iframe pointing at a YouTube embed URL. For the Wonderous preview, the direct iframe gives the same user-visible result with less plugin machinery.
AlternativeIt may be possible to use youtube_player_iframe on web by manually registering youtube_player_iframe_web's WebYoutubePlayerIframePlatform instead of webview_flutter_web‘s WebWebViewPlatform. That plugin class is not exported from the package’s public library today, so this would require either a src/ import or an upstream/exported shim. If we try it, keep it behind a conditional web-only import and do not register webview_flutter_web globally.

webview_flutter — bypassed on web

Detail
ProblemThe generic webview_flutter_web implementation does not implement the full platform interface needed by the current resolved webview_flutter_platform_interface.
Fixfullscreen_web_view.dart checks kIsWeb and falls back to launchUrl() on web, opening the link in a new tab. Native keeps the original WebViewController code.

google_maps_flutter — stubbed

Requires Google Maps JavaScript API setup and a key. The Wonderous preview replaces maps with a “Maps not available in web preview” placeholder.

home_widget — stubbed

iOS/Android-only feature with no useful web equivalent for the preview. The template uses a no-op NativeWidgetService.

Preview limitations

  • Maps are placeholders.
  • Home-screen widget integration is disabled.
  • About links open in a new browser tab.
  • YouTube videos currently use a direct iframe embed instead of the youtube_player_iframe widget on web.