To make sure the toolkit is excluded from production archives you need to setup three parts: a launch-argument hook, a debug-only setup file, and a kDebugMode gate in main().

1. A launch-argument hook

Create a file with no dependency on carp_debug_flutter. Production code reads launch arguments through this hook, so it never imports the package.
// lib/debug/debug_hooks.dart
String? Function(String key)? debugLaunchOverride;
The read the configuration anywhere in your app like the following: (in release the hook is null, so the compile-time value is used):
final mode = debugLaunchOverride?.call('deployment-mode')
    ?? const String.fromEnvironment('deployment-mode', defaultValue: 'production');

2. A debug-only setup file

This is the only file that imports the package. The two tabs differ only in where the preferences and database come from.
// lib/debug/debug_setup.dart
// ignore_for_file: depend_on_referenced_packages
import 'package:carp_debug_flutter/carp_debug_flutter.dart';
import 'package:carp_mobile_sensing/carp_mobile_sensing.dart' show Settings;
import 'package:flutter/widgets.dart';
import 'package:sembast/sembast.dart';
import 'debug_hooks.dart';

Future<void> initDebugTools() async {
  await DebugEnv().initialize();
  DebugEnv().registerAll(myEnvEntries);
  debugLaunchOverride = DebugEnv().overrideOf; // install the hook
}

Widget wrapWithToolkit(Widget child, Database db) => CarpDebugToolkit(
  config: DebugToolkitConfig(
    title: 'My CARP App Debug',
    envEntries: myEnvEntries,
    keyValueStores: [
      SharedPreferencesKeyValueStore(Settings().preferences!,
          name: 'CARP Preferences'),
    ],
    databases: [SembastDebugDatabase(db, [
      SembastStoreDescriptor('settings', StoreRef<String, Object?>.main()),
      SembastStoreDescriptor('results', intMapStoreFactory.store('result_store')),
    ])],
    onApply: () => bloc.backend.reconfigure(),        // re-point CAWS live
    onReinitialize: () => bloc.backend.reconfigure(), // iOS restart path
  ),
  child: child,
);

3. Gate it in main()

main() imports only the app-local debug_setup.dart, and calls it solely when kDebugMode. In release this folds to runApp(app) and the whole debug subtree (and the package) is tree-shaken away.
import 'package:flutter/foundation.dart';
import 'debug/debug_setup.dart' as debug;

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Load overrides BEFORE the app reads its configuration.
  if (kDebugMode) await debug.initDebugTools();

  final db = await openAppDatabase();
  final app = await buildApp(db);

  runApp(kDebugMode ? debug.wrapWithToolkit(app, db) : app);
}
See Production Builds for why this excludes the toolkit from release archives and how to verify it.

Define your launch arguments

myEnvEntries is a list of EnvEntry descriptors i.e. the values you normally pass via --dart-define:
const myEnvEntries = <EnvEntry>[
  EnvEntry(
    key: 'deployment-mode',
    label: 'Deployment mode',
    group: 'Server',
    type: EnvValueType.enumeration,
    options: ['production', 'test', 'dev'],
    fallback: String.fromEnvironment('deployment-mode', defaultValue: 'production'),
  ),
  EnvEntry(key: 'server-host', label: 'App server host', group: 'Server'),
];
Everything in DebugToolkitConfig is optional. An empty config still shows the debug button, the Device & App tool and the Logs & Errors tool.

Opening it

You can either tap the bug icon in the app or just open and close it programmatically:
DebugController.instance.open();
DebugController.instance.close();
DebugController.instance.toggle();