devlens-mcp 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/README.md +45 -37
  2. package/RELEASE_NOTES.md +249 -0
  3. package/dist/bin/cli.js +2 -0
  4. package/dist/bin/cli.js.map +1 -1
  5. package/dist/src/figma/figma-properties.d.ts +88 -0
  6. package/dist/src/figma/figma-properties.d.ts.map +1 -0
  7. package/dist/src/figma/figma-properties.js +121 -0
  8. package/dist/src/figma/figma-properties.js.map +1 -0
  9. package/dist/src/figma/figma-structure.d.ts +43 -0
  10. package/dist/src/figma/figma-structure.d.ts.map +1 -0
  11. package/dist/src/figma/figma-structure.js +74 -0
  12. package/dist/src/figma/figma-structure.js.map +1 -0
  13. package/dist/src/figma/figma-url.d.ts +37 -0
  14. package/dist/src/figma/figma-url.d.ts.map +1 -0
  15. package/dist/src/figma/figma-url.js +68 -0
  16. package/dist/src/figma/figma-url.js.map +1 -0
  17. package/dist/src/jds-tokens/resolve-token.d.ts +2 -0
  18. package/dist/src/jds-tokens/resolve-token.d.ts.map +1 -0
  19. package/dist/src/jds-tokens/resolve-token.js +24 -0
  20. package/dist/src/jds-tokens/resolve-token.js.map +1 -0
  21. package/dist/src/jds-tokens/tokens.d.ts +2 -0
  22. package/dist/src/jds-tokens/tokens.d.ts.map +1 -0
  23. package/dist/src/jds-tokens/tokens.js +12 -0
  24. package/dist/src/jds-tokens/tokens.js.map +1 -0
  25. package/dist/src/platform/ios/ios-device.d.ts +2 -0
  26. package/dist/src/platform/ios/ios-device.d.ts.map +1 -1
  27. package/dist/src/platform/ios/ios-device.js +18 -8
  28. package/dist/src/platform/ios/ios-device.js.map +1 -1
  29. package/dist/src/platform/ios/scale-resolver.d.ts +29 -0
  30. package/dist/src/platform/ios/scale-resolver.d.ts.map +1 -0
  31. package/dist/src/platform/ios/scale-resolver.js +114 -0
  32. package/dist/src/platform/ios/scale-resolver.js.map +1 -0
  33. package/dist/src/platform/ios/simctl.d.ts +5 -0
  34. package/dist/src/platform/ios/simctl.d.ts.map +1 -1
  35. package/dist/src/platform/ios/simctl.js +4 -0
  36. package/dist/src/platform/ios/simctl.js.map +1 -1
  37. package/dist/src/server.d.ts.map +1 -1
  38. package/dist/src/server.js +9 -1
  39. package/dist/src/server.js.map +1 -1
  40. package/dist/src/setup/config-patcher.d.ts +2 -0
  41. package/dist/src/setup/config-patcher.d.ts.map +1 -0
  42. package/dist/src/setup/config-patcher.js +128 -0
  43. package/dist/src/setup/config-patcher.js.map +1 -0
  44. package/dist/src/setup/shell-detector.d.ts +10 -0
  45. package/dist/src/setup/shell-detector.d.ts.map +1 -0
  46. package/dist/src/setup/shell-detector.js +72 -0
  47. package/dist/src/setup/shell-detector.js.map +1 -0
  48. package/dist/src/snapshot/device-properties.d.ts +53 -0
  49. package/dist/src/snapshot/device-properties.d.ts.map +1 -0
  50. package/dist/src/snapshot/device-properties.js +94 -0
  51. package/dist/src/snapshot/device-properties.js.map +1 -0
  52. package/dist/src/snapshot/formatter.d.ts +13 -5
  53. package/dist/src/snapshot/formatter.d.ts.map +1 -1
  54. package/dist/src/snapshot/formatter.js +28 -19
  55. package/dist/src/snapshot/formatter.js.map +1 -1
  56. package/dist/src/snapshot/layout-inference.d.ts +44 -0
  57. package/dist/src/snapshot/layout-inference.d.ts.map +1 -0
  58. package/dist/src/snapshot/layout-inference.js +138 -0
  59. package/dist/src/snapshot/layout-inference.js.map +1 -0
  60. package/dist/src/tools/analyze-tools.d.ts +60 -0
  61. package/dist/src/tools/analyze-tools.d.ts.map +1 -0
  62. package/dist/src/tools/analyze-tools.js +196 -0
  63. package/dist/src/tools/analyze-tools.js.map +1 -0
  64. package/dist/src/tools/interaction-tools.d.ts +6 -6
  65. package/dist/src/tools/interaction-tools.d.ts.map +1 -1
  66. package/dist/src/tools/interaction-tools.js +12 -2
  67. package/dist/src/tools/interaction-tools.js.map +1 -1
  68. package/dist/src/tools/metro-tools.d.ts +2 -2
  69. package/dist/src/tools/navigation-tools.d.ts.map +1 -1
  70. package/dist/src/tools/navigation-tools.js +6 -1
  71. package/dist/src/tools/navigation-tools.js.map +1 -1
  72. package/dist/src/tools/screenshot-tools.d.ts +75 -0
  73. package/dist/src/tools/screenshot-tools.d.ts.map +1 -1
  74. package/dist/src/tools/screenshot-tools.js +238 -8
  75. package/dist/src/tools/screenshot-tools.js.map +1 -1
  76. package/dist/src/tools/snapshot-tools.d.ts +15 -0
  77. package/dist/src/tools/snapshot-tools.d.ts.map +1 -1
  78. package/dist/src/tools/snapshot-tools.js +32 -1
  79. package/dist/src/tools/snapshot-tools.js.map +1 -1
  80. package/dist/src/tools/vqa-tools.d.ts +62 -0
  81. package/dist/src/tools/vqa-tools.d.ts.map +1 -0
  82. package/dist/src/tools/vqa-tools.js +204 -0
  83. package/dist/src/tools/vqa-tools.js.map +1 -0
  84. package/dist/src/utils/image-preprocess.d.ts +1 -1
  85. package/dist/src/utils/image-preprocess.d.ts.map +1 -1
  86. package/dist/src/utils/image-preprocess.js +79 -0
  87. package/dist/src/utils/image-preprocess.js.map +1 -1
  88. package/dist/src/visual/color-extractor.d.ts +37 -0
  89. package/dist/src/visual/color-extractor.d.ts.map +1 -0
  90. package/dist/src/visual/color-extractor.js +116 -0
  91. package/dist/src/visual/color-extractor.js.map +1 -0
  92. package/dist/src/visual/comparator.d.ts +21 -0
  93. package/dist/src/visual/comparator.d.ts.map +1 -1
  94. package/dist/src/visual/comparator.js +110 -13
  95. package/dist/src/visual/comparator.js.map +1 -1
  96. package/dist/src/visual/layout-analyzer.d.ts.map +1 -1
  97. package/dist/src/visual/layout-analyzer.js +17 -7
  98. package/dist/src/visual/layout-analyzer.js.map +1 -1
  99. package/dist/src/visual/node-matcher.d.ts +43 -0
  100. package/dist/src/visual/node-matcher.d.ts.map +1 -0
  101. package/dist/src/visual/node-matcher.js +190 -0
  102. package/dist/src/visual/node-matcher.js.map +1 -0
  103. package/dist/src/visual/property-comparator.d.ts +49 -0
  104. package/dist/src/visual/property-comparator.d.ts.map +1 -0
  105. package/dist/src/visual/property-comparator.js +246 -0
  106. package/dist/src/visual/property-comparator.js.map +1 -0
  107. package/dist/src/visual/structural-comparator.d.ts +46 -0
  108. package/dist/src/visual/structural-comparator.d.ts.map +1 -0
  109. package/dist/src/visual/structural-comparator.js +293 -0
  110. package/dist/src/visual/structural-comparator.js.map +1 -0
  111. package/dist/src/visual/vqa-analyzer.d.ts +30 -0
  112. package/dist/src/visual/vqa-analyzer.d.ts.map +1 -0
  113. package/dist/src/visual/vqa-analyzer.js +271 -0
  114. package/dist/src/visual/vqa-analyzer.js.map +1 -0
  115. package/docs/figma-workflow.md +207 -40
  116. package/docs/setup-guide.md +221 -226
  117. package/docs/tool-reference.md +71 -0
  118. package/package.json +1 -1
  119. package/tsconfig.json +1 -1
  120. package/INSTALLATION_GUIDE.md +0 -354
  121. package/QUICK_START.md +0 -153
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Fetch the Figma node tree via REST API and parse into a typed layout tree.
3
+ * Uses GET /v1/files/{fileKey}/nodes?ids={nodeId} — returns full JSON node data
4
+ * including auto-layout properties that image exports lose entirely.
5
+ */
6
+ export interface FigmaLayoutNode {
7
+ /** Figma node ID (e.g., "10:200") */
8
+ id: string;
9
+ /** Layer name in Figma */
10
+ name: string;
11
+ /** Node type: FRAME, GROUP, TEXT, RECTANGLE, COMPONENT, INSTANCE, etc. */
12
+ type: string;
13
+ /** Text content for TEXT nodes */
14
+ characters?: string;
15
+ layoutMode: "HORIZONTAL" | "VERTICAL" | "NONE";
16
+ primaryAxisAlignItems: "MIN" | "CENTER" | "MAX" | "SPACE_BETWEEN";
17
+ counterAxisAlignItems: "MIN" | "CENTER" | "MAX" | "BASELINE";
18
+ itemSpacing: number;
19
+ paddingLeft: number;
20
+ paddingRight: number;
21
+ paddingTop: number;
22
+ paddingBottom: number;
23
+ absoluteBoundingBox: {
24
+ x: number;
25
+ y: number;
26
+ width: number;
27
+ height: number;
28
+ };
29
+ layoutSizingHorizontal: "FIXED" | "HUG" | "FILL";
30
+ layoutSizingVertical: "FIXED" | "HUG" | "FILL";
31
+ /** Recursive children */
32
+ children: FigmaLayoutNode[];
33
+ }
34
+ /**
35
+ * Fetch the Figma node tree via the REST API.
36
+ *
37
+ * @param fileKey Figma file key
38
+ * @param nodeId Node ID in colon format (e.g., "10:200")
39
+ * @param token FIGMA_TOKEN
40
+ * @returns Parsed FigmaLayoutNode tree
41
+ */
42
+ export declare function fetchFigmaStructure(fileKey: string, nodeId: string, token: string): Promise<FigmaLayoutNode>;
43
+ //# sourceMappingURL=figma-structure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"figma-structure.d.ts","sourceRoot":"","sources":["../../../src/figma/figma-structure.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,eAAe;IAC9B,qCAAqC;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,UAAU,EAAE,YAAY,GAAG,UAAU,GAAG,MAAM,CAAC;IAC/C,qBAAqB,EAAE,KAAK,GAAG,QAAQ,GAAG,KAAK,GAAG,eAAe,CAAC;IAClE,qBAAqB,EAAE,KAAK,GAAG,QAAQ,GAAG,KAAK,GAAG,UAAU,CAAC;IAC7D,WAAW,EAAE,MAAM,CAAC;IAGpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IAGtB,mBAAmB,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAG7E,sBAAsB,EAAE,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;IACjD,oBAAoB,EAAE,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;IAE/C,yBAAyB;IACzB,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAyCD;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,eAAe,CAAC,CAmC1B"}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ /**
3
+ * Fetch the Figma node tree via REST API and parse into a typed layout tree.
4
+ * Uses GET /v1/files/{fileKey}/nodes?ids={nodeId} — returns full JSON node data
5
+ * including auto-layout properties that image exports lose entirely.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.fetchFigmaStructure = fetchFigmaStructure;
9
+ /**
10
+ * Parse a raw Figma API node into our typed FigmaLayoutNode.
11
+ * Uses safe defaults for missing auto-layout properties.
12
+ */
13
+ function parseNode(raw) {
14
+ const bbox = raw.absoluteBoundingBox ?? { x: 0, y: 0, width: 0, height: 0 };
15
+ return {
16
+ id: raw.id ?? "",
17
+ name: raw.name ?? "",
18
+ type: raw.type ?? "UNKNOWN",
19
+ characters: raw.characters,
20
+ layoutMode: raw.layoutMode || "NONE",
21
+ primaryAxisAlignItems: raw.primaryAxisAlignItems || "MIN",
22
+ counterAxisAlignItems: raw.counterAxisAlignItems || "MIN",
23
+ itemSpacing: raw.itemSpacing ?? 0,
24
+ paddingLeft: raw.paddingLeft ?? 0,
25
+ paddingRight: raw.paddingRight ?? 0,
26
+ paddingTop: raw.paddingTop ?? 0,
27
+ paddingBottom: raw.paddingBottom ?? 0,
28
+ absoluteBoundingBox: {
29
+ x: bbox.x ?? 0,
30
+ y: bbox.y ?? 0,
31
+ width: bbox.width ?? 0,
32
+ height: bbox.height ?? 0,
33
+ },
34
+ layoutSizingHorizontal: raw.layoutSizingHorizontal || "FIXED",
35
+ layoutSizingVertical: raw.layoutSizingVertical || "FIXED",
36
+ children: Array.isArray(raw.children)
37
+ ? raw.children.map(parseNode)
38
+ : [],
39
+ };
40
+ }
41
+ /**
42
+ * Fetch the Figma node tree via the REST API.
43
+ *
44
+ * @param fileKey Figma file key
45
+ * @param nodeId Node ID in colon format (e.g., "10:200")
46
+ * @param token FIGMA_TOKEN
47
+ * @returns Parsed FigmaLayoutNode tree
48
+ */
49
+ async function fetchFigmaStructure(fileKey, nodeId, token) {
50
+ const apiUrl = `https://api.figma.com/v1/files/${fileKey}/nodes?ids=${encodeURIComponent(nodeId)}`;
51
+ const controller = new AbortController();
52
+ const timeout = setTimeout(() => controller.abort(), 20000);
53
+ let response;
54
+ try {
55
+ response = await fetch(apiUrl, {
56
+ headers: { "X-Figma-Token": token },
57
+ signal: controller.signal,
58
+ });
59
+ }
60
+ finally {
61
+ clearTimeout(timeout);
62
+ }
63
+ if (!response.ok) {
64
+ const body = await response.text().catch(() => "");
65
+ throw new Error(`Figma API error (${response.status}): ${body || response.statusText}`);
66
+ }
67
+ const data = (await response.json());
68
+ const nodeData = data.nodes?.[nodeId];
69
+ if (!nodeData?.document) {
70
+ throw new Error(`Node "${nodeId}" not found in Figma file "${fileKey}". Check the node ID.`);
71
+ }
72
+ return parseNode(nodeData.document);
73
+ }
74
+ //# sourceMappingURL=figma-structure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"figma-structure.js","sourceRoot":"","sources":["../../../src/figma/figma-structure.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Shared Figma URL parsing and token resolution.
3
+ * Used by devlens_compare_with_figma and devlens_verify_layout.
4
+ */
5
+ export interface FigmaParams {
6
+ fileKey: string;
7
+ nodeId: string;
8
+ token: string;
9
+ }
10
+ /**
11
+ * Parse a Figma design URL into fileKey and nodeId.
12
+ * Accepts: https://figma.com/design/<fileKey>/<name>?node-id=<int>-<int>
13
+ */
14
+ export declare function parseFigmaUrl(url: string): {
15
+ fileKey: string;
16
+ nodeId: string;
17
+ } | null;
18
+ /**
19
+ * Get FIGMA_TOKEN from environment.
20
+ */
21
+ export declare function getFigmaToken(): string | null;
22
+ /**
23
+ * Resolve figmaUrl/fileKey/nodeId params + FIGMA_TOKEN into validated FigmaParams.
24
+ * Returns { params } on success, { error } on failure with a user-facing message.
25
+ */
26
+ export declare function resolveFigmaParams(input: {
27
+ figmaUrl?: string;
28
+ fileKey?: string;
29
+ nodeId?: string;
30
+ }): {
31
+ params: FigmaParams;
32
+ error?: never;
33
+ } | {
34
+ params?: never;
35
+ error: string;
36
+ };
37
+ //# sourceMappingURL=figma-url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"figma-url.d.ts","sourceRoot":"","sources":["../../../src/figma/figma-url.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,GACV;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAS5C;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAE7C;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,MAAM,CAAC,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAuC7E"}
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ /**
3
+ * Shared Figma URL parsing and token resolution.
4
+ * Used by devlens_compare_with_figma and devlens_verify_layout.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.parseFigmaUrl = parseFigmaUrl;
8
+ exports.getFigmaToken = getFigmaToken;
9
+ exports.resolveFigmaParams = resolveFigmaParams;
10
+ /**
11
+ * Parse a Figma design URL into fileKey and nodeId.
12
+ * Accepts: https://figma.com/design/<fileKey>/<name>?node-id=<int>-<int>
13
+ */
14
+ function parseFigmaUrl(url) {
15
+ const match = url.match(/figma\.com\/design\/([^/]+)\/[^?]+\?.*node-id=(\d+-\d+)/);
16
+ if (!match)
17
+ return null;
18
+ return {
19
+ fileKey: match[1],
20
+ nodeId: match[2].replace("-", ":"),
21
+ };
22
+ }
23
+ /**
24
+ * Get FIGMA_TOKEN from environment.
25
+ */
26
+ function getFigmaToken() {
27
+ return process.env.FIGMA_TOKEN || null;
28
+ }
29
+ /**
30
+ * Resolve figmaUrl/fileKey/nodeId params + FIGMA_TOKEN into validated FigmaParams.
31
+ * Returns { params } on success, { error } on failure with a user-facing message.
32
+ */
33
+ function resolveFigmaParams(input) {
34
+ const token = getFigmaToken();
35
+ if (!token) {
36
+ return {
37
+ error: [
38
+ "FIGMA_TOKEN environment variable is not set.",
39
+ "",
40
+ "To use this tool, set FIGMA_TOKEN in your MCP config:",
41
+ ' "env": { "FIGMA_TOKEN": "figd_xxxxx" }',
42
+ "",
43
+ "Generate a token at: https://www.figma.com/developers/api#access-tokens",
44
+ ].join("\n"),
45
+ };
46
+ }
47
+ let fileKey = input.fileKey;
48
+ let nodeId = input.nodeId;
49
+ if (input.figmaUrl) {
50
+ const parsed = parseFigmaUrl(input.figmaUrl);
51
+ if (!parsed) {
52
+ return {
53
+ error: `Could not parse Figma URL. Expected format: https://figma.com/design/<fileKey>/<name>?node-id=<id>\nGot: ${input.figmaUrl}`,
54
+ };
55
+ }
56
+ fileKey = parsed.fileKey;
57
+ nodeId = parsed.nodeId;
58
+ }
59
+ if (!fileKey || !nodeId) {
60
+ return {
61
+ error: "Provide either figmaUrl, or both fileKey and nodeId.",
62
+ };
63
+ }
64
+ // Normalize nodeId: accept "10-200" or "10:200"
65
+ const normalizedNodeId = nodeId.replace("-", ":");
66
+ return { params: { fileKey, nodeId: normalizedNodeId, token } };
67
+ }
68
+ //# sourceMappingURL=figma-url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"figma-url.js","sourceRoot":"","sources":["../../../src/figma/figma-url.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAYH,sCAWC;AAKD,sCAEC;AAMD,gDA2CC;AAvED;;;GAGG;AACH,SAAgB,aAAa,CAC3B,GAAW;IAEX,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CACrB,yDAAyD,CAC1D,CAAC;IACF,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO;QACL,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;QACjB,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC;KACnC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAgB,aAAa;IAC3B,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC;AACzC,CAAC;AAED;;;GAGG;AACH,SAAgB,kBAAkB,CAAC,KAIlC;IACC,MAAM,KAAK,GAAG,aAAa,EAAE,CAAC;IAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO;YACL,KAAK,EAAE;gBACL,8CAA8C;gBAC9C,EAAE;gBACF,uDAAuD;gBACvD,0CAA0C;gBAC1C,EAAE;gBACF,yEAAyE;aAC1E,CAAC,IAAI,CAAC,IAAI,CAAC;SACb,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC5B,IAAI,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAE1B,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACnB,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;gBACL,KAAK,EAAE,4GAA4G,KAAK,CAAC,QAAQ,EAAE;aACpI,CAAC;QACJ,CAAC;QACD,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QACzB,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IACzB,CAAC;IAED,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;QACxB,OAAO;YACL,KAAK,EAAE,sDAAsD;SAC9D,CAAC;IACJ,CAAC;IAED,gDAAgD;IAChD,MAAM,gBAAgB,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAElD,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,EAAE,CAAC;AAClE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function getResponsiveTokens(token: string): any;
2
+ //# sourceMappingURL=resolve-token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-token.d.ts","sourceRoot":"","sources":["../../../src/jds-tokens/resolve-token.ts"],"names":[],"mappings":"AAEA,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAWtD"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getResponsiveTokens = getResponsiveTokens;
4
+ const tokens_1 = require("./tokens");
5
+ function getResponsiveTokens(token) {
6
+ const withoutBraces = token.replace(/[{}]/g, '');
7
+ if (tokens_1.responsiveTokens[withoutBraces]) {
8
+ const value = tokens_1.responsiveTokens[withoutBraces];
9
+ if (value.includes('$platform')) {
10
+ const replaced = value.replace('$platform', getPlatform());
11
+ return getResponsiveTokens(replaced);
12
+ }
13
+ return value;
14
+ }
15
+ return token;
16
+ }
17
+ function getPlatform() {
18
+ if (typeof window !== 'undefined') {
19
+ const width = window.innerWidth;
20
+ return width < 620 ? 'mobile' : width < 992 ? 'tablet' : 'desktop';
21
+ }
22
+ return 'desktop';
23
+ }
24
+ //# sourceMappingURL=resolve-token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-token.js","sourceRoot":"","sources":["../../../src/jds-tokens/resolve-token.ts"],"names":[],"mappings":";;AAEA,kDAWC;AAbD,qCAA4C;AAE5C,SAAgB,mBAAmB,CAAC,KAAa;IAC7C,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACpD,IAAI,yBAAgB,CAAC,aAAa,CAAC,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,yBAAgB,CAAC,aAAa,CAAC,CAAC;QAC9C,IAAI,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YACjC,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,WAAW,EAAE,CAAC,CAAC;YAClD,OAAO,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAC/C,CAAC;QACK,OAAO,KAAK,CAAC;IACpB,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,SAAS,WAAW;IACnB,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC;QAChC,OAAO,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IACpE,CAAC;IACE,OAAO,SAAS,CAAC;AACrB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const responsiveTokens: Partial<Record<string, string>>;
2
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../../src/jds-tokens/tokens.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAO5D,CAAC"}
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.responsiveTokens = void 0;
4
+ exports.responsiveTokens = {
5
+ myCustomDirection: '{flex-direction.$platform}',
6
+ 'flex-direction.mobile': 'column',
7
+ 'flex-direction.tablet': 'row',
8
+ myCustomGap: '{custom.gap.$platform}',
9
+ 'custom.gap.mobile': '16',
10
+ 'custom.gap.tablet': '40',
11
+ };
12
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../../src/jds-tokens/tokens.ts"],"names":[],"mappings":";;;AAAa,QAAA,gBAAgB,GAAoC;IAChE,iBAAiB,EAAE,4BAA4B;IAC/C,uBAAuB,EAAE,QAAQ;IACjC,uBAAuB,EAAE,KAAK;IAC9B,WAAW,EAAE,wBAAwB;IACrC,mBAAmB,EAAE,IAAI;IACzB,mBAAmB,EAAE,IAAI;CACzB,CAAC"}
@@ -2,6 +2,8 @@ import type { Device, DeviceInfo, AppInfo, SnapshotNode } from "../device.js";
2
2
  export declare class IosDevice implements Device {
3
3
  private deviceId;
4
4
  private simctl;
5
+ private scaleResolver;
6
+ private cachedInfo;
5
7
  constructor(deviceId: string);
6
8
  getInfo(): Promise<DeviceInfo>;
7
9
  getSnapshot(): Promise<SnapshotNode>;
@@ -1 +1 @@
1
- {"version":3,"file":"ios-device.d.ts","sourceRoot":"","sources":["../../../../src/platform/ios/ios-device.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAI9E,qBAAa,SAAU,YAAW,MAAM;IAG1B,OAAO,CAAC,QAAQ;IAF5B,OAAO,CAAC,MAAM,CAAS;gBAEH,QAAQ,EAAE,MAAM;IAI9B,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC;IAkB9B,WAAW,IAAI,OAAO,CAAC,YAAY,CAAC;IAKpC,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAIjC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM9C,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAKlE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrC,KAAK,CACT,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,WAAW,SAAM,GAChB,OAAO,CAAC,IAAI,CAAC;IAIV,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB7D,cAAc,CAAC,WAAW,EAAE,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpE,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC,QAAQ,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAS9B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG1C"}
1
+ {"version":3,"file":"ios-device.d.ts","sourceRoot":"","sources":["../../../../src/platform/ios/ios-device.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAK9E,qBAAa,SAAU,YAAW,MAAM;IAK1B,OAAO,CAAC,QAAQ;IAJ5B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,UAAU,CAA2B;gBAEzB,QAAQ,EAAE,MAAM;IAK9B,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC;IAqB9B,WAAW,IAAI,OAAO,CAAC,YAAY,CAAC;IAKpC,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAIjC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIxC,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM9C,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAKlE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrC,KAAK,CACT,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,WAAW,SAAM,GAChB,OAAO,CAAC,IAAI,CAAC;IAIV,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAsB7D,cAAc,CAAC,WAAW,EAAE,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAMpE,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC,QAAQ,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAS9B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG1C"}
@@ -2,29 +2,36 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.IosDevice = void 0;
4
4
  const simctl_js_1 = require("./simctl.js");
5
+ const scale_resolver_js_1 = require("./scale-resolver.js");
5
6
  const accessibility_js_1 = require("./accessibility.js");
6
7
  class IosDevice {
7
8
  deviceId;
8
9
  simctl;
10
+ scaleResolver;
11
+ cachedInfo = null;
9
12
  constructor(deviceId) {
10
13
  this.deviceId = deviceId;
11
14
  this.simctl = new simctl_js_1.Simctl(deviceId);
15
+ this.scaleResolver = new scale_resolver_js_1.ScreenScaleResolver();
12
16
  }
13
17
  async getInfo() {
14
- const [deviceInfo, screenSize] = await Promise.all([
18
+ if (this.cachedInfo)
19
+ return this.cachedInfo;
20
+ const [deviceInfo, logicalSize] = await Promise.all([
15
21
  this.simctl.getDeviceInfo(),
16
- this.simctl.getScreenSize(),
22
+ this.scaleResolver.getLogicalSize(this.simctl),
17
23
  ]);
18
- return {
24
+ this.cachedInfo = {
19
25
  id: this.deviceId,
20
26
  name: deviceInfo.name,
21
27
  platform: "ios",
22
28
  osVersion: deviceInfo.runtime,
23
- screenWidth: screenSize.width,
24
- screenHeight: screenSize.height,
29
+ screenWidth: logicalSize.width,
30
+ screenHeight: logicalSize.height,
25
31
  orientation: "portrait", // Default; would need to query actual orientation
26
32
  isBooted: deviceInfo.state === "Booted",
27
33
  };
34
+ return this.cachedInfo;
28
35
  }
29
36
  async getSnapshot() {
30
37
  const output = await this.simctl.getAccessibilityTree();
@@ -56,17 +63,20 @@ class IosDevice {
56
63
  case "home":
57
64
  await this.simctl.pressKey("home");
58
65
  break;
59
- case "back":
66
+ case "back": {
60
67
  // iOS doesn't have a hardware back button; swipe from left edge
61
- const screenSize = await this.simctl.getScreenSize();
62
- await this.simctl.swipe(0, screenSize.height / 2, screenSize.width / 2, screenSize.height / 2);
68
+ const info = await this.getInfo();
69
+ await this.simctl.swipe(0, info.screenHeight / 2, info.screenWidth / 2, info.screenHeight / 2);
63
70
  break;
71
+ }
64
72
  case "enter":
65
73
  await this.simctl.pressKey("return");
66
74
  break;
67
75
  }
68
76
  }
69
77
  async setOrientation(orientation) {
78
+ this.scaleResolver.invalidate();
79
+ this.cachedInfo = null;
70
80
  await this.simctl.setOrientation(orientation);
71
81
  }
72
82
  async launchApp(appId) {
@@ -1 +1 @@
1
- {"version":3,"file":"ios-device.js","sourceRoot":"","sources":["../../../../src/platform/ios/ios-device.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ios-device.js","sourceRoot":"","sources":["../../../../src/platform/ios/ios-device.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { Simctl } from "./simctl.js";
2
+ /**
3
+ * ScreenScaleResolver — detects iOS Simulator scale factor (1x/2x/3x)
4
+ * by comparing screenshot physical pixel dimensions against a lookup table
5
+ * of known device logical sizes.
6
+ *
7
+ * This resolves the core coordinate mismatch: screenshots report physical
8
+ * pixels, but `simctl io tap` and accessibility bounds use logical points.
9
+ */
10
+ export declare class ScreenScaleResolver {
11
+ private scaleFactor;
12
+ private physicalWidth;
13
+ private physicalHeight;
14
+ /**
15
+ * Detect scale factor by comparing screenshot pixel dimensions
16
+ * against known logical dimensions from device name lookup.
17
+ */
18
+ detect(simctl: Simctl): Promise<number>;
19
+ /** Get logical screen dimensions (points, not physical pixels) */
20
+ getLogicalSize(simctl: Simctl): Promise<{
21
+ width: number;
22
+ height: number;
23
+ }>;
24
+ /** Get the detected scale factor (null if not yet detected) */
25
+ getScaleFactor(): number | null;
26
+ /** Invalidate cache (call on orientation change) */
27
+ invalidate(): void;
28
+ }
29
+ //# sourceMappingURL=scale-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scale-resolver.d.ts","sourceRoot":"","sources":["../../../../src/platform/ios/scale-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C;;;;;;;GAOG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,cAAc,CAAuB;IAE7C;;;OAGG;IACG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA4B7C,kEAAkE;IAC5D,cAAc,CAClB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAiB7C,+DAA+D;IAC/D,cAAc,IAAI,MAAM,GAAG,IAAI;IAI/B,oDAAoD;IACpD,UAAU,IAAI,IAAI;CAKnB"}
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ScreenScaleResolver = void 0;
4
+ /**
5
+ * ScreenScaleResolver — detects iOS Simulator scale factor (1x/2x/3x)
6
+ * by comparing screenshot physical pixel dimensions against a lookup table
7
+ * of known device logical sizes.
8
+ *
9
+ * This resolves the core coordinate mismatch: screenshots report physical
10
+ * pixels, but `simctl io tap` and accessibility bounds use logical points.
11
+ */
12
+ class ScreenScaleResolver {
13
+ scaleFactor = null;
14
+ physicalWidth = null;
15
+ physicalHeight = null;
16
+ /**
17
+ * Detect scale factor by comparing screenshot pixel dimensions
18
+ * against known logical dimensions from device name lookup.
19
+ */
20
+ async detect(simctl) {
21
+ if (this.scaleFactor)
22
+ return this.scaleFactor;
23
+ // Step 1: Get screenshot physical dimensions
24
+ const screenshotBuffer = await simctl.screenshot();
25
+ const sharp = (await import("sharp")).default;
26
+ const meta = await sharp(screenshotBuffer).metadata();
27
+ this.physicalWidth = meta.width;
28
+ this.physicalHeight = meta.height;
29
+ // Step 2: Get device name from simctl list devices --json
30
+ const info = await simctl.getDeviceInfo();
31
+ const logicalSize = DEVICE_LOGICAL_SIZES[info.name];
32
+ if (logicalSize) {
33
+ this.scaleFactor = Math.round(this.physicalWidth / logicalSize.width);
34
+ }
35
+ else {
36
+ // Fallback: common iOS scale factors are 2x or 3x
37
+ // If physical width > 1000, likely 3x; else 2x
38
+ this.scaleFactor = this.physicalWidth > 1000 ? 3 : 2;
39
+ console.error(`[scale-resolver] Unknown device "${info.name}", guessed ${this.scaleFactor}x scale`);
40
+ }
41
+ return this.scaleFactor;
42
+ }
43
+ /** Get logical screen dimensions (points, not physical pixels) */
44
+ async getLogicalSize(simctl) {
45
+ // If we haven't detected yet, detect() will take the screenshot
46
+ if (!this.physicalWidth || !this.physicalHeight) {
47
+ const screenshotBuffer = await simctl.screenshot();
48
+ const sharp = (await import("sharp")).default;
49
+ const meta = await sharp(screenshotBuffer).metadata();
50
+ this.physicalWidth = meta.width;
51
+ this.physicalHeight = meta.height;
52
+ }
53
+ const scale = await this.detect(simctl);
54
+ return {
55
+ width: Math.round(this.physicalWidth / scale),
56
+ height: Math.round(this.physicalHeight / scale),
57
+ };
58
+ }
59
+ /** Get the detected scale factor (null if not yet detected) */
60
+ getScaleFactor() {
61
+ return this.scaleFactor;
62
+ }
63
+ /** Invalidate cache (call on orientation change) */
64
+ invalidate() {
65
+ this.scaleFactor = null;
66
+ this.physicalWidth = null;
67
+ this.physicalHeight = null;
68
+ }
69
+ }
70
+ exports.ScreenScaleResolver = ScreenScaleResolver;
71
+ /**
72
+ * Known iOS Simulator logical sizes (points).
73
+ * Portrait orientation. Covers iPhone 14-16 series + common iPads.
74
+ */
75
+ const DEVICE_LOGICAL_SIZES = {
76
+ // iPhone 16 series
77
+ "iPhone 16 Pro Max": { width: 440, height: 956 },
78
+ "iPhone 16 Pro": { width: 402, height: 874 },
79
+ "iPhone 16 Plus": { width: 430, height: 932 },
80
+ "iPhone 16": { width: 393, height: 852 },
81
+ // iPhone 15 series
82
+ "iPhone 15 Pro Max": { width: 430, height: 932 },
83
+ "iPhone 15 Pro": { width: 393, height: 852 },
84
+ "iPhone 15 Plus": { width: 430, height: 932 },
85
+ "iPhone 15": { width: 393, height: 852 },
86
+ // iPhone 14 series
87
+ "iPhone 14 Pro Max": { width: 430, height: 932 },
88
+ "iPhone 14 Pro": { width: 393, height: 852 },
89
+ "iPhone 14 Plus": { width: 428, height: 926 },
90
+ "iPhone 14": { width: 390, height: 844 },
91
+ // iPhone 13 series
92
+ "iPhone 13 Pro Max": { width: 428, height: 926 },
93
+ "iPhone 13 Pro": { width: 390, height: 844 },
94
+ "iPhone 13": { width: 390, height: 844 },
95
+ "iPhone 13 mini": { width: 375, height: 812 },
96
+ // iPhone SE
97
+ "iPhone SE (3rd generation)": { width: 375, height: 667 },
98
+ "iPhone SE (2nd generation)": { width: 375, height: 667 },
99
+ // iPads
100
+ "iPad Pro 13-inch (M4)": { width: 1032, height: 1376 },
101
+ "iPad Pro (12.9-inch) (6th generation)": { width: 1024, height: 1366 },
102
+ "iPad Pro (12.9-inch) (5th generation)": { width: 1024, height: 1366 },
103
+ "iPad Pro (12.9-inch)": { width: 1024, height: 1366 },
104
+ "iPad Pro 11-inch (M4)": { width: 834, height: 1210 },
105
+ "iPad Pro (11-inch) (4th generation)": { width: 834, height: 1194 },
106
+ "iPad Pro (11-inch)": { width: 834, height: 1194 },
107
+ "iPad Air 13-inch (M2)": { width: 1024, height: 1366 },
108
+ "iPad Air 11-inch (M2)": { width: 820, height: 1180 },
109
+ "iPad Air (5th generation)": { width: 820, height: 1180 },
110
+ "iPad Air": { width: 820, height: 1180 },
111
+ "iPad mini (6th generation)": { width: 744, height: 1133 },
112
+ "iPad (10th generation)": { width: 820, height: 1180 },
113
+ };
114
+ //# sourceMappingURL=scale-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scale-resolver.js","sourceRoot":"","sources":["../../../../src/platform/ios/scale-resolver.ts"],"names":[],"mappings":"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"}
@@ -27,6 +27,11 @@ export declare class Simctl {
27
27
  width: number;
28
28
  height: number;
29
29
  }>;
30
+ /** Get logical screen size (points) using a ScreenScaleResolver */
31
+ getLogicalScreenSize(scaleResolver: import("./scale-resolver.js").ScreenScaleResolver): Promise<{
32
+ width: number;
33
+ height: number;
34
+ }>;
30
35
  /** Tap at coordinates using simctl */
31
36
  tap(x: number, y: number): Promise<void>;
32
37
  /** Swipe on the simulator */
@@ -1 +1 @@
1
- {"version":3,"file":"simctl.d.ts","sourceRoot":"","sources":["../../../../src/platform/ios/simctl.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,qBAAa,MAAM;IACL,OAAO,CAAC,QAAQ;gBAAR,QAAQ,EAAE,MAAM;IAEpC,+BAA+B;IACzB,IAAI,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAS9C,8CAA8C;IACxC,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAUnC,oEAAoE;IAC9D,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;IAe7C;;;;OAIG;YACW,yBAAyB;IAcvC,kCAAkC;IAC5B,aAAa,IAAI,OAAO,CAAC;QAC7B,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IA2BF,uCAAuC;IACjC,aAAa,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAqBjE,sCAAsC;IAChC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB9C,6BAA6B;IACvB,KAAK,CACT,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC;IAgBhB,4CAA4C;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3C,+BAA+B;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C,oBAAoB;IACd,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD,uBAAuB;IACjB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAInD,2CAA2C;IACrC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7C,0BAA0B;IACpB,QAAQ,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IA6BpE,iBAAiB;IACX,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,6BAA6B;IACvB,cAAc,CAAC,WAAW,EAAE,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAc3E"}
1
+ {"version":3,"file":"simctl.d.ts","sourceRoot":"","sources":["../../../../src/platform/ios/simctl.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,qBAAa,MAAM;IACL,OAAO,CAAC,QAAQ;gBAAR,QAAQ,EAAE,MAAM;IAEpC,+BAA+B;IACzB,IAAI,CAAC,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAS9C,8CAA8C;IACxC,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAUnC,oEAAoE;IAC9D,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC;IAe7C;;;;OAIG;YACW,yBAAyB;IAcvC,kCAAkC;IAC5B,aAAa,IAAI,OAAO,CAAC;QAC7B,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IA2BF,uCAAuC;IACjC,aAAa,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAqBjE,mEAAmE;IAC7D,oBAAoB,CACxB,aAAa,EAAE,OAAO,qBAAqB,EAAE,mBAAmB,GAC/D,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAI7C,sCAAsC;IAChC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB9C,6BAA6B;IACvB,KAAK,CACT,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC;IAgBhB,4CAA4C;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3C,+BAA+B;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C,oBAAoB;IACd,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD,uBAAuB;IACjB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAInD,2CAA2C;IACrC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7C,0BAA0B;IACpB,QAAQ,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IA6BpE,iBAAiB;IACX,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,6BAA6B;IACvB,cAAc,CAAC,WAAW,EAAE,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAc3E"}
@@ -99,6 +99,10 @@ class Simctl {
99
99
  return { width: 390, height: 844 };
100
100
  }
101
101
  }
102
+ /** Get logical screen size (points) using a ScreenScaleResolver */
103
+ async getLogicalScreenSize(scaleResolver) {
104
+ return scaleResolver.getLogicalSize(this);
105
+ }
102
106
  /** Tap at coordinates using simctl */
103
107
  async tap(x, y) {
104
108
  // simctl doesn't have a direct tap command, so we use the io command