flutter/flutter
The repo is built for extension at several layers. CLI: add a FlutterCommand subclass and register it in generateCommands(). DI: almost every service resolves through AppContext/globals, and runner.run accepts a per-type overrides map used for google3 and tests. Build: the BuildSystem runs Target subclasses registered via BuildTargets. Platform support: Feature flags + DevelopmentArtifacts + Device/DeviceDiscovery implementations (incl. custom-devices JSON config). Tool-side: an experimental ExtensionManager/ExtensionEntryPoint mechanism loads tool extensions (linux prototype wired in already). IDE surface: daemon Domains. Engine side: the embedder.h C API plus platform channels/MethodChannel for plugins, and dart_plugin_registrant for Dart-side plugin init.
- New CLI commands: subclass FlutterCommand (runner/flutter_command.dart), register an instance in the generateCommands() list in executable.dart — this is the single command table for the whole tool.
- Feature flags: add a Feature constant and a getter on FeatureFlags; flags get a configSetting consumed by `flutter config` and gate artifacts/commands — documented in docs/contributing/Feature-flags.md.
- Build steps: implement a Target subclass (inputs/outputs via Source patterns + a build action) and register it through the BuildTargets abstraction (BuildTargetsImpl in isolated/build_targets.dart overrides the interface).
- Dependency injection: services are fetched with context.get<T>()/globals.* (base/context.dart, globals.dart) and runner.run takes an overrides map <Type, Generator> — executable.main already uses it for Logger, AnsiTerminal, WebRunnerFactory, DevtoolsLauncher, TemplateRenderer, PreRunValidator, BuildTargets.
- Tool extensions: ExtensionManager + ExtensionEntryPoint (experimental/extension_manager.dart, extension_discovery.dart) load external tool extensions; the linux prototype entry point is already wired into executable.main behind isToolExtensionsEnabled.
- New device types: implement Device + DeviceDiscovery under the device manager (flutter_device_manager.dart), or declare SSH-based custom devices consumed by CustomDevicesCommand and custom_devices config.
- Doctor/validators: DoctorValidator implementations are aggregated in doctor.dart workflows (android_workflow, iosWorkflow); AnalyzeCommand additionally accepts a list of ProjectValidator plugins (GeneralInfoProjectValidator, VariableDumpMachineProjectValidator).
- IDE daemon protocol: new RPC surfaces are added as Domain subclasses registered via registerDomain() in DaemonCommand (existing domains cover app, device, emulator, daemon, devtools).
- Hot-runner hooks: HotRunnerConfig exposes setupHotRestart/setupHotReload/updateDevFSComplete/runPreShutdownOperations overridable via context.get<HotRunnerConfig>() — used by embedders like google3 to customize reload behavior.
- Engine platform ports: implement the embedder.h C API (or a platform embedder under shell/platform/) and bridge platform channels; Dart-side plugins register through dart_plugin_registrant.dart.
- Project scaffolding: `flutter create` templates live in packages/flutter_tools/templates (app, module, plugin, package_ffi...) rendered through TemplateRenderer; ExtensionTemplateManager can add extension-provided templates.
- Test infrastructure plugins: dev/bots suite runners follow the ShardRunner typedef — adding a shard means writing a run_*.dart under dev/bots/suite_runners and registering it in the selectShard map plus a matching .ci.yaml target.