@hasna/browser 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -28807,6 +28807,40 @@ function register6(server) {
28807
28807
  return err(e);
28808
28808
  }
28809
28809
  });
28810
+ server.tool("browser_diff", "Visual diff between two URLs or a URL and a gallery entry. Screenshots both, returns a pixel diff image highlighting changes in red.", {
28811
+ session_id: exports_external2.string().optional(),
28812
+ url1: exports_external2.string().describe("First URL to screenshot"),
28813
+ url2: exports_external2.string().describe("Second URL to screenshot"),
28814
+ threshold: exports_external2.number().optional().default(10).describe("Pixel difference threshold (0-255, default 10)"),
28815
+ wait_ms: exports_external2.number().optional().default(1000).describe("Wait time after navigation before screenshot (ms)")
28816
+ }, async ({ session_id, url1, url2, threshold, wait_ms }) => {
28817
+ try {
28818
+ const sid = resolveSessionId(session_id);
28819
+ const page = getSessionPage(sid);
28820
+ await page.goto(url1, { waitUntil: "domcontentloaded" });
28821
+ await new Promise((r) => setTimeout(r, wait_ms));
28822
+ const ss1 = await takeScreenshot(page, { maxWidth: 1280, compress: true, track: false });
28823
+ await page.goto(url2, { waitUntil: "domcontentloaded" });
28824
+ await new Promise((r) => setTimeout(r, wait_ms));
28825
+ const ss2 = await takeScreenshot(page, { maxWidth: 1280, compress: true, track: false });
28826
+ const { diffImages: diffImages2 } = await Promise.resolve().then(() => (init_gallery_diff(), exports_gallery_diff));
28827
+ const diff = await diffImages2(ss1.path, ss2.path);
28828
+ logEvent(sid, "diff", { url1, url2, changed_percent: diff.changed_percent });
28829
+ return json({
28830
+ url1,
28831
+ url2,
28832
+ changed_pixels: diff.changed_pixels,
28833
+ total_pixels: diff.total_pixels,
28834
+ changed_percent: Math.round(diff.changed_percent * 100) / 100,
28835
+ diff_path: diff.diff_path,
28836
+ diff_base64: diff.diff_base64.length > 50000 ? undefined : diff.diff_base64,
28837
+ screenshot1_path: ss1.path,
28838
+ screenshot2_path: ss2.path
28839
+ });
28840
+ } catch (e) {
28841
+ return err(e);
28842
+ }
28843
+ });
28810
28844
  }
28811
28845
  var init_capture = __esm(() => {
28812
28846
  init_helpers();
@@ -31942,6 +31976,53 @@ function register7(server) {
31942
31976
  return err(e);
31943
31977
  }
31944
31978
  });
31979
+ server.tool("browser_performance_budget", "Check page performance against a budget. Set thresholds for LCP, FCP, CLS, TTFB, DOM complete, and load event. Returns pass/fail per metric with actual values.", {
31980
+ session_id: exports_external2.string().optional(),
31981
+ lcp_ms: exports_external2.number().optional().describe("Largest Contentful Paint budget in ms (good: <2500)"),
31982
+ fcp_ms: exports_external2.number().optional().describe("First Contentful Paint budget in ms (good: <1800)"),
31983
+ cls: exports_external2.number().optional().describe("Cumulative Layout Shift budget (good: <0.1)"),
31984
+ ttfb_ms: exports_external2.number().optional().describe("Time to First Byte budget in ms (good: <800)"),
31985
+ dom_complete_ms: exports_external2.number().optional().describe("DOM complete budget in ms"),
31986
+ load_event_ms: exports_external2.number().optional().describe("Load event budget in ms"),
31987
+ js_heap_mb: exports_external2.number().optional().describe("JS heap size budget in MB")
31988
+ }, async ({ session_id, lcp_ms, fcp_ms, cls, ttfb_ms, dom_complete_ms, load_event_ms, js_heap_mb }) => {
31989
+ try {
31990
+ const sid = resolveSessionId(session_id);
31991
+ const page = getSessionPage(sid);
31992
+ const metrics = await getPerformanceMetrics(page);
31993
+ const checks = [];
31994
+ let allPassed = true;
31995
+ const check = (name, budget, actual) => {
31996
+ if (budget === undefined)
31997
+ return;
31998
+ const passed = actual !== undefined && actual <= budget;
31999
+ if (!passed)
32000
+ allPassed = false;
32001
+ checks.push({ metric: name, budget, actual, passed });
32002
+ };
32003
+ check("lcp", lcp_ms, metrics.lcp);
32004
+ check("fcp", fcp_ms, metrics.fcp);
32005
+ check("cls", cls, metrics.cls);
32006
+ check("ttfb", ttfb_ms, metrics.ttfb);
32007
+ check("dom_complete", dom_complete_ms, metrics.dom_complete);
32008
+ check("load_event", load_event_ms, metrics.load_event);
32009
+ if (js_heap_mb !== undefined && metrics.js_heap_size_used !== undefined) {
32010
+ const heapMb = metrics.js_heap_size_used / (1024 * 1024);
32011
+ const passed = heapMb <= js_heap_mb;
32012
+ if (!passed)
32013
+ allPassed = false;
32014
+ checks.push({ metric: "js_heap_mb", budget: js_heap_mb, actual: Math.round(heapMb * 100) / 100, passed });
32015
+ }
32016
+ return json({
32017
+ passed: allPassed,
32018
+ checks,
32019
+ metrics,
32020
+ url: page.url()
32021
+ });
32022
+ } catch (e) {
32023
+ return err(e);
32024
+ }
32025
+ });
31945
32026
  }
31946
32027
  var init_network2 = __esm(() => {
31947
32028
  init_helpers();
@@ -32390,6 +32471,19 @@ function register8(server) {
32390
32471
  return err(e);
32391
32472
  }
32392
32473
  });
32474
+ server.tool("browser_record_export", "Export a recording as a Playwright test (.spec.ts), Puppeteer script, or JSON. Returns the generated code as text.", {
32475
+ recording_id: exports_external2.string().describe("ID of the recording to export"),
32476
+ format: exports_external2.enum(["playwright", "puppeteer", "json"]).optional().default("playwright").describe("Export format")
32477
+ }, async ({ recording_id, format }) => {
32478
+ try {
32479
+ const { exportRecording: exportRecording2 } = await Promise.resolve().then(() => (init_recorder(), exports_recorder));
32480
+ const code = exportRecording2(recording_id, format);
32481
+ const ext = format === "json" ? ".json" : format === "playwright" ? ".spec.ts" : ".js";
32482
+ return json({ format, filename: `recording-${recording_id}${ext}`, code });
32483
+ } catch (e) {
32484
+ return err(e);
32485
+ }
32486
+ });
32393
32487
  }
32394
32488
  var init_recordings2 = __esm(() => {
32395
32489
  init_helpers();
@@ -47967,7 +48061,8 @@ function register10(server) {
47967
48061
  { tool: "browser_screenshot", description: "Take a screenshot (PNG/JPEG/WebP, annotate=true for labels)" },
47968
48062
  { tool: "browser_pdf", description: "Generate a PDF of the page" },
47969
48063
  { tool: "browser_scroll_and_screenshot", description: "Scroll then screenshot in one call" },
47970
- { tool: "browser_scroll_to_element", description: "Scroll element into view + screenshot" }
48064
+ { tool: "browser_scroll_to_element", description: "Scroll element into view + screenshot" },
48065
+ { tool: "browser_diff", description: "Visual diff between two URLs \u2014 highlights changes in red" }
47971
48066
  ],
47972
48067
  Storage: [
47973
48068
  { tool: "browser_cookies_get", description: "Get cookies" },
@@ -47992,7 +48087,8 @@ function register10(server) {
47992
48087
  { tool: "browser_intercept_clear", description: "Remove all response intercepts" }
47993
48088
  ],
47994
48089
  Performance: [
47995
- { tool: "browser_performance", description: "Get performance metrics" }
48090
+ { tool: "browser_performance", description: "Get performance metrics" },
48091
+ { tool: "browser_performance_budget", description: "Check perf against budget thresholds (LCP, FCP, CLS, TTFB)" }
47996
48092
  ],
47997
48093
  Console: [
47998
48094
  { tool: "browser_console_log", description: "Get console messages" },
@@ -48005,6 +48101,7 @@ function register10(server) {
48005
48101
  { tool: "browser_record_step", description: "Add a step to recording" },
48006
48102
  { tool: "browser_record_stop", description: "Stop and save recording" },
48007
48103
  { tool: "browser_record_replay", description: "Replay a recorded sequence" },
48104
+ { tool: "browser_record_export", description: "Export recording as Playwright test, Puppeteer script, or JSON" },
48008
48105
  { tool: "browser_recordings_list", description: "List all recordings" }
48009
48106
  ],
48010
48107
  Auth: [
@@ -1 +1 @@
1
- {"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../src/mcp/capture.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA6BzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,QAodzC"}
1
+ {"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../src/mcp/capture.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA6BzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,QAogBzC"}
package/dist/mcp/index.js CHANGED
@@ -19493,6 +19493,63 @@ var init_agents2 = __esm(() => {
19493
19493
  init_agents();
19494
19494
  });
19495
19495
 
19496
+ // src/lib/gallery-diff.ts
19497
+ var exports_gallery_diff = {};
19498
+ __export(exports_gallery_diff, {
19499
+ diffImages: () => diffImages
19500
+ });
19501
+ import { join as join11 } from "path";
19502
+ import { mkdirSync as mkdirSync9 } from "fs";
19503
+ async function diffImages(path1, path2) {
19504
+ const img1 = import_sharp2.default(path1);
19505
+ const img2 = import_sharp2.default(path2);
19506
+ const [meta1, meta2] = await Promise.all([img1.metadata(), img2.metadata()]);
19507
+ const w = Math.min(meta1.width ?? 1280, meta2.width ?? 1280);
19508
+ const h = Math.min(meta1.height ?? 720, meta2.height ?? 720);
19509
+ const [raw1, raw2] = await Promise.all([
19510
+ import_sharp2.default(path1).resize(w, h, { fit: "fill" }).raw().toBuffer(),
19511
+ import_sharp2.default(path2).resize(w, h, { fit: "fill" }).raw().toBuffer()
19512
+ ]);
19513
+ const totalPixels = w * h;
19514
+ const channels = 3;
19515
+ const diffBuffer = Buffer.alloc(raw1.length);
19516
+ let changedPixels = 0;
19517
+ for (let i = 0;i < raw1.length; i += channels) {
19518
+ const dr = Math.abs(raw1[i] - raw2[i]);
19519
+ const dg = Math.abs(raw1[i + 1] - raw2[i + 1]);
19520
+ const db = Math.abs(raw1[i + 2] - raw2[i + 2]);
19521
+ const diff = (dr + dg + db) / 3;
19522
+ if (diff > 10) {
19523
+ changedPixels++;
19524
+ diffBuffer[i] = 255;
19525
+ diffBuffer[i + 1] = 0;
19526
+ diffBuffer[i + 2] = 0;
19527
+ } else {
19528
+ diffBuffer[i] = Math.round(raw1[i] * 0.4);
19529
+ diffBuffer[i + 1] = Math.round(raw1[i + 1] * 0.4);
19530
+ diffBuffer[i + 2] = Math.round(raw1[i + 2] * 0.4);
19531
+ }
19532
+ }
19533
+ const dataDir = getDataDir2();
19534
+ const diffDir = join11(dataDir, "diffs");
19535
+ mkdirSync9(diffDir, { recursive: true });
19536
+ const diffPath = join11(diffDir, `diff-${Date.now()}.webp`);
19537
+ const diffImageBuffer = await import_sharp2.default(diffBuffer, { raw: { width: w, height: h, channels } }).webp({ quality: 85 }).toBuffer();
19538
+ await Bun.write(diffPath, diffImageBuffer);
19539
+ return {
19540
+ diff_path: diffPath,
19541
+ diff_base64: diffImageBuffer.toString("base64"),
19542
+ changed_pixels: changedPixels,
19543
+ total_pixels: totalPixels,
19544
+ changed_percent: changedPixels / totalPixels * 100
19545
+ };
19546
+ }
19547
+ var import_sharp2;
19548
+ var init_gallery_diff = __esm(() => {
19549
+ init_schema();
19550
+ import_sharp2 = __toESM(require_lib3(), 1);
19551
+ });
19552
+
19496
19553
  // src/lib/profiles.ts
19497
19554
  var exports_profiles = {};
19498
19555
  __export(exports_profiles, {
@@ -43580,57 +43637,9 @@ function detectType(filename) {
43580
43637
  };
43581
43638
  return map[ext] ?? "file";
43582
43639
  }
43583
- // src/lib/gallery-diff.ts
43584
- init_schema();
43585
- var import_sharp2 = __toESM(require_lib3(), 1);
43586
- import { join as join11 } from "path";
43587
- import { mkdirSync as mkdirSync9 } from "fs";
43588
- async function diffImages(path1, path2) {
43589
- const img1 = import_sharp2.default(path1);
43590
- const img2 = import_sharp2.default(path2);
43591
- const [meta1, meta2] = await Promise.all([img1.metadata(), img2.metadata()]);
43592
- const w = Math.min(meta1.width ?? 1280, meta2.width ?? 1280);
43593
- const h = Math.min(meta1.height ?? 720, meta2.height ?? 720);
43594
- const [raw1, raw2] = await Promise.all([
43595
- import_sharp2.default(path1).resize(w, h, { fit: "fill" }).raw().toBuffer(),
43596
- import_sharp2.default(path2).resize(w, h, { fit: "fill" }).raw().toBuffer()
43597
- ]);
43598
- const totalPixels = w * h;
43599
- const channels = 3;
43600
- const diffBuffer = Buffer.alloc(raw1.length);
43601
- let changedPixels = 0;
43602
- for (let i = 0;i < raw1.length; i += channels) {
43603
- const dr = Math.abs(raw1[i] - raw2[i]);
43604
- const dg = Math.abs(raw1[i + 1] - raw2[i + 1]);
43605
- const db = Math.abs(raw1[i + 2] - raw2[i + 2]);
43606
- const diff = (dr + dg + db) / 3;
43607
- if (diff > 10) {
43608
- changedPixels++;
43609
- diffBuffer[i] = 255;
43610
- diffBuffer[i + 1] = 0;
43611
- diffBuffer[i + 2] = 0;
43612
- } else {
43613
- diffBuffer[i] = Math.round(raw1[i] * 0.4);
43614
- diffBuffer[i + 1] = Math.round(raw1[i + 1] * 0.4);
43615
- diffBuffer[i + 2] = Math.round(raw1[i + 2] * 0.4);
43616
- }
43617
- }
43618
- const dataDir = getDataDir2();
43619
- const diffDir = join11(dataDir, "diffs");
43620
- mkdirSync9(diffDir, { recursive: true });
43621
- const diffPath = join11(diffDir, `diff-${Date.now()}.webp`);
43622
- const diffImageBuffer = await import_sharp2.default(diffBuffer, { raw: { width: w, height: h, channels } }).webp({ quality: 85 }).toBuffer();
43623
- await Bun.write(diffPath, diffImageBuffer);
43624
- return {
43625
- diff_path: diffPath,
43626
- diff_base64: diffImageBuffer.toString("base64"),
43627
- changed_pixels: changedPixels,
43628
- total_pixels: totalPixels,
43629
- changed_percent: changedPixels / totalPixels * 100
43630
- };
43631
- }
43632
43640
 
43633
43641
  // src/mcp/helpers.ts
43642
+ init_gallery_diff();
43634
43643
  init_snapshot();
43635
43644
 
43636
43645
  // src/lib/files-integration.ts
@@ -44879,6 +44888,40 @@ function register3(server) {
44879
44888
  return err(e);
44880
44889
  }
44881
44890
  });
44891
+ server.tool("browser_diff", "Visual diff between two URLs or a URL and a gallery entry. Screenshots both, returns a pixel diff image highlighting changes in red.", {
44892
+ session_id: exports_external.string().optional(),
44893
+ url1: exports_external.string().describe("First URL to screenshot"),
44894
+ url2: exports_external.string().describe("Second URL to screenshot"),
44895
+ threshold: exports_external.number().optional().default(10).describe("Pixel difference threshold (0-255, default 10)"),
44896
+ wait_ms: exports_external.number().optional().default(1000).describe("Wait time after navigation before screenshot (ms)")
44897
+ }, async ({ session_id, url1, url2, threshold, wait_ms }) => {
44898
+ try {
44899
+ const sid = resolveSessionId(session_id);
44900
+ const page = getSessionPage(sid);
44901
+ await page.goto(url1, { waitUntil: "domcontentloaded" });
44902
+ await new Promise((r) => setTimeout(r, wait_ms));
44903
+ const ss1 = await takeScreenshot(page, { maxWidth: 1280, compress: true, track: false });
44904
+ await page.goto(url2, { waitUntil: "domcontentloaded" });
44905
+ await new Promise((r) => setTimeout(r, wait_ms));
44906
+ const ss2 = await takeScreenshot(page, { maxWidth: 1280, compress: true, track: false });
44907
+ const { diffImages: diffImages2 } = await Promise.resolve().then(() => (init_gallery_diff(), exports_gallery_diff));
44908
+ const diff = await diffImages2(ss1.path, ss2.path);
44909
+ logEvent(sid, "diff", { url1, url2, changed_percent: diff.changed_percent });
44910
+ return json({
44911
+ url1,
44912
+ url2,
44913
+ changed_pixels: diff.changed_pixels,
44914
+ total_pixels: diff.total_pixels,
44915
+ changed_percent: Math.round(diff.changed_percent * 100) / 100,
44916
+ diff_path: diff.diff_path,
44917
+ diff_base64: diff.diff_base64.length > 50000 ? undefined : diff.diff_base64,
44918
+ screenshot1_path: ss1.path,
44919
+ screenshot2_path: ss2.path
44920
+ });
44921
+ } catch (e) {
44922
+ return err(e);
44923
+ }
44924
+ });
44882
44925
  }
44883
44926
 
44884
44927
  // src/mcp/network.ts
@@ -45223,6 +45266,53 @@ function register4(server) {
45223
45266
  return err(e);
45224
45267
  }
45225
45268
  });
45269
+ server.tool("browser_performance_budget", "Check page performance against a budget. Set thresholds for LCP, FCP, CLS, TTFB, DOM complete, and load event. Returns pass/fail per metric with actual values.", {
45270
+ session_id: exports_external.string().optional(),
45271
+ lcp_ms: exports_external.number().optional().describe("Largest Contentful Paint budget in ms (good: <2500)"),
45272
+ fcp_ms: exports_external.number().optional().describe("First Contentful Paint budget in ms (good: <1800)"),
45273
+ cls: exports_external.number().optional().describe("Cumulative Layout Shift budget (good: <0.1)"),
45274
+ ttfb_ms: exports_external.number().optional().describe("Time to First Byte budget in ms (good: <800)"),
45275
+ dom_complete_ms: exports_external.number().optional().describe("DOM complete budget in ms"),
45276
+ load_event_ms: exports_external.number().optional().describe("Load event budget in ms"),
45277
+ js_heap_mb: exports_external.number().optional().describe("JS heap size budget in MB")
45278
+ }, async ({ session_id, lcp_ms, fcp_ms, cls, ttfb_ms, dom_complete_ms, load_event_ms, js_heap_mb }) => {
45279
+ try {
45280
+ const sid = resolveSessionId(session_id);
45281
+ const page = getSessionPage(sid);
45282
+ const metrics = await getPerformanceMetrics(page);
45283
+ const checks = [];
45284
+ let allPassed = true;
45285
+ const check = (name, budget, actual) => {
45286
+ if (budget === undefined)
45287
+ return;
45288
+ const passed = actual !== undefined && actual <= budget;
45289
+ if (!passed)
45290
+ allPassed = false;
45291
+ checks.push({ metric: name, budget, actual, passed });
45292
+ };
45293
+ check("lcp", lcp_ms, metrics.lcp);
45294
+ check("fcp", fcp_ms, metrics.fcp);
45295
+ check("cls", cls, metrics.cls);
45296
+ check("ttfb", ttfb_ms, metrics.ttfb);
45297
+ check("dom_complete", dom_complete_ms, metrics.dom_complete);
45298
+ check("load_event", load_event_ms, metrics.load_event);
45299
+ if (js_heap_mb !== undefined && metrics.js_heap_size_used !== undefined) {
45300
+ const heapMb = metrics.js_heap_size_used / (1024 * 1024);
45301
+ const passed = heapMb <= js_heap_mb;
45302
+ if (!passed)
45303
+ allPassed = false;
45304
+ checks.push({ metric: "js_heap_mb", budget: js_heap_mb, actual: Math.round(heapMb * 100) / 100, passed });
45305
+ }
45306
+ return json({
45307
+ passed: allPassed,
45308
+ checks,
45309
+ metrics,
45310
+ url: page.url()
45311
+ });
45312
+ } catch (e) {
45313
+ return err(e);
45314
+ }
45315
+ });
45226
45316
  }
45227
45317
 
45228
45318
  // src/mcp/recordings.ts
@@ -45397,6 +45487,19 @@ function register5(server) {
45397
45487
  return err(e);
45398
45488
  }
45399
45489
  });
45490
+ server.tool("browser_record_export", "Export a recording as a Playwright test (.spec.ts), Puppeteer script, or JSON. Returns the generated code as text.", {
45491
+ recording_id: exports_external.string().describe("ID of the recording to export"),
45492
+ format: exports_external.enum(["playwright", "puppeteer", "json"]).optional().default("playwright").describe("Export format")
45493
+ }, async ({ recording_id, format }) => {
45494
+ try {
45495
+ const { exportRecording: exportRecording2 } = await Promise.resolve().then(() => (init_recorder(), exports_recorder));
45496
+ const code = exportRecording2(recording_id, format);
45497
+ const ext = format === "json" ? ".json" : format === "playwright" ? ".spec.ts" : ".js";
45498
+ return json({ format, filename: `recording-${recording_id}${ext}`, code });
45499
+ } catch (e) {
45500
+ return err(e);
45501
+ }
45502
+ });
45400
45503
  }
45401
45504
 
45402
45505
  // src/mcp/scripts.ts
@@ -45809,7 +45912,8 @@ function register7(server) {
45809
45912
  { tool: "browser_screenshot", description: "Take a screenshot (PNG/JPEG/WebP, annotate=true for labels)" },
45810
45913
  { tool: "browser_pdf", description: "Generate a PDF of the page" },
45811
45914
  { tool: "browser_scroll_and_screenshot", description: "Scroll then screenshot in one call" },
45812
- { tool: "browser_scroll_to_element", description: "Scroll element into view + screenshot" }
45915
+ { tool: "browser_scroll_to_element", description: "Scroll element into view + screenshot" },
45916
+ { tool: "browser_diff", description: "Visual diff between two URLs \u2014 highlights changes in red" }
45813
45917
  ],
45814
45918
  Storage: [
45815
45919
  { tool: "browser_cookies_get", description: "Get cookies" },
@@ -45834,7 +45938,8 @@ function register7(server) {
45834
45938
  { tool: "browser_intercept_clear", description: "Remove all response intercepts" }
45835
45939
  ],
45836
45940
  Performance: [
45837
- { tool: "browser_performance", description: "Get performance metrics" }
45941
+ { tool: "browser_performance", description: "Get performance metrics" },
45942
+ { tool: "browser_performance_budget", description: "Check perf against budget thresholds (LCP, FCP, CLS, TTFB)" }
45838
45943
  ],
45839
45944
  Console: [
45840
45945
  { tool: "browser_console_log", description: "Get console messages" },
@@ -45847,6 +45952,7 @@ function register7(server) {
45847
45952
  { tool: "browser_record_step", description: "Add a step to recording" },
45848
45953
  { tool: "browser_record_stop", description: "Stop and save recording" },
45849
45954
  { tool: "browser_record_replay", description: "Replay a recorded sequence" },
45955
+ { tool: "browser_record_export", description: "Export recording as Playwright test, Puppeteer script, or JSON" },
45850
45956
  { tool: "browser_recordings_list", description: "List all recordings" }
45851
45957
  ],
45852
45958
  Auth: [
@@ -1 +1 @@
1
- {"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../src/mcp/meta.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA8CzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,QAk7BzC"}
1
+ {"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../src/mcp/meta.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA8CzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,QAq7BzC"}
@@ -1 +1 @@
1
- {"version":3,"file":"network.d.ts","sourceRoot":"","sources":["../../src/mcp/network.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAiCzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,QA6czC"}
1
+ {"version":3,"file":"network.d.ts","sourceRoot":"","sources":["../../src/mcp/network.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAiCzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,QAmgBzC"}
@@ -1 +1 @@
1
- {"version":3,"file":"recordings.d.ts","sourceRoot":"","sources":["../../src/mcp/recordings.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAkBzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,QA8OzC"}
1
+ {"version":3,"file":"recordings.d.ts","sourceRoot":"","sources":["../../src/mcp/recordings.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAkBzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,QAiQzC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/browser",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "General-purpose browser agent toolkit — Playwright, Chrome DevTools Protocol, Lightpanda with auto engine selection. CLI + MCP + REST + SDK.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",