outcode_bug_reporter library

In-app bug reporter for Flutter.

Wrap your app once and users get a floating button that captures the current screen, lets them annotate and redact it, pick a severity and type, and file a fully-detailed report — screenshot, device context, and recent logs included — to ClickUp or any backend you plug in.

MaterialApp(
  builder: (context, child) => BugReporter(
    config: BugReporterConfig(
      appName: 'My App',
      appVersion: '1.0.0',
      repository: OutcodeBackendBugReporterRepository(
        endpoint: 'https://bot.example.com/admin/api/bugs/ingest',
        apiKey: apiKey,
        targetKey: targetKey,
      ),
    ),
    child: child!,
  ),
)

Part of the OutCode Bug Reporter family, sharing its report format and theme tokens with @outcode/bug-reporter-web and @outcode/bug-reporter-native.

Classes

AccelerometerSample
One accelerometer reading, in g (≈1.0 at rest, gravity included).
AnnotateOverlay
AnnotateOverlayState
Public so the orchestrator can keep the editor mounted across an "Edit" round-trip from the form without losing the drawn shapes.
AnnotateToolbar
Annotation
One drawn annotation. Coordinates are in the annotation stage's local (logical) pixels, so they scale with however the screenshot is displayed.
AnnotationPainter
AnnotationToolOption
A tool as presented in the toolbar.
BoxAnnotation
An arrow, box outline, or opaque redaction block, drawn by dragging.
One captured log line.
BugReporter
Wraps your app, screenshots it, and files reports about it.
BugReporterConfig
Everything the reporter needs: identity, backend, look, and optional hooks.
BugReporterController
Opens and closes the reporter from your own code — the analogue of the React Native package's button ref.
BugReporterHttpClient
An http.Client that records failed calls into a BugReporterLogCapture.
BugReporterLogCapture
Collects breadcrumbs and the last failed request for inclusion in reports.
BugReporterNavigatorObserver
Tracks the active route name so reports say where the bug happened — the Flutter equivalent of the web package's "Route" row.
BugReporterRepository
A report backend. Implement this to file reports anywhere — Jira, Linear, GitHub, or your own API.
BugReporterState
BugReporterTheme
Colour tokens driving every surface of the reporter UI.
BugReportForm
BugReportRequest
Payload for the default HTTP backend (BugReporterConfig.apiUrl).
BugReportResponse
The outcome of a submit attempt.
CapturedScreenshot
A captured PNG plus the geometry needed to place annotations on it.
ClickUpBugReporterRepository
Files reports as ClickUp tasks.
CreateReportParams
Parameters handed to a BugReporterRepository. Mirrors CreateReportParams in the JS core so both platforms file identical-looking tickets.
InMemoryReportQueueStorage
Non-persistent storage — useful in tests and demos. Queued reports are lost when the process exits.
LastFailedApiCall
The most recent failed HTTP call.
OutcodeBackendBugReporterRepository
Files reports via the Outcode bot's /admin/api/bugs/ingest endpoint.
PenAnnotation
A freehand stroke.
ReportContextRow
A single auto-captured context row (label → value) shown in the form and rendered into the report body.
ReportFlow
The flow itself. Mount it under an Overlay and close it from onClose.
ReportFlowRoute
Route that hosts the flow, for hosts that would rather present it themselves than use BugReporter's floating button. Transparent, so the app stays visible behind the annotation editor's scrim.
ReportFlowState
Public so a host can drive handleBack from its own back handling.
ReportQueue
Persists failed reports and replays them later.
ReportQueueStorage
Minimal key/value store backing the queue.
ReportTypeOption
A selectable report type in the form.
ScreenshotOptions
Screenshot size guard.
SeverityOption
A selectable severity in the form, with its indicator colour.
ShakeDetector
Counts jolts and reports shakes. Feed it samples with push; it calls onShake when the pattern matches. Holds no timers and no subscriptions — the caller owns the sensor, which is what makes this testable with a plain list of samples and a fake clock.
ShakeOptions
Tuning for ShakeDetector.
SubmitReportOptions
Everything needed to submit one report — and the unit the offline queue persists, hence the JSON round-trip.
SuccessCard
TextAnnotation
A text label pinned to a point on the screenshot.

Enums

AnnotationTool
The five annotation tools, in toolbar order.
BoxShape2D
The drag-drawn shapes (BoxAnnotation.shape).
ContextFlag
Optional severity hint colouring a context row's value.
LogLevel
Severity of a captured log line. Names match the JS core's wire values.
ReportPriority
Report priority. Maps to a backend priority (e.g. ClickUp 1=urgent … 4=low).
ReportSeverity
Severity selected in the report form. Maps to ReportPriority.
ReportType
Report type/category. Mapped to a backend tag.

Constants

kAnnotationColors → const List<Color>
Palette shown in the annotation toolbar (matches the design's 8 swatches).
kAnnotationTools → const List<AnnotationToolOption>
Toolbar tools with their icons (the Flutter analogue of the shared SVG paths).
kGravity → const double
Standard gravity in m/s². Matches GRAVITY in packages/core/src/shake.ts.
kRedactionFill → const Color
Opaque fill used by the redaction tool.
kReportQueueKey → const String
Default storage key.
kReportQueueMaxEntries → const int
Cap on stored entries, so a long offline streak can't grow storage without bound. Matches the JS core.
kReportTypes → const List<ReportTypeOption>
Report type choices, in form order.
kSeverities → const List<SeverityOption>
Severity choices, in form order. Colours match the web/native design.

Functions

buildContextRows(BuildContext context, BugReporterConfig config) List<ReportContextRow>
Build the auto-captured context rows for the current frame.
buildCreateReportParams(BugReporterConfig config, SubmitReportOptions options) CreateReportParams
Build the repository payload from config + submit options.
captureBoundary(GlobalKey<State<StatefulWidget>> boundaryKey, {ScreenshotOptions options = const ScreenshotOptions(), double devicePixelRatio = 1.0}) Future<CapturedScreenshot?>
Rasterize the RepaintBoundary identified by boundaryKey.
enumByName<T extends Enum>(List<T> values, String? name) → T?
Look an enum value up by its name, returning null when absent.
getReportQueue(BugReporterConfig config) ReportQueue?
Build a queue from BugReporterConfig.storage, or null when unconfigured.
severityToPriority(ReportSeverity? severity) ReportPriority?
Map form severity to backend priority.
submitBugReport(BugReportRequest request, BugReporterConfig config, {Client? client}) Future<BugReportResponse>
POST a report to BugReporterConfig.apiUrl.
submitReport(BugReporterConfig config, SubmitReportOptions options, {Client? client}) Future<BugReportResponse>
Submit via BugReporterConfig.repository when set, else the default HTTP POST.

Typedefs

AccelerometerProvider = Stream<AccelerometerSample> Function(Duration interval)
Supplies accelerometer samples in g.
AnnotateContinueCallback = void Function(CapturedScreenshot flattened, int annotationCount)
Called when the user accepts their annotations, with the flattened image.
ContextCollector = FutureOr<List<ReportContextRow>> Function()
Collects extra auto-captured context rows when the form opens. May be async.
DiagnosticsCollector = Map<String, Object?>? Function()
Collects dynamic diagnostics at submit time (breadcrumbs, last failed call).
ShakeClock = int Function()
A clock in milliseconds. Injectable so the detector is testable.