brevwick 0.6.0 copy "brevwick: ^0.6.0" to clipboard
brevwick: ^0.6.0 copied to clipboard

Brevwick SDK for Flutter — send QA feedback from your app in one widget wrap.

brevwick #

pub package license: MIT

Flutter SDK for Brevwick — send rich QA feedback from inside your app by wrapping it in a single widget. Bug reports arrive with a screenshot, the recent console / network / route history, and device context already attached, so you spend less time asking "what were you doing when it broke?".

Runs on all six Flutter platforms — Android, iOS, macOS, Linux, Windows, and web.

Install #

flutter pub add brevwick

Quick start #

Wrap your app once. Brevwick.runGuarded captures uncaught errors, BrevwickScreenshotScope enables screenshot capture, and BrevwickOverlay adds the feedback affordance.

import 'package:brevwick/brevwick.dart';
import 'package:flutter/material.dart';

void main() {
  Brevwick.runGuarded<void>(() async {
    WidgetsFlutterBinding.ensureInitialized();
    await Brevwick.install(
      BrevwickConfig(
        projectKey: 'pk_live_...',
        environment: 'prod',
        // Optional: forward the SDK's internal diagnostics into your logger.
        onLog: (level, message, {error, stackTrace}) =>
            debugPrint('[brevwick] ${level.name}: $message'),
      ),
    );
    runApp(const MyApp());
  });
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    // BrevwickScreenshotScope wraps the whole app so any route can be
    // captured.
    return BrevwickScreenshotScope(
      child: MaterialApp(
        navigatorObservers: [Brevwick.instance.routeObserver()],
        // BrevwickOverlay must sit BELOW a Navigator: its launcher shows a
        // Tooltip and opens a modal bottom sheet, both of which need a
        // Navigator + Overlay ancestor. Wrap your screen (`home`) — or, for
        // an overlay that persists across routes, a go_router `ShellRoute`
        // body. Do NOT place it in `MaterialApp.builder`, which sits ABOVE
        // the Navigator (the launcher would throw `No Overlay widget found`).
        home: BrevwickOverlay(child: const HomePage()),
      ),
    );
  }
}

Placement. BrevwickOverlay needs a Navigator + Overlay ancestor. home: / a routed screen / a ShellRoute body all qualify; MaterialApp.builder does not. BrevwickScreenshotScope has no such requirement — keep it at the top (around MaterialApp or in its builder) so every route is capturable.

Launcher presentation #

⚠️ Default change. The zero-config launcher is now a vertical tab flush against the right screen edge, vertically centered, with a rotated "Feedback" label — not the old bottom-right corner bubble. The bubble remains fully supported: any call site that passes an explicit corner position (e.g. Alignment.bottomRight) keeps compiling and keeps the bubble at that corner. To keep the bubble with no other configuration, pass variant: BrevwickLauncherVariant.bubble.

BrevwickOverlay(child: app)                          // NEW default: right-edge tab
BrevwickOverlay(side: BrevwickLauncherSide.left, child: app)   // left-edge tab
BrevwickOverlay(compact: true, child: app)           // icon-only edge tab
BrevwickOverlay(offset: 80, child: app)              // tab nudged 80 px down
BrevwickOverlay(
  variant: BrevwickLauncherVariant.bubble,           // legacy corner bubble
  child: app,
)
BrevwickOverlay(
  position: Alignment.bottomLeft,                    // legacy call site: still a bubble
  child: app,
)

How variant / position / side resolve:

variant position / side Result
null both null tab, right edge (new default)
null position non-null bubble at exactly that Alignment (legacy behaviour, including non-corner alignments)
null side non-null tab on that edge
.tab any tab; edge = side if set, else the position alignment's horizontal side (default right). Tabs are always vertically centered (± offset)
.bubble any bubble at position ?? Alignment.bottomRight; side and offset are ignored

An explicit variant always wins. label (default 'Feedback') is the tab's rotated text and its tooltip/semantics label; compact drops the visible text (the Flutter bubble is already icon-only, so compact is a no-op there).

To capture failing HTTP calls in the network ring, add the interceptor to your Dio instance:

final dio = Dio()..interceptors.add(Brevwick.instance.dioInterceptor());

What gets attached #

Every report carries, automatically:

  • Screenshot of the screen the user was on when they tapped the feedback button (captured before the composer opens, so the sheet itself isn't in the frame).
  • Breadcrumb rings — the recent console logs, network requests, and route transitions, each toggleable via RingFlags on BrevwickConfig.
  • Device context — platform, OS, locale, viewport, and SDK version.
  • User context — anything you supply via BrevwickConfig.user / userContext.

Users can add a title, expected/actual notes, and up to a handful of attachments (10 MB each), and optionally let AI format the report. The issue title is derived from the first line of the description (the API requires one); AI formatting, when enabled, refines it server-side.

App-id allowlist #

If your project restricts submissions to known apps (an AllowedAppIDs list), the SDK sends the host app's platform package id — the Android applicationId / iOS bundle id, read from package_info_plus — as the X-Brevwick-App-Id header on every ingest call. Register that id (e.g. com.acme.app, or com.acme.app.dev for a flavored build) in the project's allowlist, otherwise the API responds 403 ORIGIN_NOT_ALLOWED (app_id_mismatch). Projects without an app-id allowlist need no setup — the header is informational and the value is omitted when unavailable (e.g. some web builds).

Forwarding SDK diagnostics #

Set BrevwickConfig.onLog to route the SDK's own diagnostics — project-config fetch failures, screenshot-capture warnings, uncaught zone errors, and submit failures — into your app's logger. Messages are redacted at the boundary, and a throwing sink can never break the SDK.

await Brevwick.install(
  BrevwickConfig(
    projectKey: 'pk_live_...',
    onLog: (level, message, {error, stackTrace}) {
      switch (level) {
        case BrevwickLogLevel.error:
          myLogger.error(message, error, stackTrace);
        case BrevwickLogLevel.warn:
          myLogger.warn(message);
        case BrevwickLogLevel.info:
        case BrevwickLogLevel.debug:
          myLogger.info(message);
      }
    },
  ),
);

Privacy & redaction #

Every payload runs through a redaction pass before it leaves the device — emails, tokens, and other sensitive values are scrubbed client-side. Set fingerprintOptOut: true on BrevwickConfig to suppress device-fingerprint signals.

Platform view caveat #

The screenshot layer cannot capture AndroidView / UiKitView (maps, webviews, and other embedded platform views), which appear as gaps in the captured frame. Document this for any screen that embeds them.

Contract #

The canonical SDK contract lives in brevwick-ops/docs/brevwick-sdd.md § 12. The wire format mirrors the brevwick-sdk-js SDK byte-for-byte.

License #

MIT — see LICENSE.

0
likes
120
points
309
downloads

Documentation

API reference

Publisher

verified publishertatlacas.com

Weekly Downloads

Brevwick SDK for Flutter — send QA feedback from your app in one widget wrap.

Homepage
Repository (GitHub)
View/report issues

Topics

#feedback #bug-reports #qa #observability

Funding

Consider supporting this project:

github.com

License

MIT (license)

Dependencies

characters, crypto, device_info_plus, dio, file_picker, flutter, package_info_plus, screenshot

More

Packages that depend on brevwick