Start here
Set up with an AI coding agent
Paste one prompt into Claude Code, Cursor, Copilot or any coding agent that works in your app's repository. It installs the SDK, connects it, adds the capture adapters your app already uses and reports what it changed. A second prompt, for later, makes the flows you choose replayable.
Before you paste
- Run the agent from the root of your app repository, on a new branch, so the whole setup is one diff you can review.
- Generate an SDK token (
bcsdk.v1.…) in Project Settings › Keys › SDK tokens and copy it straight away: it is shown once. Generating one needs the Admin or Owner role, so ask one if you can't. The token is the only value the app needs. - Edit the bracketed values at the top of the prompt before you send it.
The prompts pin Flutter 0.4.1-beta.5, Android 0.4.1-beta.4, iOS 0.4.1-beta.2 and web 0.4.0-beta.2. These releases support SDK token setup. An app that already connects with an explicit API URL and bci_ ingest key keeps that setup; the prompts tell the agent not to add a token on top.
Never paste a bcs_ secret key or a bcp_ personal CLI token into a prompt. The agent doesn't need either, and both act with more rights than an app should have.
What the prompts tell the agent
| Rule | Why |
|---|---|
| Install the exact beta version | All BugCapsule packages must match, and replay depends on the build you captured. |
| Start BugCapsule first | In replay, the SDK restores storage and state before your app code reads them. |
| Adapters only for libraries the app uses | Unused adapters do nothing, and the agent lists what it skipped. |
| Storage is allowlist only | Keys with tokens, passwords or personal data stay out of Capsules. |
| Production capture stays off | Debug and QA builds record. Turn production on after the production checklist. |
| Stop and ask on conflicts | No silent dependency upgrades, replaced test runners or hand-edited Xcode projects. |
| Follow the platform guide | Agents that can browse read it first, and where the two disagree the guide wins. |
1. Connect and capture
Pick your platform and copy the prompt.
Add the BugCapsule Flutter SDK to this app. BugCapsule records failures in QA builds as replayable Capsules. Make small, reviewable changes.
SDK token from my BugCapsule dashboard: [paste bcsdk.v1.… here]
Guide: https://docs.bugcapsule.com/flutter.html. Read it first if you can browse. Where it and this prompt disagree, the guide wins.
Rules:
- Install exactly bug_capsule 0.4.1-beta.5. Don't use a version range.
- Connect with the SDK token: it carries the BugCapsule address, so there's no URL or project ID to configure. If this app already connects with an explicit API URL and a bci_ ingest key, keep that and don't add a token.
- Put the token where this project keeps client-side build configuration. It is ingest-only and ships inside the app. Never add a bcs_ secret key or a bcp_ personal token anywhere.
- Keep capture off in production builds: debug and QA builds record, production release builds don't, unless I say otherwise (https://docs.bugcapsule.com/production.html).
- Storage capture is allowlist only. Never allowlist keys that hold tokens, passwords or personal data.
- Don't upgrade or downgrade my other dependencies, and don't change what the app does. Stop and ask instead.
- Don't invent APIs. If something you need isn't in the guide or in the SDK's source, stop and ask me.
Steps:
1. Check the requirements: Flutter 3.35 or later, Dart ^3.9. If the project is older, stop and tell me.
2. Add `bug_capsule: 0.4.1-beta.5` under dependencies in pubspec.yaml and run flutter pub get. The package depends on bloc ^9, riverpod ^3, get ^4.6, mobx ^2.3, dio ^5.9, http ^1.5, go_router 14–18 and shared_preferences ^2.5, including the ones this app doesn't use. If resolution fails, stop and show me the conflict and the smallest upgrade that would fix it.
3. Make BugCapsule.init the first call in main. Move the current body of main (ensureInitialized, Firebase or Sentry setup, runApp) into appRunner, which may be async:
void main() => BugCapsule.init(
config: BugCapsuleConfig(
token: '...', // or const String.fromEnvironment('BUGCAPSULE_SDK_TOKEN'), if the project keeps config in dart-defines
enabled: !kReleaseMode || const bool.hasEnvironment('BUGCAPSULE_MODE'),
),
appRunner: () async { /* the old body of main, ending with runApp(...) */ },
);
The enabled line keeps production release builds off while debug builds and QA builds made with BUGCAPSULE_MODE record. appVersion and appBuild default to the BUGCAPSULE_APP_VERSION and BUGCAPSULE_APP_BUILD dart-defines; leave them out of the config. If main already uses runZonedGuarded or another wrapper, keep it inside appRunner and tell me.
4. Add capture adapters only for libraries the app actually uses:
- dio: one BugCapsuleDio() in integrations, and bugCapsuleDio.attach(dio) wherever a Dio is built (after any custom httpClientAdapter).
- http or chopper: BugCapsuleHttp(), and use bugCapsuleHttp.client() (or client(existingClient)) where the app creates its http.Client.
- go_router: BugCapsuleGoRouter(); pass bugCapsuleRouter.initialLocation('<the current initial location>') to GoRouter and call bugCapsuleRouter.attach(router).
- bloc: BugCapsuleBloc(states: [...]) for states that already have toJson and fromJson.
- riverpod: BugCapsuleRiverpod(states: [...]), and add bugCapsuleRiverpod.observer to ProviderScope's observers.
- provider/ChangeNotifier, get, mobx: BugCapsuleNotifiers, BugCapsuleGetx or BugCapsuleMobx as the guide shows, only for models that already serialize.
- shared_preferences: BugCapsuleSharedPreferences(allowPrefixes: [...]) with prefixes of non-sensitive keys. Never call it without allowPrefixes: that captures every key.
Don't write new serializers. List the state you skipped instead.
5. Add the QA capture button: wrap the app's child in BugCapsuleOverlay(child: child!) in the MaterialApp builder, keeping any builder that's already there. It only shows outside production.
6. Wherever this repo makes QA or CI builds (scripts, Makefile, CI workflows, Fastlane), add --dart-define=BUGCAPSULE_MODE=qa --dart-define=BUGCAPSULE_GIT_SHA=$(git rev-parse HEAD), and BUGCAPSULE_APP_VERSION / BUGCAPSULE_APP_BUILD from the pubspec version. Never add them to production release builds. If there are no build scripts, put the commands in your report.
7. Run flutter analyze and the existing tests. Fix what you broke; leave unrelated warnings alone.
Report back:
- Each file you changed and why, one line each.
- Which adapters you added, and what you skipped and why.
- How I confirm it: start a debug or QA build, open SDK Setup in the BugCapsule dashboard and wait for "Configuration fetched", then "First event or Capsule received". Or add debugPrint(BugCapsule.status.toString()) once at startup in a debug build: its connection state should become connected, and instrumentation.missing lists the adapters still to add.
- Anything you weren't sure about.
Add the BugCapsule Android SDK to this app. BugCapsule records failures in QA builds as replayable Capsules. Make small, reviewable changes.
SDK token from my BugCapsule dashboard: [paste bcsdk.v1.… here]
Guide: https://docs.bugcapsule.com/android.html. Read it first if you can browse. Where it and this prompt disagree, the guide wins.
Rules:
- Install exactly every io.github.bugcapsule module at 0.4.1-beta.4. Don't use a version range.
- Connect with the SDK token: it carries the BugCapsule address, so there's no URL or project ID to configure. If this app already connects with an explicit API URL and a bci_ ingest key, keep that and don't add a token.
- Put the token where this project keeps client-side build configuration. It is ingest-only and ships inside the app. Never add a bcs_ secret key or a bcp_ personal token anywhere.
- Keep capture off in production builds: debug and QA builds record, production release builds don't, unless I say otherwise (https://docs.bugcapsule.com/production.html).
- Storage capture is allowlist only. Never allowlist keys that hold tokens, passwords or personal data.
- Don't upgrade or downgrade my other dependencies, and don't change what the app does. Stop and ask instead.
- Don't invent APIs. If something you need isn't in the guide or in the SDK's source, stop and ask me.
Steps:
1. Check the requirements: minSdk 23 or higher and JDK 17. If the app is below that, stop and tell me.
2. Make sure google() and mavenCentral() are in the project's repositories. In the app module, add io.github.bugcapsule:bugcapsule-android:0.4.1-beta.4, plus only what the app uses: bugcapsule-okhttp (OkHttp or Retrofit), bugcapsule-navigation (Jetpack Navigation) and bugcapsule-compose (Jetpack Compose), all at the same version. Use the version catalog if the project has one. Don't add the replay runner or change testInstrumentationRunner; that's a later step.
3. Make sure the app manifest declares android.permission.INTERNET.
4. Add BuildConfig fields (and buildFeatures.buildConfig = true):
- BUGCAPSULE_TOKEN, read from the environment variable BUGCAPSULE_SDK_TOKEN or the project's existing secrets setup, so the value isn't committed. Don't read it from an environment variable named BUGCAPSULE_TOKEN: that name is the bugcapsule CLI's own credential.
- BUGCAPSULE_GIT_SHA from the Gradle property bugcapsuleGitSha, defaulting to "".
- BUGCAPSULE_ENABLED: true for debug and for the project's QA or internal build type or flavor, false for production release builds.
5. Call BugCapsule.init first in Application.onCreate, right after super.onCreate(). Create an Application subclass and register it in the manifest if there isn't one. Don't use a ContentProvider or App Startup initializer:
BugCapsule.init(
this,
BugCapsuleConfig.builder()
.token(BuildConfig.BUGCAPSULE_TOKEN)
.enabled(BuildConfig.BUGCAPSULE_ENABLED)
.gitSha(BuildConfig.BUGCAPSULE_GIT_SHA)
.build(),
listOf(/* the integrations from step 6 */),
)
Set .mode(CaptureMode.QA) only for the QA build type or flavor (for example through another BuildConfig field). Debug builds record without it.
6. Add capture adapters only for what the app uses:
- OkHttp/Retrofit: one shared BugCapsuleOkHttp() passed to init, and its .interceptor added as the last application interceptor of every OkHttpClient the app builds.
- Jetpack Navigation: one BugCapsuleNavigation() passed to init. Call attach(navController) once the graph is set, or use BugCapsuleNavigationEffect(navController, navigation) in Compose.
- SharedPreferences and DataStore: BugCapsuleSharedPreferences.builder().allowFile(...) or .allow(file, prefix), and BugCapsuleDataStore.builder().allow(...), for non-sensitive files and keys only.
7. Build the debug variant and run the unit tests. Fix what you broke; leave unrelated warnings alone.
8. For QA builds made by scripts or CI, pass -PbugcapsuleGitSha=$(git rev-parse HEAD) and set BUGCAPSULE_SDK_TOKEN. If there are no build scripts, put the commands in your report.
Report back:
- Each file you changed and why, one line each.
- Which adapters you added, and what you skipped and why.
- How I confirm it: start a debug or QA build, open SDK Setup in the BugCapsule dashboard and wait for "Configuration fetched", then "First event or Capsule received". Or add Log.i("BugCapsule", BugCapsule.status().toString()) once at startup in a debug build: its connection state should become connected, and instrumentation.missing lists the adapters still to add.
- Anything you weren't sure about.
Add the BugCapsule iOS SDK to this app. BugCapsule records failures in QA builds as replayable Capsules. Make small, reviewable changes.
SDK token from my BugCapsule dashboard: [paste bcsdk.v1.… here]
Guide: https://docs.bugcapsule.com/ios.html. Read it first if you can browse. Where it and this prompt disagree, the guide wins.
Rules:
- Install exactly https://github.com/BugCapsule/bug_capsule_ios_sdk.git at 0.4.1-beta.2. Don't use a version range.
- Connect with the SDK token: it carries the BugCapsule address, so there's no URL or project ID to configure. If this app already connects with an explicit API URL and a bci_ ingest key, keep that and don't add a token.
- Put the token where this project keeps client-side build configuration. It is ingest-only and ships inside the app. Never add a bcs_ secret key or a bcp_ personal token anywhere.
- Keep capture off in production builds: debug and QA builds record, production release builds don't, unless I say otherwise (https://docs.bugcapsule.com/production.html).
- Storage capture is allowlist only. Never allowlist keys that hold tokens, passwords or personal data.
- Don't upgrade or downgrade my other dependencies, and don't change what the app does. Stop and ask instead.
- Don't invent APIs. If something you need isn't in the guide or in the SDK's source, stop and ask me.
Steps:
1. Check the requirements: iOS 15 deployment target or later, Swift 6 toolchain. If not, stop and tell me.
2. Add the Swift package https://github.com/BugCapsule/bug_capsule_ios_sdk.git at exact version 0.4.1-beta.2, and its BugCapsule product to the app target only. If the project is generated (XcodeGen, Tuist, Package.swift), edit that. If it's a plain .xcodeproj and you can't add the package reliably, stop and give me the Xcode steps instead of hand-editing project.pbxproj.
3. Start BugCapsule first: in application(_:didFinishLaunchingWithOptions:), or in the App struct's init for SwiftUI, before any code reads UserDefaults:
BugCapsule.start(
BugCapsuleConfig(
token: "...",
enabled: <true for Debug and QA configurations, false for App Store release>),
integrations: [/* step 4 */])
Read the token from Info.plist through a build setting (or the project's existing configuration setup). For enabled, use a compilation condition or an Info.plist value set per build configuration.
4. Add capture adapters only for what the app uses:
- Networking: BugCapsuleURLSession() in integrations, plus BugCapsule.instrument(configuration) on the URLSessionConfiguration of each URLSession or Alamofire Session the app builds, or BugCapsule.instrumentSharedSession() if it uses URLSession.shared. instrument alone records nothing without BugCapsuleURLSession() in integrations.
- Navigation: BugCapsuleNavigation.shared in integrations, and BugCapsule.observe(navigationController) (UIKit, after setting your own delegate) or .bugCapsuleRoute("/path") on SwiftUI screens.
- UserDefaults: BugCapsuleUserDefaults(keys: [...], prefixes: [...]) for non-sensitive keys only.
- App state: BugCapsuleStateIntegration.shared, only if you register state; leave registering state for later.
5. QA builds: add the Info.plist keys BugCapsuleGitSHA = $(BUGCAPSULE_GIT_SHA) and BugCapsuleGitDirty = $(BUGCAPSULE_GIT_DIRTY). Add BugCapsuleMode = $(BUGCAPSULE_MODE), with BUGCAPSULE_MODE set to qa in the QA configuration only. Where scripts or CI make QA builds, pass BUGCAPSULE_GIT_SHA=$(git rev-parse HEAD) to xcodebuild. If there are none, put the command in your report.
6. Build for a simulator with xcodebuild and run the existing tests. Fix what you broke; leave unrelated warnings alone.
7. The package ships no privacy manifest and uses UserDefaults, file timestamps and system uptime (required-reason APIs). Don't edit PrivacyInfo.xcprivacy; list this in your report for me to handle before App Store submission.
Report back:
- Each file you changed and why, one line each.
- Which adapters you added, and what you skipped and why.
- How I confirm it: start a debug or QA build, open SDK Setup in the BugCapsule dashboard and wait for "Configuration fetched", then "First event or Capsule received". Or add print(BugCapsule.status) once at startup in a debug build: its connection state should become connected, and instrumentation.missing lists the adapters still to add.
- Anything you weren't sure about.
Add the BugCapsule web SDK to this app. BugCapsule records failures in QA builds as replayable Capsules. Make small, reviewable changes.
SDK token from my BugCapsule dashboard: [paste bcsdk.v1.… here]
Guide: https://docs.bugcapsule.com/web.html. Read it first if you can browse. Where it and this prompt disagree, the guide wins.
Rules:
- Install exactly @bugcapsule/web (and @bugcapsule/react) 0.4.0-beta.2. Don't use a version range.
- Connect with the SDK token: it carries the BugCapsule address, so there's no URL or project ID to configure. If this app already connects with an explicit API URL and a bci_ ingest key, keep that and don't add a token.
- Put the token where this project keeps client-side build configuration. It is ingest-only and ships inside the app. Never add a bcs_ secret key or a bcp_ personal token anywhere.
- Keep capture off in production builds: debug and QA builds record, production release builds don't, unless I say otherwise (https://docs.bugcapsule.com/production.html).
- Storage capture is allowlist only. Never allowlist keys that hold tokens, passwords or personal data.
- Don't upgrade or downgrade my other dependencies, and don't change what the app does. Stop and ask instead.
- Don't invent APIs. If something you need isn't in the guide or in the SDK's source, stop and ask me.
Steps:
1. With the repo's own package manager, install @bugcapsule/web@0.4.0-beta.2, plus @bugcapsule/react@0.4.0-beta.2 if the app uses React (same exact version). The packages are ESM only and the tooling needs Node 20 or later.
2. Expose the token through the bundler's public env convention (VITE_BUGCAPSULE_TOKEN for Vite, NEXT_PUBLIC_… for Next.js, and so on). Add the variable names to .env.example if the project has one, without real values.
3. In the browser entry point, before rendering and before any module keeps its own reference to fetch (API clients created at import time count), call:
await BugCapsule.init({
token: import.meta.env.VITE_BUGCAPSULE_TOKEN,
appVersion: '...', appBuild: '...', // package.json's version and a build number, so Capsules carry the real release
enabled: <true in dev, QA and staging builds; false in production builds>,
mode: <'debug' in dev, 'qa' in QA and staging builds>, // left out, mode is 'production', which records only 10% of sessions
gitSha: import.meta.env.VITE_BUGCAPSULE_GIT_SHA,
integrations: [/* step 4 */],
});
If top-level await isn't available, wrap it: BugCapsule.init(...).then(renderApp). If the app renders on a server (Next.js, Remix, Nuxt), initialize only in the browser, and ask me if the client entry isn't clear.
4. Add capture adapters:
- networkIntegration() for fetch and XMLHttpRequest.
- Navigation: historyIntegration(). With React Router 6.4 or later, also render <BugCapsuleRouteListener /> (from @bugcapsule/react/react-router) inside the router.
- localStorageIntegration({ allowPrefixes: [...] }) and sessionStorageIntegration({ allowPrefixes: [...] }) for non-sensitive keys only.
- React: wrap the routes in <BugCapsuleErrorBoundary>, keeping existing boundaries, and render <BugCapsuleCaptureButton /> for QA (it renders nothing in production).
5. Where scripts or CI make QA or staging builds, set VITE_BUGCAPSULE_GIT_SHA=$(git rev-parse HEAD) (or the bundler's equivalent). If there are none, put the command in your report.
6. Run the build, type check, lint and tests. Fix what you broke; leave unrelated warnings alone.
7. List every origin (scheme, host and port) the app runs on in dev, QA and staging. BugCapsule only accepts uploads from origins my team has allowed. Until then the browser shows CORS errors.
Report back:
- Each file you changed and why, one line each.
- Which adapters you added, and what you skipped and why.
- How I confirm it: start a debug or QA build, open SDK Setup in the BugCapsule dashboard and wait for "Configuration fetched", then "First event or Capsule received". Or add console.log(BugCapsule.status()) once at startup in a debug build: its connection state should become connected, and instrumentation.missing lists the adapters still to add.
- Anything you weren't sure about.
Check what the agent did
Read the diff before you run anything. Check that:
- BugCapsule starts first: the first call in Flutter's
main, first inApplication.onCreateon Android, before anyUserDefaultsread on iOS, and before rendering on the web. - Every BugCapsule package is on the same exact version, and no other dependency moved.
- Only the SDK token (or an existing ingest key) is in the app, and no
bcs_orbcp_value appears anywhere. - Production release builds have capture off.
- Every storage allowlist names only keys you're happy to see in a Capsule.
Then start a debug or QA build and open SDK Setup in the dashboard. Wait for Configuration fetched (address, token and network work), then First event or Capsule received. To check sooner, send the test message from that page. Nothing arriving? See Troubleshooting, and for web, make sure your BugCapsule team has allowed the origins the agent listed.
2. Make it replay-ready
Do this once Capsules arrive. Replace the example flows at the top of the prompt with the two or three flows QA tests most, and say what "broken" means in each one: the agent turns that into check assertions. On Android and iOS this prompt also adds the replay test runner, and on the web the Playwright runner.
BugCapsule is already connected in this app (bug_capsule 0.4.1-beta.5). Make the flows below replayable, so a Capsule captured in QA can be replayed on a developer machine. Make small, reviewable changes.
Flows to make replayable:
- [for example: checkout, from the cart through applying a coupon to paying]
- [for example: sign-in]
What "broken" means in these flows:
- [for example: the cart total is never negative]
Guide: https://docs.bugcapsule.com/flutter.html. Read it first if you can browse. Where it and this prompt disagree, the guide wins.
Rules:
- Keep the same version, 0.4.1-beta.5, for every BugCapsule package.
- Only wrap existing handlers, fields and state. Don't change what the app does.
- Use stable, readable ids: <area>.<thing>, for example cart.checkout or login.email.
- Treat password, one-time code, card and personal fields as sensitive.
- Don't invent APIs. If something you need isn't in the guide or in the SDK's source, stop and ask me.
- Don't run bugcapsule login or anything that needs my credentials; I'll do that.
Steps:
1. Wrap each button or gesture handler in these flows: onPressed: BugCapsule.action('cart.checkout', () => ...). Use BugCapsule.actionWithPayload for handlers that take data.
2. For each text field in these flows, call BugCapsule.trackText('<id>', controller) where the controller is created, and BugCapsule.untrackText when it's disposed. Pass sensitive: true for obscured and personal fields.
3. Where the broken behaviour above can be detected, add BugCapsule.check('<id>', <condition>) without changing control flow.
4. In the code these flows run, replace DateTime.now() with clock.now() (package:clock) and Random() with BugCapsule.random, only where the value changes behaviour. List each replacement.
5. Check that the network calls, routes and state these flows depend on are covered by the integrations already in BugCapsule.init (dio or http, go_router, the state integrations). List what isn't covered: dart:io HttpClient used directly, WebSockets, platform channels, and native SDKs such as Firebase.
6. Run flutter analyze and the tests.
Report back:
- The action ids, tracked fields, state and checks you added, per flow.
- What replay can't cover in these flows and why.
- The commands for me to try it:
dart pub global activate bug_capsule 0.4.1-beta.6
bugcapsule login (opens my browser; I approve it)
bugcapsule list
bugcapsule run <capsule id> -n 3 -d <simulator or emulator id>
Replay runs the app with flutter run on a simulator or emulator.
BugCapsule is already connected in this app (io.github.bugcapsule 0.4.1-beta.4). Make the flows below replayable, so a Capsule captured in QA can be replayed on a developer machine. Make small, reviewable changes.
Flows to make replayable:
- [for example: checkout, from the cart through applying a coupon to paying]
- [for example: sign-in]
What "broken" means in these flows:
- [for example: the cart total is never negative]
Guide: https://docs.bugcapsule.com/android.html. Read it first if you can browse. Where it and this prompt disagree, the guide wins.
Rules:
- Keep the same version, 0.4.1-beta.4, for every BugCapsule package.
- Only wrap existing handlers, fields and state. Don't change what the app does.
- Use stable, readable ids: <area>.<thing>, for example cart.checkout or login.email.
- Treat password, one-time code, card and personal fields as sensitive.
- Don't invent APIs. If something you need isn't in the guide or in the SDK's source, stop and ask me.
- Don't run bugcapsule login or anything that needs my credentials; I'll do that.
Steps:
1. In the app module, set defaultConfig.testInstrumentationRunner = "dev.bugcapsule.android.replay.BugCapsuleReplayRunner" and add androidTestImplementation("io.github.bugcapsule:bugcapsule-android-replay:0.4.1-beta.4"). If the module already has a custom runner (a Hilt test runner, for example), stop and ask me. Don't replace it.
2. Replay only arms on debuggable builds. Make sure the variant used for replay (debug, unless I say otherwise) is debuggable.
3. Create bugcapsule.json next to settings.gradle(.kts), using this project's real values:
{ "runtime": "android", "android": { "applicationId": "<applicationId>", "module": "app", "variant": "debug" } }
4. Name the actions and fields in these flows:
- Views: BugCapsuleViews.onClick(button, "cart.checkout") { ... } in place of setOnClickListener, and BugCapsuleViews.trackText(field, "cart.coupon").
- Compose: onClick = rememberBugCapsuleAction("cart.checkout") { ... }, and rememberTrackedText("cart.coupon") for text fields. Compose doesn't detect password fields, so pass sensitive = true yourself.
5. State: BugCapsule.registerViewModel(this, "<id>", { ... }) { ... } for ViewModels whose state already serializes, and BugCapsule.registerState for other stores. Extend the SharedPreferences or DataStore allowlists to the non-sensitive files these flows read.
6. Where the broken behaviour above can be detected, add BugCapsule.check("<id>", condition, "detail").
7. In these flows, use BugCapsule.currentTimeMillis() and BugCapsule.random() in place of System.currentTimeMillis() and Random, only where the value changes behaviour.
8. List what these flows use that isn't captured: WorkManager, alarms, HttpURLConnection, Ktor, Cronet, native crashes.
9. Build the replay variant and its androidTest APK (assembleDebug and assembleDebugAndroidTest), and run the unit tests.
Report back:
- The action ids, tracked fields, state and checks you added, per flow.
- What replay can't cover in these flows and why.
- The commands for me to try it:
dart pub global activate bug_capsule 0.4.1-beta.6
bugcapsule login (opens my browser; I approve it)
bugcapsule list
bugcapsule run <capsule id> -n 3
Run bugcapsule from the folder with bugcapsule.json. The emulator must be unlocked once after boot, and an AVD with a screen-lock PIN can't be unlocked by the CLI.
BugCapsule is already connected in this app (bug_capsule_ios_sdk 0.4.1-beta.2). Make the flows below replayable, so a Capsule captured in QA can be replayed on a developer machine. Make small, reviewable changes.
Flows to make replayable:
- [for example: checkout, from the cart through applying a coupon to paying]
- [for example: sign-in]
What "broken" means in these flows:
- [for example: the cart total is never negative]
Guide: https://docs.bugcapsule.com/ios.html. Read it first if you can browse. Where it and this prompt disagree, the guide wins.
Rules:
- Keep the same version, 0.4.1-beta.2, for every BugCapsule package.
- Only wrap existing handlers, fields and state. Don't change what the app does.
- Use stable, readable ids: <area>.<thing>, for example cart.checkout or login.email.
- Treat password, one-time code, card and personal fields as sensitive.
- Don't invent APIs. If something you need isn't in the guide or in the SDK's source, stop and ask me.
- Don't run bugcapsule login or anything that needs my credentials; I'll do that.
Steps:
1. Replay runs as a UI test. Add the package's BugCapsuleXCTest product to the app's UI test target only. If there is no UI test target, stop and give me the Xcode steps to add one (unless the project is generated by XcodeGen or Tuist; then add it there).
2. Add this test to the UI test target. It skips itself in normal test runs:
import BugCapsuleXCTest
final class BugCapsuleReplayTests: BugCapsuleReplayTestCase {
@MainActor func testReplay() throws { try runBugCapsuleReplay() }
}
3. Replay is compiled only in DEBUG. Make sure the Debug configuration's SWIFT_ACTIVE_COMPILATION_CONDITIONS include DEBUG.
4. Create bugcapsule.json next to the .xcodeproj, using this project's real values:
{ "runtime": "ios", "ios": { "project": "<App>.xcodeproj", "scheme": "<Scheme>", "bundleId": "<bundle id>", "replayTest": "<UITestTarget>/BugCapsuleReplayTests/testReplay" } }
5. iOS replay doesn't replay touches, only named actions and tracked text, so name everything these flows use:
- UIKit: button.addAction(BugCapsule.uiAction("cart.checkout") { ... }, for: .touchUpInside), keeping the existing handler's body, and BugCapsule.trackText("cart.coupon", field: textField).
- SwiftUI: Button("…", action: BugCapsule.action("cart.checkout") { ... }), and TextField(…, text: BugCapsule.trackedText("cart.coupon", $model.coupon)). Pass sensitive: true for SecureField and personal fields.
6. State: add BugCapsuleStateIntegration.shared to the start integrations if it isn't there, and register the state these flows depend on with BugCapsule.registerState(_:snapshot:restore:). Extend the UserDefaults allowlist to the non-sensitive keys these flows read.
7. Where the broken behaviour above can be detected, add BugCapsule.check("<id>", condition, "detail"). Swift traps (fatalError, force unwraps, out-of-range indexes) aren't captured, so add a check or BugCapsule.report(error:) before code in these flows that would trap.
8. In these flows, use BugCapsule.now() and BugCapsule.random in place of Date() and random number APIs, only where the value changes behaviour.
9. Build for testing on a simulator (xcodebuild build-for-testing) and run the tests.
Report back:
- The action ids, tracked fields, state and checks you added, per flow.
- What replay can't cover in these flows and why.
- The commands for me to try it:
dart pub global activate bug_capsule 0.4.1-beta.6
bugcapsule login (opens my browser; I approve it)
bugcapsule list
bugcapsule run <capsule id> -n 3 -d <simulator>
Replay runs on an iOS simulator only; physical devices aren't supported.
BugCapsule is already connected in this app (@bugcapsule/web 0.4.0-beta.2). Make the flows below replayable, so a Capsule captured in QA can be replayed on a developer machine. Make small, reviewable changes.
Flows to make replayable:
- [for example: checkout, from the cart through applying a coupon to paying]
- [for example: sign-in]
What "broken" means in these flows:
- [for example: the cart total is never negative]
Guide: https://docs.bugcapsule.com/web.html. Read it first if you can browse. Where it and this prompt disagree, the guide wins.
Rules:
- Keep the same version, 0.4.0-beta.2, for every BugCapsule package.
- Only wrap existing handlers, fields and state. Don't change what the app does.
- Use stable, readable ids: <area>.<thing>, for example cart.checkout or login.email.
- Treat password, one-time code, card and personal fields as sensitive.
- Don't invent APIs. If something you need isn't in the guide or in the SDK's source, stop and ask me.
- Don't run bugcapsule login or anything that needs my credentials; I'll do that.
Steps:
1. Add @bugcapsule/web-replay@0.4.0-beta.2 as a dev dependency with the repo's package manager.
2. In BugCapsule.init, add allowReplay: import.meta.env.DEV || import.meta.env.VITE_BUGCAPSULE_ALLOW_REPLAY === 'true' (or the bundler's equivalent). It must never be true in production builds.
3. Create bugcapsule.json next to package.json. Adapt the commands so the serve command serves the built app at exactly that URL:
{ "runtime": "web", "web": { "url": "http://127.0.0.1:4317/", "buildCommand": "npm run build", "serveCommand": "npm run preview -- --port 4317 --strictPort", "env": { "VITE_BUGCAPSULE_ALLOW_REPLAY": "true" } } }
List that origin in your report: my team has to allow it.
4. Name the actions and inputs in these flows:
- onClick={BugCapsule.action('cart.checkout', handler)}, plus data-bugcapsule-action="cart.checkout" on the same element. In React components, use useBugCapsuleAction.
- BugCapsule.trackInput('login.email', inputElement), or useTrackedState / useTrackedInput in React. Pass { sensitive: true } for personal fields; password inputs are redacted automatically.
5. State: BugCapsule.registerState('<id>', { serialize, restore }) for app stores (Redux, Zustand and so on), and useBugCapsuleState for component state these flows depend on. Extend the localStorage and sessionStorage allowlists to the non-sensitive keys these flows read.
6. Where the broken behaviour above can be detected, add BugCapsule.check('<id>', condition). Report errors the app catches with BugCapsule.reportError(error).
7. In these flows, use BugCapsule.now() and BugCapsule.random() in place of Date.now() and Math.random(), only where the value changes behaviour.
8. Run the build, type check and tests.
Report back:
- The action ids, tracked fields, state and checks you added, per flow.
- What replay can't cover in these flows and why.
- The commands for me to try it:
dart pub global activate bug_capsule 0.4.1-beta.6
bugcapsule login (opens my browser; I approve it)
npx playwright install chromium
bugcapsule list
bugcapsule run <capsule id> -n 3
Stop any dev or preview server on the replay URL first: the CLI won't start while something else serves it. Replay runs in Chromium only.
Install the CLI and run bugcapsule login yourself; it opens your browser to approve (Log in). Then capture a failure in a QA build and run bugcapsule run <id> -n 3. Verdicts & divergences explains what the result means.
When the agent gets stuck
| It stops at | What to do |
|---|---|
Flutter: pub get fails | The package pins bloc, riverpod, get, mobx, dio, http, go_router and shared_preferences, even ones you don't use. Approve the upgrade it suggests, or wait for a release that fits. See Flutter. |
| Android: a custom test runner already exists | Replay needs BugCapsuleReplayRunner as the instrumentation runner. Decide with your team whether another module or variant can carry it. |
iOS: a plain .xcodeproj | Follow the Xcode steps it gives you to add the package or the UI test target, then let it continue. |
| Web: CORS errors in the browser | The origin isn't allowed yet. Send the origins it listed to your BugCapsule team. |
| It uses an API the guide doesn't show | Point it back to the platform guide and the installed version. Signatures change between releases. |
The agent's report is a starting point, not proof. The two dashboard confirmations and a replay that reaches REPRODUCED are. Before using it on real users, finish the integration checklist and Privacy & redaction.