clariodesk 0.1.3 copy "clariodesk: ^0.1.3" to clipboard
clariodesk: ^0.1.3 copied to clipboard

ClarioDesk Flutter SDK — in-app customer support chat, bug reporting with auto screenshots, and feedback for mobile apps. Prebuilt UI or headless API.

clariodesk #

In-app support and bug reporting for Flutter apps. The native half of the ClarioDesk SaaS — drop the SDK in, get a hardware-bound device identity and a live ticket UI, no backend code on your side.

Integrating with an AI agent? (Claude Code, Cursor, Codex) Paste the install prompt and it does this whole README for you — detect, ask, install, verify. Machine-readable docs: llms.txt · rules for AI agents.

What ships #

  • ClarioDesk.init, ClarioDesk.identify, ClarioDesk.createTicket, ClarioDesk.sendMessage, ClarioDesk.ticketsStream, ClarioDesk.messagesStream, ClarioDesk.reset.
  • iOS Secure Enclave / Android Keystore-backed ECDSA P-256 keypair. Generated on first launch, never extractable.
  • Challenge-response device registration, per-request signatures, signed SSE handshakes.

Quick start #

import 'package:clariodesk/clariodesk.dart';

Future<void> main() async {
  // First call generates the hardware key + registers with the backend.
  // Subsequent launches reuse the existing key (no network).
  await ClarioDesk.init(apiKey: 'pk_live_…');

  runApp(const MyApp());
}

// After your own auth knows who the user is. Optional — pure metadata.
// See "Lifecycle integration" below for the four host events you need
// to wire (especially case 1, which covers users who were already
// logged in before you installed the SDK).
await ClarioDesk.identify(
  externalId: hostUser.id,
  email: hostUser.email,
  traits: {'plan': 'pro'},
);

// File a ticket.
final t = await ClarioDesk.createTicket(
  subject: 'Upload broken',
  body: 'Tapping upload does nothing.',
);

// Reactive inbox — auto-primes + live updates.
StreamBuilder<List<Ticket>>(
  stream: ClarioDesk.ticketsStream(),
  builder: (_, snap) => /* … */,
);

Lifecycle integration #

Four host events touch the SDK. Wire each one and you're done.

1. App launch (every time, including for already-logged-in users) #

The most common integration miss: existing users who installed your app before you added ClarioDesk never go through the login flow again, so an "identify on login" hook alone leaves them as unlabeled devices.

Hydrate from your own persisted session on launch and identify unconditionally — identify() is idempotent (same values = no-op write) and cheap (one signed POST, ~5–25 ms).

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await ClarioDesk.init(apiKey: 'pk_live_…');

  final user = await yourAuth.currentUser();   // Firebase, Supabase,
                                                // your own session store, …
  if (user != null) {
    await ClarioDesk.identify(
      externalId: user.id,
      email: user.email,
      traits: {'plan': user.plan},
    );
  }

  runApp(const MyApp());
}

2. Fresh login or signup #

Right after your auth succeeds:

await yourAuth.signIn(email, password);
await ClarioDesk.identify(
  externalId: user.id,
  email: user.email,
  traits: {'plan': user.plan},
);

This overwrites the label on the existing device row — no new device gets registered, no new hardware key gets generated. The same device now carries the new user's metadata.

3. Logout #

await ClarioDesk.reset();
await yourAuth.signOut();

reset() best-effort revokes the device server-side, wipes the hardware key, and clears local caches. The next init() registers a brand-new device — important if the device is shared.

4. User switch (account A → account B without app restart) #

await ClarioDesk.reset();
await ClarioDesk.init(apiKey: 'pk_live_…');   // fresh device for user B
await ClarioDesk.identify(
  externalId: userB.id,
  email: userB.email,
);

Same as logout + login. Don't try to "rebind" the existing device to the new user — reset() + new device is the right boundary because each device row carries an independent ticket history.

What if I never call identify()? #

Tickets still work. The device row exists, agents see a device id but no email — the dashboard shows an "Unverified device" badge. Useful for anonymous-feedback flows; otherwise call identify() from case 1 above and you're covered.

Auth model #

You ship one publishable API key (pk_live_…) in your app binary. Its only capability is letting a fresh install register a device with us — it cannot read tickets or impersonate users. Every authenticated call the SDK makes is signed by the device's hardware-bound private key.

If your key leaks, an attacker can register throwaway devices (rate- limited and bounded) but cannot touch any existing user's data. There is no separate "secure mode" to enable, no HMAC backend to build, no identity-verification setup. You ship the key, your users are secure by default.

Full documentation at docs.clariodesk.com.

Platforms #

  • iOS — Secure Enclave when present (most iPhones since 5s), software-backed Keychain otherwise. Requires iOS 13+.
  • Android — StrongBox when supported (Pixel 3+, recent Samsung), TEE-backed Keystore otherwise. Requires API 23+ (Marshmallow).

Example app #

See example/. Runs against staging or local API:

cd example
flutter run --dart-define=CLARIODESK_API_KEY=pk_live_…
0
likes
140
points
206
downloads

Documentation

Documentation
API reference

Publisher

unverified uploader

Weekly Downloads

ClarioDesk Flutter SDK — in-app customer support chat, bug reporting with auto screenshots, and feedback for mobile apps. Prebuilt UI or headless API.

Homepage
Repository (GitHub)
View/report issues

Topics

#support #customer-support #chat #bug-reporting #feedback

License

MIT (license)

Dependencies

centrifuge, connectivity_plus, crypto, device_info_plus, file_selector, flutter, flutter_secure_storage, http, image_picker, package_info_plus, share_plus, url_launcher

More

Packages that depend on clariodesk

Packages that implement clariodesk