docker-flutter-ios-simulator-mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/CLAUDE.md +74 -0
  2. package/LICENSE +21 -0
  3. package/README.md +370 -0
  4. package/dist/flutter/log-buffer.d.ts +14 -0
  5. package/dist/flutter/log-buffer.d.ts.map +1 -0
  6. package/dist/flutter/log-buffer.js +49 -0
  7. package/dist/flutter/log-buffer.js.map +1 -0
  8. package/dist/flutter/process.d.ts +30 -0
  9. package/dist/flutter/process.d.ts.map +1 -0
  10. package/dist/flutter/process.js +241 -0
  11. package/dist/flutter/process.js.map +1 -0
  12. package/dist/flutter/types.d.ts +31 -0
  13. package/dist/flutter/types.d.ts.map +1 -0
  14. package/dist/flutter/types.js +2 -0
  15. package/dist/flutter/types.js.map +1 -0
  16. package/dist/index.d.ts +3 -0
  17. package/dist/index.d.ts.map +1 -0
  18. package/dist/index.js +207 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/server.d.ts +3 -0
  21. package/dist/server.d.ts.map +1 -0
  22. package/dist/server.js +18 -0
  23. package/dist/server.js.map +1 -0
  24. package/dist/session/manager.d.ts +74 -0
  25. package/dist/session/manager.d.ts.map +1 -0
  26. package/dist/session/manager.js +209 -0
  27. package/dist/session/manager.js.map +1 -0
  28. package/dist/session/state.d.ts +14 -0
  29. package/dist/session/state.d.ts.map +1 -0
  30. package/dist/session/state.js +42 -0
  31. package/dist/session/state.js.map +1 -0
  32. package/dist/session/types.d.ts +26 -0
  33. package/dist/session/types.d.ts.map +1 -0
  34. package/dist/session/types.js +2 -0
  35. package/dist/session/types.js.map +1 -0
  36. package/dist/simulator/idb.d.ts +42 -0
  37. package/dist/simulator/idb.d.ts.map +1 -0
  38. package/dist/simulator/idb.js +127 -0
  39. package/dist/simulator/idb.js.map +1 -0
  40. package/dist/simulator/simctl.d.ts +9 -0
  41. package/dist/simulator/simctl.d.ts.map +1 -0
  42. package/dist/simulator/simctl.js +96 -0
  43. package/dist/simulator/simctl.js.map +1 -0
  44. package/dist/simulator/types.d.ts +25 -0
  45. package/dist/simulator/types.d.ts.map +1 -0
  46. package/dist/simulator/types.js +2 -0
  47. package/dist/simulator/types.js.map +1 -0
  48. package/dist/tools/flutter-commands.d.ts +128 -0
  49. package/dist/tools/flutter-commands.d.ts.map +1 -0
  50. package/dist/tools/flutter-commands.js +275 -0
  51. package/dist/tools/flutter-commands.js.map +1 -0
  52. package/dist/tools/index.d.ts +3 -0
  53. package/dist/tools/index.d.ts.map +1 -0
  54. package/dist/tools/index.js +499 -0
  55. package/dist/tools/index.js.map +1 -0
  56. package/dist/tools/session.d.ts +38 -0
  57. package/dist/tools/session.d.ts.map +1 -0
  58. package/dist/tools/session.js +40 -0
  59. package/dist/tools/session.js.map +1 -0
  60. package/dist/tools/simulator-ui.d.ts +102 -0
  61. package/dist/tools/simulator-ui.d.ts.map +1 -0
  62. package/dist/tools/simulator-ui.js +117 -0
  63. package/dist/tools/simulator-ui.js.map +1 -0
  64. package/dist/tools/simulator.d.ts +7 -0
  65. package/dist/tools/simulator.d.ts.map +1 -0
  66. package/dist/tools/simulator.js +8 -0
  67. package/dist/tools/simulator.js.map +1 -0
  68. package/dist/transport.d.ts +4 -0
  69. package/dist/transport.d.ts.map +1 -0
  70. package/dist/transport.js +20 -0
  71. package/dist/transport.js.map +1 -0
  72. package/dist/utils/exec.d.ts +29 -0
  73. package/dist/utils/exec.d.ts.map +1 -0
  74. package/dist/utils/exec.js +109 -0
  75. package/dist/utils/exec.js.map +1 -0
  76. package/dist/utils/logger.d.ts +17 -0
  77. package/dist/utils/logger.d.ts.map +1 -0
  78. package/dist/utils/logger.js +60 -0
  79. package/dist/utils/logger.js.map +1 -0
  80. package/package.json +76 -0
package/CLAUDE.md ADDED
@@ -0,0 +1,74 @@
1
+ # CLAUDE.md
2
+
3
+ Information and instructions to AI agents using this MCP
4
+
5
+ ## Purpose
6
+
7
+ This MCP provides access to and control of building flutter apps, launching the iOS simulator, and interacting with it, including taking screenshots and getting accessibility info.
8
+
9
+ ### 3. Use the Tools
10
+
11
+ The MCP server provides these tools to AI agents:
12
+
13
+ **Session Management:**
14
+ - `session_start` - Create a new development session with a simulator
15
+ - `session_end` - Clean up and delete the simulator
16
+ - `session_list` - View active sessions
17
+
18
+ **Flutter Development:**
19
+ - `flutter_run` - Build and launch your app
20
+ - `flutter_build` - Build iOS app without running (for CI/deployment)
21
+ - `flutter_test` - Run Flutter tests and return results
22
+ - `flutter_clean` - Clean build cache and artifacts
23
+ - `flutter_logs` - Monitor build progress and app output
24
+ - `flutter_hot_reload` - Apply code changes instantly
25
+ - `flutter_hot_restart` - Restart the app
26
+ - `flutter_stop` - Stop the running app
27
+
28
+ **UI Interaction:**
29
+ - `screenshot` - Capture and view the simulator screen
30
+ - `ui_tap` - Tap at coordinates
31
+ - `ui_swipe` - Swipe gestures (scrolling, swiping)
32
+ - `ui_type` - Enter text into fields
33
+ - `ui_describe_all` - Get accessibility tree
34
+ - `ui_describe_point` - Inspect element at coordinates
35
+
36
+ **Device Management:**
37
+ - `simulator_list` - See available iOS device types
38
+
39
+ ## Example Workflow
40
+
41
+ Here's a typical AI agent workflow:
42
+
43
+ ```javascript
44
+ // 1. Start a session with your Flutter project
45
+ session_start({
46
+ worktreePath: "/path/to/your/flutter/project",
47
+ deviceType: "iPhone 16 Pro"
48
+ })
49
+ // Returns: { sessionId: "abc-123", simulatorUdid: "..." }
50
+
51
+ // 2. Run the Flutter app
52
+ flutter_run({ sessionId: "abc-123" })
53
+
54
+ // 3. Monitor build progress (poll every few seconds)
55
+ flutter_logs({
56
+ sessionId: "abc-123",
57
+ fromIndex: 0, // Start from beginning
58
+ limit: 100 // Get 100 lines
59
+ })
60
+
61
+ // 4. Take a screenshot to see the app
62
+ screenshot({ sessionId: "abc-123" })
63
+ // Returns image directly in response!
64
+
65
+ // 5. Interact with the UI
66
+ ui_tap({ sessionId: "abc-123", x: 200, y: 400 })
67
+
68
+ // 6. Make code changes, then hot reload
69
+ flutter_hot_reload({ sessionId: "abc-123" })
70
+
71
+ // 7. Clean up when done
72
+ session_end({ sessionId: "abc-123" })
73
+ ```
74
+
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Nick Clifford
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,370 @@
1
+ # docker-flutter-ios-simulator-mcp
2
+
3
+ **Model Context Protocol server for Flutter iOS development with AI agents**
4
+
5
+ Enables AI agents (like Claude) inside a Docker container to build, run, and interact with Flutter iOS applications through an iOS Simulator running on the host. Perfect for running claude inside a secure container while allowing it to build and test iOS and macOS apps
6
+
7
+ ## Features
8
+
9
+ - 🎯 **Session-based Development** - Isolated simulator and Flutter process per session
10
+ - 🔥 **Hot Reload & Restart** - Instant code updates without full rebuilds
11
+ - 📱 **UI Automation** - Tap, swipe, type, and interact with the simulator
12
+ - 📸 **Visual Feedback** - Screenshots returned as images (Docker-compatible)
13
+ - 🔍 **Accessibility Tree** - Inspect UI elements and hierarchy
14
+ - 📊 **Live Logs** - Real-time Flutter build output and app logs
15
+ - 🌐 **HTTP Transport** - Works from Docker containers (no filesystem access needed)
16
+
17
+ ## Architecture
18
+
19
+ Enables AI agents running in Docker containers to control iOS Simulators on the macOS host:
20
+
21
+ ```
22
+ ┌─────────────────────────────────────────────────────────────────┐
23
+ │ macOS Host │
24
+ │ │
25
+ │ ┌──────────────────┐ ┌─────────────────────────────┐ │
26
+ │ │ iOS Simulators │ │ docker-flutter-ios- │ │
27
+ │ │ ┌─ Sim 1 ──────┐ │◄────────┤ simulator-mcp │ │
28
+ │ │ ┌─ Sim 2 ──────┐ │ │ │ │
29
+ │ │ │ Flutter App │ │ │ • Session Management │ │
30
+ │ │ │ │ │ │ • Flutter Build/Run/Test │ │
31
+ │ │ └──────────────┘ │ │ • Hot Reload/Restart │ │
32
+ │ │ │ │ • Screenshots (via IDB) │ │
33
+ │ │ Status: Booted │ │ • UI Automation │ │
34
+ │ └──────────────────┘ │ • Log Streaming │ │
35
+ │ └─────────────────────────────┘ │
36
+ │ ▲ │
37
+ │ │ HTTP/MCP │
38
+ └─────────────────────────────────────────┼───────────────────────┘
39
+
40
+ ┌─────────────────────┴──────────────────────┐
41
+ │ │
42
+ ┌─────────┴──────────┐ ┌──────────────────┴┐
43
+ │ Docker Container │ │ Docker Container │
44
+ │ │ │ │
45
+ │ ┌──────────────┐ │ │ ┌───────────────┐ │
46
+ │ │ AI Agent │ │ │ │ AI Agent │ │
47
+ │ │ (Claude) │──┼──────────────┼─│ (Claude) │ │
48
+ │ │ │ │ │ │ │ │
49
+ │ │ Builds & │ │ │ │ Tests & │ │
50
+ │ │ Develops │ │ │ │ Debugs │ │
51
+ │ └──────────────┘ │ │ └───────────────┘ │
52
+ │ │ │ │
53
+ └────────────────────┘ └───────────────────┘
54
+ ```
55
+
56
+ **Flow:**
57
+ 1. AI agents in containers connect to MCP server via HTTP
58
+ 2. MCP server manages iOS Simulator instances and Flutter processes
59
+ 3. Agents can build, run, test, and interact with Flutter apps
60
+ 4. Screenshots and logs flow back to agents in real-time
61
+
62
+ ## Prerequisites
63
+
64
+ **macOS only** - Requires Xcode and iOS Simulator
65
+
66
+ 1. **Xcode** - Install from Mac App Store, then run:
67
+ ```bash
68
+ sudo xcode-select --switch /Applications/Xcode.app
69
+ xcodebuild -runFirstLaunch
70
+ ```
71
+
72
+ 2. **Flutter SDK** - [Install Flutter](https://docs.flutter.dev/get-started/install/macos) and ensure it's in your PATH:
73
+ ```bash
74
+ flutter --version
75
+ ```
76
+
77
+ 3. **Node.js 18+** - [Install Node.js](https://nodejs.org/)
78
+
79
+ 4. **Facebook IDB** - iOS automation tool:
80
+ MacOS's Python environment is pretty borked at the moment, it's best to use brew and pipx to manage the installation:
81
+
82
+ ```bash
83
+ # First, ensure you have a modern python installed via homebrew (if not already done)
84
+ brew install python@3.12
85
+
86
+ # Then, install pipx using that specific python's pip
87
+ python3.12 -m pip install pipx
88
+
89
+ # Ensure pipx is added to your PATH
90
+ pipx ensurepath
91
+
92
+ # Install IDB
93
+ pipx install fb-idb
94
+
95
+ # Verify installation
96
+ idb --help
97
+
98
+ # Then install idb-companion
99
+ brew tap facebook/fb
100
+ brew install idb-companion
101
+
102
+ # Verify it works
103
+ idb list-targets
104
+ ```
105
+
106
+ ## Installation
107
+
108
+ ### Option 1: NPX (Recommended for Users)
109
+
110
+ No installation needed! Run directly with npx:
111
+
112
+ ```bash
113
+ npx docker-flutter-ios-simulator-mcp
114
+ # Server starts at http://localhost:3000/mcp
115
+ ```
116
+
117
+ ### Option 2: Local Development
118
+
119
+ Clone and run from source:
120
+
121
+ ```bash
122
+ # Clone the repository
123
+ git clone https://github.com/zafnz/docker-flutter-ios-simulator-mcp.git
124
+ cd docker-flutter-ios-simulator-mcp
125
+
126
+ # Install dependencies
127
+ npm install
128
+
129
+ # Build TypeScript
130
+ npm run build
131
+
132
+ # Start the server
133
+ npm start
134
+ # Server starts at http://localhost:3000/mcp
135
+ ```
136
+
137
+ ## Quick Start
138
+
139
+ ### 1. Start the MCP Server
140
+
141
+ ```bash
142
+ npx docker-flutter-ios-simulator-mcp
143
+ ```
144
+
145
+ The server will start on port 3000 by default.
146
+
147
+ ### 2. Configure Your MCP Client
148
+
149
+ For **Claude Desktop** or **Docker containers**, connect to:
150
+ ```
151
+ http://localhost:3000/mcp
152
+ ```
153
+
154
+ From **Docker**, use:
155
+ ```
156
+ http://host.docker.internal:3000/mcp
157
+ ```
158
+
159
+ ### 3. Use the Tools
160
+
161
+ The MCP server provides these tools to AI agents:
162
+
163
+ **Session Management:**
164
+ - `session_start` - Create a new development session with a simulator
165
+ - `session_end` - Clean up and delete the simulator
166
+ - `session_list` - View active sessions
167
+
168
+ **Flutter Development:**
169
+ - `flutter_run` - Build and launch your app
170
+ - `flutter_build` - Build iOS app without running (for CI/deployment)
171
+ - `flutter_test` - Run Flutter tests and return results
172
+ - `flutter_clean` - Clean build cache and artifacts
173
+ - `flutter_logs` - Monitor build progress and app output
174
+ - `flutter_hot_reload` - Apply code changes instantly
175
+ - `flutter_hot_restart` - Restart the app
176
+ - `flutter_stop` - Stop the running app
177
+
178
+ **UI Interaction:**
179
+ - `screenshot` - Capture and view the simulator screen
180
+ - `ui_tap` - Tap at coordinates
181
+ - `ui_swipe` - Swipe gestures (scrolling, swiping)
182
+ - `ui_type` - Enter text into fields
183
+ - `ui_describe_all` - Get accessibility tree
184
+ - `ui_describe_point` - Inspect element at coordinates
185
+
186
+ **Device Management:**
187
+ - `simulator_list` - See available iOS device types
188
+
189
+ ## Example Workflow
190
+
191
+ Here's a typical AI agent workflow:
192
+
193
+ ```javascript
194
+ // 1. Start a session with your Flutter project
195
+ session_start({
196
+ worktreePath: "/path/to/your/flutter/project",
197
+ deviceType: "iPhone 16 Pro"
198
+ })
199
+ // Returns: { sessionId: "abc-123", simulatorUdid: "..." }
200
+
201
+ // 2. Run the Flutter app
202
+ flutter_run({ sessionId: "abc-123" })
203
+
204
+ // 3. Monitor build progress (poll every few seconds)
205
+ flutter_logs({
206
+ sessionId: "abc-123",
207
+ fromIndex: 0, // Start from beginning
208
+ limit: 100 // Get 100 lines
209
+ })
210
+
211
+ // 4. Take a screenshot to see the app
212
+ screenshot({ sessionId: "abc-123" })
213
+ // Returns image directly in response!
214
+
215
+ // 5. Interact with the UI
216
+ ui_tap({ sessionId: "abc-123", x: 200, y: 400 })
217
+
218
+ // 6. Make code changes, then hot reload
219
+ flutter_hot_reload({ sessionId: "abc-123" })
220
+
221
+ // 7. Clean up when done
222
+ session_end({ sessionId: "abc-123" })
223
+ ```
224
+
225
+ ## Configuration
226
+
227
+ ### Command-Line Options
228
+
229
+ ```bash
230
+ docker-flutter-ios-simulator-mcp [OPTIONS]
231
+
232
+ OPTIONS:
233
+ -p, --port <port> Port to listen on (default: 3000)
234
+ --host <host> Host address to bind to (default: 127.0.0.1)
235
+ --allow-only <path> Only allow Flutter projects under this path (default: /Users/)
236
+ --max-sessions <number> Maximum number of concurrent sessions (default: 10)
237
+ --pre-build-script <cmd> Command to run before flutter build/run (e.g., "git pull")
238
+ --post-build-script <cmd> Command to run after flutter build/run completes
239
+ -h, --help Show this help message
240
+ ```
241
+
242
+ ### Environment Variables
243
+
244
+ | Variable | Description | Default |
245
+ |----------|-------------|---------|
246
+ | `PORT` | HTTP server port | `3000` |
247
+ | `HOST` | Server bind address (use `0.0.0.0` for Docker) | `127.0.0.1` |
248
+ | `ALLOW_ONLY` | Path prefix for allowed Flutter projects | `/Users/` |
249
+ | `MAX_SESSIONS` | Maximum number of concurrent sessions | `10` |
250
+ | `PRE_BUILD_SCRIPT` | Command to run before flutter build/run | (none) |
251
+ | `POST_BUILD_SCRIPT` | Command to run after flutter build/run | (none) |
252
+ | `LOG_LEVEL` | Logging verbosity (`debug`, `info`, `warn`, `error`) | `info` |
253
+
254
+ ### Examples
255
+
256
+ ```bash
257
+ # Default (localhost only, /Users/ projects)
258
+ npx docker-flutter-ios-simulator-mcp
259
+
260
+ # Custom port
261
+ npx docker-flutter-ios-simulator-mcp --port 8080
262
+
263
+ # Docker (bind to all interfaces)
264
+ npx docker-flutter-ios-simulator-mcp --host 0.0.0.0
265
+
266
+ # Restrict to specific directory
267
+ npx docker-flutter-ios-simulator-mcp --allow-only /Users/alice/flutter-projects
268
+
269
+ # Allow more concurrent sessions
270
+ npx docker-flutter-ios-simulator-mcp --max-sessions 20
271
+
272
+ # Run git pull before each build
273
+ npx docker-flutter-ios-simulator-mcp --pre-build-script "git pull"
274
+
275
+ # Run commands before and after builds
276
+ npx docker-flutter-ios-simulator-mcp --pre-build-script "git pull" --post-build-script "echo Build complete"
277
+
278
+ # Multiple options
279
+ npx docker-flutter-ios-simulator-mcp --port 8080 --host 0.0.0.0 --allow-only /Users/alice --max-sessions 15
280
+ ```
281
+
282
+ ### Security
283
+
284
+ By default, the server:
285
+ - Binds to `127.0.0.1` (localhost only) for security
286
+ - Only allows Flutter projects under `/Users/` to prevent access to system directories
287
+ - Validates all project paths have a `pubspec.yaml` file
288
+ - Limits concurrent sessions to 10 to prevent resource exhaustion
289
+
290
+ ## Troubleshooting
291
+
292
+ ### "Session not found" errors
293
+ - Sessions are in-memory and lost if the MCP server restarts
294
+ - Create a new session after restarting the server
295
+
296
+ ### "Simulator failed to boot"
297
+ - Check Xcode is installed: `xcode-select -p`
298
+ - Verify simulators are available: `xcrun simctl list devices`
299
+ - Try rebooting: `sudo killall -9 com.apple.CoreSimulator.CoreSimulatorService`
300
+
301
+ ### "Flutter not found"
302
+ - Ensure Flutter is in your PATH: `which flutter`
303
+ - Add to PATH in `~/.zshrc` or `~/.bash_profile`
304
+
305
+ ### "IDB command failed"
306
+ - Verify IDB is installed: `which idb`
307
+ - Check IDB version: `idb --version`
308
+ - Reinstall if needed: `pipx install --force fb-idb`
309
+
310
+ ### Screenshots not appearing
311
+ - Screenshots are returned as images in the MCP response
312
+ - They work automatically with Docker containers (no filesystem needed)
313
+
314
+ ### First Flutter build is slow
315
+ - First build can take 1-2 minutes (normal)
316
+ - Use `flutter_logs` to monitor progress
317
+ - Subsequent builds are much faster with hot reload
318
+
319
+ ## Development
320
+
321
+ ### Run in Development Mode
322
+
323
+ ```bash
324
+ npm run dev # Watch mode with auto-restart
325
+ npm run build # Build TypeScript
326
+ npm test # Run tests
327
+ npm run test:watch # Tests in watch mode
328
+ npm run lint # Check code style
329
+ npm run typecheck # Type checking
330
+ ```
331
+
332
+ ### Project Structure
333
+
334
+ ```
335
+ src/
336
+ ├── index.ts # Entry point & Express server
337
+ ├── server.ts # MCP server setup
338
+ ├── session/ # Session management
339
+ ├── flutter/ # Flutter process control
340
+ ├── simulator/ # iOS Simulator & IDB wrappers
341
+ ├── tools/ # MCP tool definitions
342
+ └── utils/ # Helpers & utilities
343
+ ```
344
+
345
+ ## How It Works
346
+
347
+ 1. **Session-based Isolation**: Each session creates a dedicated iOS Simulator and Flutter process
348
+ 2. **HTTP Transport**: MCP protocol over HTTP (works from Docker containers)
349
+ 3. **Log Buffering**: Flutter output is buffered in memory, retrieved via polling
350
+ 4. **Image Transport**: Screenshots are returned as base64 PNG in MCP responses
351
+ 5. **UI Automation**: Uses Facebook IDB for simulator interaction
352
+
353
+ ## Contributing
354
+
355
+ Contributions welcome! Please:
356
+ 1. Fork the repository
357
+ 2. Create a feature branch
358
+ 3. Run tests: `npm test`
359
+ 4. Submit a pull request
360
+
361
+ ## License
362
+
363
+ MIT
364
+
365
+ ## Links
366
+
367
+ - [MCP Protocol Specification](https://modelcontextprotocol.io/)
368
+ - [Flutter Documentation](https://docs.flutter.dev/)
369
+ - [Facebook IDB](https://fbidb.io/)
370
+ - [Xcode](https://developer.apple.com/xcode/)
@@ -0,0 +1,14 @@
1
+ import { LogEntry } from './types.js';
2
+ export declare class LogBuffer {
3
+ private logs;
4
+ private currentIndex;
5
+ private readonly maxLines;
6
+ constructor(maxLines?: number);
7
+ append(line: string): void;
8
+ getLogs(fromIndex?: number, limit?: number): LogEntry[];
9
+ getNextIndex(): number;
10
+ getTotalLines(): number;
11
+ clear(): void;
12
+ getRecentLines(count: number): string[];
13
+ }
14
+ //# sourceMappingURL=log-buffer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-buffer.d.ts","sourceRoot":"","sources":["../../src/flutter/log-buffer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,qBAAa,SAAS;IACpB,OAAO,CAAC,IAAI,CAAkB;IAC9B,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,QAAQ,SAAO;IAI3B,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAc1B,OAAO,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,KAAK,SAAM,GAAG,QAAQ,EAAE;IAoBpD,YAAY,IAAI,MAAM;IAItB,aAAa,IAAI,MAAM;IAIvB,KAAK,IAAI,IAAI;IAKb,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAIxC"}
@@ -0,0 +1,49 @@
1
+ export class LogBuffer {
2
+ logs = [];
3
+ currentIndex = 0;
4
+ maxLines;
5
+ constructor(maxLines = 1000) {
6
+ this.maxLines = maxLines;
7
+ }
8
+ append(line) {
9
+ const entry = {
10
+ line,
11
+ timestamp: new Date(),
12
+ index: this.currentIndex++,
13
+ };
14
+ this.logs.push(entry);
15
+ if (this.logs.length > this.maxLines) {
16
+ this.logs.shift();
17
+ }
18
+ }
19
+ getLogs(fromIndex, limit = 100) {
20
+ // Validate fromIndex is non-negative
21
+ if (fromIndex !== undefined && fromIndex < 0) {
22
+ throw new Error(`fromIndex must be non-negative, got: ${String(fromIndex)}`);
23
+ }
24
+ // Validate limit is positive
25
+ if (limit <= 0) {
26
+ throw new Error(`limit must be positive, got: ${String(limit)}`);
27
+ }
28
+ let filtered = this.logs;
29
+ if (fromIndex !== undefined) {
30
+ filtered = this.logs.filter((entry) => entry.index >= fromIndex);
31
+ }
32
+ return filtered.slice(0, limit);
33
+ }
34
+ getNextIndex() {
35
+ return this.currentIndex;
36
+ }
37
+ getTotalLines() {
38
+ return this.logs.length;
39
+ }
40
+ clear() {
41
+ this.logs = [];
42
+ this.currentIndex = 0;
43
+ }
44
+ getRecentLines(count) {
45
+ const start = Math.max(0, this.logs.length - count);
46
+ return this.logs.slice(start).map((entry) => entry.line);
47
+ }
48
+ }
49
+ //# sourceMappingURL=log-buffer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-buffer.js","sourceRoot":"","sources":["../../src/flutter/log-buffer.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,SAAS;IACZ,IAAI,GAAe,EAAE,CAAC;IACtB,YAAY,GAAG,CAAC,CAAC;IACR,QAAQ,CAAS;IAElC,YAAY,QAAQ,GAAG,IAAI;QACzB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,MAAM,CAAC,IAAY;QACjB,MAAM,KAAK,GAAa;YACtB,IAAI;YACJ,SAAS,EAAE,IAAI,IAAI,EAAE;YACrB,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE;SAC3B,CAAC;QAEF,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAEtB,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YACrC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;IAED,OAAO,CAAC,SAAkB,EAAE,KAAK,GAAG,GAAG;QACrC,qCAAqC;QACrC,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YAC7C,MAAM,IAAI,KAAK,CAAC,wCAAwC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAC/E,CAAC;QAED,6BAA6B;QAC7B,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,gCAAgC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACnE,CAAC;QAED,IAAI,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC;QAEzB,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5B,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI,SAAS,CAAC,CAAC;QACnE,CAAC;QAED,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,YAAY;QACV,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,aAAa;QACX,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;IAC1B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QACf,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;IACxB,CAAC;IAED,cAAc,CAAC,KAAa;QAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;QACpD,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3D,CAAC;CACF"}
@@ -0,0 +1,30 @@
1
+ import { FlutterProcess, FlutterRunOptions } from './types.js';
2
+ export declare class FlutterProcessManager {
3
+ private process?;
4
+ private flutterProcess?;
5
+ private logBuffer;
6
+ private logSubscribers;
7
+ constructor(maxLogLines?: number);
8
+ start(options: FlutterRunOptions): Promise<FlutterProcess>;
9
+ private handleOutput;
10
+ private detectStatusChanges;
11
+ private handleExit;
12
+ stop(): boolean;
13
+ hotReload(): boolean;
14
+ hotRestart(): boolean;
15
+ kill(signal?: NodeJS.Signals): boolean;
16
+ getStatus(): FlutterProcess | undefined;
17
+ getLogs(fromIndex?: number, limit?: number): {
18
+ logs: Array<{
19
+ line: string;
20
+ timestamp: Date;
21
+ index: number;
22
+ }>;
23
+ nextIndex: number;
24
+ totalLines: number;
25
+ };
26
+ subscribeToLogs(callback: (line: string) => void): () => void;
27
+ clearLogs(): void;
28
+ cleanup(): Promise<void>;
29
+ }
30
+ //# sourceMappingURL=process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/flutter/process.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAI/D,qBAAa,qBAAqB;IAChC,OAAO,CAAC,OAAO,CAAC,CAAiB;IACjC,OAAO,CAAC,cAAc,CAAC,CAAiB;IACxC,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,cAAc,CAA0C;gBAEpD,WAAW,SAAO;IAKxB,KAAK,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC;IAwIhE,OAAO,CAAC,YAAY;IAoBpB,OAAO,CAAC,mBAAmB;IAa3B,OAAO,CAAC,UAAU;IAYlB,IAAI,IAAI,OAAO;IAcf,SAAS,IAAI,OAAO;IAYpB,UAAU,IAAI,OAAO;IAYrB,IAAI,CAAC,MAAM,GAAE,MAAM,CAAC,OAAmB,GAAG,OAAO;IASjD,SAAS,IAAI,cAAc,GAAG,SAAS;IAIvC,OAAO,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG;QAC3C,IAAI,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,IAAI,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC9D,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;KACpB;IASD,eAAe,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI;IAQ7D,SAAS,IAAI,IAAI;IAIX,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CA8B/B"}