testerpaykit 2.1.3
testerpaykit: ^2.1.3 copied to clipboard
In-app bug reports for TesterPayKit testers — screenshots, recordings and voice notes, crash capture, sessions and engaged minutes.
Changelog #
All notable changes to TesterPayKit will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
2.1.3 - 2026-11-09 #
Fixed #
- On the web the local database did not start when a page was opened directly
on a deep link. The drift worker and
sqlite3.wasmwere resolved against the page URL, so/app/idea/42asked for/app/idea/assets/...and a single-page host answered with HTML. They now resolve against the document's<base href>.
2.1.2 - 2026-11-09 #
- No change of its own. Follows the release train, which moved for a fix in the Expo and Swift SDKs.
2.1.1 - 2026-11-09 #
Changed #
- With
syncSessions: falsea launch sends nothing at all until the first report: no sign-in and no profile check. Signing in marked the tester as active on every start, so "no tracking" was not quite true. A person approved on an earlier launch still signs in at launch and sees the widget; confirming a number signs in when it starts.
2.1.0 - 2026-11-09 #
Added #
TesterPayKitConfig.syncSessions(defaulttrue). Withfalseno usage data goes to the server: no device registration, no server session, no foreground seconds, no breadcrumb or event flushes, no period submissions and no task auto-completion. Bug reports and crash reports keep working and carry a local session id.trackError(once per error) andsubmitFeedbackare sent as reports, because the session flush was their only way off the device. For hosts that promise "no tracking"; leave it on for paid test orders.- Automatic error and crash reports carry
automatic: true. A project that switched onacceptUnverifiedAutoReportson the server takes them from its anonymous installs without a confirmed number. Reports a person writes stay behind the gate.
Fixed #
- A silently uploaded crash report carries the first 30 lines of the stack instead of one.
2.0.1 - 2026-11-07 #
Fixed #
- A bug report from a screen with a degenerate transform (an animated
bar scaling through zero, a card mid-animation) no longer fails with
"Converting object to an encodable object failed: NaN". The annotated
screenshot skips widgets whose position or size is NaN or infinite,
and the report metadata turns any remaining non-finite number into
nullbefore it is saved, so a report always saves.
2.0.0 - 2026-11-07 #
Breaking: the widget now only appears for confirmed and approved testers, and the local earnings estimate is gone. Same release as Expo, Web and Swift 2.0.0.
Added #
TesterPayKit.instance.access(ValueListenable<TpkAccess>),refreshAccess()andopenVerification(context): hosts can offer their own "Become a tester" entry and see when the widget is visible.- Phone confirmation before the first report (number → SMS code → "Du meldest als
- "Du bist
- Mein Geld / My money from the menu: the ledger from
GET /v1/testers/me/compensation, play money labelled "Spielgeld · Pilot", the start bonus as "Startguthaben" (held until the first approved work), time pay only for test orders with an announced duration, a line on bug rewards, announced pay on tasks. - Daily briefing on the first tap of a local day (and again for new bug news): greeting, money yesterday / this week, up to three bug news, messages, retests, open checklist tasks. Unread badge on the button and a short bug-news banner. The server's "seen" signal reads as "Wird angeschaut".
- Thank-you after every report names the tester and the next step, without promising amounts.
Changed #
- The widget only appears for confirmed and approved testers, in every build: floating button, shake, three-finger tap, crash prompt, dashboard, onboarding, welcome sheet and checklist stay hidden for everyone else. Access is re-checked on app resume; a 403 from the tester gate on any request hides the widget again.
- "Beta-Tester werden" goes straight to the phone confirmation; without a saved code the SDK creates the tester with a stable per-install code. The invite-code screen no longer opens on its own; a remembered code still signs in silently.
- Every report ships the current screen, the last breadcrumbs and the device model.
- Voice recordings and voice notes run up to 3 minutes (was 60–120 s).
- The tester FAB menu is trimmed to what testers use.
Removed #
- The local earnings estimate:
FloatingFeedbackButtonparameterssessionStartedAt,sessionTaps,sessionScreenViews,sessionForegroundSeconds,onShowSessionDetails,earningsBaseAmount,earningsPerMinuteRate,earningsCurrency, and the session-details screen. The ledger is the only source of money.
Fixed #
- Session-end rating and comments reach the server.
- Network logs no longer land in the screenshot slot; tester invite codes are no longer logged.
- Unpaid beta feedback works reliably.
- The three-finger-tap detector no longer asserts on dispose when it started disabled.
1.2.0 - 2026-11-01 #
Changed #
- Live link actions report a field by its label only, without the hint text that followed it after a newline.
- Same version number as all TesterPayKit SDKs (Flutter, Expo, Swift, Web) from now on: one release train, one feature set. No functional change against the previous version.
0.9.0 - 2026-10-31 #
Added #
- Live link to Claude Code (opt-in,
TesterPayKitWrapper(enableLiveLink: true)). Two new items in the TPK menu: "Connect to Claude" keeps a WebSocket to the API while the app is in front, so the developer's Claude Code session can ask what the screen shows (MCPdevice_snapshot: screenshot, every text and field value, current screen, navigation, breadcrumbs, logs). "Send to Claude" captures the screen, asks for one line and sends it as a note (MCPlist_device_notes/get_device_note). Extra app state for both:TesterPayKit.instance.liveStateProvider. The choice survives app restarts; the socket closes when the app goes to the background. Needs the API from 2026-10-31. - Claude can drive the app over the live link: tap (by visible text
or by x/y in points), type (into the field with that label, or the
focused one, optionally pressing done), scroll and back (MCP
device_tap/device_type/device_scroll/device_back). Works on the semantics tree; the AI tester's deny list (delete account, pay now, sign out …) applies and TesterPayKit's own button and panels are never a target. A short hint on the device ("Claude taps: Save") shows what happened. Needs the API from 2026-11-01. - "What to test" in the TPK menu (shown when the project has a
checklist): the tester picks a task, walks its steps with ✓ / ✗ and an
optional note (asked for once on ✗), and sends the run
(
GET /v1/testers/me/checklist,POST /v1/testers/me/checklist/<taskId>/runs, API from 2026-11-01). The steps sit in a small panel at the bottom that does not block the app and folds down to one line. The list shows the tester's last result per task.ApiClient.getChecklist/submitChecklistRun.
Changed #
- The remote AI-run claim sends the app version, so an AI retest of a fixed bug reaches this app only from the fixed build on.
- The voice bug sheet no longer darkens the app behind it: the scrim is almost clear, so the tester sees the screen they describe while recording.
0.8.0 - 2026-10-30 #
Added #
- Quick actions in the voice sheet: "Doesn't work", "Don't get it",
"Looks broken", "Something's missing". One tap sends the screenshot
taken before the sheet opened, the API drafts the report
(
POST /v1/testers/me/bug-reports/quick-draft, API from 2026-10-28), and the tester reviews it before submitting. Same four buttons as the Expo SDK.ApiClient.quickDraftBug. - German and English tester surface, chosen by device language
(German devices get German, all others English). Before, menu, tour,
retests and voice sheet mixed both.
TesterPayKitWrapper(language: TpkLanguage.de)pins one;TpkLanguageis exported. Money shows as "1,00 €" in German and "€1.00" in English.
Changed #
- The workboard shows only real data: the tester's assigned tasks, the app's own version and build, and focus areas / build notes only when the host passes them. It used to fill empty parameters with invented sample tasks, fixes and focus areas. The "View All Tasks" button that only said "coming soon" is gone.
Removed #
MockTestData(the invented workboard data).
Fixed #
- The end-of-session dialog showed earnings in dollars while the floating button and session details showed euros.
- The voice sheet scrolls instead of overflowing on short screens.
- Flutter web works.
TesterPayKit.initializefailed on every web app because the local database expectedsqlite3.wasmanddrift_worker.jsin the host'sweb/folder. Both now ship with the SDK as web-only assets, so nothing has to be copied. - Web: the voice bug report crashed right after the microphone prompt (it needed a temp directory). It now records Opus/WebM in memory.
- Web: saving an annotated screenshot crashed (it wrote a file), and
screen recording threw on
Platform. - Web: screenshots, voice notes and the network log are now uploaded with the report instead of being dropped.
- After saving an annotated screenshot the bug report dialog closed again instead of coming back (the editor popped twice).
Note #
- A web app served from its own domain needs that origin entered in the project settings (web origins), otherwise the browser blocks every API call (CORS).
0.7.0 - 2026-10-28 #
Added #
- Retests judged step by step.
RetestItem.acceptanceStepscarries the bug's acceptance steps (needs an API from 2026-10-28). The retest detail lists them with 👍/👎 per step; "Verified" stays disabled until every step passed, and the verdicts go along withverifyRetest(bugId, stepVerdicts:)/reopenRetest(bugId, stepVerdicts:). Bugs without acceptance steps work as before. - Debug builds print a note when the API reports a newer
testerpaykitrelease than the one running, with the update command. The API also mails the project's coordinator once per release and shows a notice on the project page in the console.
0.6.0 - 2026-10-25 #
Added #
- AI test runs started from outside.
TesterPayKitWrapper(aiRemoteTrigger: true)pollsPOST /v1/testers/me/ai-sessions/claimeveryaiRemotePollSeconds(default 15) while the app is resumed and no AI run is open. A run started in the console or withtpk autotestopens straight away — no persona picker, no coordinator token in the build — and the overlay closes itself 3 s after the run ends.ApiClient.claimRemoteAiSession(projectId)returns the claimedRemoteAiSessionor null. - The AI tester can type: the
typeaction fills a text field throughSemanticsAction.setText(focusing it first). Same deny list and overlay exclusion as tap; an obscured field accepts text, but its value never reaches the model. AiRemoteControltakesremoteSession,captureScreenshotandonSessionEnded;apiBaseUrl,coordinatorTokenandprojectIdare now only needed for runs started in the app.
Fixed #
- The AI model now gets a screenshot on every step. Before, the Flutter
SDK replied with the widget list only, so the model could not see
whether a tap changed anything. The capture is the masked app area
(
TesterSensitiveregions stay hidden) at logical-pixel size. - A step's screenshot waits at most 5 s. When the app drew no frames, the capture used to block the whole discover_widgets reply, and the server ended the run after 10 s.
- The AI could pick the Stop button of its own overlay and the TesterPayKit button as widgets to tap. Both are now hidden from it.
0.5.0 - 2026-10-21 #
0.4.3 was prepared but never published; its changes ship here.
Changed #
- Dependencies to their latest majors:
file_picker^13.1.0,record^7.1.2,pro_image_editor^13.5.0,json_annotation^4.12.0. Host apps that pin older majors of these need to move up too.pro_image_editorstays on 13: version 14 moves tomaterial_ui, and hosts on the regular Material library would crash in the annotation editor without extra localization setup. flutter_riverpodis no longer a dependency. The SDK never used it; the^2.6.1constraint only blocked host apps on Riverpod 3.- Bug-report repro steps reorder through
onReorderItem(theonReordercallback is deprecated since Flutter 3.41). - README rewritten: correct quick start (the old one used config fields that don't exist), invite-only account note, honest platform list (Android, iOS) and the commercial licence instead of "MIT".
file_pickerconstraint raised from^12.0.0-beta.3. Host apps that pinnedfile_pickerto a 12.0 beta as a workaround for the build failure below can drop the pin.
Added #
ApiClient.getMyPoints()— the calling tester's total points and leaderboard rank (GET /v1/testers/me/points).ApiClient.submitDemandSignal(...)— the tester's "would you use / pay for / recommend it?" answers for a session they tested (POST /v1/testers/me/demand-signals, upserts per session).
Fixed #
- Host-app builds failed once
file_pickerresolved to 12.3.0. The old^12.0.0-beta.3range let a plainflutter pub upgradepick 12.3.0. That release removedFilePickerResult:pickFiles()returns the list itself, andPlatformFileno longer hassizeorbytes.flutter buildthen aborted inkernel_snapshot_programwith "The getter 'files' isn't defined for the type 'List - The reference-screenshot picker did nothing on iOS and Android. It
read
PlatformFile.byteswithoutwithData: true, and that field is only filled on web, so the picked image was dropped without a message. It now loads the image withreadAsBytes()on every platform.
0.4.2 - 2026-07-10 #
Changed #
- Screen recording now uses
moinsen_screen_recordinginstead of the unmaintainedflutter_screen_recording 2.0.25. Upstream declared two dead / unreachable Gradle repositories (jcenter()+ abytedance.commaven) that break a Gradle 9 app build. The fork removes exactly those two (keeping the native HBRecorder recorder on jitpack, injected by the plugin so apps still need no repo config). One SDK bump lifts Gradle 9 compatibility for every app that embeds TesterPayKit — no per-app gradle changes. Verified: the SDK example builds on both Gradle 8.12 and Gradle 9.0.0 (AGP 8.11.1). The recorder's Dart/iOS API is unchanged.
0.4.1 - 2026-06-22 #
Fixed #
- Tester dashboard crash under
MaterialApp.builder/MaterialApp.routermounts. The inline "Welcome, Tester!" dashboard was returned outside the host Navigator, so opening its in-screen About dialog (showAboutDialog(useRootNavigator: false)) asserted with "Navigator operation requested with a context that does not include a Navigator" on hosts that mount the wrapper above their Navigator (e.g.go_routerviaMaterialApp.router).TesterPayKitWrappernow wraps the inline dashboard in its ownNavigator, restoring the nearest-Navigator ancestor its modals need — without re-introducing a theme-overridingMaterialApp(which had previously broken dark mode). The host-providednavigatorKeyonly backed wrapper-pushed routes, not the dashboard's own modals, so this closes that gap.
0.4.0 - 2026-06-03 #
Consolidated entry — the CHANGELOG had drifted (last entry 0.1.0 while
the reported sdk_version was hardcoded inconsistently at 0.1.0/0.2.0).
This release introduces a single source of truth (kTpkSdkVersion,
kept in sync with pubspec.yaml) and folds in the batches since 0.1.0.
Added #
- In-widget notification feed: server auto-notifies the tester (bug accepted/fixed/rejected, retest assigned, reward) → "Nachrichten" inbox in the FAB with an unread badge.
- Runtime invite-code onboarding:
TesterPayKit.loginAnonymous()(parity with the TS SDK) +InviteCodeScreen+ persistence; gated byTesterPayKitConfig.enableInviteCodeOnboarding. - Navigation flow in bugs:
TpkNavigatorObserver+ breadcrumb-basednavigationFlow()ship the screen path that led to a bug (inappSnapshot.navigationPath). - Activity-gated earnings, Session-Details + "Meine Bugs" screens, task-progress auto-detection ("X von Y erledigt"), AI-Tester (gesture injection + remote control), first-tap widget tour.
Changed #
sdk_versionsingle source of truth —kTpkSdkVersion(lib/src/version.dart), used by the session + bug-report + submission paths; keep in sync withpubspec.yaml.- Session lifecycle: background pauses (not ends) the session; foreground resumes; foreground-time clock drives engaged minutes.
- Durable payment pipeline: reconcile orphaned sessions on launch, periodic weekly-submission, client-idempotent retry.
Fixed #
- Voice bugs on native (iOS/Android) now transmit the O-Ton
transcript+sourceLanguage(were dropped in the native upload payload → tester_title/description/language stayed empty). environmentdetection recognises.local/.lanmDNS + all RFC-1918 private ranges aslocal(a dev build onhttp://*.local:18080was mislabelledprod).- Submission outbox JSON round-trip; branded screens readable on dark-host themes.
0.1.0 - 2025-11-05 #
Added - Phase 1: MVP Bug Reporting & Crash Handling #
Bug Reporting
- Bug Report Dialog: Comprehensive dialog for reporting bugs with rich categorization
- Type selection (bug, crash, UI issue, performance, feature request)
- Severity levels (critical, high, medium, low)
- Category classification (functional, UI, performance, security, data, network, crash, other)
- Reproduction steps with frequency tracking
- Expected vs actual behavior fields
- Affected feature identification
- Shake-to-Report: Shake device gesture to instantly trigger bug report dialog
- Auto-Context Capture: Automatically captures device state, app state, and breadcrumbs
- Screenshot Support: Database schema ready for screenshot and screen recording attachments
Crash Handling
- Automatic Crash Detection: Flutter error and platform exception capture
- Post-Crash Reporting: Crash report dialog shown on next app launch
- Full Crash Context: Complete crash information including:
- Stack traces
- Device snapshots (OS, model, battery, network)
- App snapshots (version, build, memory)
- User journey breadcrumbs
- Battery Integration: Real-time battery level and charging state capture via
battery_plus - Network Integration: Network type and connectivity status via
connectivity_plus - Memory Tracking: Basic memory tracking structure (platform-specific implementation required)
- Crash Report Dialog: Post-crash dialog with optional notes and submission
Session Management
- Automatic Session Tracking: Start, end, duration, and activity metrics
- Session End Dialog: Structured feedback collection at session completion
- Duration worked
- Overall experience rating
- Issues encountered count
- Quality assessment
- Free-form feedback
- Session Stats: Screen views, taps, and event counts
- Session Breadcrumbs: Complete user journey tracking
Tester Dashboard
- Daily Dashboard: One-time-per-day tester onboarding screen
- Test Tasks Display: Show assigned testing tasks with priorities
- Build Information: Display app version, build number, and environment
- Focus Areas: Highlight specific features to test
- Smart Persistence:
SharedPreferencesto track dashboard views
UI Components
- Floating Feedback Button: Always-accessible draggable button
- Report bug action
- General feedback action
- View dashboard action
- End session action
- Notification badge with unreported items count
- Smooth animations and haptic feedback
- TesterPayKitWrapper: Main wrapper widget that:
- Shows dashboard on first daily launch
- Provides floating feedback button
- Handles shake gesture detection
- Manages session lifecycle
Data Management
- SQLite Database: Fast, reliable local storage with Drift ORM
- Database Tables:
bug_reports- Detailed bug reports with all contextcrash_contexts- Crash information and stack tracesbreadcrumbs- User journey trackingsession_end_feedbacks- Session completion feedbackdevice_id_metadata- Device ID rotation managementevents- Comprehensive event trackingsessions- Session lifecycle tracking
- Schema Versioning: Automatic migrations from v1 → v2 → v3
- Device ID Rotation: Automatic 30-day device ID rotation for privacy
- Notification Counter: Real-time count of unreported crashes and draft bug reports
Privacy & Security
- Local-First Architecture: All data stored locally
- Device ID Management: Privacy-preserving device identification with automatic rotation
- GDPR Compliance: Privacy-first design principles
- No Tracking Without Consent: Explicit initialization required
Developer Experience
- Comprehensive Documentation: Full README with examples
- Type Safety: Freezed models for immutable data structures
- Error Handling: Robust error capture and reporting
- Logging: Optional debug logging via configuration
Dependencies #
drift(^2.23.0) - SQLite ORMbattery_plus(^7.0.0) - Battery level detectionconnectivity_plus(^7.0.0) - Network connectivitydevice_info_plus(^11.1.0) - Device informationshake(^3.0.0) - Shake gesture detectionshared_preferences(^2.3.5) - Persistent storagefreezed(^2.5.7) - Immutable modelsjson_annotation(^4.9.0) - JSON serialization
Technical Details #
- Flutter SDK: >=3.5.0
- Dart SDK: >=3.5.0
- Platforms: Android, iOS, Linux, macOS, Windows
- Database Schema Version: 3
- Lines of Code: ~8,500 (excluding generated files)
Known Limitations #
- Screenshot capture deferred (requires app wrapper architectural changes)
- Memory tracking basic structure only (native implementation needed)
- API submission not yet implemented (data stored locally)