inkpal_bridge 1.3.3 copy "inkpal_bridge: ^1.3.3" to clipboard
inkpal_bridge: ^1.3.3 copied to clipboard

Flutter MCP bridge for AI agents — runtime error capture, HTTP monitor, widget tree inspection, tap/type/screenshot. 33+ VM service extensions, zero deps.

example/lib/main.dart

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

void main() {
  InkPalBridge.init(
    serverUrl: 'ws://localhost:8765',
    appRunner: () => runApp(const TestApp()),
    licenseKey: const String.fromEnvironment('INKPAL_LICENSE_KEY'),
    knownRoutes: ['/home', '/search', '/profile'],
    routeDescriptions: {
      '/home': 'Main feed with counters and buttons',
      '/search': 'Search screen with text field',
      '/profile': 'User profile page',
    },
  );
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'InkPal Bridge Test',
      navigatorObservers: [
        if (InkPalBridge.instance != null)
          InkPalBridge.instance!.navigatorObserver,
      ],
      home: RepaintBoundary(
        key: InkPalBridge.instance?.repaintBoundaryKey,
        child: const HomeScreen(),
      ),
      routes: {
        '/search': (_) => const SearchScreen(),
        '/profile': (_) => const ProfileScreen(),
      },
    );
  }
}

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  int _counter = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Bridge Test')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Counter: $_counter', style: const TextStyle(fontSize: 24)),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: () {
                setState(() => _counter++);
                InkPalBridge.instance?.logger.log('Counter incremented to $_counter');
              },
              child: const Text('Increment'),
            ),
            const SizedBox(height: 8),
            ElevatedButton(
              onPressed: () => Navigator.pushNamed(context, '/search'),
              child: const Text('Go to Search'),
            ),
            const SizedBox(height: 8),
            ElevatedButton(
              onPressed: () => throw Exception('Test error from bridge'),
              child: const Text('Trigger Error'),
            ),
          ],
        ),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
          BottomNavigationBarItem(icon: Icon(Icons.search), label: 'Search'),
          BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Profile'),
        ],
        onTap: (i) {
          final routes = ['/', '/search', '/profile'];
          if (i > 0) Navigator.pushNamed(context, routes[i]);
        },
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Search')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          children: [
            TextField(
              decoration: const InputDecoration(
                hintText: 'Search...',
                prefixIcon: Icon(Icons.search),
              ),
              onChanged: (v) =>
                  InkPalBridge.instance?.logger.debug('Search: $v'),
            ),
            const SizedBox(height: 16),
            const Text('Type to search'),
          ],
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Profile')),
      body: const Center(child: Text('User Profile')),
    );
  }
}
4
likes
0
points
512
downloads

Publisher

verified publisherinkpal.ai

Weekly Downloads

Flutter MCP bridge for AI agents — runtime error capture, HTTP monitor, widget tree inspection, tap/type/screenshot. 33+ VM service extensions, zero deps.

Repository (GitHub)
View/report issues

Topics

#ai #testing #debugging #mcp #devtools

License

unknown (license)

Dependencies

flutter

More

Packages that depend on inkpal_bridge