Start here
Quickstart: capture to verified fix
About 30 minutes. You'll install the CLI, capture a planted bug in one of the demo apps, replay it to REPRODUCED, fix it, and verify to FIXED. Then move the same steps to your own app.
Before you start
From your BugCapsule team you need the project's API URL, ingest key (bci_…) and secret key (bcs_…). The ingest key goes into apps and is treated as public; the secret key is for the CLI only and must never ship in an app.
| For | You need |
|---|---|
| CLI | Flutter 3.35+ (the CLI is a Dart tool shipped with the Flutter package), git |
| Flutter / iOS demo | Xcode with an iOS simulator |
| Android demo | Android SDK, an emulator (API 35 tested), JDK 17 |
| Web demo | Node 20+; your origin allowed by your BugCapsule team (see Web) |
1. Install the CLI and log in
dart pub global activate --source git https://github.com/draz26648/bug_capsule_flutter_sdk --git-path packages/bug_capsule
bugcapsule login --url https://api.bugcapsule.com --secret-key bcs_... --ingest-key bci_...
bugcapsule list # empty for a new project
Details and alternatives: CLI install.
2. Capture the first capsule
Clone the SDK repository for your platform and pick its demo. The Flutter, iOS and web demos share a planted bug: a coupon SAVE100 that takes a fixed 100 off, so a cart under 100 gets a negative total and fires check("cart_total_non_negative").
cd bug_capsule_flutter_sdk/example/bug_capsule_demo
flutter run -d <simulator> \
--dart-define=BUGCAPSULE_GIT_SHA=$(git rev-parse HEAD) \
--dart-define=BUGCAPSULE_BACKEND_URL=https://api.bugcapsule.com \
--dart-define=BUGCAPSULE_INGEST_KEY=bci_...
Open the cart until the subtotal is below $100, type SAVE100, apply.
cd bug_capsule_android_sdk
export BUGCAPSULE_INGEST_KEY=bci_...
./gradlew :demo:installDebug -PbugcapsuleBackendUrl=https://api.bugcapsule.com
On Android, use the race bug, whose fix toggle verifies cleanly: tap Refresh home until the app crashes (~1 in 4, recommendations arrive before the profile). The crash capsule is written synchronously and uploaded on the next launch, so open the app again. The project folder for the CLI is examples/demo.
cd bug_capsule_ios_sdk/Examples/Demo
xcodebuild test -project BugCapsuleDemo.xcodeproj -scheme BugCapsuleDemo \
-destination 'id=<simulator udid>' -collect-test-diagnostics never \
BUGCAPSULE_BACKEND_URL=https://api.bugcapsule.com BUGCAPSULE_INGEST_KEY=bci_... \
-only-testing:BugCapsuleDemoUITests/CaptureFlowTests/testCaptureNegativeTotal
The UI test drives the app into the bug for you.
cd bug_capsule_web_sdk && npm install && npm run build
node examples/shop/api-server.mjs & # the demo shop's own API on :4318
cd examples/shop
VITE_BUGCAPSULE_BACKEND_URL=https://api.bugcapsule.com VITE_BUGCAPSULE_INGEST_KEY=bci_... \
VITE_BUGCAPSULE_ALLOW_REPLAY=true npx vite build && npx vite preview --port 4317 --strictPort
Open http://127.0.0.1:4317/, build a cart under 100, apply SAVE100. Stop the preview server before replaying: the CLI refuses to start when something already serves the app URL.
The app writes a capsule and uploads it. The upload waits until the app has fetched its capture settings once, so give it a second.
bugcapsule list # status new, eligibility eligible
bugcapsule inspect <id> # failure, eligibility, network, timeline
bugcapsule inspect <id> --json | less # check nothing is in there that shouldn't be
3. Replay it
Run from the demo's project folder (or pass -p):
bugcapsule run <id> -n 3 # add -d <simulator|avd> to pick a device
Expected: REPRODUCED 3/3, exit 0, capsule status reproduced. If you get INCONCLUSIVE, the output lists why (for example an action id that isn't registered in the replayed build); see Troubleshooting.
4. Fix and verify
Fix lib/shop.dart: clamp the coupon discount to the subtotal. Then:
bugcapsule verify <id> -d <simulator> -n 5
The demo has build-time fix toggles (race, price, legacy), so no source change is needed. Only race keeps the recorded request sequence; the others change which requests the app makes and verify as INCONCLUSIVE by design.
BUGCAPSULE_ANDROID_GRADLE_ARGS=-PbugcapsuleDemoFix=race bugcapsule verify <id> -p examples/demo -n 3
BUGCAPSULE_IOS_BUILD_SETTINGS='DEMO_FIXES=FIX_NEGATIVE_TOTAL' bugcapsule verify <id> -p Examples/Demo -n 3
Set the demo's fix toggle in the build environment:
VITE_BUGCAPSULE_DEMO_FIX=coupon bugcapsule verify <id> -n 3
Expected: FIXED — failure gone in N/N valid runs, exit 0, status fixed. Anything less than every requested attempt running validly is INCONCLUSIVE (exit 3) and doesn't change the status.
5. Keep it as a regression test
bugcapsule regress add <id> --name "coupon over subtotal"
bugcapsule regress run # exit 1 if any test fails; wire it into CI
Next: run regressions in CI.
Now do it in your own app
- Integrate the SDK per your platform page (Flutter, Android, iOS, Web) and register action ids for the flows QA tests most.
- Build QA builds with mode
qaand the git SHA. Keep production capture off until the production checklist passes. - Before the first upload from a real user, review redaction with a real login and payment flow and add
redactKeys/redactPatterns/excluderules. See Privacy & redaction.