@buoy-gg/mcp 7.0.46 → 7.0.48

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.mjs CHANGED
@@ -1,8 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import{SyncClient as i,createMcpServer as p,runInit as a}from"./chunk-WST6W5ZP.mjs";import{StdioServerTransport as l}from"@modelcontextprotocol/sdk/server/stdio.js";console.log=(...e)=>console.error(...e);console.info=(...e)=>console.error(...e);console.debug=(...e)=>console.error(...e);async function d(){const e=process.env.BUOY_BROKER_PORT;const s=new i({url:process.env.BUOY_BROKER_URL,port:e?Number(e):void 0,autoSpawnBroker:process.env.BUOY_NO_SPAWN!=="1"});const o=p(s);const c=new l;let n=false;const r=t=>{if(n)return;n=true;process.stderr.write(`[buoy-mcp] shutting down (${t})
3
- `);setTimeout(()=>process.exit(0),2e3).unref();void(async()=>{await s.stop().catch(()=>{});await o.close().catch(()=>{});process.exit(0)})()};process.stdin.once("end",()=>r("stdin closed"));process.stdin.once("close",()=>r("stdin closed"));o.server.onclose=()=>r("transport closed");process.on("SIGINT",()=>r("SIGINT"));process.on("SIGTERM",()=>r("SIGTERM"));process.on("SIGHUP",()=>r("SIGHUP"));await o.connect(c);process.stderr.write(`[buoy-mcp] serving MCP over stdio; connecting to broker\u2026
4
- `);s.start().then(t=>process.stderr.write(`[buoy-mcp] broker ${t}
5
- `)).catch(t=>process.stderr.write(`[buoy-mcp] broker connection failed: ${t?.message??t} \u2014 tools will report no devices until it recovers
6
- `))}if(process.argv[2]==="init"){try{const e=process.argv.slice(3);let s="auto";if(e.includes("--local"))s="local";else if(e.includes("--npx"))s="npx";const o=e.indexOf("--registry");const c=o!==-1?e[o+1]:void 0;a({mode:s,registry:c});process.exit(0)}catch(e){process.stderr.write(`[buoy-mcp] init failed: ${e?.message??e}
7
- `);process.exit(1)}}else{d().catch(e=>{process.stderr.write(`[buoy-mcp] fatal: ${e?.message??e}
2
+ import{SyncClient as a,createMcpServer as p,runInit as l}from"./chunk-OBR5RY7Z.mjs";import"./chunk-2PTJT2QF.mjs";import{StdioServerTransport as d}from"@modelcontextprotocol/sdk/server/stdio.js";console.log=(...e)=>console.error(...e);console.info=(...e)=>console.error(...e);console.debug=(...e)=>console.error(...e);async function u(){const e=process.env.BUOY_BROKER_PORT;const s=new a({url:process.env.BUOY_BROKER_URL,port:e?Number(e):void 0,autoSpawnBroker:process.env.BUOY_NO_SPAWN!=="1"});const t=p(s);const c=new d;let n=false;const r=o=>{if(n)return;n=true;process.stderr.write(`[buoy-mcp] shutting down (${o})
3
+ `);setTimeout(()=>process.exit(0),2e3).unref();void(async()=>{await s.stop().catch(()=>{});await t.close().catch(()=>{});process.exit(0)})()};process.stdin.once("end",()=>r("stdin closed"));process.stdin.once("close",()=>r("stdin closed"));t.server.onclose=()=>r("transport closed");process.on("SIGINT",()=>r("SIGINT"));process.on("SIGTERM",()=>r("SIGTERM"));process.on("SIGHUP",()=>r("SIGHUP"));await t.connect(c);process.stderr.write(`[buoy-mcp] serving MCP over stdio; connecting to broker\u2026
4
+ `);s.start().then(o=>process.stderr.write(`[buoy-mcp] broker ${o}
5
+ `)).catch(o=>process.stderr.write(`[buoy-mcp] broker connection failed: ${o?.message??o} \u2014 tools will report no devices until it recovers
6
+ `))}if(process.argv[2]==="web-bench"){void(async()=>{try{const e=process.argv.slice(3);const s=e.find(i=>!i.startsWith("--"));if(!s)throw new Error("usage: buoy-mcp web-bench <config.json> [--json]");const{readFileSync:t}=await import("fs");const{runWebBench:c,formatWebBenchMarkdown:n}=await import("./webBench-LKAOZXHK.mjs");const r=JSON.parse(t(s,"utf8"));const o=await c({...r,durationMs:r.durationMs??r.perCaseDurationMs},i=>process.stderr.write(`[web-bench] ${i}
7
+ `));process.stdout.write((e.includes("--json")?JSON.stringify(o,null,2):n(o))+"\n");process.exit(0)}catch(e){process.stderr.write(`[buoy-mcp] web-bench failed: ${e?.message??e}
8
+ `);process.exit(1)}})()}else if(process.argv[2]==="init"){try{const e=process.argv.slice(3);let s="auto";if(e.includes("--local"))s="local";else if(e.includes("--npx"))s="npx";const t=e.indexOf("--registry");const c=t!==-1?e[t+1]:void 0;l({mode:s,registry:c});process.exit(0)}catch(e){process.stderr.write(`[buoy-mcp] init failed: ${e?.message??e}
9
+ `);process.exit(1)}}else{u().catch(e=>{process.stderr.write(`[buoy-mcp] fatal: ${e?.message??e}
8
10
  `);process.exit(1)})}
package/dist/index.d.mts CHANGED
@@ -474,6 +474,59 @@ interface AutomationConfig {
474
474
  captureRenders?: boolean;
475
475
  }
476
476
  /** A lightweight saved-recording summary (the device's index entry). */
477
+ /** Per-run browser probe summary (perf-monitor webRunProbe.ts). */
478
+ interface WebRunSummary {
479
+ durationMs: number;
480
+ frames: number;
481
+ refreshHz: number;
482
+ frameGapP95Ms: number | null;
483
+ frameGapMaxMs: number | null;
484
+ longFrames: number;
485
+ longTasksSupported: boolean;
486
+ longTaskMs: number | null;
487
+ longTaskPct: number | null;
488
+ hidden: boolean;
489
+ heapSupported: boolean;
490
+ viewport: {
491
+ width: number;
492
+ height: number;
493
+ } | null;
494
+ dpr: number | null;
495
+ resized: boolean;
496
+ userAgent: string | null;
497
+ loaf?: {
498
+ count: number;
499
+ blockingMs: number;
500
+ worstMs: number;
501
+ styleLayoutMs: number;
502
+ forcedLayoutMs: number;
503
+ topScripts: {
504
+ name: string;
505
+ ms: number;
506
+ count: number;
507
+ }[];
508
+ } | null;
509
+ interactions?: {
510
+ count: number;
511
+ worstMs: number | null;
512
+ worstInputDelayMs: number | null;
513
+ worstProcessingMs: number | null;
514
+ worstPresentationMs: number | null;
515
+ worstType: string | null;
516
+ } | null;
517
+ layoutShift?: number | null;
518
+ domNodesStart?: number | null;
519
+ domNodesEnd?: number | null;
520
+ pageLoad?: {
521
+ pageAgeMs: number;
522
+ ttfbMs: number | null;
523
+ fcpMs: number | null;
524
+ lcpMs: number | null;
525
+ domContentLoadedMs: number | null;
526
+ scriptKb: number | null;
527
+ totalKb: number | null;
528
+ } | null;
529
+ }
477
530
  interface IndexEntry {
478
531
  id: string;
479
532
  createdAt: number;
@@ -496,6 +549,10 @@ interface IndexEntry {
496
549
  caseId?: string;
497
550
  runIndex?: number;
498
551
  isMedianRun?: boolean;
552
+ /** Set on every run of the batch's baseline case. batchIndex is the shuffled slot, so it can't say which case is the baseline. */
553
+ isBaseline?: boolean;
554
+ /** Browser runs only: what the per-run probe saw. Mirrors perf-monitor's WebRunSummary. */
555
+ webRun?: WebRunSummary;
499
556
  /** Thermal state at run start; a throttled run reads cheap AND janky. */
500
557
  thermalState?: "nominal" | "fair" | "serious" | "critical";
501
558
  /** Render-capture mirror (absent when capture was unavailable/disabled). */
@@ -607,7 +664,56 @@ interface RankRow {
607
664
  jsJank: number | null;
608
665
  uiJank: number | null;
609
666
  deviceMaxRefreshRate: number | null;
610
- /** Delta vs the baseline (first case) — positive = better/more fps. */
667
+ /** True for the caller's baseline case (its first case, wherever it ran). */
668
+ isBaseline?: boolean;
669
+ /**
670
+ * "web" when the run came from a browser. Browser rows read differently:
671
+ * one main-thread FPS (in `jsFps`; `uiFps` is null), no CPU (long-task time
672
+ * is in `longTaskPct`), and real frame gaps instead of slow-sample counts.
673
+ */
674
+ platform?: "web";
675
+ /** Browser rows: % of the run the main thread spent in long tasks (>50 ms). null = not supported. */
676
+ longTaskPct?: number | null;
677
+ /** Browser rows: 95th-percentile gap between frames, ms. */
678
+ frameGapP95Ms?: number | null;
679
+ /** Browser rows: the longest gap between frames, ms. */
680
+ frameGapMaxMs?: number | null;
681
+ /** Browser rows: gaps long enough to miss at least one frame. */
682
+ longFrames?: number | null;
683
+ /** Browser rows: metrics this browser can't measure (they show as —, never 0). */
684
+ missingMetrics?: string[];
685
+ /** Browser rows (LoAF): input-blocking time in long animation frames, ms. */
686
+ loafBlockingMs?: number | null;
687
+ /** Browser rows (LoAF): style + layout time at the end of slow frames, ms. */
688
+ styleLayoutMs?: number | null;
689
+ /** Browser rows (LoAF): layout forced inside scripts, ms. */
690
+ forcedLayoutMs?: number | null;
691
+ /** Browser rows (LoAF): the scripts that took the most time in slow frames. */
692
+ topScripts?: {
693
+ name: string;
694
+ ms: number;
695
+ count: number;
696
+ }[];
697
+ /** Browser rows: slowest tap/key from input to next paint, ms (null = no input). */
698
+ worstInteractionMs?: number | null;
699
+ /** Browser rows: layout-shift score inside the run. */
700
+ layoutShift?: number | null;
701
+ /** Browser rows: elements in the page at the end of the median run. */
702
+ domNodes?: number | null;
703
+ /**
704
+ * Browser rows: elements added between the first and last run of this case,
705
+ * when every run started with more than the one before. Each run remounts
706
+ * the screen, so steady growth means nodes are left behind.
707
+ */
708
+ domGrowth?: number | null;
709
+ /** FPS range over this case's valid runs (UI FPS on native, FPS on web). */
710
+ fpsMin?: number | null;
711
+ fpsMax?: number | null;
712
+ /** Runs that saved without a failure. */
713
+ validRuns?: number;
714
+ /** Browser rows: how the page loaded (page-lifetime; see FRESH_LOAD_MS). */
715
+ pageLoad?: NonNullable<WebRunSummary["pageLoad"]> | null;
716
+ /** Delta vs the baseline case — positive = better/more fps. */
611
717
  deltaUiFps: number | null;
612
718
  deltaJsFps: number | null;
613
719
  /** At-risk axes for this case (e.g. "UI thread drops frames", "CPU near cap"). */
@@ -637,6 +743,8 @@ interface BatchRanking {
637
743
  lowestCpu?: string;
638
744
  lowestMem?: string;
639
745
  fewestJank?: string;
746
+ /** Browser batches: least main-thread time in long tasks. */
747
+ fewestLongTasks?: string;
640
748
  };
641
749
  /** Cases with an at-risk axis (esp. UI thread) — never a silent winner. */
642
750
  flagged: {
package/dist/index.d.ts CHANGED
@@ -474,6 +474,59 @@ interface AutomationConfig {
474
474
  captureRenders?: boolean;
475
475
  }
476
476
  /** A lightweight saved-recording summary (the device's index entry). */
477
+ /** Per-run browser probe summary (perf-monitor webRunProbe.ts). */
478
+ interface WebRunSummary {
479
+ durationMs: number;
480
+ frames: number;
481
+ refreshHz: number;
482
+ frameGapP95Ms: number | null;
483
+ frameGapMaxMs: number | null;
484
+ longFrames: number;
485
+ longTasksSupported: boolean;
486
+ longTaskMs: number | null;
487
+ longTaskPct: number | null;
488
+ hidden: boolean;
489
+ heapSupported: boolean;
490
+ viewport: {
491
+ width: number;
492
+ height: number;
493
+ } | null;
494
+ dpr: number | null;
495
+ resized: boolean;
496
+ userAgent: string | null;
497
+ loaf?: {
498
+ count: number;
499
+ blockingMs: number;
500
+ worstMs: number;
501
+ styleLayoutMs: number;
502
+ forcedLayoutMs: number;
503
+ topScripts: {
504
+ name: string;
505
+ ms: number;
506
+ count: number;
507
+ }[];
508
+ } | null;
509
+ interactions?: {
510
+ count: number;
511
+ worstMs: number | null;
512
+ worstInputDelayMs: number | null;
513
+ worstProcessingMs: number | null;
514
+ worstPresentationMs: number | null;
515
+ worstType: string | null;
516
+ } | null;
517
+ layoutShift?: number | null;
518
+ domNodesStart?: number | null;
519
+ domNodesEnd?: number | null;
520
+ pageLoad?: {
521
+ pageAgeMs: number;
522
+ ttfbMs: number | null;
523
+ fcpMs: number | null;
524
+ lcpMs: number | null;
525
+ domContentLoadedMs: number | null;
526
+ scriptKb: number | null;
527
+ totalKb: number | null;
528
+ } | null;
529
+ }
477
530
  interface IndexEntry {
478
531
  id: string;
479
532
  createdAt: number;
@@ -496,6 +549,10 @@ interface IndexEntry {
496
549
  caseId?: string;
497
550
  runIndex?: number;
498
551
  isMedianRun?: boolean;
552
+ /** Set on every run of the batch's baseline case. batchIndex is the shuffled slot, so it can't say which case is the baseline. */
553
+ isBaseline?: boolean;
554
+ /** Browser runs only: what the per-run probe saw. Mirrors perf-monitor's WebRunSummary. */
555
+ webRun?: WebRunSummary;
499
556
  /** Thermal state at run start; a throttled run reads cheap AND janky. */
500
557
  thermalState?: "nominal" | "fair" | "serious" | "critical";
501
558
  /** Render-capture mirror (absent when capture was unavailable/disabled). */
@@ -607,7 +664,56 @@ interface RankRow {
607
664
  jsJank: number | null;
608
665
  uiJank: number | null;
609
666
  deviceMaxRefreshRate: number | null;
610
- /** Delta vs the baseline (first case) — positive = better/more fps. */
667
+ /** True for the caller's baseline case (its first case, wherever it ran). */
668
+ isBaseline?: boolean;
669
+ /**
670
+ * "web" when the run came from a browser. Browser rows read differently:
671
+ * one main-thread FPS (in `jsFps`; `uiFps` is null), no CPU (long-task time
672
+ * is in `longTaskPct`), and real frame gaps instead of slow-sample counts.
673
+ */
674
+ platform?: "web";
675
+ /** Browser rows: % of the run the main thread spent in long tasks (>50 ms). null = not supported. */
676
+ longTaskPct?: number | null;
677
+ /** Browser rows: 95th-percentile gap between frames, ms. */
678
+ frameGapP95Ms?: number | null;
679
+ /** Browser rows: the longest gap between frames, ms. */
680
+ frameGapMaxMs?: number | null;
681
+ /** Browser rows: gaps long enough to miss at least one frame. */
682
+ longFrames?: number | null;
683
+ /** Browser rows: metrics this browser can't measure (they show as —, never 0). */
684
+ missingMetrics?: string[];
685
+ /** Browser rows (LoAF): input-blocking time in long animation frames, ms. */
686
+ loafBlockingMs?: number | null;
687
+ /** Browser rows (LoAF): style + layout time at the end of slow frames, ms. */
688
+ styleLayoutMs?: number | null;
689
+ /** Browser rows (LoAF): layout forced inside scripts, ms. */
690
+ forcedLayoutMs?: number | null;
691
+ /** Browser rows (LoAF): the scripts that took the most time in slow frames. */
692
+ topScripts?: {
693
+ name: string;
694
+ ms: number;
695
+ count: number;
696
+ }[];
697
+ /** Browser rows: slowest tap/key from input to next paint, ms (null = no input). */
698
+ worstInteractionMs?: number | null;
699
+ /** Browser rows: layout-shift score inside the run. */
700
+ layoutShift?: number | null;
701
+ /** Browser rows: elements in the page at the end of the median run. */
702
+ domNodes?: number | null;
703
+ /**
704
+ * Browser rows: elements added between the first and last run of this case,
705
+ * when every run started with more than the one before. Each run remounts
706
+ * the screen, so steady growth means nodes are left behind.
707
+ */
708
+ domGrowth?: number | null;
709
+ /** FPS range over this case's valid runs (UI FPS on native, FPS on web). */
710
+ fpsMin?: number | null;
711
+ fpsMax?: number | null;
712
+ /** Runs that saved without a failure. */
713
+ validRuns?: number;
714
+ /** Browser rows: how the page loaded (page-lifetime; see FRESH_LOAD_MS). */
715
+ pageLoad?: NonNullable<WebRunSummary["pageLoad"]> | null;
716
+ /** Delta vs the baseline case — positive = better/more fps. */
611
717
  deltaUiFps: number | null;
612
718
  deltaJsFps: number | null;
613
719
  /** At-risk axes for this case (e.g. "UI thread drops frames", "CPU near cap"). */
@@ -637,6 +743,8 @@ interface BatchRanking {
637
743
  lowestCpu?: string;
638
744
  lowestMem?: string;
639
745
  fewestJank?: string;
746
+ /** Browser batches: least main-thread time in long tasks. */
747
+ fewestLongTasks?: string;
640
748
  };
641
749
  /** Cases with an at-risk axis (esp. UI thread) — never a silent winner. */
642
750
  flagged: {