@github/computer-use-mcp 0.1.35 → 0.1.38

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 (28) hide show
  1. package/dist/{main.js → mcp/index.js} +12 -14
  2. package/dist/{index.js → mcp/main.js} +18 -16
  3. package/dist/{prebuilds/darwin-x64 → mcp/prebuilds/darwin-arm64}/Copilot Computer Use.app/Contents/CodeResources +0 -0
  4. package/dist/{prebuilds → mcp/prebuilds}/darwin-arm64/Copilot Computer Use.app/Contents/Info.plist +2 -2
  5. package/dist/mcp/prebuilds/darwin-arm64/Copilot Computer Use.app/Contents/MacOS/Copilot Computer Use +0 -0
  6. package/dist/mcp/prebuilds/darwin-arm64/computer.node +0 -0
  7. package/dist/{prebuilds/darwin-arm64 → mcp/prebuilds/darwin-x64}/Copilot Computer Use.app/Contents/CodeResources +0 -0
  8. package/dist/{prebuilds → mcp/prebuilds}/darwin-x64/Copilot Computer Use.app/Contents/Info.plist +2 -2
  9. package/dist/mcp/prebuilds/darwin-x64/Copilot Computer Use.app/Contents/MacOS/Copilot Computer Use +0 -0
  10. package/dist/mcp/prebuilds/darwin-x64/computer.node +0 -0
  11. package/dist/{prebuilds → mcp/prebuilds}/win32-arm64/computer.node +0 -0
  12. package/dist/{prebuilds → mcp/prebuilds}/win32-x64/computer.node +0 -0
  13. package/package.json +17 -15
  14. package/dist/prebuilds/darwin-arm64/Copilot Computer Use.app/Contents/MacOS/Copilot Computer Use +0 -0
  15. package/dist/prebuilds/darwin-arm64/computer.node +0 -0
  16. package/dist/prebuilds/darwin-x64/Copilot Computer Use.app/Contents/MacOS/Copilot Computer Use +0 -0
  17. package/dist/prebuilds/darwin-x64/computer.node +0 -0
  18. /package/dist/{index.d.ts → mcp/index.d.ts} +0 -0
  19. /package/dist/{prebuilds → mcp/prebuilds}/darwin-arm64/Copilot Computer Use.app/Contents/PkgInfo +0 -0
  20. /package/dist/{prebuilds → mcp/prebuilds}/darwin-arm64/Copilot Computer Use.app/Contents/Resources/Assets.car +0 -0
  21. /package/dist/{prebuilds → mcp/prebuilds}/darwin-arm64/Copilot Computer Use.app/Contents/Resources/icon.icns +0 -0
  22. /package/dist/{prebuilds → mcp/prebuilds}/darwin-arm64/Copilot Computer Use.app/Contents/_CodeSignature/CodeResources +0 -0
  23. /package/dist/{prebuilds → mcp/prebuilds}/darwin-x64/Copilot Computer Use.app/Contents/PkgInfo +0 -0
  24. /package/dist/{prebuilds → mcp/prebuilds}/darwin-x64/Copilot Computer Use.app/Contents/Resources/Assets.car +0 -0
  25. /package/dist/{prebuilds → mcp/prebuilds}/darwin-x64/Copilot Computer Use.app/Contents/Resources/icon.icns +0 -0
  26. /package/dist/{prebuilds → mcp/prebuilds}/darwin-x64/Copilot Computer Use.app/Contents/_CodeSignature/CodeResources +0 -0
  27. /package/dist/{prebuilds → mcp/prebuilds}/linux-arm64/computer.node +0 -0
  28. /package/dist/{prebuilds → mcp/prebuilds}/linux-x64/computer.node +0 -0
@@ -1,17 +1,16 @@
1
- #!/usr/bin/env node
2
- var Xt=Object.defineProperty;var ct=(u,t)=>()=>(u&&(t=u(u=0)),t);var yt=(u,t)=>{for(var e in t)Xt(u,e,{get:t[e],enumerable:!0})};import{randomBytes as re}from"crypto";import*as B from"fs/promises";import{createServer as ae}from"net";import{tmpdir as ce}from"os";import{join as St}from"path";var ot,It=ct(()=>{"use strict";ot=class{constructor(t,e){this.name=t;this.logger=e}name;logger;server;socket;socketDir;socketPath;token;startPromise;nextId=1;buffer="";pending=new Map;escapeCallback;lockPromise;async requestPermission(t){}async capabilities(){return{discovery:!1,application:!1,window:!1,state:!1}}async click(t,e,i,s,n=""){let o=await this.resolveCoordinateSpace(n);this.assertPointInBounds(o,t,e);let[r,a]=this.toNative(o,t,e);await this.request("click",{x:r,y:a,button:i,count:s})}async move(t,e,i=""){let s=await this.resolveCoordinateSpace(i);this.assertPointInBounds(s,t,e);let[n,o]=this.toNative(s,t,e);await this.request("move",{x:n,y:o})}async drag(t,e,i,s,n=""){let o=await this.resolveCoordinateSpace(n);this.assertPointInBounds(o,t,e),this.assertPointInBounds(o,i,s);let[r,a]=this.toNative(o,t,e),[c,l]=this.toNative(o,i,s);await this.request("drag",{x1:r,y1:a,x2:c,y2:l})}async mouseDown(t,e,i=""){let s=await this.resolveCoordinateSpace(i);this.assertPointInBounds(s,t,e);let[n,o]=this.toNative(s,t,e);await this.request("mouseDown",{x:n,y:o})}async mouseUp(t,e,i=""){let s=await this.resolveCoordinateSpace(i);this.assertPointInBounds(s,t,e);let[n,o]=this.toNative(s,t,e);await this.request("mouseUp",{x:n,y:o})}async type(t){await this.request("type",{text:t})}async key(t){await this.request("key",{combo:t})}async scroll(t,e,i,s,n=""){let o=await this.resolveCoordinateSpace(n);this.assertPointInBounds(o,t,e);let[r,a]=this.toNative(o,t,e);await this.request("scroll",{x:r,y:a,dx:i,dy:s})}async cursorPosition(t=""){let e=await this.request("cursorPosition",{}),i=await this.resolveCoordinateSpace(t),[s,n]=this.fromNative(i,e.x,e.y);return{x:s,y:n}}async display(t=""){let e=await this.resolveCoordinateSpace(t);return{width:e.targetWidth,height:e.targetHeight}}async screenshot(t,e,i,s,n,o,r){let a=await this.resolveCoordinateSpace(t,s,n),c=r??-1;if(o){this.assertRegionEdgeInBounds(a,o[0],o[1]),this.assertRegionEdgeInBounds(a,o[2],o[3]);let[d,w,h,A]=this.toNativeCrop(a,o[0],o[1],o[2],o[3]),C=await this.request("screenshot",{display:t,allowedApplicationIds:e,blockedWindowIds:i,width:0,height:0,x1:d,y1:w,x2:h,y2:A,quality:c});return C?Buffer.from(C,"base64"):null}let l=await this.request("screenshot",{display:t,allowedApplicationIds:e,blockedWindowIds:i,width:a.targetWidth,height:a.targetHeight,x1:0,y1:0,x2:0,y2:0,quality:c});return l?Buffer.from(l,"base64"):null}async listDisplays(){return(await this.listDisplayInfos()).map(e=>{let{targetWidth:i,targetHeight:s}=this.targetSizeForDisplay(e.bounds.width,e.bounds.height);return{displayId:e.displayId,label:e.label,width:i,height:s,isPrimary:e.isPrimary}})}async listWindows(){return this.request("listWindows",{})}async resolveApplication(t){return this.request("resolveApplication",{app:t})}async windowAtPoint(t,e,i){let s=await this.resolveCoordinateSpace(t);this.assertPointInBounds(s,e,i);let[n,o]=this.toNative(s,e,i);return this.request("windowAtPoint",{displayId:t,x:n,y:o})}async getActiveWindow(){return this.request("getActiveWindow",{})}async activateApplication(t){return this.request("activateApplication",{applicationId:t})}async concealApplication(t){return this.request("concealApplication",{applicationId:t})}async restoreApplication(t){return this.request("restoreApplication",{applicationId:t})}async activateWindow(t){return this.request("activateWindow",{windowId:t})}async concealWindow(t){return this.request("concealWindow",{windowId:t})}async restoreWindow(t){return this.request("restoreWindow",{windowId:t})}async getClipboard(){return this.request("getClipboard",{})}async setClipboard(t){await this.request("setClipboard",{text:t})}lock(t){this.escapeCallback=t;let e=this.request("lock",{}).then(i=>{if(!i)throw new Error(`${this.name} could not install the ESC abort handler.`);return!0}).catch(i=>{throw this.lockPromise===e&&(this.lockPromise=void 0),this.escapeCallback=void 0,i});return this.lockPromise=e,e.catch(i=>{this.logger?.log("debug","Driver","service.lock",this.errorFromUnknown(i).message)}),!0}unlock(){let t=this.lockPromise;this.lockPromise=void 0,this.escapeCallback=void 0;let e=()=>this.request("unlock",{});(t?t.catch(()=>!1).then(()=>e()):e()).catch(s=>{this.logger?.log("debug","Driver","service.unlock",this.errorFromUnknown(s).message)})}hideActionCursor(){this.request("hideActionCursor",{}).catch(t=>{this.logger?.log("debug","Driver","hideActionCursor",this.errorFromUnknown(t).message)})}async getWindowState(t,e,i,s,n,o,r){let a=await this.request("getWindowState",{app:t,windowTitleContains:e,windowId:i,includeScreenshot:s,includeTree:n,maxNodes:o,diffSince:r});return this.windowStateResult(t,this.parseServiceJson(a,"getWindowState"))}async windowClick(t,e,i,s,n,o,r,a,c,l,d){let w=this.parseServiceJson(await this.request("windowClick",this.actionParams({app:t,elementIndex:e,x:i,y:s,clickCount:n,mouseButton:o,windowTitleContains:r,windowId:a,stateToken:c},l,d)),"windowClick");return this.parseActionResult(w)}async invokeAction(t,e,i,s,n,o,r,a){let c=this.parseServiceJson(await this.request("invokeAction",this.actionParams({app:t,elementIndex:e,action:i,windowTitleContains:s,windowId:n,stateToken:o},r,a)),"invokeAction");return this.parseActionResult(c)}async windowScroll(t,e,i,s,n,o,r,a,c){let l=this.parseServiceJson(await this.request("windowScroll",this.actionParams({app:t,elementIndex:e,direction:i,pages:s,windowTitleContains:n,windowId:o,stateToken:r},a,c)),"windowScroll");return this.parseActionResult(l)}async windowDrag(t,e,i,s,n,o,r,a,c,l){let d=this.parseServiceJson(await this.request("windowDrag",this.actionParams({app:t,fromX:e,fromY:i,toX:s,toY:n,windowTitleContains:o,windowId:r,stateToken:a},c,l)),"windowDrag");return this.parseActionResult(d)}async typeText(t,e,i,s,n,o,r,a){let c=this.parseServiceJson(await this.request("typeText",this.actionParams({app:t,text:e,elementIndex:i,windowTitleContains:s,windowId:n,stateToken:o},r,a)),"typeText");return this.parseActionResult(c)}async pressKey(t,e,i,s,n,o,r){let a=this.parseServiceJson(await this.request("pressKey",this.actionParams({app:t,key:e,windowTitleContains:i,windowId:s,stateToken:n},o,r)),"pressKey");return this.parseActionResult(a)}async setValue(t,e,i,s,n,o,r,a){let c=this.parseServiceJson(await this.request("setValue",this.actionParams({app:t,elementIndex:e,value:i,windowTitleContains:s,windowId:n,stateToken:o},r,a)),"setValue");return this.parseActionResult(c)}async selectText(t,e,i,s,n,o,r,a,c,l,d){let w=this.parseServiceJson(await this.request("selectText",this.actionParams({app:t,elementIndex:e,text:i,prefix:s,suffix:n,selection:o,windowTitleContains:r,windowId:a,stateToken:c},l,d)),"selectText");return this.parseActionResult(w)}async prepareForInput(t,e,i){let s=Number.NaN,n=Number.NaN;if(i){let o=await this.resolveCoordinateSpace(t);this.assertPointInBounds(o,i.x,i.y),[s,n]=this.toNative(o,i.x,i.y)}return this.request("prepareForInput",{displayId:t,allowedAppIds:e,blockedWindowIds:i?.blockedWindowIds??[],x:s,y:n})}async request(t,e){t!=="lock"&&t!=="unlock"&&await this.lockPromise,await this.start();let i=this.socket,s=this.token;if(!i||i.destroyed||!s)throw new Error(`${this.name} is not connected.`);let n=this.nextId++,o=JSON.stringify({id:n,token:s,method:t,params:e})+`
1
+ var Xt=Object.defineProperty;var lt=(h,t)=>()=>(h&&(t=h(h=0)),t);var yt=(h,t)=>{for(var e in t)Xt(h,e,{get:t[e],enumerable:!0})};import{randomBytes as re}from"crypto";import*as B from"fs/promises";import{createServer as ae}from"net";import{tmpdir as ce}from"os";import{join as St}from"path";var rt,It=lt(()=>{"use strict";rt=class{constructor(t,e){this.name=t;this.logger=e}name;logger;server;socket;socketDir;socketPath;token;startPromise;nextId=1;buffer="";pending=new Map;escapeCallback;lockPromise;async requestPermission(t){}async capabilities(){return{discovery:!1,application:!1,window:!1,state:!1}}async click(t,e,i,s,n=""){let o=await this.resolveCoordinateSpace(n);this.assertPointInBounds(o,t,e);let[r,a]=this.toNative(o,t,e);await this.request("click",{x:r,y:a,button:i,count:s})}async move(t,e,i=""){let s=await this.resolveCoordinateSpace(i);this.assertPointInBounds(s,t,e);let[n,o]=this.toNative(s,t,e);await this.request("move",{x:n,y:o})}async drag(t,e,i,s,n=""){let o=await this.resolveCoordinateSpace(n);this.assertPointInBounds(o,t,e),this.assertPointInBounds(o,i,s);let[r,a]=this.toNative(o,t,e),[c,l]=this.toNative(o,i,s);await this.request("drag",{x1:r,y1:a,x2:c,y2:l})}async mouseDown(t,e,i=""){let s=await this.resolveCoordinateSpace(i);this.assertPointInBounds(s,t,e);let[n,o]=this.toNative(s,t,e);await this.request("mouseDown",{x:n,y:o})}async mouseUp(t,e,i=""){let s=await this.resolveCoordinateSpace(i);this.assertPointInBounds(s,t,e);let[n,o]=this.toNative(s,t,e);await this.request("mouseUp",{x:n,y:o})}async type(t){await this.request("type",{text:t})}async key(t){await this.request("key",{combo:t})}async scroll(t,e,i,s,n=""){let o=await this.resolveCoordinateSpace(n);this.assertPointInBounds(o,t,e);let[r,a]=this.toNative(o,t,e);await this.request("scroll",{x:r,y:a,dx:i,dy:s})}async cursorPosition(t=""){let e=await this.request("cursorPosition",{}),i=await this.resolveCoordinateSpace(t),[s,n]=this.fromNative(i,e.x,e.y);return{x:s,y:n}}async display(t=""){let e=await this.resolveCoordinateSpace(t);return{width:e.targetWidth,height:e.targetHeight}}async screenshot(t,e,i,s,n,o,r){let a=await this.resolveCoordinateSpace(t,s,n),c=r??-1;if(o){this.assertRegionEdgeInBounds(a,o[0],o[1]),this.assertRegionEdgeInBounds(a,o[2],o[3]);let[d,w,u,A]=this.toNativeCrop(a,o[0],o[1],o[2],o[3]),C=await this.request("screenshot",{display:t,allowedApplicationIds:e,blockedWindowIds:i,width:0,height:0,x1:d,y1:w,x2:u,y2:A,quality:c});return C?Buffer.from(C,"base64"):null}let l=await this.request("screenshot",{display:t,allowedApplicationIds:e,blockedWindowIds:i,width:a.targetWidth,height:a.targetHeight,x1:0,y1:0,x2:0,y2:0,quality:c});return l?Buffer.from(l,"base64"):null}async listDisplays(){return(await this.listDisplayInfos()).map(e=>{let{targetWidth:i,targetHeight:s}=this.targetSizeForDisplay(e.bounds.width,e.bounds.height);return{displayId:e.displayId,label:e.label,width:i,height:s,isPrimary:e.isPrimary}})}async listWindows(){return this.request("listWindows",{})}async resolveApplication(t){return this.request("resolveApplication",{app:t})}async windowAtPoint(t,e,i){let s=await this.resolveCoordinateSpace(t);this.assertPointInBounds(s,e,i);let[n,o]=this.toNative(s,e,i);return this.request("windowAtPoint",{displayId:t,x:n,y:o})}async getActiveWindow(){return this.request("getActiveWindow",{})}async activateApplication(t){return this.request("activateApplication",{applicationId:t})}async concealApplication(t){return this.request("concealApplication",{applicationId:t})}async restoreApplication(t){return this.request("restoreApplication",{applicationId:t})}async activateWindow(t){return this.request("activateWindow",{windowId:t})}async concealWindow(t){return this.request("concealWindow",{windowId:t})}async restoreWindow(t){return this.request("restoreWindow",{windowId:t})}async getClipboard(){return this.request("getClipboard",{})}async setClipboard(t){await this.request("setClipboard",{text:t})}lock(t){this.escapeCallback=t;let e=this.request("lock",{}).then(i=>{if(!i)throw new Error(`${this.name} could not install the ESC abort handler.`);return!0}).catch(i=>{throw this.lockPromise===e&&(this.lockPromise=void 0),this.escapeCallback=void 0,i});return this.lockPromise=e,e.catch(i=>{this.logger?.log("debug","Driver","service.lock",this.errorFromUnknown(i).message)}),!0}unlock(){let t=this.lockPromise;this.lockPromise=void 0,this.escapeCallback=void 0;let e=()=>this.request("unlock",{});(t?t.catch(()=>!1).then(()=>e()):e()).catch(s=>{this.logger?.log("debug","Driver","service.unlock",this.errorFromUnknown(s).message)})}hideActionCursor(){this.request("hideActionCursor",{}).catch(t=>{this.logger?.log("debug","Driver","hideActionCursor",this.errorFromUnknown(t).message)})}async getWindowState(t,e,i,s,n,o,r){let a=await this.request("getWindowState",{app:t,windowTitleContains:e,windowId:i,includeScreenshot:s,includeTree:n,maxNodes:o,diffSince:r});return this.windowStateResult(t,this.parseServiceJson(a,"getWindowState"))}async windowClick(t,e,i,s,n,o,r,a,c,l,d){let w=this.parseServiceJson(await this.request("windowClick",this.actionParams({app:t,elementIndex:e,x:i,y:s,clickCount:n,mouseButton:o,windowTitleContains:r,windowId:a,stateToken:c},l,d)),"windowClick");return this.parseActionResult(w)}async invokeAction(t,e,i,s,n,o,r,a){let c=this.parseServiceJson(await this.request("invokeAction",this.actionParams({app:t,elementIndex:e,action:i,windowTitleContains:s,windowId:n,stateToken:o},r,a)),"invokeAction");return this.parseActionResult(c)}async windowScroll(t,e,i,s,n,o,r,a,c){let l=this.parseServiceJson(await this.request("windowScroll",this.actionParams({app:t,elementIndex:e,direction:i,pages:s,windowTitleContains:n,windowId:o,stateToken:r},a,c)),"windowScroll");return this.parseActionResult(l)}async windowDrag(t,e,i,s,n,o,r,a,c,l){let d=this.parseServiceJson(await this.request("windowDrag",this.actionParams({app:t,fromX:e,fromY:i,toX:s,toY:n,windowTitleContains:o,windowId:r,stateToken:a},c,l)),"windowDrag");return this.parseActionResult(d)}async typeText(t,e,i,s,n,o,r,a){let c=this.parseServiceJson(await this.request("typeText",this.actionParams({app:t,text:e,elementIndex:i,windowTitleContains:s,windowId:n,stateToken:o},r,a)),"typeText");return this.parseActionResult(c)}async pressKey(t,e,i,s,n,o,r){let a=this.parseServiceJson(await this.request("pressKey",this.actionParams({app:t,key:e,windowTitleContains:i,windowId:s,stateToken:n},o,r)),"pressKey");return this.parseActionResult(a)}async setValue(t,e,i,s,n,o,r,a){let c=this.parseServiceJson(await this.request("setValue",this.actionParams({app:t,elementIndex:e,value:i,windowTitleContains:s,windowId:n,stateToken:o},r,a)),"setValue");return this.parseActionResult(c)}async selectText(t,e,i,s,n,o,r,a,c,l,d){let w=this.parseServiceJson(await this.request("selectText",this.actionParams({app:t,elementIndex:e,text:i,prefix:s,suffix:n,selection:o,windowTitleContains:r,windowId:a,stateToken:c},l,d)),"selectText");return this.parseActionResult(w)}async prepareForInput(t,e,i){let s=Number.NaN,n=Number.NaN;if(i){let o=await this.resolveCoordinateSpace(t);this.assertPointInBounds(o,i.x,i.y),[s,n]=this.toNative(o,i.x,i.y)}return this.request("prepareForInput",{displayId:t,allowedAppIds:e,blockedWindowIds:i?.blockedWindowIds??[],x:s,y:n})}async request(t,e){t!=="lock"&&t!=="unlock"&&await this.lockPromise,await this.start();let i=this.socket,s=this.token;if(!i||i.destroyed||!s)throw new Error(`${this.name} is not connected.`);let n=this.nextId++,o=JSON.stringify({id:n,token:s,method:t,params:e})+`
3
2
  `;return new Promise((r,a)=>{this.pending.set(n,{resolve:r,reject:a}),i.write(o,c=>{c&&(this.pending.delete(n),a(c))})})}actionParams(t,e,i){let s=e??"text";return s==="none"?{...t,returnState:s}:i===void 0?{...t,returnState:s}:{...t,returnState:s,maxNodes:i}}errorFromUnknown(t){return t instanceof Error?t:new Error(String(t))}parseServiceJson(t,e){let i=JSON.parse(t);if(!this.isJsonObject(i))throw new Error(`Service ${e} returned an invalid JSON payload.`);return i}windowStateResult(t,e){let i=this.isJsonObject(e.window)?e.window:void 0,s=this.isJsonObject(e.screenshot)?e.screenshot:void 0,n=this.isJsonObject(s?.image)?s.image:void 0,o=typeof n?.imageBase64=="string"?n.imageBase64:void 0;return{app:t,windowId:typeof i?.windowID=="string"?i.windowID:void 0,stateToken:typeof e.stateToken=="string"?e.stateToken:void 0,text:typeof e.text=="string"?e.text:void 0,json:this.stripInlineImages(e),image:o?{data:o,mimeType:n?.mimeType==="image/jpeg"?"image/jpeg":"image/png"}:void 0,diagnostics:e.diagnostics}}parseActionResult(t){let e=this.isJsonObject(t.postState)?t.postState:void 0,i=Array.isArray(t.warnings)?t.warnings:[],s=typeof t.preStateToken=="string"&&t.preStateToken.length>0?t.preStateToken:void 0,n=typeof t.stateToken=="string"&&t.stateToken.length>0?t.stateToken:void 0,o=t.postStateUnavailableReason==="target_window_closed"||t.postStateUnavailableReason==="target_app_has_no_window"?t.postStateUnavailableReason:void 0;return{ok:typeof t.ok=="boolean"?t.ok:!1,windowId:typeof t.windowId=="string"?t.windowId:void 0,stateToken:s??n,postStateToken:typeof t.postStateToken=="string"?t.postStateToken:void 0,postState:e?this.windowStateResult(typeof e.app=="string"?e.app:"",e):void 0,postStateUnavailableReason:o,classification:typeof t.classification=="string"?t.classification:void 0,summary:typeof t.summary=="string"?t.summary:typeof t.classification=="string"?t.classification:void 0,warnings:i.filter(r=>typeof r=="string"),diagnostics:t}}stripInlineImages(t){if(typeof t=="string"&&t.length>1e3)return`${t.slice(0,1e3)}...[truncated ${t.length-1e3} chars]`;if(Array.isArray(t))return t.map(i=>this.stripInlineImages(i));if(!this.isJsonObject(t))return t;let e={};for(let[i,s]of Object.entries(t))e[i]=i==="imageBase64"?void 0:this.stripInlineImages(s);return e}isJsonObject(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}async start(){if(!(this.socket&&!this.socket.destroyed))return this.startPromise?this.startPromise:(this.startPromise=(async()=>{let t=await B.mkdtemp(St(ce(),"cuh.")),e=St(t,"s"),i=re(32).toString("hex");this.socketDir=t,this.socketPath=e,this.token=i;let s,n,o=new Promise((a,c)=>{s=a,n=c});await new Promise((a,c)=>{let l=ae(d=>{if(this.socket&&!this.socket.destroyed){d.destroy();return}this.attachSocket(d),s()});this.server=l,l.once("error",c),l.listen(e,()=>{l.unref(),B.chmod(e,384).catch(()=>{}),a()})});let r=setTimeout(()=>n(new Error(`${this.name} did not connect within 10s.`)),1e4);try{let a=await this.launchService(e,i,n);await o,this.logger?.log("debug","Driver","service_start",`Connected to ${a}`)}finally{clearTimeout(r)}})().catch(t=>{throw this.startPromise=void 0,this.stop(this.errorFromUnknown(t)),t}),this.startPromise)}attachSocket(t){this.socket=t,t.unref(),t.setEncoding("utf8"),t.on("data",e=>this.handleData(e)),t.once("close",()=>{this.stop(new Error(`${this.name} socket closed.`))}),t.once("error",e=>{this.stop(e)})}handleData(t){for(this.buffer+=t;;){let e=this.buffer.indexOf(`
4
- `);if(e<0)return;let i=this.buffer.slice(0,e);this.buffer=this.buffer.slice(e+1),i.trim()&&this.handleResponseLine(i)}}handleResponseLine(t){let e;try{e=JSON.parse(t)}catch(s){this.stop(this.errorFromUnknown(s));return}if(e.event==="escape"){this.escapeCallback?.();return}if(typeof e.id!="number")return;let i=this.pending.get(e.id);i&&(this.pending.delete(e.id),e.ok?i.resolve(e.result):i.reject(new Error(e.error?.message??e.error?.code??`${this.name} request failed.`)))}stop(t){for(let n of this.pending.values())n.reject(t);this.pending.clear(),this.lockPromise=void 0,this.escapeCallback=void 0,this.buffer="";let e=this.socket;this.socket=void 0,e?.destroy();let i=this.server;this.server=void 0,i?.close();let s=this.socketDir;this.socketDir=void 0,this.socketPath=void 0,this.token=void 0,this.startPromise=void 0,s&&B.rm(s,{recursive:!0,force:!0}).catch(()=>{})}async listDisplayInfos(){return this.request("listDisplays",{})}async nativeDisplay(){return this.request("display",{})}async resolveDisplay(t){let e=await this.listDisplayInfos();return t!==""?e.find(i=>i.displayId===t):e.find(i=>i.isPrimary)??e[0]}targetSizeForDisplay(t,e,i=0,s=0){if(i>0&&s>0)return{targetWidth:i,targetHeight:s};let r=Math.min(1,1568/Math.max(t,e),Math.sqrt(115e4/(t*e)));return{targetWidth:Math.floor(t*r),targetHeight:Math.floor(e*r)}}async resolveCoordinateSpace(t,e=0,i=0){let s=await this.resolveDisplay(t),n=s?.bounds.x??0,o=s?.bounds.y??0,r=s?.bounds??await this.nativeDisplay(),a=r.width,c=r.height,{targetWidth:l,targetHeight:d}=this.targetSizeForDisplay(a,c,e,i);return{originX:n,originY:o,displayWidth:a,displayHeight:c,scaleX:a/l,scaleY:c/d,targetWidth:l,targetHeight:d}}toNative(t,e,i){return[t.originX+e*t.scaleX,t.originY+i*t.scaleY]}fromNative(t,e,i){return[Math.round((e-t.originX)/t.scaleX),Math.round((i-t.originY)/t.scaleY)]}toNativeCrop(t,e,i,s,n){return[Math.floor(e*t.scaleX),Math.floor(i*t.scaleY),Math.ceil(s*t.scaleX),Math.ceil(n*t.scaleY)]}assertPointInBounds(t,e,i){if(e<0||i<0||e>=t.targetWidth||i>=t.targetHeight)throw new Error(`Coordinates (${e}, ${i}) are outside display bounds ${t.targetWidth}x${t.targetHeight}.`)}assertRegionEdgeInBounds(t,e,i){if(e<0||i<0||e>t.targetWidth||i>t.targetHeight)throw new Error(`Region edge (${e}, ${i}) is outside display bounds ${t.targetWidth}x${t.targetHeight}.`)}}});var $t={};yt($t,{MacComputer:()=>ut});import{execFile as le,spawn as de}from"child_process";import{createHash as pe}from"crypto";import*as b from"fs/promises";import{homedir as ue}from"os";import{dirname as pt,join as k}from"path";import{fileURLToPath as Pt}from"url";import{promisify as he}from"util";var Y,me,ut,Ct=ct(()=>{"use strict";It();Y=he(le),me=[{kind:"accessibility",label:"Accessibility"},{kind:"screen",label:"Screen Recording"}],ut=class u extends ot{constructor(e=pt(Pt(import.meta.url)),i){super("Copilot Computer Use",i);this.distDir=e}distDir;appName=`${this.name}.app`;systemInstallDir="/Applications";userInstallDir=k(ue(),"Applications");static create(e){return new u(pt(Pt(import.meta.url)),e)}async capabilities(){return{discovery:!0,application:!0,window:!0,state:!0}}async requestPermission(e){let i=await this.installApp(),s=await this.missingPermissions();if(s.length===0)return;let n=!0;for(;s.length>0;){let o=s.map(l=>`${l.label} for ${this.name}`),r=`Computer Use cannot start access until these permissions are granted: ${o.join(", ")}. The helper app is installed at ${i}. If ${this.name} is not listed in System Settings, add that app with the + button. Enable the listed permissions in System Settings > Privacy & Security, then retry the tool; ${this.name} will relaunch automatically if needed.`,a=await e.requestPermission({mode:"form",message:["",`Computer Use needs the following permission${s.length>1?"s":""} to control your desktop:`,"",...o.map(l=>`* ${l}`),"",`Choose each missing permission below, enable ${this.name} in System Settings, then return here.`,`The helper app is installed at ${i}.`,`If ${this.name} is not listed, add that app with the + button.`,`When all listed permissions are enabled, choose "I've granted the permissions".`,"",`Note: After granting permissions, retry the tool; ${this.name} will relaunch automatically if needed.`].join(`
3
+ `);if(e<0)return;let i=this.buffer.slice(0,e);this.buffer=this.buffer.slice(e+1),i.trim()&&this.handleResponseLine(i)}}handleResponseLine(t){let e;try{e=JSON.parse(t)}catch(s){this.stop(this.errorFromUnknown(s));return}if(e.event==="escape"){this.escapeCallback?.();return}if(typeof e.id!="number")return;let i=this.pending.get(e.id);i&&(this.pending.delete(e.id),e.ok?i.resolve(e.result):i.reject(new Error(e.error?.message??e.error?.code??`${this.name} request failed.`)))}stop(t){for(let n of this.pending.values())n.reject(t);this.pending.clear(),this.lockPromise=void 0,this.escapeCallback=void 0,this.buffer="";let e=this.socket;this.socket=void 0,e?.destroy();let i=this.server;this.server=void 0,i?.close();let s=this.socketDir;this.socketDir=void 0,this.socketPath=void 0,this.token=void 0,this.startPromise=void 0,s&&B.rm(s,{recursive:!0,force:!0}).catch(()=>{})}async listDisplayInfos(){return this.request("listDisplays",{})}async nativeDisplay(){return this.request("display",{})}async resolveDisplay(t){let e=await this.listDisplayInfos();return t!==""?e.find(i=>i.displayId===t):e.find(i=>i.isPrimary)??e[0]}targetSizeForDisplay(t,e,i=0,s=0){if(i>0&&s>0)return{targetWidth:i,targetHeight:s};let r=Math.min(1,1568/Math.max(t,e),Math.sqrt(115e4/(t*e)));return{targetWidth:Math.floor(t*r),targetHeight:Math.floor(e*r)}}async resolveCoordinateSpace(t,e=0,i=0){let s=await this.resolveDisplay(t),n=s?.bounds.x??0,o=s?.bounds.y??0,r=s?.bounds??await this.nativeDisplay(),a=r.width,c=r.height,{targetWidth:l,targetHeight:d}=this.targetSizeForDisplay(a,c,e,i);return{originX:n,originY:o,displayWidth:a,displayHeight:c,scaleX:a/l,scaleY:c/d,targetWidth:l,targetHeight:d}}toNative(t,e,i){return[t.originX+e*t.scaleX,t.originY+i*t.scaleY]}fromNative(t,e,i){return[Math.round((e-t.originX)/t.scaleX),Math.round((i-t.originY)/t.scaleY)]}toNativeCrop(t,e,i,s,n){return[Math.floor(e*t.scaleX),Math.floor(i*t.scaleY),Math.ceil(s*t.scaleX),Math.ceil(n*t.scaleY)]}assertPointInBounds(t,e,i){if(e<0||i<0||e>=t.targetWidth||i>=t.targetHeight)throw new Error(`Coordinates (${e}, ${i}) are outside display bounds ${t.targetWidth}x${t.targetHeight}.`)}assertRegionEdgeInBounds(t,e,i){if(e<0||i<0||e>t.targetWidth||i>t.targetHeight)throw new Error(`Region edge (${e}, ${i}) is outside display bounds ${t.targetWidth}x${t.targetHeight}.`)}}});var Ct={};yt(Ct,{MacComputer:()=>ut});import{execFile as le,spawn as de}from"child_process";import{createHash as pe}from"crypto";import*as b from"fs/promises";import{homedir as ue}from"os";import{basename as Pt,dirname as U,join as k}from"path";import{fileURLToPath as $t}from"url";import{promisify as he}from"util";var X,me,ut,Wt=lt(()=>{"use strict";It();X=he(le),me=[{kind:"accessibility",label:"Accessibility"},{kind:"screen",label:"Screen Recording"}],ut=class h extends rt{constructor(e=U($t(import.meta.url)),i){super("Copilot Computer Use",i);this.distDir=e}distDir;appName=`${this.name}.app`;systemInstallDir="/Applications";userInstallDir=k(ue(),"Applications");static create(e){return new h(U($t(import.meta.url)),e)}async capabilities(){return{discovery:!0,application:!0,window:!0,state:!0}}async requestPermission(e){let i=await this.installApp(),s=await this.missingPermissions();if(s.length===0)return;let n=!0;for(;s.length>0;){let o=s.map(l=>`${l.label} for ${this.name}`),r=`Computer Use cannot start access until these permissions are granted: ${o.join(", ")}. The helper app is installed at ${i}. If ${this.name} is not listed in System Settings, add that app with the + button. Enable the listed permissions in System Settings > Privacy & Security, then retry the tool; ${this.name} will relaunch automatically if needed.`,a=await e.requestPermission({mode:"form",message:["",`Computer Use needs the following permission${s.length>1?"s":""} to control your desktop:`,"",...o.map(l=>`* ${l}`),"",`Choose each missing permission below, enable ${this.name} in System Settings, then return here.`,`The helper app is installed at ${i}.`,`If ${this.name} is not listed, add that app with the + button.`,`When all listed permissions are enabled, choose "I've granted the permissions".`,"",`Note: After granting permissions, retry the tool; ${this.name} will relaunch automatically if needed.`].join(`
5
4
  `),requestedSchema:{type:"object",properties:{action:{type:"string",title:`Grant ${s.map(l=>l.label).join(" and ")} permission${s.length>1?"s":""}`,oneOf:[...s.map((l,d)=>({const:`open:${l.kind}`,title:`${d+1}. Open System Settings and grant ${l.label} permissions`})),{const:"done",title:`${s.length+1}. I've granted the permissions`}]}},required:["action"]}},r),c=a.action==="accept"?a.content?.action:void 0;if(c==="done")break;if(typeof c=="string"&&c.startsWith("open:")){let l=c.slice(5),d=s.find(w=>w.kind===l);if(!d)throw new Error(r);await this.requestPermissions(d.kind),s=await this.missingPermissions()}else throw new Error(r)}if(s=await this.missingPermissions(),s.length>0){let o=s.map(r=>`${r.label} for ${this.name}`);throw new Error(`These permissions are still not detected: ${o.join(", ")}. The helper app is installed at ${i}. Retry the tool; ${this.name} will relaunch automatically if needed. If it stays stuck, remove and re-add ${this.name} in System Settings, then try again.`)}n&&this.stop(new Error(`${this.name} restarting after permission grant.`))}async launchService(e,i,s){let n=await this.installApp(),o="",r=de("/usr/bin/open",["-n","-g",n,"--args","--socket",e,"--token",i,"--parent-pid",String(process.pid)],{stdio:["ignore","ignore","pipe"],detached:!1});r.unref();let a=r.stderr;return a.unref?.(),a.on("data",c=>{let l=c.toString("utf8").trim();l&&(o+=`${l}
6
- `,this.logger?.log("debug","Driver","service_stderr",l))}),r.once("exit",(c,l)=>{if(c!==0){let d=o.trim()?`: ${o.trim()}`:"";s(new Error(`${this.name} launch failed (${l??c??"unknown"})${d}`))}}),r.once("error",s),n}async installApp(){let e=k(this.distDir,"prebuilds",`darwin-${process.arch}`,this.appName),i=k(e,"Contents","MacOS",this.name);try{await b.access(i)}catch(c){throw new Error(`${this.name} is not installed at ${e}. Rebuild @github/computer-use-mcp so window-state mode can use the macOS service.`,{cause:c})}let s=await this.installDir(),n=k(s,this.appName),o=k(n,"Contents","MacOS",this.name),r=await this.fingerprint(e),a=await this.fingerprint(n);return r!==a&&(await b.mkdir(s,{recursive:!0}),await b.rm(n,{recursive:!0,force:!0}),await Y("/usr/bin/ditto",[e,n]),await b.chmod(o,493)),await this.clearQuarantineForLocalDev(n),await this.refreshLaunchServices(n,e),n}async missingPermissions(){let e=[];for(let i of me)await this.checkPermissions(i.kind)||e.push(i);return e}async checkPermissions(e){return this.request("checkPermissions",{kind:e})}async requestPermissions(e){await this.request("requestPermissions",{kind:e})}async installDir(){try{if((await b.stat(this.systemInstallDir)).isDirectory())return await b.access(this.systemInstallDir,b.constants.W_OK),this.systemInstallDir;this.logger?.log("debug","Driver","service_install_dir",`${this.systemInstallDir} is not a directory; using ${this.userInstallDir}.`)}catch(e){let i=e instanceof Error?e.message:String(e);this.logger?.log("debug","Driver","service_install_dir",`Using ${this.userInstallDir}; ${this.systemInstallDir} is not writable: ${i}`)}return this.userInstallDir}async fingerprint(e){try{let i=pe("sha256");for(let s of await this.bundleFiles(e))i.update(s),i.update("\0"),i.update(await b.readFile(k(e,s))),i.update("\0");return i.digest("hex")}catch(i){if(i instanceof Error&&"code"in i&&i.code==="ENOENT")return null;throw i}}async bundleFiles(e,i=""){let s=await b.readdir(k(e,i),{withFileTypes:!0}),n=[];for(let o of s.sort((r,a)=>r.name.localeCompare(a.name))){let r=i?k(i,o.name):o.name;o.isDirectory()?n.push(...await this.bundleFiles(e,r)):(o.isFile()||o.isSymbolicLink())&&n.push(r)}return n}async clearQuarantineForLocalDev(e){try{await b.access(k(pt(this.distDir),".git"))}catch{return}try{await Y("/usr/bin/xattr",["-dr","com.apple.quarantine",e])}catch(i){let s=i instanceof Error?i.message:String(i);this.logger?.log("debug","Driver","service_xattr",`Could not clear quarantine for ${e}: ${s}`)}}knownStaleServiceAppPaths(e,i){let s=new Set([e,k(this.systemInstallDir,this.appName),k(this.userInstallDir,this.appName)]);for(let n of["arm64","x64"])s.add(k(this.distDir,"helpers",`darwin-${n}`,this.appName)),s.add(k(this.distDir,"prebuilds",`darwin-${n}`,this.appName));return s.delete(i),[...s]}async refreshLaunchServices(e,i){try{await Y("/usr/bin/touch",[e])}catch(n){let o=n instanceof Error?n.message:String(n);this.logger?.log("debug","Driver","service_touch",`Could not touch ${e}: ${o}`)}let s="/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister";try{await b.access(s)}catch{this.logger?.log("debug","Driver","service_lsregister","LaunchServices registration tool is not present on this macOS version.");return}for(let n of this.knownStaleServiceAppPaths(i,e))try{await Y(s,["-u","-R",n])}catch(o){let r=o instanceof Error?o.message:String(o);this.logger?.log("debug","Driver","service_lsregister",`Could not unregister stale ${this.name} copy at ${n}: ${r}`)}try{await Y(s,["-f","-R",e])}catch(n){let o=n instanceof Error?n.message:String(n);this.logger?.log("debug","Driver","service_lsregister",`Could not refresh LaunchServices for ${e}: ${o}`)}}}});var Wt={};yt(Wt,{NativeComputer:()=>ht});import{createRequire as we}from"module";import{dirname as ge,join as fe}from"path";import{fileURLToPath as ye}from"url";var ht,Tt=ct(()=>{"use strict";ht=class u{constructor(t,e){this.native=t;this.logger=e;t.setLogger?.((i,s,n)=>{e?.log(this.nativeLogLevel(i),"Driver",s,n)})}native;logger;static create(t){let e=fe(ge(ye(import.meta.url)),"prebuilds",`${process.platform}-${process.arch}`,"computer.node"),i;try{i=we(import.meta.url)(e)}catch(s){let n=s instanceof Error?s.message:String(s);throw new Error(`Native computer bindings not available for ${process.platform}-${process.arch}: ${n} (path: ${e})`,{cause:s})}return new u(i,t)}static createForTest(t){return new u(t)}async requestPermission(t){process.platform==="linux"&&await this.display()}async capabilities(){let t=this.native.capabilities();return{...t,discovery:!!t.discovery&&typeof this.native.getActiveWindow=="function"&&typeof this.native.windowAtPoint=="function",state:!1}}async click(t,e,i,s,n=""){let o=await this.resolveCoordinateSpace(n);this.assertPointInBounds(o,t,e);let[r,a]=this.toNative(o,t,e);this.native.click(r,a,i,s)}async move(t,e,i=""){let s=await this.resolveCoordinateSpace(i);this.assertPointInBounds(s,t,e);let[n,o]=this.toNative(s,t,e);this.native.move(n,o)}async drag(t,e,i,s,n=""){let o=await this.resolveCoordinateSpace(n);this.assertPointInBounds(o,t,e),this.assertPointInBounds(o,i,s);let[r,a]=this.toNative(o,t,e),[c,l]=this.toNative(o,i,s);this.native.drag(r,a,c,l)}async mouseDown(t,e,i=""){let s=await this.resolveCoordinateSpace(i);this.assertPointInBounds(s,t,e);let[n,o]=this.toNative(s,t,e);this.native.mouseDown(n,o)}async mouseUp(t,e,i=""){let s=await this.resolveCoordinateSpace(i);this.assertPointInBounds(s,t,e);let[n,o]=this.toNative(s,t,e);this.native.mouseUp(n,o)}async type(t){this.native.type(t)}async key(t){this.native.key(t)}async scroll(t,e,i,s,n=""){let o=await this.resolveCoordinateSpace(n);this.assertPointInBounds(o,t,e);let[r,a]=this.toNative(o,t,e);this.native.scroll(r,a,i,s)}async cursorPosition(t=""){let e=this.native.cursorPosition(),i=await this.resolveCoordinateSpace(t),[s,n]=this.fromNative(i,e.x,e.y);return{x:s,y:n}}async display(t=""){let e=await this.resolveCoordinateSpace(t);return{width:e.targetWidth,height:e.targetHeight}}async screenshot(t,e,i,s,n,o,r){let a=await this.resolveCoordinateSpace(t,s,n),c=r??-1;if(o){this.assertRegionEdgeInBounds(a,o[0],o[1]),this.assertRegionEdgeInBounds(a,o[2],o[3]);let[l,d,w,h]=this.toNativeCrop(a,o[0],o[1],o[2],o[3]);return this.native.screenshot(t,e,i,0,0,l,d,w,h,c)}return this.native.screenshot(t,e,i,a.targetWidth,a.targetHeight,0,0,0,0,c)}async listDisplays(){return this.native.listDisplays().map(e=>{let{targetWidth:i,targetHeight:s}=this.targetSizeForDisplay(e.bounds.width,e.bounds.height);return{displayId:e.displayId,label:e.label,width:i,height:s,isPrimary:e.isPrimary}})}async listWindows(){return this.native.listWindows()}async resolveApplication(t){return null}async windowAtPoint(t,e,i){if(!this.native.windowAtPoint)return null;let s=await this.resolveCoordinateSpace(t);this.assertPointInBounds(s,e,i);let[n,o]=this.toNative(s,e,i);return this.native.windowAtPoint(t,n,o)}async getActiveWindow(){return this.native.getActiveWindow?this.native.getActiveWindow():null}async activateApplication(t){return this.native.activateApplication(t)}async concealApplication(t){return this.native.concealApplication(t)}async restoreApplication(t){return this.native.restoreApplication(t)}async activateWindow(t){return this.native.activateWindow(t)}async concealWindow(t){return this.native.concealWindow(t)}async restoreWindow(t){return this.native.restoreWindow(t)}async getClipboard(){return this.native.getClipboard()}async setClipboard(t){this.native.setClipboard(t)}lock(t){return this.native.lock?.(t)??!1}unlock(){this.native.unlock?.()}hideActionCursor(){}async getWindowState(t,e,i,s,n,o,r){throw new Error("Window-state is not implemented by NativeComputer.")}async windowClick(t,e,i,s,n,o,r,a,c,l,d){throw new Error("Window-state is not implemented by NativeComputer.")}async invokeAction(t,e,i,s,n,o,r,a){throw new Error("Window-state is not implemented by NativeComputer.")}async windowScroll(t,e,i,s,n,o,r,a,c){throw new Error("Window-state is not implemented by NativeComputer.")}async windowDrag(t,e,i,s,n,o,r,a,c,l){throw new Error("Window-state is not implemented by NativeComputer.")}async typeText(t,e,i,s,n,o,r,a){throw new Error("Window-state is not implemented by NativeComputer.")}async pressKey(t,e,i,s,n,o,r){throw new Error("Window-state is not implemented by NativeComputer.")}async setValue(t,e,i,s,n,o,r,a){throw new Error("Window-state is not implemented by NativeComputer.")}async selectText(t,e,i,s,n,o,r,a,c,l,d){throw new Error("Window-state is not implemented by NativeComputer.")}async prepareForInput(t,e,i){let s=Number.NaN,n=Number.NaN;if(i){let o=await this.resolveCoordinateSpace(t);this.assertPointInBounds(o,i.x,i.y),[s,n]=this.toNative(o,i.x,i.y)}return this.native.prepareForInput(t,e,i?.blockedWindowIds??[],s,n)}nativeLogLevel(t){switch(t){case 0:return"trace";case 1:return"debug";case 2:return"info";case 3:return"warn";case 4:return"error";default:return"info"}}async resolveDisplay(t){let e=this.native.listDisplays();return t!==""?e.find(i=>i.displayId===t):e.find(i=>i.isPrimary)??e[0]}targetSizeForDisplay(t,e,i=0,s=0){if(i>0&&s>0)return{targetWidth:i,targetHeight:s};let r=Math.min(1,1568/Math.max(t,e),Math.sqrt(115e4/(t*e)));return{targetWidth:Math.floor(t*r),targetHeight:Math.floor(e*r)}}async resolveCoordinateSpace(t,e=0,i=0){let s=await this.resolveDisplay(t),n=s?.bounds.x??0,o=s?.bounds.y??0,r=s?.bounds??this.native.display(),a=r.width,c=r.height,{targetWidth:l,targetHeight:d}=this.targetSizeForDisplay(a,c,e,i);return{originX:n,originY:o,displayWidth:a,displayHeight:c,scaleX:a/l,scaleY:c/d,targetWidth:l,targetHeight:d}}toNative(t,e,i){return[t.originX+e*t.scaleX,t.originY+i*t.scaleY]}fromNative(t,e,i){return[Math.round((e-t.originX)/t.scaleX),Math.round((i-t.originY)/t.scaleY)]}toNativeCrop(t,e,i,s,n){return[Math.floor(e*t.scaleX),Math.floor(i*t.scaleY),Math.ceil(s*t.scaleX),Math.ceil(n*t.scaleY)]}assertPointInBounds(t,e,i){if(e<0||i<0||e>=t.targetWidth||i>=t.targetHeight)throw new Error(`Coordinates (${e}, ${i}) are outside display bounds ${t.targetWidth}x${t.targetHeight}.`)}assertRegionEdgeInBounds(t,e,i){if(e<0||i<0||e>t.targetWidth||i>t.targetHeight)throw new Error(`Region edge (${e}, ${i}) is outside display bounds ${t.targetWidth}x${t.targetHeight}.`)}}});import{StdioServerTransport as Xe}from"@modelcontextprotocol/sdk/server/stdio.js";import{McpServer as be}from"@modelcontextprotocol/sdk/server/mcp.js";import{ElicitResultSchema as ve}from"@modelcontextprotocol/sdk/types.js";import{z as p}from"zod";var et=class{knownApplications=new Map;allowedAppIds=new Set;accessActive=!1;allowAll=!1;hostWindowId=null;rememberApplications(t){this.knownApplications.clear();for(let e of t)this.knownApplications.set(e.id,e);if(this.allowAll)for(let e of t)this.allowedAppIds.add(e.id)}getKnownApplications(t){return t.map(e=>{let i=this.knownApplications.get(e);if(!i)throw new Error(`Unknown application id '${e}'. Call list_applications first.`);return i})}setHostWindowId(t){this.hostWindowId=t}tryGetKnownApplication(t){return this.knownApplications.get(t)}allKnownApplications(){return[...this.knownApplications.values()]}allowApplications(t,e=!1,i){this.accessActive=!0;for(let s of t)this.allowedAppIds.add(s);if(e){this.allowAll=!0;for(let s of this.knownApplications.keys())this.allowedAppIds.add(s)}return i&&(this.hostWindowId=i),this.getState()}areAllowedForAccess(t){return this.allowAll||t.every(e=>this.allowedAppIds.has(e))}getState(){return{accessActive:this.accessActive,allowedAppIds:[...this.allowedAppIds],allowAll:this.allowAll,hostWindowId:this.hostWindowId}}};function E(u){let t=new Map,e=[...u].sort((i,s)=>`${i.applicationName}\0${i.title}\0${i.windowId}`.localeCompare(`${s.applicationName}\0${s.title}\0${s.windowId}`));for(let i of e){let s=i.applicationName||i.title||i.applicationId,n=t.get(i.applicationId);n||(n={id:i.applicationId,displayName:s,applicationNames:i.applicationNames,windows:[]},t.set(i.applicationId,n)),n.windows.push({windowId:i.windowId,title:i.title,displayId:i.displayId,isMinimized:i.isMinimized})}return[...t.values()].sort((i,s)=>`${i.displayName}\0${i.id}`.localeCompare(`${s.displayName}\0${s.id}`))}function _t(u){return u.toLowerCase().split(/[^a-z0-9]+/).filter(t=>t.length>0)}function bt(u){let t=new Set;for(let e of u)for(let i of _t(e))t.add(i);return t}function At(u){return u.trim().toLowerCase()}function vt(u){let t=new Set;for(let e of u){let i=At(e);i&&t.add(i)}return t}var J=class{appRecords=new Map;updateApplications(t){for(let e of t){let i=[e.displayName,...e.applicationNames??[]],s=this.appRecords.get(e.id);if(s){for(let n of bt(i))s.tokenBag.add(n);for(let n of vt(i))s.exactNames.add(n);s.displayName=e.displayName}else this.appRecords.set(e.id,{appId:e.id,displayName:e.displayName,tokenBag:bt(i),exactNames:vt(i)})}}resolve(t){let e=this.appRecords.get(t);if(e)return[e];let i=At(t);if(i){let o=[];for(let r of this.appRecords.values())r.exactNames.has(i)&&o.push(r);if(o.length>0)return o}let s=_t(t);if(s.length===0)return[];let n=[];for(let o of this.appRecords.values())s.every(r=>o.tokenBag.has(r))&&n.push(o);return n}allRecords(){return[...this.appRecords.values()]}};import{randomUUID as Kt}from"node:crypto";import{mkdirSync as Gt,writeFileSync as Qt}from"node:fs";import{homedir as Zt,tmpdir as te}from"node:os";import{dirname as ee,isAbsolute as ie,join as kt}from"node:path";var se={actionCoordinates:"window-local screenshot coordinates with origin at the target window top-left",screenFrames:"screen@ frames and window bounds are global screen coordinates; do not pass them directly to click/drag",localCenter:"local_center/localCenter values are window-local x,y hints suitable for click/drag coordinates"},V=class{constructor(t){this.result=t}result;toToolResult(t){let e=[],i=this.sanitizeJsonForOutput(),s;t.imageMode==="path"&&this.result.image&&(s=this.writeImage(t.screenshotOutFile),this.setScreenshotPath(i,s));let n=this.result.text?this.augmentProjection(this.result.text,i):this.buildProjection(i);s&&t.format!=="json"&&(n=`${n}
7
- screenshot: ${s}`);let o=i;if(t.format==="both"&&this.isRecord(i)){let c={...i},l=this.recordAtPath(c,["tree"]);if(l){let d=this.arrayAtPath(l,["nodes"]);c.tree={truncated:l.truncated,nodeCount:d.length,nodesOmitted:d.length>0}}o=c}let r=JSON.stringify(o,null,2),a=t.format==="json"?r:t.format==="both"?`${n}
5
+ `,this.logger?.log("debug","Driver","service_stderr",l))}),r.once("exit",(c,l)=>{if(c!==0){let d=o.trim()?`: ${o.trim()}`:"";s(new Error(`${this.name} launch failed (${l??c??"unknown"})${d}`))}}),r.once("error",s),n}async installApp(){let e=k(this.distDir,"prebuilds",`darwin-${process.arch}`,this.appName),i=k(e,"Contents","MacOS",this.name);try{await b.access(i)}catch(c){throw new Error(`${this.name} is not installed at ${e}. Rebuild @github/computer-use-mcp so window-state mode can use the macOS service.`,{cause:c})}let s=await this.installDir(),n=k(s,this.appName),o=k(n,"Contents","MacOS",this.name),r=await this.fingerprint(e),a=await this.fingerprint(n);return r!==a&&(await b.mkdir(s,{recursive:!0}),await b.rm(n,{recursive:!0,force:!0}),await X("/usr/bin/ditto",[e,n]),await b.chmod(o,493)),await this.clearQuarantineForLocalDev(n),await this.refreshLaunchServices(n,e),n}async missingPermissions(){let e=[];for(let i of me)await this.checkPermissions(i.kind)||e.push(i);return e}async checkPermissions(e){return this.request("checkPermissions",{kind:e})}async requestPermissions(e){await this.request("requestPermissions",{kind:e})}async installDir(){try{if((await b.stat(this.systemInstallDir)).isDirectory())return await b.access(this.systemInstallDir,b.constants.W_OK),this.systemInstallDir;this.logger?.log("debug","Driver","service_install_dir",`${this.systemInstallDir} is not a directory; using ${this.userInstallDir}.`)}catch(e){let i=e instanceof Error?e.message:String(e);this.logger?.log("debug","Driver","service_install_dir",`Using ${this.userInstallDir}; ${this.systemInstallDir} is not writable: ${i}`)}return this.userInstallDir}async fingerprint(e){try{let i=pe("sha256");for(let s of await this.bundleFiles(e))i.update(s),i.update("\0"),i.update(await b.readFile(k(e,s))),i.update("\0");return i.digest("hex")}catch(i){if(i instanceof Error&&"code"in i&&i.code==="ENOENT")return null;throw i}}async bundleFiles(e,i=""){let s=await b.readdir(k(e,i),{withFileTypes:!0}),n=[];for(let o of s.sort((r,a)=>r.name.localeCompare(a.name))){let r=i?k(i,o.name):o.name;o.isDirectory()?n.push(...await this.bundleFiles(e,r)):(o.isFile()||o.isSymbolicLink())&&n.push(r)}return n}async clearQuarantineForLocalDev(e){if(await this.isLocalCheckout())try{await X("/usr/bin/xattr",["-dr","com.apple.quarantine",e])}catch(i){let s=i instanceof Error?i.message:String(i);this.logger?.log("debug","Driver","service_xattr",`Could not clear quarantine for ${e}: ${s}`)}}async isLocalCheckout(){for(let e of[k(U(this.distDir),".git"),k(U(U(this.distDir)),".git")])try{return await b.access(e),!0}catch{continue}return!1}knownStaleServiceAppPaths(e,i){let s=U(this.distDir),n=new Set([this.distDir]);Pt(this.distDir)==="mcp"&&Pt(s)==="dist"&&n.add(s);let o=new Set([e,k(this.systemInstallDir,this.appName),k(this.userInstallDir,this.appName)]);for(let r of["arm64","x64"])for(let a of n)o.add(k(a,"helpers",`darwin-${r}`,this.appName)),o.add(k(a,"prebuilds",`darwin-${r}`,this.appName));return o.delete(i),[...o]}async refreshLaunchServices(e,i){try{await X("/usr/bin/touch",[e])}catch(n){let o=n instanceof Error?n.message:String(n);this.logger?.log("debug","Driver","service_touch",`Could not touch ${e}: ${o}`)}let s="/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister";try{await b.access(s)}catch{this.logger?.log("debug","Driver","service_lsregister","LaunchServices registration tool is not present on this macOS version.");return}for(let n of this.knownStaleServiceAppPaths(i,e))try{await X(s,["-u","-R",n])}catch(o){let r=o instanceof Error?o.message:String(o);this.logger?.log("debug","Driver","service_lsregister",`Could not unregister stale ${this.name} copy at ${n}: ${r}`)}try{await X(s,["-f","-R",e])}catch(n){let o=n instanceof Error?n.message:String(n);this.logger?.log("debug","Driver","service_lsregister",`Could not refresh LaunchServices for ${e}: ${o}`)}}}});var Rt={};yt(Rt,{NativeComputer:()=>ht});import{createRequire as we}from"module";import{dirname as ge,join as fe}from"path";import{fileURLToPath as ye}from"url";var ht,Tt=lt(()=>{"use strict";ht=class h{constructor(t,e){this.native=t;this.logger=e;t.setLogger?.((i,s,n)=>{e?.log(this.nativeLogLevel(i),"Driver",s,n)})}native;logger;static create(t){let e=fe(ge(ye(import.meta.url)),"prebuilds",`${process.platform}-${process.arch}`,"computer.node"),i;try{i=we(import.meta.url)(e)}catch(s){let n=s instanceof Error?s.message:String(s);throw new Error(`Native computer bindings not available for ${process.platform}-${process.arch}: ${n} (path: ${e})`,{cause:s})}return new h(i,t)}static createForTest(t){return new h(t)}async requestPermission(t){process.platform==="linux"&&await this.display()}async capabilities(){let t=this.native.capabilities();return{...t,discovery:!!t.discovery&&typeof this.native.getActiveWindow=="function"&&typeof this.native.windowAtPoint=="function",state:!1}}async click(t,e,i,s,n=""){let o=await this.resolveCoordinateSpace(n);this.assertPointInBounds(o,t,e);let[r,a]=this.toNative(o,t,e);this.native.click(r,a,i,s)}async move(t,e,i=""){let s=await this.resolveCoordinateSpace(i);this.assertPointInBounds(s,t,e);let[n,o]=this.toNative(s,t,e);this.native.move(n,o)}async drag(t,e,i,s,n=""){let o=await this.resolveCoordinateSpace(n);this.assertPointInBounds(o,t,e),this.assertPointInBounds(o,i,s);let[r,a]=this.toNative(o,t,e),[c,l]=this.toNative(o,i,s);this.native.drag(r,a,c,l)}async mouseDown(t,e,i=""){let s=await this.resolveCoordinateSpace(i);this.assertPointInBounds(s,t,e);let[n,o]=this.toNative(s,t,e);this.native.mouseDown(n,o)}async mouseUp(t,e,i=""){let s=await this.resolveCoordinateSpace(i);this.assertPointInBounds(s,t,e);let[n,o]=this.toNative(s,t,e);this.native.mouseUp(n,o)}async type(t){this.native.type(t)}async key(t){this.native.key(t)}async scroll(t,e,i,s,n=""){let o=await this.resolveCoordinateSpace(n);this.assertPointInBounds(o,t,e);let[r,a]=this.toNative(o,t,e);this.native.scroll(r,a,i,s)}async cursorPosition(t=""){let e=this.native.cursorPosition(),i=await this.resolveCoordinateSpace(t),[s,n]=this.fromNative(i,e.x,e.y);return{x:s,y:n}}async display(t=""){let e=await this.resolveCoordinateSpace(t);return{width:e.targetWidth,height:e.targetHeight}}async screenshot(t,e,i,s,n,o,r){let a=await this.resolveCoordinateSpace(t,s,n),c=r??-1;if(o){this.assertRegionEdgeInBounds(a,o[0],o[1]),this.assertRegionEdgeInBounds(a,o[2],o[3]);let[l,d,w,u]=this.toNativeCrop(a,o[0],o[1],o[2],o[3]);return this.native.screenshot(t,e,i,0,0,l,d,w,u,c)}return this.native.screenshot(t,e,i,a.targetWidth,a.targetHeight,0,0,0,0,c)}async listDisplays(){return this.native.listDisplays().map(e=>{let{targetWidth:i,targetHeight:s}=this.targetSizeForDisplay(e.bounds.width,e.bounds.height);return{displayId:e.displayId,label:e.label,width:i,height:s,isPrimary:e.isPrimary}})}async listWindows(){return this.native.listWindows()}async resolveApplication(t){return null}async windowAtPoint(t,e,i){if(!this.native.windowAtPoint)return null;let s=await this.resolveCoordinateSpace(t);this.assertPointInBounds(s,e,i);let[n,o]=this.toNative(s,e,i);return this.native.windowAtPoint(t,n,o)}async getActiveWindow(){return this.native.getActiveWindow?this.native.getActiveWindow():null}async activateApplication(t){return this.native.activateApplication(t)}async concealApplication(t){return this.native.concealApplication(t)}async restoreApplication(t){return this.native.restoreApplication(t)}async activateWindow(t){return this.native.activateWindow(t)}async concealWindow(t){return this.native.concealWindow(t)}async restoreWindow(t){return this.native.restoreWindow(t)}async getClipboard(){return this.native.getClipboard()}async setClipboard(t){this.native.setClipboard(t)}lock(t){return this.native.lock?.(t)??!1}unlock(){this.native.unlock?.()}hideActionCursor(){}async getWindowState(t,e,i,s,n,o,r){throw new Error("Window-state is not implemented by NativeComputer.")}async windowClick(t,e,i,s,n,o,r,a,c,l,d){throw new Error("Window-state is not implemented by NativeComputer.")}async invokeAction(t,e,i,s,n,o,r,a){throw new Error("Window-state is not implemented by NativeComputer.")}async windowScroll(t,e,i,s,n,o,r,a,c){throw new Error("Window-state is not implemented by NativeComputer.")}async windowDrag(t,e,i,s,n,o,r,a,c,l){throw new Error("Window-state is not implemented by NativeComputer.")}async typeText(t,e,i,s,n,o,r,a){throw new Error("Window-state is not implemented by NativeComputer.")}async pressKey(t,e,i,s,n,o,r){throw new Error("Window-state is not implemented by NativeComputer.")}async setValue(t,e,i,s,n,o,r,a){throw new Error("Window-state is not implemented by NativeComputer.")}async selectText(t,e,i,s,n,o,r,a,c,l,d){throw new Error("Window-state is not implemented by NativeComputer.")}async prepareForInput(t,e,i){let s=Number.NaN,n=Number.NaN;if(i){let o=await this.resolveCoordinateSpace(t);this.assertPointInBounds(o,i.x,i.y),[s,n]=this.toNative(o,i.x,i.y)}return this.native.prepareForInput(t,e,i?.blockedWindowIds??[],s,n)}nativeLogLevel(t){switch(t){case 0:return"trace";case 1:return"debug";case 2:return"info";case 3:return"warn";case 4:return"error";default:return"info"}}async resolveDisplay(t){let e=this.native.listDisplays();return t!==""?e.find(i=>i.displayId===t):e.find(i=>i.isPrimary)??e[0]}targetSizeForDisplay(t,e,i=0,s=0){if(i>0&&s>0)return{targetWidth:i,targetHeight:s};let r=Math.min(1,1568/Math.max(t,e),Math.sqrt(115e4/(t*e)));return{targetWidth:Math.floor(t*r),targetHeight:Math.floor(e*r)}}async resolveCoordinateSpace(t,e=0,i=0){let s=await this.resolveDisplay(t),n=s?.bounds.x??0,o=s?.bounds.y??0,r=s?.bounds??this.native.display(),a=r.width,c=r.height,{targetWidth:l,targetHeight:d}=this.targetSizeForDisplay(a,c,e,i);return{originX:n,originY:o,displayWidth:a,displayHeight:c,scaleX:a/l,scaleY:c/d,targetWidth:l,targetHeight:d}}toNative(t,e,i){return[t.originX+e*t.scaleX,t.originY+i*t.scaleY]}fromNative(t,e,i){return[Math.round((e-t.originX)/t.scaleX),Math.round((i-t.originY)/t.scaleY)]}toNativeCrop(t,e,i,s,n){return[Math.floor(e*t.scaleX),Math.floor(i*t.scaleY),Math.ceil(s*t.scaleX),Math.ceil(n*t.scaleY)]}assertPointInBounds(t,e,i){if(e<0||i<0||e>=t.targetWidth||i>=t.targetHeight)throw new Error(`Coordinates (${e}, ${i}) are outside display bounds ${t.targetWidth}x${t.targetHeight}.`)}assertRegionEdgeInBounds(t,e,i){if(e<0||i<0||e>t.targetWidth||i>t.targetHeight)throw new Error(`Region edge (${e}, ${i}) is outside display bounds ${t.targetWidth}x${t.targetHeight}.`)}}});import{McpServer as be}from"@modelcontextprotocol/sdk/server/mcp.js";import{ElicitResultSchema as ve}from"@modelcontextprotocol/sdk/types.js";import{z as p}from"zod";var it=class{knownApplications=new Map;allowedAppIds=new Set;accessActive=!1;allowAll=!1;hostWindowId=null;rememberApplications(t){this.knownApplications.clear();for(let e of t)this.knownApplications.set(e.id,e);if(this.allowAll)for(let e of t)this.allowedAppIds.add(e.id)}getKnownApplications(t){return t.map(e=>{let i=this.knownApplications.get(e);if(!i)throw new Error(`Unknown application id '${e}'. Call list_applications first.`);return i})}setHostWindowId(t){this.hostWindowId=t}tryGetKnownApplication(t){return this.knownApplications.get(t)}allKnownApplications(){return[...this.knownApplications.values()]}allowApplications(t,e=!1,i){this.accessActive=!0;for(let s of t)this.allowedAppIds.add(s);if(e){this.allowAll=!0;for(let s of this.knownApplications.keys())this.allowedAppIds.add(s)}return i&&(this.hostWindowId=i),this.getState()}areAllowedForAccess(t){return this.allowAll||t.every(e=>this.allowedAppIds.has(e))}getState(){return{accessActive:this.accessActive,allowedAppIds:[...this.allowedAppIds],allowAll:this.allowAll,hostWindowId:this.hostWindowId}}};function E(h){let t=new Map,e=[...h].sort((i,s)=>`${i.applicationName}\0${i.title}\0${i.windowId}`.localeCompare(`${s.applicationName}\0${s.title}\0${s.windowId}`));for(let i of e){let s=i.applicationName||i.title||i.applicationId,n=t.get(i.applicationId);n||(n={id:i.applicationId,displayName:s,applicationNames:i.applicationNames,windows:[]},t.set(i.applicationId,n)),n.windows.push({windowId:i.windowId,title:i.title,displayId:i.displayId,isMinimized:i.isMinimized})}return[...t.values()].sort((i,s)=>`${i.displayName}\0${i.id}`.localeCompare(`${s.displayName}\0${s.id}`))}function _t(h){return h.toLowerCase().split(/[^a-z0-9]+/).filter(t=>t.length>0)}function bt(h){let t=new Set;for(let e of h)for(let i of _t(e))t.add(i);return t}function At(h){return h.trim().toLowerCase()}function vt(h){let t=new Set;for(let e of h){let i=At(e);i&&t.add(i)}return t}var V=class{appRecords=new Map;updateApplications(t){for(let e of t){let i=[e.displayName,...e.applicationNames??[]],s=this.appRecords.get(e.id);if(s){for(let n of bt(i))s.tokenBag.add(n);for(let n of vt(i))s.exactNames.add(n);s.displayName=e.displayName}else this.appRecords.set(e.id,{appId:e.id,displayName:e.displayName,tokenBag:bt(i),exactNames:vt(i)})}}resolve(t){let e=this.appRecords.get(t);if(e)return[e];let i=At(t);if(i){let o=[];for(let r of this.appRecords.values())r.exactNames.has(i)&&o.push(r);if(o.length>0)return o}let s=_t(t);if(s.length===0)return[];let n=[];for(let o of this.appRecords.values())s.every(r=>o.tokenBag.has(r))&&n.push(o);return n}allRecords(){return[...this.appRecords.values()]}};import{randomUUID as Kt}from"node:crypto";import{mkdirSync as Gt,writeFileSync as Qt}from"node:fs";import{homedir as Zt,tmpdir as te}from"node:os";import{dirname as ee,isAbsolute as ie,join as kt}from"node:path";var se={actionCoordinates:"window-local screenshot coordinates with origin at the target window top-left",screenFrames:"screen@ frames and window bounds are global screen coordinates; do not pass them directly to click/drag",localCenter:"local_center/localCenter values are window-local x,y hints suitable for click/drag coordinates"},Y=class{constructor(t){this.result=t}result;toToolResult(t){let e=[],i=this.sanitizeJsonForOutput(),s;t.imageMode==="path"&&this.result.image&&(s=this.writeImage(t.screenshotOutFile),this.setScreenshotPath(i,s));let n=this.result.text?this.augmentProjection(this.result.text,i):this.buildProjection(i);s&&t.format!=="json"&&(n=`${n}
6
+ screenshot: ${s}`);let o=i;if(t.format==="both"&&this.isRecord(i)){let c={...i},l=this.recordAtPath(c,["tree"]);if(l){let d=this.arrayAtPath(l,["nodes"]);c.tree={truncated:l.truncated,nodeCount:d.length,nodeDetailsOmitted:d.length>0}}o=c}let r=JSON.stringify(o,null,2),a=t.format==="json"?r:t.format==="both"?`${n}
8
7
 
9
8
  --- window_state_json ---
10
- ${r}`:n;return e.push({type:"text",text:a}),t.imageMode==="image"&&this.result.image&&e.push({type:"image",data:this.result.image.data,mimeType:this.result.image.mimeType,_meta:{screenshot:!0,windowState:!0,stateToken:this.result.stateToken}}),{content:e}}sanitizeJsonForOutput(){return this.addCoordinateMetadata(this.sanitizeJson(this.result.json??{app:this.result.app,windowId:this.result.windowId,stateToken:this.result.stateToken}))}buildProjection(t=this.sanitizeJsonForOutput()){let e=this.stringAtPath(t,["window","applicationName"])??this.result.app??this.stringAtPath(t,["app"])??"unknown",i=this.stringAtPath(t,["window","applicationId"]),s=this.stringAtPath(t,["window","title"]),n=this.stringAtPath(t,["window","windowID"])??this.result.windowId,o=this.stringAtPath(t,["stateToken"])??this.result.stateToken,r=this.recordAtPath(t,["window","bounds"]),a=this.recordAtPath(t,["tree"]),c=this.arrayAtPath(a,["nodes"]).filter(h=>this.isRecord(h)),l=this.valueAtPath(a,["truncated"])===!0,d=["window_state compact_v1",`app: ${e}${i?` (${i})`:""}`,`window: ${s?JSON.stringify(s):"(untitled)"}${n?` id=${n}`:""}${r?` ${this.compactWindowRect(r,"screen@")}`:""}`,o?`state_token: ${o}`:void 0,`tree: ${c.length} node${c.length===1?"":"s"}${l?" (truncated)":""}`,"coordinate_contract: action x,y are window-local screenshot coordinates; screen@ frames are global; use local_center for click/drag","targeting: pass a line number or nodeId as element_index; include state_token when available",""].filter(h=>h!==void 0),w=this.renderCompactWindowNodes(c);return d.push(...w.length?w:["(no accessibility nodes returned)"]),d.join(`
9
+ ${r}`:n;return e.push({type:"text",text:a}),t.imageMode==="image"&&this.result.image&&e.push({type:"image",data:this.result.image.data,mimeType:this.result.image.mimeType,_meta:{screenshot:!0,windowState:!0,stateToken:this.result.stateToken}}),{content:e}}sanitizeJsonForOutput(){return this.addCoordinateMetadata(this.sanitizeJson(this.result.json??{app:this.result.app,windowId:this.result.windowId,stateToken:this.result.stateToken}))}buildProjection(t=this.sanitizeJsonForOutput()){let e=this.stringAtPath(t,["window","applicationName"])??this.result.app??this.stringAtPath(t,["app"])??"unknown",i=this.stringAtPath(t,["window","applicationId"]),s=this.stringAtPath(t,["window","title"]),n=this.stringAtPath(t,["window","windowID"])??this.result.windowId,o=this.stringAtPath(t,["stateToken"])??this.result.stateToken,r=this.recordAtPath(t,["window","bounds"]),a=this.recordAtPath(t,["tree"]),c=this.arrayAtPath(a,["nodes"]).filter(u=>this.isRecord(u)),l=this.valueAtPath(a,["truncated"])===!0,d=["window_state compact_v1",`app: ${e}${i?` (${i})`:""}`,`window: ${s?JSON.stringify(s):"(untitled)"}${n?` id=${n}`:""}${r?` ${this.compactWindowRect(r,"screen@")}`:""}`,o?`state_token: ${o}`:void 0,`tree: ${c.length} node${c.length===1?"":"s"}${l?" (truncated)":""}`,"coordinate_contract: action x,y are window-local screenshot coordinates; screen@ frames are global; use local_center for click/drag","targeting: pass a line number or nodeId as element_index; include state_token when available",""].filter(u=>u!==void 0),w=this.renderCompactWindowNodes(c);return d.push(...w.length?w:["(no accessibility nodes returned)"]),d.join(`
11
10
  `)}writeImage(t){if(!this.result.image)throw new Error("get_window_state image_mode=path requested a screenshot, but no screenshot was returned.");let e=t?this.expandHomePath(t):this.defaultImagePath();if(!ie(e))throw new Error("get_window_state screenshot_out_file must be an absolute path.");return Gt(ee(e),{recursive:!0}),Qt(e,Buffer.from(this.result.image.data,"base64")),e}defaultImagePath(){let t=this.result.image?.mimeType==="image/jpeg"?"jpg":"png",e=(this.result.app??"app").replace(/[^A-Za-z0-9._-]+/g,"-").replace(/^-+|-+$/g,"")||"app";return kt(te(),"computer-use-mcp","window-state",`${e}-${Date.now()}-${Kt()}.${t}`)}setScreenshotPath(t,e){if(!this.isRecord(t))return;let i=this.isRecord(t.screenshot)?t.screenshot:{},s=this.isRecord(i.image)?i.image:{};s.imagePath=e,i.image=s,t.screenshot=i}sanitizeJson(t,e){if(e==="imageBase64")return;if(typeof t=="string")return this.truncateString(t);if(Array.isArray(t))return t.map(s=>this.sanitizeJson(s));if(!this.isRecord(t))return t;let i={};for(let[s,n]of Object.entries(t))i[s]=this.sanitizeJson(n,s);return i}addCoordinateMetadata(t){if(!this.isRecord(t))return t;t.coordinateContract??=se;let e=this.recordAtPath(t,["window","bounds"]),i=this.recordAtPath(t,["tree"]),s=this.arrayAtPath(i,["nodes"]);for(let n of s){if(!this.isRecord(n)||this.isRecord(n.localCenter))continue;let o=this.localCenterForNode(n,e);o&&(n.localCenter=o)}return t}augmentProjection(t,e){if(t=this.labelScreenFrames(t),t.includes("coordinate_contract:"))return t;let i=t.split(`
12
11
  `),s=Math.max(i.findIndex(o=>o.trim()===""),0),n=["coordinate_contract: action x,y are window-local screenshot coordinates; screen@ frames are global; use local_center for click/drag",this.compactLocalCenters(e)].filter(o=>!!o);return s===0&&i[0]?.trim()!==""?[...n,...i].join(`
13
12
  `):(i.splice(s,0,...n),i.join(`
14
- `))}labelScreenFrames(t){return t.replace(/(^|[\s(])@(-?\d+,-?\d+\s+\d+x\d+)/g,"$1screen@$2")}truncateString(t){return t.length<=1e3?t:`${t.slice(0,1e3)}...[truncated ${t.length-1e3} chars]`}renderCompactWindowNodes(t){let e=[];for(let i of t){let s=this.compactWindowNodeLine(i);s&&e.push(s)}return e}compactWindowNodeLine(t){let e=this.stringValue(t.index)??this.numberValue(t.index)?.toString(),i=this.compactWindowRole(this.stringValue(t.role),this.stringValue(t.subrole)),s=[this.stringValue(t.title),this.stringValue(t.description),this.stringValue(t.value),this.stringValue(t.valueDescription)].map(d=>d?.replace(/\s+/g," ").trim()).filter(d=>!!d),n=[...new Set(s)].slice(0,2).map(d=>JSON.stringify(d.length>160?`${d.slice(0,157)}...`:d)),o=Array.isArray(t.actions)?t.actions.filter(d=>typeof d=="string").slice(0,4):[],r=[t.focused===!0?"focused":void 0,t.enabled===!1?"disabled":void 0].filter(d=>!!d),a=this.isRecord(t.frame)?this.compactWindowRect(t.frame,"screen@"):void 0,c=this.isRecord(t.localCenter)?this.compactPoint(t.localCenter):void 0;if(e==="1"||n.length>0||o.length>0||r.length>0||["window","button","checkbox","radio_button","text_field","text_area","link","menu_item","row","cell","table","list","scroll_area","web_area"].includes(i))return[`${e?`${e}. `:""}${i}`,...n,r.length?`[${r.join(",")}]`:void 0,o.length?`{${o.map(d=>d.replace(/^AX/,"").toLowerCase()).join(",")}}`:void 0,a,c?`local_center=${c}`:void 0].filter(d=>!!d).join(" ")}compactWindowRole(t,e){return(e&&e!==t?e:t??"element").replace(/^AX/,"").replace(/([a-z])([A-Z])/g,"$1_$2").replace(/[^A-Za-z0-9]+/g,"_").replace(/^_+|_+$/g,"").toLowerCase()||"element"}compactWindowRect(t,e="@"){let i=this.numberValue(t.x),s=this.numberValue(t.y),n=this.numberValue(t.width),o=this.numberValue(t.height);if(!(i===void 0||s===void 0||n===void 0||o===void 0))return`${e}${Math.round(i)},${Math.round(s)} ${Math.round(n)}x${Math.round(o)}`}compactPoint(t){let e=this.numberValue(t.x),i=this.numberValue(t.y);if(!(e===void 0||i===void 0))return`${Math.round(e)},${Math.round(i)}`}localCenterForNode(t,e){let i=this.recordAtPath(t,["frame"]);if(!i||!e)return;let s=this.numberValue(e.x),n=this.numberValue(e.y),o=this.numberValue(i.x),r=this.numberValue(i.y),a=this.numberValue(i.width),c=this.numberValue(i.height);if(s===void 0||n===void 0||o===void 0||r===void 0||a===void 0||c===void 0)return;let l=o-s+a/2,d=r-n+c/2;if(!(l<0||d<0))return{x:Math.round(l),y:Math.round(d)}}compactLocalCenters(t){let e=this.recordAtPath(t,["tree"]),s=this.arrayAtPath(e,["nodes"]).filter(n=>this.isRecord(n)).map(n=>{let o=this.isRecord(n.localCenter)?this.compactPoint(n.localCenter):void 0;if(!o)return;let r=this.stringValue(n.index)??this.numberValue(n.index)?.toString(),a=this.stringValue(n.nodeId),c=r??a;if(!(!c||c==="1"||!this.isActionableNode(n)))return`${c}=${o}`}).filter(n=>!!n).slice(0,12);return s.length?`local_centers: ${s.join(" ")} (window-local)`:void 0}isActionableNode(t){let e=this.compactWindowRole(this.stringValue(t.role),this.stringValue(t.subrole));return(Array.isArray(t.actions)?t.actions.some(s=>typeof s=="string"):!1)||["button","checkbox","radio_button","text_field","text_area","link","menu_item","row","cell"].includes(e)}expandHomePath(t){return t==="~"||t.startsWith("~/")?kt(Zt(),t.slice(2)):t}isRecord(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}stringValue(t){return typeof t=="string"?t:void 0}numberValue(t){return typeof t=="number"&&Number.isFinite(t)?t:void 0}valueAtPath(t,e){let i=t;for(let s of e){if(!this.isRecord(i))return;i=i[s]}return i}stringAtPath(t,e){return this.stringValue(this.valueAtPath(t,e))}recordAtPath(t,e){let i=this.valueAtPath(t,e);return this.isRecord(i)?i:void 0}arrayAtPath(t,e){let i=this.valueAtPath(t,e);return Array.isArray(i)?i:[]}};var ne=new Set(["ctrl","control","shift","alt","option","super","meta","cmd","command","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9","return","enter","tab","space","backspace","delete","forwarddelete","escape","esc","up","down","left","right","home","end","pageup","pagedown","insert","capslock","f1","f2","f3","f4","f5","f6","f7","f8","f9","f10","f11","f12","-","minus","=","equal","plus","[","]","\\",";","'",",",".","/","`"]),oe={arrowup:"up",arrowdown:"down",arrowleft:"left",arrowright:"right",page_up:"pageup",page_down:"pagedown",backslash:"\\",semicolon:";",slash:"/",grave:"`",bracketleft:"[",bracketright:"]",super_l:"super",gui:"super",win:"super",windows:"super",caps_lock:"capslock",caps:"capslock",del:"delete"};function lt(u){u==="+"?u="plus":u.length>2&&u.endsWith("++")&&(u=u.slice(0,-1)+"plus");let t=u.split("+").map(i=>i.trim().toLowerCase()).filter(Boolean);if(t.length===0)throw new Error("Key combo must contain at least one key.");return t.map(i=>{let s=oe[i]??i;if(!ne.has(s))throw new Error(`Unknown key "${i}" in combo "${u}".`);return s}).join("+")}import*as $ from"fs/promises";import*as xt from"os";import*as it from"path";var dt="<!-- LOG -->",st=class{logDir;logPath;startTime=performance.now();queue=Promise.resolve();constructor(){this.logDir=it.join(xt.homedir(),".copilot","logs","computer-use"),this.logPath=it.join(this.logDir,`${this.timestamp()}.html`)}timestamp(){let t=new Date,e=(i,s=2)=>String(i).padStart(s,"0");return`${t.getFullYear()}${e(t.getMonth()+1)}${e(t.getDate())}-${e(t.getHours())}${e(t.getMinutes())}${e(t.getSeconds())}.${e(Math.floor(t.getMilliseconds()/10))}`}elapsed(){return`${((performance.now()-this.startTime)/1e3).toFixed(2)}s`}insert(t){return this.queue=this.queue.then(()=>this.write(t)).catch(()=>this.write(t)).catch(()=>{}),this.queue}async write(t){let e=!0;try{await $.access(this.logPath)}catch{e=!1}e||(await $.mkdir(this.logDir,{recursive:!0}),await $.writeFile(this.logPath,`<!DOCTYPE html>
13
+ `))}labelScreenFrames(t){return t.replace(/(^|[\s(])@(-?\d+,-?\d+\s+\d+x\d+)/g,"$1screen@$2")}truncateString(t){return t.length<=1e3?t:`${t.slice(0,1e3)}...[truncated ${t.length-1e3} chars]`}renderCompactWindowNodes(t){let e=[];for(let i of t){let s=this.compactWindowNodeLine(i);s&&e.push(s)}return e}compactWindowNodeLine(t){let e=this.stringValue(t.index)??this.numberValue(t.index)?.toString(),i=this.compactWindowRole(this.stringValue(t.role),this.stringValue(t.subrole)),s=[this.stringValue(t.title),this.stringValue(t.description),this.stringValue(t.value),this.stringValue(t.valueDescription)].map(d=>d?.replace(/\s+/g," ").trim()).filter(d=>!!d),n=[...new Set(s)].slice(0,2).map(d=>JSON.stringify(d.length>160?`${d.slice(0,157)}...`:d)),o=Array.isArray(t.actions)?t.actions.filter(d=>typeof d=="string").slice(0,4):[],r=[t.focused===!0?"focused":void 0,t.enabled===!1?"disabled":void 0].filter(d=>!!d),a=this.isRecord(t.frame)?this.compactWindowRect(t.frame,"screen@"):void 0,c=this.isRecord(t.localCenter)?this.compactPoint(t.localCenter):void 0;if(e==="1"||n.length>0||o.length>0||r.length>0||["window","button","checkbox","radio_button","text_field","text_area","link","menu_item","row","cell","table","list","scroll_area","web_area"].includes(i))return[`${e?`${e}. `:""}${i}`,...n,r.length?`[${r.join(",")}]`:void 0,o.length?`{${o.map(d=>d.replace(/^AX/,"").toLowerCase()).join(",")}}`:void 0,a,c?`local_center=${c}`:void 0].filter(d=>!!d).join(" ")}compactWindowRole(t,e){return(e&&e!==t?e:t??"element").replace(/^AX/,"").replace(/([a-z])([A-Z])/g,"$1_$2").replace(/[^A-Za-z0-9]+/g,"_").replace(/^_+|_+$/g,"").toLowerCase()||"element"}compactWindowRect(t,e="@"){let i=this.numberValue(t.x),s=this.numberValue(t.y),n=this.numberValue(t.width),o=this.numberValue(t.height);if(!(i===void 0||s===void 0||n===void 0||o===void 0))return`${e}${Math.round(i)},${Math.round(s)} ${Math.round(n)}x${Math.round(o)}`}compactPoint(t){let e=this.numberValue(t.x),i=this.numberValue(t.y);if(!(e===void 0||i===void 0))return`${Math.round(e)},${Math.round(i)}`}localCenterForNode(t,e){let i=this.recordAtPath(t,["frame"]);if(!i||!e)return;let s=this.numberValue(e.x),n=this.numberValue(e.y),o=this.numberValue(i.x),r=this.numberValue(i.y),a=this.numberValue(i.width),c=this.numberValue(i.height);if(s===void 0||n===void 0||o===void 0||r===void 0||a===void 0||c===void 0)return;let l=o-s+a/2,d=r-n+c/2;if(!(l<0||d<0))return{x:Math.round(l),y:Math.round(d)}}compactLocalCenters(t){let e=this.recordAtPath(t,["tree"]),s=this.arrayAtPath(e,["nodes"]).filter(n=>this.isRecord(n)).map(n=>{let o=this.isRecord(n.localCenter)?this.compactPoint(n.localCenter):void 0;if(!o)return;let r=this.stringValue(n.index)??this.numberValue(n.index)?.toString(),a=this.stringValue(n.nodeId),c=r??a;if(!(!c||c==="1"||!this.isActionableNode(n)))return`${c}=${o}`}).filter(n=>!!n).slice(0,12);return s.length?`local_centers: ${s.join(" ")} (window-local)`:void 0}isActionableNode(t){let e=this.compactWindowRole(this.stringValue(t.role),this.stringValue(t.subrole));return(Array.isArray(t.actions)?t.actions.some(s=>typeof s=="string"):!1)||["button","checkbox","radio_button","text_field","text_area","link","menu_item","row","cell"].includes(e)}expandHomePath(t){return t==="~"||t.startsWith("~/")?kt(Zt(),t.slice(2)):t}isRecord(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}stringValue(t){return typeof t=="string"?t:void 0}numberValue(t){return typeof t=="number"&&Number.isFinite(t)?t:void 0}valueAtPath(t,e){let i=t;for(let s of e){if(!this.isRecord(i))return;i=i[s]}return i}stringAtPath(t,e){return this.stringValue(this.valueAtPath(t,e))}recordAtPath(t,e){let i=this.valueAtPath(t,e);return this.isRecord(i)?i:void 0}arrayAtPath(t,e){let i=this.valueAtPath(t,e);return Array.isArray(i)?i:[]}};var ne=new Set(["ctrl","control","shift","alt","option","super","meta","cmd","command","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9","return","enter","tab","space","backspace","delete","forwarddelete","escape","esc","up","down","left","right","home","end","pageup","pagedown","insert","capslock","f1","f2","f3","f4","f5","f6","f7","f8","f9","f10","f11","f12","-","minus","=","equal","plus","[","]","\\",";","'",",",".","/","`"]),oe={arrowup:"up",arrowdown:"down",arrowleft:"left",arrowright:"right",page_up:"pageup",page_down:"pagedown",backslash:"\\",semicolon:";",slash:"/",grave:"`",bracketleft:"[",bracketright:"]",super_l:"super",gui:"super",win:"super",windows:"super",caps_lock:"capslock",caps:"capslock",del:"delete"};function dt(h){h==="+"?h="plus":h.length>2&&h.endsWith("++")&&(h=h.slice(0,-1)+"plus");let t=h.split("+").map(i=>i.trim().toLowerCase()).filter(Boolean);if(t.length===0)throw new Error("Key combo must contain at least one key.");return t.map(i=>{let s=oe[i]??i;if(!ne.has(s))throw new Error(`Unknown key "${i}" in combo "${h}".`);return s}).join("+")}import*as $ from"fs/promises";import*as xt from"os";import*as st from"path";var pt="<!-- LOG -->",nt=class{logDir;logPath;startTime=performance.now();queue=Promise.resolve();constructor(){this.logDir=st.join(xt.homedir(),".copilot","logs","computer-use"),this.logPath=st.join(this.logDir,`${this.timestamp()}.html`)}timestamp(){let t=new Date,e=(i,s=2)=>String(i).padStart(s,"0");return`${t.getFullYear()}${e(t.getMonth()+1)}${e(t.getDate())}-${e(t.getHours())}${e(t.getMinutes())}${e(t.getSeconds())}.${e(Math.floor(t.getMilliseconds()/10))}`}elapsed(){return`${((performance.now()-this.startTime)/1e3).toFixed(2)}s`}insert(t){return this.queue=this.queue.then(()=>this.write(t)).catch(()=>this.write(t)).catch(()=>{}),this.queue}async write(t){let e=!0;try{await $.access(this.logPath)}catch{e=!1}e||(await $.mkdir(this.logDir,{recursive:!0}),await $.writeFile(this.logPath,`<!DOCTYPE html>
15
14
  <html>
16
15
  <head>
17
16
  <meta charset="utf-8">
@@ -35,18 +34,17 @@ ${r}`:n;return e.push({type:"text",text:a}),t.imageMode==="image"&&this.result.i
35
34
  <body>
36
35
  <table>
37
36
  <tr><th>Time</th><th>Level</th><th>Source</th><th>Action</th><th>Details</th></tr>
38
- ${dt}
37
+ ${pt}
39
38
  </table>
40
39
  </body>
41
40
  </html>
42
- `));let i=await $.readFile(this.logPath,"utf-8");await $.writeFile(this.logPath,i.replace(dt,t+dt))}rowHtml(t,e,i,s){return`<tr><td class="time">${this.elapsed()}</td><td class="level level-${i}">${i}</td><td class="source">${s}</td><td class="action">${this.escapeHtml(t)}</td><td>${e}</td></tr>
41
+ `));let i=await $.readFile(this.logPath,"utf-8");await $.writeFile(this.logPath,i.replace(pt,t+pt))}rowHtml(t,e,i,s){return`<tr><td class="time">${this.elapsed()}</td><td class="level level-${i}">${i}</td><td class="source">${s}</td><td class="action">${this.escapeHtml(t)}</td><td>${e}</td></tr>
43
42
  `}escapeHtml(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}renderMarkdown(t){let e=t.split(`
44
- `),i=[],s=[],n=()=>{s.length>0&&(i.push(`<ul style="margin:0;padding-left:1.2em">${s.map(o=>`<li>${this.escapeHtml(o)}</li>`).join("")}</ul>`),s=[])};for(let o of e)o.startsWith("- ")?s.push(o.slice(2)):(n(),o.length>0&&(i.length>0&&i.push("<br>"),i.push(this.escapeHtml(o))));return n(),i.join("")}log(t,e,i,s){this.insert(this.rowHtml(i,this.renderMarkdown(s),t,e))}logScreenshot(t,e,i,s){if(i){let n=s===void 0?"png":"jpg",o=`${this.timestamp()}.${n}`;$.mkdir(this.logDir,{recursive:!0}).then(()=>$.writeFile(it.join(this.logDir,o),i)),this.insert(this.rowHtml(t,`${this.escapeHtml(e)}<br><img src="${o}">`,"info","Computer"))}else this.insert(this.rowHtml(t,this.escapeHtml(e),"error","Computer"))}};var nt=class{computer;logger;constructor(t,e){this.computer=t,this.logger=e}log(t,e){this.logger.log("info","Computer",t,e)}async requestPermission(t){await this.computer.requestPermission(t)}async capabilities(){let t=await this.computer.capabilities();return this.log("capabilities",JSON.stringify(t)),t}async click(t,e,i,s,n=""){await this.computer.click(t,e,i,s,n),this.log("click",`(${t}, ${e}) button=${i} count=${s}${n?` display=${n}`:""}`)}async move(t,e,i=""){await this.computer.move(t,e,i),this.log("move",`(${t}, ${e})${i?` display=${i}`:""}`)}async drag(t,e,i,s,n=""){await this.computer.drag(t,e,i,s,n),this.log("drag",`(${t}, ${e}) \u2192 (${i}, ${s})${n?` display=${n}`:""}`)}async mouseDown(t,e,i=""){await this.computer.mouseDown(t,e,i),this.log("mouseDown",`(${t}, ${e})${i?` display=${i}`:""}`)}async mouseUp(t,e,i=""){await this.computer.mouseUp(t,e,i),this.log("mouseUp",`(${t}, ${e})${i?` display=${i}`:""}`)}async type(t){await this.computer.type(t),this.log("type",`"${t}"`)}async key(t){await this.computer.key(t),this.log("key",t)}async scroll(t,e,i,s,n=""){await this.computer.scroll(t,e,i,s,n),this.log("scroll",`(${t}, ${e}) dx=${i} dy=${s}${n?` display=${n}`:""}`)}async cursorPosition(t=""){let e=await this.computer.cursorPosition(t);return this.log("cursorPosition",`(${e.x}, ${e.y})${t?` display=${t}`:""}`),e}async display(t=""){let e=await this.computer.display(t);return this.log("display",`${e.width}x${e.height}${t?` display=${t}`:""}`),e}async listDisplays(){let t=await this.computer.listDisplays(),e=t.map(i=>`${i.isPrimary?"*":""}${i.displayId} "${i.label}" ${i.width}x${i.height}`).join("; ");return this.log("listDisplays",`${t.length} displays${e?`: ${e}`:""}`),t}async listWindows(){let t=await this.computer.listWindows(),e=new Map;for(let s of t){let n=s.displayId||"(unknown)",o=e.get(n)??{visible:0,minimized:0};s.isMinimized?o.minimized+=1:o.visible+=1,e.set(n,o)}let i=[...e.entries()].sort(([s],[n])=>s.localeCompare(n)).map(([s,n])=>`${s}: ${n.visible} visible, ${n.minimized} minimized`).join("; ");return this.log("listWindows",`${t.length} windows${i?`: ${i}`:""}`),t}async resolveApplication(t){let e=await this.computer.resolveApplication(t);return this.log("resolveApplication",`${t} -> ${e?`${e.applicationName} (${e.applicationId})`:"null"}`),e}async windowAtPoint(t,e,i){let s=await this.computer.windowAtPoint(t,e,i);return this.log("windowAtPoint",`display=${t||"(primary)"} (${e}, ${i}) -> ${s?`${s.windowId} title="${s.title}"`:"null"}`),s}async getActiveWindow(){let t=await this.computer.getActiveWindow();return this.log("getActiveWindow",t?`${t.windowId} title="${t.title}"`:"null"),t}async activateApplication(t){let e=await this.computer.activateApplication(t);return this.log("activateApplication",`${t} -> ${e}`),e}async concealApplication(t){let e=await this.computer.concealApplication(t);return this.log("concealApplication",`${t} -> ${e}`),e}async restoreApplication(t){let e=await this.computer.restoreApplication(t);return this.log("restoreApplication",`${t} -> ${e}`),e}async activateWindow(t){let e=await this.computer.activateWindow(t);return this.log("activateWindow",`${t} -> ${e}`),e}async concealWindow(t){let e=await this.computer.concealWindow(t);return this.log("concealWindow",`${t} -> ${e}`),e}async restoreWindow(t){let e=await this.computer.restoreWindow(t);return this.log("restoreWindow",`${t} -> ${e}`),e}async getClipboard(){let t=await this.computer.getClipboard(),e=t.slice(0,200)+(t.length>200?"\u2026":"");return this.log("getClipboard",`"${e}"`),t}async setClipboard(t){await this.computer.setClipboard(t);let e=t.slice(0,200)+(t.length>200?"\u2026":"");this.log("setClipboard",`"${e}" (${t.length} chars)`)}async getWindowState(t,e,i,s,n,o,r){let a=await this.computer.getWindowState(t,e,i,s,n,o,r);return this.log("getWindowState",`app=${t} windowId=${a.windowId??"(default)"} stateToken=${a.stateToken??"(none)"} diffSince=${r??"(none)"}`),a}async windowClick(t,e,i,s,n,o,r,a,c,l,d){let w=await this.computer.windowClick(t,e,i,s,n,o,r,a,c,l,d);return this.log("windowClick",`app=${t} ok=${w.ok}`),w}async invokeAction(t,e,i,s,n,o,r,a){let c=await this.computer.invokeAction(t,e,i,s,n,o,r,a);return this.log("invokeAction",`app=${t} element=${e} action=${i} ok=${c.ok}`),c}async windowScroll(t,e,i,s,n,o,r,a,c){let l=await this.computer.windowScroll(t,e,i,s,n,o,r,a,c);return this.log("windowScroll",`app=${t} element=${e} direction=${i} ok=${l.ok}`),l}async windowDrag(t,e,i,s,n,o,r,a,c,l){let d=await this.computer.windowDrag(t,e,i,s,n,o,r,a,c,l);return this.log("windowDrag",`app=${t} (${e},${i}) -> (${s},${n}) ok=${d.ok}`),d}async typeText(t,e,i,s,n,o,r,a){let c=await this.computer.typeText(t,e,i,s,n,o,r,a);return this.log("typeText",`app=${t} chars=${e.length} ok=${c.ok}`),c}async pressKey(t,e,i,s,n,o,r){let a=await this.computer.pressKey(t,e,i,s,n,o,r);return this.log("pressKey",`app=${t} key=${e} ok=${a.ok}`),a}async setValue(t,e,i,s,n,o,r,a){let c=await this.computer.setValue(t,e,i,s,n,o,r,a);return this.log("setValue",`app=${t} element=${e} chars=${i.length} ok=${c.ok}`),c}async selectText(t,e,i,s,n,o,r,a,c,l,d){let w=await this.computer.selectText(t,e,i,s,n,o,r,a,c,l,d);return this.log("selectText",`app=${t} element=${e} chars=${i.length} selection=${o??"text"} ok=${w.ok}`),w}lock(t){return this.computer.lock(t)}unlock(){this.computer.unlock()}hideActionCursor(){this.computer.hideActionCursor()}async prepareForInput(t,e,i){let s=await this.computer.prepareForInput(t,e,i),n=i?` @ (${i.x},${i.y})`:"",o=e===null?"all":e.length.toString();return this.log("prepareForInput",`${t} -> ${s} (${o} apps)${n}`),s}async screenshot(t,e,i,s,n,o,r){let a=await this.computer.screenshot(t,e,i,s,n,o,r),c=s&&n?` (${s}x${n})`:"",l=o?` crop=[${o.join(",")}]`:"",d=`display=${t||"(primary)"}`,w=r===void 0?"":` quality=${r}`,h=`${d}${c}${l}${w}`;return this.logger.logScreenshot("screenshot",h,a,r),a}};var X=.8,_e=250,D={readOnlyHint:!0,destructiveHint:!1,openWorldHint:!1},_={readOnlyHint:!1,destructiveHint:!0,openWorldHint:!0},mt={readOnlyHint:!1,destructiveHint:!1,openWorldHint:!1},x=" Requires `request_access`.",Rt=" If the target app is missing, call `list_applications` then `request_access`.",S=p.coerce.number().transform(Math.round),K=p.object({x:S.describe("Horizontal pixel coordinate."),y:S.describe("Vertical pixel coordinate.")}),Ae=p.object({x1:S.describe("Left edge of the region in screenshot pixel coordinates."),y1:S.describe("Top edge of the region in screenshot pixel coordinates."),x2:S.describe("Right edge of the region in screenshot pixel coordinates."),y2:S.describe("Bottom edge of the region in screenshot pixel coordinates.")}).refine(({x1:u,x2:t})=>t>u,{message:"x2 must be greater than x1.",path:["x2"]}).refine(({y1:u,y2:t})=>t>u,{message:"y2 must be greater than y1.",path:["y2"]}),ke=p.string().min(1).describe("Application name or stable app id from `list_applications`. Examples: 'Google Chrome', 'Microsoft Outlook', 'app.windows.abc123'."),xe=p.object({display_id:p.string().optional().describe("Display id to select. Omit or pass an empty string to use the default display.")}),Dt=p.object({display_id:p.string().optional().describe("Optional display id to filter by. When provided, only apps with at least one non-minimized window on that display are returned.")}),Nt=K.optional().describe("{x, y} pixel coordinate. Clicks at current cursor position if omitted."),qt=p.enum(["left","right","middle"]).optional().describe("Mouse button to click (default left)."),Et=p.coerce.number().int().min(1).max(3).optional().describe("Number of clicks: 1 single, 2 double, 3 triple (default 1)."),Mt=K.describe("{x, y} pixel coordinate to move the cursor to."),jt=K.describe("{x, y} pixel coordinate to start the drag from."),Ot=K.describe("{x, y} pixel coordinate to drag to."),Lt=p.string().describe("The text to type."),Ft=p.string().describe("Key combo to press (e.g. 'Return', 'ctrl+s', 'alt+Tab')."),Bt=p.enum(["up","down","left","right"]).describe("Direction to scroll."),Ut=K.optional().describe("{x, y} pixel coordinate to scroll at. Scrolls at current cursor position if omitted."),Ht=p.number().int().nonnegative().max(100).optional().describe("Number of scroll clicks (default 3)."),Se=p.number().nonnegative().max(100).describe("Seconds to wait (max 100). Use after a screenshot shows the UI is not in the expected state yet, but an operation may still finish."),zt=p.string().describe("The text to copy to the clipboard."),m={app:p.string().min(1).describe("App name or bundle identifier."),window_title_contains:p.string().min(1).optional().describe("Optional window title substring to choose a specific window."),window_id:p.string().min(1).optional().describe("Optional helper/native window id returned by a prior window-state response."),state_token:p.string().min(1).optional().describe("Optional state token returned by get_window_state. Pass it to detect stale UI state.")},U=p.string().min(1).describe("Element index or stable nodeId from get_window_state. Prefer nodeId when available."),Ie=p.enum(["image","path","omit"]).describe("How to return screenshots. `image` returns MCP image content, `path` writes a local file and returns its path, `omit` skips capture. Defaults to omit; pass image or path when a visual snapshot is needed."),Pe=p.enum(["text","json","both"]).describe("Response format. `text` returns compact semantic state, `json` returns sanitized debug metadata, and `both` returns compact state plus sanitized JSON. Defaults to text."),$e=p.enum(["none","text","image","path"]).describe("Post-action state to return. Defaults to text for a fresh semantic snapshot; pass none to skip the post-action state poll."),M={return_state:$e.optional(),screenshot_out_file:p.string().min(1).optional().describe("Optional absolute path for return_state=path. Parent directories are created if needed."),max_nodes:p.number().int().positive().optional().describe("Maximum UI tree nodes for returned post-action state.")},Ce=p.object({app:m.app,window_title_contains:m.window_title_contains,window_id:m.window_id,image_mode:Ie.optional(),format:Pe.optional(),screenshot_out_file:p.string().min(1).optional().describe("Optional absolute path for image_mode=path. Parent directories are created if needed."),include_screenshot:p.boolean().optional().describe("Deprecated compatibility flag. Use image_mode instead. false maps to image_mode=omit."),include_tree:p.boolean().optional().describe("Whether to include the accessibility/UI tree. Defaults to true."),max_nodes:p.number().int().positive().optional().describe("Maximum UI tree nodes to return."),diff_since:p.string().min(1).optional().describe("Optional prior state_token. Returns compact semantic diff when native can compare against that snapshot."),diff_from_state_token:p.string().min(1).optional().describe("Alias for diff_since.")}),We=p.object({app:m.app,window_title_contains:m.window_title_contains,window_id:m.window_id,state_token:m.state_token,element_index:U.optional(),x:S.optional().describe("Window-local x coordinate in the screenshot returned by get_window_state. Origin is the target window's top-left, not the desktop."),y:S.optional().describe("Window-local y coordinate in the screenshot returned by get_window_state. Origin is the target window's top-left, not the desktop."),click_count:p.number().int().positive().max(2).optional().describe("Number of clicks. Defaults to 1."),mouse_button:p.enum(["left","right","middle"]).optional().describe("Mouse button. Defaults to left."),...M}),Te=p.object({app:m.app,window_title_contains:m.window_title_contains,window_id:m.window_id,state_token:m.state_token,element_index:U,action:p.string().min(1).describe("Accessibility action label from get_window_state."),...M}),Re=p.object({app:m.app,window_title_contains:m.window_title_contains,window_id:m.window_id,state_token:m.state_token,element_index:U.describe("Scrollable element index or stable nodeId from get_window_state."),direction:p.enum(["up","down","left","right"]).describe("Scroll direction."),pages:p.number().int().positive().optional().describe("Number of pages to scroll. Defaults to 1."),...M}),De=p.object({app:m.app,window_title_contains:m.window_title_contains,window_id:m.window_id,state_token:m.state_token,from_x:S.describe("Start window-local x coordinate in the screenshot returned by get_window_state. Origin is the target window's top-left, not the desktop."),from_y:S.describe("Start window-local y coordinate in the screenshot returned by get_window_state. Origin is the target window's top-left, not the desktop."),to_x:S.describe("End window-local x coordinate in the screenshot returned by get_window_state. Origin is the target window's top-left, not the desktop."),to_y:S.describe("End window-local y coordinate in the screenshot returned by get_window_state. Origin is the target window's top-left, not the desktop."),...M}),Ne=p.object({app:m.app,window_title_contains:m.window_title_contains,window_id:m.window_id,state_token:m.state_token,element_index:U.optional().describe("Optional text element index or stable nodeId from get_window_state."),text:p.string().describe("Literal text to type."),...M}),qe=p.object({app:m.app,window_title_contains:m.window_title_contains,window_id:m.window_id,state_token:m.state_token,key:p.string().min(1).optional().describe("Key or key-combination, e.g. command+a, Return, Escape, PageDown."),keys:p.string().min(1).optional().describe("Alias for `key`. Models sometimes emit `keys` instead; either name works."),...M}),Ee=p.object({app:m.app,window_title_contains:m.window_title_contains,window_id:m.window_id,state_token:m.state_token,element_index:U.describe("Settable element index or stable nodeId from get_window_state."),value:p.string().describe("Value to set."),...M}),Me=p.object({app:m.app,window_title_contains:m.window_title_contains,window_id:m.window_id,state_token:m.state_token,element_index:U.describe("Text element index or stable nodeId from get_window_state."),text:p.string().min(1).describe("Exact text to select or place the cursor around."),prefix:p.string().optional().describe("Optional text immediately before the target text to disambiguate repeated matches."),suffix:p.string().optional().describe("Optional text immediately after the target text to disambiguate repeated matches."),selection:p.enum(["text","cursor_before","cursor_after"]).optional().describe("Selection mode. Defaults to text."),...M}),je=p.object({action:p.literal("click"),coordinate:Nt,button:qt,count:Et}),Oe=p.object({action:p.literal("mouse_move"),coordinate:Mt}),Le=p.object({action:p.literal("left_click_drag"),start_coordinate:jt,coordinate:Ot}),Fe=p.object({action:p.literal("left_mouse_down")}),Be=p.object({action:p.literal("left_mouse_up")}),Ue=p.object({action:p.literal("type"),text:Lt}),He=p.object({action:p.literal("key"),text:Ft}),ze=p.object({action:p.literal("scroll"),scroll_direction:Bt,coordinate:Ut,scroll_amount:Ht}),Je=p.object({action:p.literal("set_clipboard"),text:zt}),Ve=p.discriminatedUnion("action",[je,Oe,Le,Fe,Be,Ue,He,ze,Je]),Ye=p.object({actions:p.array(Ve).min(1).describe("Ordered actions. Do not include waits; call the separate `wait` tool only after observing a screenshot that is not ready yet.")}),rt=class u{_computer;_caps;_locked=null;_safetyTimer;static SAFETY_TIMEOUT_MS=180*1e3;server;logger;accessStore=new et;appNameResolver=new J;lastUnsharedWindowsNote=null;accessRequestQueue=Promise.resolve();selectedDisplay="";options;constructor(t={}){this.options={...t,window_state:t.window_state},process.env.DEBUG&&(this.logger=new st)}toText(t,e){let i=[{type:"text",text:t}];return e?{content:i,isError:!0}:{content:i}}toJson(t){return this.toText(JSON.stringify(t,null,2))}toImage(t,e,i){return t?{content:[{type:"image",data:t.toString("base64"),mimeType:this.imageMimeType(i),_meta:{screenshot:!0}}]}:this.toText(e,!0)}buildAccessMessage(t,e){let i=t.length===0?["","Computer Use runs on your actual desktop and can send mouse and keyboard input.","","Computer Use wants to control your desktop for this session.","","Apps that are not allowed may be hidden."]:["","Computer Use runs on your actual desktop and can send mouse and keyboard input to the apps you share.","","Computer Use wants to control these apps:","",...t.map(s=>`- ${s}`),"","Apps that are not allowed may be hidden."];return e&&i.push("","Reason:",e),i.join(`
43
+ `),i=[],s=[],n=()=>{s.length>0&&(i.push(`<ul style="margin:0;padding-left:1.2em">${s.map(o=>`<li>${this.escapeHtml(o)}</li>`).join("")}</ul>`),s=[])};for(let o of e)o.startsWith("- ")?s.push(o.slice(2)):(n(),o.length>0&&(i.length>0&&i.push("<br>"),i.push(this.escapeHtml(o))));return n(),i.join("")}log(t,e,i,s){this.insert(this.rowHtml(i,this.renderMarkdown(s),t,e))}logScreenshot(t,e,i,s){if(i){let n=s===void 0?"png":"jpg",o=`${this.timestamp()}.${n}`;$.mkdir(this.logDir,{recursive:!0}).then(()=>$.writeFile(st.join(this.logDir,o),i)),this.insert(this.rowHtml(t,`${this.escapeHtml(e)}<br><img src="${o}">`,"info","Computer"))}else this.insert(this.rowHtml(t,this.escapeHtml(e),"error","Computer"))}};var ot=class{computer;logger;constructor(t,e){this.computer=t,this.logger=e}log(t,e){this.logger.log("info","Computer",t,e)}async requestPermission(t){await this.computer.requestPermission(t)}async capabilities(){let t=await this.computer.capabilities();return this.log("capabilities",JSON.stringify(t)),t}async click(t,e,i,s,n=""){await this.computer.click(t,e,i,s,n),this.log("click",`(${t}, ${e}) button=${i} count=${s}${n?` display=${n}`:""}`)}async move(t,e,i=""){await this.computer.move(t,e,i),this.log("move",`(${t}, ${e})${i?` display=${i}`:""}`)}async drag(t,e,i,s,n=""){await this.computer.drag(t,e,i,s,n),this.log("drag",`(${t}, ${e}) \u2192 (${i}, ${s})${n?` display=${n}`:""}`)}async mouseDown(t,e,i=""){await this.computer.mouseDown(t,e,i),this.log("mouseDown",`(${t}, ${e})${i?` display=${i}`:""}`)}async mouseUp(t,e,i=""){await this.computer.mouseUp(t,e,i),this.log("mouseUp",`(${t}, ${e})${i?` display=${i}`:""}`)}async type(t){await this.computer.type(t),this.log("type",`"${t}"`)}async key(t){await this.computer.key(t),this.log("key",t)}async scroll(t,e,i,s,n=""){await this.computer.scroll(t,e,i,s,n),this.log("scroll",`(${t}, ${e}) dx=${i} dy=${s}${n?` display=${n}`:""}`)}async cursorPosition(t=""){let e=await this.computer.cursorPosition(t);return this.log("cursorPosition",`(${e.x}, ${e.y})${t?` display=${t}`:""}`),e}async display(t=""){let e=await this.computer.display(t);return this.log("display",`${e.width}x${e.height}${t?` display=${t}`:""}`),e}async listDisplays(){let t=await this.computer.listDisplays(),e=t.map(i=>`${i.isPrimary?"*":""}${i.displayId} "${i.label}" ${i.width}x${i.height}`).join("; ");return this.log("listDisplays",`${t.length} displays${e?`: ${e}`:""}`),t}async listWindows(){let t=await this.computer.listWindows(),e=new Map;for(let s of t){let n=s.displayId||"(unknown)",o=e.get(n)??{visible:0,minimized:0};s.isMinimized?o.minimized+=1:o.visible+=1,e.set(n,o)}let i=[...e.entries()].sort(([s],[n])=>s.localeCompare(n)).map(([s,n])=>`${s}: ${n.visible} visible, ${n.minimized} minimized`).join("; ");return this.log("listWindows",`${t.length} windows${i?`: ${i}`:""}`),t}async resolveApplication(t){let e=await this.computer.resolveApplication(t);return this.log("resolveApplication",`${t} -> ${e?`${e.applicationName} (${e.applicationId})`:"null"}`),e}async windowAtPoint(t,e,i){let s=await this.computer.windowAtPoint(t,e,i);return this.log("windowAtPoint",`display=${t||"(primary)"} (${e}, ${i}) -> ${s?`${s.windowId} title="${s.title}"`:"null"}`),s}async getActiveWindow(){let t=await this.computer.getActiveWindow();return this.log("getActiveWindow",t?`${t.windowId} title="${t.title}"`:"null"),t}async activateApplication(t){let e=await this.computer.activateApplication(t);return this.log("activateApplication",`${t} -> ${e}`),e}async concealApplication(t){let e=await this.computer.concealApplication(t);return this.log("concealApplication",`${t} -> ${e}`),e}async restoreApplication(t){let e=await this.computer.restoreApplication(t);return this.log("restoreApplication",`${t} -> ${e}`),e}async activateWindow(t){let e=await this.computer.activateWindow(t);return this.log("activateWindow",`${t} -> ${e}`),e}async concealWindow(t){let e=await this.computer.concealWindow(t);return this.log("concealWindow",`${t} -> ${e}`),e}async restoreWindow(t){let e=await this.computer.restoreWindow(t);return this.log("restoreWindow",`${t} -> ${e}`),e}async getClipboard(){let t=await this.computer.getClipboard(),e=t.slice(0,200)+(t.length>200?"\u2026":"");return this.log("getClipboard",`"${e}"`),t}async setClipboard(t){await this.computer.setClipboard(t);let e=t.slice(0,200)+(t.length>200?"\u2026":"");this.log("setClipboard",`"${e}" (${t.length} chars)`)}async getWindowState(t,e,i,s,n,o,r){let a=await this.computer.getWindowState(t,e,i,s,n,o,r);return this.log("getWindowState",`app=${t} windowId=${a.windowId??"(default)"} stateToken=${a.stateToken??"(none)"} diffSince=${r??"(none)"}`),a}async windowClick(t,e,i,s,n,o,r,a,c,l,d){let w=await this.computer.windowClick(t,e,i,s,n,o,r,a,c,l,d);return this.log("windowClick",`app=${t} ok=${w.ok}`),w}async invokeAction(t,e,i,s,n,o,r,a){let c=await this.computer.invokeAction(t,e,i,s,n,o,r,a);return this.log("invokeAction",`app=${t} element=${e} action=${i} ok=${c.ok}`),c}async windowScroll(t,e,i,s,n,o,r,a,c){let l=await this.computer.windowScroll(t,e,i,s,n,o,r,a,c);return this.log("windowScroll",`app=${t} element=${e} direction=${i} ok=${l.ok}`),l}async windowDrag(t,e,i,s,n,o,r,a,c,l){let d=await this.computer.windowDrag(t,e,i,s,n,o,r,a,c,l);return this.log("windowDrag",`app=${t} (${e},${i}) -> (${s},${n}) ok=${d.ok}`),d}async typeText(t,e,i,s,n,o,r,a){let c=await this.computer.typeText(t,e,i,s,n,o,r,a);return this.log("typeText",`app=${t} chars=${e.length} ok=${c.ok}`),c}async pressKey(t,e,i,s,n,o,r){let a=await this.computer.pressKey(t,e,i,s,n,o,r);return this.log("pressKey",`app=${t} key=${e} ok=${a.ok}`),a}async setValue(t,e,i,s,n,o,r,a){let c=await this.computer.setValue(t,e,i,s,n,o,r,a);return this.log("setValue",`app=${t} element=${e} chars=${i.length} ok=${c.ok}`),c}async selectText(t,e,i,s,n,o,r,a,c,l,d){let w=await this.computer.selectText(t,e,i,s,n,o,r,a,c,l,d);return this.log("selectText",`app=${t} element=${e} chars=${i.length} selection=${o??"text"} ok=${w.ok}`),w}lock(t){return this.computer.lock(t)}unlock(){this.computer.unlock()}hideActionCursor(){this.computer.hideActionCursor()}async prepareForInput(t,e,i){let s=await this.computer.prepareForInput(t,e,i),n=i?` @ (${i.x},${i.y})`:"",o=e===null?"all":e.length.toString();return this.log("prepareForInput",`${t} -> ${s} (${o} apps)${n}`),s}async screenshot(t,e,i,s,n,o,r){let a=await this.computer.screenshot(t,e,i,s,n,o,r),c=s&&n?` (${s}x${n})`:"",l=o?` crop=[${o.join(",")}]`:"",d=`display=${t||"(primary)"}`,w=r===void 0?"":` quality=${r}`,u=`${d}${c}${l}${w}`;return this.logger.logScreenshot("screenshot",u,a,r),a}};var K=.8,_e=250,D={readOnlyHint:!0,destructiveHint:!1,openWorldHint:!1},_={readOnlyHint:!1,destructiveHint:!0,openWorldHint:!0},mt={readOnlyHint:!1,destructiveHint:!1,openWorldHint:!1},x=" Requires `request_access`.",Dt=" If the target app is missing, call `list_applications` then `request_access`.",S=p.coerce.number().transform(Math.round),G=p.object({x:S.describe("Horizontal pixel coordinate."),y:S.describe("Vertical pixel coordinate.")}),Ae=p.object({x1:S.describe("Left edge of the region in screenshot pixel coordinates."),y1:S.describe("Top edge of the region in screenshot pixel coordinates."),x2:S.describe("Right edge of the region in screenshot pixel coordinates."),y2:S.describe("Bottom edge of the region in screenshot pixel coordinates.")}).refine(({x1:h,x2:t})=>t>h,{message:"x2 must be greater than x1.",path:["x2"]}).refine(({y1:h,y2:t})=>t>h,{message:"y2 must be greater than y1.",path:["y2"]}),ke=p.string().min(1).describe("Application name or stable app id from `list_applications`. Examples: 'Google Chrome', 'Microsoft Outlook', 'app.windows.abc123'."),xe=p.object({display_id:p.string().optional().describe("Display id to select. Omit or pass an empty string to use the default display.")}),Nt=p.object({display_id:p.string().optional().describe("Optional display id to filter by. When provided, only apps with at least one non-minimized window on that display are returned.")}),qt=G.optional().describe("{x, y} pixel coordinate. Clicks at current cursor position if omitted."),Et=p.enum(["left","right","middle"]).optional().describe("Mouse button to click (default left)."),Mt=p.coerce.number().int().min(1).max(3).optional().describe("Number of clicks: 1 single, 2 double, 3 triple (default 1)."),jt=G.describe("{x, y} pixel coordinate to move the cursor to."),Ot=G.describe("{x, y} pixel coordinate to start the drag from."),Lt=G.describe("{x, y} pixel coordinate to drag to."),Ft=p.string().describe("The text to type."),Bt=p.string().describe("Key combo to press (e.g. 'Return', 'ctrl+s', 'alt+Tab')."),Ut=p.enum(["up","down","left","right"]).describe("Direction to scroll."),Ht=G.optional().describe("{x, y} pixel coordinate to scroll at. Scrolls at current cursor position if omitted."),zt=p.number().int().nonnegative().max(100).optional().describe("Number of scroll clicks (default 3)."),Se=p.number().nonnegative().max(100).describe("Seconds to wait (max 100). Use after a screenshot shows the UI is not in the expected state yet, but an operation may still finish."),Jt=p.string().describe("The text to copy to the clipboard."),m={app:p.string().min(1).describe("App name or bundle identifier."),window_title_contains:p.string().min(1).optional().describe("Optional window title substring to choose a specific window."),window_id:p.string().min(1).optional().describe("Optional helper/native window id returned by a prior window-state response."),state_token:p.string().min(1).optional().describe("Optional state token returned by get_window_state. Pass it to detect stale UI state.")},H=p.string().min(1).describe("Element index or stable nodeId from get_window_state. Prefer nodeId when available."),Ie=p.enum(["image","path","omit"]).describe("How to return screenshots. `image` returns MCP image content, `path` writes a local file and returns its path, `omit` skips capture. Defaults to omit; pass image or path when a visual snapshot is needed."),Pe=p.enum(["text","json","both"]).describe("Response format. `text` returns compact semantic state, `json` returns sanitized debug metadata, and `both` returns compact state plus sanitized JSON. Defaults to text."),$e=p.enum(["none","text","image","path"]).describe("Post-action state to return. Defaults to text for a fresh semantic snapshot; pass none to skip the post-action state poll."),M={return_state:$e.optional(),screenshot_out_file:p.string().min(1).optional().describe("Optional absolute path for return_state=path. Parent directories are created if needed."),max_nodes:p.number().int().positive().optional().describe("Maximum UI tree nodes for returned post-action state.")},Ce=p.object({app:m.app,window_title_contains:m.window_title_contains,window_id:m.window_id,image_mode:Ie.optional(),format:Pe.optional(),screenshot_out_file:p.string().min(1).optional().describe("Optional absolute path for image_mode=path. Parent directories are created if needed."),include_screenshot:p.boolean().optional().describe("Deprecated compatibility flag. Use image_mode instead. false maps to image_mode=omit."),include_tree:p.boolean().optional().describe("Whether to include the accessibility/UI tree. Defaults to true."),max_nodes:p.number().int().positive().optional().describe("Maximum UI tree nodes to return."),diff_since:p.string().min(1).optional().describe("Optional prior state_token. Returns compact semantic diff when native can compare against that snapshot."),diff_from_state_token:p.string().min(1).optional().describe("Alias for diff_since.")}),We=p.object({app:m.app,window_title_contains:m.window_title_contains,window_id:m.window_id,state_token:m.state_token,element_index:H.optional(),x:S.optional().describe("Window-local x coordinate in the screenshot returned by get_window_state. Origin is the target window's top-left, not the desktop."),y:S.optional().describe("Window-local y coordinate in the screenshot returned by get_window_state. Origin is the target window's top-left, not the desktop."),click_count:p.number().int().positive().max(2).optional().describe("Number of clicks. Defaults to 1."),mouse_button:p.enum(["left","right","middle"]).optional().describe("Mouse button. Defaults to left."),...M}),Re=p.object({app:m.app,window_title_contains:m.window_title_contains,window_id:m.window_id,state_token:m.state_token,element_index:H,action:p.string().min(1).describe("Accessibility action label from get_window_state."),...M}),Te=p.object({app:m.app,window_title_contains:m.window_title_contains,window_id:m.window_id,state_token:m.state_token,element_index:H.describe("Scrollable element index or stable nodeId from get_window_state."),direction:p.enum(["up","down","left","right"]).describe("Scroll direction."),pages:p.number().int().positive().optional().describe("Number of pages to scroll. Defaults to 1."),...M}),De=p.object({app:m.app,window_title_contains:m.window_title_contains,window_id:m.window_id,state_token:m.state_token,from_x:S.describe("Start window-local x coordinate in the screenshot returned by get_window_state. Origin is the target window's top-left, not the desktop."),from_y:S.describe("Start window-local y coordinate in the screenshot returned by get_window_state. Origin is the target window's top-left, not the desktop."),to_x:S.describe("End window-local x coordinate in the screenshot returned by get_window_state. Origin is the target window's top-left, not the desktop."),to_y:S.describe("End window-local y coordinate in the screenshot returned by get_window_state. Origin is the target window's top-left, not the desktop."),...M}),Ne=p.object({app:m.app,window_title_contains:m.window_title_contains,window_id:m.window_id,state_token:m.state_token,element_index:H.optional().describe("Optional text element index or stable nodeId from get_window_state."),text:p.string().describe("Literal text to type."),...M}),qe=p.object({app:m.app,window_title_contains:m.window_title_contains,window_id:m.window_id,state_token:m.state_token,key:p.string().min(1).optional().describe("Key or key-combination, e.g. command+a, Return, Escape, PageDown."),keys:p.string().min(1).optional().describe("Alias for `key`. Models sometimes emit `keys` instead; either name works."),...M}),Ee=p.object({app:m.app,window_title_contains:m.window_title_contains,window_id:m.window_id,state_token:m.state_token,element_index:H.describe("Settable element index or stable nodeId from get_window_state."),value:p.string().describe("Value to set."),...M}),Me=p.object({app:m.app,window_title_contains:m.window_title_contains,window_id:m.window_id,state_token:m.state_token,element_index:H.describe("Text element index or stable nodeId from get_window_state."),text:p.string().min(1).describe("Exact text to select or place the cursor around."),prefix:p.string().optional().describe("Nearby text that appears before the target when repeated matches need disambiguation."),suffix:p.string().optional().describe("Nearby text that appears after the target when repeated matches need disambiguation."),selection:p.enum(["text","cursor_before","cursor_after"]).optional().describe("Selection mode. Defaults to text."),...M}),je=p.object({action:p.literal("click"),coordinate:qt,button:Et,count:Mt}),Oe=p.object({action:p.literal("mouse_move"),coordinate:jt}),Le=p.object({action:p.literal("left_click_drag"),start_coordinate:Ot,coordinate:Lt}),Fe=p.object({action:p.literal("left_mouse_down")}),Be=p.object({action:p.literal("left_mouse_up")}),Ue=p.object({action:p.literal("type"),text:Ft}),He=p.object({action:p.literal("key"),text:Bt}),ze=p.object({action:p.literal("scroll"),scroll_direction:Ut,coordinate:Ht,scroll_amount:zt}),Je=p.object({action:p.literal("set_clipboard"),text:Jt}),Ve=p.discriminatedUnion("action",[je,Oe,Le,Fe,Be,Ue,He,ze,Je]),Ye=p.object({actions:p.array(Ve).min(1).describe("Ordered actions. Do not include waits; call the separate `wait` tool only after observing a screenshot that is not ready yet.")}),at=class h{_computer;_caps;_locked=null;_safetyTimer;static SAFETY_TIMEOUT_MS=180*1e3;server;logger;accessStore=new it;appNameResolver=new V;lastUnsharedWindowsNote=null;accessRequestQueue=Promise.resolve();selectedDisplay="";options;constructor(t={}){this.options={...t,window_state:t.window_state},process.env.DEBUG&&(this.logger=new nt)}toText(t,e){let i=[{type:"text",text:t}];return e?{content:i,isError:!0}:{content:i}}toJson(t){return this.toText(JSON.stringify(t,null,2))}toImage(t,e,i){return t?{content:[{type:"image",data:t.toString("base64"),mimeType:this.imageMimeType(i),_meta:{screenshot:!0}}]}:this.toText(e,!0)}buildAccessMessage(t,e){let i=t.length===0?["","Computer Use runs on your actual desktop and can send mouse and keyboard input.","","Computer Use wants to control your desktop for this session.","","Apps that are not allowed may be hidden."]:["","Computer Use runs on your actual desktop and can send mouse and keyboard input to the apps you share.","","Computer Use wants to control these apps:","",...t.map(s=>`- ${s}`),"","Apps that are not allowed may be hidden."];return e&&i.push("","Reason:",e),i.join(`
45
44
  `)}imageMimeType(t){return t!==void 0?"image/jpeg":"image/png"}collectDisplayIds(t,e){let i=new Set;for(let s of t)!s.isMinimized&&s.displayId&&(!e||s.applicationId===e)&&i.add(s.displayId);return[...i]}buildAllowedAppsInfo(t,e){return t.map(i=>({appId:i.id,name:i.displayName,displayIds:this.collectDisplayIds(e,i.id)}))}create(){let t=["This MCP server provides desktop automation tools (mouse, keyboard, screenshots, clipboard)."];this.options.window_state?(t.push("This MCP server is running in app-scoped window-state mode."),this.options.yolo?t.push("YOLO mode is enabled. Window-state tools auto-allow their target app before each operation."):t.push("Window-state tools request access for their target app inline before operating; use `list_applications` only for discovery or ambiguity."),t.push("For a named target app, pass the app name directly to `get_window_state` or a window-state action; it can find the app, select its display, and start the access session without capturing a screenshot.","If macOS Accessibility or Screen Recording permission is missing, the target window-state tool will request it. Even when asked to look at the screen, do not switch to AppleScript, `osascript`, System Events, `screencapture`, or shell GUI automation because a discovery call could not yet confirm window-state access.","If a window-state tool is allowed with `allowAll=true`, all current and future apps are allowed for the rest of this session.","For speed and background correctness, use `get_window_state` for perception; request visual pixels with `get_window_state image_mode=image` or `image_mode=path` only when needed.","Prefer keyboard shortcuts, `type_text`, and `press_key` over visual menu navigation when reliable.","If you launch a new app during the session, pass it to a window-state tool; use `list_applications` first if you need to discover the app or its display.","Window-state tools will ask again when a new, unshared target app is used.","Call `get_window_state` once per turn before `click`, `scroll`, `drag`, `type_text`, `press_key`, `set_value`, or `invoke_action`. Pass the returned `state_token`, and prefer nodeId/element_index targets from `get_window_state` over screenshot coordinates.","`get_window_state` returns compact semantic text and is much faster than a desktop screenshot. Default `image_mode=omit` skips screenshot capture; pass `image` only when visual coordinates are needed. Its output labels action coordinates as window-local screenshot x/y with origin at the target window top-left; screen/global frames should not be passed directly to click/drag. Pass `diff_since` with a prior state_token for compact changes when useful, and use `format=json` or `format=both` only for sanitized debug metadata.","For background windows, close documents by pressing the close button element from `get_window_state`, then handle any sheet/dialog buttons from a refreshed app-level `get_window_state`. Do not use `press_key` for shortcuts like Cmd+W unless the app is foreground, and do not use `invoke_action` with an action that is not listed on that exact element.","If a window-state action returns `classification=user_intervened`, the user interacted with that target app after your last perception snapshot. Call `get_window_state` for that same app to clear the per-app yield block, then retry if the refreshed state still matches your intent.","Window-state actions show an animated non-interactive overlay cursor when supported so the user can see what the window-scoped action is doing, even when the action does not use a physical mouse click.","Raw coordinate/HID input tools (`left_click_drag`, `mouse_move`, `left_mouse_down`, `left_mouse_up`, `batch`) and the cross-platform `key`/`type` tools are intentionally NOT available in window-state mode. The window-scoped tools (`click`, `drag`, `scroll`, `type_text`, `press_key`, `set_value`, `invoke_action`) target windows directly, support stable element ids, and don't move the user's real cursor. For perception use `get_window_state`; pass `image_mode=image` or `image_mode=path` when visual pixels are needed."),process.platform==="darwin"&&t.push("For macOS GUI tasks, do not use AppleScript, `osascript`, System Events, `screencapture`, or shell-based GUI automation unless the user explicitly asks for that exact approach. Use the computer-use window-state tools instead so actions stay in the background service and preserve app sharing.")):(this.options.yolo?t.push("YOLO mode is enabled. Call `request_access` once to auto-allow all current and future apps for this session."):t.push("Before using access-gated tools (screenshot, click, type, clipboard, etc.), you MUST call `request_access` to start an access session."),t.push("For a named target app, call `request_access` directly; it can find the app, select its display, and return the first screenshot. Use `list_applications` only for discovery or ambiguity.","Calling `request_access` with an empty apps array allows all visible apps on the selected display. If none are visible, it falls back to desktop access and empty desktop screenshots until apps are allowed.","Screenshots and zoom captures are composited to show ONLY the windows of allowed applications (plus system UI like the Dock). Disallowed app windows are not visible.","For speed, use returned screenshots instead of post-action `screenshot`, and batch predictable actions. Returned screenshots already include a small settle delay; do not add waits just for screenshot timing.","Prefer keyboard shortcuts, `type`, and `key` over visual menu navigation when reliable.","If `request_access` returns `allowAll=true`, all current and future apps are allowed for the rest of this session and you do not need to call `request_access` again.","Otherwise, if you launch a new app during the session, call `request_access` again to add it. Use `list_applications` first if you need to discover the app or its display."));let e={name:"computer-use",version:"1.0.0"};this.server=new be(e,{instructions:t.join(`
46
- `)});let i=p.object({method:p.literal("notifications/copilot"),params:p.object({type:p.string()}).passthrough()});return this.server.server.setNotificationHandler(i,s=>{switch(s.params.type){case"assistant.turn_start":this._locked===null&&(this._locked=!1),this.unlock();break;case"assistant.turn_end":this.unlock();break;case"user.abort":case"assistant.abort":this.unlock();break}}),this.server.registerTool("get_clipboard",{description:"Get the current text contents of the system clipboard."+x,annotations:D},()=>this.get_clipboard()),this.server.registerTool("set_clipboard",{description:"Set the system clipboard to the specified text."+x,inputSchema:{text:zt},annotations:mt},s=>this.set_clipboard(s)),this.server.registerTool("wait",{description:"Pause, then return an updated screenshot if access is active. Use after a screenshot shows the UI is not ready yet.",inputSchema:{duration:Se.optional(),seconds:p.number().nonnegative().max(100).optional().describe("Alias for `duration`. Either name works.")},annotations:{...D,idempotentHint:!0}},s=>this.wait({duration:s.duration??s.seconds??0})),this.options.window_state?this.registerWindowStateTools():this.registerCoordinateTools(),this.server}registerCoordinateTools(){this.server.registerTool("list_applications",{description:"List currently controllable app windows and `selectedDisplay`. Use for discovery only; `request_access` can resolve named apps directly.",inputSchema:Dt.shape,annotations:D},e=>this.list_applications(e)),this.server.registerTool("request_access",{description:"Request app access by friendly name or appId; pass [] for all visible apps. For a named app, call this directly; it finds the app and selects its display. Returns JSON (`allowed`, `allowAll`, `message`, `allowedApps?`, `selectedDisplay?`) and, when allowed, a screenshot. `allowAll=true` covers future apps for this session.",inputSchema:{apps:p.array(ke).describe('Applications to allow. Each entry can be a friendly name (e.g. "Outlook") or a stable appId, if already known. Pass an empty array to allow all apps on the selected display.'),reason:p.string().min(1).optional().describe("Optional reason text shown in the access dialog.")},annotations:mt},e=>this.request_access(e)),this.server.registerTool("list_displays",{description:"List available displays and the currently selected display used for screenshots, zoom, cursor position, and coordinate-based actions.",annotations:D},()=>this.list_displays()),this.server.registerTool("select_display",{description:"Select the active display used for screenshots, zoom, cursor position, and coordinate-based actions. Omit display_id or pass an empty string to use the default display.",inputSchema:xe.shape,annotations:mt},e=>this.select_display(e)),this.server.registerTool("screenshot",{description:"Capture the current filtered screen. "+Rt+x,annotations:D},()=>this.screenshot()),this.server.registerTool("zoom",{description:"Capture a filtered screen region at full resolution."+Rt+x,inputSchema:{region:Ae.describe("{x1, y1, x2, y2} coordinates defining top-left and bottom-right corners of the region to capture.")},annotations:D},e=>this.zoom(e)),this.server.registerTool("cursor_position",{description:"Get the current cursor position in pixel coordinates. Returns {x, y}."+x,annotations:D},()=>this.cursor_position());let t={coordinate:Nt,button:qt,count:Et};this.server.registerTool("click",{description:"Click a mouse button. Defaults to a single left click; use `button` for right/middle click and `count` 2 or 3 for double/triple-click. Optionally move to a coordinate first."+x,inputSchema:t,annotations:_},e=>this.click(e)),this.server.registerTool("mouse_move",{description:"Move the mouse cursor to the specified pixel coordinate."+x,inputSchema:{coordinate:Mt},annotations:_},e=>this.mouse_move(e)),this.server.registerTool("left_click_drag",{description:"Click and drag from a start coordinate to an end coordinate."+x,inputSchema:{start_coordinate:jt,coordinate:Ot},annotations:_},e=>this.left_click_drag(e)),this.server.registerTool("left_mouse_down",{description:"Press and hold the left mouse button at the current cursor position."+x,annotations:_},()=>this.left_mouse_down()),this.server.registerTool("left_mouse_up",{description:"Release the left mouse button at the current cursor position."+x,annotations:_},()=>this.left_mouse_up()),this.server.registerTool("type",{description:"Type a string for text input fields. Use `key` for physical-key controls."+x,inputSchema:{text:Lt},annotations:_},e=>this.type(e)),this.server.registerTool("key",{description:"Press a key or combo, e.g. 'Return', 'ctrl+s', 'alt+Tab', '1'."+x,inputSchema:{text:Ft},annotations:_},e=>this.key(e)),this.server.registerTool("scroll",{description:"Scroll the screen in a given direction at an optional coordinate."+x,inputSchema:{scroll_direction:Bt,coordinate:Ut,scroll_amount:Ht},annotations:_},e=>this.scroll(e)),this.server.registerTool("batch",{description:"Run ordered actions and return one final screenshot after a built-in settle delay. Use for predictable sequences; wait is intentionally not supported. Supported actions: click, mouse_move, left_click_drag, left_mouse_down, left_mouse_up, type, key, scroll, set_clipboard.",inputSchema:Ye.shape,annotations:_},e=>this.batch(e))}registerWindowStateTools(){let t=" Call `get_window_state` once per turn before using window-state actions. Pass `state_token`, and prefer a nodeId/element_index target over screenshot coordinates; if coordinates are needed, use local_center/window-local hints, not screen/global frames. If the user interacted with that app, actions return classification=user_intervened until you re-read get_window_state for the same app. Actions show an animated overlay cursor when supported.";this.server.registerTool("list_applications",{description:"List visible app windows and `selectedDisplay` for discovery. In window-state mode, if macOS Accessibility is not granted yet this may use raw window discovery; use the named target window-state tool to request permissions and operate the app. Use for discovery only; window-state tools can resolve named apps directly.",inputSchema:Dt.shape,annotations:D},e=>this.list_applications(e)),this.server.registerTool("get_window_state",{description:"Get compact semantic state for a target app window. Defaults to text; use format=json/both only for sanitized debug metadata. Screenshots are returned according to `image_mode`: MCP image content, local file path, or omitted; base64 is never embedded in text. Output coordinate contract: click/drag x,y are window-local screenshot coordinates with origin at the target window top-left; screen/global frames should not be used directly as action coordinates. Pass `diff_since` with a prior state_token for compact semantic changes when useful.",inputSchema:Ce.shape,annotations:D},e=>this.get_window_state(e)),this.server.registerTool("click",{description:"Click an element by numeric index or stable nodeId in `element_index`, or a window-local screenshot coordinate/local_center from `get_window_state` as fallback."+t,inputSchema:We.shape,annotations:_},e=>this.window_click(e)),this.server.registerTool("invoke_action",{description:"Invoke an accessibility action exposed by an element in `get_window_state`; the `action` string must come from that element's listed actions such as {press} or {confirm}, not an inferred command like `close` unless it is explicitly listed."+t,inputSchema:Te.shape,annotations:_},e=>this.invoke_action(e)),this.server.registerTool("scroll",{description:"Scroll an element from `get_window_state` in an app window."+t,inputSchema:Re.shape,annotations:_},e=>this.scroll_window(e)),this.server.registerTool("drag",{description:"Drag between window-local screenshot coordinates from `get_window_state` (origin is the target window's top-left; do not use screen/global frame coordinates directly).",inputSchema:De.shape,annotations:_},e=>this.drag_window(e)),this.server.registerTool("type_text",{description:"Type literal text into an app window, optionally targeting an element from `get_window_state`."+t,inputSchema:Ne.shape,annotations:_},e=>this.type_text(e)),this.server.registerTool("press_key",{description:"Press a key or key-combination against an app window. Background apps cannot receive global shortcuts without activation; for background document close use the close button element from `get_window_state` instead of Cmd+W."+t,inputSchema:qe.shape,annotations:_},e=>this.press_key(e)),this.server.registerTool("set_value",{description:"Set the value of a settable accessibility element from `get_window_state`."+t,inputSchema:Ee.shape,annotations:_},e=>this.set_value(e)),process.platform==="darwin"&&this.server.registerTool("select_text",{description:"Select exact text in a text element from `get_window_state`, or place the cursor before/after that text using AX selectedTextRange."+t,inputSchema:Me.shape,annotations:_},e=>this.select_text(e))}lock(){this._locked===null||!this._computer||(this._locked||(this._locked=this._computer.lock(()=>{this.unlock(),this.server.server.notification({method:"notifications/copilot",params:{type:"user.abort"}}).catch(()=>{});let t=this.accessStore.getState().hostWindowId;t&&this._computer&&this._computer.activateWindow(t).catch(()=>{})})),this._safetyTimer&&clearTimeout(this._safetyTimer),this._safetyTimer=setTimeout(()=>this.unlock(),u.SAFETY_TIMEOUT_MS))}unlock(){this._computer&&this._computer.hideActionCursor(),!(this._locked===null||!this._computer)&&(this._safetyTimer&&(clearTimeout(this._safetyTimer),this._safetyTimer=void 0),this._locked&&this._computer.unlock(),this._locked=!1)}async computer(){if(!this._computer){if(process.platform==="darwin"){let{MacComputer:t}=await Promise.resolve().then(()=>(Ct(),$t));this._computer=t.create(this.logger)}else{let{NativeComputer:t}=await Promise.resolve().then(()=>(Tt(),Wt));this._computer=t.create(this.logger)}this.logger&&(this._computer=new nt(this._computer,this.logger))}return this._computer}logEvent(t,e){this.logger?.log("info","Server",t,e)}async capabilities(){if(!this._caps){let t=await this.computer();this._caps=await t.capabilities()}return this._caps}async requestPermission(t,e){if(!this.server.server.getClientCapabilities()?.elicitation?.form)throw new Error(e);this._computer&&await this.showHostWindow(this._computer);let i=await this.server.server.elicitInput(t),s={};if(typeof i.content=="object"&&i.content!==null&&!Array.isArray(i.content))for(let[n,o]of Object.entries(i.content))(typeof o=="string"||typeof o=="number"||typeof o=="boolean"||Array.isArray(o)&&o.every(r=>typeof r=="string"))&&(s[n]=o);return{action:i.action,content:Object.keys(s).length>0?s:void 0}}async activeDisplayId(t){return this.selectedDisplay!==""?this.selectedDisplay:(await t.listDisplays()).find(i=>i.isPrimary)?.displayId??""}async listAccessWindows(t){return await t.listWindows()}applicationInfoToListing(t){return{id:t.applicationId,displayName:t.applicationName,applicationNames:t.applicationNames,windows:[]}}resolveApplicationsFromWindows(t,e){let i=E(t),s=new J;s.updateApplications(i);let n=new Set(s.resolve(e).map(o=>o.appId));return i.filter(o=>n.has(o.id))}async requireAccess(){let t=this.accessStore.getState();if(!t.accessActive)throw new Error("No access session is active. Call request_access first to start a session.");let e=await this.computer();if(t.allowAll&&(await this.capabilities()).discovery){let s=this.options.window_state?await this.listAccessWindows(e):void 0,{windows:n}=await this.filterHostWindow(e,s),o=E(n);this.accessStore.rememberApplications(o),this.appNameResolver.updateApplications(o),t=this.accessStore.getState()}return{computer:e,allowedAppIds:t.allowAll?null:t.allowedAppIds,allowAll:t.allowAll,hostWindowId:t.hostWindowId}}async hostWindowId(t){let e=this.accessStore.getState().hostWindowId;if(e)return e;if(!(await this.capabilities()).discovery)return null;let s=await t.getActiveWindow();return s&&(await this.listAccessWindows(t)).some(o=>o.windowId===s.windowId)?s.windowId:null}async showHostWindow(t){try{let e=await this.hostWindowId(t);if(!e)return;await t.activateWindow(e)}catch{}}async filterHostWindow(t,e){let i=e??await t.listWindows(),s=await this.hostWindowId(t);return{windows:s?i.filter(n=>n.windowId!==s):i,hostWindowId:s}}async prepareForInput(t,e,i){if(!(await this.capabilities()).discovery)return;let n=await this.activeDisplayId(t),o=i!==void 0;if((e===null||e.length===0)&&!o)return;if(!await t.prepareForInput(n,e,o?i:void 0)){if(o)throw new Error("Input blocked: a disallowed app at the target could not be hidden. Call `list_applications` to see what's there, then `request_access` to allow it.");let a=await t.getActiveWindow();throw a&&e!==null&&!e.includes(a.applicationId)?new Error(this.keyboardInputBlockedMessage(a)):new Error("Keyboard input blocked: an allowed application could not be focused. Click an allowed application first, or call `request_access` to allow it.")}}keyboardInputBlockedMessage(t){return`Keyboard input blocked: the focused application ("${t.applicationName}") is not allowed. Click an allowed application first, or call \`request_access\` to allow it.`}async validateActiveWindow(t,e){if(e===null||e.length===0||!(await this.capabilities()).discovery)return;let s=await t.getActiveWindow();if(s&&!e.includes(s.applicationId))throw new Error(this.keyboardInputBlockedMessage(s))}pointerInputBlockedMessage(t){return`Pointer input blocked: the focused application ("${t.applicationName}") is not allowed. Focus an allowed application first, or call \`request_access\` to allow it.`}async validatePointerInput(t,e,i){if(e===null||e.length===0||!(await this.capabilities()).discovery)return;let n=await t.getActiveWindow();if(n&&!e.includes(n.applicationId))throw new Error(this.pointerInputBlockedMessage(n));let o=await this.activeDisplayId(t),r=await t.windowAtPoint(o,i.x,i.y);if(!r||e.includes(r.applicationId))return;let a=r.applicationName||r.title||r.applicationId;throw new Error(`Pointer input blocked: the target location is covered by disallowed application ("${a}"). Call \`list_applications\` to see what's there, then \`request_access\` to allow it.`)}async list_displays(){let t=await this.computer(),e=await t.listDisplays(),i=await this.activeDisplayId(t);return this.toJson({displays:e,selectedDisplay:i})}async select_display({display_id:t}){let e=t??"",i=await this.computer(),s=await i.listDisplays();if(e!==""&&!s.some(r=>r.displayId===e))throw new Error(`Unknown display id '${e}'. Call list_displays first.`);this.selectedDisplay=e;let n=await this.activeDisplayId(i),o=s.find(r=>r.displayId===n)??null;return this.toJson({selectedDisplay:n,status:"selected",message:e===""?"Using the default display for screenshots, zoom, cursor position, and coordinate-based actions.":`Selected display '${o?.label??e}' for screenshots, zoom, cursor position, and coordinate-based actions.`})}async list_applications({display_id:t}={}){let e=await this.computer(),i=await this.listAccessWindows(e),{windows:s}=await this.filterHostWindow(e,i),n=E(s);this.accessStore.rememberApplications(n),this.appNameResolver.updateApplications(n);let o=t??"";if(o!==""&&!(await e.listDisplays()).some(d=>d.displayId===o))throw new Error(`Unknown display id '${o}'. Call list_displays first.`);let r=o===""?s:s.filter(l=>!l.isMinimized&&l.displayId===o),a=E(r),c=await this.activeDisplayId(e);return this.toJson({selectedDisplay:c,applications:a})}async request_access({apps:t,reason:e}){let i=await this.requestAccess({apps:t,reason:e}),s=this.toJson({allowed:i.allowed,allowAll:i.state.allowAll,...i.allowedApps?{allowedApps:i.allowedApps}:{},selectedDisplay:this.selectedDisplay||void 0,message:i.message});if(!i.allowed)return s;let n=await this.computer();this.lock();let o=i.state.hostWindowId?[i.state.hostWindowId]:[];return this.addScreenshot(n,i.state.allowAll?null:i.state.allowedAppIds,o,s)}async requestAccess({apps:t,reason:e}){let i=this.accessRequestQueue.catch(()=>{}),s=()=>{};this.accessRequestQueue=i.then(()=>new Promise(n=>{s=n})),await i;try{this.logEvent("request_access",`Start: apps=[${t.join(", ")}]${e?` reason="${e}"`:""}`),await(await this.computer()).requestPermission(this);let o={const:"allow",title:"Allow"},r={const:"allow_all",title:"Allow all apps (don't ask again)"},a={const:"deny",title:"Deny (Esc)"},c,l=(f,T,G)=>{this.logEvent("request_access",`End: allowed=${f} allowAll=${T.allowAll} selectedDisplay=${this.selectedDisplay||"(default)"} hostWindowId=${T.hostWindowId??"null"} message="${G}"`);let q=c??(T.allowAll?void 0:T.allowedAppIds.map(F=>{let L=this.accessStore.tryGetKnownApplication(F);return{appId:F,name:L?.displayName,displayIds:this.collectDisplayIds(L?.windows??[])}}));return{allowed:f,state:T,message:G,...q?{allowedApps:q}:{}}};if(this.options.yolo){let f=this.accessStore.allowApplications([],!0);return l(!0,f,"YOLO mode is enabled. Auto-allowing full desktop access for this session.")}let d=await this.capabilities();if(!this.server.server.getClientCapabilities()?.elicitation?.form){let f=this.accessStore.allowApplications([],!0);return l(!0,f,"Elicitation is not supported by this client. Auto-allowing full desktop access for this session.")}let h,A,C,N,j;if(d.discovery){let f=await this.computer(),T=this.accessStore.getState().hostWindowId,G=await this.listAccessWindows(f),{windows:q}=await this.filterHostWindow(f,G);j=q;let F=E(q);this.accessStore.rememberApplications(F),this.appNameResolver.updateApplications(F);let L=t&&t.length>0?"":await this.activeDisplayId(f);L&&(this.selectedDisplay=L);let Vt=new Set(T?[T]:[]),R;if(t&&t.length>0){let y=new Map;for(let v of t){let z=this.appNameResolver.resolve(v);if(z.length===0){let P=await f.resolveApplication(v);if(P){y.set(P.applicationId,this.applicationInfoToListing(P));continue}throw new Error(`No matching application found for '${v}'. The app may not be installed or discoverable.`)}for(let P of z)if(!y.has(P.appId)){let tt=this.accessStore.tryGetKnownApplication(P.appId);y.set(P.appId,tt??{id:P.appId,displayName:P.displayName,windows:[]})}}R=[...y.values()];let Yt=new Set(y.keys()),Z=new Map;for(let v of j??q)Yt.has(v.applicationId)&&!v.isMinimized&&v.displayId&&Z.set(v.displayId,(Z.get(v.displayId)??0)+1);if(Z.size>0){let v="",z=0;for(let[P,tt]of Z)tt>z&&(v=P,z=tt);this.selectedDisplay=v}let gt=new Map(F.map(v=>[v.id,v]));for(let v of R)gt.set(v.id,v);let ft=[...gt.values()];this.accessStore.rememberApplications(ft),this.appNameResolver.updateApplications(ft),c=this.buildAllowedAppsInfo(R,j??q)}else R=E(q.filter(y=>!y.isMinimized&&(L===""||y.displayId===L)&&!Vt.has(y.windowId)));let Q=R.map(y=>y.id),at=this.accessStore.getState(),H=R.length;A=["allow","allow_all"],C=Q.length===0?at.allowAll||at.accessActive:Q.every(y=>this.accessStore.areAllowedForAccess([y])),N=Q.length===0?at.allowAll?"Access is already configured to auto-allow future requests for this session, so you do not need to call request_access again.":"Desktop access is already active for this session.":H===1?`'${R[0].displayName}' is already shared for this session.`:"The requested apps are already shared for this session.",h={choices:[o,r,a],message:this.buildAccessMessage(R.map(y=>y.displayName),e),denyMessage:H===0?"The user declined desktop access.":H===1?`The user declined to share '${R[0].displayName}'.`:"The user declined to share the requested apps.",allow:y=>y==="allow_all"?this.accessStore.allowApplications([],!0):this.accessStore.allowApplications(Q),allowedMessage:y=>y==="allow_all"?"All current and future apps are allowed for the rest of this session, so you do not need to call request_access again.":H===0?"Desktop access is active for this session.":H===1?`Access session started for '${R[0].displayName}'.`:"Access session started for the requested apps."}}else{let f=this.accessStore.getState();A=["allow_all"],C=f.allowAll||f.accessActive,N=f.allowAll?"Access is already configured to auto-allow future requests for this session, so you do not need to call request_access again.":"Desktop access is already active for this session.",h={choices:[r,a],message:this.buildAccessMessage([],e),denyMessage:"The user declined desktop access.",allow:()=>this.accessStore.allowApplications([],!0),allowedMessage:()=>"Access session started for the desktop. All current and future apps are allowed for the rest of this session, so you do not need to call request_access again."}}if(C){let f=this.accessStore.getState();return l(!0,f,N)}this.accessStore.getState().hostWindowId&&await this.showHostWindow(await this.computer());let O=await this.server.server.request({method:"elicitation/create",params:{mode:"form",message:h.message,requestedSchema:{type:"object",properties:{decision:{type:"string",title:"Allow access for this session?",oneOf:h.choices}},required:["decision"]}}},ve,{timeout:300*1e3}),g=await this.computer(),I=await this.hostWindowId(g);I&&this.accessStore.setHostWindowId(I);let W=O.action==="accept"?O.content?.decision:void 0;if(O.action!=="accept"||!W||typeof W!="string"||!A.includes(W)){let f=this.accessStore.getState(),T=typeof W=="string"&&W!==a.const?`The user did not approve this access request. User response: ${W}`:h.denyMessage;return l(!1,f,T)}let wt=h.allow(W);return wt.allowAll&&j&&(c=this.buildAllowedAppsInfo(this.accessStore.allKnownApplications(),j)),l(!0,wt,h.allowedMessage(W))}finally{s()}}async requireWindowStateAccess(t,e,i){let s=this.accessStore.getState();if(!s.accessActive){let h=await this.requestAccess({apps:[t],reason:`Use ${t} with computer-use window-state tools.`});if(!h.allowed)throw new Error(h.message||`Access to "${t}" was not approved.`);s=this.accessStore.getState()}let n=await this.computer(),o=s.allowAll;if(s.accessActive&&({computer:n,allowAll:o}=await this.requireAccess()),o)return n;let r=await this.listAccessWindows(n),a=E(r);this.accessStore.rememberApplications([...a,...this.accessStore.allKnownApplications().filter(h=>!a.some(A=>A.id===h.id))]),this.appNameResolver.updateApplications(this.accessStore.allKnownApplications());let c=this.appNameResolver.resolve(t).map(h=>h.appId);if(c.length===0){let h=await n.resolveApplication(t);if(h){let A=this.applicationInfoToListing(h);this.accessStore.rememberApplications([...this.accessStore.allKnownApplications().filter(C=>C.id!==A.id),A]),this.appNameResolver.updateApplications(this.accessStore.allKnownApplications()),c=[h.applicationId]}}let l=new Set(c),d=(e?r.filter(h=>h.windowId===e):r.filter(h=>l.has(h.applicationId))).filter(h=>!i||h.title.toLowerCase().includes(i.toLowerCase()));if(c.length===0)throw new Error(`No matching application found for '${t}'. The app may not be installed or discoverable.`);if(e&&d.length===0)throw new Error(`Window-state target not found for "${t}". Call list_applications, then pass the intended app/window_id.`);if(e&&!d.some(h=>l.has(h.applicationId))){let h=d[0];throw new Error(`Window-state target blocked: window_id "${e}" belongs to "${h.applicationName}", not "${t}".`)}let w=d.length>0?[...new Set(d.map(h=>h.applicationId))]:[...new Set(c)];if(w.length!==1){let h=d.length>0?d.map(A=>`${A.applicationName} (${A.applicationId})`).join(", "):w.join(", ");throw new Error(`Window-state target is ambiguous for "${t}". Candidate apps: ${h}.`)}if(!this.accessStore.areAllowedForAccess([w[0]])){let h=await this.requestAccess({apps:[t],reason:`Use ${t} with computer-use window-state tools.`});if(!h.allowed)throw new Error(h.message||`Access to "${t}" was not approved.`);if(s=this.accessStore.getState(),n=await this.computer(),o=s.allowAll,s.accessActive&&({computer:n,allowAll:o}=await this.requireAccess()),o)return n;if(!this.accessStore.areAllowedForAccess([w[0]]))throw new Error(`Window-state input blocked: "${d[0]?.applicationName??t}" is not shared.`)}return n}async windowActionToolResult(t,e){let i=await t,s={...i};if(delete s.postState,typeof i.diagnostics=="object"&&i.diagnostics!==null&&!Array.isArray(i.diagnostics)){let a={...i.diagnostics};delete a.postState,s.diagnostics=a}else delete s.diagnostics;let n=this.toJson(s);i.ok||(n.isError=!0);let o=e.return_state??"text";if(!i.ok||o==="none")return n;let r=o==="image"||o==="path"?o:"omit";if(i.postState){let a=new V(i.postState).toToolResult({imageMode:r,format:"text",screenshotOutFile:e.screenshot_out_file});return{content:[...n.content,...a.content],isError:n.isError}}if(i.postStateUnavailableReason)return n;throw new Error("Action completed, but requested post-action window state was not returned.")}async get_window_state(t){let e=await this.requireWindowStateAccess(t.app,t.window_id,t.window_title_contains),i=t.image_mode??(t.include_screenshot===!0?"image":"omit");if(t.include_screenshot===!1&&i!=="omit")throw new Error("get_window_state include_screenshot=false conflicts with image_mode. Use image_mode=omit.");if(t.include_screenshot===!0&&t.image_mode==="omit")throw new Error("get_window_state include_screenshot=true conflicts with image_mode=omit.");let s=i!=="omit",n=await e.getWindowState(t.app,t.window_title_contains,t.window_id,s,t.include_tree,t.max_nodes,t.diff_since??t.diff_from_state_token);return new V(n).toToolResult({imageMode:i,format:t.format??"text",screenshotOutFile:t.screenshot_out_file})}async window_click(t){let e=await this.requireWindowStateAccess(t.app,t.window_id,t.window_title_contains);if(!t.element_index&&(t.x===void 0||t.y===void 0))throw new Error("click requires either element_index or both x and y from get_window_state.");if(t.element_index&&(t.x!==void 0||t.y!==void 0))throw new Error("click accepts either element_index or coordinates, not both.");let i=t.return_state??"text";return this.windowActionToolResult(e.windowClick(t.app,t.element_index,t.x,t.y,t.click_count,t.mouse_button,t.window_title_contains,t.window_id,t.state_token,i,t.max_nodes),{...t,return_state:i})}async invoke_action(t){let e=await this.requireWindowStateAccess(t.app,t.window_id,t.window_title_contains),i=t.return_state??"text";return this.windowActionToolResult(e.invokeAction(t.app,t.element_index,t.action,t.window_title_contains,t.window_id,t.state_token,i,t.max_nodes),{...t,return_state:i})}async scroll_window(t){let e=await this.requireWindowStateAccess(t.app,t.window_id,t.window_title_contains),i=t.return_state??"text";return this.windowActionToolResult(e.windowScroll(t.app,t.element_index,t.direction,t.pages,t.window_title_contains,t.window_id,t.state_token,i,t.max_nodes),{...t,return_state:i})}async drag_window(t){let e=await this.requireWindowStateAccess(t.app,t.window_id,t.window_title_contains),i=t.return_state??"text";return this.windowActionToolResult(e.windowDrag(t.app,t.from_x,t.from_y,t.to_x,t.to_y,t.window_title_contains,t.window_id,t.state_token,i,t.max_nodes),{...t,return_state:i})}async type_text(t){let e=await this.requireWindowStateAccess(t.app,t.window_id,t.window_title_contains),i=t.return_state??"text";return this.windowActionToolResult(e.typeText(t.app,t.text,t.element_index,t.window_title_contains,t.window_id,t.state_token,i,t.max_nodes),{...t,return_state:i})}async press_key(t){let e=await this.requireWindowStateAccess(t.app,t.window_id,t.window_title_contains),i=t.key??t.keys;if(!i)throw new Error("press_key requires `key` (or its alias `keys`).");let s=t.return_state??"text";return this.windowActionToolResult(e.pressKey(t.app,i,t.window_title_contains,t.window_id,t.state_token,s,t.max_nodes),{...t,return_state:s})}async set_value(t){let e=await this.requireWindowStateAccess(t.app,t.window_id,t.window_title_contains),i=t.return_state??"text";return this.windowActionToolResult(e.setValue(t.app,t.element_index,t.value,t.window_title_contains,t.window_id,t.state_token,i,t.max_nodes),{...t,return_state:i})}async select_text(t){let e=await this.requireWindowStateAccess(t.app,t.window_id,t.window_title_contains),i=t.return_state??"text",s=t.selection??"text";return this.windowActionToolResult(e.selectText(t.app,t.element_index,t.text,t.prefix,t.suffix,s,t.window_title_contains,t.window_id,t.state_token,i,t.max_nodes),{...t,return_state:i})}async screenshot(){let{computer:t,allowedAppIds:e,hostWindowId:i}=await this.requireAccess();this.lock();let s=i?[i]:[];return this.addScreenshot(t,e,s)}async addScreenshot(t,e,i,s){let n=s===void 0;n||await new Promise(g=>setTimeout(g,_e));let o=g=>{let I=this.accessStore.tryGetKnownApplication(g);return I?`${I.displayName} (${g})`:g},r=(g,I)=>I.length===1?`${g}: ${I[0]}`:`${g}:
45
+ `)});let i=p.object({method:p.literal("notifications/copilot"),params:p.object({type:p.string()}).passthrough()});return this.server.server.setNotificationHandler(i,s=>{switch(s.params.type){case"assistant.turn_start":this._locked===null&&(this._locked=!1),this.unlock();break;case"assistant.turn_end":this.unlock();break;case"user.abort":case"assistant.abort":this.unlock();break}}),this.server.registerTool("get_clipboard",{description:"Get the current text contents of the system clipboard."+x,annotations:D},()=>this.get_clipboard()),this.server.registerTool("set_clipboard",{description:"Set the system clipboard to the specified text."+x,inputSchema:{text:Jt},annotations:mt},s=>this.set_clipboard(s)),this.server.registerTool("wait",{description:"Pause, then return an updated screenshot if access is active. Use after a screenshot shows the UI is not ready yet.",inputSchema:{duration:Se.optional(),seconds:p.number().nonnegative().max(100).optional().describe("Alias for `duration`. Either name works.")},annotations:{...D,idempotentHint:!0}},s=>this.wait({duration:s.duration??s.seconds??0})),this.options.window_state?this.registerWindowStateTools():this.registerCoordinateTools(),this.server}registerCoordinateTools(){this.server.registerTool("list_applications",{description:"List currently controllable app windows and `selectedDisplay`. Use for discovery only; `request_access` can resolve named apps directly.",inputSchema:Nt.shape,annotations:D},e=>this.list_applications(e)),this.server.registerTool("request_access",{description:"Request app access by friendly name or appId; pass [] for all visible apps. For a named app, call this directly; it finds the app and selects its display. Returns JSON (`allowed`, `allowAll`, `message`, `allowedApps?`, `selectedDisplay?`) and, when allowed, a screenshot. `allowAll=true` covers future apps for this session.",inputSchema:{apps:p.array(ke).describe('Applications to allow. Each entry can be a friendly name (e.g. "Outlook") or a stable appId, if already known. Pass an empty array to allow all apps on the selected display.'),reason:p.string().min(1).optional().describe("Optional reason text shown in the access dialog.")},annotations:mt},e=>this.request_access(e)),this.server.registerTool("list_displays",{description:"List available displays and the currently selected display used for screenshots, zoom, cursor position, and coordinate-based actions.",annotations:D},()=>this.list_displays()),this.server.registerTool("select_display",{description:"Select the active display used for screenshots, zoom, cursor position, and coordinate-based actions. Omit display_id or pass an empty string to use the default display.",inputSchema:xe.shape,annotations:mt},e=>this.select_display(e)),this.server.registerTool("screenshot",{description:"Capture the current filtered screen. "+Dt+x,annotations:D},()=>this.screenshot()),this.server.registerTool("zoom",{description:"Capture a filtered screen region at full resolution."+Dt+x,inputSchema:{region:Ae.describe("{x1, y1, x2, y2} coordinates defining top-left and bottom-right corners of the region to capture.")},annotations:D},e=>this.zoom(e)),this.server.registerTool("cursor_position",{description:"Get the current cursor position in pixel coordinates. Returns {x, y}."+x,annotations:D},()=>this.cursor_position());let t={coordinate:qt,button:Et,count:Mt};this.server.registerTool("click",{description:"Click a mouse button. Defaults to a single left click; use `button` for right/middle click and `count` 2 or 3 for double/triple-click. Optionally move to a coordinate first."+x,inputSchema:t,annotations:_},e=>this.click(e)),this.server.registerTool("mouse_move",{description:"Move the mouse cursor to the specified pixel coordinate."+x,inputSchema:{coordinate:jt},annotations:_},e=>this.mouse_move(e)),this.server.registerTool("left_click_drag",{description:"Click and drag from a start coordinate to an end coordinate."+x,inputSchema:{start_coordinate:Ot,coordinate:Lt},annotations:_},e=>this.left_click_drag(e)),this.server.registerTool("left_mouse_down",{description:"Press and hold the left mouse button at the current cursor position."+x,annotations:_},()=>this.left_mouse_down()),this.server.registerTool("left_mouse_up",{description:"Release the left mouse button at the current cursor position."+x,annotations:_},()=>this.left_mouse_up()),this.server.registerTool("type",{description:"Type a string for text input fields. Use `key` for physical-key controls."+x,inputSchema:{text:Ft},annotations:_},e=>this.type(e)),this.server.registerTool("key",{description:"Press a key or combo, e.g. 'Return', 'ctrl+s', 'alt+Tab', '1'."+x,inputSchema:{text:Bt},annotations:_},e=>this.key(e)),this.server.registerTool("scroll",{description:"Scroll the screen in a given direction at an optional coordinate."+x,inputSchema:{scroll_direction:Ut,coordinate:Ht,scroll_amount:zt},annotations:_},e=>this.scroll(e)),this.server.registerTool("batch",{description:"Run ordered actions and return one final screenshot after a built-in settle delay. Use for predictable sequences; wait is intentionally not supported. Supported actions: click, mouse_move, left_click_drag, left_mouse_down, left_mouse_up, type, key, scroll, set_clipboard.",inputSchema:Ye.shape,annotations:_},e=>this.batch(e))}registerWindowStateTools(){let t=" Call `get_window_state` once per turn before using window-state actions. Pass `state_token`, and prefer a nodeId/element_index target over screenshot coordinates; if coordinates are needed, use local_center/window-local hints, not screen/global frames. If the user interacted with that app, actions return classification=user_intervened until you re-read get_window_state for the same app. Actions show an animated overlay cursor when supported.";this.server.registerTool("list_applications",{description:"List visible app windows and `selectedDisplay` for discovery. In window-state mode, if macOS Accessibility is not granted yet this may use raw window discovery; use the named target window-state tool to request permissions and operate the app. Use for discovery only; window-state tools can resolve named apps directly.",inputSchema:Nt.shape,annotations:D},e=>this.list_applications(e)),this.server.registerTool("get_window_state",{description:"Get compact semantic state for a target app window. Defaults to text; use format=json/both only for sanitized debug metadata. Screenshots are returned according to `image_mode`: MCP image content, local file path, or omitted; base64 is never embedded in text. Output coordinate contract: click/drag x,y are window-local screenshot coordinates with origin at the target window top-left; screen/global frames should not be used directly as action coordinates. Pass `diff_since` with a prior state_token for compact semantic changes when useful.",inputSchema:Ce.shape,annotations:D},e=>this.get_window_state(e)),this.server.registerTool("click",{description:"Click an element by numeric index or stable nodeId in `element_index`, or a window-local screenshot coordinate/local_center from `get_window_state` as fallback."+t,inputSchema:We.shape,annotations:_},e=>this.window_click(e)),this.server.registerTool("invoke_action",{description:"Invoke an accessibility action exposed by an element in `get_window_state`; the `action` string must come from that element's listed actions such as {press} or {confirm}, not an inferred command like `close` unless it is explicitly listed."+t,inputSchema:Re.shape,annotations:_},e=>this.invoke_action(e)),this.server.registerTool("scroll",{description:"Scroll an element from `get_window_state` in an app window."+t,inputSchema:Te.shape,annotations:_},e=>this.scroll_window(e)),this.server.registerTool("drag",{description:"Drag between window-local screenshot coordinates from `get_window_state` (origin is the target window's top-left; do not use screen/global frame coordinates directly).",inputSchema:De.shape,annotations:_},e=>this.drag_window(e)),this.server.registerTool("type_text",{description:"Type literal text into an app window, optionally targeting an element from `get_window_state`."+t,inputSchema:Ne.shape,annotations:_},e=>this.type_text(e)),this.server.registerTool("press_key",{description:"Press a key or key-combination against an app window. Background apps cannot receive global shortcuts without activation; for background document close use the close button element from `get_window_state` instead of Cmd+W."+t,inputSchema:qe.shape,annotations:_},e=>this.press_key(e)),this.server.registerTool("set_value",{description:"Update a writable element value identified from `get_window_state`."+t,inputSchema:Ee.shape,annotations:_},e=>this.set_value(e)),process.platform==="darwin"&&this.server.registerTool("select_text",{description:"Select exact text in a text element from `get_window_state`, or place the cursor before/after that text using AX selectedTextRange."+t,inputSchema:Me.shape,annotations:_},e=>this.select_text(e))}lock(){this._locked===null||!this._computer||(this._locked||(this._locked=this._computer.lock(()=>{this.unlock(),this.server.server.notification({method:"notifications/copilot",params:{type:"user.abort"}}).catch(()=>{});let t=this.accessStore.getState().hostWindowId;t&&this._computer&&this._computer.activateWindow(t).catch(()=>{})})),this._safetyTimer&&clearTimeout(this._safetyTimer),this._safetyTimer=setTimeout(()=>this.unlock(),h.SAFETY_TIMEOUT_MS))}unlock(){this._computer&&this._computer.hideActionCursor(),!(this._locked===null||!this._computer)&&(this._safetyTimer&&(clearTimeout(this._safetyTimer),this._safetyTimer=void 0),this._locked&&this._computer.unlock(),this._locked=!1)}async computer(){if(!this._computer){if(process.platform==="darwin"){let{MacComputer:t}=await Promise.resolve().then(()=>(Wt(),Ct));this._computer=t.create(this.logger)}else{let{NativeComputer:t}=await Promise.resolve().then(()=>(Tt(),Rt));this._computer=t.create(this.logger)}this.logger&&(this._computer=new ot(this._computer,this.logger))}return this._computer}logEvent(t,e){this.logger?.log("info","Server",t,e)}async capabilities(){if(!this._caps){let t=await this.computer();this._caps=await t.capabilities()}return this._caps}async requestPermission(t,e){if(!this.server.server.getClientCapabilities()?.elicitation?.form)throw new Error(e);this._computer&&await this.showHostWindow(this._computer);let i=await this.server.server.elicitInput(t),s={};if(typeof i.content=="object"&&i.content!==null&&!Array.isArray(i.content))for(let[n,o]of Object.entries(i.content))(typeof o=="string"||typeof o=="number"||typeof o=="boolean"||Array.isArray(o)&&o.every(r=>typeof r=="string"))&&(s[n]=o);return{action:i.action,content:Object.keys(s).length>0?s:void 0}}async activeDisplayId(t){return this.selectedDisplay!==""?this.selectedDisplay:(await t.listDisplays()).find(i=>i.isPrimary)?.displayId??""}async listAccessWindows(t){return await t.listWindows()}applicationInfoToListing(t){return{id:t.applicationId,displayName:t.applicationName,applicationNames:t.applicationNames,windows:[]}}resolveApplicationsFromWindows(t,e){let i=E(t),s=new V;s.updateApplications(i);let n=new Set(s.resolve(e).map(o=>o.appId));return i.filter(o=>n.has(o.id))}async requireAccess(){let t=this.accessStore.getState();if(!t.accessActive)throw new Error("No access session is active. Call request_access first to start a session.");let e=await this.computer();if(t.allowAll&&(await this.capabilities()).discovery){let s=this.options.window_state?await this.listAccessWindows(e):void 0,{windows:n}=await this.filterHostWindow(e,s),o=E(n);this.accessStore.rememberApplications(o),this.appNameResolver.updateApplications(o),t=this.accessStore.getState()}return{computer:e,allowedAppIds:t.allowAll?null:t.allowedAppIds,allowAll:t.allowAll,hostWindowId:t.hostWindowId}}async hostWindowId(t){let e=this.accessStore.getState().hostWindowId;if(e)return e;if(!(await this.capabilities()).discovery)return null;let s=await t.getActiveWindow();return s&&(await this.listAccessWindows(t)).some(o=>o.windowId===s.windowId)?s.windowId:null}async showHostWindow(t){try{let e=await this.hostWindowId(t);if(!e)return;await t.activateWindow(e)}catch{}}async filterHostWindow(t,e){let i=e??await t.listWindows(),s=await this.hostWindowId(t);return{windows:s?i.filter(n=>n.windowId!==s):i,hostWindowId:s}}async prepareForInput(t,e,i){if(!(await this.capabilities()).discovery)return;let n=await this.activeDisplayId(t),o=i!==void 0;if((e===null||e.length===0)&&!o)return;if(!await t.prepareForInput(n,e,o?i:void 0)){if(o)throw new Error("Input blocked: a disallowed app at the target could not be hidden. Call `list_applications` to see what's there, then `request_access` to allow it.");let a=await t.getActiveWindow();throw a&&e!==null&&!e.includes(a.applicationId)?new Error(this.keyboardInputBlockedMessage(a)):new Error("Keyboard input blocked: an allowed application could not be focused. Click an allowed application first, or call `request_access` to allow it.")}}keyboardInputBlockedMessage(t){return`Keyboard input blocked: the focused application ("${t.applicationName}") is not allowed. Click an allowed application first, or call \`request_access\` to allow it.`}async validateActiveWindow(t,e){if(e===null||e.length===0||!(await this.capabilities()).discovery)return;let s=await t.getActiveWindow();if(s&&!e.includes(s.applicationId))throw new Error(this.keyboardInputBlockedMessage(s))}pointerInputBlockedMessage(t){return`Pointer input blocked: the focused application ("${t.applicationName}") is not allowed. Focus an allowed application first, or call \`request_access\` to allow it.`}async validatePointerInput(t,e,i){if(e===null||e.length===0||!(await this.capabilities()).discovery)return;let n=await t.getActiveWindow();if(n&&!e.includes(n.applicationId))throw new Error(this.pointerInputBlockedMessage(n));let o=await this.activeDisplayId(t),r=await t.windowAtPoint(o,i.x,i.y);if(!r||e.includes(r.applicationId))return;let a=r.applicationName||r.title||r.applicationId;throw new Error(`Pointer input blocked: the target location is covered by disallowed application ("${a}"). Call \`list_applications\` to see what's there, then \`request_access\` to allow it.`)}async list_displays(){let t=await this.computer(),e=await t.listDisplays(),i=await this.activeDisplayId(t);return this.toJson({displays:e,selectedDisplay:i})}async select_display({display_id:t}){let e=t??"",i=await this.computer(),s=await i.listDisplays();if(e!==""&&!s.some(r=>r.displayId===e))throw new Error(`Unknown display id '${e}'. Call list_displays first.`);this.selectedDisplay=e;let n=await this.activeDisplayId(i),o=s.find(r=>r.displayId===n)??null;return this.toJson({selectedDisplay:n,status:"selected",message:e===""?"Using the default display for screenshots, zoom, cursor position, and coordinate-based actions.":`Selected display '${o?.label??e}' for screenshots, zoom, cursor position, and coordinate-based actions.`})}async list_applications({display_id:t}={}){let e=await this.computer(),i=await this.listAccessWindows(e),{windows:s}=await this.filterHostWindow(e,i),n=E(s);this.accessStore.rememberApplications(n),this.appNameResolver.updateApplications(n);let o=t??"";if(o!==""&&!(await e.listDisplays()).some(d=>d.displayId===o))throw new Error(`Unknown display id '${o}'. Call list_displays first.`);let r=o===""?s:s.filter(l=>!l.isMinimized&&l.displayId===o),a=E(r),c=await this.activeDisplayId(e);return this.toJson({selectedDisplay:c,applications:a})}async request_access({apps:t,reason:e}){let i=await this.requestAccess({apps:t,reason:e}),s=this.toJson({allowed:i.allowed,allowAll:i.state.allowAll,...i.allowedApps?{allowedApps:i.allowedApps}:{},selectedDisplay:this.selectedDisplay||void 0,message:i.message});if(!i.allowed)return s;let n=await this.computer();this.lock();let o=i.state.hostWindowId?[i.state.hostWindowId]:[];return this.addScreenshot(n,i.state.allowAll?null:i.state.allowedAppIds,o,s)}async requestAccess({apps:t,reason:e}){let i=this.accessRequestQueue.catch(()=>{}),s=()=>{};this.accessRequestQueue=i.then(()=>new Promise(n=>{s=n})),await i;try{this.logEvent("request_access",`Start: apps=[${t.join(", ")}]${e?` reason="${e}"`:""}`),await(await this.computer()).requestPermission(this);let o={const:"allow",title:"Allow"},r={const:"allow_all",title:"Allow all apps (don't ask again)"},a={const:"deny",title:"Deny (Esc)"},c,l=(f,R,Q)=>{this.logEvent("request_access",`End: allowed=${f} allowAll=${R.allowAll} selectedDisplay=${this.selectedDisplay||"(default)"} hostWindowId=${R.hostWindowId??"null"} message="${Q}"`);let q=c??(R.allowAll?void 0:R.allowedAppIds.map(F=>{let L=this.accessStore.tryGetKnownApplication(F);return{appId:F,name:L?.displayName,displayIds:this.collectDisplayIds(L?.windows??[])}}));return{allowed:f,state:R,message:Q,...q?{allowedApps:q}:{}}};if(this.options.yolo){let f=this.accessStore.allowApplications([],!0);return l(!0,f,"YOLO mode is enabled. Auto-allowing full desktop access for this session.")}let d=await this.capabilities();if(!this.server.server.getClientCapabilities()?.elicitation?.form){let f=this.accessStore.allowApplications([],!0);return l(!0,f,"Elicitation is not supported by this client. Auto-allowing full desktop access for this session.")}let u,A,C,N,j;if(d.discovery){let f=await this.computer(),R=this.accessStore.getState().hostWindowId,Q=await this.listAccessWindows(f),{windows:q}=await this.filterHostWindow(f,Q);j=q;let F=E(q);this.accessStore.rememberApplications(F),this.appNameResolver.updateApplications(F);let L=t&&t.length>0?"":await this.activeDisplayId(f);L&&(this.selectedDisplay=L);let Vt=new Set(R?[R]:[]),T;if(t&&t.length>0){let y=new Map;for(let v of t){let J=this.appNameResolver.resolve(v);if(J.length===0){let P=await f.resolveApplication(v);if(P){y.set(P.applicationId,this.applicationInfoToListing(P));continue}throw new Error(`No matching application found for '${v}'. The app may not be installed or discoverable.`)}for(let P of J)if(!y.has(P.appId)){let et=this.accessStore.tryGetKnownApplication(P.appId);y.set(P.appId,et??{id:P.appId,displayName:P.displayName,windows:[]})}}T=[...y.values()];let Yt=new Set(y.keys()),tt=new Map;for(let v of j??q)Yt.has(v.applicationId)&&!v.isMinimized&&v.displayId&&tt.set(v.displayId,(tt.get(v.displayId)??0)+1);if(tt.size>0){let v="",J=0;for(let[P,et]of tt)et>J&&(v=P,J=et);this.selectedDisplay=v}let gt=new Map(F.map(v=>[v.id,v]));for(let v of T)gt.set(v.id,v);let ft=[...gt.values()];this.accessStore.rememberApplications(ft),this.appNameResolver.updateApplications(ft),c=this.buildAllowedAppsInfo(T,j??q)}else T=E(q.filter(y=>!y.isMinimized&&(L===""||y.displayId===L)&&!Vt.has(y.windowId)));let Z=T.map(y=>y.id),ct=this.accessStore.getState(),z=T.length;A=["allow","allow_all"],C=Z.length===0?ct.allowAll||ct.accessActive:Z.every(y=>this.accessStore.areAllowedForAccess([y])),N=Z.length===0?ct.allowAll?"Access is already configured to auto-allow future requests for this session, so you do not need to call request_access again.":"Desktop access is already active for this session.":z===1?`'${T[0].displayName}' is already shared for this session.`:"The requested apps are already shared for this session.",u={choices:[o,r,a],message:this.buildAccessMessage(T.map(y=>y.displayName),e),denyMessage:z===0?"The user declined desktop access.":z===1?`The user declined to share '${T[0].displayName}'.`:"The user declined to share the requested apps.",allow:y=>y==="allow_all"?this.accessStore.allowApplications([],!0):this.accessStore.allowApplications(Z),allowedMessage:y=>y==="allow_all"?"All current and future apps are allowed for the rest of this session, so you do not need to call request_access again.":z===0?"Desktop access is active for this session.":z===1?`Access session started for '${T[0].displayName}'.`:"Access session started for the requested apps."}}else{let f=this.accessStore.getState();A=["allow_all"],C=f.allowAll||f.accessActive,N=f.allowAll?"Access is already configured to auto-allow future requests for this session, so you do not need to call request_access again.":"Desktop access is already active for this session.",u={choices:[r,a],message:this.buildAccessMessage([],e),denyMessage:"The user declined desktop access.",allow:()=>this.accessStore.allowApplications([],!0),allowedMessage:()=>"Access session started for the desktop. All current and future apps are allowed for the rest of this session, so you do not need to call request_access again."}}if(C){let f=this.accessStore.getState();return l(!0,f,N)}this.accessStore.getState().hostWindowId&&await this.showHostWindow(await this.computer());let O=await this.server.server.request({method:"elicitation/create",params:{mode:"form",message:u.message,requestedSchema:{type:"object",properties:{decision:{type:"string",title:"Allow access for this session?",oneOf:u.choices}},required:["decision"]}}},ve,{timeout:300*1e3}),g=await this.computer(),I=await this.hostWindowId(g);I&&this.accessStore.setHostWindowId(I);let W=O.action==="accept"?O.content?.decision:void 0;if(O.action!=="accept"||!W||typeof W!="string"||!A.includes(W)){let f=this.accessStore.getState(),R=typeof W=="string"&&W!==a.const?`The user did not approve this access request. User response: ${W}`:u.denyMessage;return l(!1,f,R)}let wt=u.allow(W);return wt.allowAll&&j&&(c=this.buildAllowedAppsInfo(this.accessStore.allKnownApplications(),j)),l(!0,wt,u.allowedMessage(W))}finally{s()}}async requireWindowStateAccess(t,e,i){let s=this.accessStore.getState();if(!s.accessActive){let u=await this.requestAccess({apps:[t],reason:`Use ${t} with computer-use window-state tools.`});if(!u.allowed)throw new Error(u.message||`Access to "${t}" was not approved.`);s=this.accessStore.getState()}let n=await this.computer(),o=s.allowAll;if(s.accessActive&&({computer:n,allowAll:o}=await this.requireAccess()),o)return n;let r=await this.listAccessWindows(n),a=E(r);this.accessStore.rememberApplications([...a,...this.accessStore.allKnownApplications().filter(u=>!a.some(A=>A.id===u.id))]),this.appNameResolver.updateApplications(this.accessStore.allKnownApplications());let c=this.appNameResolver.resolve(t).map(u=>u.appId);if(c.length===0){let u=await n.resolveApplication(t);if(u){let A=this.applicationInfoToListing(u);this.accessStore.rememberApplications([...this.accessStore.allKnownApplications().filter(C=>C.id!==A.id),A]),this.appNameResolver.updateApplications(this.accessStore.allKnownApplications()),c=[u.applicationId]}}let l=new Set(c),d=(e?r.filter(u=>u.windowId===e):r.filter(u=>l.has(u.applicationId))).filter(u=>!i||u.title.toLowerCase().includes(i.toLowerCase()));if(c.length===0)throw new Error(`No matching application found for '${t}'. The app may not be installed or discoverable.`);if(e&&d.length===0)throw new Error(`Window-state target not found for "${t}". Call list_applications, then pass the intended app/window_id.`);if(e&&!d.some(u=>l.has(u.applicationId))){let u=d[0];throw new Error(`Window-state target blocked: window_id "${e}" belongs to "${u.applicationName}", not "${t}".`)}let w=d.length>0?[...new Set(d.map(u=>u.applicationId))]:[...new Set(c)];if(w.length!==1){let u=d.length>0?d.map(A=>`${A.applicationName} (${A.applicationId})`).join(", "):w.join(", ");throw new Error(`Window-state target is ambiguous for "${t}". Candidate apps: ${u}.`)}if(!this.accessStore.areAllowedForAccess([w[0]])){let u=await this.requestAccess({apps:[t],reason:`Use ${t} with computer-use window-state tools.`});if(!u.allowed)throw new Error(u.message||`Access to "${t}" was not approved.`);if(s=this.accessStore.getState(),n=await this.computer(),o=s.allowAll,s.accessActive&&({computer:n,allowAll:o}=await this.requireAccess()),o)return n;if(!this.accessStore.areAllowedForAccess([w[0]]))throw new Error(`Window-state input blocked: "${d[0]?.applicationName??t}" is not shared.`)}return n}async windowActionToolResult(t,e){let i=await t,s={...i};if(delete s.postState,typeof i.diagnostics=="object"&&i.diagnostics!==null&&!Array.isArray(i.diagnostics)){let a={...i.diagnostics};delete a.postState,s.diagnostics=a}else delete s.diagnostics;let n=this.toJson(s);i.ok||(n.isError=!0);let o=e.return_state??"text";if(!i.ok||o==="none")return n;let r=o==="image"||o==="path"?o:"omit";if(i.postState){let a=new Y(i.postState).toToolResult({imageMode:r,format:"text",screenshotOutFile:e.screenshot_out_file});return{content:[...n.content,...a.content],isError:n.isError}}if(i.postStateUnavailableReason)return n;throw new Error("Action completed, but requested post-action window state was not returned.")}async get_window_state(t){let e=await this.requireWindowStateAccess(t.app,t.window_id,t.window_title_contains),i=t.image_mode??(t.include_screenshot===!0?"image":"omit");if(t.include_screenshot===!1&&i!=="omit")throw new Error("get_window_state include_screenshot=false conflicts with image_mode. Use image_mode=omit.");if(t.include_screenshot===!0&&t.image_mode==="omit")throw new Error("get_window_state include_screenshot=true conflicts with image_mode=omit.");let s=i!=="omit",n=await e.getWindowState(t.app,t.window_title_contains,t.window_id,s,t.include_tree,t.max_nodes,t.diff_since??t.diff_from_state_token);return new Y(n).toToolResult({imageMode:i,format:t.format??"text",screenshotOutFile:t.screenshot_out_file})}async window_click(t){let e=await this.requireWindowStateAccess(t.app,t.window_id,t.window_title_contains);if(!t.element_index&&(t.x===void 0||t.y===void 0))throw new Error("click requires either element_index or both x and y from get_window_state.");if(t.element_index&&(t.x!==void 0||t.y!==void 0))throw new Error("click accepts either element_index or coordinates, not both.");let i=t.return_state??"text";return this.windowActionToolResult(e.windowClick(t.app,t.element_index,t.x,t.y,t.click_count,t.mouse_button,t.window_title_contains,t.window_id,t.state_token,i,t.max_nodes),{...t,return_state:i})}async invoke_action(t){let e=await this.requireWindowStateAccess(t.app,t.window_id,t.window_title_contains),i=t.return_state??"text";return this.windowActionToolResult(e.invokeAction(t.app,t.element_index,t.action,t.window_title_contains,t.window_id,t.state_token,i,t.max_nodes),{...t,return_state:i})}async scroll_window(t){let e=await this.requireWindowStateAccess(t.app,t.window_id,t.window_title_contains),i=t.return_state??"text";return this.windowActionToolResult(e.windowScroll(t.app,t.element_index,t.direction,t.pages,t.window_title_contains,t.window_id,t.state_token,i,t.max_nodes),{...t,return_state:i})}async drag_window(t){let e=await this.requireWindowStateAccess(t.app,t.window_id,t.window_title_contains),i=t.return_state??"text";return this.windowActionToolResult(e.windowDrag(t.app,t.from_x,t.from_y,t.to_x,t.to_y,t.window_title_contains,t.window_id,t.state_token,i,t.max_nodes),{...t,return_state:i})}async type_text(t){let e=await this.requireWindowStateAccess(t.app,t.window_id,t.window_title_contains),i=t.return_state??"text";return this.windowActionToolResult(e.typeText(t.app,t.text,t.element_index,t.window_title_contains,t.window_id,t.state_token,i,t.max_nodes),{...t,return_state:i})}async press_key(t){let e=await this.requireWindowStateAccess(t.app,t.window_id,t.window_title_contains),i=t.key??t.keys;if(!i)throw new Error("press_key requires `key` (or its alias `keys`).");let s=t.return_state??"text";return this.windowActionToolResult(e.pressKey(t.app,i,t.window_title_contains,t.window_id,t.state_token,s,t.max_nodes),{...t,return_state:s})}async set_value(t){let e=await this.requireWindowStateAccess(t.app,t.window_id,t.window_title_contains),i=t.return_state??"text";return this.windowActionToolResult(e.setValue(t.app,t.element_index,t.value,t.window_title_contains,t.window_id,t.state_token,i,t.max_nodes),{...t,return_state:i})}async select_text(t){let e=await this.requireWindowStateAccess(t.app,t.window_id,t.window_title_contains),i=t.return_state??"text",s=t.selection??"text";return this.windowActionToolResult(e.selectText(t.app,t.element_index,t.text,t.prefix,t.suffix,s,t.window_title_contains,t.window_id,t.state_token,i,t.max_nodes),{...t,return_state:i})}async screenshot(){let{computer:t,allowedAppIds:e,hostWindowId:i}=await this.requireAccess();this.lock();let s=i?[i]:[];return this.addScreenshot(t,e,s)}async addScreenshot(t,e,i,s){let n=s===void 0;n||await new Promise(g=>setTimeout(g,_e));let o=g=>{let I=this.accessStore.tryGetKnownApplication(g);return I?`${I.displayName} (${g})`:g},r=(g,I)=>I.length===1?`${g}: ${I[0]}`:`${g}:
47
46
  ${I.map(W=>`- ${W}`).join(`
48
47
  `)}`,a=[e===null?"allowed: (all apps)":e.length?r("allowed",e.map(o)):"allowed: (no app windows)"];i.length&&a.push(r("blocked",i.map(g=>{let I=g.includes("|")?g.split("|")[1]:g;return o(I)}))),this.logEvent("screenshot filter",a.join(`
49
- `));let c=null;if(n)c=await t.screenshot(this.selectedDisplay,e,i,0,0,void 0,X);else try{c=await t.screenshot(this.selectedDisplay,e,i,0,0,void 0,X)}catch{}let l=s??{content:[]};if(!c)return n?this.toText("Screenshot failed",!0):(l.content.push({type:"text",text:"Screenshot capture failed"}),l);if(l.content.push({type:"image",data:c.toString("base64"),mimeType:this.imageMimeType(X),_meta:{screenshot:!0}}),e===null)return this.lastUnsharedWindowsNote=null,l;if(!(await this.capabilities()).discovery)return l;let w=await this.activeDisplayId(t),h=new Set(e),A=new Set(i),{windows:C}=await this.filterHostWindow(t),N=C.filter(g=>!g.isMinimized&&(w===""||g.displayId===w)&&!h.has(g.applicationId)&&!A.has(g.windowId));if(N.length===0)return this.lastUnsharedWindowsNote=null,l;let j=N.length===1?"window":"windows",O=`${N.length} other ${j} on this display ${N.length===1?"is":"are"} from an unshared app. The screenshot may not show everything that's running. Use \`list_applications\` to see what else is there if you need to.`;return(n||O!==this.lastUnsharedWindowsNote)&&l.content.push({type:"text",text:O}),this.lastUnsharedWindowsNote=O,l}async cursor_position(){let e=await(await this.computer()).cursorPosition(this.selectedDisplay);return this.toText(`${e.x},${e.y}`)}async _click(t,e,i,s,n,o,r){let a;switch(o){case 1:a="";break;case 2:a="double ";break;case 3:a="triple ";break;default:throw new Error(`Invalid click count '${o}'. Expected 1, 2, or 3.`)}let c=r??await t.cursorPosition(s);await this.prepareForInput(t,e,{x:c.x,y:c.y,blockedWindowIds:i}),await this.validatePointerInput(t,e,c),r&&await t.move(c.x,c.y,s),await t.click(c.x,c.y,n,o,s);let l=r?` at (${r.x},${r.y})`:"",d=n==="left"?"":`${n} `;return`${a}${d}click${l}`}async click({coordinate:t,button:e,count:i}){let{computer:s,allowedAppIds:n,hostWindowId:o}=await this.requireAccess();this.lock();let r=o?[o]:[],a=await this._click(s,n,r,this.selectedDisplay,e??"left",i??1,t);return this.addScreenshot(s,n,r,this.toText(a))}async mouse_move({coordinate:t}){let{computer:e,allowedAppIds:i,hostWindowId:s}=await this.requireAccess();this.lock();let n=s?[s]:[];return await this.prepareForInput(e,i,{x:t.x,y:t.y,blockedWindowIds:n}),await this.validatePointerInput(e,i,t),await e.move(t.x,t.y,this.selectedDisplay),this.addScreenshot(e,i,n,this.toText(`Moved to (${t.x},${t.y})`))}async left_click_drag({start_coordinate:t,coordinate:e}){let{computer:i,allowedAppIds:s,hostWindowId:n}=await this.requireAccess();this.lock();let o=n?[n]:[];return await this.prepareForInput(i,s,{x:t.x,y:t.y,blockedWindowIds:o}),await this.prepareForInput(i,s,{x:e.x,y:e.y,blockedWindowIds:o}),await this.validatePointerInput(i,s,t),await this.validatePointerInput(i,s,e),await i.drag(t.x,t.y,e.x,e.y,this.selectedDisplay),this.addScreenshot(i,s,o,this.toText(`Dragged (${t.x},${t.y}) -> (${e.x},${e.y})`))}async left_mouse_down(){let{computer:t,allowedAppIds:e,hostWindowId:i}=await this.requireAccess();this.lock();let s=i?[i]:[],n=await t.cursorPosition(this.selectedDisplay);return await this.prepareForInput(t,e,{x:n.x,y:n.y,blockedWindowIds:s}),await this.validatePointerInput(t,e,n),await t.mouseDown(n.x,n.y,this.selectedDisplay),this.addScreenshot(t,e,s,this.toText(`Mouse down at (${n.x},${n.y})`))}async left_mouse_up(){let{computer:t,allowedAppIds:e,hostWindowId:i}=await this.requireAccess();this.lock();let s=i?[i]:[],n=await t.cursorPosition(this.selectedDisplay);return await this.prepareForInput(t,e,{x:n.x,y:n.y,blockedWindowIds:s}),await this.validatePointerInput(t,e,n),await t.mouseUp(n.x,n.y,this.selectedDisplay),this.addScreenshot(t,e,s,this.toText(`Mouse up at (${n.x},${n.y})`))}async type({text:t}){let{computer:e,allowedAppIds:i,hostWindowId:s}=await this.requireAccess();this.lock();let n=s?[s]:[];return await this.prepareForInput(e,i),await this.validateActiveWindow(e,i),await e.type(t),this.addScreenshot(e,i,n,this.toText(`Typed ${t.length} chars`))}async key({text:t}){let{computer:e,allowedAppIds:i,hostWindowId:s}=await this.requireAccess();this.lock();let n=s?[s]:[];await this.prepareForInput(e,i),await this.validateActiveWindow(e,i);let o=lt(t);return await e.key(o),this.addScreenshot(e,i,n,this.toText(`Pressed ${o}`))}async scroll({scroll_direction:t,coordinate:e,scroll_amount:i}){let{computer:s,allowedAppIds:n,hostWindowId:o}=await this.requireAccess();this.lock();let r=o?[o]:[],a=i??3,c=await s.cursorPosition(this.selectedDisplay),l=e?.x??c.x,d=e?.y??c.y;await this.prepareForInput(s,n,{x:l,y:d,blockedWindowIds:r}),await this.validatePointerInput(s,n,{x:l,y:d});let w=t==="left"?-a:t==="right"?a:0,h=t==="down"?a:t==="up"?-a:0;return await s.scroll(l,d,w,h,this.selectedDisplay),this.addScreenshot(s,n,r,this.toText(`Scrolled ${t} ${a} at (${l},${d})`))}async wait({duration:t}){this.logEvent("wait",`duration=${String(t)}s`),await new Promise(r=>setTimeout(r,t*1e3));let e=this.toText(`Waited ${t}s`);if(!this.accessStore.getState().accessActive||this.options.window_state)return e;let{computer:i,allowedAppIds:s,hostWindowId:n}=await this.requireAccess(),o=n?[n]:[];return this.addScreenshot(i,s,o,e)}async get_clipboard(){let{computer:t}=await this.requireAccess();this.lock();let e=await t.getClipboard();return this.toText(e)}async set_clipboard({text:t}){let{computer:e}=await this.requireAccess();if(this.lock(),await e.setClipboard(t),await e.getClipboard()!==t)throw new Error("Clipboard write did not verify after setting the requested text.");return this.toText(`Clipboard set (${t.length} chars)`)}async zoom({region:t}){let{computer:e,allowedAppIds:i,hostWindowId:s}=await this.requireAccess();this.lock();let n=s?[s]:[],o=await e.screenshot(this.selectedDisplay,i,n,0,0,[t.x1,t.y1,t.x2,t.y2],X);return this.toImage(o,"Zoom screenshot failed",X)}async batch({actions:t}){let{computer:e,allowedAppIds:i,hostWindowId:s}=await this.requireAccess();this.lock(),this.logEvent("batch",`${t.length} actions: ${t.map(a=>a.action).join(", ")}`);let n=this.selectedDisplay,o=s?[s]:[],r=[];for(let a=0;a<t.length;a++){let c=t[a];try{switch(c.action){case"click":{let l=await this._click(e,i,o,n,c.button??"left",c.count??1,c.coordinate);r.push(`[${a}] ${l}`);break}case"mouse_move":await this.prepareForInput(e,i,{x:c.coordinate.x,y:c.coordinate.y,blockedWindowIds:o}),await this.validatePointerInput(e,i,c.coordinate),await e.move(c.coordinate.x,c.coordinate.y,n),r.push(`[${a}] moved to (${c.coordinate.x},${c.coordinate.y})`);break;case"left_click_drag":await this.prepareForInput(e,i,{x:c.start_coordinate.x,y:c.start_coordinate.y,blockedWindowIds:o}),await this.prepareForInput(e,i,{x:c.coordinate.x,y:c.coordinate.y,blockedWindowIds:o}),await this.validatePointerInput(e,i,c.start_coordinate),await this.validatePointerInput(e,i,c.coordinate),await e.drag(c.start_coordinate.x,c.start_coordinate.y,c.coordinate.x,c.coordinate.y,n),r.push(`[${a}] dragged (${c.start_coordinate.x},${c.start_coordinate.y}) -> (${c.coordinate.x},${c.coordinate.y})`);break;case"left_mouse_down":{let l=await e.cursorPosition(n);await this.prepareForInput(e,i,{x:l.x,y:l.y,blockedWindowIds:o}),await this.validatePointerInput(e,i,l),await e.mouseDown(l.x,l.y,n),r.push(`[${a}] mouse down at (${l.x},${l.y})`);break}case"left_mouse_up":{let l=await e.cursorPosition(n);await this.prepareForInput(e,i,{x:l.x,y:l.y,blockedWindowIds:o}),await this.validatePointerInput(e,i,l),await e.mouseUp(l.x,l.y,n),r.push(`[${a}] mouse up at (${l.x},${l.y})`);break}case"type":await this.prepareForInput(e,i),await this.validateActiveWindow(e,i),await e.type(c.text),r.push(`[${a}] typed ${c.text.length} chars`);break;case"key":{await this.prepareForInput(e,i),await this.validateActiveWindow(e,i);let l=lt(c.text);await e.key(l),r.push(`[${a}] key ${c.text}`);break}case"scroll":{let l=c.scroll_amount??3,d=c.coordinate??await e.cursorPosition(n);await this.prepareForInput(e,i,{x:d.x,y:d.y,blockedWindowIds:o}),await this.validatePointerInput(e,i,d);let w=c.scroll_direction==="left"?-l:c.scroll_direction==="right"?l:0,h=c.scroll_direction==="down"?l:c.scroll_direction==="up"?-l:0;await e.scroll(d.x,d.y,w,h,n),r.push(`[${a}] scroll ${c.scroll_direction}${c.coordinate?` at (${d.x},${d.y})`:""}`);break}case"set_clipboard":if(await e.setClipboard(c.text),await e.getClipboard()!==c.text)throw new Error("Clipboard write did not verify after setting the requested text.");r.push(`[${a}] clipboard set`);break}}catch(l){return r.push(`[${a}] ${c.action}: FAILED - ${l instanceof Error?l.message:String(l)}`),this.toText(r.join(`
48
+ `));let c=null;if(n)c=await t.screenshot(this.selectedDisplay,e,i,0,0,void 0,K);else try{c=await t.screenshot(this.selectedDisplay,e,i,0,0,void 0,K)}catch{}let l=s??{content:[]};if(!c)return n?this.toText("Screenshot failed",!0):(l.content.push({type:"text",text:"Screenshot capture failed"}),l);if(l.content.push({type:"image",data:c.toString("base64"),mimeType:this.imageMimeType(K),_meta:{screenshot:!0}}),e===null)return this.lastUnsharedWindowsNote=null,l;if(!(await this.capabilities()).discovery)return l;let w=await this.activeDisplayId(t),u=new Set(e),A=new Set(i),{windows:C}=await this.filterHostWindow(t),N=C.filter(g=>!g.isMinimized&&(w===""||g.displayId===w)&&!u.has(g.applicationId)&&!A.has(g.windowId));if(N.length===0)return this.lastUnsharedWindowsNote=null,l;let j=N.length===1?"window":"windows",O=`${N.length} other ${j} on this display ${N.length===1?"is":"are"} from an unshared app. The screenshot may not show everything that's running. Use \`list_applications\` to see what else is there if you need to.`;return(n||O!==this.lastUnsharedWindowsNote)&&l.content.push({type:"text",text:O}),this.lastUnsharedWindowsNote=O,l}async cursor_position(){let e=await(await this.computer()).cursorPosition(this.selectedDisplay);return this.toText(`${e.x},${e.y}`)}async _click(t,e,i,s,n,o,r){let a;switch(o){case 1:a="";break;case 2:a="double ";break;case 3:a="triple ";break;default:throw new Error(`Invalid click count '${o}'. Expected 1, 2, or 3.`)}let c=r??await t.cursorPosition(s);await this.prepareForInput(t,e,{x:c.x,y:c.y,blockedWindowIds:i}),await this.validatePointerInput(t,e,c),r&&await t.move(c.x,c.y,s),await t.click(c.x,c.y,n,o,s);let l=r?` at (${r.x},${r.y})`:"",d=n==="left"?"":`${n} `;return`${a}${d}click${l}`}async click({coordinate:t,button:e,count:i}){let{computer:s,allowedAppIds:n,hostWindowId:o}=await this.requireAccess();this.lock();let r=o?[o]:[],a=await this._click(s,n,r,this.selectedDisplay,e??"left",i??1,t);return this.addScreenshot(s,n,r,this.toText(a))}async mouse_move({coordinate:t}){let{computer:e,allowedAppIds:i,hostWindowId:s}=await this.requireAccess();this.lock();let n=s?[s]:[];return await this.prepareForInput(e,i,{x:t.x,y:t.y,blockedWindowIds:n}),await this.validatePointerInput(e,i,t),await e.move(t.x,t.y,this.selectedDisplay),this.addScreenshot(e,i,n,this.toText(`Moved to (${t.x},${t.y})`))}async left_click_drag({start_coordinate:t,coordinate:e}){let{computer:i,allowedAppIds:s,hostWindowId:n}=await this.requireAccess();this.lock();let o=n?[n]:[];return await this.prepareForInput(i,s,{x:t.x,y:t.y,blockedWindowIds:o}),await this.prepareForInput(i,s,{x:e.x,y:e.y,blockedWindowIds:o}),await this.validatePointerInput(i,s,t),await this.validatePointerInput(i,s,e),await i.drag(t.x,t.y,e.x,e.y,this.selectedDisplay),this.addScreenshot(i,s,o,this.toText(`Dragged (${t.x},${t.y}) -> (${e.x},${e.y})`))}async left_mouse_down(){let{computer:t,allowedAppIds:e,hostWindowId:i}=await this.requireAccess();this.lock();let s=i?[i]:[],n=await t.cursorPosition(this.selectedDisplay);return await this.prepareForInput(t,e,{x:n.x,y:n.y,blockedWindowIds:s}),await this.validatePointerInput(t,e,n),await t.mouseDown(n.x,n.y,this.selectedDisplay),this.addScreenshot(t,e,s,this.toText(`Mouse down at (${n.x},${n.y})`))}async left_mouse_up(){let{computer:t,allowedAppIds:e,hostWindowId:i}=await this.requireAccess();this.lock();let s=i?[i]:[],n=await t.cursorPosition(this.selectedDisplay);return await this.prepareForInput(t,e,{x:n.x,y:n.y,blockedWindowIds:s}),await this.validatePointerInput(t,e,n),await t.mouseUp(n.x,n.y,this.selectedDisplay),this.addScreenshot(t,e,s,this.toText(`Mouse up at (${n.x},${n.y})`))}async type({text:t}){let{computer:e,allowedAppIds:i,hostWindowId:s}=await this.requireAccess();this.lock();let n=s?[s]:[];return await this.prepareForInput(e,i),await this.validateActiveWindow(e,i),await e.type(t),this.addScreenshot(e,i,n,this.toText(`Typed ${t.length} chars`))}async key({text:t}){let{computer:e,allowedAppIds:i,hostWindowId:s}=await this.requireAccess();this.lock();let n=s?[s]:[];await this.prepareForInput(e,i),await this.validateActiveWindow(e,i);let o=dt(t);return await e.key(o),this.addScreenshot(e,i,n,this.toText(`Pressed ${o}`))}async scroll({scroll_direction:t,coordinate:e,scroll_amount:i}){let{computer:s,allowedAppIds:n,hostWindowId:o}=await this.requireAccess();this.lock();let r=o?[o]:[],a=i??3,c=await s.cursorPosition(this.selectedDisplay),l=e?.x??c.x,d=e?.y??c.y;await this.prepareForInput(s,n,{x:l,y:d,blockedWindowIds:r}),await this.validatePointerInput(s,n,{x:l,y:d});let w=t==="left"?-a:t==="right"?a:0,u=t==="down"?a:t==="up"?-a:0;return await s.scroll(l,d,w,u,this.selectedDisplay),this.addScreenshot(s,n,r,this.toText(`Scrolled ${t} ${a} at (${l},${d})`))}async wait({duration:t}){this.logEvent("wait",`duration=${String(t)}s`),await new Promise(r=>setTimeout(r,t*1e3));let e=this.toText(`Waited ${t}s`);if(!this.accessStore.getState().accessActive||this.options.window_state)return e;let{computer:i,allowedAppIds:s,hostWindowId:n}=await this.requireAccess(),o=n?[n]:[];return this.addScreenshot(i,s,o,e)}async get_clipboard(){let{computer:t}=await this.requireAccess();this.lock();let e=await t.getClipboard();return this.toText(e)}async set_clipboard({text:t}){let{computer:e}=await this.requireAccess();if(this.lock(),await e.setClipboard(t),await e.getClipboard()!==t)throw new Error("Clipboard write did not verify after setting the requested text.");return this.toText(`Clipboard set (${t.length} chars)`)}async zoom({region:t}){let{computer:e,allowedAppIds:i,hostWindowId:s}=await this.requireAccess();this.lock();let n=s?[s]:[],o=await e.screenshot(this.selectedDisplay,i,n,0,0,[t.x1,t.y1,t.x2,t.y2],K);return this.toImage(o,"Zoom screenshot failed",K)}async batch({actions:t}){let{computer:e,allowedAppIds:i,hostWindowId:s}=await this.requireAccess();this.lock(),this.logEvent("batch",`${t.length} actions: ${t.map(a=>a.action).join(", ")}`);let n=this.selectedDisplay,o=s?[s]:[],r=[];for(let a=0;a<t.length;a++){let c=t[a];try{switch(c.action){case"click":{let l=await this._click(e,i,o,n,c.button??"left",c.count??1,c.coordinate);r.push(`[${a}] ${l}`);break}case"mouse_move":await this.prepareForInput(e,i,{x:c.coordinate.x,y:c.coordinate.y,blockedWindowIds:o}),await this.validatePointerInput(e,i,c.coordinate),await e.move(c.coordinate.x,c.coordinate.y,n),r.push(`[${a}] moved to (${c.coordinate.x},${c.coordinate.y})`);break;case"left_click_drag":await this.prepareForInput(e,i,{x:c.start_coordinate.x,y:c.start_coordinate.y,blockedWindowIds:o}),await this.prepareForInput(e,i,{x:c.coordinate.x,y:c.coordinate.y,blockedWindowIds:o}),await this.validatePointerInput(e,i,c.start_coordinate),await this.validatePointerInput(e,i,c.coordinate),await e.drag(c.start_coordinate.x,c.start_coordinate.y,c.coordinate.x,c.coordinate.y,n),r.push(`[${a}] dragged (${c.start_coordinate.x},${c.start_coordinate.y}) -> (${c.coordinate.x},${c.coordinate.y})`);break;case"left_mouse_down":{let l=await e.cursorPosition(n);await this.prepareForInput(e,i,{x:l.x,y:l.y,blockedWindowIds:o}),await this.validatePointerInput(e,i,l),await e.mouseDown(l.x,l.y,n),r.push(`[${a}] mouse down at (${l.x},${l.y})`);break}case"left_mouse_up":{let l=await e.cursorPosition(n);await this.prepareForInput(e,i,{x:l.x,y:l.y,blockedWindowIds:o}),await this.validatePointerInput(e,i,l),await e.mouseUp(l.x,l.y,n),r.push(`[${a}] mouse up at (${l.x},${l.y})`);break}case"type":await this.prepareForInput(e,i),await this.validateActiveWindow(e,i),await e.type(c.text),r.push(`[${a}] typed ${c.text.length} chars`);break;case"key":{await this.prepareForInput(e,i),await this.validateActiveWindow(e,i);let l=dt(c.text);await e.key(l),r.push(`[${a}] key ${c.text}`);break}case"scroll":{let l=c.scroll_amount??3,d=c.coordinate??await e.cursorPosition(n);await this.prepareForInput(e,i,{x:d.x,y:d.y,blockedWindowIds:o}),await this.validatePointerInput(e,i,d);let w=c.scroll_direction==="left"?-l:c.scroll_direction==="right"?l:0,u=c.scroll_direction==="down"?l:c.scroll_direction==="up"?-l:0;await e.scroll(d.x,d.y,w,u,n),r.push(`[${a}] scroll ${c.scroll_direction}${c.coordinate?` at (${d.x},${d.y})`:""}`);break}case"set_clipboard":if(await e.setClipboard(c.text),await e.getClipboard()!==c.text)throw new Error("Clipboard write did not verify after setting the requested text.");r.push(`[${a}] clipboard set`);break}}catch(l){return r.push(`[${a}] ${c.action}: FAILED - ${l instanceof Error?l.message:String(l)}`),this.toText(r.join(`
50
49
  `),!0)}}return this.addScreenshot(e,i,o,this.toText(r.join(`
51
- `)))}};function Jt(u={}){return process.platform==="darwin"&&!process.env.COPILOT_COMPUTER_USE_DISABLE_WINDOW_STATE&&u.window_state!==!1&&(u.window_state=!0),process.env.COPILOT_COMPUTER_USE_YOLO&&(u.yolo=!0),new rt(u).create()}async function Ke(){let u=!1;for(let s of process.argv.slice(2))s==="--yolo"?u=!0:(console.log(["Usage: computer-use-mcp [--yolo]","","Options:"," --yolo Auto-allow full desktop access when request_access is called."," -h, --help Show this help message."].join(`
52
- `)),process.exit(s==="-h"||s==="--help"?0:1));let t=Jt({yolo:u});async function e(){await t.close(),process.exit(0)}process.on("SIGINT",()=>{e()}),process.on("SIGTERM",()=>{e()});let i=new Xe;await t.connect(i)}Ke().catch(u=>{console.error(u),process.exit(1)});
50
+ `)))}};function Ti(h={}){return process.platform==="darwin"&&!process.env.COPILOT_COMPUTER_USE_DISABLE_WINDOW_STATE&&h.window_state!==!1&&(h.window_state=!0),process.env.COPILOT_COMPUTER_USE_YOLO&&(h.yolo=!0),new at(h).create()}export{Ti as createServer};