Skip to content

feat: capture requests - setCaptureEnabled, setRemoteLogCollectionEnabled and log flush - #40

Merged
boehlerlukas merged 3 commits into
mainfrom
claude/capture-requests
Oct 1, 2026
Merged

boehlerlukas merged 3 commits into
mainfrom
claude/capture-requests

Conversation

@boehlerlukas

@boehlerlukas boehlerlukas commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Version 19.1.0 is in this PR (native pins, version, CHANGELOG with release notes). Merge after iOS + Android 19.1.0 are published (CocoaPods CDN + Maven Central show them), then tag 19.1.0. Flutter web needs the JavaScript SDK 19.1.0 for capture.

What this adds

Flutter support for capture requests. Workflows, AI agents and teammates can ask the customer for a screenshot or a screen recording, and can collect the app's logs in the background. The native SDKs (and the JavaScript SDK on web) do the capturing.

  • Gleap.setCaptureEnabled({required bool enabled}): turns in-app screenshots and recordings for capture requests on or off. While off, the widget offers only a file upload. Default on.
  • Gleap.setRemoteLogCollectionEnabled({required bool enabled}): turns log collection for capture requests on or off. While off, log requests are answered as unsupported. Default on.
  • Web: the setters call the JavaScript SDK. A call made before it has loaded (or on an older JavaScript SDK) never throws, and is applied once the SDK reports initialized.
  • Log flush (iOS and Android): Dart pushes network logs to native at most every 500 ms. Before the native SDK collects logs for a request, the plugin calls flushLogs on the main thread. Dart pushes a pending push right away (GleapNetworkLogStore.flushPending), and the native SDK continues. It waits at most 500 ms; a detached engine answers right away.
  • Known limit, web: the JavaScript SDK has no flush hook, so logs pushed from Dart can lag up to 500 ms. Page recordings of a Flutter web app (canvas) show no content.
  • Masking: the native SDKs black out secure native views, FLAG_SECURE windows (Android) and views passed to their maskView. Fields drawn by Flutter (e.g. a password TextField) are not native views, so they are not detected. The customer reviews every screenshot and recording before sending and can blur parts of a screenshot. maskView is not exposed from Dart, because a Flutter widget can't be targeted as a native view.

Verification

  • flutter test 21/21, including the new flushPending test.
  • flutter analyze shows only 5 existing infos, all in example/.
  • flutter build web of the example OK.
  • Android javac against the local Android SDK branch is OK. Against 19.0.0 it fails only on the new symbols.
  • iOS clang syntax check against the local iOS SDK branch is OK. Against origin/main it fails only on the new symbols.

Release

After the native release: bump the podspec, Package.swift and the Android dependency, add the CHANGELOG entry and update the docs version table.


The whole program: capture requests ("Show me the issue")

Workflows, AI agents (Kai, Kai Resolve, custom agents) and teammates can now ask a customer for a screenshot (with annotation) or a screen recording in the middle of a conversation, and can collect logs (console, network, custom data, environment data, events) from the customer's app in the background.

One server object, the capture request, backs all three. The customer sees a card in the widget; the SDK in their app does the capture; the result lands in the thread and resumes the workflow or wakes the agent. Background log requests travel over the SDK websocket every SDK already keeps open.

How each platform captures:

  • Web, desktop Chrome/Edge: screenshot via one-click "Share this tab" (exact pixels), in-browser render as fallback; recording via tab capture, "Record this page" fallback when sharing is blocked.
  • Web, Firefox/Safari/phones/tablets: in-browser screenshot; window/screen recording on desktop, page recording (rrweb) on phones.
  • iOS / Android apps (incl. React Native, Flutter, Capacitor): in-app capture of the app's own windows: no OS prompt and no new permissions (no ReplayKit, no MediaProjection). Recordings are H.264 MP4 built from frames.
  • Older SDKs, email, WhatsApp & co.: upload / reply-with-attachment fallback, so a request never dead-ends.

Design: https://claude.ai/artifact/5i88BeWfcsWUFhhJmPwK5V (private)

PRs in this program (one per repo):

🤖 Generated with Claude Code

boehlerlukas and others added 2 commits September 30, 2026 23:08
… requests

Gleap.setCaptureEnabled(enabled: ...) turns the in-app screenshots and screen
recordings for capture requests ("show me the issue") on or off; while off,
the widget only offers a file upload. Gleap.setRemoteLogCollectionEnabled(
enabled: ...) turns sending the app's logs for capture requests on or off;
while off, log requests are answered as unsupported. Both default to on.

iOS and Android pass them to the native SDKs. Web calls the JavaScript SDK's
Gleap.setCaptureEnabled / setRemoteLogCollectionEnabled; a call made before
the JavaScript SDK has loaded (or on one without them) never throws and is
applied once it reports initialized.

Needs the native iOS / Android release with capture requests and, on web,
the JavaScript SDK release with them (pins stay on 19.0.0 until the release
bumps them).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…logs for a capture request

Network requests logged from Dart (logNetworkRequest, the http / dio
interceptors) are pushed to the native SDK at most every 500 ms. When a
capture request asks for the app's logs, the native SDK now first calls the
log flush handler, registered on initialize (Android and iOS): the plugin
invokes flushLogs on the main thread, Dart pushes a scheduled push right away
(GleapNetworkLogStore.flushPending, awaiting attachNetworkLogs) and returns,
and the plugin calls done. The SDK waits at most 500 ms; with the engine
detached the flush is answered right away.

Web has no flush hook: the JavaScript SDK collects the logs there and Dart
pushes to it at most every 500 ms, as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@boehlerlukas
boehlerlukas merged commit df94af4 into main Oct 1, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant