@buoy-gg/mcp 7.0.71 → 7.0.73
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/README.md +2 -2
- package/dist/{chunk-K4R23SLC.mjs → chunk-AHIKIVTB.mjs} +1 -1
- package/dist/chunk-DZRRLTOD.mjs +4 -0
- package/dist/chunk-MJDNVDJI.mjs +474 -0
- package/dist/{chunk-ISZRKNVH.mjs → chunk-OADIHE3T.mjs} +1 -1
- package/dist/{chunk-PIMFQHV4.mjs → chunk-OUCQTYIW.mjs} +1 -1
- package/dist/{chunk-AN6T7AGX.mjs → chunk-S4JHE46Q.mjs} +92 -92
- package/dist/cli.js +305 -253
- package/dist/cli.mjs +6 -6
- package/dist/{flowRun-M652USJQ.mjs → flowRun-GTYQQXHF.mjs} +1 -1
- package/dist/index.js +30 -28
- package/dist/index.mjs +1 -1
- package/dist/{init-Z4SKOMSV.mjs → init-FDDGVIXA.mjs} +1 -1
- package/dist/{main-MGASA6BJ.mjs → main-DJT43WTJ.mjs} +2 -2
- package/dist/{simFarm-QD6SXEZE.mjs → simFarm-5MWIXNER.mjs} +1 -1
- package/dist/src-ZFIIN4L2.mjs +1 -0
- package/package.json +4 -4
- package/skill/buoy-optimize/MEASURING.md +11 -2
- package/skill/buoy-optimize/SKILL.md +1 -1
- package/dist/chunk-EVLLWLFB.mjs +0 -4
- package/dist/chunk-N573FXZ7.mjs +0 -422
- package/dist/src-TOKDOFTX.mjs +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{createRequire as A}from"module";const G=A(import.meta.url);import{PACKAGE_NAME as l,VERSION as b}from"./chunk-
|
|
1
|
+
import{createRequire as A}from"module";const G=A(import.meta.url);import{PACKAGE_NAME as l,VERSION as b}from"./chunk-AHIKIVTB.mjs";import{spawnSync as m}from"child_process";import s from"fs";import E from"os";import c from"path";function g(){return{BUOY_VERIFY:"auto"}}var w="https://registry.npmjs.org";var f=3e3;function C(e={}){const t=e.cwd??process.cwd();const r=e.skillSrcDir??c.resolve(__dirname,"../skill");const n=e.log??(a=>process.stdout.write(a+"\n"));const o=k(e,n);const i=[];d(c.join(t,".mcp.json"),"mcpServers",o,t,i);s.mkdirSync(c.join(t,".cursor"),{recursive:true});d(c.join(t,".cursor","mcp.json"),"mcpServers",o,t,i);if(s.existsSync(c.join(t,".vscode"))){d(c.join(t,".vscode","mcp.json"),"servers",o,t,i)}D(r,t,i);x(c.join(t,"CLAUDE.md"),t,i);x(c.join(t,"AGENTS.md"),t,i);n("Buoy MCP configuration written:");for(const a of i)n(" \u2022 "+a);n("");n("Next steps:");n(" 1. Restart your editor (or reconnect the MCP server) to load `buoy`.");n(" 2. Complete account setup, then open an app with the required Buoy tools and sync integration.");n(" 3. Confirm the device and tools are available. Free accounts get the basic MCP tools; Pro adds the rest.");n("");n(`Want your AI to use the web too? Run \`npx -y ${l}@latest init --web\` for Buoy Web (free, no account).`);if(o.command==="npx"){n("");n(`The editor launches the server with \`npx -y ${l}@latest\`, so it stays`);n(`Registry access may be needed. Re-run \`npx -y ${l}@latest init\` to refresh configuration.`)}else if(!e.cliPath){n("");n(`This uses a pinned local install (no network on startup). To update it later,`);n(`To update the local package, run: npx -y ${o.args[0]?.replace(/dist[/\\]cli\.js$/,"")??""}@latest init --local`)}}function k(e,t){if(e.cliPath){return{type:"stdio",command:"node",args:[e.cliPath],env:g()}}const r=e.mode??"auto";if(r==="npx"){return y()}if(r==="local"){return $(e,t)}const n=I();if(n.reachable){return y()}t(`\u26A0 npm registry ${n.registry?`(${n.registry}) `:""}looks unreachable \u2014 \`npx @latest\` would hang your editor at startup. Falling back to a pinned local install.`);return $(e,t)}function y(){return{type:"stdio",command:"npx",args:["-y",`${l}@latest`],env:g()}}function $(e,t){const r=e.installDir??process.env.BUOY_MCP_HOME??c.join(E.homedir(),".buoy-mcp");const n=e.registry??w;const o=R(r,n,t);if(o){return{type:"stdio",command:"node",args:[o],env:g()}}t("\u26A0 local install failed \u2014 writing the npx entry instead (see the error above).");return y()}function R(e,t,r){const n=`${l}@${b==="0.0.0-dev"?"latest":b}`;s.mkdirSync(e,{recursive:true});const o=process.platform==="win32"?"npm.cmd":"npm";r(`Installing ${n} into ${e} from ${t} \u2026`);const i=m(o,["install",n,"--prefix",e,"--registry",t,`--@buoy-gg:registry=${t}`,"--no-audit","--no-fund","--loglevel=error"],{stdio:["ignore","ignore","inherit"],encoding:"utf8"});if(i.status!==0){r(`\u26A0 npm install exited with code ${i.status??"?"}${i.error?` (${i.error.message})`:""}.`);return null}const a=c.join(e,"node_modules",l,"dist","cli.js");if(!s.existsSync(a)){r(`\u26A0 install finished but ${a} is missing.`);return null}return a}function I(){const e=P();if(!e)return{reachable:false,registry:null};if(/^https?:\/\/registry\.npmjs\.org\/?$/i.test(e)){return{reachable:true,registry:e}}return{reachable:T(e),registry:e}}function P(){const e=S("@buoy-gg:registry");if(e)return e;const t=S("registry");return t??w}function S(e){const t=process.platform==="win32"?"npm.cmd":"npm";const r=m(t,["config","get",e],{encoding:"utf8",timeout:f});if(r.status!==0||typeof r.stdout!=="string")return null;const n=r.stdout.trim();if(!n||n==="undefined"||n==="null")return null;return n}function T(e){const t=m(process.execPath,["-e",F,e,String(f)],{encoding:"utf8",timeout:f+2e3});return t.status===0}var F=`
|
|
2
2
|
const url = process.argv[1];
|
|
3
3
|
const ms = Number(process.argv[2]) || 3000;
|
|
4
4
|
const c = new AbortController();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import{createRequire as q}from"module";const fe=q(import.meta.url);import I from"fs";import R from"os";import y from"path";var G='// Buoy Web helper. Chrome starts it for the Buoy Web extension (native messaging) and\n// ends it when Chrome closes. It passes messages between the extension and Buoy MCP\n// sessions, which connect over a Unix socket only this user can open.\n//\n// extension <-- stdin/stdout (native messaging) --> helper <-- ~/.buoy/web/chrome-<pid>.sock --> MCP sessions\nimport fs from "node:fs";\nimport net from "node:net";\nimport os from "node:os";\nimport path from "node:path";\n\nconst dir = process.env.BUOY_WEB_DIR ?? path.join(os.homedir(), ".buoy", "web");\nfs.mkdirSync(dir, { recursive: true, mode: 0o700 });\nfs.chmodSync(dir, 0o700);\nconst sock = path.join(dir, `chrome-${process.pid}.sock`);\nconst info = path.join(dir, `chrome-${process.pid}.json`);\n\n// ---- native messaging: 4-byte little-endian length, then JSON -----------------\nlet inbuf = Buffer.alloc(0);\nprocess.stdin.on("data", (chunk) => {\n inbuf = Buffer.concat([inbuf, chunk]);\n while (inbuf.length >= 4) {\n const n = inbuf.readUInt32LE(0);\n if (inbuf.length < 4 + n) break;\n const msg = JSON.parse(inbuf.subarray(4, 4 + n).toString("utf8"));\n inbuf = inbuf.subarray(4 + n);\n fromExtension(msg);\n }\n});\nprocess.stdin.on("end", quit); // Chrome closed or the extension let go\nprocess.stdout.on("error", quit);\nfunction toExtension(msg) {\n const body = Buffer.from(JSON.stringify(msg), "utf8");\n if (body.length > 1024 * 1024) throw new Error("Message too big for Chrome (over 1 MB).");\n const head = Buffer.alloc(4);\n head.writeUInt32LE(body.length, 0);\n process.stdout.write(Buffer.concat([head, body]));\n}\n\n// ---- MCP sessions: one JSON message per line ------------------------------------\nconst clients = new Map(); // id -> socket\nlet nextClient = 1;\nfunction fromExtension(msg) {\n const s = clients.get(msg.c);\n if (!s) return;\n const { c, ...rest } = msg;\n s.write(JSON.stringify(rest) + "\\n");\n}\n\nconst server = net.createServer((s) => {\n const c = nextClient++;\n clients.set(c, s);\n let buf = "";\n s.setEncoding("utf8");\n s.on("data", (d) => {\n buf += d;\n let i;\n while ((i = buf.indexOf("\\n")) >= 0) {\n const line = buf.slice(0, i);\n buf = buf.slice(i + 1);\n if (!line) continue;\n let msg;\n try {\n msg = JSON.parse(line);\n toExtension({ ...msg, c });\n } catch (e) {\n if (msg?.id != null) s.write(JSON.stringify({ id: msg.id, error: String(e.message ?? e) }) + "\\n");\n }\n }\n });\n const gone = () => {\n if (!clients.delete(c)) return;\n try {\n toExtension({ c, method: "client.closed" });\n } catch {}\n };\n s.on("close", gone);\n s.on("error", gone);\n});\n\n// Clear out sockets left by helpers that died without cleaning up.\nfor (const f of fs.readdirSync(dir)) {\n const m = /^chrome-(\\d+)\\.(sock|json)$/.exec(f);\n if (!m || Number(m[1]) === process.pid) continue;\n try {\n process.kill(Number(m[1]), 0);\n } catch {\n fs.rmSync(path.join(dir, f), { force: true });\n }\n}\n\nconst old = process.umask(0o177); // the socket file is created 0600\nserver.listen(sock, () => {\n process.umask(old);\n fs.writeFileSync(info, JSON.stringify({ pid: process.pid, sock, started: Date.now() }), { mode: 0o600 });\n // Tells Buoy the extension is set up, so a closed Chrome isn\'t mistaken for "no extension".\n fs.writeFileSync(path.join(dir, "seen"), new Date().toISOString(), { mode: 0o600 });\n toExtension({ ready: true }); // the extension shows "connected" only after this\n});\n\nfunction quit() {\n for (const f of [sock, info]) fs.rmSync(f, { force: true });\n process.exit(0);\n}\nprocess.on("SIGTERM", quit);\nprocess.on("SIGINT", quit);\n';import V from"crypto";import N from"fs";import X from"http";import K from"net";import z from"os";import U from"path";import{WebSocketServer as Q}from"ws";var Z=process.env.BUOY_WEB_RELAYLOG==="1";var M=(...n)=>Z&&process.stderr.write(`[buoy-web relay] ${n.join(" ")}
|
|
2
2
|
`);var x=()=>process.env.BUOY_WEB_DIR??U.join(z.homedir(),".buoy","web");function ee(n=x()){let e=[];try{e=N.readdirSync(n)}catch{return[]}const i=[];for(const o of e){const a=/^chrome-(\d+)\.json$/.exec(o);if(!a)continue;try{process.kill(Number(a[1]),0);const b=JSON.parse(N.readFileSync(U.join(n,o),"utf8"));if(N.existsSync(b.sock))i.push(b)}catch{}}return i.sort((o,a)=>a.started-o.started)}function te(n){return new Promise((e,i)=>{const o=K.createConnection(n);const a=new Map;let b=1;let l="";let d=false;let v=false;const w={onEvent:()=>{},onClose:()=>{},call(m,S){if(v)return Promise.reject(new Error("Chrome's Buoy helper closed."));const c=b++;o.write(JSON.stringify({id:c,method:m,params:S})+"\n");return new Promise((O,B)=>a.set(c,{res:O,rej:B}))},close:()=>o.end()};o.setEncoding("utf8");o.on("connect",()=>{d=true;e(w)});o.on("error",m=>{if(!d)i(m)});o.on("data",m=>{l+=m;let S;while((S=l.indexOf("\n"))>=0){const c=JSON.parse(l.slice(0,S));l=l.slice(S+1);if(c.id!=null&&a.has(c.id)){const{res:O,rej:B}=a.get(c.id);a.delete(c.id);if(c.error)B(new Error(c.error));else O(c.result)}else if(c.event)w.onEvent(c.event,c.params)}});o.on("close",()=>{v=true;for(const{rej:m}of a.values())m(new Error("Chrome's Buoy helper closed."));a.clear();w.onClose()})})}async function ne({sock:n}){const e=await te(n);const i=await e.call("hello");const o=new Map;let a=1;let b=false;let l=null;const d=new Set;const v=t=>{if(l?.readyState===1)l.send(JSON.stringify(t))};const w=t=>[...o.values()].find(t);const m={url:"",hello:i,onDetach:()=>{},onClose:()=>{},idle:()=>Promise.all([...d]),close:()=>{}};async function S(t,{settle:r=false}={}){const s=o.get(t);if(s)return s;await e.call("debugger.attach",{tabId:t});if(r){const E=Date.now();while(Date.now()-E<5e3){const T=await e.call("debugger.send",{tabId:t,method:"Runtime.evaluate",params:{expression:"[location.href, document.readyState]",returnByValue:true}}).catch(()=>null);const[D,L]=T?.result?.value??[];if(D&&D!=="about:blank"&&L!=="loading")break;await new Promise(H=>setTimeout(H,50))}}const{targetInfo:u}=await e.call("debugger.send",{tabId:t,method:"Target.getTargetInfo"});const{openerId:g,openerFrameId:f,...p}=u;p.canAccessOpener=false;const h={tabId:t,sessionId:`buoy-tab-${a++}`,targetInfo:p,children:new Set,framesSent:false,held:[]};o.set(t,h);v({method:"Target.attachedToTarget",params:{sessionId:h.sessionId,targetInfo:{...p,attached:true},waitingForDebugger:false}});return h}function c(t){const r=o.get(t);if(!r)return;o.delete(t);v({method:"Target.detachedFromTarget",params:{sessionId:r.sessionId,targetId:r.targetInfo?.targetId}})}e.onEvent=(t,r)=>{if(t==="debugger.event"){const s=o.get(r.tabId);if(!s)return;const u=r.params?.sessionId;if(r.method==="Target.attachedToTarget"&&u)s.children.add(u);if(r.method==="Target.detachedFromTarget"&&u)s.children.delete(u);const g={sessionId:r.sessionId||s.sessionId,method:r.method,params:r.params};if(!s.framesSent)s.held.push(g);else v(g)}else if(t==="debugger.detached"){c(r.tabId);m.onDetach(r)}else if(t==="tabs.created"){if(b){const s=S(r.id,{settle:true}).catch(()=>{});d.add(s);void s.finally(()=>d.delete(s))}}else if(t==="tabs.removed")c(r.tabId)};e.onClose=()=>{for(const t of[...o.keys()])c(t);l?.close();m.onClose()};async function O(t,r,s){if(!s){switch(t){case"Browser.getVersion":return{protocolVersion:"1.3",product:"Chrome/BuoyWeb",userAgent:i.userAgent,jsVersion:""};case"Browser.setDownloadBehavior":case"Target.setDiscoverTargets":case"Browser.close":return{};case"Target.setAutoAttach":b=true;return{};case"Target.getTargetInfo":return{targetInfo:{targetId:"buoy-browser",type:"browser",title:"",url:"",attached:true,canAccessOpener:false}};case"Target.getBrowserContexts":return{browserContextIds:[]};case"Target.createTarget":{const p=await e.call("tabs.create",{url:r?.url});const h=await S(p.id);return{targetId:h.targetInfo.targetId}}case"Target.closeTarget":{const p=w(h=>h.targetInfo?.targetId===r?.targetId);if(!p)return{success:false};await e.call("tabs.remove",{tabId:p.tabId});return{success:true}}}const f=o.values().next().value;if(!f)throw new Error(`No Buoy tab to run ${t} on.`);return e.call("debugger.send",{tabId:f.tabId,method:t,params:r})}if(t==="Target.getTargetInfo"){const f=w(p=>p.sessionId===s);if(f)return{targetInfo:f.targetInfo}}let u=w(f=>f.sessionId===s);let g;if(!u){u=w(f=>f.children.has(s));g=s}if(!u)throw new Error(`No Buoy tab for session ${s}.`);return e.call("debugger.send",{tabId:u.tabId,sessionId:g,method:t,params:r})}const B=V.randomUUID();const _=X.createServer((t,r)=>r.writeHead(404).end());const C=new Q({server:_});C.on("connection",(t,r)=>{if(r.url!==`/${B}`||l)return t.close(4004,"No.");l=t;t.on("message",async s=>{const{id:u,sessionId:g,method:f,params:p}=JSON.parse(s.toString());try{const h=await O(f,p,g);M("ok ",g??"-",f);t.send(JSON.stringify({id:u,sessionId:g,result:h??{}}));if(f==="Page.getFrameTree"){const E=w(T=>T.sessionId===g);if(E&&!E.framesSent){E.framesSent=true;for(const T of E.held.splice(0))v(T)}}}catch(h){M("ERR",g??"-",f,h.message);t.send(JSON.stringify({id:u,sessionId:g,error:{message:String(h.message??h)}}))}});t.on("close",()=>{l=null;e.close()})});await new Promise(t=>_.listen(0,"127.0.0.1",t));m.url=`ws://127.0.0.1:${_.address().port}/${B}`;m.close=()=>{e.close();C.close();_.close()};return m}var J="gg.buoy.web";var $=["cfolfiajhlenfifknbomdogooagnlamf","kjbgbjimhjiocnfifnemmenkondjeifp",...(process.env.BUOY_WEB_EXTENSION_IDS??"").split(",").filter(Boolean)];var A=["Google/Chrome","Google/Chrome Beta","Google/Chrome Dev","Google/Chrome Canary","Chromium","BraveSoftware/Brave-Browser","Microsoft Edge","Vivaldi","Arc/User Data"];function P(){if(process.env.BUOY_WEB_NMH_DIRS)return process.env.BUOY_WEB_NMH_DIRS.split(y.delimiter).filter(Boolean);if(process.platform!=="darwin")return[];const n=y.join(R.homedir(),"Library","Application Support");return A.map(e=>y.join(n,e)).filter(e=>I.existsSync(e)).map(e=>y.join(e,"NativeMessagingHosts"))}var j=(n,e,i)=>{try{if(I.readFileSync(n,"utf8")===e)return}catch{}I.writeFileSync(n,e,{mode:i});I.chmodSync(n,i)};function oe(){try{const n=y.join(x(),"helper");I.mkdirSync(n,{recursive:true,mode:448});const e=y.join(n,"helper.mjs");const i=y.join(n,"helper.sh");j(e,G,384);const o=d=>`'${d.replace(/'/g,`'\\''`)}'`;const a=process.env.BUOY_WEB_DIR?`BUOY_WEB_DIR=${o(process.env.BUOY_WEB_DIR)} `:"";j(i,`#!/bin/sh
|
|
3
3
|
${a}exec ${o(process.execPath)} ${o(e)} "$@"
|
|
4
|
-
`,448);const b=JSON.stringify({name:J,description:"Buoy Web helper: lets the Buoy MCP use Buoy's own tabs through the Buoy Web extension.",path:i,type:"stdio",allowed_origins:$.map(d=>`chrome-extension://${d}/`)},null,2);const l=[];for(const d of P()){try{I.mkdirSync(d,{recursive:true});j(y.join(d,`${J}.json`),b+"\n",420);l.push(d)}catch{}}return l}catch{return[]}}function re(){if(process.env.BUOY_WEB_NMH_DIRS)return false;if(process.platform!=="darwin")return false;const n=y.join(R.homedir(),"Library","Application Support");for(const e of A){let i=[];try{i=I.readdirSync(y.join(n,e))}catch{continue}for(const o of i){if(o!=="Default"&&!/^Profile \d+$/.test(o))continue;if($.some(a=>I.existsSync(y.join(n,e,o,"Extensions",a))))return true}}return false}import se from"crypto";import k from"fs";import W from"path";var ie=process.env.BUOY_TELEMETRY_URL??"https://buoy.gg/api/t";var ae=24*60*60*1e3;function Y(){const n=(process.env.BUOY_TELEMETRY??"").toLowerCase();return n==="0"||n==="false"||n==="off"||process.env.DO_NOT_TRACK==="1"}var F=false;function ce(){if(F||Y())return;F=true;try{const n=W.join(x(),"install.json");let e={};try{e=JSON.parse(k.readFileSync(n,"utf8"))}catch{}if(typeof e.installId!=="string")e={installId:se.randomUUID(),lastPingAt:0};if(Date.now()-(e.lastPingAt??0)<ae)return;e.lastPingAt=Date.now();k.mkdirSync(W.dirname(n),{recursive:true,mode:448});k.writeFileSync(n,JSON.stringify(e),{mode:384});const i=JSON.stringify({installId:e.installId,version:"7.0.
|
|
4
|
+
`,448);const b=JSON.stringify({name:J,description:"Buoy Web helper: lets the Buoy MCP use Buoy's own tabs through the Buoy Web extension.",path:i,type:"stdio",allowed_origins:$.map(d=>`chrome-extension://${d}/`)},null,2);const l=[];for(const d of P()){try{I.mkdirSync(d,{recursive:true});j(y.join(d,`${J}.json`),b+"\n",420);l.push(d)}catch{}}return l}catch{return[]}}function re(){if(process.env.BUOY_WEB_NMH_DIRS)return false;if(process.platform!=="darwin")return false;const n=y.join(R.homedir(),"Library","Application Support");for(const e of A){let i=[];try{i=I.readdirSync(y.join(n,e))}catch{continue}for(const o of i){if(o!=="Default"&&!/^Profile \d+$/.test(o))continue;if($.some(a=>I.existsSync(y.join(n,e,o,"Extensions",a))))return true}}return false}import se from"crypto";import k from"fs";import W from"path";var ie=process.env.BUOY_TELEMETRY_URL??"https://buoy.gg/api/t";var ae=24*60*60*1e3;function Y(){const n=(process.env.BUOY_TELEMETRY??"").toLowerCase();return n==="0"||n==="false"||n==="off"||process.env.DO_NOT_TRACK==="1"}var F=false;function ce(){if(F||Y())return;F=true;try{const n=W.join(x(),"install.json");let e={};try{e=JSON.parse(k.readFileSync(n,"utf8"))}catch{}if(typeof e.installId!=="string")e={installId:se.randomUUID(),lastPingAt:0};if(Date.now()-(e.lastPingAt??0)<ae)return;e.lastPingAt=Date.now();k.mkdirSync(W.dirname(n),{recursive:true,mode:448});k.writeFileSync(n,JSON.stringify(e),{mode:384});const i=JSON.stringify({installId:e.installId,version:"7.0.73",platform:process.platform==="darwin"?"macos":process.platform==="win32"?"windows":"linux",tier:"locked",surface:"web-mcp"});void fetch(ie,{method:"POST",headers:{"content-type":"application/json"},body:i,signal:AbortSignal.timeout(5e3)}).catch(()=>{})}catch{}}export{x as webDir,ee as findHelpers,ne as startRelay,P as helperManifestDirs,oe as ensureHelper,re as extensionInstalled,Y as telemetryOff,ce as noteUse};
|