@@ -25,6 +25,9 @@ void main(List<String> args) async {
25
25
final flutterSdkPath =
26
26
parsedArgs.option (flutterSdkOption) ??
27
27
io.Platform .environment['FLUTTER_SDK' ];
28
+ final logFilePath = parsedArgs.option (logFileOption);
29
+ final logFileSink =
30
+ logFilePath == null ? null : createLogSink (io.File (logFilePath));
28
31
runZonedGuarded (
29
32
() {
30
33
server = DartMCPServer (
@@ -40,7 +43,8 @@ void main(List<String> args) async {
40
43
),
41
44
forceRootsFallback: parsedArgs.flag (forceRootsFallback),
42
45
sdk: Sdk .find (dartSdkPath: dartSdkPath, flutterSdkPath: flutterSdkPath),
43
- );
46
+ protocolLogSink: logFileSink,
47
+ )..done.whenComplete (() => logFileSink? .close ());
44
48
},
45
49
(e, s) {
46
50
if (server != null ) {
@@ -94,9 +98,37 @@ final argParser =
94
98
'cursor which claim to have roots support but do not actually '
95
99
'support it.' ,
96
100
)
101
+ ..addOption (
102
+ logFileOption,
103
+ help:
104
+ 'Path to a file to log all MPC protocol traffic to. File will be '
105
+ 'overwritten if it exists.' ,
106
+ )
97
107
..addFlag (help, abbr: 'h' , help: 'Show usage text' );
98
108
99
109
const dartSdkOption = 'dart-sdk' ;
100
110
const flutterSdkOption = 'flutter-sdk' ;
101
111
const forceRootsFallback = 'force-roots-fallback' ;
102
112
const help = 'help' ;
113
+ const logFileOption = 'log-file' ;
114
+
115
+ /// Creates a `Sink<String>` for [logFile] .
116
+ Sink <String > createLogSink (io.File logFile) {
117
+ logFile.createSync (recursive: true );
118
+ final fileByteSink = logFile.openWrite (
119
+ mode: io.FileMode .write,
120
+ encoding: utf8,
121
+ );
122
+ return fileByteSink.transform (
123
+ StreamSinkTransformer .fromHandlers (
124
+ handleData: (data, innerSink) {
125
+ innerSink.add (utf8.encode (data));
126
+ // It's a log, so we want to make sure it's always up-to-date.
127
+ fileByteSink.flush ();
128
+ },
129
+ handleDone: (innerSink) {
130
+ innerSink.close ();
131
+ },
132
+ ),
133
+ );
134
+ }
0 commit comments