devlens-mcp 0.4.2 → 0.5.2

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 (131) hide show
  1. package/README.md +211 -35
  2. package/RELEASE_NOTES.md +3 -7
  3. package/dist/bin/cli.js +41 -14
  4. package/dist/bin/cli.js.map +1 -1
  5. package/dist/bin/setup.d.ts +14 -0
  6. package/dist/bin/setup.d.ts.map +1 -0
  7. package/dist/bin/setup.js +272 -0
  8. package/dist/bin/setup.js.map +1 -0
  9. package/dist/src/figma/figma-api.d.ts +108 -0
  10. package/dist/src/figma/figma-api.d.ts.map +1 -0
  11. package/dist/src/figma/figma-api.js +284 -0
  12. package/dist/src/figma/figma-api.js.map +1 -0
  13. package/dist/src/figma/figma-cache.d.ts +57 -0
  14. package/dist/src/figma/figma-cache.d.ts.map +1 -0
  15. package/dist/src/figma/figma-cache.js +266 -0
  16. package/dist/src/figma/figma-cache.js.map +1 -0
  17. package/dist/src/figma/figma-client.d.ts +62 -0
  18. package/dist/src/figma/figma-client.d.ts.map +1 -0
  19. package/dist/src/figma/figma-client.js +224 -0
  20. package/dist/src/figma/figma-client.js.map +1 -0
  21. package/dist/src/figma/figma-rate-limiter.d.ts +46 -0
  22. package/dist/src/figma/figma-rate-limiter.d.ts.map +1 -0
  23. package/dist/src/figma/figma-rate-limiter.js +153 -0
  24. package/dist/src/figma/figma-rate-limiter.js.map +1 -0
  25. package/dist/src/figma/figma-retry.d.ts +19 -0
  26. package/dist/src/figma/figma-retry.d.ts.map +1 -0
  27. package/dist/src/figma/figma-retry.js +57 -0
  28. package/dist/src/figma/figma-retry.js.map +1 -0
  29. package/dist/src/figma/figma-structure.d.ts +1 -1
  30. package/dist/src/figma/figma-structure.d.ts.map +1 -1
  31. package/dist/src/figma/figma-structure.js +11 -1
  32. package/dist/src/figma/figma-structure.js.map +1 -1
  33. package/dist/src/figma/figma-types.d.ts +54 -0
  34. package/dist/src/figma/figma-types.d.ts.map +1 -0
  35. package/dist/src/figma/figma-types.js +33 -0
  36. package/dist/src/figma/figma-types.js.map +1 -0
  37. package/dist/src/figma/url-parser.d.ts +40 -0
  38. package/dist/src/figma/url-parser.d.ts.map +1 -0
  39. package/dist/src/figma/url-parser.js +107 -0
  40. package/dist/src/figma/url-parser.js.map +1 -0
  41. package/dist/src/platform/device-manager.d.ts +5 -0
  42. package/dist/src/platform/device-manager.d.ts.map +1 -1
  43. package/dist/src/platform/device-manager.js +18 -0
  44. package/dist/src/platform/device-manager.js.map +1 -1
  45. package/dist/src/platform/device-pool.d.ts +105 -0
  46. package/dist/src/platform/device-pool.d.ts.map +1 -0
  47. package/dist/src/platform/device-pool.js +328 -0
  48. package/dist/src/platform/device-pool.js.map +1 -0
  49. package/dist/src/platform/device-profiles.d.ts +50 -0
  50. package/dist/src/platform/device-profiles.d.ts.map +1 -0
  51. package/dist/src/platform/device-profiles.js +155 -0
  52. package/dist/src/platform/device-profiles.js.map +1 -0
  53. package/dist/src/platform/ios/ios-device.d.ts +0 -2
  54. package/dist/src/platform/ios/ios-device.d.ts.map +1 -1
  55. package/dist/src/platform/ios/ios-device.js +8 -18
  56. package/dist/src/platform/ios/ios-device.js.map +1 -1
  57. package/dist/src/platform/ios/simctl.d.ts +0 -5
  58. package/dist/src/platform/ios/simctl.d.ts.map +1 -1
  59. package/dist/src/platform/ios/simctl.js +0 -4
  60. package/dist/src/platform/ios/simctl.js.map +1 -1
  61. package/dist/src/platform/simulator-factory.d.ts +85 -0
  62. package/dist/src/platform/simulator-factory.d.ts.map +1 -0
  63. package/dist/src/platform/simulator-factory.js +396 -0
  64. package/dist/src/platform/simulator-factory.js.map +1 -0
  65. package/dist/src/platform/system-resources.d.ts +44 -0
  66. package/dist/src/platform/system-resources.d.ts.map +1 -0
  67. package/dist/src/platform/system-resources.js +103 -0
  68. package/dist/src/platform/system-resources.js.map +1 -0
  69. package/dist/src/prototype/browser-engine.d.ts +62 -0
  70. package/dist/src/prototype/browser-engine.d.ts.map +1 -0
  71. package/dist/src/prototype/browser-engine.js +199 -0
  72. package/dist/src/prototype/browser-engine.js.map +1 -0
  73. package/dist/src/prototype/figma-navigator.d.ts +40 -0
  74. package/dist/src/prototype/figma-navigator.d.ts.map +1 -0
  75. package/dist/src/prototype/figma-navigator.js +95 -0
  76. package/dist/src/prototype/figma-navigator.js.map +1 -0
  77. package/dist/src/prototype/flow-reporter.d.ts +47 -0
  78. package/dist/src/prototype/flow-reporter.d.ts.map +1 -0
  79. package/dist/src/prototype/flow-reporter.js +255 -0
  80. package/dist/src/prototype/flow-reporter.js.map +1 -0
  81. package/dist/src/prototype/screen-analyzer.d.ts +31 -0
  82. package/dist/src/prototype/screen-analyzer.d.ts.map +1 -0
  83. package/dist/src/prototype/screen-analyzer.js +114 -0
  84. package/dist/src/prototype/screen-analyzer.js.map +1 -0
  85. package/dist/src/prototype/web-crawler.d.ts +31 -0
  86. package/dist/src/prototype/web-crawler.d.ts.map +1 -0
  87. package/dist/src/prototype/web-crawler.js +88 -0
  88. package/dist/src/prototype/web-crawler.js.map +1 -0
  89. package/dist/src/reports/cross-device-report.d.ts +84 -0
  90. package/dist/src/reports/cross-device-report.d.ts.map +1 -0
  91. package/dist/src/reports/cross-device-report.js +342 -0
  92. package/dist/src/reports/cross-device-report.js.map +1 -0
  93. package/dist/src/server.d.ts.map +1 -1
  94. package/dist/src/server.js +9 -1
  95. package/dist/src/server.js.map +1 -1
  96. package/dist/src/snapshot/formatter.d.ts +5 -13
  97. package/dist/src/snapshot/formatter.d.ts.map +1 -1
  98. package/dist/src/snapshot/formatter.js +19 -28
  99. package/dist/src/snapshot/formatter.js.map +1 -1
  100. package/dist/src/tools/interaction-tools.d.ts +6 -6
  101. package/dist/src/tools/interaction-tools.d.ts.map +1 -1
  102. package/dist/src/tools/interaction-tools.js +2 -12
  103. package/dist/src/tools/interaction-tools.js.map +1 -1
  104. package/dist/src/tools/metro-tools.d.ts +2 -2
  105. package/dist/src/tools/multi-device-tools.d.ts +133 -0
  106. package/dist/src/tools/multi-device-tools.d.ts.map +1 -0
  107. package/dist/src/tools/multi-device-tools.js +365 -0
  108. package/dist/src/tools/multi-device-tools.js.map +1 -0
  109. package/dist/src/tools/navigation-tools.d.ts.map +1 -1
  110. package/dist/src/tools/navigation-tools.js +1 -6
  111. package/dist/src/tools/navigation-tools.js.map +1 -1
  112. package/dist/src/tools/prototype-tools.d.ts +102 -0
  113. package/dist/src/tools/prototype-tools.d.ts.map +1 -0
  114. package/dist/src/tools/prototype-tools.js +391 -0
  115. package/dist/src/tools/prototype-tools.js.map +1 -0
  116. package/dist/src/tools/screenshot-tools.d.ts +7 -74
  117. package/dist/src/tools/screenshot-tools.d.ts.map +1 -1
  118. package/dist/src/tools/screenshot-tools.js +19 -286
  119. package/dist/src/tools/screenshot-tools.js.map +1 -1
  120. package/dist/src/tools/vqa-tools.d.ts +2 -2
  121. package/dist/src/tools/vqa-tools.d.ts.map +1 -1
  122. package/dist/src/tools/vqa-tools.js +4 -69
  123. package/dist/src/tools/vqa-tools.js.map +1 -1
  124. package/docs/figma-workflow.md +58 -6
  125. package/docs/installation-guide.md +302 -0
  126. package/docs/setup-guide.md +77 -79
  127. package/docs/tool-reference.md +152 -69
  128. package/install.sh +119 -0
  129. package/package.json +5 -2
  130. package/setup.sh +320 -0
  131. package/tsconfig.json +1 -1
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Adaptive token-bucket rate limiter for the Figma API.
3
+ * Starts conservative (10 req/min), auto-adapts when 429 headers
4
+ * reveal the user's plan tier and seat type.
5
+ */
6
+ import { type FigmaRateLimitInfo, type RateLimiterStatus } from "./figma-types.js";
7
+ export declare class FigmaRateLimiter {
8
+ private budget;
9
+ private tokens;
10
+ private lastRefill;
11
+ private pausedUntil;
12
+ private consecutiveSuccesses;
13
+ private planCap;
14
+ private detectedPlanTier?;
15
+ private detectedSeatType?;
16
+ private totalRequests;
17
+ private throttledRequests;
18
+ constructor(config?: {
19
+ initialBudget?: number;
20
+ });
21
+ /**
22
+ * Wait until a request is allowed. Blocks if paused or no tokens.
23
+ * Throws FigmaRateLimitError for View/Collab seats (budget = 0).
24
+ */
25
+ acquire(): Promise<void>;
26
+ /**
27
+ * Called when a 429 response is received. Adapts budget and pauses.
28
+ */
29
+ onRateLimited(info: FigmaRateLimitInfo): void;
30
+ /**
31
+ * Called on successful API response. Gradually increases budget.
32
+ */
33
+ onSuccess(): void;
34
+ /**
35
+ * Check if currently rate-limited without blocking.
36
+ */
37
+ isLimited(): boolean;
38
+ /**
39
+ * Get status for logging/observability.
40
+ */
41
+ getStatus(): RateLimiterStatus;
42
+ private refillTokens;
43
+ private msUntilNextToken;
44
+ private sleep;
45
+ }
46
+ //# sourceMappingURL=figma-rate-limiter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"figma-rate-limiter.d.ts","sourceRoot":"","sources":["../../../src/figma/figma-rate-limiter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACvB,MAAM,kBAAkB,CAAC;AAgB1B,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,oBAAoB,CAAK;IACjC,OAAO,CAAC,OAAO,CAAY;IAE3B,OAAO,CAAC,gBAAgB,CAAC,CAAS;IAClC,OAAO,CAAC,gBAAgB,CAAC,CAAS;IAClC,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,iBAAiB,CAAK;gBAElB,MAAM,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE;IAM/C;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAkC9B;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI;IAmC7C;;OAEG;IACH,SAAS,IAAI,IAAI;IAUjB;;OAEG;IACH,SAAS,IAAI,OAAO;IAKpB;;OAEG;IACH,SAAS,IAAI,iBAAiB;IAc9B,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,KAAK;CAGd"}
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ /**
3
+ * Adaptive token-bucket rate limiter for the Figma API.
4
+ * Starts conservative (10 req/min), auto-adapts when 429 headers
5
+ * reveal the user's plan tier and seat type.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.FigmaRateLimiter = void 0;
9
+ const figma_types_js_1 = require("./figma-types.js");
10
+ /** Plan-tier caps (requests per minute) */
11
+ const PLAN_CAPS = {
12
+ starter: 10,
13
+ pro: 15,
14
+ org: 20,
15
+ organization: 20,
16
+ enterprise: 30,
17
+ };
18
+ const DEFAULT_BUDGET = 10;
19
+ const BUDGET_INCREASE_THRESHOLD = 20; // consecutive successes before increasing
20
+ const BUDGET_INCREASE_STEP = 2;
21
+ const BUDGET_DECREASE_FACTOR = 0.7; // multiply by this on 429
22
+ class FigmaRateLimiter {
23
+ budget;
24
+ tokens;
25
+ lastRefill;
26
+ pausedUntil = 0;
27
+ consecutiveSuccesses = 0;
28
+ planCap = Infinity;
29
+ detectedPlanTier;
30
+ detectedSeatType;
31
+ totalRequests = 0;
32
+ throttledRequests = 0;
33
+ constructor(config) {
34
+ this.budget = config?.initialBudget ?? DEFAULT_BUDGET;
35
+ this.tokens = this.budget;
36
+ this.lastRefill = Date.now();
37
+ }
38
+ /**
39
+ * Wait until a request is allowed. Blocks if paused or no tokens.
40
+ * Throws FigmaRateLimitError for View/Collab seats (budget = 0).
41
+ */
42
+ async acquire() {
43
+ this.totalRequests++;
44
+ this.refillTokens();
45
+ // If paused (after a 429), wait it out
46
+ const now = Date.now();
47
+ if (this.pausedUntil > now) {
48
+ const waitMs = this.pausedUntil - now;
49
+ if (waitMs > 300_000) {
50
+ // More than 5 minutes — likely a View/Collab seat
51
+ throw new figma_types_js_1.FigmaRateLimitError("Figma API rate limit: long pause required (likely View/Collab seat).", {
52
+ retryAfterSeconds: Math.ceil(waitMs / 1000),
53
+ planTier: this.detectedPlanTier,
54
+ rateLimitType: this.detectedSeatType,
55
+ });
56
+ }
57
+ this.throttledRequests++;
58
+ await this.sleep(waitMs);
59
+ }
60
+ // Wait for a token
61
+ while (this.tokens < 1) {
62
+ this.throttledRequests++;
63
+ const refillWait = this.msUntilNextToken();
64
+ await this.sleep(refillWait);
65
+ this.refillTokens();
66
+ }
67
+ this.tokens--;
68
+ }
69
+ /**
70
+ * Called when a 429 response is received. Adapts budget and pauses.
71
+ */
72
+ onRateLimited(info) {
73
+ this.consecutiveSuccesses = 0;
74
+ // Detect plan tier from headers
75
+ if (info.planTier && !this.detectedPlanTier) {
76
+ this.detectedPlanTier = info.planTier.toLowerCase();
77
+ const cap = PLAN_CAPS[this.detectedPlanTier];
78
+ if (cap) {
79
+ this.planCap = cap;
80
+ this.budget = Math.min(this.budget, cap);
81
+ }
82
+ }
83
+ if (info.rateLimitType && !this.detectedSeatType) {
84
+ this.detectedSeatType = info.rateLimitType.toLowerCase();
85
+ if (this.detectedSeatType === "low") {
86
+ // View/Collab seat — extremely limited (6 req/month)
87
+ this.budget = 0;
88
+ this.planCap = 0;
89
+ this.tokens = 0;
90
+ const pauseMs = info.retryAfterSeconds * 1000;
91
+ this.pausedUntil = Date.now() + pauseMs;
92
+ return; // Skip normal budget decrease
93
+ }
94
+ }
95
+ // Decrease budget
96
+ this.budget = Math.max(1, Math.floor(this.budget * BUDGET_DECREASE_FACTOR));
97
+ // Pause for the Retry-After duration
98
+ const pauseMs = info.retryAfterSeconds * 1000;
99
+ this.pausedUntil = Date.now() + pauseMs;
100
+ this.tokens = 0;
101
+ }
102
+ /**
103
+ * Called on successful API response. Gradually increases budget.
104
+ */
105
+ onSuccess() {
106
+ this.consecutiveSuccesses++;
107
+ if (this.consecutiveSuccesses >= BUDGET_INCREASE_THRESHOLD) {
108
+ this.consecutiveSuccesses = 0;
109
+ const newBudget = this.budget + BUDGET_INCREASE_STEP;
110
+ this.budget = Math.min(newBudget, this.planCap);
111
+ }
112
+ }
113
+ /**
114
+ * Check if currently rate-limited without blocking.
115
+ */
116
+ isLimited() {
117
+ this.refillTokens();
118
+ return Date.now() < this.pausedUntil || this.tokens < 1;
119
+ }
120
+ /**
121
+ * Get status for logging/observability.
122
+ */
123
+ getStatus() {
124
+ this.refillTokens();
125
+ return {
126
+ budget: this.budget,
127
+ tokens: Math.floor(this.tokens),
128
+ pausedUntil: this.pausedUntil,
129
+ detectedPlanTier: this.detectedPlanTier,
130
+ detectedSeatType: this.detectedSeatType,
131
+ totalRequests: this.totalRequests,
132
+ throttledRequests: this.throttledRequests,
133
+ isLimited: this.isLimited(),
134
+ };
135
+ }
136
+ refillTokens() {
137
+ const now = Date.now();
138
+ const elapsed = now - this.lastRefill;
139
+ const refillAmount = (elapsed / 60_000) * this.budget;
140
+ this.tokens = Math.min(this.budget, this.tokens + refillAmount);
141
+ this.lastRefill = now;
142
+ }
143
+ msUntilNextToken() {
144
+ if (this.budget <= 0)
145
+ return 60_000;
146
+ return Math.ceil(60_000 / this.budget);
147
+ }
148
+ sleep(ms) {
149
+ return new Promise((resolve) => setTimeout(resolve, Math.min(ms, 60_000)));
150
+ }
151
+ }
152
+ exports.FigmaRateLimiter = FigmaRateLimiter;
153
+ //# sourceMappingURL=figma-rate-limiter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"figma-rate-limiter.js","sourceRoot":"","sources":["../../../src/figma/figma-rate-limiter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * 429-aware retry wrapper for Figma API requests.
3
+ * Respects Retry-After headers, delegates to the rate limiter,
4
+ * and uses exponential backoff for 5xx errors.
5
+ */
6
+ import type { FigmaRateLimiter } from "./figma-rate-limiter.js";
7
+ export interface FigmaRetryOptions {
8
+ rateLimiter: FigmaRateLimiter;
9
+ maxAttempts?: number;
10
+ onRetry?: (attempt: number, delayMs: number, reason: string) => void;
11
+ }
12
+ /**
13
+ * Execute a fetch with rate limiting + retry.
14
+ * - 429: parse Retry-After, pause via rate limiter, retry
15
+ * - 5xx: exponential backoff (1s, 2s, 4s)
16
+ * - 4xx (non-429): throw immediately
17
+ */
18
+ export declare function figmaRetry(fn: () => Promise<Response>, options: FigmaRetryOptions): Promise<Response>;
19
+ //# sourceMappingURL=figma-retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"figma-retry.d.ts","sourceRoot":"","sources":["../../../src/figma/figma-retry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,gBAAgB,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACtE;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,EAAE,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,EAC3B,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,QAAQ,CAAC,CAoDnB"}
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ /**
3
+ * 429-aware retry wrapper for Figma API requests.
4
+ * Respects Retry-After headers, delegates to the rate limiter,
5
+ * and uses exponential backoff for 5xx errors.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.figmaRetry = figmaRetry;
9
+ const figma_types_js_1 = require("./figma-types.js");
10
+ /**
11
+ * Execute a fetch with rate limiting + retry.
12
+ * - 429: parse Retry-After, pause via rate limiter, retry
13
+ * - 5xx: exponential backoff (1s, 2s, 4s)
14
+ * - 4xx (non-429): throw immediately
15
+ */
16
+ async function figmaRetry(fn, options) {
17
+ const { rateLimiter, maxAttempts = 3, onRetry } = options;
18
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
19
+ await rateLimiter.acquire();
20
+ const response = await fn();
21
+ if (response.status === 429) {
22
+ const info = (0, figma_types_js_1.parseRateLimitHeaders)(response);
23
+ if (info) {
24
+ rateLimiter.onRateLimited(info);
25
+ // View/Collab seats or extremely long waits — don't retry
26
+ if (info.retryAfterSeconds > 300 || info.rateLimitType === "low") {
27
+ throw new figma_types_js_1.FigmaRateLimitError(`Figma API rate limited (retry-after: ${info.retryAfterSeconds}s)`, info);
28
+ }
29
+ if (attempt < maxAttempts) {
30
+ const delayMs = info.retryAfterSeconds * 1000;
31
+ onRetry?.(attempt, delayMs, `429 rate limited, retry-after ${info.retryAfterSeconds}s`);
32
+ await sleep(delayMs);
33
+ continue;
34
+ }
35
+ }
36
+ // All retries exhausted
37
+ throw new figma_types_js_1.FigmaRateLimitError(`Figma API rate limited after ${maxAttempts} attempts`, info ?? { retryAfterSeconds: 60 });
38
+ }
39
+ if (response.status >= 500 && attempt < maxAttempts) {
40
+ const delayMs = 1000 * Math.pow(2, attempt - 1); // 1s, 2s, 4s
41
+ onRetry?.(attempt, delayMs, `server error ${response.status}`);
42
+ await sleep(delayMs);
43
+ continue;
44
+ }
45
+ // Success or non-retryable error
46
+ if (response.ok) {
47
+ rateLimiter.onSuccess();
48
+ }
49
+ return response;
50
+ }
51
+ // Should not reach here, but TypeScript needs it
52
+ throw new Error("figmaRetry: exhausted all attempts");
53
+ }
54
+ function sleep(ms) {
55
+ return new Promise((resolve) => setTimeout(resolve, ms));
56
+ }
57
+ //# sourceMappingURL=figma-retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"figma-retry.js","sourceRoot":"","sources":["../../../src/figma/figma-retry.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAiBH,gCAuDC;AAtED,qDAA8E;AAS9E;;;;;GAKG;AACI,KAAK,UAAU,UAAU,CAC9B,EAA2B,EAC3B,OAA0B;IAE1B,MAAM,EAAE,WAAW,EAAE,WAAW,GAAG,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAE1D,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;QACxD,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC;QAE5B,MAAM,QAAQ,GAAG,MAAM,EAAE,EAAE,CAAC;QAE5B,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,IAAA,sCAAqB,EAAC,QAAQ,CAAC,CAAC;YAC7C,IAAI,IAAI,EAAE,CAAC;gBACT,WAAW,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;gBAEhC,0DAA0D;gBAC1D,IAAI,IAAI,CAAC,iBAAiB,GAAG,GAAG,IAAI,IAAI,CAAC,aAAa,KAAK,KAAK,EAAE,CAAC;oBACjE,MAAM,IAAI,oCAAmB,CAC3B,wCAAwC,IAAI,CAAC,iBAAiB,IAAI,EAClE,IAAI,CACL,CAAC;gBACJ,CAAC;gBAED,IAAI,OAAO,GAAG,WAAW,EAAE,CAAC;oBAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;oBAC9C,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,iCAAiC,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;oBACxF,MAAM,KAAK,CAAC,OAAO,CAAC,CAAC;oBACrB,SAAS;gBACX,CAAC;YACH,CAAC;YAED,wBAAwB;YACxB,MAAM,IAAI,oCAAmB,CAC3B,gCAAgC,WAAW,WAAW,EACtD,IAAI,IAAI,EAAE,iBAAiB,EAAE,EAAE,EAAE,CAClC,CAAC;QACJ,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,IAAI,OAAO,GAAG,WAAW,EAAE,CAAC;YACpD,MAAM,OAAO,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa;YAC9D,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,gBAAgB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YAC/D,MAAM,KAAK,CAAC,OAAO,CAAC,CAAC;YACrB,SAAS;QACX,CAAC;QAED,iCAAiC;QACjC,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;YAChB,WAAW,CAAC,SAAS,EAAE,CAAC;QAC1B,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,iDAAiD;IACjD,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC"}
@@ -39,5 +39,5 @@ export interface FigmaLayoutNode {
39
39
  * @param token FIGMA_TOKEN
40
40
  * @returns Parsed FigmaLayoutNode tree
41
41
  */
42
- export declare function fetchFigmaStructure(fileKey: string, nodeId: string, token: string): Promise<FigmaLayoutNode>;
42
+ export declare function fetchFigmaStructure(fileKey: string, nodeId: string, token: string, client?: import("./figma-client.js").FigmaClient): Promise<FigmaLayoutNode>;
43
43
  //# sourceMappingURL=figma-structure.d.ts.map
@@ -1 +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"}
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,EACb,MAAM,CAAC,EAAE,OAAO,mBAAmB,EAAE,WAAW,GAC/C,OAAO,CAAC,eAAe,CAAC,CAmD1B"}
@@ -46,7 +46,17 @@ function parseNode(raw) {
46
46
  * @param token FIGMA_TOKEN
47
47
  * @returns Parsed FigmaLayoutNode tree
48
48
  */
49
- async function fetchFigmaStructure(fileKey, nodeId, token) {
49
+ async function fetchFigmaStructure(fileKey, nodeId, token, client) {
50
+ // Use FigmaClient path if provided — gets caching + rate limiting
51
+ if (client) {
52
+ const data = (await client.fetchStructure(fileKey, nodeId, token));
53
+ const nodeData = data.nodes?.[nodeId];
54
+ if (!nodeData?.document) {
55
+ throw new Error(`Node "${nodeId}" not found in Figma file "${fileKey}". Check the node ID.`);
56
+ }
57
+ return parseNode(nodeData.document);
58
+ }
59
+ // Legacy direct fetch path
50
60
  const apiUrl = `https://api.figma.com/v1/files/${fileKey}/nodes?ids=${encodeURIComponent(nodeId)}`;
51
61
  const controller = new AbortController();
52
62
  const timeout = setTimeout(() => controller.abort(), 20000);
@@ -1 +1 @@
1
- {"version":3,"file":"figma-structure.js","sourceRoot":"","sources":["../../../src/figma/figma-structure.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"figma-structure.js","sourceRoot":"","sources":["../../../src/figma/figma-structure.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Shared types, error classes, and header parsers for the Figma API resilience layer.
3
+ */
4
+ export interface FigmaClientConfig {
5
+ /** Disk cache directory. Default: ~/.devlens/cache */
6
+ cacheDir?: string;
7
+ /** Memory cache max size in bytes. Default: 50MB */
8
+ memoryCacheMaxBytes?: number;
9
+ /** Default metadata TTL in ms. Default: 24h */
10
+ metadataTtlMs?: number;
11
+ /** Default image buffer TTL in ms. Default: 24h */
12
+ imageTtlMs?: number;
13
+ /** Initial rate limit budget (requests per minute). Default: 10 */
14
+ rateLimitBudget?: number;
15
+ /** Max retry attempts on 429/5xx. Default: 3 */
16
+ maxRetries?: number;
17
+ }
18
+ export interface FigmaRateLimitInfo {
19
+ retryAfterSeconds: number;
20
+ /** X-Figma-Plan-Tier header (e.g., "starter", "pro", "org", "enterprise") */
21
+ planTier?: string;
22
+ /** X-Figma-Rate-Limit-Type header ("low" = View/Collab seat, "high" = Full/Dev seat) */
23
+ rateLimitType?: string;
24
+ /** X-Figma-Upgrade-Link header */
25
+ upgradeLink?: string;
26
+ }
27
+ export declare class FigmaRateLimitError extends Error {
28
+ readonly info: FigmaRateLimitInfo;
29
+ constructor(message: string, info: FigmaRateLimitInfo);
30
+ }
31
+ /**
32
+ * Parse 429 response headers into structured rate limit info.
33
+ * Returns null if the response is not a 429.
34
+ */
35
+ export declare function parseRateLimitHeaders(response: Response): FigmaRateLimitInfo | null;
36
+ export interface RateLimiterStatus {
37
+ budget: number;
38
+ tokens: number;
39
+ pausedUntil: number;
40
+ detectedPlanTier?: string;
41
+ detectedSeatType?: string;
42
+ totalRequests: number;
43
+ throttledRequests: number;
44
+ isLimited: boolean;
45
+ }
46
+ export interface CacheStats {
47
+ memoryEntries: number;
48
+ diskEntries: number;
49
+ memoryBytes: number;
50
+ hitRate: number;
51
+ hits: number;
52
+ misses: number;
53
+ }
54
+ //# sourceMappingURL=figma-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"figma-types.d.ts","sourceRoot":"","sources":["../../../src/figma/figma-types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,iBAAiB;IAChC,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,+CAA+C;IAC/C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wFAAwF;IACxF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kCAAkC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,mBAAoB,SAAQ,KAAK;aAG1B,IAAI,EAAE,kBAAkB;gBADxC,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,kBAAkB;CAK3C;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,QAAQ,GACjB,kBAAkB,GAAG,IAAI,CAY3B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB"}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ /**
3
+ * Shared types, error classes, and header parsers for the Figma API resilience layer.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.FigmaRateLimitError = void 0;
7
+ exports.parseRateLimitHeaders = parseRateLimitHeaders;
8
+ class FigmaRateLimitError extends Error {
9
+ info;
10
+ constructor(message, info) {
11
+ super(message);
12
+ this.info = info;
13
+ this.name = "FigmaRateLimitError";
14
+ }
15
+ }
16
+ exports.FigmaRateLimitError = FigmaRateLimitError;
17
+ /**
18
+ * Parse 429 response headers into structured rate limit info.
19
+ * Returns null if the response is not a 429.
20
+ */
21
+ function parseRateLimitHeaders(response) {
22
+ if (response.status !== 429)
23
+ return null;
24
+ const retryAfter = response.headers.get("retry-after");
25
+ const retryAfterSeconds = retryAfter ? parseInt(retryAfter, 10) : 60;
26
+ return {
27
+ retryAfterSeconds: isNaN(retryAfterSeconds) ? 60 : retryAfterSeconds,
28
+ planTier: response.headers.get("x-figma-plan-tier") ?? undefined,
29
+ rateLimitType: response.headers.get("x-figma-rate-limit-type") ?? undefined,
30
+ upgradeLink: response.headers.get("x-figma-upgrade-link") ?? undefined,
31
+ };
32
+ }
33
+ //# sourceMappingURL=figma-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"figma-types.js","sourceRoot":"","sources":["../../../src/figma/figma-types.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAyCH,sDAcC;AA5BD,MAAa,mBAAoB,SAAQ,KAAK;IAG1B;IAFlB,YACE,OAAe,EACC,IAAwB;QAExC,KAAK,CAAC,OAAO,CAAC,CAAC;QAFC,SAAI,GAAJ,IAAI,CAAoB;QAGxC,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACpC,CAAC;CACF;AARD,kDAQC;AAED;;;GAGG;AACH,SAAgB,qBAAqB,CACnC,QAAkB;IAElB,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAEzC,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IACvD,MAAM,iBAAiB,GAAG,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAErE,OAAO;QACL,iBAAiB,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,iBAAiB;QACpE,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,SAAS;QAChE,aAAa,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,IAAI,SAAS;QAC3E,WAAW,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,IAAI,SAAS;KACvE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,40 @@
1
+ export type PrototypeUrlType = "figma-design" | "figma-proto" | "web";
2
+ export interface ParsedFigmaUrl {
3
+ fileKey: string;
4
+ nodeId?: string;
5
+ fileName?: string;
6
+ }
7
+ export interface ParsedPrototypeUrl {
8
+ type: PrototypeUrlType;
9
+ originalUrl: string;
10
+ fileKey?: string;
11
+ nodeId?: string;
12
+ baseUrl?: string;
13
+ }
14
+ /**
15
+ * Parse a Figma design URL (supports /design/, /branch/, and both
16
+ * dash-separated and colon-separated node IDs).
17
+ */
18
+ export declare function parseFigmaUrl(url: string): ParsedFigmaUrl | undefined;
19
+ /**
20
+ * Normalise a node ID to colon-separated format ("10-200" -> "10:200").
21
+ */
22
+ export declare function normalizeNodeId(nodeId: string): string;
23
+ /**
24
+ * Detect the prototype URL type and extract relevant identifiers.
25
+ */
26
+ export declare function parsePrototypeUrl(url: string): ParsedPrototypeUrl;
27
+ /**
28
+ * Convert a Figma file key (and optional starting node) to a
29
+ * public prototype URL.
30
+ */
31
+ export declare function toPrototypeUrl(fileKey: string, startNodeId?: string): string;
32
+ /**
33
+ * Check whether a URL already points to a Figma prototype viewer.
34
+ */
35
+ export declare function isPrototypeUrl(url: string): boolean;
36
+ /**
37
+ * Normalise a web URL to its origin (scheme + host).
38
+ */
39
+ export declare function discoverBaseUrl(url: string): string;
40
+ //# sourceMappingURL=url-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url-parser.d.ts","sourceRoot":"","sources":["../../../src/figma/url-parser.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG,cAAc,GAAG,aAAa,GAAG,KAAK,CAAC;AAEtE,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,gBAAgB,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAWD;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,GACV,cAAc,GAAG,SAAS,CA6B5B;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,CA0BjE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,MAAM,GACnB,MAAM,CAOR;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAOnD"}
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseFigmaUrl = parseFigmaUrl;
4
+ exports.normalizeNodeId = normalizeNodeId;
5
+ exports.parsePrototypeUrl = parsePrototypeUrl;
6
+ exports.toPrototypeUrl = toPrototypeUrl;
7
+ exports.isPrototypeUrl = isPrototypeUrl;
8
+ exports.discoverBaseUrl = discoverBaseUrl;
9
+ const FIGMA_DESIGN_REGEX = /figma\.com\/design\/([^/]+)\/([^?/]*)\??(?:.*node-id=(\d+-\d+))?/;
10
+ const FIGMA_BRANCH_REGEX = /figma\.com\/design\/[^/]+\/branch\/([^/]+)\/([^?/]*)\??(?:.*node-id=(\d+-\d+))?/;
11
+ const FIGMA_PROTO_REGEX = /figma\.com\/proto\/([^/]+)\/([^?/]*)\??(?:.*node-id=(\d+-\d+))?/;
12
+ /**
13
+ * Parse a Figma design URL (supports /design/, /branch/, and both
14
+ * dash-separated and colon-separated node IDs).
15
+ */
16
+ function parseFigmaUrl(url) {
17
+ const branchMatch = url.match(FIGMA_BRANCH_REGEX);
18
+ if (branchMatch) {
19
+ return {
20
+ fileKey: branchMatch[1],
21
+ nodeId: branchMatch[3]?.replace("-", ":"),
22
+ fileName: decodeURIComponent(branchMatch[2] || ""),
23
+ };
24
+ }
25
+ const designMatch = url.match(FIGMA_DESIGN_REGEX);
26
+ if (designMatch) {
27
+ return {
28
+ fileKey: designMatch[1],
29
+ nodeId: designMatch[3]?.replace("-", ":"),
30
+ fileName: decodeURIComponent(designMatch[2] || ""),
31
+ };
32
+ }
33
+ const protoMatch = url.match(FIGMA_PROTO_REGEX);
34
+ if (protoMatch) {
35
+ return {
36
+ fileKey: protoMatch[1],
37
+ nodeId: protoMatch[3]?.replace("-", ":"),
38
+ fileName: decodeURIComponent(protoMatch[2] || ""),
39
+ };
40
+ }
41
+ return undefined;
42
+ }
43
+ /**
44
+ * Normalise a node ID to colon-separated format ("10-200" -> "10:200").
45
+ */
46
+ function normalizeNodeId(nodeId) {
47
+ return nodeId.replace("-", ":");
48
+ }
49
+ /**
50
+ * Detect the prototype URL type and extract relevant identifiers.
51
+ */
52
+ function parsePrototypeUrl(url) {
53
+ if (FIGMA_PROTO_REGEX.test(url)) {
54
+ const parsed = parseFigmaUrl(url);
55
+ return {
56
+ type: "figma-proto",
57
+ originalUrl: url,
58
+ fileKey: parsed?.fileKey,
59
+ nodeId: parsed?.nodeId,
60
+ };
61
+ }
62
+ if (FIGMA_DESIGN_REGEX.test(url) || FIGMA_BRANCH_REGEX.test(url)) {
63
+ const parsed = parseFigmaUrl(url);
64
+ return {
65
+ type: "figma-design",
66
+ originalUrl: url,
67
+ fileKey: parsed?.fileKey,
68
+ nodeId: parsed?.nodeId,
69
+ };
70
+ }
71
+ return {
72
+ type: "web",
73
+ originalUrl: url,
74
+ baseUrl: discoverBaseUrl(url),
75
+ };
76
+ }
77
+ /**
78
+ * Convert a Figma file key (and optional starting node) to a
79
+ * public prototype URL.
80
+ */
81
+ function toPrototypeUrl(fileKey, startNodeId) {
82
+ let url = `https://www.figma.com/proto/${fileKey}/Prototype`;
83
+ if (startNodeId) {
84
+ const dashId = startNodeId.replace(":", "-");
85
+ url += `?node-id=${dashId}&starting-point-node-id=${dashId}`;
86
+ }
87
+ return url;
88
+ }
89
+ /**
90
+ * Check whether a URL already points to a Figma prototype viewer.
91
+ */
92
+ function isPrototypeUrl(url) {
93
+ return FIGMA_PROTO_REGEX.test(url);
94
+ }
95
+ /**
96
+ * Normalise a web URL to its origin (scheme + host).
97
+ */
98
+ function discoverBaseUrl(url) {
99
+ try {
100
+ const u = new URL(url);
101
+ return u.origin;
102
+ }
103
+ catch {
104
+ return url;
105
+ }
106
+ }
107
+ //# sourceMappingURL=url-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url-parser.js","sourceRoot":"","sources":["../../../src/figma/url-parser.ts"],"names":[],"mappings":";;AA6BA,sCA+BC;AAKD,0CAEC;AAKD,8CA0BC;AAMD,wCAUC;AAKD,wCAEC;AAKD,0CAOC;AArHD,MAAM,kBAAkB,GACtB,kEAAkE,CAAC;AAErE,MAAM,kBAAkB,GACtB,iFAAiF,CAAC;AAEpF,MAAM,iBAAiB,GACrB,iEAAiE,CAAC;AAEpE;;;GAGG;AACH,SAAgB,aAAa,CAC3B,GAAW;IAEX,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAClD,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO;YACL,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC;YACvB,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC;YACzC,QAAQ,EAAE,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACnD,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAClD,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO;YACL,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC;YACvB,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC;YACzC,QAAQ,EAAE,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACnD,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAChD,IAAI,UAAU,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC;YACtB,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC;YACxC,QAAQ,EAAE,kBAAkB,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SAClD,CAAC;IACJ,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,MAAc;IAC5C,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,SAAgB,iBAAiB,CAAC,GAAW;IAC3C,IAAI,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;QAClC,OAAO;YACL,IAAI,EAAE,aAAa;YACnB,WAAW,EAAE,GAAG;YAChB,OAAO,EAAE,MAAM,EAAE,OAAO;YACxB,MAAM,EAAE,MAAM,EAAE,MAAM;SACvB,CAAC;IACJ,CAAC;IAED,IAAI,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACjE,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;QAClC,OAAO;YACL,IAAI,EAAE,cAAc;YACpB,WAAW,EAAE,GAAG;YAChB,OAAO,EAAE,MAAM,EAAE,OAAO;YACxB,MAAM,EAAE,MAAM,EAAE,MAAM;SACvB,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI,EAAE,KAAK;QACX,WAAW,EAAE,GAAG;QAChB,OAAO,EAAE,eAAe,CAAC,GAAG,CAAC;KAC9B,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAgB,cAAc,CAC5B,OAAe,EACf,WAAoB;IAEpB,IAAI,GAAG,GAAG,+BAA+B,OAAO,YAAY,CAAC;IAC7D,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC7C,GAAG,IAAI,YAAY,MAAM,2BAA2B,MAAM,EAAE,CAAC;IAC/D,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;GAEG;AACH,SAAgB,cAAc,CAAC,GAAW;IACxC,OAAO,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,GAAW;IACzC,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QACvB,OAAO,CAAC,CAAC,MAAM,CAAC;IAClB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC"}
@@ -23,6 +23,11 @@ export declare class DeviceManager {
23
23
  private checkDeviceHealth;
24
24
  private discoverAndroidDevices;
25
25
  private discoverIosDevices;
26
+ /**
27
+ * Get Device instances for multiple device IDs simultaneously.
28
+ * Used by multi-device tools for parallel operations.
29
+ */
30
+ getMultipleDevices(deviceIds: string[]): Promise<Device[]>;
26
31
  private getAdbPath;
27
32
  }
28
33
  //# sourceMappingURL=device-manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"device-manager.d.ts","sourceRoot":"","sources":["../../../src/platform/device-manager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAc,MAAM,aAAa,CAAC;AAMtD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,cAAc,CAAkC;IAElD,eAAe,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAkB9C,SAAS,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAqDnD;;;OAGG;YACW,iBAAiB;YAgCjB,sBAAsB;YAkDtB,kBAAkB;IAsChC,OAAO,CAAC,UAAU;CAQnB"}
1
+ {"version":3,"file":"device-manager.d.ts","sourceRoot":"","sources":["../../../src/platform/device-manager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAc,MAAM,aAAa,CAAC;AAMtD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,cAAc,CAAkC;IAElD,eAAe,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAkB9C,SAAS,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAqDnD;;;OAGG;YACW,iBAAiB;YAgCjB,sBAAsB;YAkDtB,kBAAkB;IAsChC;;;OAGG;IACG,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAkBhE,OAAO,CAAC,UAAU;CAQnB"}