@bdayadev/flutter-ultra-mcp 0.0.0 → 1.0.1

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 (58) hide show
  1. package/.claude-plugin/marketplace.json +35 -0
  2. package/.claude-plugin/plugin.json +14 -14
  3. package/.mcp.json +67 -67
  4. package/CODE_OF_CONDUCT.md +83 -83
  5. package/CONTRIBUTING.md +108 -108
  6. package/LICENSE +201 -201
  7. package/README.md +77 -77
  8. package/SECURITY.md +19 -19
  9. package/dart/ultra_flutter/CHANGELOG.md +34 -34
  10. package/dart/ultra_flutter/EXTENSIONS.md +61 -61
  11. package/dart/ultra_flutter/README.md +109 -109
  12. package/dart/ultra_flutter/pubspec.yaml +37 -37
  13. package/dart/ultra_flutter_devtools/README.md +7 -7
  14. package/dart/ultra_flutter_devtools/pubspec.yaml +27 -27
  15. package/docs/UPSTREAM-PATROL-PRS.md +5 -5
  16. package/docs/UPSTREAM-SENTRY-PR.md +62 -62
  17. package/docs/discovery-empirics.md +435 -435
  18. package/examples/counter-app/README.md +24 -24
  19. package/examples/counter-app/pubspec.yaml +23 -23
  20. package/examples/oidc-app/README.md +48 -48
  21. package/examples/oidc-app/pubspec.yaml +24 -24
  22. package/package.json +82 -82
  23. package/packages/flutter-ultra-browser/README.md +29 -29
  24. package/packages/flutter-ultra-browser/package.json +39 -39
  25. package/packages/flutter-ultra-build/README.md +60 -60
  26. package/packages/flutter-ultra-build/package.json +38 -38
  27. package/packages/flutter-ultra-devtools/README.md +7 -7
  28. package/packages/flutter-ultra-devtools/package.json +36 -36
  29. package/packages/flutter-ultra-gesture/README.md +51 -51
  30. package/packages/flutter-ultra-gesture/package.json +58 -58
  31. package/packages/flutter-ultra-native-desktop/README.md +131 -131
  32. package/packages/flutter-ultra-native-desktop/package.json +81 -81
  33. package/packages/flutter-ultra-native-mobile/README.md +103 -103
  34. package/packages/flutter-ultra-native-mobile/package.json +72 -72
  35. package/packages/flutter-ultra-patrol/README.md +40 -40
  36. package/packages/flutter-ultra-patrol/package.json +38 -38
  37. package/packages/flutter-ultra-runtime/README.md +63 -63
  38. package/packages/flutter-ultra-runtime/package.json +69 -69
  39. package/shared/contracts/package.json +31 -31
  40. package/shared/device-router/README.md +51 -51
  41. package/shared/device-router/package.json +62 -62
  42. package/shared/keyring/README.md +7 -7
  43. package/shared/keyring/package.json +24 -24
  44. package/shared/mcp-runtime/README.md +116 -116
  45. package/shared/mcp-runtime/package.json +58 -58
  46. package/shared/state-store/README.md +66 -66
  47. package/shared/state-store/package.json +60 -60
  48. package/shared/vm-service-client/README.md +135 -135
  49. package/shared/vm-service-client/package.json +62 -62
  50. package/skills/_internal-on-tool-failure/SKILL.md +13 -13
  51. package/skills/_internal-session-bootstrap/SKILL.md +18 -18
  52. package/skills/debug/SKILL.md +20 -20
  53. package/skills/devtools/SKILL.md +21 -21
  54. package/skills/drive/SKILL.md +20 -20
  55. package/skills/scaffold/SKILL.md +21 -21
  56. package/skills/setup/SKILL.md +26 -26
  57. package/skills/test/SKILL.md +19 -19
  58. package/skills/tour/SKILL.md +22 -22
@@ -1,66 +1,66 @@
1
- # @flutter-ultra/state-store
2
-
3
- File-based IPC for the flutter-ultra-mcp plugin's 8 servers. Atomic
4
- read-modify-write of JSON state files via [`proper-lockfile`](https://www.npmjs.com/package/proper-lockfile),
5
- plus an append-only JSONL writer for streams (log tails, screencast frames).
6
-
7
- ## Why files, not a daemon
8
-
9
- Each MCP server is a separate process spawned by Claude Code. A daemon would
10
- add another moving part with its own failure surface; the file model means:
11
-
12
- - **No bootstrap order**: servers start independently.
13
- - **Survives restarts**: state persists when a single server crashes and is
14
- re-spawned.
15
- - **Cross-tool inspection**: `cat ${CLAUDE_PLUGIN_DATA}/state/sessions.json`
16
- works as a debugging primitive.
17
-
18
- ## Storage layout
19
-
20
- ```
21
- ${CLAUDE_PLUGIN_DATA}/state/
22
- sessions.json ← runtime server writes, others read
23
- jobs/<jobId>.json ← split-tool job state (build_runner_build, etc.)
24
- streams/<streamId>.jsonl ← append-only event streams (tail_logs, etc.)
25
- locks/ ← proper-lockfile metadata
26
- ```
27
-
28
- `CLAUDE_PLUGIN_DATA` is set by Claude Code; otherwise we fall back to
29
- `%LOCALAPPDATA%/flutter-ultra-mcp` (Windows),
30
- `~/Library/Application Support/flutter-ultra-mcp` (macOS),
31
- `$XDG_DATA_HOME/flutter-ultra-mcp` (Linux).
32
-
33
- ## API
34
-
35
- ```ts
36
- import { stateUpdate, stateRead, sessionsFilePath } from '@flutter-ultra/state-store';
37
- import { SessionsFileSchema, emptySessionsFile } from '@flutter-ultra/mcp-runtime';
38
-
39
- // Read with default fallback
40
- const file = await stateRead(sessionsFilePath(), emptySessionsFile(), SessionsFileSchema);
41
-
42
- // Lock-guarded mutation
43
- await stateUpdate(sessionsFilePath(), emptySessionsFile(), SessionsFileSchema, (current) => ({
44
- ...current,
45
- sessions: [...current.sessions, newSession],
46
- }));
47
- ```
48
-
49
- For continuous streams (log tails):
50
-
51
- ```ts
52
- import { appendJsonl, readJsonl, streamFilePath } from '@flutter-ultra/state-store';
53
-
54
- await appendJsonl(
55
- streamFilePath('s1'),
56
- { ts: Date.now(), level: 'info', msg: '…' },
57
- { maxLines: 10_000 },
58
- );
59
-
60
- // Reader polls with a cursor
61
- const { entries, cursor } = await readJsonl(streamFilePath('s1'), (raw) => raw, /*afterCursor*/ 0);
62
- ```
63
-
64
- ## License
65
-
66
- Apache-2.0. See [LICENSE](../../LICENSE).
1
+ # @flutter-ultra/state-store
2
+
3
+ File-based IPC for the flutter-ultra-mcp plugin's 8 servers. Atomic
4
+ read-modify-write of JSON state files via [`proper-lockfile`](https://www.npmjs.com/package/proper-lockfile),
5
+ plus an append-only JSONL writer for streams (log tails, screencast frames).
6
+
7
+ ## Why files, not a daemon
8
+
9
+ Each MCP server is a separate process spawned by Claude Code. A daemon would
10
+ add another moving part with its own failure surface; the file model means:
11
+
12
+ - **No bootstrap order**: servers start independently.
13
+ - **Survives restarts**: state persists when a single server crashes and is
14
+ re-spawned.
15
+ - **Cross-tool inspection**: `cat ${CLAUDE_PLUGIN_DATA}/state/sessions.json`
16
+ works as a debugging primitive.
17
+
18
+ ## Storage layout
19
+
20
+ ```
21
+ ${CLAUDE_PLUGIN_DATA}/state/
22
+ sessions.json ← runtime server writes, others read
23
+ jobs/<jobId>.json ← split-tool job state (build_runner_build, etc.)
24
+ streams/<streamId>.jsonl ← append-only event streams (tail_logs, etc.)
25
+ locks/ ← proper-lockfile metadata
26
+ ```
27
+
28
+ `CLAUDE_PLUGIN_DATA` is set by Claude Code; otherwise we fall back to
29
+ `%LOCALAPPDATA%/flutter-ultra-mcp` (Windows),
30
+ `~/Library/Application Support/flutter-ultra-mcp` (macOS),
31
+ `$XDG_DATA_HOME/flutter-ultra-mcp` (Linux).
32
+
33
+ ## API
34
+
35
+ ```ts
36
+ import { stateUpdate, stateRead, sessionsFilePath } from '@flutter-ultra/state-store';
37
+ import { SessionsFileSchema, emptySessionsFile } from '@flutter-ultra/mcp-runtime';
38
+
39
+ // Read with default fallback
40
+ const file = await stateRead(sessionsFilePath(), emptySessionsFile(), SessionsFileSchema);
41
+
42
+ // Lock-guarded mutation
43
+ await stateUpdate(sessionsFilePath(), emptySessionsFile(), SessionsFileSchema, (current) => ({
44
+ ...current,
45
+ sessions: [...current.sessions, newSession],
46
+ }));
47
+ ```
48
+
49
+ For continuous streams (log tails):
50
+
51
+ ```ts
52
+ import { appendJsonl, readJsonl, streamFilePath } from '@flutter-ultra/state-store';
53
+
54
+ await appendJsonl(
55
+ streamFilePath('s1'),
56
+ { ts: Date.now(), level: 'info', msg: '…' },
57
+ { maxLines: 10_000 },
58
+ );
59
+
60
+ // Reader polls with a cursor
61
+ const { entries, cursor } = await readJsonl(streamFilePath('s1'), (raw) => raw, /*afterCursor*/ 0);
62
+ ```
63
+
64
+ ## License
65
+
66
+ Apache-2.0. See [LICENSE](../../LICENSE).
@@ -1,60 +1,60 @@
1
- {
2
- "name": "@flutter-ultra/state-store",
3
- "version": "0.0.1",
4
- "private": false,
5
- "description": "File-based IPC for cross-server shared state. Atomic read-modify-write via proper-lockfile.",
6
- "license": "Apache-2.0",
7
- "homepage": "https://github.com/Bdaya-Dev/flutter-ultra-mcp/tree/main/shared/state-store",
8
- "repository": {
9
- "type": "git",
10
- "url": "git+https://github.com/Bdaya-Dev/flutter-ultra-mcp.git",
11
- "directory": "shared/state-store"
12
- },
13
- "bugs": {
14
- "url": "https://github.com/Bdaya-Dev/flutter-ultra-mcp/issues"
15
- },
16
- "keywords": [
17
- "mcp",
18
- "flutter-ultra",
19
- "ipc",
20
- "state"
21
- ],
22
- "type": "module",
23
- "main": "dist/index.js",
24
- "module": "dist/index.js",
25
- "types": "dist/index.d.ts",
26
- "exports": {
27
- ".": {
28
- "types": "./dist/index.d.ts",
29
- "import": "./dist/index.js"
30
- }
31
- },
32
- "sideEffects": false,
33
- "files": [
34
- "dist",
35
- "README.md"
36
- ],
37
- "scripts": {
38
- "build": "tsc -b",
39
- "lint": "eslint src",
40
- "test": "vitest run",
41
- "typecheck": "tsc -b --noEmit",
42
- "clean": "rimraf dist .turbo *.tsbuildinfo"
43
- },
44
- "dependencies": {
45
- "proper-lockfile": "^4.1.2",
46
- "zod": "^3.23.8"
47
- },
48
- "devDependencies": {
49
- "@types/proper-lockfile": "^4.1.4",
50
- "rimraf": "^6.0.0",
51
- "typescript": "^5.6.0",
52
- "vitest": "^2.1.0"
53
- },
54
- "engines": {
55
- "node": ">=20"
56
- },
57
- "publishConfig": {
58
- "access": "public"
59
- }
60
- }
1
+ {
2
+ "name": "@flutter-ultra/state-store",
3
+ "version": "0.0.1",
4
+ "private": true,
5
+ "description": "File-based IPC for cross-server shared state. Atomic read-modify-write via proper-lockfile.",
6
+ "license": "Apache-2.0",
7
+ "homepage": "https://github.com/Bdaya-Dev/flutter-ultra-mcp/tree/main/shared/state-store",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/Bdaya-Dev/flutter-ultra-mcp.git",
11
+ "directory": "shared/state-store"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/Bdaya-Dev/flutter-ultra-mcp/issues"
15
+ },
16
+ "keywords": [
17
+ "mcp",
18
+ "flutter-ultra",
19
+ "ipc",
20
+ "state"
21
+ ],
22
+ "type": "module",
23
+ "main": "dist/index.js",
24
+ "module": "dist/index.js",
25
+ "types": "dist/index.d.ts",
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "import": "./dist/index.js"
30
+ }
31
+ },
32
+ "sideEffects": false,
33
+ "files": [
34
+ "dist",
35
+ "README.md"
36
+ ],
37
+ "scripts": {
38
+ "build": "tsc -b",
39
+ "lint": "eslint src",
40
+ "test": "vitest run",
41
+ "typecheck": "tsc -b --noEmit",
42
+ "clean": "rimraf dist .turbo *.tsbuildinfo"
43
+ },
44
+ "dependencies": {
45
+ "proper-lockfile": "^4.1.2",
46
+ "zod": "^3.23.8"
47
+ },
48
+ "devDependencies": {
49
+ "@types/proper-lockfile": "^4.1.4",
50
+ "rimraf": "^6.0.0",
51
+ "typescript": "^5.6.0",
52
+ "vitest": "^2.1.0"
53
+ },
54
+ "engines": {
55
+ "node": ">=20"
56
+ },
57
+ "publishConfig": {
58
+ "access": "public"
59
+ }
60
+ }
@@ -1,135 +1,135 @@
1
- # @flutter-ultra/vm-service-client
2
-
3
- TypeScript Dart VM Service client with DDS multi-client coordination. Backs the
4
- `flutter-ultra-runtime`, `flutter-ultra-gesture`, `flutter-ultra-devtools`, and
5
- `flutter-ultra-patrol` MCP servers in the [flutter-ultra-mcp](https://github.com/Bdaya-Dev/flutter-ultra-mcp)
6
- plugin.
7
-
8
- Ports the subset of [`package:vm_service`](https://pub.dev/packages/vm_service)
9
- those servers actually call (~15 methods) plus the two DDS extensions that make
10
- coexistence with VS Code's Dart debugger safe.
11
-
12
- ## Install
13
-
14
- ```bash
15
- npm install @flutter-ultra/vm-service-client
16
- ```
17
-
18
- ## Quick start
19
-
20
- ```ts
21
- import { VmServiceClient } from '@flutter-ultra/vm-service-client';
22
-
23
- const client = new VmServiceClient('ws://127.0.0.1:8181/abc/ws', {
24
- // DDS multi-client identity. Format recommendation: flutter-ultra/<server>/<pid>
25
- clientName: `flutter-ultra/runtime/${process.pid}`,
26
- });
27
-
28
- await client.connect();
29
-
30
- const vm = await client.getVM();
31
- console.log(`pid=${vm.pid} isolates=${vm.isolates.length}`);
32
-
33
- await client.streamListen('Logging');
34
- client.on('loggingEvent', (event) => {
35
- console.log('log:', event);
36
- });
37
-
38
- await client.dispose();
39
- ```
40
-
41
- Connection target also accepts `{host, port, ws_path}`:
42
-
43
- ```ts
44
- const client = new VmServiceClient({ host: '127.0.0.1', port: 8181, ws_path: 'abc/ws' });
45
- ```
46
-
47
- ## Ported method surface
48
-
49
- | Group | RPCs |
50
- | ---------------- | ----------------------------------------------------------------------------- |
51
- | Inspection | `getVM`, `getIsolate`, `getObject`, `getFlagList`, `getInstances`, `getStack` |
52
- | Evaluation | `evaluate`, `evaluateInFrame`, `callServiceExtension` |
53
- | Streams | `streamListen`, `streamCancel` |
54
- | Execution | `pause`, `resume`, `setLibraryDebuggable` |
55
- | DDS coordination | `setClientName`, `getStreamHistory` |
56
-
57
- Plus typed event subscriptions:
58
-
59
- - `client.on('isolateEvent' | 'extensionEvent' | 'loggingEvent' | 'stdoutEvent' | 'stderrEvent' | 'vmEvent' | 'debugEvent' | 'serviceEvent' | 'timelineEvent', (event) => …)`
60
- - `for await (const event of client.onIsolateEvent()) { … }` (AsyncIterable)
61
- - Catch-all: `client.on('event', (streamId, event) => …)`
62
-
63
- ## DDS coexistence (plan §7.2)
64
-
65
- The client is designed to share a DDS instance with VS Code's Dart debugger
66
- without conflict. Two rules:
67
-
68
- 1. Always set `clientName` to something unique-per-process. DDS uses the name
69
- to identify cooperating clients for resume coordination.
70
- 2. **Never** call `requirePermissionToResume(...)` — VS Code's debugger must
71
- remain the sole resume authority. This client deliberately does NOT expose
72
- that DDS RPC.
73
-
74
- ## Polymorphic responses
75
-
76
- `evaluate` and `evaluateInFrame` return one of three shapes — narrow on
77
- `result.type`:
78
-
79
- ```ts
80
- const result = await client.evaluate(isolateId, targetId, 'someExpression');
81
- switch (result.type) {
82
- case '@Instance':
83
- console.log('value =', result.valueAsString);
84
- break;
85
- case '@Error':
86
- console.log('eval failed:', result.message);
87
- break;
88
- case 'Sentinel':
89
- console.log('isolate state changed:', result.kind);
90
- break;
91
- }
92
- ```
93
-
94
- `getIsolate` / `getObject` throw `SentinelException` instead of returning a
95
- sentinel union, since the caller almost always wants to re-discover and retry
96
- rather than handle the sentinel inline.
97
-
98
- ## Reconnect
99
-
100
- Auto-reconnect is on by default with exponential backoff
101
- (`[500, 1000, 2000, 4000, 8000, 14500] ms`). Tune via:
102
-
103
- ```ts
104
- new VmServiceClient(uri, {
105
- autoReconnect: true,
106
- reconnectDelaysMs: [500, 1_000, 2_000, 5_000],
107
- });
108
- ```
109
-
110
- Pending in-flight requests reject with `ConnectionDisposedError` on disconnect;
111
- listen for the `disconnect` event on the client (and the `reconnected` event
112
- on `client.transport`) to drive a retry loop in your tool layer.
113
-
114
- ## Error model
115
-
116
- | Class | Thrown on |
117
- | ------------------------- | --------------------------------------------------------------------------------------------- |
118
- | `RpcError` | JSON-RPC error response (carries `code`, `message`, optional `data`, originating method name) |
119
- | `SentinelException` | `getIsolate` / `getObject` got back a `Sentinel` instead of the requested type |
120
- | `ConnectionDisposedError` | Transport closed before the request completed |
121
- | `ConnectionTimeoutError` | WS connect or per-request timeout fired |
122
-
123
- `RpcErrorCode` exports the documented VM service + DDS error codes
124
- (`-32601` `MethodNotFound`, `106` `IsolateMustBePaused`, etc.).
125
-
126
- ## Strict typing
127
-
128
- All response shapes are validated at runtime via Zod (`.strict()` everywhere,
129
- no `z.any()`/`z.record()` in the schema graph), then surfaced as inferred
130
- TypeScript types. Schema drift in the VM service protocol fails loudly rather
131
- than silently corrupting downstream consumers.
132
-
133
- ## License
134
-
135
- Apache-2.0. See [LICENSE](../../LICENSE).
1
+ # @flutter-ultra/vm-service-client
2
+
3
+ TypeScript Dart VM Service client with DDS multi-client coordination. Backs the
4
+ `flutter-ultra-runtime`, `flutter-ultra-gesture`, `flutter-ultra-devtools`, and
5
+ `flutter-ultra-patrol` MCP servers in the [flutter-ultra-mcp](https://github.com/Bdaya-Dev/flutter-ultra-mcp)
6
+ plugin.
7
+
8
+ Ports the subset of [`package:vm_service`](https://pub.dev/packages/vm_service)
9
+ those servers actually call (~15 methods) plus the two DDS extensions that make
10
+ coexistence with VS Code's Dart debugger safe.
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ npm install @flutter-ultra/vm-service-client
16
+ ```
17
+
18
+ ## Quick start
19
+
20
+ ```ts
21
+ import { VmServiceClient } from '@flutter-ultra/vm-service-client';
22
+
23
+ const client = new VmServiceClient('ws://127.0.0.1:8181/abc/ws', {
24
+ // DDS multi-client identity. Format recommendation: flutter-ultra/<server>/<pid>
25
+ clientName: `flutter-ultra/runtime/${process.pid}`,
26
+ });
27
+
28
+ await client.connect();
29
+
30
+ const vm = await client.getVM();
31
+ console.log(`pid=${vm.pid} isolates=${vm.isolates.length}`);
32
+
33
+ await client.streamListen('Logging');
34
+ client.on('loggingEvent', (event) => {
35
+ console.log('log:', event);
36
+ });
37
+
38
+ await client.dispose();
39
+ ```
40
+
41
+ Connection target also accepts `{host, port, ws_path}`:
42
+
43
+ ```ts
44
+ const client = new VmServiceClient({ host: '127.0.0.1', port: 8181, ws_path: 'abc/ws' });
45
+ ```
46
+
47
+ ## Ported method surface
48
+
49
+ | Group | RPCs |
50
+ | ---------------- | ----------------------------------------------------------------------------- |
51
+ | Inspection | `getVM`, `getIsolate`, `getObject`, `getFlagList`, `getInstances`, `getStack` |
52
+ | Evaluation | `evaluate`, `evaluateInFrame`, `callServiceExtension` |
53
+ | Streams | `streamListen`, `streamCancel` |
54
+ | Execution | `pause`, `resume`, `setLibraryDebuggable` |
55
+ | DDS coordination | `setClientName`, `getStreamHistory` |
56
+
57
+ Plus typed event subscriptions:
58
+
59
+ - `client.on('isolateEvent' | 'extensionEvent' | 'loggingEvent' | 'stdoutEvent' | 'stderrEvent' | 'vmEvent' | 'debugEvent' | 'serviceEvent' | 'timelineEvent', (event) => …)`
60
+ - `for await (const event of client.onIsolateEvent()) { … }` (AsyncIterable)
61
+ - Catch-all: `client.on('event', (streamId, event) => …)`
62
+
63
+ ## DDS coexistence (plan §7.2)
64
+
65
+ The client is designed to share a DDS instance with VS Code's Dart debugger
66
+ without conflict. Two rules:
67
+
68
+ 1. Always set `clientName` to something unique-per-process. DDS uses the name
69
+ to identify cooperating clients for resume coordination.
70
+ 2. **Never** call `requirePermissionToResume(...)` — VS Code's debugger must
71
+ remain the sole resume authority. This client deliberately does NOT expose
72
+ that DDS RPC.
73
+
74
+ ## Polymorphic responses
75
+
76
+ `evaluate` and `evaluateInFrame` return one of three shapes — narrow on
77
+ `result.type`:
78
+
79
+ ```ts
80
+ const result = await client.evaluate(isolateId, targetId, 'someExpression');
81
+ switch (result.type) {
82
+ case '@Instance':
83
+ console.log('value =', result.valueAsString);
84
+ break;
85
+ case '@Error':
86
+ console.log('eval failed:', result.message);
87
+ break;
88
+ case 'Sentinel':
89
+ console.log('isolate state changed:', result.kind);
90
+ break;
91
+ }
92
+ ```
93
+
94
+ `getIsolate` / `getObject` throw `SentinelException` instead of returning a
95
+ sentinel union, since the caller almost always wants to re-discover and retry
96
+ rather than handle the sentinel inline.
97
+
98
+ ## Reconnect
99
+
100
+ Auto-reconnect is on by default with exponential backoff
101
+ (`[500, 1000, 2000, 4000, 8000, 14500] ms`). Tune via:
102
+
103
+ ```ts
104
+ new VmServiceClient(uri, {
105
+ autoReconnect: true,
106
+ reconnectDelaysMs: [500, 1_000, 2_000, 5_000],
107
+ });
108
+ ```
109
+
110
+ Pending in-flight requests reject with `ConnectionDisposedError` on disconnect;
111
+ listen for the `disconnect` event on the client (and the `reconnected` event
112
+ on `client.transport`) to drive a retry loop in your tool layer.
113
+
114
+ ## Error model
115
+
116
+ | Class | Thrown on |
117
+ | ------------------------- | --------------------------------------------------------------------------------------------- |
118
+ | `RpcError` | JSON-RPC error response (carries `code`, `message`, optional `data`, originating method name) |
119
+ | `SentinelException` | `getIsolate` / `getObject` got back a `Sentinel` instead of the requested type |
120
+ | `ConnectionDisposedError` | Transport closed before the request completed |
121
+ | `ConnectionTimeoutError` | WS connect or per-request timeout fired |
122
+
123
+ `RpcErrorCode` exports the documented VM service + DDS error codes
124
+ (`-32601` `MethodNotFound`, `106` `IsolateMustBePaused`, etc.).
125
+
126
+ ## Strict typing
127
+
128
+ All response shapes are validated at runtime via Zod (`.strict()` everywhere,
129
+ no `z.any()`/`z.record()` in the schema graph), then surfaced as inferred
130
+ TypeScript types. Schema drift in the VM service protocol fails loudly rather
131
+ than silently corrupting downstream consumers.
132
+
133
+ ## License
134
+
135
+ Apache-2.0. See [LICENSE](../../LICENSE).
@@ -1,62 +1,62 @@
1
- {
2
- "name": "@flutter-ultra/vm-service-client",
3
- "version": "0.0.1",
4
- "private": false,
5
- "description": "TypeScript Dart VM Service client with DDS multi-client coordination. Backs the runtime, gesture, devtools, and patrol MCP servers.",
6
- "license": "Apache-2.0",
7
- "homepage": "https://github.com/Bdaya-Dev/flutter-ultra-mcp/tree/main/shared/vm-service-client",
8
- "repository": {
9
- "type": "git",
10
- "url": "git+https://github.com/Bdaya-Dev/flutter-ultra-mcp.git",
11
- "directory": "shared/vm-service-client"
12
- },
13
- "bugs": {
14
- "url": "https://github.com/Bdaya-Dev/flutter-ultra-mcp/issues"
15
- },
16
- "keywords": [
17
- "dart",
18
- "flutter",
19
- "vm-service",
20
- "dds",
21
- "debugger",
22
- "mcp"
23
- ],
24
- "type": "module",
25
- "main": "dist/index.js",
26
- "module": "dist/index.js",
27
- "types": "dist/index.d.ts",
28
- "exports": {
29
- ".": {
30
- "types": "./dist/index.d.ts",
31
- "import": "./dist/index.js"
32
- }
33
- },
34
- "sideEffects": false,
35
- "files": [
36
- "dist",
37
- "README.md"
38
- ],
39
- "scripts": {
40
- "build": "tsc -b",
41
- "lint": "eslint src",
42
- "test": "vitest run",
43
- "typecheck": "tsc -b --noEmit",
44
- "clean": "rimraf dist .turbo *.tsbuildinfo"
45
- },
46
- "dependencies": {
47
- "ws": "^8.18.0",
48
- "zod": "^3.23.8"
49
- },
50
- "devDependencies": {
51
- "@types/ws": "^8.5.13",
52
- "rimraf": "^6.0.0",
53
- "typescript": "^5.6.0",
54
- "vitest": "^2.1.0"
55
- },
56
- "engines": {
57
- "node": ">=20"
58
- },
59
- "publishConfig": {
60
- "access": "public"
61
- }
62
- }
1
+ {
2
+ "name": "@flutter-ultra/vm-service-client",
3
+ "version": "0.0.1",
4
+ "private": true,
5
+ "description": "TypeScript Dart VM Service client with DDS multi-client coordination. Backs the runtime, gesture, devtools, and patrol MCP servers.",
6
+ "license": "Apache-2.0",
7
+ "homepage": "https://github.com/Bdaya-Dev/flutter-ultra-mcp/tree/main/shared/vm-service-client",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/Bdaya-Dev/flutter-ultra-mcp.git",
11
+ "directory": "shared/vm-service-client"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/Bdaya-Dev/flutter-ultra-mcp/issues"
15
+ },
16
+ "keywords": [
17
+ "dart",
18
+ "flutter",
19
+ "vm-service",
20
+ "dds",
21
+ "debugger",
22
+ "mcp"
23
+ ],
24
+ "type": "module",
25
+ "main": "dist/index.js",
26
+ "module": "dist/index.js",
27
+ "types": "dist/index.d.ts",
28
+ "exports": {
29
+ ".": {
30
+ "types": "./dist/index.d.ts",
31
+ "import": "./dist/index.js"
32
+ }
33
+ },
34
+ "sideEffects": false,
35
+ "files": [
36
+ "dist",
37
+ "README.md"
38
+ ],
39
+ "scripts": {
40
+ "build": "tsc -b",
41
+ "lint": "eslint src",
42
+ "test": "vitest run",
43
+ "typecheck": "tsc -b --noEmit",
44
+ "clean": "rimraf dist .turbo *.tsbuildinfo"
45
+ },
46
+ "dependencies": {
47
+ "ws": "^8.18.0",
48
+ "zod": "^3.23.8"
49
+ },
50
+ "devDependencies": {
51
+ "@types/ws": "^8.5.13",
52
+ "rimraf": "^6.0.0",
53
+ "typescript": "^5.6.0",
54
+ "vitest": "^2.1.0"
55
+ },
56
+ "engines": {
57
+ "node": ">=20"
58
+ },
59
+ "publishConfig": {
60
+ "access": "public"
61
+ }
62
+ }