| # Ephemeral Runtime Demo App |
| |
| ## Prerequisites |
| |
| - `gclient` (from depot_tools) installed and in your PATH. |
| |
| ## Setup |
| |
| Create an empty directory for the workspace. Then run: |
| |
| ```sh |
| 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 restart`is 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: |
| |
| ```sh |
| 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: |
| |
| ```sh |
| 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](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: |
| |
| ```sh |
| 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. |
| |
| ```sh |
| 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): |
| |
| ```sh |
| # ../../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: |
| |
| ```sh |
| 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`: |
| ```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](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. |
| |
| ```sh |
| cd third_party/dart-sdk/sdk |
| ``` |
| |
| ### Build the Dart SDK |
| |
| Build the worker and SDK tarball: |
| |
| ```sh |
| ./tools/build.py -m release -a x64 dartpad |
| ``` |
| |
| ### 7. Set up Local Flutter Assets |
| |
| ```sh |
| 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: |
| |
| ```sh |
| ./tools/build.py -m release -a x64 dartpad --no-verify-sdk-hash |
| ``` |
| |
| <details> |
| <summary>Crash Log Example</summary> |
| |
| ``` |
| 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). |
| ... |
| ``` |
| |
| </details> |
| |
| ### Run the Integration Test |
| |
| Run the integration test from the `pkg/dartpad_worker` directory, again using the newly built `dart` executable: |
| |
| ```sh |
| 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](https://firebase.corp.google.com/project/dart-vibepad/appdistribution/app/ios:dev.dart.vibepadcompanion/releases) 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](https://firebase.corp.google.com/project/dart-vibepad/appdistribution/app/android:dev.dart.vibepadcompanion/releases) of Android app. |
| c) Send it to the "VibePad Partners" group. |
| |
| ### Frontend |
| |
| 1. `cd packages/frontend` |
| 1. `PATH="../../third_party/flutter/bin:$PATH" dart run jaspr_cli:jaspr build --dart-define-from-file=.env.prod` |
| 2. `cd build/jaspr` |
| 3. `zip -r ../vibepad_deploy.zip * -x "*.DS_Store"` |
| 4. Upload the zip to go/zipline. |
| 5. Update the go/try-vibepad (and go/try-public-vibepad) link. |