blob: 8efb49291aa637e0de52e7ce33691c2b75f74dca [file] [view]
# 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.