@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,51 +1,51 @@
1
- # @flutter-ultra/device-router
2
-
3
- Device abstraction for flutter-ultra-mcp: run commands on local, WSL, or SSH-remote targets from a single interface.
4
-
5
- ## Usage
6
-
7
- ```typescript
8
- import { DeviceRouter } from '@flutter-ultra/device-router';
9
-
10
- const router = new DeviceRouter();
11
-
12
- // List available devices (local + WSL distros + SSH hosts)
13
- const devices = await router.listAvailable();
14
-
15
- // Connect to a WSL distro
16
- const { device, probe } = await router.connect({ kind: 'wsl', distro: 'Ubuntu-22.04' });
17
-
18
- // Run a command on the device
19
- const result = await device.exec(['flutter', 'build', 'linux', '--release']);
20
-
21
- // Forward a TCP port from the remote device to local
22
- const fwd = await device.forwardTcpPort('localhost', 8080);
23
- console.log(`VM service available at ws://localhost:${fwd.localPort}/ws`);
24
-
25
- // Clean up
26
- await fwd.close();
27
- await router.disconnect(device.id);
28
- ```
29
-
30
- ## Device types
31
-
32
- | Kind | Transport | Platform | Use case |
33
- | ------- | --------------------- | ----------- | --------------------------------------- |
34
- | `local` | `child_process` | Host OS | Default — same machine |
35
- | `wsl` | `wsl.exe -d <distro>` | Linux | Flutter Linux builds/tests from Windows |
36
- | `ssh` | SSH ControlMaster | Linux/macOS | Flutter macOS builds via remote Mac |
37
-
38
- ## Legacy adapter
39
-
40
- Existing code using worker-J's v1 Device shape (`label/isLocal/exec/uploadFile/fileExists/openRpcStream`) can use the `LegacyDeviceAdapter`:
41
-
42
- ```typescript
43
- import { LegacyDeviceAdapter } from '@flutter-ultra/device-router';
44
-
45
- const legacy = new LegacyDeviceAdapter(device);
46
- // legacy.label, legacy.isLocal, legacy.exec(), legacy.fileExists(), legacy.openRpcStream()
47
- ```
48
-
49
- ## License
50
-
51
- Apache-2.0
1
+ # @flutter-ultra/device-router
2
+
3
+ Device abstraction for flutter-ultra-mcp: run commands on local, WSL, or SSH-remote targets from a single interface.
4
+
5
+ ## Usage
6
+
7
+ ```typescript
8
+ import { DeviceRouter } from '@flutter-ultra/device-router';
9
+
10
+ const router = new DeviceRouter();
11
+
12
+ // List available devices (local + WSL distros + SSH hosts)
13
+ const devices = await router.listAvailable();
14
+
15
+ // Connect to a WSL distro
16
+ const { device, probe } = await router.connect({ kind: 'wsl', distro: 'Ubuntu-22.04' });
17
+
18
+ // Run a command on the device
19
+ const result = await device.exec(['flutter', 'build', 'linux', '--release']);
20
+
21
+ // Forward a TCP port from the remote device to local
22
+ const fwd = await device.forwardTcpPort('localhost', 8080);
23
+ console.log(`VM service available at ws://localhost:${fwd.localPort}/ws`);
24
+
25
+ // Clean up
26
+ await fwd.close();
27
+ await router.disconnect(device.id);
28
+ ```
29
+
30
+ ## Device types
31
+
32
+ | Kind | Transport | Platform | Use case |
33
+ | ------- | --------------------- | ----------- | --------------------------------------- |
34
+ | `local` | `child_process` | Host OS | Default — same machine |
35
+ | `wsl` | `wsl.exe -d <distro>` | Linux | Flutter Linux builds/tests from Windows |
36
+ | `ssh` | SSH ControlMaster | Linux/macOS | Flutter macOS builds via remote Mac |
37
+
38
+ ## Legacy adapter
39
+
40
+ Existing code using worker-J's v1 Device shape (`label/isLocal/exec/uploadFile/fileExists/openRpcStream`) can use the `LegacyDeviceAdapter`:
41
+
42
+ ```typescript
43
+ import { LegacyDeviceAdapter } from '@flutter-ultra/device-router';
44
+
45
+ const legacy = new LegacyDeviceAdapter(device);
46
+ // legacy.label, legacy.isLocal, legacy.exec(), legacy.fileExists(), legacy.openRpcStream()
47
+ ```
48
+
49
+ ## License
50
+
51
+ Apache-2.0
@@ -1,62 +1,62 @@
1
- {
2
- "name": "@flutter-ultra/device-router",
3
- "version": "0.0.1",
4
- "private": false,
5
- "description": "Device abstraction for flutter-ultra-mcp: run commands on local, WSL, or SSH-remote targets from a single interface.",
6
- "license": "Apache-2.0",
7
- "homepage": "https://github.com/Bdaya-Dev/flutter-ultra-mcp/tree/main/shared/device-router",
8
- "repository": {
9
- "type": "git",
10
- "url": "git+https://github.com/Bdaya-Dev/flutter-ultra-mcp.git",
11
- "directory": "shared/device-router"
12
- },
13
- "bugs": {
14
- "url": "https://github.com/Bdaya-Dev/flutter-ultra-mcp/issues"
15
- },
16
- "keywords": [
17
- "flutter",
18
- "mcp",
19
- "device",
20
- "wsl",
21
- "ssh",
22
- "remote"
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
- "execa": "^9.5.1",
48
- "ssh-config": "^5.0.0",
49
- "zod": "^3.25.76"
50
- },
51
- "devDependencies": {
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/device-router",
3
+ "version": "0.0.1",
4
+ "private": true,
5
+ "description": "Device abstraction for flutter-ultra-mcp: run commands on local, WSL, or SSH-remote targets from a single interface.",
6
+ "license": "Apache-2.0",
7
+ "homepage": "https://github.com/Bdaya-Dev/flutter-ultra-mcp/tree/main/shared/device-router",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/Bdaya-Dev/flutter-ultra-mcp.git",
11
+ "directory": "shared/device-router"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/Bdaya-Dev/flutter-ultra-mcp/issues"
15
+ },
16
+ "keywords": [
17
+ "flutter",
18
+ "mcp",
19
+ "device",
20
+ "wsl",
21
+ "ssh",
22
+ "remote"
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
+ "execa": "^9.5.1",
48
+ "ssh-config": "^5.0.0",
49
+ "zod": "^3.25.76"
50
+ },
51
+ "devDependencies": {
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,7 +1,7 @@
1
- # @flutter-ultra/keyring
2
-
3
- OS-keyring-backed secret storage for plugin-managed credentials: signing certs, OIDC tokens, Sentry DSNs.
4
-
5
- **Status:** scaffold stub. Implementation owner: shared infra (wave 2).
6
-
7
- Cross-platform via native APIs — Windows Credential Manager, macOS Keychain, Linux Secret Service. Plain-filesystem fallback is intentionally absent to preserve the plan §19 security guarantee.
1
+ # @flutter-ultra/keyring
2
+
3
+ OS-keyring-backed secret storage for plugin-managed credentials: signing certs, OIDC tokens, Sentry DSNs.
4
+
5
+ **Status:** scaffold stub. Implementation owner: shared infra (wave 2).
6
+
7
+ Cross-platform via native APIs — Windows Credential Manager, macOS Keychain, Linux Secret Service. Plain-filesystem fallback is intentionally absent to preserve the plan §19 security guarantee.
@@ -1,24 +1,24 @@
1
- {
2
- "name": "@flutter-ultra/keyring",
3
- "version": "0.0.0",
4
- "private": true,
5
- "description": "OS-keyring-backed secret storage for plugin-managed credentials (signing certs, OIDC tokens, Sentry DSNs).",
6
- "license": "Apache-2.0",
7
- "type": "module",
8
- "main": "dist/index.js",
9
- "types": "dist/index.d.ts",
10
- "files": [
11
- "dist",
12
- "README.md"
13
- ],
14
- "scripts": {
15
- "build": "tsc -b",
16
- "lint": "eslint src",
17
- "test": "vitest run",
18
- "typecheck": "tsc -b --noEmit",
19
- "clean": "rimraf dist .turbo *.tsbuildinfo"
20
- },
21
- "dependencies": {
22
- "@napi-rs/keyring": "^1.3.0"
23
- }
24
- }
1
+ {
2
+ "name": "@flutter-ultra/keyring",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "description": "OS-keyring-backed secret storage for plugin-managed credentials (signing certs, OIDC tokens, Sentry DSNs).",
6
+ "license": "Apache-2.0",
7
+ "type": "module",
8
+ "main": "dist/index.js",
9
+ "types": "dist/index.d.ts",
10
+ "files": [
11
+ "dist",
12
+ "README.md"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc -b",
16
+ "lint": "eslint src",
17
+ "test": "vitest run",
18
+ "typecheck": "tsc -b --noEmit",
19
+ "clean": "rimraf dist .turbo *.tsbuildinfo"
20
+ },
21
+ "dependencies": {
22
+ "@napi-rs/keyring": "^1.3.0"
23
+ }
24
+ }
@@ -1,116 +1,116 @@
1
- # @flutter-ultra/mcp-runtime
2
-
3
- Shared MCP server scaffolding for the flutter-ultra-mcp plugin's 8 servers.
4
- Encapsulates the recurring patterns — stdio transport boot, Zod-validated
5
- tools, watchdog/timeout enforcement, keep-alive against
6
- [Claude Code #58004](https://github.com/anthropics/claude-code/issues/58004),
7
- the cross-server session model, and the canonical FinderSpec for widget
8
- lookups — so each server's `src/index.ts` stays focused on its tool catalogue.
9
-
10
- ## Quick start
11
-
12
- ```ts
13
- import { createServer } from '@flutter-ultra/mcp-runtime';
14
- import { z } from 'zod';
15
-
16
- const server = createServer({
17
- info: { name: 'flutter-ultra-runtime', version: '0.0.1' },
18
- });
19
-
20
- server.defineTool(
21
- {
22
- name: 'list_sessions',
23
- description: 'List active Flutter sessions attached by this server.',
24
- timeoutClass: 'instant',
25
- annotations: { readOnlyHint: true, idempotentHint: true },
26
- },
27
- async () => ({
28
- sessions: [
29
- /* ... */
30
- ],
31
- }),
32
- );
33
-
34
- server.defineTool(
35
- {
36
- name: 'hot_reload',
37
- description: 'Trigger a hot reload on the given session.',
38
- inputShape: { sessionId: z.string().min(8) },
39
- timeoutClass: 'quick',
40
- ceilingMs: 60_000,
41
- },
42
- async ({ sessionId }, { signal, sendProgress }) => {
43
- sendProgress({ progress: 0, message: 'Sending reloadSources to VM service' });
44
- // ... handler body with signal-aware aborts
45
- return { ok: true, sessionId };
46
- },
47
- );
48
-
49
- await server.start();
50
- process.on('SIGTERM', () => server.stop());
51
- ```
52
-
53
- ## Components
54
-
55
- | Module | Exports |
56
- | -------------- | ------------------------------------------------------------------------------------------------------ |
57
- | `server.ts` | `createServer`, `defineTool` — high-level builder over `@modelcontextprotocol/sdk` |
58
- | `watchdog.ts` | `runWithWatchdog`, `TimeoutClass`, `DEFAULT_CEILINGS_MS` — per-tool hard cap + AbortSignal propagation |
59
- | `keepAlive.ts` | `startKeepAlive` — periodic `notifications/message` debug ping (plan §17.9) |
60
- | `logger.ts` | `createLogger` — JSON-lines stderr logger with per-tool child loggers |
61
- | `session.ts` | `Session`, `SessionResource`, `SessionsFile` — cross-server session model |
62
- | `finder.ts` | `FinderSchema`, `FinderSpec`, `matchesText` — shared discriminated union for widget lookups |
63
- | `errors.ts` | `ToolWatchdogTimeoutError`, `SessionNotFoundError`, etc. |
64
-
65
- ## Timeout classes (plan §17.2)
66
-
67
- | Class | Ceiling | When to use |
68
- | ---------- | ------- | ------------------------------------------------------------------ |
69
- | `instant` | 10 s | < 1 s p95: `list_sessions`, `get_widget_tree` on small trees |
70
- | `quick` | 30 s | 1–5 s p95: `hot_reload`, `screenshot`, `tap` |
71
- | `long` | 55 s | 5–55 s p95: `dump_render_tree`, `wait_for` (always emit progress) |
72
- | `marathon` | 55 s | > 55 s: MUST be split-tool (`start_*` / `poll_*` / `get_*_result`) |
73
-
74
- Per-tool override via env var: `FLUTTER_ULTRA_TOOL_TIMEOUT_<NAME_UPPER>=120000`.
75
-
76
- ## Session model
77
-
78
- Sessions live as JSON in `${CLAUDE_PLUGIN_DATA}/state/sessions.json` (path
79
- resolved by `@flutter-ultra/state-store`). The runtime server is the sole
80
- writer; gesture / devtools / patrol read-only. Each session carries:
81
-
82
- ```
83
- { id, uri, source, clientName, attachedAt, lastSeenAt,
84
- status, pid?, projectRoot?, device?, isolateIds?, appName? }
85
- ```
86
-
87
- `SessionResource<T>` reference-counts an expensive per-session resource
88
- (e.g. the `VmServiceClient` WebSocket) so multiple parallel tool calls
89
- share one connection per plan §17.10.
90
-
91
- ## FinderSpec
92
-
93
- Discriminated union used by both runtime (`widget_exists`, `find_widget`)
94
- and gesture (`tap`, `enter_text`, `wait_for`) so an agent's "is the widget
95
- in the tree?" check uses the exact same matcher as the subsequent tap:
96
-
97
- ```ts
98
- type FinderSpec =
99
- | { kind: 'key'; value: string }
100
- | {
101
- kind: 'text';
102
- value: string;
103
- matchType?: 'exact' | 'contains' | 'regex';
104
- caseInsensitive?: boolean;
105
- }
106
- | { kind: 'type'; value: string }
107
- | { kind: 'coords'; x: number; y: number }
108
- | { kind: 'semanticsLabel'; value: string; matchType?: 'exact' | 'contains' | 'regex' }
109
- | { kind: 'tooltip'; value: string; matchType?: 'exact' | 'contains' | 'regex' };
110
- ```
111
-
112
- `matchesText(candidate, spec)` is the shared comparator both consumers use.
113
-
114
- ## License
115
-
116
- Apache-2.0. See [LICENSE](../../LICENSE).
1
+ # @flutter-ultra/mcp-runtime
2
+
3
+ Shared MCP server scaffolding for the flutter-ultra-mcp plugin's 8 servers.
4
+ Encapsulates the recurring patterns — stdio transport boot, Zod-validated
5
+ tools, watchdog/timeout enforcement, keep-alive against
6
+ [Claude Code #58004](https://github.com/anthropics/claude-code/issues/58004),
7
+ the cross-server session model, and the canonical FinderSpec for widget
8
+ lookups — so each server's `src/index.ts` stays focused on its tool catalogue.
9
+
10
+ ## Quick start
11
+
12
+ ```ts
13
+ import { createServer } from '@flutter-ultra/mcp-runtime';
14
+ import { z } from 'zod';
15
+
16
+ const server = createServer({
17
+ info: { name: 'flutter-ultra-runtime', version: '0.0.1' },
18
+ });
19
+
20
+ server.defineTool(
21
+ {
22
+ name: 'list_sessions',
23
+ description: 'List active Flutter sessions attached by this server.',
24
+ timeoutClass: 'instant',
25
+ annotations: { readOnlyHint: true, idempotentHint: true },
26
+ },
27
+ async () => ({
28
+ sessions: [
29
+ /* ... */
30
+ ],
31
+ }),
32
+ );
33
+
34
+ server.defineTool(
35
+ {
36
+ name: 'hot_reload',
37
+ description: 'Trigger a hot reload on the given session.',
38
+ inputShape: { sessionId: z.string().min(8) },
39
+ timeoutClass: 'quick',
40
+ ceilingMs: 60_000,
41
+ },
42
+ async ({ sessionId }, { signal, sendProgress }) => {
43
+ sendProgress({ progress: 0, message: 'Sending reloadSources to VM service' });
44
+ // ... handler body with signal-aware aborts
45
+ return { ok: true, sessionId };
46
+ },
47
+ );
48
+
49
+ await server.start();
50
+ process.on('SIGTERM', () => server.stop());
51
+ ```
52
+
53
+ ## Components
54
+
55
+ | Module | Exports |
56
+ | -------------- | ------------------------------------------------------------------------------------------------------ |
57
+ | `server.ts` | `createServer`, `defineTool` — high-level builder over `@modelcontextprotocol/sdk` |
58
+ | `watchdog.ts` | `runWithWatchdog`, `TimeoutClass`, `DEFAULT_CEILINGS_MS` — per-tool hard cap + AbortSignal propagation |
59
+ | `keepAlive.ts` | `startKeepAlive` — periodic `notifications/message` debug ping (plan §17.9) |
60
+ | `logger.ts` | `createLogger` — JSON-lines stderr logger with per-tool child loggers |
61
+ | `session.ts` | `Session`, `SessionResource`, `SessionsFile` — cross-server session model |
62
+ | `finder.ts` | `FinderSchema`, `FinderSpec`, `matchesText` — shared discriminated union for widget lookups |
63
+ | `errors.ts` | `ToolWatchdogTimeoutError`, `SessionNotFoundError`, etc. |
64
+
65
+ ## Timeout classes (plan §17.2)
66
+
67
+ | Class | Ceiling | When to use |
68
+ | ---------- | ------- | ------------------------------------------------------------------ |
69
+ | `instant` | 10 s | < 1 s p95: `list_sessions`, `get_widget_tree` on small trees |
70
+ | `quick` | 30 s | 1–5 s p95: `hot_reload`, `screenshot`, `tap` |
71
+ | `long` | 55 s | 5–55 s p95: `dump_render_tree`, `wait_for` (always emit progress) |
72
+ | `marathon` | 55 s | > 55 s: MUST be split-tool (`start_*` / `poll_*` / `get_*_result`) |
73
+
74
+ Per-tool override via env var: `FLUTTER_ULTRA_TOOL_TIMEOUT_<NAME_UPPER>=120000`.
75
+
76
+ ## Session model
77
+
78
+ Sessions live as JSON in `${CLAUDE_PLUGIN_DATA}/state/sessions.json` (path
79
+ resolved by `@flutter-ultra/state-store`). The runtime server is the sole
80
+ writer; gesture / devtools / patrol read-only. Each session carries:
81
+
82
+ ```
83
+ { id, uri, source, clientName, attachedAt, lastSeenAt,
84
+ status, pid?, projectRoot?, device?, isolateIds?, appName? }
85
+ ```
86
+
87
+ `SessionResource<T>` reference-counts an expensive per-session resource
88
+ (e.g. the `VmServiceClient` WebSocket) so multiple parallel tool calls
89
+ share one connection per plan §17.10.
90
+
91
+ ## FinderSpec
92
+
93
+ Discriminated union used by both runtime (`widget_exists`, `find_widget`)
94
+ and gesture (`tap`, `enter_text`, `wait_for`) so an agent's "is the widget
95
+ in the tree?" check uses the exact same matcher as the subsequent tap:
96
+
97
+ ```ts
98
+ type FinderSpec =
99
+ | { kind: 'key'; value: string }
100
+ | {
101
+ kind: 'text';
102
+ value: string;
103
+ matchType?: 'exact' | 'contains' | 'regex';
104
+ caseInsensitive?: boolean;
105
+ }
106
+ | { kind: 'type'; value: string }
107
+ | { kind: 'coords'; x: number; y: number }
108
+ | { kind: 'semanticsLabel'; value: string; matchType?: 'exact' | 'contains' | 'regex' }
109
+ | { kind: 'tooltip'; value: string; matchType?: 'exact' | 'contains' | 'regex' };
110
+ ```
111
+
112
+ `matchesText(candidate, spec)` is the shared comparator both consumers use.
113
+
114
+ ## License
115
+
116
+ Apache-2.0. See [LICENSE](../../LICENSE).
@@ -1,58 +1,58 @@
1
- {
2
- "name": "@flutter-ultra/mcp-runtime",
3
- "version": "0.0.1",
4
- "private": false,
5
- "description": "Shared MCP server scaffolding: stdio transport, watchdog/timeout, structured logging, session model, finder spec.",
6
- "license": "Apache-2.0",
7
- "homepage": "https://github.com/Bdaya-Dev/flutter-ultra-mcp/tree/main/shared/mcp-runtime",
8
- "repository": {
9
- "type": "git",
10
- "url": "git+https://github.com/Bdaya-Dev/flutter-ultra-mcp.git",
11
- "directory": "shared/mcp-runtime"
12
- },
13
- "bugs": {
14
- "url": "https://github.com/Bdaya-Dev/flutter-ultra-mcp/issues"
15
- },
16
- "keywords": [
17
- "mcp",
18
- "model-context-protocol",
19
- "flutter-ultra"
20
- ],
21
- "type": "module",
22
- "main": "dist/index.js",
23
- "module": "dist/index.js",
24
- "types": "dist/index.d.ts",
25
- "exports": {
26
- ".": {
27
- "types": "./dist/index.d.ts",
28
- "import": "./dist/index.js"
29
- }
30
- },
31
- "sideEffects": false,
32
- "files": [
33
- "dist",
34
- "README.md"
35
- ],
36
- "scripts": {
37
- "build": "tsc -b",
38
- "lint": "eslint src",
39
- "test": "vitest run",
40
- "typecheck": "tsc -b --noEmit",
41
- "clean": "rimraf dist .turbo *.tsbuildinfo"
42
- },
43
- "dependencies": {
44
- "@modelcontextprotocol/sdk": "^1.29.0",
45
- "zod": "^3.23.8"
46
- },
47
- "devDependencies": {
48
- "rimraf": "^6.0.0",
49
- "typescript": "^5.6.0",
50
- "vitest": "^2.1.0"
51
- },
52
- "engines": {
53
- "node": ">=20"
54
- },
55
- "publishConfig": {
56
- "access": "public"
57
- }
58
- }
1
+ {
2
+ "name": "@flutter-ultra/mcp-runtime",
3
+ "version": "0.0.1",
4
+ "private": true,
5
+ "description": "Shared MCP server scaffolding: stdio transport, watchdog/timeout, structured logging, session model, finder spec.",
6
+ "license": "Apache-2.0",
7
+ "homepage": "https://github.com/Bdaya-Dev/flutter-ultra-mcp/tree/main/shared/mcp-runtime",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/Bdaya-Dev/flutter-ultra-mcp.git",
11
+ "directory": "shared/mcp-runtime"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/Bdaya-Dev/flutter-ultra-mcp/issues"
15
+ },
16
+ "keywords": [
17
+ "mcp",
18
+ "model-context-protocol",
19
+ "flutter-ultra"
20
+ ],
21
+ "type": "module",
22
+ "main": "dist/index.js",
23
+ "module": "dist/index.js",
24
+ "types": "dist/index.d.ts",
25
+ "exports": {
26
+ ".": {
27
+ "types": "./dist/index.d.ts",
28
+ "import": "./dist/index.js"
29
+ }
30
+ },
31
+ "sideEffects": false,
32
+ "files": [
33
+ "dist",
34
+ "README.md"
35
+ ],
36
+ "scripts": {
37
+ "build": "tsc -b",
38
+ "lint": "eslint src",
39
+ "test": "vitest run",
40
+ "typecheck": "tsc -b --noEmit",
41
+ "clean": "rimraf dist .turbo *.tsbuildinfo"
42
+ },
43
+ "dependencies": {
44
+ "@modelcontextprotocol/sdk": "^1.29.0",
45
+ "zod": "^3.23.8"
46
+ },
47
+ "devDependencies": {
48
+ "rimraf": "^6.0.0",
49
+ "typescript": "^5.6.0",
50
+ "vitest": "^2.1.0"
51
+ },
52
+ "engines": {
53
+ "node": ">=20"
54
+ },
55
+ "publishConfig": {
56
+ "access": "public"
57
+ }
58
+ }