@browserstack/mcp-server 1.2.15-beta.2 → 1.2.16-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/dist/server-factory.js +0 -4
  2. package/dist/tools/percy-sdk.js +20 -11
  3. package/dist/tools/testmanagement-utils/get-testplan.d.ts +16 -0
  4. package/dist/tools/testmanagement-utils/get-testplan.js +99 -0
  5. package/dist/tools/testmanagement-utils/list-folders.d.ts +16 -0
  6. package/dist/tools/testmanagement-utils/list-folders.js +77 -0
  7. package/dist/tools/testmanagement-utils/list-testcases.js +1 -1
  8. package/dist/tools/testmanagement-utils/list-testplans.d.ts +15 -0
  9. package/dist/tools/testmanagement-utils/list-testplans.js +75 -0
  10. package/dist/tools/testmanagement-utils/update-testcase.d.ts +16 -0
  11. package/dist/tools/testmanagement-utils/update-testcase.js +133 -10
  12. package/dist/tools/testmanagement.d.ts +15 -0
  13. package/dist/tools/testmanagement.js +73 -2
  14. package/package.json +2 -3
  15. package/dist/lib/percy-api/auth.d.ts +0 -41
  16. package/dist/lib/percy-api/auth.js +0 -96
  17. package/dist/lib/percy-api/cache.d.ts +0 -28
  18. package/dist/lib/percy-api/cache.js +0 -48
  19. package/dist/lib/percy-api/client.d.ts +0 -69
  20. package/dist/lib/percy-api/client.js +0 -275
  21. package/dist/lib/percy-api/errors.d.ts +0 -15
  22. package/dist/lib/percy-api/errors.js +0 -52
  23. package/dist/lib/percy-api/formatter.d.ts +0 -16
  24. package/dist/lib/percy-api/formatter.js +0 -344
  25. package/dist/lib/percy-api/percy-auth.d.ts +0 -43
  26. package/dist/lib/percy-api/percy-auth.js +0 -137
  27. package/dist/lib/percy-api/percy-error-handler.d.ts +0 -24
  28. package/dist/lib/percy-api/percy-error-handler.js +0 -302
  29. package/dist/lib/percy-api/percy-session.d.ts +0 -42
  30. package/dist/lib/percy-api/percy-session.js +0 -87
  31. package/dist/lib/percy-api/polling.d.ts +0 -26
  32. package/dist/lib/percy-api/polling.js +0 -42
  33. package/dist/lib/percy-api/types.d.ts +0 -56
  34. package/dist/lib/percy-api/types.js +0 -76
  35. package/dist/tools/percy-mcp/advanced/branchline-operations.d.ts +0 -16
  36. package/dist/tools/percy-mcp/advanced/branchline-operations.js +0 -81
  37. package/dist/tools/percy-mcp/advanced/manage-variants.d.ts +0 -16
  38. package/dist/tools/percy-mcp/advanced/manage-variants.js +0 -155
  39. package/dist/tools/percy-mcp/advanced/manage-visual-monitoring.d.ts +0 -16
  40. package/dist/tools/percy-mcp/advanced/manage-visual-monitoring.js +0 -171
  41. package/dist/tools/percy-mcp/auth/auth-status.d.ts +0 -3
  42. package/dist/tools/percy-mcp/auth/auth-status.js +0 -131
  43. package/dist/tools/percy-mcp/core/approve-build.d.ts +0 -14
  44. package/dist/tools/percy-mcp/core/approve-build.js +0 -97
  45. package/dist/tools/percy-mcp/core/get-build-items.d.ts +0 -13
  46. package/dist/tools/percy-mcp/core/get-build-items.js +0 -65
  47. package/dist/tools/percy-mcp/core/get-build.d.ts +0 -10
  48. package/dist/tools/percy-mcp/core/get-build.js +0 -16
  49. package/dist/tools/percy-mcp/core/get-comparison.d.ts +0 -11
  50. package/dist/tools/percy-mcp/core/get-comparison.js +0 -59
  51. package/dist/tools/percy-mcp/core/get-snapshot.d.ts +0 -10
  52. package/dist/tools/percy-mcp/core/get-snapshot.js +0 -40
  53. package/dist/tools/percy-mcp/core/list-builds.d.ts +0 -14
  54. package/dist/tools/percy-mcp/core/list-builds.js +0 -45
  55. package/dist/tools/percy-mcp/core/list-projects.d.ts +0 -12
  56. package/dist/tools/percy-mcp/core/list-projects.js +0 -51
  57. package/dist/tools/percy-mcp/creation/create-app-snapshot.d.ts +0 -12
  58. package/dist/tools/percy-mcp/creation/create-app-snapshot.js +0 -29
  59. package/dist/tools/percy-mcp/creation/create-build.d.ts +0 -19
  60. package/dist/tools/percy-mcp/creation/create-build.js +0 -68
  61. package/dist/tools/percy-mcp/creation/create-comparison.d.ts +0 -18
  62. package/dist/tools/percy-mcp/creation/create-comparison.js +0 -90
  63. package/dist/tools/percy-mcp/creation/create-snapshot.d.ts +0 -17
  64. package/dist/tools/percy-mcp/creation/create-snapshot.js +0 -99
  65. package/dist/tools/percy-mcp/creation/finalize-build.d.ts +0 -12
  66. package/dist/tools/percy-mcp/creation/finalize-build.js +0 -33
  67. package/dist/tools/percy-mcp/creation/finalize-comparison.d.ts +0 -10
  68. package/dist/tools/percy-mcp/creation/finalize-comparison.js +0 -16
  69. package/dist/tools/percy-mcp/creation/finalize-snapshot.d.ts +0 -12
  70. package/dist/tools/percy-mcp/creation/finalize-snapshot.js +0 -33
  71. package/dist/tools/percy-mcp/creation/upload-resource.d.ts +0 -15
  72. package/dist/tools/percy-mcp/creation/upload-resource.js +0 -43
  73. package/dist/tools/percy-mcp/creation/upload-tile.d.ts +0 -11
  74. package/dist/tools/percy-mcp/creation/upload-tile.js +0 -53
  75. package/dist/tools/percy-mcp/diagnostics/analyze-logs-realtime.d.ts +0 -13
  76. package/dist/tools/percy-mcp/diagnostics/analyze-logs-realtime.js +0 -65
  77. package/dist/tools/percy-mcp/diagnostics/get-build-logs.d.ts +0 -17
  78. package/dist/tools/percy-mcp/diagnostics/get-build-logs.js +0 -74
  79. package/dist/tools/percy-mcp/diagnostics/get-network-logs.d.ts +0 -5
  80. package/dist/tools/percy-mcp/diagnostics/get-network-logs.js +0 -21
  81. package/dist/tools/percy-mcp/diagnostics/get-suggestions.d.ts +0 -7
  82. package/dist/tools/percy-mcp/diagnostics/get-suggestions.js +0 -24
  83. package/dist/tools/percy-mcp/index.d.ts +0 -36
  84. package/dist/tools/percy-mcp/index.js +0 -1137
  85. package/dist/tools/percy-mcp/intelligence/get-ai-analysis.d.ts +0 -15
  86. package/dist/tools/percy-mcp/intelligence/get-ai-analysis.js +0 -166
  87. package/dist/tools/percy-mcp/intelligence/get-ai-quota.d.ts +0 -9
  88. package/dist/tools/percy-mcp/intelligence/get-ai-quota.js +0 -73
  89. package/dist/tools/percy-mcp/intelligence/get-build-summary.d.ts +0 -11
  90. package/dist/tools/percy-mcp/intelligence/get-build-summary.js +0 -78
  91. package/dist/tools/percy-mcp/intelligence/get-rca.d.ts +0 -6
  92. package/dist/tools/percy-mcp/intelligence/get-rca.js +0 -153
  93. package/dist/tools/percy-mcp/intelligence/suggest-prompt.d.ts +0 -15
  94. package/dist/tools/percy-mcp/intelligence/suggest-prompt.js +0 -86
  95. package/dist/tools/percy-mcp/intelligence/trigger-ai-recompute.d.ts +0 -16
  96. package/dist/tools/percy-mcp/intelligence/trigger-ai-recompute.js +0 -64
  97. package/dist/tools/percy-mcp/management/create-project.d.ts +0 -14
  98. package/dist/tools/percy-mcp/management/create-project.js +0 -52
  99. package/dist/tools/percy-mcp/management/get-usage-stats.d.ts +0 -12
  100. package/dist/tools/percy-mcp/management/get-usage-stats.js +0 -61
  101. package/dist/tools/percy-mcp/management/manage-browser-targets.d.ts +0 -12
  102. package/dist/tools/percy-mcp/management/manage-browser-targets.js +0 -136
  103. package/dist/tools/percy-mcp/management/manage-comments.d.ts +0 -14
  104. package/dist/tools/percy-mcp/management/manage-comments.js +0 -147
  105. package/dist/tools/percy-mcp/management/manage-ignored-regions.d.ts +0 -18
  106. package/dist/tools/percy-mcp/management/manage-ignored-regions.js +0 -182
  107. package/dist/tools/percy-mcp/management/manage-project-settings.d.ts +0 -16
  108. package/dist/tools/percy-mcp/management/manage-project-settings.js +0 -97
  109. package/dist/tools/percy-mcp/management/manage-tokens.d.ts +0 -14
  110. package/dist/tools/percy-mcp/management/manage-tokens.js +0 -90
  111. package/dist/tools/percy-mcp/management/manage-webhooks.d.ts +0 -15
  112. package/dist/tools/percy-mcp/management/manage-webhooks.js +0 -180
  113. package/dist/tools/percy-mcp/v2/auth-status.d.ts +0 -3
  114. package/dist/tools/percy-mcp/v2/auth-status.js +0 -80
  115. package/dist/tools/percy-mcp/v2/clone-build.d.ts +0 -24
  116. package/dist/tools/percy-mcp/v2/clone-build.js +0 -539
  117. package/dist/tools/percy-mcp/v2/create-app-build.d.ts +0 -28
  118. package/dist/tools/percy-mcp/v2/create-app-build.js +0 -442
  119. package/dist/tools/percy-mcp/v2/create-build.d.ts +0 -16
  120. package/dist/tools/percy-mcp/v2/create-build.js +0 -601
  121. package/dist/tools/percy-mcp/v2/create-project.d.ts +0 -8
  122. package/dist/tools/percy-mcp/v2/create-project.js +0 -33
  123. package/dist/tools/percy-mcp/v2/discover-urls.d.ts +0 -7
  124. package/dist/tools/percy-mcp/v2/discover-urls.js +0 -38
  125. package/dist/tools/percy-mcp/v2/figma-baseline.d.ts +0 -7
  126. package/dist/tools/percy-mcp/v2/figma-baseline.js +0 -18
  127. package/dist/tools/percy-mcp/v2/figma-build.d.ts +0 -7
  128. package/dist/tools/percy-mcp/v2/figma-build.js +0 -39
  129. package/dist/tools/percy-mcp/v2/figma-link.d.ts +0 -6
  130. package/dist/tools/percy-mcp/v2/figma-link.js +0 -27
  131. package/dist/tools/percy-mcp/v2/get-ai-summary.d.ts +0 -5
  132. package/dist/tools/percy-mcp/v2/get-ai-summary.js +0 -109
  133. package/dist/tools/percy-mcp/v2/get-build-detail.d.ts +0 -22
  134. package/dist/tools/percy-mcp/v2/get-build-detail.js +0 -567
  135. package/dist/tools/percy-mcp/v2/get-builds.d.ts +0 -8
  136. package/dist/tools/percy-mcp/v2/get-builds.js +0 -63
  137. package/dist/tools/percy-mcp/v2/get-comparison.d.ts +0 -5
  138. package/dist/tools/percy-mcp/v2/get-comparison.js +0 -94
  139. package/dist/tools/percy-mcp/v2/get-devices.d.ts +0 -5
  140. package/dist/tools/percy-mcp/v2/get-devices.js +0 -33
  141. package/dist/tools/percy-mcp/v2/get-insights.d.ts +0 -7
  142. package/dist/tools/percy-mcp/v2/get-insights.js +0 -52
  143. package/dist/tools/percy-mcp/v2/get-projects.d.ts +0 -6
  144. package/dist/tools/percy-mcp/v2/get-projects.js +0 -41
  145. package/dist/tools/percy-mcp/v2/get-snapshot.d.ts +0 -5
  146. package/dist/tools/percy-mcp/v2/get-snapshot.js +0 -96
  147. package/dist/tools/percy-mcp/v2/get-test-case-history.d.ts +0 -5
  148. package/dist/tools/percy-mcp/v2/get-test-case-history.js +0 -20
  149. package/dist/tools/percy-mcp/v2/get-test-cases.d.ts +0 -6
  150. package/dist/tools/percy-mcp/v2/get-test-cases.js +0 -36
  151. package/dist/tools/percy-mcp/v2/index.d.ts +0 -35
  152. package/dist/tools/percy-mcp/v2/index.js +0 -544
  153. package/dist/tools/percy-mcp/v2/list-integrations.d.ts +0 -5
  154. package/dist/tools/percy-mcp/v2/list-integrations.js +0 -41
  155. package/dist/tools/percy-mcp/v2/manage-domains.d.ts +0 -8
  156. package/dist/tools/percy-mcp/v2/manage-domains.js +0 -33
  157. package/dist/tools/percy-mcp/v2/manage-insights-email.d.ts +0 -8
  158. package/dist/tools/percy-mcp/v2/manage-insights-email.js +0 -49
  159. package/dist/tools/percy-mcp/v2/manage-usage-alerts.d.ts +0 -10
  160. package/dist/tools/percy-mcp/v2/manage-usage-alerts.js +0 -43
  161. package/dist/tools/percy-mcp/v2/migrate-integrations.d.ts +0 -6
  162. package/dist/tools/percy-mcp/v2/migrate-integrations.js +0 -20
  163. package/dist/tools/percy-mcp/v2/preview-comparison.d.ts +0 -5
  164. package/dist/tools/percy-mcp/v2/preview-comparison.js +0 -17
  165. package/dist/tools/percy-mcp/v2/search-build-items.d.ts +0 -12
  166. package/dist/tools/percy-mcp/v2/search-build-items.js +0 -45
  167. package/dist/tools/percy-mcp/workflows/auto-triage.d.ts +0 -7
  168. package/dist/tools/percy-mcp/workflows/auto-triage.js +0 -82
  169. package/dist/tools/percy-mcp/workflows/clone-build.d.ts +0 -22
  170. package/dist/tools/percy-mcp/workflows/clone-build.js +0 -414
  171. package/dist/tools/percy-mcp/workflows/create-percy-build.d.ts +0 -32
  172. package/dist/tools/percy-mcp/workflows/create-percy-build.js +0 -434
  173. package/dist/tools/percy-mcp/workflows/debug-failed-build.d.ts +0 -5
  174. package/dist/tools/percy-mcp/workflows/debug-failed-build.js +0 -122
  175. package/dist/tools/percy-mcp/workflows/diff-explain.d.ts +0 -6
  176. package/dist/tools/percy-mcp/workflows/diff-explain.js +0 -147
  177. package/dist/tools/percy-mcp/workflows/pr-visual-report.d.ts +0 -8
  178. package/dist/tools/percy-mcp/workflows/pr-visual-report.js +0 -184
  179. package/dist/tools/percy-mcp/workflows/run-tests.d.ts +0 -17
  180. package/dist/tools/percy-mcp/workflows/run-tests.js +0 -107
  181. package/dist/tools/percy-mcp/workflows/snapshot-urls.d.ts +0 -18
  182. package/dist/tools/percy-mcp/workflows/snapshot-urls.js +0 -197
@@ -1,275 +0,0 @@
1
- /**
2
- * Percy API HTTP client.
3
- *
4
- * Uses native `fetch` (consistent with existing Percy tools in this repo).
5
- * Handles JSON:API deserialization, rate limiting, and error enrichment.
6
- *
7
- * SECURITY: Token values are NEVER logged or exposed in error messages.
8
- */
9
- import { getPercyHeaders, getPercyApiBaseUrl } from "./auth.js";
10
- import { enrichPercyError } from "./errors.js";
11
- // ---------------------------------------------------------------------------
12
- // Helpers – kebab-case to camelCase
13
- // ---------------------------------------------------------------------------
14
- function kebabToCamel(str) {
15
- return str.replace(/-([a-z0-9])/g, (_, char) => char.toUpperCase());
16
- }
17
- function camelCaseKeys(obj) {
18
- if (obj === null || obj === undefined) {
19
- return obj;
20
- }
21
- if (Array.isArray(obj)) {
22
- return obj.map(camelCaseKeys);
23
- }
24
- if (typeof obj === "object") {
25
- const result = {};
26
- for (const [key, value] of Object.entries(obj)) {
27
- const camelKey = kebabToCamel(key);
28
- result[camelKey] =
29
- value !== null && typeof value === "object"
30
- ? camelCaseKeys(value)
31
- : value;
32
- }
33
- return result;
34
- }
35
- return obj;
36
- }
37
- // ---------------------------------------------------------------------------
38
- // JSON:API Deserializer
39
- // ---------------------------------------------------------------------------
40
- /**
41
- * Builds a lookup index of included resources keyed by `type:id`.
42
- */
43
- function buildIncludedIndex(included) {
44
- const index = new Map();
45
- for (const resource of included) {
46
- const flattened = flattenResource(resource);
47
- index.set(`${resource.type}:${resource.id}`, flattened);
48
- }
49
- return index;
50
- }
51
- /**
52
- * Flattens a single JSON:API resource — merges `attributes` into the top
53
- * level alongside `id` and `type`, converting keys to camelCase.
54
- */
55
- function flattenResource(resource) {
56
- const attrs = resource.attributes
57
- ? camelCaseKeys(resource.attributes)
58
- : {};
59
- return {
60
- id: resource.id,
61
- type: resource.type,
62
- ...attrs,
63
- };
64
- }
65
- /**
66
- * Resolves relationships for a resource against the included index.
67
- * Returns the resolved object(s) or the raw { id, type } ref when not found.
68
- */
69
- function resolveRelationships(resource, index) {
70
- if (!resource.relationships) {
71
- return {};
72
- }
73
- const resolved = {};
74
- for (const [relName, relValue] of Object.entries(resource.relationships)) {
75
- const camelName = kebabToCamel(relName);
76
- const { data } = relValue;
77
- if (data === null || data === undefined) {
78
- resolved[camelName] = null;
79
- }
80
- else if (Array.isArray(data)) {
81
- resolved[camelName] = data.map((ref) => index.get(`${ref.type}:${ref.id}`) ?? { id: ref.id, type: ref.type });
82
- }
83
- else {
84
- resolved[camelName] = index.get(`${data.type}:${data.id}`) ?? {
85
- id: data.id,
86
- type: data.type,
87
- };
88
- }
89
- }
90
- return resolved;
91
- }
92
- /**
93
- * Deserializes a JSON:API envelope into plain objects.
94
- *
95
- * - `data: null` → returns `null`
96
- * - `data: []` → returns `[]`
97
- * - `data: { ... }` → returns a single deserialized object
98
- * - `data: [{ ... }, ...]` → returns an array of deserialized objects
99
- */
100
- export function deserialize(envelope) {
101
- const included = envelope.included ?? [];
102
- const index = buildIncludedIndex(included);
103
- if (envelope.data === null || envelope.data === undefined) {
104
- return { data: null, meta: envelope.meta };
105
- }
106
- if (Array.isArray(envelope.data)) {
107
- const records = envelope.data.map((resource) => ({
108
- ...flattenResource(resource),
109
- ...resolveRelationships(resource, index),
110
- }));
111
- return { data: records, meta: envelope.meta };
112
- }
113
- const record = {
114
- ...flattenResource(envelope.data),
115
- ...resolveRelationships(envelope.data, index),
116
- };
117
- return { data: record, meta: envelope.meta };
118
- }
119
- // ---------------------------------------------------------------------------
120
- // Rate Limit / Retry
121
- // ---------------------------------------------------------------------------
122
- const MAX_RETRIES = 3;
123
- const BASE_RETRY_DELAY_MS = 1_000;
124
- async function sleep(ms) {
125
- return new Promise((resolve) => setTimeout(resolve, ms));
126
- }
127
- // ---------------------------------------------------------------------------
128
- // PercyClient
129
- // ---------------------------------------------------------------------------
130
- export class PercyClient {
131
- config;
132
- options;
133
- constructor(config, options) {
134
- this.config = config;
135
- this.options = options ?? {};
136
- }
137
- // -----------------------------------------------------------------------
138
- // Public HTTP methods
139
- // -----------------------------------------------------------------------
140
- /**
141
- * GET request with optional query params and JSON:API `include`.
142
- */
143
- async get(path, params, includes) {
144
- const url = this.buildUrl(path, params, includes);
145
- return this.request("GET", url);
146
- }
147
- /**
148
- * POST request with an optional JSON body.
149
- */
150
- async post(path, body) {
151
- const url = this.buildUrl(path);
152
- return this.request("POST", url, body);
153
- }
154
- /**
155
- * PATCH request with an optional JSON body.
156
- */
157
- async patch(path, body) {
158
- const url = this.buildUrl(path);
159
- return this.request("PATCH", url, body);
160
- }
161
- /**
162
- * DELETE request.
163
- */
164
- async del(path) {
165
- const url = this.buildUrl(path);
166
- await this.request("DELETE", url);
167
- }
168
- // -----------------------------------------------------------------------
169
- // Internal
170
- // -----------------------------------------------------------------------
171
- buildUrl(path, params, includes) {
172
- const base = getPercyApiBaseUrl();
173
- // Ensure no double slashes between base and path
174
- const normalizedPath = path.startsWith("/") ? path : `/${path}`;
175
- const url = new URL(`${base}${normalizedPath}`);
176
- if (params) {
177
- for (const [key, value] of Object.entries(params)) {
178
- url.searchParams.set(key, value);
179
- }
180
- }
181
- if (includes && includes.length > 0) {
182
- url.searchParams.set("include", includes.join(","));
183
- }
184
- return url.toString();
185
- }
186
- async request(method, url, body) {
187
- const headers = await getPercyHeaders(this.config, {
188
- scope: this.options.scope,
189
- projectName: this.options.projectName,
190
- });
191
- let lastError;
192
- for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
193
- const fetchOptions = {
194
- method,
195
- headers,
196
- };
197
- if (body !== undefined) {
198
- fetchOptions.body = JSON.stringify(body);
199
- }
200
- let response;
201
- try {
202
- response = await fetch(url, fetchOptions);
203
- }
204
- catch (networkError) {
205
- lastError =
206
- networkError instanceof Error
207
- ? networkError
208
- : new Error(String(networkError));
209
- // Network errors are not retryable via the rate-limit path,
210
- // but we still respect the retry loop for consistency.
211
- if (attempt < MAX_RETRIES) {
212
- await sleep(BASE_RETRY_DELAY_MS * Math.pow(2, attempt));
213
- continue;
214
- }
215
- throw lastError;
216
- }
217
- // 204 No Content
218
- if (response.status === 204) {
219
- return undefined;
220
- }
221
- // Rate limited — retry with backoff
222
- if (response.status === 429) {
223
- const retryAfter = response.headers.get("Retry-After");
224
- const delayMs = retryAfter
225
- ? parseFloat(retryAfter) * 1_000
226
- : BASE_RETRY_DELAY_MS * Math.pow(2, attempt);
227
- if (attempt < MAX_RETRIES) {
228
- await sleep(delayMs);
229
- continue;
230
- }
231
- // Exhausted retries — throw enriched error
232
- let errorBody;
233
- try {
234
- errorBody = await response.json();
235
- }
236
- catch {
237
- errorBody = undefined;
238
- }
239
- throw enrichPercyError(429, errorBody, `${method} ${url}`);
240
- }
241
- // Non-2xx error
242
- if (!response.ok) {
243
- let errorBody;
244
- try {
245
- errorBody = await response.json();
246
- }
247
- catch {
248
- errorBody = undefined;
249
- }
250
- throw enrichPercyError(response.status, errorBody, `${method} ${url}`);
251
- }
252
- // Successful JSON response — deserialize JSON:API
253
- const json = await response.json();
254
- // If the response has a JSON:API `data` key, deserialize it
255
- if (json && typeof json === "object" && "data" in json) {
256
- const deserialized = deserialize(json);
257
- // Unwrap: return the data directly (single object or array)
258
- // Attach meta as a non-enumerable property so it's accessible but doesn't clutter
259
- const result = deserialized.data;
260
- if (result && typeof result === "object" && deserialized.meta) {
261
- Object.defineProperty(result, "__meta", {
262
- value: deserialized.meta,
263
- enumerable: false,
264
- writable: false,
265
- });
266
- }
267
- return result;
268
- }
269
- // Non-JSON:API response — return as-is
270
- return json;
271
- }
272
- // Should not reach here, but satisfy TypeScript
273
- throw lastError ?? new Error("Request failed after retries");
274
- }
275
- }
@@ -1,15 +0,0 @@
1
- /**
2
- * Percy API error enrichment module.
3
- * Maps Percy API error responses to actionable, user-friendly messages.
4
- */
5
- export declare class PercyApiError extends Error {
6
- statusCode: number;
7
- errorCode?: string;
8
- body?: unknown;
9
- constructor(message: string, statusCode: number, errorCode?: string, body?: unknown);
10
- }
11
- /**
12
- * Maps Percy API error responses to actionable messages.
13
- * Handles known error codes from Percy's JSON:API responses.
14
- */
15
- export declare function enrichPercyError(status: number, body: unknown, context?: string): PercyApiError;
@@ -1,52 +0,0 @@
1
- /**
2
- * Percy API error enrichment module.
3
- * Maps Percy API error responses to actionable, user-friendly messages.
4
- */
5
- export class PercyApiError extends Error {
6
- statusCode;
7
- errorCode;
8
- body;
9
- constructor(message, statusCode, errorCode, body) {
10
- super(message);
11
- this.name = "PercyApiError";
12
- this.statusCode = statusCode;
13
- this.errorCode = errorCode;
14
- this.body = body;
15
- }
16
- }
17
- /**
18
- * Maps Percy API error responses to actionable messages.
19
- * Handles known error codes from Percy's JSON:API responses.
20
- */
21
- export function enrichPercyError(status, body, context) {
22
- const prefix = context ? `${context}: ` : "";
23
- const errorBody = body;
24
- const errors = (errorBody?.errors ?? []);
25
- const firstError = errors[0];
26
- const errorCode = (firstError?.code ?? firstError?.source);
27
- const detail = (firstError?.detail ?? firstError?.title ?? "");
28
- switch (status) {
29
- case 401:
30
- return new PercyApiError(`${prefix}Percy token is invalid or expired. Check PERCY_TOKEN environment variable.`, 401, errorCode, body);
31
- case 403: {
32
- if (errorCode === "project_rbac_access_denied") {
33
- return new PercyApiError(`${prefix}Insufficient permissions. This operation requires write access to the project.`, 403, errorCode, body);
34
- }
35
- if (errorCode === "build_deleted") {
36
- return new PercyApiError(`${prefix}This build has been deleted.`, 403, errorCode, body);
37
- }
38
- if (errorCode === "plan_history_exceeded") {
39
- return new PercyApiError(`${prefix}This build is outside your plan's history limit.`, 403, errorCode, body);
40
- }
41
- return new PercyApiError(`${prefix}Forbidden: ${detail || "Access denied."}`, 403, errorCode, body);
42
- }
43
- case 404:
44
- return new PercyApiError(`${prefix}Resource not found. Check the ID and try again.`, 404, errorCode, body);
45
- case 422:
46
- return new PercyApiError(`${prefix}Invalid request: ${detail || "Unprocessable entity."}`, 422, errorCode, body);
47
- case 429:
48
- return new PercyApiError(`${prefix}Rate limit exceeded. Try again shortly.`, 429, errorCode, body);
49
- default:
50
- return new PercyApiError(`${prefix}Percy API error (${status}): ${detail || "Unknown error"}`, status, errorCode, body);
51
- }
52
- }
@@ -1,16 +0,0 @@
1
- /**
2
- * Markdown formatting utilities for Percy API responses.
3
- *
4
- * Each function transforms typed Percy API data into concise,
5
- * agent-readable markdown. All functions handle null/undefined
6
- * fields gracefully — showing "N/A" or omitting the section.
7
- */
8
- export declare function formatBuild(build: any): string;
9
- export declare function formatSnapshot(snapshot: any, comparisons?: any[]): string;
10
- export declare function formatComparison(comparison: any, options?: {
11
- includeRegions?: boolean;
12
- }): string;
13
- export declare function formatSuggestions(suggestions: any[]): string;
14
- export declare function formatNetworkLogs(logs: any[]): string;
15
- export declare function formatBuildStatus(build: any): string;
16
- export declare function formatAiWarning(comparisons: any[]): string;