framewatch-mcp-server 0.1.1 → 0.2.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 (127) hide show
  1. package/README.md +797 -8
  2. package/dist/constants.d.ts +264 -0
  3. package/dist/constants.js +268 -0
  4. package/dist/constants.js.map +1 -1
  5. package/dist/engine/browser.js +4 -0
  6. package/dist/engine/browser.js.map +1 -1
  7. package/dist/engine/clicks.d.ts +221 -0
  8. package/dist/engine/clicks.js +801 -0
  9. package/dist/engine/clicks.js.map +1 -0
  10. package/dist/engine/forms.d.ts +137 -0
  11. package/dist/engine/forms.js +474 -0
  12. package/dist/engine/forms.js.map +1 -0
  13. package/dist/engine/hmr.d.ts +41 -0
  14. package/dist/engine/hmr.js +91 -0
  15. package/dist/engine/hmr.js.map +1 -0
  16. package/dist/engine/inspect.d.ts +31 -0
  17. package/dist/engine/inspect.js +383 -0
  18. package/dist/engine/inspect.js.map +1 -0
  19. package/dist/engine/interaction.d.ts +6 -1
  20. package/dist/engine/interaction.js +21 -6
  21. package/dist/engine/interaction.js.map +1 -1
  22. package/dist/engine/links.d.ts +134 -0
  23. package/dist/engine/links.js +384 -0
  24. package/dist/engine/links.js.map +1 -0
  25. package/dist/engine/mocks.d.ts +53 -0
  26. package/dist/engine/mocks.js +148 -0
  27. package/dist/engine/mocks.js.map +1 -0
  28. package/dist/engine/rtl.d.ts +129 -0
  29. package/dist/engine/rtl.js +540 -0
  30. package/dist/engine/rtl.js.map +1 -0
  31. package/dist/engine/seo.d.ts +189 -0
  32. package/dist/engine/seo.js +398 -0
  33. package/dist/engine/seo.js.map +1 -0
  34. package/dist/engine/snapshot.d.ts +29 -0
  35. package/dist/engine/snapshot.js +10 -0
  36. package/dist/engine/snapshot.js.map +1 -0
  37. package/dist/engine/vue.d.ts +54 -0
  38. package/dist/engine/vue.js +419 -0
  39. package/dist/engine/vue.js.map +1 -0
  40. package/dist/index.js +42 -1
  41. package/dist/index.js.map +1 -1
  42. package/dist/tools/accessibility.js +4 -3
  43. package/dist/tools/accessibility.js.map +1 -1
  44. package/dist/tools/api-mock.d.ts +405 -0
  45. package/dist/tools/api-mock.js +186 -0
  46. package/dist/tools/api-mock.js.map +1 -0
  47. package/dist/tools/capture.d.ts +83 -23
  48. package/dist/tools/capture.js +105 -60
  49. package/dist/tools/capture.js.map +1 -1
  50. package/dist/tools/compare.js +4 -3
  51. package/dist/tools/compare.js.map +1 -1
  52. package/dist/tools/dead-clicks.d.ts +128 -0
  53. package/dist/tools/dead-clicks.js +570 -0
  54. package/dist/tools/dead-clicks.js.map +1 -0
  55. package/dist/tools/form-test.d.ts +112 -0
  56. package/dist/tools/form-test.js +477 -0
  57. package/dist/tools/form-test.js.map +1 -0
  58. package/dist/tools/index.d.ts +16 -1
  59. package/dist/tools/index.js +42 -1
  60. package/dist/tools/index.js.map +1 -1
  61. package/dist/tools/inspect.d.ts +78 -0
  62. package/dist/tools/inspect.js +136 -0
  63. package/dist/tools/inspect.js.map +1 -0
  64. package/dist/tools/interact.d.ts +29 -16
  65. package/dist/tools/interact.js +99 -13
  66. package/dist/tools/interact.js.map +1 -1
  67. package/dist/tools/links.d.ts +129 -0
  68. package/dist/tools/links.js +640 -0
  69. package/dist/tools/links.js.map +1 -0
  70. package/dist/tools/responsive.d.ts +6 -6
  71. package/dist/tools/responsive.js +9 -9
  72. package/dist/tools/responsive.js.map +1 -1
  73. package/dist/tools/rtl.d.ts +241 -0
  74. package/dist/tools/rtl.js +410 -0
  75. package/dist/tools/rtl.js.map +1 -0
  76. package/dist/tools/save-auth.d.ts +22 -22
  77. package/dist/tools/screenshot.js +13 -5
  78. package/dist/tools/screenshot.js.map +1 -1
  79. package/dist/tools/seo.d.ts +113 -0
  80. package/dist/tools/seo.js +281 -0
  81. package/dist/tools/seo.js.map +1 -0
  82. package/dist/tools/snapshot.d.ts +122 -0
  83. package/dist/tools/snapshot.js +183 -0
  84. package/dist/tools/snapshot.js.map +1 -0
  85. package/dist/tools/wait-for.d.ts +107 -0
  86. package/dist/tools/wait-for.js +167 -0
  87. package/dist/tools/wait-for.js.map +1 -0
  88. package/dist/utils/arabic-text.d.ts +14 -0
  89. package/dist/utils/arabic-text.js +193 -0
  90. package/dist/utils/arabic-text.js.map +1 -0
  91. package/dist/utils/budget.d.ts +41 -0
  92. package/dist/utils/budget.js +182 -0
  93. package/dist/utils/budget.js.map +1 -0
  94. package/dist/utils/format.d.ts +11 -1
  95. package/dist/utils/format.js +27 -4
  96. package/dist/utils/format.js.map +1 -1
  97. package/dist/utils/highlight.d.ts +69 -0
  98. package/dist/utils/highlight.js +181 -0
  99. package/dist/utils/highlight.js.map +1 -0
  100. package/dist/utils/link-rules.d.ts +100 -0
  101. package/dist/utils/link-rules.js +284 -0
  102. package/dist/utils/link-rules.js.map +1 -0
  103. package/dist/utils/mock-rules.d.ts +144 -0
  104. package/dist/utils/mock-rules.js +224 -0
  105. package/dist/utils/mock-rules.js.map +1 -0
  106. package/dist/utils/rtl-rules.d.ts +142 -0
  107. package/dist/utils/rtl-rules.js +296 -0
  108. package/dist/utils/rtl-rules.js.map +1 -0
  109. package/dist/utils/seo-rules.d.ts +129 -0
  110. package/dist/utils/seo-rules.js +726 -0
  111. package/dist/utils/seo-rules.js.map +1 -0
  112. package/dist/utils/snapshot-rules.d.ts +33 -0
  113. package/dist/utils/snapshot-rules.js +111 -0
  114. package/dist/utils/snapshot-rules.js.map +1 -0
  115. package/dist/utils/storage-state.d.ts +42 -1
  116. package/dist/utils/storage-state.js +115 -4
  117. package/dist/utils/storage-state.js.map +1 -1
  118. package/dist/utils/style-rules.d.ts +107 -0
  119. package/dist/utils/style-rules.js +223 -0
  120. package/dist/utils/style-rules.js.map +1 -0
  121. package/dist/utils/test-data.d.ts +75 -0
  122. package/dist/utils/test-data.js +294 -0
  123. package/dist/utils/test-data.js.map +1 -0
  124. package/dist/utils/vue-rules.d.ts +72 -0
  125. package/dist/utils/vue-rules.js +108 -0
  126. package/dist/utils/vue-rules.js.map +1 -0
  127. package/package.json +6 -4
@@ -180,3 +180,267 @@ export declare const SERVER_PORT_POLL_MS = 200;
180
180
  export declare const SERVER_PORT_PROBE_TIMEOUT_MS = 1000;
181
181
  /** Time a stopped server gets to exit on SIGTERM before it is killed outright. */
182
182
  export declare const SERVER_STOP_GRACE_MS = 5000;
183
+ /** How much text a `maxlength` strategy puts in a field that declares no limit of its own. */
184
+ export declare const MAX_FORM_FILL_LENGTH = 10000;
185
+ /** Default settle time after a submit before the result is read and photographed. */
186
+ export declare const DEFAULT_FORM_WAIT_MS = 2000;
187
+ /**
188
+ * Settle time between filling the last field and the "after fill" screenshot.
189
+ * Live validation runs on blur/input and often on a debounce, so a shot taken
190
+ * the instant the last field is filled shows a form that has not reacted yet.
191
+ */
192
+ export declare const FORM_FILL_SETTLE_MS = 300;
193
+ /** Fields one strategy will fill. A form longer than this is filled up to the cap and says so. */
194
+ export declare const MAX_FORM_FIELDS = 60;
195
+ /** Fields listed by name in the report for one strategy, before the rest are counted instead. */
196
+ export declare const MAX_FORM_FIELDS_LISTED = 10;
197
+ /** Validation messages (browser-side and on-page alike) listed per strategy. */
198
+ export declare const MAX_FORM_ERRORS = 8;
199
+ /** Network requests listed per strategy. */
200
+ export declare const MAX_FORM_NETWORK_EVENTS = 8;
201
+ /** Console entries listed per strategy. */
202
+ export declare const MAX_FORM_CONSOLE_ENTRIES = 8;
203
+ /** Length of one echoed field value or error message before it is elided. */
204
+ export declare const MAX_FORM_TEXT_LENGTH = 80;
205
+ /** Validation messages read off the page in one scan, and the longest text counted as a message. */
206
+ export declare const MAX_FORM_MESSAGES = 20;
207
+ export declare const MAX_FORM_MESSAGE_LENGTH = 200;
208
+ /** Bound on one form-test screenshot. A page wedged by its own submit handler must not stall the run. */
209
+ export declare const FORM_SCREENSHOT_TIMEOUT_MS = 5000;
210
+ /** Default settle time after load before the page is read. */
211
+ export declare const DEFAULT_SEO_WAIT_MS = 1000;
212
+ /**
213
+ * Title length bounds. Search results are laid out in pixels, not characters,
214
+ * so these are the usual rules of thumb rather than hard limits: under 30
215
+ * characters is leaving the strongest ranking signal on the page unused, and
216
+ * past 60 the tail is generally cut off.
217
+ */
218
+ export declare const SEO_TITLE_MIN = 30;
219
+ export declare const SEO_TITLE_MAX = 60;
220
+ /** Meta description bounds — the snippet is cut somewhere around 160 characters. */
221
+ export declare const SEO_DESCRIPTION_MIN = 70;
222
+ export declare const SEO_DESCRIPTION_MAX = 160;
223
+ /** What a share image should be: the 1.91:1 card the networks render, and the floor below which they render none. */
224
+ export declare const SEO_OG_IMAGE_IDEAL: {
225
+ readonly width: 1200;
226
+ readonly height: 630;
227
+ };
228
+ export declare const SEO_OG_IMAGE_MIN: {
229
+ readonly width: 200;
230
+ readonly height: 200;
231
+ };
232
+ /** Headings listed in the outline before the rest are counted instead. */
233
+ export declare const MAX_SEO_HEADINGS = 40;
234
+ /** Images listed by source when they have no alt text. */
235
+ export declare const MAX_SEO_IMAGES_LISTED = 10;
236
+ /** JSON-LD blocks parsed, and the length of one before it is elided. */
237
+ export declare const MAX_SEO_JSONLD_BLOCKS = 10;
238
+ export declare const MAX_SEO_JSONLD_LENGTH = 20000;
239
+ /** Length of one echoed value (title, heading, URL) before it is elided. */
240
+ export declare const MAX_SEO_TEXT_LENGTH = 120;
241
+ /** Bounds on the two extra requests an audit makes: robots.txt and the share image. */
242
+ export declare const SEO_FETCH_TIMEOUT_MS = 8000;
243
+ /** A share image larger than this is measured and reported but never returned as an image block. */
244
+ export declare const MAX_SEO_IMAGE_BYTES = 8000000;
245
+ /**
246
+ * Core Web Vitals thresholds — Google's own "good" and "poor" boundaries.
247
+ * These are lab numbers from one headless load, so they are reported as
248
+ * measurements with a verdict attached, never as a score.
249
+ */
250
+ export declare const SEO_LCP_GOOD_MS = 2500;
251
+ export declare const SEO_LCP_POOR_MS = 4000;
252
+ export declare const SEO_CLS_GOOD = 0.1;
253
+ export declare const SEO_CLS_POOR = 0.25;
254
+ export declare const SEO_TTFB_GOOD_MS = 800;
255
+ export declare const SEO_TTFB_POOR_MS = 1800;
256
+ /** Resource types listed in the page-weight breakdown. */
257
+ export declare const MAX_SEO_RESOURCE_TYPES = 6;
258
+ /** DOM size Lighthouse starts warning about, and the size it calls excessive. */
259
+ export declare const SEO_DOM_NODES_WARN = 1400;
260
+ export declare const SEO_DOM_NODES_POOR = 3000;
261
+ /** Default settle time after load before the page is swept for clickable elements. */
262
+ export declare const DEFAULT_DEAD_CLICK_WAIT_MS = 1000;
263
+ /**
264
+ * How long the page is watched after each click before the verdict is taken.
265
+ * Long enough for a handler, a render and a fetch to start; short enough that
266
+ * forty of them do not turn one tool call into a minute of waiting.
267
+ */
268
+ export declare const DEFAULT_DEAD_CLICK_SETTLE_MS = 500;
269
+ /** Elements one sweep clicks by default, and the hard cap. Every one costs a click and a settle. */
270
+ export declare const DEFAULT_DEAD_CLICK_ELEMENTS = 40;
271
+ export declare const MAX_DEAD_CLICK_ELEMENTS = 100;
272
+ /**
273
+ * Bound on one click and on re-finding the element it belongs to. Much shorter
274
+ * than SELECTOR_TIMEOUT_MS: a control that cannot be clicked within this is a
275
+ * finding in its own right, and waiting ten seconds for each of forty of them
276
+ * is not a test anybody would run twice.
277
+ */
278
+ export declare const DEAD_CLICK_TIMEOUT_MS = 3000;
279
+ /** Elements walked when looking for clickable ones. Past this the page is reporting a tree, not a screen. */
280
+ export declare const MAX_DEAD_CLICK_SCAN = 5000;
281
+ /** Settle time after hovering an element before its hover styles are read (CSS transitions). */
282
+ export declare const DEAD_CLICK_HOVER_SETTLE_MS = 250;
283
+ /** DOM mutations quoted under one element before the rest are counted instead. */
284
+ export declare const MAX_DEAD_CLICK_CHANGES = 6;
285
+ /**
286
+ * Distinct mutation descriptions the page keeps per window.
287
+ *
288
+ * Comfortably more than are ever printed, and for a reason: what a click did
289
+ * is decided by which of these the page does *not* also do on its own, so a
290
+ * list that filled up with a ticking clock's churn would hide the one change
291
+ * that mattered.
292
+ */
293
+ export declare const MAX_DEAD_CLICK_CHANGE_SAMPLES = 24;
294
+ /** Elements listed in each section of the report before the rest are counted instead. */
295
+ export declare const MAX_DEAD_CLICK_LISTED = 20;
296
+ /** Effects listed for one element before the rest are counted instead. */
297
+ export declare const MAX_DEAD_CLICK_EFFECTS = 5;
298
+ /** Length of one element's visible text, and of one generated selector, before it is elided. */
299
+ export declare const MAX_DEAD_CLICK_TEXT_LENGTH = 60;
300
+ export declare const MAX_DEAD_CLICK_SELECTOR_LENGTH = 120;
301
+ /** Boxes one overlay draws. Past this the screenshot is a colour field, not a finding. */
302
+ export declare const MAX_HIGHLIGHTS = 30;
303
+ /** The overlay's colours: what a dead element is painted, and what a broken one is. */
304
+ export declare const HIGHLIGHT_DEAD_COLOUR = "#e5194b";
305
+ export declare const HIGHLIGHT_BROKEN_COLOUR = "#f08c00";
306
+ /** Default settle time after each page load before its links are read. */
307
+ export declare const DEFAULT_LINKS_WAIT_MS = 1000;
308
+ /** Bound on one link check, and the bounds the caller may set. */
309
+ export declare const DEFAULT_LINK_TIMEOUT_MS = 5000;
310
+ export declare const MIN_LINK_TIMEOUT_MS = 100;
311
+ export declare const MAX_LINK_TIMEOUT_MS = 30000;
312
+ /** Link checks in flight at once. Every one of them is a real request to somebody's server. */
313
+ export declare const DEFAULT_LINK_CONCURRENCY = 5;
314
+ export declare const MAX_LINK_CONCURRENCY = 10;
315
+ /**
316
+ * Redirects followed before a chain is called endless. Generous next to the
317
+ * two or three a real site uses, and far below the point where following one
318
+ * more would tell anybody anything.
319
+ */
320
+ export declare const MAX_LINK_REDIRECTS = 10;
321
+ /** Distinct URLs one run will check, and how deep a crawl may go. */
322
+ export declare const DEFAULT_MAX_LINKS = 200;
323
+ export declare const MAX_LINKS_CAP = 500;
324
+ export declare const MAX_LINK_DEPTH = 3;
325
+ /** Pages one crawl will open. Each is a full browser navigation, not a fetch. */
326
+ export declare const DEFAULT_LINK_PAGES = 10;
327
+ export declare const MAX_LINK_PAGES = 25;
328
+ /** Elements walked when collecting links. Past this the page is a document dump, not a screen. */
329
+ export declare const MAX_LINK_SCAN = 5000;
330
+ /** Links listed in one section of the report before the rest are counted instead. */
331
+ export declare const MAX_LINKS_LISTED = 25;
332
+ /** Places one link is named as appearing before the rest are counted instead. */
333
+ export declare const MAX_LINK_SOURCES_LISTED = 3;
334
+ /** Length of one link's text, URL and selector before each is elided. */
335
+ export declare const MAX_LINK_TEXT_LENGTH = 60;
336
+ export declare const MAX_LINK_URL_LENGTH = 120;
337
+ export declare const MAX_LINK_SELECTOR_LENGTH = 120;
338
+ /** Mocks one call may declare. Each is a live route on the page. */
339
+ export declare const MAX_MOCKS = 20;
340
+ /**
341
+ * Delay the `slow` scenario applies. Five seconds is past every spinner
342
+ * timeout worth having and comfortably inside the default recording, so the
343
+ * frames show the waiting state and then the arrival.
344
+ */
345
+ export declare const MOCK_SLOW_DELAY_MS = 5000;
346
+ /** Longest delay a mock may declare. Beyond the recording it is simply never delivered. */
347
+ export declare const MAX_MOCK_DELAY_MS = 30000;
348
+ /**
349
+ * Size of one mock body. Generous, because "how does this render 1000 rows"
350
+ * is one of the scenarios this tool exists for, and still bounded — the body
351
+ * is held in Node, sent over stdio and echoed in the report.
352
+ */
353
+ export declare const MAX_MOCK_BODY_BYTES = 2000000;
354
+ /** Requests named under one mock in the report before the rest are counted instead. */
355
+ export declare const MAX_MOCK_URLS_LISTED = 3;
356
+ /** Unmatched requests named in the report before the rest are counted instead. */
357
+ export declare const MAX_UNMATCHED_LISTED = 10;
358
+ /** Unmatched requests recorded at all. A page that never stops polling must not fill the response. */
359
+ export declare const MAX_UNMATCHED_TRACKED = 200;
360
+ /** Default settle time after each load before the page is measured. */
361
+ export declare const DEFAULT_RTL_WAIT_MS = 1000;
362
+ /**
363
+ * Slack (px) before a box counts as "did not move".
364
+ *
365
+ * Sub-pixel layout, fractional scaling and font metrics routinely shift a box
366
+ * by a pixel between two renders of the same page. A tolerance under about
367
+ * two pixels reports that rounding as a mirroring bug on almost every element.
368
+ */
369
+ export declare const RTL_MIRROR_TOLERANCE_PX = 2;
370
+ /** Slack (px) on padding and margin comparisons, for the same reason. */
371
+ export declare const RTL_ALIGN_TOLERANCE_PX = 1;
372
+ /**
373
+ * Slack (px) before content counts as overflowing in RTL.
374
+ *
375
+ * Matches OVERFLOW_TOLERANCE_PX in spirit but is looser: an RTL relayout
376
+ * reflows every line box, so a page routinely lands a pixel or two wider than
377
+ * it did in LTR without anything being wrong.
378
+ */
379
+ export declare const RTL_OVERFLOW_TOLERANCE_PX = 2;
380
+ /** Elements walked when measuring a page. Past this the page is a document dump, not a screen. */
381
+ export declare const MAX_RTL_SCAN = 5000;
382
+ /**
383
+ * Elements actually measured and compared, by default and at the cap.
384
+ *
385
+ * Every one of these is measured twice and compared, so the cost is real but
386
+ * bounded — and a page with more than a few hundred laid-out boxes is one
387
+ * where the first hundred findings are the whole story anyway.
388
+ */
389
+ export declare const DEFAULT_RTL_ELEMENTS = 400;
390
+ export declare const MAX_RTL_ELEMENTS = 1500;
391
+ /** Findings listed in one section of the report before the rest are counted instead. */
392
+ export declare const MAX_RTL_LISTED = 25;
393
+ /** Issues listed under one element before the rest are counted instead. */
394
+ export declare const MAX_RTL_ISSUES_PER_ELEMENT = 4;
395
+ /** Length of one element's text, and of one generated selector, before it is elided. */
396
+ export declare const MAX_RTL_TEXT_LENGTH = 60;
397
+ export declare const MAX_RTL_SELECTOR_LENGTH = 120;
398
+ /** Text nodes one Arabic injection will replace. A page longer than this is filled up to the cap. */
399
+ export declare const MAX_ARABIC_INJECTION_NODES = 2000;
400
+ /** Longest single string the Arabic injector will build, however long the original was. */
401
+ export declare const MAX_ARABIC_INJECTION_LENGTH = 300;
402
+ /** What a finding is painted in the overlay: a problem, and a warning. */
403
+ export declare const HIGHLIGHT_RTL_PROBLEM_COLOUR = "#e5194b";
404
+ export declare const HIGHLIGHT_RTL_WARNING_COLOUR = "#f08c00";
405
+ /** Characters of aria tree one snapshot returns before it is cut, with a note. */
406
+ export declare const DEFAULT_SNAPSHOT_MAX_CHARS = 12000;
407
+ export declare const MAX_SNAPSHOT_MAX_CHARS = 100000;
408
+ /** Elements one inspect call measures. Each is a full evaluate and a block of lines. */
409
+ export declare const MAX_INSPECT_TARGETS = 12;
410
+ /** Length of an element's own text quoted in an inspection before it is elided. */
411
+ export declare const MAX_INSPECT_TEXT_LENGTH = 60;
412
+ /** Elements the design inventory walks before it stops counting. */
413
+ export declare const MAX_INVENTORY_ELEMENTS = 3000;
414
+ /** Values listed per inventory dimension; the rest are counted into a tail. */
415
+ export declare const MAX_INVENTORY_VALUES = 12;
416
+ /** Settle time after opening a page for snapshot/inspect, so a client-rendered app has drawn. */
417
+ export declare const DEFAULT_SNAPSHOT_WAIT_MS = 500;
418
+ /** What inspect's boxes are painted. */
419
+ export declare const HIGHLIGHT_INSPECT_COLOUR = "#e5194b";
420
+ /** How long a session tool looks for a Vue app after opening a page before treating it as a plain page. */
421
+ export declare const VUE_DETECT_MS = 500;
422
+ /** Once an app is found: max wait for vue-router to be ready. */
423
+ export declare const VUE_READY_TIMEOUT_MS = 5000;
424
+ /** framewatch_wait_for's default and ceiling. */
425
+ export declare const DEFAULT_WAIT_FOR_TIMEOUT_MS = 10000;
426
+ export declare const MAX_WAIT_FOR_TIMEOUT_MS = 120000;
427
+ /** One serialised prop or state value, and how many of each are listed per component. */
428
+ export declare const MAX_COMPONENT_VALUE_LENGTH = 40;
429
+ export declare const MAX_COMPONENT_ENTRIES = 12;
430
+ /** Components the tree walk names before it stops. */
431
+ export declare const MAX_COMPONENT_TREE_NODES = 300;
432
+ /** Vite events remembered per session page. */
433
+ export declare const MAX_HMR_EVENTS = 50;
434
+ /** Claude Code's default cap on one MCP tool result; base64 image data counts toward it. */
435
+ export declare const DEFAULT_MCP_OUTPUT_TOKENS = 25000;
436
+ /** How base64 tokenises, conservatively: a result sized on 3 chars/token never lands over the cap. */
437
+ export declare const BUDGET_CHARS_PER_TOKEN = 3;
438
+ /** Tokens left for JSON framing and the budget note itself. */
439
+ export declare const BUDGET_MARGIN_TOKENS = 1500;
440
+ /** Widths a frame is stepped down through before any frame is dropped, then after the last one. */
441
+ export declare const BUDGET_WIDTHS: readonly [640, 480];
442
+ export declare const BUDGET_LAST_RESORT_WIDTHS: readonly [320, 240, 160];
443
+ /** JPEG quality for the lossy candidate. */
444
+ export declare const BUDGET_JPEG_QUALITY = 78;
445
+ /** What to tell the user to set for full results. */
446
+ export declare const BUDGET_SUGGESTED_TOKENS = 100000;
package/dist/constants.js CHANGED
@@ -176,4 +176,272 @@ export const SERVER_PORT_POLL_MS = 200;
176
176
  export const SERVER_PORT_PROBE_TIMEOUT_MS = 1000;
177
177
  /** Time a stopped server gets to exit on SIGTERM before it is killed outright. */
178
178
  export const SERVER_STOP_GRACE_MS = 5000;
179
+ /* ── Form testing (Tier 1) ────────────────────────────────────────────── */
180
+ /** How much text a `maxlength` strategy puts in a field that declares no limit of its own. */
181
+ export const MAX_FORM_FILL_LENGTH = 10_000;
182
+ /** Default settle time after a submit before the result is read and photographed. */
183
+ export const DEFAULT_FORM_WAIT_MS = 2000;
184
+ /**
185
+ * Settle time between filling the last field and the "after fill" screenshot.
186
+ * Live validation runs on blur/input and often on a debounce, so a shot taken
187
+ * the instant the last field is filled shows a form that has not reacted yet.
188
+ */
189
+ export const FORM_FILL_SETTLE_MS = 300;
190
+ /** Fields one strategy will fill. A form longer than this is filled up to the cap and says so. */
191
+ export const MAX_FORM_FIELDS = 60;
192
+ /** Fields listed by name in the report for one strategy, before the rest are counted instead. */
193
+ export const MAX_FORM_FIELDS_LISTED = 10;
194
+ /** Validation messages (browser-side and on-page alike) listed per strategy. */
195
+ export const MAX_FORM_ERRORS = 8;
196
+ /** Network requests listed per strategy. */
197
+ export const MAX_FORM_NETWORK_EVENTS = 8;
198
+ /** Console entries listed per strategy. */
199
+ export const MAX_FORM_CONSOLE_ENTRIES = 8;
200
+ /** Length of one echoed field value or error message before it is elided. */
201
+ export const MAX_FORM_TEXT_LENGTH = 80;
202
+ /** Validation messages read off the page in one scan, and the longest text counted as a message. */
203
+ export const MAX_FORM_MESSAGES = 20;
204
+ export const MAX_FORM_MESSAGE_LENGTH = 200;
205
+ /** Bound on one form-test screenshot. A page wedged by its own submit handler must not stall the run. */
206
+ export const FORM_SCREENSHOT_TIMEOUT_MS = 5000;
207
+ /* ── SEO (Tier 1) ─────────────────────────────────────────────────────── */
208
+ /** Default settle time after load before the page is read. */
209
+ export const DEFAULT_SEO_WAIT_MS = 1000;
210
+ /**
211
+ * Title length bounds. Search results are laid out in pixels, not characters,
212
+ * so these are the usual rules of thumb rather than hard limits: under 30
213
+ * characters is leaving the strongest ranking signal on the page unused, and
214
+ * past 60 the tail is generally cut off.
215
+ */
216
+ export const SEO_TITLE_MIN = 30;
217
+ export const SEO_TITLE_MAX = 60;
218
+ /** Meta description bounds — the snippet is cut somewhere around 160 characters. */
219
+ export const SEO_DESCRIPTION_MIN = 70;
220
+ export const SEO_DESCRIPTION_MAX = 160;
221
+ /** What a share image should be: the 1.91:1 card the networks render, and the floor below which they render none. */
222
+ export const SEO_OG_IMAGE_IDEAL = { width: 1200, height: 630 };
223
+ export const SEO_OG_IMAGE_MIN = { width: 200, height: 200 };
224
+ /** Headings listed in the outline before the rest are counted instead. */
225
+ export const MAX_SEO_HEADINGS = 40;
226
+ /** Images listed by source when they have no alt text. */
227
+ export const MAX_SEO_IMAGES_LISTED = 10;
228
+ /** JSON-LD blocks parsed, and the length of one before it is elided. */
229
+ export const MAX_SEO_JSONLD_BLOCKS = 10;
230
+ export const MAX_SEO_JSONLD_LENGTH = 20_000;
231
+ /** Length of one echoed value (title, heading, URL) before it is elided. */
232
+ export const MAX_SEO_TEXT_LENGTH = 120;
233
+ /** Bounds on the two extra requests an audit makes: robots.txt and the share image. */
234
+ export const SEO_FETCH_TIMEOUT_MS = 8000;
235
+ /** A share image larger than this is measured and reported but never returned as an image block. */
236
+ export const MAX_SEO_IMAGE_BYTES = 8_000_000;
237
+ /**
238
+ * Core Web Vitals thresholds — Google's own "good" and "poor" boundaries.
239
+ * These are lab numbers from one headless load, so they are reported as
240
+ * measurements with a verdict attached, never as a score.
241
+ */
242
+ export const SEO_LCP_GOOD_MS = 2500;
243
+ export const SEO_LCP_POOR_MS = 4000;
244
+ export const SEO_CLS_GOOD = 0.1;
245
+ export const SEO_CLS_POOR = 0.25;
246
+ export const SEO_TTFB_GOOD_MS = 800;
247
+ export const SEO_TTFB_POOR_MS = 1800;
248
+ /** Resource types listed in the page-weight breakdown. */
249
+ export const MAX_SEO_RESOURCE_TYPES = 6;
250
+ /** DOM size Lighthouse starts warning about, and the size it calls excessive. */
251
+ export const SEO_DOM_NODES_WARN = 1400;
252
+ export const SEO_DOM_NODES_POOR = 3000;
253
+ /* ── Dead clicks (Tier 1) ─────────────────────────────────────────────── */
254
+ /** Default settle time after load before the page is swept for clickable elements. */
255
+ export const DEFAULT_DEAD_CLICK_WAIT_MS = 1000;
256
+ /**
257
+ * How long the page is watched after each click before the verdict is taken.
258
+ * Long enough for a handler, a render and a fetch to start; short enough that
259
+ * forty of them do not turn one tool call into a minute of waiting.
260
+ */
261
+ export const DEFAULT_DEAD_CLICK_SETTLE_MS = 500;
262
+ /** Elements one sweep clicks by default, and the hard cap. Every one costs a click and a settle. */
263
+ export const DEFAULT_DEAD_CLICK_ELEMENTS = 40;
264
+ export const MAX_DEAD_CLICK_ELEMENTS = 100;
265
+ /**
266
+ * Bound on one click and on re-finding the element it belongs to. Much shorter
267
+ * than SELECTOR_TIMEOUT_MS: a control that cannot be clicked within this is a
268
+ * finding in its own right, and waiting ten seconds for each of forty of them
269
+ * is not a test anybody would run twice.
270
+ */
271
+ export const DEAD_CLICK_TIMEOUT_MS = 3000;
272
+ /** Elements walked when looking for clickable ones. Past this the page is reporting a tree, not a screen. */
273
+ export const MAX_DEAD_CLICK_SCAN = 5000;
274
+ /** Settle time after hovering an element before its hover styles are read (CSS transitions). */
275
+ export const DEAD_CLICK_HOVER_SETTLE_MS = 250;
276
+ /** DOM mutations quoted under one element before the rest are counted instead. */
277
+ export const MAX_DEAD_CLICK_CHANGES = 6;
278
+ /**
279
+ * Distinct mutation descriptions the page keeps per window.
280
+ *
281
+ * Comfortably more than are ever printed, and for a reason: what a click did
282
+ * is decided by which of these the page does *not* also do on its own, so a
283
+ * list that filled up with a ticking clock's churn would hide the one change
284
+ * that mattered.
285
+ */
286
+ export const MAX_DEAD_CLICK_CHANGE_SAMPLES = 24;
287
+ /** Elements listed in each section of the report before the rest are counted instead. */
288
+ export const MAX_DEAD_CLICK_LISTED = 20;
289
+ /** Effects listed for one element before the rest are counted instead. */
290
+ export const MAX_DEAD_CLICK_EFFECTS = 5;
291
+ /** Length of one element's visible text, and of one generated selector, before it is elided. */
292
+ export const MAX_DEAD_CLICK_TEXT_LENGTH = 60;
293
+ export const MAX_DEAD_CLICK_SELECTOR_LENGTH = 120;
294
+ /* ── Highlight overlay ────────────────────────────────────────────────── */
295
+ /** Boxes one overlay draws. Past this the screenshot is a colour field, not a finding. */
296
+ export const MAX_HIGHLIGHTS = 30;
297
+ /** The overlay's colours: what a dead element is painted, and what a broken one is. */
298
+ export const HIGHLIGHT_DEAD_COLOUR = "#e5194b";
299
+ export const HIGHLIGHT_BROKEN_COLOUR = "#f08c00";
300
+ /* ── Links (Tier 1) ───────────────────────────────────────────────────── */
301
+ /** Default settle time after each page load before its links are read. */
302
+ export const DEFAULT_LINKS_WAIT_MS = 1000;
303
+ /** Bound on one link check, and the bounds the caller may set. */
304
+ export const DEFAULT_LINK_TIMEOUT_MS = 5000;
305
+ export const MIN_LINK_TIMEOUT_MS = 100;
306
+ export const MAX_LINK_TIMEOUT_MS = 30_000;
307
+ /** Link checks in flight at once. Every one of them is a real request to somebody's server. */
308
+ export const DEFAULT_LINK_CONCURRENCY = 5;
309
+ export const MAX_LINK_CONCURRENCY = 10;
310
+ /**
311
+ * Redirects followed before a chain is called endless. Generous next to the
312
+ * two or three a real site uses, and far below the point where following one
313
+ * more would tell anybody anything.
314
+ */
315
+ export const MAX_LINK_REDIRECTS = 10;
316
+ /** Distinct URLs one run will check, and how deep a crawl may go. */
317
+ export const DEFAULT_MAX_LINKS = 200;
318
+ export const MAX_LINKS_CAP = 500;
319
+ export const MAX_LINK_DEPTH = 3;
320
+ /** Pages one crawl will open. Each is a full browser navigation, not a fetch. */
321
+ export const DEFAULT_LINK_PAGES = 10;
322
+ export const MAX_LINK_PAGES = 25;
323
+ /** Elements walked when collecting links. Past this the page is a document dump, not a screen. */
324
+ export const MAX_LINK_SCAN = 5000;
325
+ /** Links listed in one section of the report before the rest are counted instead. */
326
+ export const MAX_LINKS_LISTED = 25;
327
+ /** Places one link is named as appearing before the rest are counted instead. */
328
+ export const MAX_LINK_SOURCES_LISTED = 3;
329
+ /** Length of one link's text, URL and selector before each is elided. */
330
+ export const MAX_LINK_TEXT_LENGTH = 60;
331
+ export const MAX_LINK_URL_LENGTH = 120;
332
+ export const MAX_LINK_SELECTOR_LENGTH = 120;
333
+ /* ── API mocking (Tier 2) ─────────────────────────────────────────────── */
334
+ /** Mocks one call may declare. Each is a live route on the page. */
335
+ export const MAX_MOCKS = 20;
336
+ /**
337
+ * Delay the `slow` scenario applies. Five seconds is past every spinner
338
+ * timeout worth having and comfortably inside the default recording, so the
339
+ * frames show the waiting state and then the arrival.
340
+ */
341
+ export const MOCK_SLOW_DELAY_MS = 5000;
342
+ /** Longest delay a mock may declare. Beyond the recording it is simply never delivered. */
343
+ export const MAX_MOCK_DELAY_MS = MAX_CAPTURE_DURATION_MS;
344
+ /**
345
+ * Size of one mock body. Generous, because "how does this render 1000 rows"
346
+ * is one of the scenarios this tool exists for, and still bounded — the body
347
+ * is held in Node, sent over stdio and echoed in the report.
348
+ */
349
+ export const MAX_MOCK_BODY_BYTES = 2_000_000;
350
+ /** Requests named under one mock in the report before the rest are counted instead. */
351
+ export const MAX_MOCK_URLS_LISTED = 3;
352
+ /** Unmatched requests named in the report before the rest are counted instead. */
353
+ export const MAX_UNMATCHED_LISTED = 10;
354
+ /** Unmatched requests recorded at all. A page that never stops polling must not fill the response. */
355
+ export const MAX_UNMATCHED_TRACKED = 200;
356
+ /* ── RTL (Tier 2) ─────────────────────────────────────────────────────── */
357
+ /** Default settle time after each load before the page is measured. */
358
+ export const DEFAULT_RTL_WAIT_MS = 1000;
359
+ /**
360
+ * Slack (px) before a box counts as "did not move".
361
+ *
362
+ * Sub-pixel layout, fractional scaling and font metrics routinely shift a box
363
+ * by a pixel between two renders of the same page. A tolerance under about
364
+ * two pixels reports that rounding as a mirroring bug on almost every element.
365
+ */
366
+ export const RTL_MIRROR_TOLERANCE_PX = 2;
367
+ /** Slack (px) on padding and margin comparisons, for the same reason. */
368
+ export const RTL_ALIGN_TOLERANCE_PX = 1;
369
+ /**
370
+ * Slack (px) before content counts as overflowing in RTL.
371
+ *
372
+ * Matches OVERFLOW_TOLERANCE_PX in spirit but is looser: an RTL relayout
373
+ * reflows every line box, so a page routinely lands a pixel or two wider than
374
+ * it did in LTR without anything being wrong.
375
+ */
376
+ export const RTL_OVERFLOW_TOLERANCE_PX = 2;
377
+ /** Elements walked when measuring a page. Past this the page is a document dump, not a screen. */
378
+ export const MAX_RTL_SCAN = 5000;
379
+ /**
380
+ * Elements actually measured and compared, by default and at the cap.
381
+ *
382
+ * Every one of these is measured twice and compared, so the cost is real but
383
+ * bounded — and a page with more than a few hundred laid-out boxes is one
384
+ * where the first hundred findings are the whole story anyway.
385
+ */
386
+ export const DEFAULT_RTL_ELEMENTS = 400;
387
+ export const MAX_RTL_ELEMENTS = 1500;
388
+ /** Findings listed in one section of the report before the rest are counted instead. */
389
+ export const MAX_RTL_LISTED = 25;
390
+ /** Issues listed under one element before the rest are counted instead. */
391
+ export const MAX_RTL_ISSUES_PER_ELEMENT = 4;
392
+ /** Length of one element's text, and of one generated selector, before it is elided. */
393
+ export const MAX_RTL_TEXT_LENGTH = 60;
394
+ export const MAX_RTL_SELECTOR_LENGTH = 120;
395
+ /** Text nodes one Arabic injection will replace. A page longer than this is filled up to the cap. */
396
+ export const MAX_ARABIC_INJECTION_NODES = 2000;
397
+ /** Longest single string the Arabic injector will build, however long the original was. */
398
+ export const MAX_ARABIC_INJECTION_LENGTH = 300;
399
+ /** What a finding is painted in the overlay: a problem, and a warning. */
400
+ export const HIGHLIGHT_RTL_PROBLEM_COLOUR = "#e5194b";
401
+ export const HIGHLIGHT_RTL_WARNING_COLOUR = "#f08c00";
402
+ /* ── Snapshot & inspect ───────────────────────────────────────────────── */
403
+ /** Characters of aria tree one snapshot returns before it is cut, with a note. */
404
+ export const DEFAULT_SNAPSHOT_MAX_CHARS = 12_000;
405
+ export const MAX_SNAPSHOT_MAX_CHARS = 100_000;
406
+ /** Elements one inspect call measures. Each is a full evaluate and a block of lines. */
407
+ export const MAX_INSPECT_TARGETS = 12;
408
+ /** Length of an element's own text quoted in an inspection before it is elided. */
409
+ export const MAX_INSPECT_TEXT_LENGTH = 60;
410
+ /** Elements the design inventory walks before it stops counting. */
411
+ export const MAX_INVENTORY_ELEMENTS = 3000;
412
+ /** Values listed per inventory dimension; the rest are counted into a tail. */
413
+ export const MAX_INVENTORY_VALUES = 12;
414
+ /** Settle time after opening a page for snapshot/inspect, so a client-rendered app has drawn. */
415
+ export const DEFAULT_SNAPSHOT_WAIT_MS = 500;
416
+ /** What inspect's boxes are painted. */
417
+ export const HIGHLIGHT_INSPECT_COLOUR = "#e5194b";
418
+ /* ── Vue & Vite ───────────────────────────────────────────────────────── */
419
+ /** How long a session tool looks for a Vue app after opening a page before treating it as a plain page. */
420
+ export const VUE_DETECT_MS = 500;
421
+ /** Once an app is found: max wait for vue-router to be ready. */
422
+ export const VUE_READY_TIMEOUT_MS = 5000;
423
+ /** framewatch_wait_for's default and ceiling. */
424
+ export const DEFAULT_WAIT_FOR_TIMEOUT_MS = 10_000;
425
+ export const MAX_WAIT_FOR_TIMEOUT_MS = 120_000;
426
+ /** One serialised prop or state value, and how many of each are listed per component. */
427
+ export const MAX_COMPONENT_VALUE_LENGTH = 40;
428
+ export const MAX_COMPONENT_ENTRIES = 12;
429
+ /** Components the tree walk names before it stops. */
430
+ export const MAX_COMPONENT_TREE_NODES = 300;
431
+ /** Vite events remembered per session page. */
432
+ export const MAX_HMR_EVENTS = 50;
433
+ /* ── Image budget ─────────────────────────────────────────────────────── */
434
+ /** Claude Code's default cap on one MCP tool result; base64 image data counts toward it. */
435
+ export const DEFAULT_MCP_OUTPUT_TOKENS = 25_000;
436
+ /** How base64 tokenises, conservatively: a result sized on 3 chars/token never lands over the cap. */
437
+ export const BUDGET_CHARS_PER_TOKEN = 3;
438
+ /** Tokens left for JSON framing and the budget note itself. */
439
+ export const BUDGET_MARGIN_TOKENS = 1500;
440
+ /** Widths a frame is stepped down through before any frame is dropped, then after the last one. */
441
+ export const BUDGET_WIDTHS = [640, 480];
442
+ export const BUDGET_LAST_RESORT_WIDTHS = [320, 240, 160];
443
+ /** JPEG quality for the lossy candidate. */
444
+ export const BUDGET_JPEG_QUALITY = 78;
445
+ /** What to tell the user to set for full results. */
446
+ export const BUDGET_SUGGESTED_TOKENS = 100_000;
179
447
  //# sourceMappingURL=constants.js.map