Clone this repo:

Branches

  1. 3742c71 fix open in new tab by Kilian Schulte · 3 weeks ago main
  2. 57b2784 migrate to dartpad packages by Kilian Schulte · 3 weeks ago
  3. 1c07d86 Release v0.4.0+3 (frontend only) by Michael Goderbauer · 5 weeks ago
  4. 557fa02 make share links run in Safari by Michael Goderbauer · 5 weeks ago
  5. 78818e4 Add QR code to share dialog by Michael Goderbauer · 5 weeks ago

Ephemeral Runtime Demo App

Prerequisites

  • gclient (from depot_tools) installed and in your PATH.

Setup

Create an empty directory for the workspace. Then run:

gclient config --spec='solutions=[
  {
    "name": "vibepad",
    "url": "https://dart.googlesource.com/vibepad",
    "deps_file": "DEPS",
    "managed": False,
    "custom_vars": {
    }
  }
]'
gclient sync

cd vibepad

# Strictly needed only if you need to build the dill files (already checked in).
#
# Normally when setting up the Dart SDK in a non-nested config, https://github.com/dart-lang/sdk/blob/1f48889e8f28eb1ec2a1debfbd053c3307f91261/DEPS#L180-L183 causes this file to be automatically created.
# But in this repo, we have a nested gclient setup so that doesn't work. So create the file manually
echo 'build_devtools_from_sources = false' > third_party/dart-sdk/sdk/build/config/gclient_args.gni

Run the web app

Create an .env.local file in packages/frontend with the env.example as a template. Leave the FIREBASE_APPCHECK_DEBUG_TOKEN empty if you don't have one. When you run the app, it will print a debug token in the browser console that you can use to populate the env variable. Add this to the Debug Tokens in Firebase App Check (message goderbauer@google.com to have it added). The FIREBASE_APPCHECK_SITE_KEY can be ignored for local development.

Note: -m restartis required due to two issues with build_web_compilers and hot-reload in Jaspr. See https://github.com/dart-lang/build/pull/4945 and https://github.com/dart-lang/build/issues/4950


This command overrides the specific version of Flutter and Dart. The `$PATH` override also overrides subprocess calls since jaspr_cli calls into `dart` again. ```sh cd packages/frontend PATH="../../third_party/flutter/bin:$PATH" dart run jaspr_cli:jaspr serve --dart-define-from-file=.env.local

Accessing from a remote machine

Note: Might not be needed if you use a VS Code variant and have the remote.autoForwardPorts settings enabled.

If you access the app from a remote machine (e.g., using the server's hostname or IP), the development features like hot reload will fail because they try to connect to localhost:8080 on the remote machine.

To fix this, use SSH port forwarding:

ssh -L 8080:localhost:8080 <user>@<server-ip-or-hostname>

Then access the app at http://localhost:8080 on the remote machine.

Run the companion app

TODO(b/474440143): Simplify running bytecode in Flutter.

The default engine that ships with Flutter doesn not have support for bytecode enabled, but a custom engine with bytecode support can be downloaded by running:

cd packages/companion
../../third_party/flutter/bin/dart run script/download_ddm_artifacts.dart

For iOS, this will “poisen” the Flutter cache with an engine version with bytecode support.

For Android, this will download a seperate engine version with bytecode support to the Flutter cache and android/app/build.gradle.kts has been modified to inject that engine (tested for arm64 devices in debug mode).


Create an .env.local file in packages/companion with the env.example as a template. Leave the FIREBASE_APPCHECK_DEBUG_TOKEN empty if you don't have one. When you run the app, it will print a debug token in the terminal that you can use to populate the env variable. Add this to the Debug Tokens in Firebase App Check (message goderbauer@google.com to have it added).


After downloading the custom engines and creating the local env file, execute the command below to run the companion app:

cd packages/companion
PATH="../../third_party/flutter/bin:$PATH" flutter run --extra-front-end-options=--dynamic-interface=dynamic_interface.yaml --dart-define-from-file=.env.local

Optional: Build artifacts needed for bytecode compilation

This section is optional as the relevant artifacts have been checked into packages/frontend/web/ddm for now.

cd packages/companion
../../third_party/flutter/bin/flutter pub get
../../third_party/flutter/bin/cache/dart-sdk/bin/dartaotruntime \
  --disable-dart-dev \
  ../../third_party/flutter/bin/cache/dart-sdk/bin/snapshots/frontend_server_aot.dart.snapshot \
  --sdk-root ../../third_party/flutter/bin/cache/artifacts/engine/common/flutter_patched_sdk_product \
  --target=flutter \
  --no-print-incremental-dependencies \
  -Ddart.vm.profile=false \
  -Ddart.vm.product=true \
  --delete-tostring-package-uri=dart:ui \
  --delete-tostring-package-uri=package:flutter \
  --no-aot \
  --packages "../../.dart_tool/package_config.json" \
  --output-dill ../frontend/web/ddm/host_app.dill \
  --no-embed-source-text \
  --verbosity=error \
  --dynamic-interface=dynamic_interface.yaml \
  "package:companion/dummy.dart"
cp dynamic_interface.yaml ../frontend/web/ddm/dynamic_interface.yaml

TODO(goderbauer): Trim the host_app.dill (trimming with trim.dart results in Unsupported operation: Platform._version when trying to compile bytecode):

# ../../third_party/flutter/bin/dart \
#   ../../third_party/dart-sdk/sdk/pkg/front_end/tool/trim.dart \
#   --input ../frontend/web/ddm/host_app.dill \
#   --platform ../../third_party/flutter/bin/cache/artifacts/engine/common/flutter_patched_sdk_product/platform_strong.dill \
#   --output ../frontend/web/ddm/host_app_trimmed.dill \
#   --output-platform ../frontend/web/ddm/platform_strong_trimmed.dill \
#   --dynamic-interface dynamic_interface.yaml

Examples

Examples are template projects shown on the prompt page. They are defined in examples/examples.yaml and bundled into ZIP files for the frontend.

Rebundle after changes

If you modify anything under examples/ (code, YAML manifest, or images), rebundle:

dart run tool/bundle_examples.dart

Add a new example

  1. Create a directory examples/<id>/ with at least a pubspec.yaml
  2. Add an entry to examples/examples.yaml:
    - id: my_example
      title: My Example
      prompt: >- # optional: pre-fills the agent composer
        Tell the agent what to do...
      image: screenshot.png # optional: attaches an image to the prompt
    
  3. Run dart run tool/bundle_examples.dart

See packages/frontend/docs/examples.md for full details on the example structure, YAML fields, and runtime behavior.

Optional: Building and Testing Artifacts

This section is optional as the relevant artifacts have been checked into packages/frontend/web/ for now.

cd third_party/dart-sdk/sdk

Build the Dart SDK

Build the worker and SDK tarball:

./tools/build.py -m release -a x64 dartpad

7. Set up Local Flutter Assets

FLUTTER_ROOT=../../flutter ./out/ReleaseX64/dart-sdk/bin/dart pkg/dartpad_worker/tool/setup_local_flutter.dart \
  --bootstrap-code-path ../../../packages/frontend/bootstrap_flutter.dart && \
cp -r pkg/dartpad_worker/.dart_tool/dartpad_worker/asset/flutter ../../../packages/frontend/web/

On macOS replace out/ with xcodebuild/ in the command above.

Crash (SDK Hash Mismatch)

If the setup command causes an Unexpected Kernel SDK Version crash, it means the compiled Dart SDK expects a different SDK hash than the prebuilt Flutter SDK kernel files.

To avoid this, build the Dart SDK with the --no-verify-sdk-hash (or -nvh) flag:

./tools/build.py -m release -a x64 dartpad --no-verify-sdk-hash
Using Flutter SDK at: /tmp/ert/ert/third_party/flutter
Target asset directory: /tmp/ert/ert/third_party/dart-sdk/sdk/pkg/dartpad_worker/.dart_tool/dartpad_worker/asset/flutter
Creating dummy app...
Pruning pubspec.yaml...
Running flutter pub get...
Building dummy app for web (to harvest assets)...
Scraping assets...
Copying flutter.js
Scraping CanvasKit...
Compiling flutter_web.js and flutter_web.dill...
Command failed: ... dartdevc.dart.snapshot ...
stderr: Unhandled exception:
Crash when compiling package:characters/characters.dart:
Unexpected Kernel SDK Version a3af894986 (expected 7ee6441aed).
...

Run the Integration Test

Run the integration test from the pkg/dartpad_worker directory, again using the newly built dart executable:

cd pkg/dartpad_worker
../../out/ReleaseX64/dart-sdk/bin/dart test test/flutter/integration/test_flutterpad.dart

On macOS replace out/ with xcodebuild/ in the command above.

You should see All tests passed!.

Releases

Before releasing, update the version number in packages/companion/pubspec.yaml (e.g. by increaseing the build number after the + sign).

Companion App

  1. cd packages/companion
  2. ../../third_party/flutter/bin/dart run script/download_ddm_artifacts.dart
  3. iOS (IPA) a) PATH="../../third_party/flutter/bin:$PATH" flutter build ipa --export-method ad-hoc --extra-front-end-options=--dynamic-interface=dynamic_interface.yaml --dart-define-from-file=.env.prod b) Upload build/ios/ipa/VibePad Companion.ipa to Firebase console of iOS app. c) Send it to the “VibePad Partners” group.
  4. Android (APK) a) PATH="../../third_party/flutter/bin:$PATH" flutter build apk --extra-front-end-options=--dynamic-interface=dynamic_interface.yaml --dart-define-from-file=.env.prod b) Upload build/app/outputs/flutter-apk/app-release.apk to the Firebase console of Android app. c) Send it to the “VibePad Partners” group.

Frontend

  1. cd packages/frontend
  2. PATH="../../third_party/flutter/bin:$PATH" dart run jaspr_cli:jaspr build --dart-define-from-file=.env.prod
  3. cd build/jaspr
  4. zip -r ../vibepad_deploy.zip * -x "*.DS_Store"
  5. Upload the zip to go/zipline.
  6. Update the go/try-vibepad (and go/try-public-vibepad) link.