diff --git a/lib/app/app_controller_desktop_core.dart b/lib/app/app_controller_desktop_core.dart index ac269098..0af2433b 100644 --- a/lib/app/app_controller_desktop_core.dart +++ b/lib/app/app_controller_desktop_core.dart @@ -26,6 +26,7 @@ import '../runtime/gateway_acp_client.dart'; import '../runtime/codex_runtime.dart'; import '../runtime/codex_config_bridge.dart'; import '../runtime/code_agent_node_orchestrator.dart'; +import '../runtime/go_gateway_runtime_desktop_client.dart'; import '../runtime/assistant_artifacts.dart'; import '../runtime/desktop_thread_artifact_service.dart'; import '../runtime/external_code_agent_acp_desktop_transport.dart'; @@ -142,6 +143,7 @@ class AppController extends ChangeNotifier { gateway: GatewayRuntime( store: storeInternal, identityStore: DeviceIdentityStore(storeInternal), + sessionClient: GoGatewayRuntimeDesktopClient(), allowDirectSocketFallbackOnSessionClientFailure: shouldBlockEmbeddedAgentLaunch( isAppleHost: Platform.isIOS || Platform.isMacOS, diff --git a/lib/runtime/gateway_runtime_core.dart b/lib/runtime/gateway_runtime_core.dart index ec1e3570..9330146b 100644 --- a/lib/runtime/gateway_runtime_core.dart +++ b/lib/runtime/gateway_runtime_core.dart @@ -100,6 +100,9 @@ class GatewayRuntime extends ChangeNotifier with GatewayRuntimeHelpersInternal { appendLogInternal(this, level, category, message); } + @visibleForTesting + bool get usesSessionClient => sessionClientInternal != null; + Future initialize() async { sessionUpdatesInternal ??= sessionClientInternal?.updates.listen( _handleSessionUpdateInternal, diff --git a/lib/runtime/go_acp_stdio_bridge.dart b/lib/runtime/go_acp_stdio_bridge.dart index c27b129e..f761b8db 100644 --- a/lib/runtime/go_acp_stdio_bridge.dart +++ b/lib/runtime/go_acp_stdio_bridge.dart @@ -46,6 +46,8 @@ class GoAcpStdioBridge { Stream> get notifications => _notificationsController.stream; + bool get isStarted => _process != null || _startupFuture != null; + Future> request({ required String method, required Map params, diff --git a/lib/runtime/go_gateway_runtime_desktop_client.dart b/lib/runtime/go_gateway_runtime_desktop_client.dart index e8c29db2..0354a4a8 100644 --- a/lib/runtime/go_gateway_runtime_desktop_client.dart +++ b/lib/runtime/go_gateway_runtime_desktop_client.dart @@ -67,6 +67,9 @@ class GoGatewayRuntimeDesktopClient implements GatewayRuntimeSessionClient { @override Future disconnect({required String runtimeId}) async { + if (!_bridge.isStarted) { + return; + } await _request( method: 'xworkmate.gateway.disconnect', params: {'runtimeId': runtimeId}, diff --git a/test/app_controller_desktop_gateway_bridge_client_test.dart b/test/app_controller_desktop_gateway_bridge_client_test.dart new file mode 100644 index 00000000..ea884ec2 --- /dev/null +++ b/test/app_controller_desktop_gateway_bridge_client_test.dart @@ -0,0 +1,13 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:xworkmate/app/app_controller_desktop_core.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + test('default desktop controller wires gateway runtime through bridge client', () { + final controller = AppController(); + addTearDown(controller.dispose); + + expect(controller.runtime.usesSessionClient, isTrue); + }); +}