react-native-mcp-kit 4.2.0 → 4.2.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.
- package/dist/babel/testIdPlugin/collectHooks.d.ts +13 -0
- package/dist/babel/testIdPlugin/collectHooks.d.ts.map +1 -0
- package/dist/babel/testIdPlugin/collectHooks.js +112 -0
- package/dist/babel/testIdPlugin/collectHooks.js.map +1 -0
- package/dist/babel/testIdPlugin/constants.d.ts +6 -0
- package/dist/babel/testIdPlugin/constants.d.ts.map +1 -0
- package/dist/babel/testIdPlugin/constants.js +49 -0
- package/dist/babel/testIdPlugin/constants.js.map +1 -0
- package/dist/babel/testIdPlugin/helpers.d.ts +7 -0
- package/dist/babel/testIdPlugin/helpers.d.ts.map +1 -0
- package/dist/babel/testIdPlugin/helpers.js +77 -0
- package/dist/babel/testIdPlugin/helpers.js.map +1 -0
- package/dist/babel/testIdPlugin/hocUnwrap.d.ts +4 -0
- package/dist/babel/testIdPlugin/hocUnwrap.d.ts.map +1 -0
- package/dist/babel/testIdPlugin/hocUnwrap.js +94 -0
- package/dist/babel/testIdPlugin/hocUnwrap.js.map +1 -0
- package/dist/babel/{testIdPlugin.d.ts → testIdPlugin/index.d.ts} +1 -1
- package/dist/babel/testIdPlugin/index.d.ts.map +1 -0
- package/dist/babel/testIdPlugin/index.js +205 -0
- package/dist/babel/testIdPlugin/index.js.map +1 -0
- package/dist/babel/testIdPlugin/inject.d.ts +7 -0
- package/dist/babel/testIdPlugin/inject.d.ts.map +1 -0
- package/dist/babel/testIdPlugin/inject.js +86 -0
- package/dist/babel/testIdPlugin/inject.js.map +1 -0
- package/dist/babel/testIdPlugin/types.d.ts +59 -0
- package/dist/babel/testIdPlugin/types.d.ts.map +1 -0
- package/dist/babel/testIdPlugin/types.js +3 -0
- package/dist/babel/testIdPlugin/types.js.map +1 -0
- package/dist/bin/ios-hid +0 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/modules/fiberTree/hooks/extract.d.ts +6 -0
- package/dist/modules/fiberTree/hooks/extract.d.ts.map +1 -0
- package/dist/modules/fiberTree/hooks/extract.js +187 -0
- package/dist/modules/fiberTree/hooks/extract.js.map +1 -0
- package/dist/modules/fiberTree/hooks/flatten.d.ts +4 -0
- package/dist/modules/fiberTree/hooks/flatten.d.ts.map +1 -0
- package/dist/modules/fiberTree/hooks/flatten.js +81 -0
- package/dist/modules/fiberTree/hooks/flatten.js.map +1 -0
- package/dist/modules/fiberTree/hooks/index.d.ts +5 -0
- package/dist/modules/fiberTree/hooks/index.d.ts.map +1 -0
- package/dist/modules/fiberTree/hooks/index.js +10 -0
- package/dist/modules/fiberTree/hooks/index.js.map +1 -0
- package/dist/modules/fiberTree/hooks/options.d.ts +9 -0
- package/dist/modules/fiberTree/hooks/options.d.ts.map +1 -0
- package/dist/modules/fiberTree/hooks/options.js +27 -0
- package/dist/modules/fiberTree/hooks/options.js.map +1 -0
- package/dist/modules/fiberTree/hooks/patterns.d.ts +2 -0
- package/dist/modules/fiberTree/hooks/patterns.d.ts.map +1 -0
- package/dist/modules/fiberTree/hooks/patterns.js +26 -0
- package/dist/modules/fiberTree/hooks/patterns.js.map +1 -0
- package/dist/modules/fiberTree/hooks/shape.d.ts +3 -0
- package/dist/modules/fiberTree/hooks/shape.d.ts.map +1 -0
- package/dist/modules/fiberTree/hooks/shape.js +66 -0
- package/dist/modules/fiberTree/hooks/shape.js.map +1 -0
- package/dist/modules/fiberTree/hooks/slotCount.d.ts +2 -0
- package/dist/modules/fiberTree/hooks/slotCount.d.ts.map +1 -0
- package/dist/modules/fiberTree/hooks/slotCount.js +93 -0
- package/dist/modules/fiberTree/hooks/slotCount.js.map +1 -0
- package/dist/modules/fiberTree/{hooks.d.ts → hooks/types.d.ts} +1 -34
- package/dist/modules/fiberTree/hooks/types.d.ts.map +1 -0
- package/dist/modules/fiberTree/hooks/types.js +3 -0
- package/dist/modules/fiberTree/hooks/types.js.map +1 -0
- package/dist/modules/fiberTree/hooks/value.d.ts +2 -0
- package/dist/modules/fiberTree/hooks/value.d.ts.map +1 -0
- package/dist/modules/fiberTree/hooks/value.js +89 -0
- package/dist/modules/fiberTree/hooks/value.js.map +1 -0
- package/dist/modules/fiberTree/utils/constants.d.ts +8 -0
- package/dist/modules/fiberTree/utils/constants.d.ts.map +1 -0
- package/dist/modules/fiberTree/utils/constants.js +15 -0
- package/dist/modules/fiberTree/utils/constants.js.map +1 -0
- package/dist/modules/fiberTree/utils/index.d.ts +9 -0
- package/dist/modules/fiberTree/utils/index.d.ts.map +1 -0
- package/dist/modules/fiberTree/utils/index.js +34 -0
- package/dist/modules/fiberTree/utils/index.js.map +1 -0
- package/dist/modules/fiberTree/utils/match.d.ts +4 -0
- package/dist/modules/fiberTree/utils/match.d.ts.map +1 -0
- package/dist/modules/fiberTree/utils/match.js +169 -0
- package/dist/modules/fiberTree/utils/match.js.map +1 -0
- package/dist/modules/fiberTree/utils/naming.d.ts +4 -0
- package/dist/modules/fiberTree/utils/naming.d.ts.map +1 -0
- package/dist/modules/fiberTree/utils/naming.js +52 -0
- package/dist/modules/fiberTree/utils/naming.js.map +1 -0
- package/dist/modules/fiberTree/utils/native.d.ts +5 -0
- package/dist/modules/fiberTree/utils/native.d.ts.map +1 -0
- package/dist/modules/fiberTree/utils/native.js +101 -0
- package/dist/modules/fiberTree/utils/native.js.map +1 -0
- package/dist/modules/fiberTree/utils/projection.d.ts +9 -0
- package/dist/modules/fiberTree/utils/projection.d.ts.map +1 -0
- package/dist/modules/fiberTree/utils/projection.js +75 -0
- package/dist/modules/fiberTree/utils/projection.js.map +1 -0
- package/dist/modules/fiberTree/utils/root.d.ts +4 -0
- package/dist/modules/fiberTree/utils/root.d.ts.map +1 -0
- package/dist/modules/fiberTree/utils/root.js +30 -0
- package/dist/modules/fiberTree/utils/root.js.map +1 -0
- package/dist/modules/fiberTree/utils/screen.d.ts +10 -0
- package/dist/modules/fiberTree/utils/screen.d.ts.map +1 -0
- package/dist/modules/fiberTree/utils/screen.js +39 -0
- package/dist/modules/fiberTree/utils/screen.js.map +1 -0
- package/dist/modules/fiberTree/utils/serialize.d.ts +4 -0
- package/dist/modules/fiberTree/utils/serialize.d.ts.map +1 -0
- package/dist/modules/fiberTree/utils/serialize.js +102 -0
- package/dist/modules/fiberTree/utils/serialize.js.map +1 -0
- package/dist/modules/fiberTree/utils/traverse.d.ts +12 -0
- package/dist/modules/fiberTree/utils/traverse.d.ts.map +1 -0
- package/dist/modules/fiberTree/utils/traverse.js +107 -0
- package/dist/modules/fiberTree/utils/traverse.js.map +1 -0
- package/dist/server/dispatch.d.ts +15 -0
- package/dist/server/dispatch.d.ts.map +1 -0
- package/dist/server/dispatch.js +121 -0
- package/dist/server/dispatch.js.map +1 -0
- package/dist/server/helpers.d.ts +97 -0
- package/dist/server/helpers.d.ts.map +1 -0
- package/dist/server/helpers.js +162 -0
- package/dist/server/helpers.js.map +1 -0
- package/dist/server/host/deviceResolver/byClient.d.ts +5 -0
- package/dist/server/host/deviceResolver/byClient.d.ts.map +1 -0
- package/dist/server/host/deviceResolver/byClient.js +171 -0
- package/dist/server/host/deviceResolver/byClient.js.map +1 -0
- package/dist/server/host/deviceResolver/byId.d.ts +5 -0
- package/dist/server/host/deviceResolver/byId.d.ts.map +1 -0
- package/dist/server/host/deviceResolver/byId.js +81 -0
- package/dist/server/host/deviceResolver/byId.js.map +1 -0
- package/dist/server/host/deviceResolver/enrich.d.ts +5 -0
- package/dist/server/host/deviceResolver/enrich.d.ts.map +1 -0
- package/dist/server/host/deviceResolver/enrich.js +123 -0
- package/dist/server/host/deviceResolver/enrich.js.map +1 -0
- package/dist/server/host/deviceResolver/index.d.ts +13 -0
- package/dist/server/host/deviceResolver/index.d.ts.map +1 -0
- package/dist/server/host/deviceResolver/index.js +65 -0
- package/dist/server/host/deviceResolver/index.js.map +1 -0
- package/dist/server/host/deviceResolver/list.d.ts +10 -0
- package/dist/server/host/deviceResolver/list.d.ts.map +1 -0
- package/dist/server/host/deviceResolver/list.js +119 -0
- package/dist/server/host/deviceResolver/list.js.map +1 -0
- package/dist/server/host/deviceResolver/scan.d.ts +4 -0
- package/dist/server/host/deviceResolver/scan.d.ts.map +1 -0
- package/dist/server/host/deviceResolver/scan.js +102 -0
- package/dist/server/host/deviceResolver/scan.js.map +1 -0
- package/dist/server/host/{deviceResolver.d.ts → deviceResolver/types.d.ts} +1 -16
- package/dist/server/host/deviceResolver/types.d.ts.map +1 -0
- package/dist/server/host/deviceResolver/types.js +3 -0
- package/dist/server/host/deviceResolver/types.js.map +1 -0
- package/dist/server/host/tools/input/android.d.ts +15 -0
- package/dist/server/host/tools/input/android.d.ts.map +1 -0
- package/dist/server/host/tools/input/android.js +88 -0
- package/dist/server/host/tools/input/android.js.map +1 -0
- package/dist/server/host/tools/input/constants.d.ts +14 -0
- package/dist/server/host/tools/input/constants.d.ts.map +1 -0
- package/dist/server/host/tools/input/constants.js +41 -0
- package/dist/server/host/tools/input/constants.js.map +1 -0
- package/dist/server/host/tools/input/drag.d.ts +4 -0
- package/dist/server/host/tools/input/drag.d.ts.map +1 -0
- package/dist/server/host/tools/input/drag.js +76 -0
- package/dist/server/host/tools/input/drag.js.map +1 -0
- package/dist/server/host/tools/input/index.d.ts +8 -0
- package/dist/server/host/tools/input/index.d.ts.map +1 -0
- package/dist/server/host/tools/input/index.js +18 -0
- package/dist/server/host/tools/input/index.js.map +1 -0
- package/dist/server/host/tools/input/longPress.d.ts +4 -0
- package/dist/server/host/tools/input/longPress.d.ts.map +1 -0
- package/dist/server/host/tools/input/longPress.js +49 -0
- package/dist/server/host/tools/input/longPress.js.map +1 -0
- package/dist/server/host/tools/input/pressKey.d.ts +4 -0
- package/dist/server/host/tools/input/pressKey.d.ts.map +1 -0
- package/dist/server/host/tools/input/pressKey.js +42 -0
- package/dist/server/host/tools/input/pressKey.js.map +1 -0
- package/dist/server/host/tools/input/swipe.d.ts +4 -0
- package/dist/server/host/tools/input/swipe.d.ts.map +1 -0
- package/dist/server/host/tools/input/swipe.js +71 -0
- package/dist/server/host/tools/input/swipe.js.map +1 -0
- package/dist/server/host/tools/input/tap.d.ts +4 -0
- package/dist/server/host/tools/input/tap.d.ts.map +1 -0
- package/dist/server/host/tools/input/tap.js +49 -0
- package/dist/server/host/tools/input/tap.js.map +1 -0
- package/dist/server/host/tools/input/typeText.d.ts +4 -0
- package/dist/server/host/tools/input/typeText.d.ts.map +1 -0
- package/dist/server/host/tools/input/typeText.js +52 -0
- package/dist/server/host/tools/input/typeText.js.map +1 -0
- package/dist/server/host/tools/input/typeTextBatch.d.ts +4 -0
- package/dist/server/host/tools/input/typeTextBatch.d.ts.map +1 -0
- package/dist/server/host/tools/input/typeTextBatch.js +106 -0
- package/dist/server/host/tools/input/typeTextBatch.js.map +1 -0
- package/dist/server/instructions.d.ts +2 -0
- package/dist/server/instructions.d.ts.map +1 -0
- package/dist/server/instructions.js +74 -0
- package/dist/server/instructions.js.map +1 -0
- package/dist/server/mcpServer.d.ts +0 -12
- package/dist/server/mcpServer.d.ts.map +1 -1
- package/dist/server/mcpServer.js +26 -877
- package/dist/server/mcpServer.js.map +1 -1
- package/dist/server/predicate.d.ts +31 -0
- package/dist/server/predicate.d.ts.map +1 -0
- package/dist/server/predicate.js +104 -0
- package/dist/server/predicate.js.map +1 -0
- package/dist/server/tools/assert.d.ts +4 -0
- package/dist/server/tools/assert.d.ts.map +1 -0
- package/dist/server/tools/assert.js +79 -0
- package/dist/server/tools/assert.js.map +1 -0
- package/dist/server/tools/call.d.ts +4 -0
- package/dist/server/tools/call.d.ts.map +1 -0
- package/dist/server/tools/call.js +38 -0
- package/dist/server/tools/call.js.map +1 -0
- package/dist/server/tools/connectionStatus.d.ts +4 -0
- package/dist/server/tools/connectionStatus.d.ts.map +1 -0
- package/dist/server/tools/connectionStatus.js +41 -0
- package/dist/server/tools/connectionStatus.js.map +1 -0
- package/dist/server/tools/describeTool.d.ts +4 -0
- package/dist/server/tools/describeTool.d.ts.map +1 -0
- package/dist/server/tools/describeTool.js +130 -0
- package/dist/server/tools/describeTool.js.map +1 -0
- package/dist/server/tools/listTools.d.ts +4 -0
- package/dist/server/tools/listTools.d.ts.map +1 -0
- package/dist/server/tools/listTools.js +109 -0
- package/dist/server/tools/listTools.js.map +1 -0
- package/dist/server/tools/waitUntil.d.ts +4 -0
- package/dist/server/tools/waitUntil.d.ts.map +1 -0
- package/dist/server/tools/waitUntil.js +119 -0
- package/dist/server/tools/waitUntil.js.map +1 -0
- package/package.json +2 -2
- package/dist/babel/testIdPlugin.d.ts.map +0 -1
- package/dist/babel/testIdPlugin.js +0 -585
- package/dist/babel/testIdPlugin.js.map +0 -1
- package/dist/modules/fiberTree/hooks.d.ts.map +0 -1
- package/dist/modules/fiberTree/hooks.js +0 -550
- package/dist/modules/fiberTree/hooks.js.map +0 -1
- package/dist/modules/fiberTree/utils.d.ts +0 -39
- package/dist/modules/fiberTree/utils.d.ts.map +0 -1
- package/dist/modules/fiberTree/utils.js +0 -641
- package/dist/modules/fiberTree/utils.js.map +0 -1
- package/dist/server/host/deviceResolver.d.ts.map +0 -1
- package/dist/server/host/deviceResolver.js +0 -621
- package/dist/server/host/deviceResolver.js.map +0 -1
- package/dist/server/host/tools/input.d.ts +0 -10
- package/dist/server/host/tools/input.d.ts.map +0 -1
- package/dist/server/host/tools/input.js +0 -503
- package/dist/server/host/tools/input.js.map +0 -1
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.serializeFiber = exports.getTextContent = void 0;
|
|
4
|
+
const constants_1 = require("./constants");
|
|
5
|
+
const naming_1 = require("./naming");
|
|
6
|
+
const getTextContent = (fiber) => {
|
|
7
|
+
if (fiber.tag === constants_1.HOST_TEXT) {
|
|
8
|
+
return fiber.memoizedProps;
|
|
9
|
+
}
|
|
10
|
+
// Check children for text
|
|
11
|
+
let text = '';
|
|
12
|
+
let child = fiber.child;
|
|
13
|
+
while (child) {
|
|
14
|
+
if (child.tag === constants_1.HOST_TEXT && typeof child.memoizedProps === 'string') {
|
|
15
|
+
text += child.memoizedProps;
|
|
16
|
+
}
|
|
17
|
+
child = child.sibling;
|
|
18
|
+
}
|
|
19
|
+
return text || undefined;
|
|
20
|
+
};
|
|
21
|
+
exports.getTextContent = getTextContent;
|
|
22
|
+
// Host components that are just native mirrors of composite wrappers (e.g. RCTView for View)
|
|
23
|
+
const HOST_PASSTHROUGH = new Set(['RCTView', 'RCTText', 'RCTScrollView', 'RCTSafeAreaView']);
|
|
24
|
+
const shouldSkipFiber = (fiber) => {
|
|
25
|
+
const componentType = (0, naming_1.getComponentType)(fiber);
|
|
26
|
+
// Skip internal React wrapper nodes (providers, contexts, etc.)
|
|
27
|
+
if (componentType === 'other' && fiber.tag !== constants_1.HOST_TEXT)
|
|
28
|
+
return true;
|
|
29
|
+
// Skip native host mirrors — their composite parent already represents the same component
|
|
30
|
+
if (componentType === 'host' && HOST_PASSTHROUGH.has((0, naming_1.getComponentName)(fiber)))
|
|
31
|
+
return true;
|
|
32
|
+
return false;
|
|
33
|
+
};
|
|
34
|
+
const collectChildren = (fiber, maxDepth, currentDepth) => {
|
|
35
|
+
const children = [];
|
|
36
|
+
let child = fiber.child;
|
|
37
|
+
while (child) {
|
|
38
|
+
if (shouldSkipFiber(child)) {
|
|
39
|
+
// Skip this node but collect its children at the same depth
|
|
40
|
+
children.push(...collectChildren(child, maxDepth, currentDepth));
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
const serialized = (0, exports.serializeFiber)(child, maxDepth, currentDepth + 1);
|
|
44
|
+
if (serialized) {
|
|
45
|
+
children.push(serialized);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
child = child.sibling;
|
|
49
|
+
}
|
|
50
|
+
return children;
|
|
51
|
+
};
|
|
52
|
+
const serializeFiberUnsafe = (fiber, maxDepth, currentDepth) => {
|
|
53
|
+
if (shouldSkipFiber(fiber)) {
|
|
54
|
+
const children = collectChildren(fiber, maxDepth, currentDepth);
|
|
55
|
+
if (children.length === 1)
|
|
56
|
+
return children[0];
|
|
57
|
+
if (children.length > 1) {
|
|
58
|
+
return {
|
|
59
|
+
children,
|
|
60
|
+
name: 'Fragment',
|
|
61
|
+
props: {},
|
|
62
|
+
type: 'other',
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
const name = (0, naming_1.getComponentName)(fiber);
|
|
68
|
+
// Pass raw memoizedProps through — handler-level `applyProjection` runs the
|
|
69
|
+
// single canonical projectValue walk on the final response, including this
|
|
70
|
+
// tree. Projecting here would cause double-projection and break path drill.
|
|
71
|
+
const props = (fiber.memoizedProps ?? {});
|
|
72
|
+
const mcpId = fiber.memoizedProps?.['data-mcp-id'];
|
|
73
|
+
const testID = fiber.memoizedProps?.testID;
|
|
74
|
+
const text = (0, exports.getTextContent)(fiber);
|
|
75
|
+
const children = collectChildren(fiber, maxDepth, currentDepth);
|
|
76
|
+
return {
|
|
77
|
+
children,
|
|
78
|
+
mcpId,
|
|
79
|
+
name,
|
|
80
|
+
props,
|
|
81
|
+
testID,
|
|
82
|
+
text,
|
|
83
|
+
type: (0, naming_1.getComponentType)(fiber),
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
const serializeFiber = (fiber, maxDepth, currentDepth = 0) => {
|
|
87
|
+
if (!fiber || currentDepth > maxDepth)
|
|
88
|
+
return null;
|
|
89
|
+
try {
|
|
90
|
+
return serializeFiberUnsafe(fiber, maxDepth, currentDepth);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return {
|
|
94
|
+
children: [],
|
|
95
|
+
name: (0, naming_1.getComponentName)(fiber),
|
|
96
|
+
props: { __error: 'Failed to serialize' },
|
|
97
|
+
type: (0, naming_1.getComponentType)(fiber),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
exports.serializeFiber = serializeFiber;
|
|
102
|
+
//# sourceMappingURL=serialize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialize.js","sourceRoot":"","sources":["../../../../src/modules/fiberTree/utils/serialize.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Fiber } from '../../../modules/fiberTree/types';
|
|
2
|
+
export declare const findFiber: (root: Fiber, predicate: (fiber: Fiber) => boolean) => Fiber | null;
|
|
3
|
+
export declare const findAllFibers: (root: Fiber, predicate: (fiber: Fiber) => boolean) => Fiber[];
|
|
4
|
+
export declare const findByMcpId: (root: Fiber, mcpId: string) => Fiber | null;
|
|
5
|
+
export declare const findByTestID: (root: Fiber, testID: string) => Fiber | null;
|
|
6
|
+
export declare const findByName: (root: Fiber, name: string) => Fiber | null;
|
|
7
|
+
export declare const findByText: (root: Fiber, text: string) => Fiber | null;
|
|
8
|
+
export declare const getDirectChildren: (fiber: Fiber) => Fiber[];
|
|
9
|
+
export declare const getSiblings: (fiber: Fiber) => Fiber[];
|
|
10
|
+
export declare const getAncestors: (fiber: Fiber) => Fiber[];
|
|
11
|
+
export declare const findHostFiber: (fiber: Fiber) => Fiber | null;
|
|
12
|
+
//# sourceMappingURL=traverse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traverse.d.ts","sourceRoot":"","sources":["../../../../src/modules/fiberTree/utils/traverse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAMvD,eAAO,MAAM,SAAS,SAAU,KAAK,aAAa,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,KAAG,KAAK,GAAG,IAWrF,CAAC;AAEF,eAAO,MAAM,aAAa,SAAU,KAAK,aAAa,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,KAAG,KAAK,EAgBtF,CAAC;AAEF,eAAO,MAAM,WAAW,SAAU,KAAK,SAAS,MAAM,KAAG,KAAK,GAAG,IAIhE,CAAC;AAEF,eAAO,MAAM,YAAY,SAAU,KAAK,UAAU,MAAM,KAAG,KAAK,GAAG,IAIlE,CAAC;AAEF,eAAO,MAAM,UAAU,SAAU,KAAK,QAAQ,MAAM,KAAG,KAAK,GAAG,IAI9D,CAAC;AAEF,eAAO,MAAM,UAAU,SAAU,KAAK,QAAQ,MAAM,KAAG,KAAK,GAAG,IAK9D,CAAC;AAGF,eAAO,MAAM,iBAAiB,UAAW,KAAK,KAAG,KAAK,EAQrD,CAAC;AAGF,eAAO,MAAM,WAAW,UAAW,KAAK,KAAG,KAAK,EAM/C,CAAC;AAGF,eAAO,MAAM,YAAY,UAAW,KAAK,KAAG,KAAK,EAQhD,CAAC;AAGF,eAAO,MAAM,aAAa,UAAW,KAAK,KAAG,KAAK,GAAG,IAUpD,CAAC"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.findHostFiber = exports.getAncestors = exports.getSiblings = exports.getDirectChildren = exports.findByText = exports.findByName = exports.findByTestID = exports.findByMcpId = exports.findAllFibers = exports.findFiber = void 0;
|
|
4
|
+
const constants_1 = require("./constants");
|
|
5
|
+
const naming_1 = require("./naming");
|
|
6
|
+
const serialize_1 = require("./serialize");
|
|
7
|
+
const findFiber = (root, predicate) => {
|
|
8
|
+
if (predicate(root))
|
|
9
|
+
return root;
|
|
10
|
+
let child = root.child;
|
|
11
|
+
while (child) {
|
|
12
|
+
const found = (0, exports.findFiber)(child, predicate);
|
|
13
|
+
if (found)
|
|
14
|
+
return found;
|
|
15
|
+
child = child.sibling;
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
};
|
|
19
|
+
exports.findFiber = findFiber;
|
|
20
|
+
const findAllFibers = (root, predicate) => {
|
|
21
|
+
const results = [];
|
|
22
|
+
const walk = (fiber) => {
|
|
23
|
+
if (predicate(fiber)) {
|
|
24
|
+
results.push(fiber);
|
|
25
|
+
}
|
|
26
|
+
let child = fiber.child;
|
|
27
|
+
while (child) {
|
|
28
|
+
walk(child);
|
|
29
|
+
child = child.sibling;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
walk(root);
|
|
33
|
+
return results;
|
|
34
|
+
};
|
|
35
|
+
exports.findAllFibers = findAllFibers;
|
|
36
|
+
const findByMcpId = (root, mcpId) => {
|
|
37
|
+
return (0, exports.findFiber)(root, (fiber) => {
|
|
38
|
+
return fiber.memoizedProps?.['data-mcp-id'] === mcpId;
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
exports.findByMcpId = findByMcpId;
|
|
42
|
+
const findByTestID = (root, testID) => {
|
|
43
|
+
return (0, exports.findFiber)(root, (fiber) => {
|
|
44
|
+
return fiber.memoizedProps?.testID === testID;
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
exports.findByTestID = findByTestID;
|
|
48
|
+
const findByName = (root, name) => {
|
|
49
|
+
return (0, exports.findFiber)(root, (fiber) => {
|
|
50
|
+
return (0, naming_1.getComponentName)(fiber) === name;
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
exports.findByName = findByName;
|
|
54
|
+
const findByText = (root, text) => {
|
|
55
|
+
return (0, exports.findFiber)(root, (fiber) => {
|
|
56
|
+
const content = (0, serialize_1.getTextContent)(fiber);
|
|
57
|
+
return content !== undefined && content.includes(text);
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
exports.findByText = findByText;
|
|
61
|
+
// Direct children of a fiber (one level down, not descendants).
|
|
62
|
+
const getDirectChildren = (fiber) => {
|
|
63
|
+
const out = [];
|
|
64
|
+
let child = fiber.child;
|
|
65
|
+
while (child) {
|
|
66
|
+
out.push(child);
|
|
67
|
+
child = child.sibling;
|
|
68
|
+
}
|
|
69
|
+
return out;
|
|
70
|
+
};
|
|
71
|
+
exports.getDirectChildren = getDirectChildren;
|
|
72
|
+
// Sibling fibers at the same level, excluding `fiber` itself.
|
|
73
|
+
const getSiblings = (fiber) => {
|
|
74
|
+
const parent = fiber.return;
|
|
75
|
+
if (!parent)
|
|
76
|
+
return [];
|
|
77
|
+
return (0, exports.getDirectChildren)(parent).filter((f) => {
|
|
78
|
+
return f !== fiber;
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
exports.getSiblings = getSiblings;
|
|
82
|
+
// Ancestors walked upward via `fiber.return`, nearest first.
|
|
83
|
+
const getAncestors = (fiber) => {
|
|
84
|
+
const out = [];
|
|
85
|
+
let current = fiber.return;
|
|
86
|
+
while (current) {
|
|
87
|
+
out.push(current);
|
|
88
|
+
current = current.return;
|
|
89
|
+
}
|
|
90
|
+
return out;
|
|
91
|
+
};
|
|
92
|
+
exports.getAncestors = getAncestors;
|
|
93
|
+
// Find the nearest host fiber (native component) from a given fiber.
|
|
94
|
+
const findHostFiber = (fiber) => {
|
|
95
|
+
if (fiber.tag === constants_1.HOST_COMPONENT)
|
|
96
|
+
return fiber;
|
|
97
|
+
let child = fiber.child;
|
|
98
|
+
while (child) {
|
|
99
|
+
const found = (0, exports.findHostFiber)(child);
|
|
100
|
+
if (found)
|
|
101
|
+
return found;
|
|
102
|
+
child = child.sibling;
|
|
103
|
+
}
|
|
104
|
+
return null;
|
|
105
|
+
};
|
|
106
|
+
exports.findHostFiber = findHostFiber;
|
|
107
|
+
//# sourceMappingURL=traverse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traverse.js","sourceRoot":"","sources":["../../../../src/modules/fiberTree/utils/traverse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type Bridge } from './bridge';
|
|
2
|
+
import { type DispatchResult, type HostToolEntry } from './helpers';
|
|
3
|
+
import { type HostModule } from './host/types';
|
|
4
|
+
/**
|
|
5
|
+
* Pre-indexes host tools by full name so dispatch is O(1).
|
|
6
|
+
*/
|
|
7
|
+
export declare const buildHostToolMap: (hostModules: HostModule[]) => Map<string, HostToolEntry>;
|
|
8
|
+
/**
|
|
9
|
+
* Creates the tool dispatcher used by `call`, `wait_until`, `assert`, and host
|
|
10
|
+
* tools that chain (`host__tap_fiber` → `fiber_tree__query` + `host__tap`). The
|
|
11
|
+
* returned function closes over `bridge` + `hostToolMap` so the host context's
|
|
12
|
+
* own `dispatch` callback can re-enter without losing the original clientId.
|
|
13
|
+
*/
|
|
14
|
+
export declare const createDispatcher: (bridge: Bridge, hostToolMap: Map<string, HostToolEntry>) => ((tool: string, args: Record<string, unknown>, clientId?: string) => Promise<DispatchResult>);
|
|
15
|
+
//# sourceMappingURL=dispatch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../src/server/dispatch.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AACpE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C;;GAEG;AACH,eAAO,MAAM,gBAAgB,gBAAiB,UAAU,EAAE,KAAG,GAAG,CAAC,MAAM,EAAE,aAAa,CAcrF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,WACnB,MAAM,eACD,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,KACtC,CAAC,CACF,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,QAAQ,CAAC,EAAE,MAAM,KACd,OAAO,CAAC,cAAc,CAAC,CA8F3B,CAAC"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createDispatcher = exports.buildHostToolMap = void 0;
|
|
4
|
+
const protocol_1 = require("../shared/protocol");
|
|
5
|
+
/**
|
|
6
|
+
* Pre-indexes host tools by full name so dispatch is O(1).
|
|
7
|
+
*/
|
|
8
|
+
const buildHostToolMap = (hostModules) => {
|
|
9
|
+
const map = new Map();
|
|
10
|
+
for (const mod of hostModules) {
|
|
11
|
+
for (const [toolName, tool] of Object.entries(mod.tools)) {
|
|
12
|
+
const fullName = `${mod.name}${protocol_1.MODULE_SEPARATOR}${toolName}`;
|
|
13
|
+
map.set(fullName, {
|
|
14
|
+
handler: tool.handler,
|
|
15
|
+
moduleName: mod.name,
|
|
16
|
+
timeout: tool.timeout,
|
|
17
|
+
toolName,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return map;
|
|
22
|
+
};
|
|
23
|
+
exports.buildHostToolMap = buildHostToolMap;
|
|
24
|
+
/**
|
|
25
|
+
* Creates the tool dispatcher used by `call`, `wait_until`, `assert`, and host
|
|
26
|
+
* tools that chain (`host__tap_fiber` → `fiber_tree__query` + `host__tap`). The
|
|
27
|
+
* returned function closes over `bridge` + `hostToolMap` so the host context's
|
|
28
|
+
* own `dispatch` callback can re-enter without losing the original clientId.
|
|
29
|
+
*/
|
|
30
|
+
const createDispatcher = (bridge, hostToolMap) => {
|
|
31
|
+
const dispatch = async (tool, args, clientId) => {
|
|
32
|
+
const hostEntry = hostToolMap.get(tool);
|
|
33
|
+
if (hostEntry) {
|
|
34
|
+
try {
|
|
35
|
+
const result = await hostEntry.handler(args, {
|
|
36
|
+
bridge,
|
|
37
|
+
dispatch: (nextTool, nextArgs, nextClientId) => {
|
|
38
|
+
return dispatch(nextTool, nextArgs, nextClientId ?? clientId);
|
|
39
|
+
},
|
|
40
|
+
requestedClientId: clientId,
|
|
41
|
+
});
|
|
42
|
+
return { ok: true, result };
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
return { error: `Host tool "${tool}" threw: ${err.message}`, ok: false };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const resolution = bridge.resolveClient(clientId);
|
|
49
|
+
if (!resolution.ok)
|
|
50
|
+
return { error: resolution.error, ok: false };
|
|
51
|
+
const client = resolution.client;
|
|
52
|
+
let mod;
|
|
53
|
+
let moduleName = '';
|
|
54
|
+
let methodName = '';
|
|
55
|
+
for (const m of client.modules) {
|
|
56
|
+
const prefix = `${m.name}${protocol_1.MODULE_SEPARATOR}`;
|
|
57
|
+
if (tool.startsWith(prefix)) {
|
|
58
|
+
mod = m;
|
|
59
|
+
moduleName = m.name;
|
|
60
|
+
methodName = tool.slice(prefix.length);
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (!mod) {
|
|
65
|
+
if (tool.startsWith(protocol_1.DYNAMIC_PREFIX)) {
|
|
66
|
+
moduleName = `${protocol_1.MODULE_SEPARATOR}dynamic`;
|
|
67
|
+
methodName = tool.slice(protocol_1.DYNAMIC_PREFIX.length);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
const idx = tool.indexOf(protocol_1.MODULE_SEPARATOR);
|
|
71
|
+
if (idx <= 0) {
|
|
72
|
+
return {
|
|
73
|
+
error: `Invalid tool name "${tool}". Use "module${protocol_1.MODULE_SEPARATOR}method" format.`,
|
|
74
|
+
ok: false,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
moduleName = tool.slice(0, idx);
|
|
78
|
+
methodName = tool.slice(idx + protocol_1.MODULE_SEPARATOR.length);
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
const result = await bridge.call(client.id, moduleName, methodName, args);
|
|
82
|
+
return { ok: true, result };
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
const allModules = client.modules
|
|
86
|
+
.map((m) => {
|
|
87
|
+
return m.name;
|
|
88
|
+
})
|
|
89
|
+
.join(', ');
|
|
90
|
+
const dynNames = [...client.dynamicTools.keys()].join(', ');
|
|
91
|
+
return {
|
|
92
|
+
error: `Tool "${tool}" not found on client '${client.id}'. Modules: ${allModules || '(none)'}. Dynamic: ${dynNames || '(none)'}`,
|
|
93
|
+
ok: false,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const toolDef = mod.tools.find((t) => {
|
|
98
|
+
return t.name === methodName;
|
|
99
|
+
});
|
|
100
|
+
if (!toolDef) {
|
|
101
|
+
return {
|
|
102
|
+
error: `Tool "${methodName}" not found in module "${moduleName}" on client '${client.id}'. Available: ${mod.tools
|
|
103
|
+
.map((t) => {
|
|
104
|
+
return t.name;
|
|
105
|
+
})
|
|
106
|
+
.join(', ')}`,
|
|
107
|
+
ok: false,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
const result = await bridge.call(client.id, moduleName, methodName, args, toolDef.timeout);
|
|
112
|
+
return { ok: true, result };
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
return { error: err.message, ok: false };
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
return dispatch;
|
|
119
|
+
};
|
|
120
|
+
exports.createDispatcher = createDispatcher;
|
|
121
|
+
//# sourceMappingURL=dispatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../../src/server/dispatch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { type Bridge, type ClientEntry } from './bridge';
|
|
2
|
+
import { type HostModule, type HostToolHandler } from './host/types';
|
|
3
|
+
export type TextContent = {
|
|
4
|
+
text: string;
|
|
5
|
+
type: 'text';
|
|
6
|
+
};
|
|
7
|
+
export type ImageContent = {
|
|
8
|
+
data: string;
|
|
9
|
+
mimeType: string;
|
|
10
|
+
type: 'image';
|
|
11
|
+
};
|
|
12
|
+
export interface HostToolEntry {
|
|
13
|
+
handler: HostToolHandler['handler'];
|
|
14
|
+
moduleName: string;
|
|
15
|
+
toolName: string;
|
|
16
|
+
timeout?: number;
|
|
17
|
+
}
|
|
18
|
+
export interface ToolDescriptorShape {
|
|
19
|
+
description: string;
|
|
20
|
+
name: string;
|
|
21
|
+
inputSchema?: Record<string, unknown>;
|
|
22
|
+
}
|
|
23
|
+
export interface ToolGroup {
|
|
24
|
+
description: string | undefined;
|
|
25
|
+
module: string;
|
|
26
|
+
tools: Array<{
|
|
27
|
+
description: string;
|
|
28
|
+
name: string;
|
|
29
|
+
inputSchema?: Record<string, unknown>;
|
|
30
|
+
}>;
|
|
31
|
+
}
|
|
32
|
+
export type DispatchResult = {
|
|
33
|
+
ok: true;
|
|
34
|
+
result: unknown;
|
|
35
|
+
} | {
|
|
36
|
+
error: string;
|
|
37
|
+
ok: false;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Shared state passed to every MCP tool registration in `src/server/tools/`.
|
|
41
|
+
* The McpServerWrapper constructs one and hands it to each `register<Tool>`
|
|
42
|
+
* function so the tool files stay decoupled from the class.
|
|
43
|
+
*/
|
|
44
|
+
export interface ServerContext {
|
|
45
|
+
bridge: Bridge;
|
|
46
|
+
dispatchTool: (tool: string, args: Record<string, unknown>, clientId?: string) => Promise<DispatchResult>;
|
|
47
|
+
formatResult: (result: unknown) => Array<TextContent | ImageContent>;
|
|
48
|
+
hostModules: HostModule[];
|
|
49
|
+
hostToolMap: Map<string, HostToolEntry>;
|
|
50
|
+
listToolGroups: (client: ClientEntry) => ToolGroup[];
|
|
51
|
+
}
|
|
52
|
+
export declare const jsonError: (msg: string) => {
|
|
53
|
+
content: TextContent[];
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Parse a `call`-style args argument that may arrive as a JSON string (older
|
|
57
|
+
* clients) or a plain object (new form). Returns { ok, args } or { ok: false,
|
|
58
|
+
* error } on malformed JSON.
|
|
59
|
+
*/
|
|
60
|
+
export declare const parseCallArgs: (raw: unknown) => {
|
|
61
|
+
args: Record<string, unknown>;
|
|
62
|
+
ok: true;
|
|
63
|
+
} | {
|
|
64
|
+
error: string;
|
|
65
|
+
ok: false;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Recursively serializes a value to JSON with sorted object keys, producing a
|
|
69
|
+
* stable canonical form that's safe to use as a dedup Map key. Arrays keep
|
|
70
|
+
* their original order — caller is responsible for normalizing them when
|
|
71
|
+
* order-independence is desired.
|
|
72
|
+
*/
|
|
73
|
+
export declare const canonicalize: (value: unknown) => string;
|
|
74
|
+
/**
|
|
75
|
+
* Produces a canonical key for a ToolGroup that's independent of tool
|
|
76
|
+
* registration order. Two modules with the same name + tools (regardless of
|
|
77
|
+
* order) + descriptions + schemas produce the same key.
|
|
78
|
+
*/
|
|
79
|
+
export declare const canonicalizeGroup: (group: ToolGroup) => string;
|
|
80
|
+
/**
|
|
81
|
+
* Looks up a full tool descriptor on a client by its full name
|
|
82
|
+
* (`module__method`). Checks both static modules and dynamic tools registered
|
|
83
|
+
* via useMcpTool. Returns null if the tool is not on this client.
|
|
84
|
+
*/
|
|
85
|
+
export declare const findToolInClient: (client: ClientEntry, toolFullName: string) => ToolDescriptorShape | null;
|
|
86
|
+
/**
|
|
87
|
+
* Builds the per-client list of ToolGroup entries that `list_tools` deduplicates
|
|
88
|
+
* across clients. Static modules are passed through; dynamic tools are grouped
|
|
89
|
+
* under a synthetic `<module> (dynamic)` group per source module.
|
|
90
|
+
*/
|
|
91
|
+
export declare const buildToolGroups: (client: ClientEntry) => ToolGroup[];
|
|
92
|
+
/**
|
|
93
|
+
* Detects image-content payloads (from host__screenshot) and passes them
|
|
94
|
+
* through as MCP image blocks; everything else is JSON-serialized text.
|
|
95
|
+
*/
|
|
96
|
+
export declare const formatResult: (result: unknown) => Array<TextContent | ImageContent>;
|
|
97
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/server/helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatResult = exports.buildToolGroups = exports.findToolInClient = exports.canonicalizeGroup = exports.canonicalize = exports.parseCallArgs = exports.jsonError = void 0;
|
|
4
|
+
const protocol_1 = require("../shared/protocol");
|
|
5
|
+
const jsonError = (msg) => {
|
|
6
|
+
return {
|
|
7
|
+
content: [{ text: JSON.stringify({ error: msg }), type: 'text' }],
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
exports.jsonError = jsonError;
|
|
11
|
+
/**
|
|
12
|
+
* Parse a `call`-style args argument that may arrive as a JSON string (older
|
|
13
|
+
* clients) or a plain object (new form). Returns { ok, args } or { ok: false,
|
|
14
|
+
* error } on malformed JSON.
|
|
15
|
+
*/
|
|
16
|
+
const parseCallArgs = (raw) => {
|
|
17
|
+
if (raw === undefined || raw === null)
|
|
18
|
+
return { args: {}, ok: true };
|
|
19
|
+
if (typeof raw === 'string') {
|
|
20
|
+
if (raw.length === 0)
|
|
21
|
+
return { args: {}, ok: true };
|
|
22
|
+
try {
|
|
23
|
+
const parsed = JSON.parse(raw);
|
|
24
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
25
|
+
return { args: parsed, ok: true };
|
|
26
|
+
}
|
|
27
|
+
return { error: 'Parsed args must be an object.', ok: false };
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return { error: 'Invalid JSON in args.', ok: false };
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (typeof raw === 'object' && !Array.isArray(raw)) {
|
|
34
|
+
return { args: raw, ok: true };
|
|
35
|
+
}
|
|
36
|
+
return { error: 'args must be an object or a JSON string.', ok: false };
|
|
37
|
+
};
|
|
38
|
+
exports.parseCallArgs = parseCallArgs;
|
|
39
|
+
/**
|
|
40
|
+
* Recursively serializes a value to JSON with sorted object keys, producing a
|
|
41
|
+
* stable canonical form that's safe to use as a dedup Map key. Arrays keep
|
|
42
|
+
* their original order — caller is responsible for normalizing them when
|
|
43
|
+
* order-independence is desired.
|
|
44
|
+
*/
|
|
45
|
+
const canonicalize = (value) => {
|
|
46
|
+
return JSON.stringify(value, (_key, v) => {
|
|
47
|
+
if (v && typeof v === 'object' && !Array.isArray(v)) {
|
|
48
|
+
const sorted = {};
|
|
49
|
+
for (const k of Object.keys(v).sort()) {
|
|
50
|
+
sorted[k] = v[k];
|
|
51
|
+
}
|
|
52
|
+
return sorted;
|
|
53
|
+
}
|
|
54
|
+
return v;
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
exports.canonicalize = canonicalize;
|
|
58
|
+
/**
|
|
59
|
+
* Produces a canonical key for a ToolGroup that's independent of tool
|
|
60
|
+
* registration order. Two modules with the same name + tools (regardless of
|
|
61
|
+
* order) + descriptions + schemas produce the same key.
|
|
62
|
+
*/
|
|
63
|
+
const canonicalizeGroup = (group) => {
|
|
64
|
+
const normalized = {
|
|
65
|
+
description: group.description,
|
|
66
|
+
module: group.module,
|
|
67
|
+
tools: [...group.tools].sort((a, b) => {
|
|
68
|
+
return a.name.localeCompare(b.name);
|
|
69
|
+
}),
|
|
70
|
+
};
|
|
71
|
+
return (0, exports.canonicalize)(normalized);
|
|
72
|
+
};
|
|
73
|
+
exports.canonicalizeGroup = canonicalizeGroup;
|
|
74
|
+
/**
|
|
75
|
+
* Looks up a full tool descriptor on a client by its full name
|
|
76
|
+
* (`module__method`). Checks both static modules and dynamic tools registered
|
|
77
|
+
* via useMcpTool. Returns null if the tool is not on this client.
|
|
78
|
+
*/
|
|
79
|
+
const findToolInClient = (client, toolFullName) => {
|
|
80
|
+
for (const mod of client.modules) {
|
|
81
|
+
const prefix = `${mod.name}${protocol_1.MODULE_SEPARATOR}`;
|
|
82
|
+
if (toolFullName.startsWith(prefix)) {
|
|
83
|
+
const methodName = toolFullName.slice(prefix.length);
|
|
84
|
+
const toolDef = mod.tools.find((t) => {
|
|
85
|
+
return t.name === methodName;
|
|
86
|
+
});
|
|
87
|
+
if (toolDef) {
|
|
88
|
+
return {
|
|
89
|
+
description: toolDef.description,
|
|
90
|
+
inputSchema: toolDef.inputSchema,
|
|
91
|
+
name: toolFullName,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const dynamicEntry = client.dynamicTools.get(toolFullName);
|
|
97
|
+
if (dynamicEntry) {
|
|
98
|
+
return {
|
|
99
|
+
description: dynamicEntry.description,
|
|
100
|
+
inputSchema: dynamicEntry.inputSchema,
|
|
101
|
+
name: toolFullName,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
return null;
|
|
105
|
+
};
|
|
106
|
+
exports.findToolInClient = findToolInClient;
|
|
107
|
+
/**
|
|
108
|
+
* Builds the per-client list of ToolGroup entries that `list_tools` deduplicates
|
|
109
|
+
* across clients. Static modules are passed through; dynamic tools are grouped
|
|
110
|
+
* under a synthetic `<module> (dynamic)` group per source module.
|
|
111
|
+
*/
|
|
112
|
+
const buildToolGroups = (client) => {
|
|
113
|
+
const groups = client.modules.map((mod) => {
|
|
114
|
+
return {
|
|
115
|
+
description: mod.description,
|
|
116
|
+
module: mod.name,
|
|
117
|
+
tools: mod.tools.map((t) => {
|
|
118
|
+
return {
|
|
119
|
+
description: t.description,
|
|
120
|
+
inputSchema: t.inputSchema,
|
|
121
|
+
name: `${mod.name}${protocol_1.MODULE_SEPARATOR}${t.name}`,
|
|
122
|
+
};
|
|
123
|
+
}),
|
|
124
|
+
};
|
|
125
|
+
});
|
|
126
|
+
if (client.dynamicTools.size > 0) {
|
|
127
|
+
const dynamicByModule = new Map();
|
|
128
|
+
for (const [fullName, info] of client.dynamicTools) {
|
|
129
|
+
const existing = dynamicByModule.get(info.module) ?? [];
|
|
130
|
+
existing.push({
|
|
131
|
+
description: info.description,
|
|
132
|
+
inputSchema: info.inputSchema,
|
|
133
|
+
name: fullName,
|
|
134
|
+
});
|
|
135
|
+
dynamicByModule.set(info.module, existing);
|
|
136
|
+
}
|
|
137
|
+
for (const [module, dynTools] of dynamicByModule) {
|
|
138
|
+
groups.push({
|
|
139
|
+
description: 'Dynamically registered tools from useMcpTool hooks',
|
|
140
|
+
module: `${module} (dynamic)`,
|
|
141
|
+
tools: dynTools,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return groups;
|
|
146
|
+
};
|
|
147
|
+
exports.buildToolGroups = buildToolGroups;
|
|
148
|
+
/**
|
|
149
|
+
* Detects image-content payloads (from host__screenshot) and passes them
|
|
150
|
+
* through as MCP image blocks; everything else is JSON-serialized text.
|
|
151
|
+
*/
|
|
152
|
+
const formatResult = (result) => {
|
|
153
|
+
if (Array.isArray(result) && result.length > 0) {
|
|
154
|
+
const first = result[0];
|
|
155
|
+
if (typeof first === 'object' && first !== null && 'type' in first && first.type === 'image') {
|
|
156
|
+
return result;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return [{ text: JSON.stringify(result, null, 2), type: 'text' }];
|
|
160
|
+
};
|
|
161
|
+
exports.formatResult = formatResult;
|
|
162
|
+
//# sourceMappingURL=helpers.js.map
|