omo-ai 5.1.6 → 5.1.7

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.
@@ -28,7 +28,8 @@ function readyLines(report) {
28
28
  : `${stopLevel} computer use stop path: ${capabilities.stopPath}${stopReason}`
29
29
  return [
30
30
  baseLine(report),
31
- `PASS computer use engine: ${report.enginePath} (version ${report.hello.engineVersion}, ABI ${report.hello.abi}, protocol ${report.hello.protocolVersion})`,
31
+ `PASS computer use engine: ready (${report.engineSource}) ${report.enginePath} (version ${report.hello.engineVersion}, ABI ${report.hello.abi}, protocol ${report.hello.protocolVersion})`,
32
+ ...(report.launchedEnginePath ? [`INFO computer use launched executable: ${report.launchedEnginePath}`] : []),
32
33
  `${backendLevel} computer use backend: ${capabilities.backend}${displayServer}`,
33
34
  `${permissionLevel} computer use permissions: capture=${capabilities.capturePermission} input=${capabilities.inputPermission} accessibility=${capabilities.axPermission}`,
34
35
  `${displayLevel} computer use display: count=${capabilities.displayCount} screenLocked=${capabilities.screenLocked}`,
@@ -64,6 +65,8 @@ export function formatComputerUseDoctorLines(report) {
64
65
  baseLine(report),
65
66
  `FAIL computer use engine: ${report.code}: ${report.message}`,
66
67
  `INFO computer use engine path: ${report.enginePath}`,
68
+ `INFO computer use engine source: ${report.engineSource}`,
69
+ ...(report.launchedEnginePath ? [`INFO computer use launched executable: ${report.launchedEnginePath}`] : []),
67
70
  ]
68
71
  default:
69
72
  throw new TypeError(`unknown computer use doctor report kind: ${String(report.kind)}`)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omo-ai",
3
- "version": "5.1.6",
3
+ "version": "5.1.7",
4
4
  "type": "module",
5
5
  "description": "OmO Native - the standalone omo command with the OMO extension built in: bun add -g omo-ai",
6
6
  "bin": {
@@ -7,6 +7,40 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [5.1.7] - 2026-09-30
11
+
12
+ **Computer use on macOS says what it needs and where its engine comes from.** A downloaded install trusts the engine shipped inside its own app, a missing Screen Recording or Accessibility grant opens the right System Settings pane, and `/computer status` and `omo doctor` show which engine you have before it starts. This release runs on the senpi 2026.9.30 engine, like 5.1.6.
13
+
14
+ ### Added
15
+
16
+ `/computer status` and `omo doctor` report where the computer-use engine is and where it came from (the app bundle, the cache or a path you set) without starting it, name hosts it does not support, and give the same answer. `omo doctor` never downloads the engine. ([#9286](https://github.com/code-yeongyu/oh-my-openagent/issues/9286), [#9311](https://github.com/code-yeongyu/oh-my-openagent/pull/9311))
17
+
18
+ ### Changed
19
+
20
+ Test cleanups from an internal audit, with no change to behavior. ([#9302](https://github.com/code-yeongyu/oh-my-openagent/pull/9302), [#9304](https://github.com/code-yeongyu/oh-my-openagent/pull/9304), [#9310](https://github.com/code-yeongyu/oh-my-openagent/pull/9310), [#9312](https://github.com/code-yeongyu/oh-my-openagent/pull/9312), [#9314](https://github.com/code-yeongyu/oh-my-openagent/pull/9314), [#9315](https://github.com/code-yeongyu/oh-my-openagent/pull/9315), [#9316](https://github.com/code-yeongyu/oh-my-openagent/pull/9316), [#9317](https://github.com/code-yeongyu/oh-my-openagent/pull/9317), [#9318](https://github.com/code-yeongyu/oh-my-openagent/pull/9318), [#9319](https://github.com/code-yeongyu/oh-my-openagent/pull/9319), [#9321](https://github.com/code-yeongyu/oh-my-openagent/pull/9321))
21
+
22
+ ### Fixed
23
+
24
+ On macOS, an install downloaded from the web trusts the computer-use engine shipped inside its own app when the engine sits inside the install and matches the checksums shipped beside it. Before, the download quarantine made that engine look untrusted. Any other quarantined engine is still refused. ([#9283](https://github.com/code-yeongyu/oh-my-openagent/issues/9283), [#9301](https://github.com/code-yeongyu/oh-my-openagent/pull/9301))
25
+
26
+ When computer use is missing the Screen Recording or Accessibility grant, it opens that System Settings pane once, names the app to enable, and tells you to quit and relaunch it. A denied Accessibility listener now reads as a permission problem instead of "supervisor not live". ([#9284](https://github.com/code-yeongyu/oh-my-openagent/issues/9284), [#9309](https://github.com/code-yeongyu/oh-my-openagent/pull/9309))
27
+
28
+ On Windows set to a language other than English, unpacking a download no longer fails when `tar` lists month names outside ASCII. Thanks to @willowite for the report, the reproduction and the fix. ([#9289](https://github.com/code-yeongyu/oh-my-openagent/issues/9289), [#9303](https://github.com/code-yeongyu/oh-my-openagent/pull/9303))
29
+
30
+ Editing a file with no extension, such as a shebang script or a `Makefile`, no longer returns "LSP errors detected ... please fix" when no language server covers it. Thanks to @MoerAI for the fix and @floweredao for the report. ([#9292](https://github.com/code-yeongyu/oh-my-openagent/issues/9292), [#9296](https://github.com/code-yeongyu/oh-my-openagent/pull/9296))
31
+
32
+ Your home folder no longer counts as a project by itself, so a dotfiles `.git` or a stray `~/package.json` stops the language-server install prompt from firing for every file in it. A project with its own marker inside your home folder still counts. Thanks to @MoerAI. ([#9227](https://github.com/code-yeongyu/oh-my-openagent/issues/9227), [#9297](https://github.com/code-yeongyu/oh-my-openagent/pull/9297))
33
+
34
+ On OpenCode, picking a non-GPT model for Hephaestus fails with an error saying Hephaestus needs a GPT model, instead of an opaque `UnknownError`. Thanks to @RaviTharuma. ([#7704](https://github.com/code-yeongyu/oh-my-openagent/issues/7704), [#7707](https://github.com/code-yeongyu/oh-my-openagent/pull/7707))
35
+
36
+ On OpenCode, `opencode run --agent sisyphus` and the other original config keys pick that agent again after display names are applied. A category or an unknown name passed to `--agent` fails with a clear error instead of quietly running the default agent. Thanks to @RaviTharuma. ([#7701](https://github.com/code-yeongyu/oh-my-openagent/issues/7701), [#7703](https://github.com/code-yeongyu/oh-my-openagent/issues/7703), [#7708](https://github.com/code-yeongyu/oh-my-openagent/pull/7708))
37
+
38
+ On OpenCode, ordinary chat no longer turns into a goal, and a message containing pause, resume or clear leaves your goal alone. A prompt longer than 2,000 characters no longer fails with `InvalidObjectiveError`. Goals change only through an explicit `/goal` command, or from your first message when `default_mode.goal` is on. Thanks to @RaviTharuma for the fix and @Cle2ment for the report. ([#6391](https://github.com/code-yeongyu/oh-my-openagent/issues/6391), [#7979](https://github.com/code-yeongyu/oh-my-openagent/pull/7979))
39
+
40
+ On Codex, updating removes the retired `features.child_agents_md` setting that Codex 0.156 rejects at startup, and the bundled rules no longer mention it. Thanks to @LilMGenius. ([#8693](https://github.com/code-yeongyu/oh-my-openagent/pull/8693))
41
+
42
+ On Codex, the spawn examples in the bundled Hephaestus rule name their `agent_type`, so a session that follows them spawns its subagents instead of being blocked by the spawn guard. Thanks to @LilMGenius. ([#8298](https://github.com/code-yeongyu/oh-my-openagent/pull/8298))
43
+
10
44
  ## [5.1.6] - 2026-09-30
11
45
 
12
46
  **Hotfix: reopening a session with an unanswerable question no longer crashes the TUI.** ([#9268](https://github.com/code-yeongyu/oh-my-openagent/issues/9268)) When a session was resumed with a pending question whose saved arguments no longer formed a valid question set, the question widget showed "0 unanswered" and crashed with `Cannot read properties of undefined (reading 'question')` as soon as you expanded it. The call now settles as lost in a restart, so the model learns the question is gone and can ask again, and clicking a widget whose questions all have answers submits them. Thanks to @copycatcode for the report. This release runs on the senpi 2026.9.30 engine.
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- // omo:E6wxsbgn9wHM1Vn0p76LjLmxCW2N_Wy3ZgZIQGgU3L8:wrcNysGCSmPQBapD2B6XCs6Q9IVy4wapNChJ-vEMgU8
2
+ // omo:5ixRJIhPSEuIl-PJdbo4U6vtImrUaFMyMIZXIZV47NI:wrcNysGCSmPQBapD2B6XCs6Q9IVy4wapNChJ-vEMgU8
3
3
  import{spawn as t}from"node:child_process";import*as e from"node:fs";import*as r from"node:fs/promises";function n(t){if(t instanceof Error&&"code"in t)return"string"==typeof t.code?t.code:void 0}async function i(t){for(let e=0;;e+=1)try{return await t()}catch(t){if("EINTR"!==n(t)||e>=128)throw t}}function o(t){for(let e=0;;e+=1)try{return t()}catch(t){if("EINTR"!==n(t)||e>=128)throw t}}import{Buffer as a}from"node:buffer";import{constants as s}from"node:fs";function l(t){return"number"==typeof t?0!==(t&s.O_EXCL):"string"==typeof t&&t.toLowerCase().includes("x")}function c(t){return"function"==typeof t}function u(t){return(...e)=>i(async()=>t(...e))}function d(t){return(...e)=>o(()=>t(...e))}function f(t,e){let r="async"===e?u:d,n=new Map;return new Proxy(t,{get(t,e){if(n.has(e))return n.get(e);let i=Reflect.get(t,e);if(!c(i))return i;let o=r(i),a=Reflect.get(i,"native");return c(a)&&Object.assign(o,{native:r(a)}),n.set(e,o),o}})}var p=new Set(["stat","sync","datasync","chmod","chown","utimes","truncate"]);var m=f(r,"async"),w=f(e,"sync"),{access:h,chmod:y,copyFile:g,cp:v,link:b,lstat:E,mkdir:S,mkdtemp:_,readFile:x,readdir:I,realpath:N,rename:O,rm:k,rmdir:P,stat:T,unlink:R}=m,{accessSync:M,chmodSync:A,fsyncSync:$,linkSync:L,lstatSync:C,mkdirSync:D,readFileSync:U,readdirSync:q,realpathSync:j,statSync:F,unlinkSync:H,writeFileSync:J,writeSync:B}=w,{constants:G,watch:V}=e,Y=async(...t)=>{let e=()=>r.open(...t);return function(t){return new Proxy(t,{get(t,e){let r=Reflect.get(t,e);if(!c(r))return r;let o=e=>Reflect.apply(r,t,[...e]);return"close"===e||e===Symbol.asyncDispose?(...t)=>{let e=o(t);return e instanceof Promise?e.catch(t=>{if("EINTR"!==n(t))throw t}):e}:"string"==typeof e&&p.has(e)?(...t)=>{let e=o(t);return e instanceof Promise?e.catch(e=>{if("EINTR"!==n(e))throw e;return i(async()=>o(t))}):e}:(...t)=>o(t)}})}(await(l(t[1]??"r")?e():i(e)))},K=(t,r,n)=>function(t,e,r,n){return l(r)?t(e,r,n):o(()=>t(e,r,n))}(e.openSync,t,r,n??void 0);function z(t){try{e.closeSync(t)}catch(t){if("EINTR"!==n(t))throw t}}function X(t){try{return o(()=>e.statSync(t)),!0}catch{return!1}}import{join as Z}from"node:path";import{fileURLToPath as W}from"node:url";import{randomUUID as Q}from"node:crypto";import{dirname as tt}from"node:path";async function et(t){return JSON.parse(await x(t,"utf8"))}async function rt(t,e,r=384){let n=`${t}.tmp-${process.pid}-${Q()}`,i=await Y(n,"wx",r),o=!1;try{try{await i.writeFile(`${JSON.stringify(e,null,2)}\n`,"utf8"),await i.sync()}finally{await i.close()}await O(n,t),o=!0,await async function(t){try{let e=await Y(t,"r");try{await e.sync()}finally{await e.close()}}catch(t){let e=t instanceof Error&&"code"in t?t.code:void 0;if("win32"!==process.platform||!["EISDIR","EPERM"].includes(String(e)))throw t}}(tt(t))}finally{o||await it(n)}}async function nt(t,e){let r=await et(t);await rt(t,{...r,...e})}async function it(t){try{await R(t)}catch(t){if(!(t instanceof Error&&"code"in t&&"ENOENT"===t.code))throw t}}import{spawn as ot,spawnSync as at}from"node:child_process";import{execFile as st}from"node:child_process";var lt=null;function ct(){return lt??=async function(){if("darwin"!==process.platform)return null;try{let{dlopen:t,FFIType:e}=await(import("bun:ffi")),r=t("/usr/lib/libSystem.B.dylib",{proc_pidinfo:{args:[e.i32,e.i32,e.u64,e.ptr,e.i32],returns:e.i32}});return(t,e,n,i,o)=>Number(r.symbols.proc_pidinfo(t,e,n,i,o))}catch{return null}}(),lt}var ut=null;async function dt(t){if("win32"!==process.platform)return null;if(!Number.isSafeInteger(t)||t<=0)return null;ut??=async function(){if("win32"!==process.platform)return null;try{let{dlopen:t,FFIType:e}=await(import("bun:ffi"));return t("kernel32.dll",{OpenProcess:{args:[e.u32,e.i32,e.u32],returns:e.ptr},GetProcessTimes:{args:[e.ptr,e.ptr,e.ptr,e.ptr,e.ptr],returns:e.i32},CloseHandle:{args:[e.ptr],returns:e.i32}}).symbols}catch{return null}}();let e=await ut;if(null===e)return null;let r=e.OpenProcess(4096,0,t);if(null===r||0===r||0n===r)return null;try{let t=new BigUint64Array(1),n=e.GetProcessTimes(r,t,new BigUint64Array(1),new BigUint64Array(1),new BigUint64Array(1)),i=t[0]??0n;return 0===n||0n===i?null:i}finally{e.CloseHandle(r)}}async function ft(t,e){return await new Promise(r=>{st(t,e,{encoding:"utf8",timeout:2e3,windowsHide:!0},(t,e)=>{if(null!==t)return void r(null);let n=e.trim();r(n.length>0?n:null)})})}var pt=function(t,e){let r;return n=>n!==e?t(n):(r??=t(n).then(t=>(null===t&&(r=void 0),t),t=>{throw r=void 0,t}),r)}(async function(t){if("linux"===process.platform)return await async function(t){try{let e=await x(`/proc/${t}/stat`,"utf8"),r=e.lastIndexOf(")");if(r<0)return null;let n=e.slice(r+2).trim().split(/\s+/)[19];return void 0===n?null:`linux-proc-start-ticks:${n}`}catch{return null}}(t);if("darwin"===process.platform||"freebsd"===process.platform){if("dead"===wt(t))return null;let e=await async function(t){if("darwin"!==process.platform)return null;if(!Number.isSafeInteger(t)||t<=0)return null;let e=await ct();if(null===e)return null;let r=new Uint8Array(136),n=0;try{n=e(t,3,0n,r,136)}catch{return null}if(136!==n)return null;let i=new DataView(r.buffer,r.byteOffset,r.byteLength),o=Number(i.getBigUint64(120,!0));return o>0?o:null}(t);if(null!==e)return`proc-start-epoch:${e}`;let r=await ft("/bin/ps",["-o","lstart=","-p",String(t)]);return null===r?null:`ps-lstart:${r.replace(/\s+/g," ")}`}return"win32"===process.platform?await async function(t){if("dead"===wt(t))return null;let e=await dt(t);if(null!==e)return`win32-creation-filetime:${e}`;let r=await ft("powershell.exe",["-NoProfile","-Command",`(Get-Process -Id ${t} -ErrorAction SilentlyContinue).StartTime.ToUniversalTime().ToString('o')`]);return null===r?null:`win32-creation-date:${r}`}(t):null},process.pid);function mt(t){let e=t.indexOf(":");return e<=0?null:t.slice(0,e)}function wt(t){try{return process.kill(t,0),"alive"}catch(t){let e=function(t){if(t instanceof Error&&"code"in t)return"string"==typeof t.code?t.code:void 0}(t);return"ESRCH"===e?"dead":"EPERM"===e?"alive":"unknown"}}function ht(){return"1"===process.env.OMO_MEMORY_SUPERVISOR_ALLOW_TEST_SEAMS}function yt(){if(ht()){let t=process.env.OMO_MEMORY_SUPERVISOR_PLATFORM;if("posix"===t||"win32"===t)return t}return"win32"===process.platform?"win32":"posix"}function gt(t,e){let r=ht()?process.env.OMO_MEMORY_SUPERVISOR_CLOCK_PATH:void 0;if(void 0===r){let r=setTimeout(e,Math.max(0,t-Date.now()));return()=>clearTimeout(r)}let n=!1,i=()=>{if(n)return;let i=bt(r);!Number.isFinite(i)||i<t||(n=!0,o?.close(),clearInterval(a),e())};if(bt(r)>=t)return n=!0,e(),()=>{};let o=V(r,i),a=setInterval(i,vt);return i(),()=>{n||(n=!0,o.close(),clearInterval(a))}}var vt=25;function bt(t){let e=q(t).map(t=>/^(\d+)-(-?\d+(?:\.\d+)?)$/.exec(t)).filter(t=>null!==t).sort((t,e)=>Number(t[1])-Number(e[1])).at(-1);return void 0===e?Number.NaN:Number(e[2])}function Et(t,e){if(!ht())return;let r=process.env.OMO_MEMORY_SUPERVISOR_TASKKILL_RUN_DIR;void 0!==r&&J(`${r}/${t}-${process.pid}.json`,`${JSON.stringify({targetPid:e})}\n`,"utf8")}function St(t){if(!ht())return;let e=process.env[t];if(void 0===e)return;let r=JSON.parse(e);if(!Array.isArray(r)||!r.every(t=>"string"==typeof t)||0===r.length)throw TypeError(`${t} must be a non-empty string array`);return r}function _t(t,e,r){let[n,...i]=t;if(void 0===n)throw TypeError("termination command is required");if(r){let t=at(n,[...i,...e],{env:process.env,stdio:"ignore",windowsHide:!0});if(void 0!==t.error)throw t.error;return}ot(n,[...i,...e],{env:process.env,stdio:"ignore",windowsHide:!0}).once("error",t=>process.stderr.write(`${t.message}\n`))}function xt(t,e){Et(`posix-${e}`,t);let r=St("OMO_MEMORY_SUPERVISOR_POSIX_SIGNAL_COMMAND");if(void 0===r)try{process.kill(-t,e)}catch(t){if(!(t instanceof Error&&"code"in t&&"ESRCH"===t.code))throw t}else _t(r,["--signal-group",String(t),e],!1)}function It(t){void 0!==t&&Et("win32-graceful",t)}function Nt(t,e){"win32"===t?(It(e.pid),e.kill()):void 0!==e.pid&&xt(e.pid,"SIGTERM")}function Ot(t,e,r=!1){void 0!==e&&("win32"===t?function(t,e){_t(St("OMO_MEMORY_SUPERVISOR_TASKKILL_COMMAND")??["taskkill"],["/pid",String(t),"/T","/F"],e)}(e,r):xt(e,"SIGKILL"))}async function kt(t){return await pt(t)}import{join as Pt}from"node:path";function Tt(t){return"object"==typeof t&&null!==t}function Rt(t,e){try{return t?.[e]}catch(t){return void Error}}function Mt(t,e){let r=Rt(t,e);return Tt(r)?r:void 0}function At(t){if(!t)return"";if("string"==typeof t)return t.toLowerCase();if(!Tt(t))try{return JSON.stringify(t).toLowerCase()}catch(t){if(!(t instanceof Error))throw t;return""}let e=Mt(t,"data"),r=[e,Mt(t,"error"),t,Mt(e,"error")].filter(t=>void 0!==t);for(let t of r){let e=Rt(t,"message");if("string"==typeof e&&e.length>0)return e.toLowerCase()}let n=Rt(t,"name");if("string"==typeof n&&n.length>0){let t=n.match(/:\s*(.+)/);if(t)return t[1]?.trim().toLowerCase()??""}try{return JSON.stringify(t).toLowerCase()}catch(t){if(!(t instanceof Error))throw t;return""}}function $t(t,e){if(function(t){return"object"==typeof t&&null!==t}(t))try{return t[e]}catch(t){return void Error}}function Lt(t){return"terminal_quota_exhausted"===function(t){let e=$t(t,"data"),r=$t(t,"detail")??$t(e,"detail")??t,n=$t(r,"error")??r,i=$t(n,"type")??$t(r,"type");return"string"==typeof i?i.toLowerCase():void 0}(t)||(e=At(t),!/\bnon[-\s]+terminal\s+quota\b/i.test(e)&&!/\bnon[-\s]+terminal\s+billing\s+limit\b/i.test(e)&&(/\bterminal\s+quota\b/i.test(e)||/\bterminal\s+billing\s+limit\b/i.test(e)||/\bhard\s+billing\s+limit\b/i.test(e)));var e}function Ct(t){if(Lt(t))return"abort";let e=At(t),r=function(t){if(!Tt(t))return;let e=Mt(t,"data"),r=[t,e,Mt(t,"error"),Mt(e,"error")].filter(t=>void 0!==t);for(let t of r){let e=Rt(t,"name");if("string"==typeof e&&e.length>0)return e}}(t)?.toLowerCase().replace(/[_-]/g,"");return r?.includes("messageabortederror")||r?.includes("aborterror")?"abort":"contextoverflowerror"===r?"context_overflow":r?.includes("ailoadapikeyerror")||r?.includes("loadapi")||/api.?key.?is.?missing/i.test(e)&&/environment variable/i.test(e)?"missing_api_key":/api.?key/i.test(e)&&/must be a string/i.test(e)?"invalid_api_key":r?.includes("providermodelnotfounderror")||r?.includes("modelnotfounderror")||r?.includes("unknownerror")&&/model\s+not\s+found/i.test(e)?"model_not_found":r?.includes("quotaexceeded")||r?.includes("insufficientquota")||r?.includes("billingerror")||r?.includes("resourceexhausted")||r?.includes("insufficientcredits")||r?.includes("usagelimit")||/quota.?exceeded/i.test(e)||/exceeded.*quota/i.test(e)||/quota\b.*\breset/i.test(e)||/usage\s*quota/i.test(e)||/subscription.?(?:quota|limit)/i.test(e)||/insufficient.?(?:quota|balance|funds?|credits?)/i.test(e)||/credits?\s+exhausted/i.test(e)||/\b(?:session|weekly|monthly|daily|hourly|\d+[-\s]hour|plan|call)\s+limit\b/i.test(e)||/\bhit\s+your\b[^.]*\blimit\b/i.test(e)||/\bin\s+arrears\b/i.test(e)||/\brecharge\s+and\s+try\b/i.test(e)||/billing.?(?:hard.?)?limit/i.test(e)||/exhausted\s+your\s+capacity/i.test(e)||/resource.?exhausted/i.test(e)||/out\s+of\s+credits?/i.test(e)||/payment.?required/i.test(e)||/usage\s+limit/i.test(e)||/credit\s+balance.*too\s+low/i.test(e)||/limit\s+exhausted/i.test(e)||/使用上限/.test(e)||/用量上限/.test(e)||/达到.*限制/.test(e)||/额度.*不足/.test(e)||/余额.*不足/.test(e)||/已耗尽/.test(e)||function(t){return/预扣费额度失败/i.test(t)&&/用户剩余额度/i.test(t)||/用户剩余额度/i.test(t)&&/需要预扣费额度/i.test(t)}(e)?"quota_exceeded":void 0}var Dt=new Set(["providermodelnotfounderror","ratelimiterror","modelunavailableerror","providerconnectionerror","authenticationerror"]),Ut=new Set(["messageabortederror","permissiondeniederror","contextlengtherror","timeouterror","validationerror","syntaxerror","usererror"]),qt=["rate_limit","rate limit","usage_limit_reached","usage limit has been reached","quota","all credentials for model","cooling down","exhausted your capacity","not found","unavailable","insufficient","too many requests","over limit","overloaded","bad gateway","bad request","unknown provider","provider not found","model_not_supported","model not supported","model is not supported","connection error","network error","timeout","service unavailable","internal_server_error","free usage","usage exceeded","credit","balance","temporarily unavailable","try again","请稍后重试","503","502","504","429","529","selected provider is forbidden","provider is forbidden","频率限制","请求过于频繁","暂时不可用","服务不可用","server_error","an error occurred while processing","upstream request failed"],jt=["rate limit","cooling down","credentials for model"];function Ft(t){let e=t.name?.toLowerCase();if(void 0!==e&&Ut.has(e))return!1;if(Lt(t))return!1;if("quota_exceeded"===Ct(t))return!0;if(void 0!==e&&Dt.has(e))return!0;let r=t.message?.toLowerCase()??"";return!(!(n=r).includes("retrying in")||!jt.some(t=>n.includes(t)))||(null!=t.statusCode&&(429===t.statusCode||503===t.statusCode||529===t.statusCode)||qt.some(t=>r.includes(t)));var n}var Ht=[/prompt is too long/i,/request_too_large/i,/input is too long for requested model/i,/exceeds the context window/i,/exceeds (?:the )?(?:model'?s )?maximum context length(?: of [\d,]+ tokens?|\s*\([\d,]+\))/i,/input token count.*exceeds the maximum/i,/maximum prompt length is \d+/i,/reduce the length of the messages/i,/maximum context length is \d+ tokens/i,/exceeds (?:the )?maximum allowed input length of [\d,]+ tokens?/i,/input \(\d+ tokens\) is longer than the model'?s context length \d+ tokens/i,/exceeds the limit of \d+/i,/exceeds the available context size/i,/greater than the context length/i,/context window exceeds limit/i,/exceeded model token limit/i,/too large for model with \d+ maximum context length/i,/prompt has [\d,]+ tokens?, but the configured context size is [\d,]+ tokens?/i,/prompt too long; exceeded (?:max )?context length/i,/range of input length should be/i,/model_context_window_exceeded/i,/context[_ ]length[_ ]exceeded/i,/too many tokens/i,/token limit exceeded/i,/^4(?:00|13)\s*(?:status code)?\s*\(no body\)/i,/(?:request[ _])?(?:body|entity|payload)[_ ]too[_ ]large/i,/Request payload is \d+ (?:bytes, over the \d+ byte|tokens, over the \d+ token) limit Kiro accepts\./i,/Model context limit reached\. Conversation size exceeds model capacity\./i],Jt=[/^(Throttling error|Service unavailable):/i,/rate limit/i,/too many requests/i];var Bt=/^Error: Model "([^"]+)" not found\. Use --list-models to see available models\.$/m,Gt=/^(?:Error:\s*)?No API key found for\s+([^\s.]+)/m,Vt=/(?:^|\s)(\d{3})\s*:/;function Yt(t){if(t.timedOut||0===t.code)return;let e=`${t.stderr}\n${t.stdout}`,r=Bt.exec(e)?.[1];if(void 0!==r)return{kind:"model_not_visible",id:r};let n=Gt.exec(e)?.[1];if(void 0!==n)return{kind:"auth_missing",provider:n};let i=function(t){for(let e of[t.stderr,t.stdout]){let t=e.split("\n").map(t=>t.trim()).find(t=>t.length>0);if(void 0!==t)return t.slice(0,200)}return}(t);if(void 0===i)return;if(o=i,!Jt.some(t=>t.test(o))&&Ht.some(t=>t.test(o)))return{kind:"context_overflow",detail:i};var o;let a=Number.parseInt(Vt.exec(i)?.[1]??"",10);return Ft({message:i,...Number.isNaN(a)?{}:{statusCode:a}})?{kind:"provider_unavailable",detail:i}:void 0}import{randomUUID as Kt}from"node:crypto";import{dirname as zt,join as Xt}from"node:path";import{randomUUID as Zt}from"node:crypto";import{hostname as Wt}from"node:os";import Qt from"node:path";import te from"node:path";var ee=new Set;function re(t){ee.add(t)}function ne(t){ee.delete(t)}var ie=/\.candidate-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function oe(t){if(t instanceof Error&&"code"in t)return"string"==typeof t.code?t.code:void 0}function ae(t,e){try{t.onFailure?.(e)}catch{}}function se(t){if("win32"!==process.platform)return!1;let e=oe(t);return"EBUSY"===e||"EPERM"===e||"EACCES"===e}import{randomUUID as le}from"node:crypto";import{hostname as ce}from"node:os";function ue(t){return"string"==typeof t&&t.length>0}function de(t){let e;try{e=JSON.parse(t)}catch{return null}if("object"!=typeof e||null===e||Array.isArray(e))return null;let r=e;return!Number.isInteger(r.pid)||Number(r.pid)<=0?null:ue(r.process_start)&&ue(r.hostname)&&ue(r.nonce)?!ue(r.created_at)||Number.isNaN(Date.parse(r.created_at))?null:ue(r.purpose)&&(void 0===r.run_id||ue(r.run_id))?{pid:Number(r.pid),process_start:r.process_start,hostname:r.hostname,nonce:r.nonce,created_at:r.created_at,purpose:r.purpose,...void 0===r.run_id?{}:{run_id:r.run_id}}:null:null}async function fe(t,e={}){if(0===t.length)throw Error("lock purpose must not be empty");let r=await pt(process.pid);return{pid:process.pid,process_start:r??"unavailable",hostname:ce(),nonce:le(),created_at:(new Date).toISOString(),purpose:t,...void 0===e.runId?{}:{run_id:e.runId}}}class pe extends Error{lockPath;owner;retriable=!0;constructor(t,e){super(`Lock is held: ${t}`),this.lockPath=t,this.owner=e,this.name="LockContentionError"}}function me(t){if(t instanceof Error&&"code"in t)return"string"==typeof t.code?t.code:void 0}function we(t,e){if(void 0!==e)return e(t);if("win32"!==process.platform)return!1;let r=me(t);return"EBUSY"===r||"EPERM"===r||"EACCES"===r}async function he(t){for(let e=0;e<3;e+=1)try{return await(Ee.unlink??R)(t),ne(t),!0}catch(r){if("ENOENT"===me(r))return ne(t),!0;if(!we(r,Ee.isSharingError))throw re(t),Se(Qt.dirname(t)),r;if(e+1===3)return re(t),Se(Qt.dirname(t)),!1}return!1}function ye(t,e){return e?.throwIfAborted(),new Promise((r,n)=>{let i=setTimeout(a,t),o=()=>a(e?.reason??new DOMException("The operation was aborted","AbortError"));function a(t){clearTimeout(i),e?.removeEventListener("abort",o),void 0===t?r():n(t)}e?.addEventListener("abort",o,{once:!0})})}async function ge(t){try{let e=await x(t,"utf8");return{raw:e,record:de(e)}}catch(t){let e=me(t);if("ENOENT"===e)return null;if("\\"===Qt.sep&&"EPERM"===e)return{raw:"",record:null};throw t}}async function ve(t,e){await S(Qt.dirname(t),{recursive:!0,mode:448});let{candidatePath:r,handle:n}=await async function(t){for(let e=0;;e+=1){let r=`${t}.candidate-${Zt()}`;try{return{candidatePath:r,handle:await Y(r,"wx",384)}}catch(n){if(await he(r)||Se(Qt.dirname(t)),"EINTR"!==me(n)||e>=128)throw n}}}(t);try{try{await async function(t,e,r,n){let o="string"==typeof e?a.from(e,r??"utf8"):e,s=0;for(;s<o.length;){n?.throwIfAborted();let{bytesWritten:e}=await i(()=>t.write(o,s));if(e<=0)throw Error(`fs write made no progress at offset ${s}`);s+=e}}(n,`${JSON.stringify(e)}\n`,"utf8"),await n.sync()}finally{await n.close()}try{return await b(r,t),!0}catch(t){if(function(t){let e=me(t);return"EEXIST"===e||"ENOENT"===e}(t))return!1;throw t}}finally{await he(r)||Se(Qt.dirname(t))}}var be=new Set,Ee={};function Se(t){be.delete(t)}async function _e(t){if(t.hostname!==Wt())return!1;let e=wt(t.pid);if("dead"===e)return!0;if("unknown"===e)return!1;let r=await pt(t.pid);return null!==r&&"unavailable"!==t.process_start&&function(t,e){let r=mt(t);return null!==r&&r===mt(e)&&t!==e}(t.process_start,r)}async function xe(t){let e=await ge(t);if(null===e||null===e.record||!await _e(e.record))return!1;let r=`${t}.reaping-${Zt()}`;try{await O(t,r)}catch(t){if("ENOENT"===me(t))return!1;if(we(t))return!1;throw t}let n=await ge(r);if(null!==n&&n.raw===e.raw)return await R(r),!0;try{await b(r,t)}catch(t){if("EEXIST"!==me(t))throw t}return await R(r),!1}async function Ie(t,e,r){if(null===e.record||!await _e(e.record))return!1;let n=`${t}.recovery`,i={...r,nonce:Zt(),created_at:(new Date).toISOString(),purpose:`${r.purpose}:recovery`};for(let t=0;!await ve(n,i);t+=1)if(t>0||!await xe(n))return!1;try{let r=await ge(t);if(null===r)return!0;if(r.raw!==e.raw||null===r.record)return!1;if(!await _e(r.record))return!1;let o=await ge(n);return null!==o&&o.record?.nonce===i.nonce&&(await R(t),!0)}finally{await Oe(n,i)}}async function Ne(t,e,r={}){let n=r.waitTimeoutMs??0,i=r.retryDelayMs??25;if(n<0||i<=0)throw Error("lock wait options must be positive");let o=Qt.dirname(t);be.has(o)||(be.add(o),await async function(t,e=Date.now,r={}){let n;try{n=await I(t)}catch(e){if("ENOENT"===oe(e)){for(let e of ee)te.dirname(e)===t&&ne(e);return 0}throw e}let i=0;for(let o of n){if(!ie.test(o))continue;let n=te.join(t,o);try{let t=await T(n);if(!ee.has(n)&&e()-t.mtimeMs<=36e5)continue;let o=!1;for(let t=0;t<3;t+=1)try{await(r.unlink??R)(n),ne(n),o=!0;break}catch(e){if("ENOENT"===oe(e)){ne(n),o=!0;break}if(!(r.isSharingError?.(e)??se(e)))throw e;t+1===3&&ae(r,n)}o&&(i+=1)}catch(t){"ENOENT"===oe(t)&&ne(n),ae(r,n)}}return i}(o,Date.now,{...void 0===Ee.unlink?{}:{unlink:Ee.unlink},...void 0===Ee.isSharingError?{}:{isSharingError:Ee.isSharingError},onFailure:()=>Se(o)}).catch(()=>{Se(o)}));let a=Date.now()+n;for(;;){r.signal?.throwIfAborted();let n=await ge(t);if(null===n){if(await ve(t,e))return;if(r.signal?.throwIfAborted(),n=await ge(t),null===n)continue}if(!await Ie(t,n,e)){if(r.signal?.throwIfAborted(),Date.now()>=a)throw new pe(t,n.record);await ye(Math.min(i,Math.max(1,a-Date.now())),r.signal)}}}async function Oe(t,e){let r=await ge(t);if(null===r||r.record?.nonce!==e.nonce)return!1;try{return await R(t),!0}catch(t){if("ENOENT"===me(t))return!1;throw t}}async function ke(t,e,r,n){await Ne(t,e,n);try{return await r()}finally{await Oe(t,e)}}Promise.resolve();var Pe=[["\\bAKIA[0-9A-Z]{16}\\b",""],["\\b(?:bearer|token|api[_-]?key|secret|password|passwd|pwd)\\s*[=:]\\s*\\S{1,256}","i"],["\\bAuthorization\\s*:\\s*Bearer\\s+\\S{1,256}","i"],["\\bsk-(?:proj-)?[-_A-Za-z0-9]+\\b",""],["\\b(?:ghp|github_pat|glpat|xox[baprs])-[-_A-Za-z0-9]+\\b",""]];Pe.map(([t,e])=>new RegExp(t,e)),Pe.map(([t,e])=>new RegExp(t,`${e}g`));new TextDecoder("utf-8",{fatal:!0,ignoreBOM:!0});import{dirname as Te}from"node:path";import{fileURLToPath as Re}from"node:url";Te(Re(import.meta.url));import{dirname as Me}from"node:path";import{fileURLToPath as Ae}from"node:url";Me(Ae(import.meta.url)),new Date(0).toISOString();var $e="\\p{Script=Hangul}\\p{Script=Han}\\p{Script=Hiragana}\\p{Script=Katakana}\\u30fc";new RegExp(`[${$e}]+|(?:(?![${$e}])[\\p{L}\\p{M}\\p{N}])+`,"gu"),new RegExp(`^[${$e}]+$`,"u"),new RegExp(`[${$e}]`,"u"),new RegExp(`[${$e}]`,"gu"),new RegExp(`[\\p{L}${$e}]`,"gu");import{dirname as Le}from"node:path";import{fileURLToPath as Ce}from"node:url";Le(Ce(import.meta.url));function De(t){return Xt(t,"terminal-claim.json")}function Ue(t,e,r){return t.runId===e.runId&&t.attempt===e.attempt&&(void 0===r||t.kind===r)}function qe(t,e){let r=`${t}.${process.pid}.${Kt()}.candidate`;!function(t,e){let r=K(t,"wx",384);try{J(r,`${JSON.stringify(e,null,2)}\n`,"utf8"),$(r)}finally{z(r)}}(r,e);try{L(r,t)}catch(t){if("EEXIST"===Ge(t))return!1;throw t}finally{He(r)}return function(t){let e;try{e=K(t,"r")}catch(t){if("win32"===process.platform&&["EISDIR","EPERM"].includes(Ge(t)??""))return;throw t}try{$(e)}catch(t){if("win32"!==process.platform||!["EPERM","EACCES","EINVAL"].includes(Ge(t)??""))throw t}finally{z(e)}}(zt(t)),!0}function je(t){let e;try{e=U(t,"utf8")}catch(t){if("ENOENT"===Ge(t))return;throw t}try{return{raw:e,claim:Be(JSON.parse(e))}}catch{return{raw:e,claim:void 0}}}async function Fe(t,e,r,n,i,o){let a=await fe("reflection-finalize",{runId:i.runId});return ke(Xt(t,"terminal-claim-recovery.lock"),a,async()=>{let t=je(e);if(void 0!==t){if(t.raw!==r.raw)return t.claim;if("invalid"===n){if(void 0!==t.claim)return t.claim}else{if(void 0===t.claim)return;if("publish"!==t.claim.kind||!Je(t.claim,o))return t.claim}He(e)}},{waitTimeoutMs:Number.POSITIVE_INFINITY})}function He(t){try{H(t)}catch(t){if("ENOENT"!==Ge(t))throw t}}function Je(t,e){return"dead"===(e.getPidLiveness??wt)(t.claimantPid)}function Be(t){if(!function(t){return null!==t&&"object"==typeof t&&!Array.isArray(t)}(t)||1!==t.version||"publish"!==t.kind&&"abandon"!==t.kind||"string"!=typeof t.runId||!Number.isInteger(t.attempt)||!Number.isInteger(t.claimantPid)||Number(t.claimantPid)<=0)throw TypeError("Invalid run terminal claim");return{version:1,kind:t.kind,runId:t.runId,attempt:Number(t.attempt),claimantPid:Number(t.claimantPid)}}function Ge(t){return t instanceof Error&&"code"in t?String(t.code):void 0}import{join as Ve}from"node:path";async function Ye(t,e,r){let n={runId:e.runId,attempt:e.attempt??1},i=await async function(t,e,r,n={},i=process.pid){let o=De(t),a={version:1,kind:r,runId:e.runId,attempt:e.attempt,claimantPid:i},s=0;for(;;){if(qe(o,a))return a;let i=je(o);if(void 0===i)continue;let l=i.claim;if(void 0===l){if(s>0)throw TypeError("Invalid run terminal claim");s+=1,await(n.beforeRecovery?.("invalid"));let r=await Fe(t,o,i,"invalid",e,n);if(void 0!==r)return r;continue}if(Ue(l,e,r))return l;if("publish"!==l.kind||!Je(l,n))return l;await(n.beforeRecovery?.("dead-publish"));let c=await Fe(t,o,i,"dead-publish",e,n);if(void 0!==c)return c}}(t,n,"publish");Ue(i,n,"publish")&&(await rt(Pt(t,"publishing.json"),{version:1,...n,finishedAt:r.finishedAt}),await async function(t,e,r,n=ke,i=fe){let o=await i("reflection-finalize",{runId:e});return n(Ve(t,"terminalization.lock"),o,r,{waitTimeoutMs:Number.POSITIVE_INFINITY})}(t,e.runId,async()=>{if(X(Pt(t,"final.json"))||X(Pt(t,"abandoned.json")))return;if(!Ue(function(t){return Be(JSON.parse(U(De(t),"utf8")))}(t),n,"publish"))return;let i=void 0!==Yt({code:r.childExit.code,stdout:U(e.stdoutPath,"utf8"),stderr:U(e.stderrPath,"utf8"),timedOut:r.timedOut});i&&void 0!==e.nextAttempt&&await nt(Pt(t,"ledger.json"),{attempt:e.nextAttempt.attempt,model:e.nextAttempt.model,...void 0===e.nextAttempt.thinking?{thinking:void 0}:{thinking:e.nextAttempt.thinking},launching:!0,pid:void 0,processStart:void 0,childPid:void 0,childProcessStart:void 0}),await rt(Pt(t,"outcome.json"),r),i&&await it(De(t))}))}function Ke(t){try{B(3,`${JSON.stringify(t)}\n`)}catch(t){if(!(t instanceof Error&&"code"in t&&["EPIPE","EBADF"].includes(String(t.code))))throw t}}var ze=process.argv.slice(2);try{if("--child-bootstrap"===ze[0]){if(void 0===ze[1])throw TypeError("run directory is required");await async function(e){if(!await async function(){for await(let t of process.stdin)if(Buffer.byteLength(t)>0)return!0;return!1}())return;let r=await et(Z(e,"launch.json")),n=yt(),i=t(r.command,[...r.args],{cwd:r.cwd,env:r.env,detached:!1,stdio:["ignore","inherit","inherit"],windowsHide:!0});Ke({code:i.pid??null,signal:"MODEL_PID"});let o=()=>{"win32"!==n&&"win32"!==process.platform||i.kill()};process.on("SIGTERM",o),process.on("SIGINT",o);let a=gt(r.hardDeadlineAt,()=>{"win32"===n?Nt(n,i):xt(process.pid,"SIGTERM")}),s=gt(r.hardDeadlineAt+r.terminationGraceMs,()=>{Ot(n,process.pid)});Ke(await new Promise(t=>{let e=!1;i.once("error",()=>{e||(e=!0,t({code:null,signal:null}))}),i.once("close",(r,n)=>{e||(e=!0,t({code:r,signal:n}))})}).finally(()=>{a(),s()}))}(ze[1])}else{if(void 0===ze[0])throw TypeError("run directory is required");await async function(e){let r=Z(e,"launch.json"),n=Z(e,"ledger.json"),i=await et(r),o=yt();await nt(n,{launching:!1,pid:process.pid,processStart:await kt(process.pid)});let a,s=K(i.stdoutPath,"w"),l=K(i.stderrPath,"w"),c=t(process.execPath,[W(import.meta.url),"--child-bootstrap",e],{env:process.env,detached:!0,stdio:["pipe",s,l,"pipe"],windowsHide:!0}),u=c.pid,d="",f=c.stdio[3];null!=f&&"setEncoding"in f&&(f.setEncoding("utf8"),f.on("data",t=>{d+=t;for(let t of d.split("\n"))try{let e=JSON.parse(t);"MODEL_PID"===e.signal&&"number"==typeof e.code&&(a=e.code)}catch(t){if(!(t instanceof SyntaxError))throw t}}));let p=(t=!1)=>{try{Ot(o,u,t)}catch(t){process.stderr.write(`${t instanceof Error?t.message:String(t)}\n`)}};if(process.once("exit",()=>p(!0)),process.once("SIGTERM",()=>{p(),u=void 0,process.exit(143)}),process.once("SIGINT",()=>{p(),u=void 0,process.exit(130)}),void 0===c.pid)throw Error("child bootstrap did not receive a pid");await nt(n,{childPid:c.pid,childProcessStart:await kt(c.pid)}),c.stdin?.end("1\n");let m,w=!1,h=Promise.resolve();"win32"===o&&(h=new Promise(t=>{m=t}));let y=gt(i.hardDeadlineAt,()=>{w=!0,"win32"===o?It(c.pid):Nt(o,c)}),g=gt(i.hardDeadlineAt+i.terminationGraceMs,()=>{Ot(o,a??u),m?.()}),v=await new Promise((t,e)=>{let r=!1;c.once("error",t=>{r||(r=!0,e(t))}),c.once("close",(e,n)=>{r||(r=!0,t({code:e,signal:n}))})}),b=function(t){let e=t.trim().split("\n").at(-1);if(void 0!==e&&0!==e.length)try{let t=JSON.parse(e),r="number"==typeof t.code||null===t.code?t.code:void 0,n="string"==typeof t.signal||null===t.signal?t.signal:void 0;return void 0===r||void 0===n||"MODEL_PID"===n?void 0:{code:r,signal:n}}catch{return}}(d);"win32"===o&&w&&void 0===b&&await h,y(),g(),u=void 0,z(s),z(l);let E=function(){let t=ht()?process.env.OMO_MEMORY_SUPERVISOR_CLOCK_PATH:void 0;return void 0===t?Date.now():bt(t)}(),S=(new Date).toISOString(),_={version:1,runId:i.runId,attempt:i.attempt,finishedAt:S,childExit:b??v,timedOut:w||Number.isFinite(E)&&E>=i.hardDeadlineAt};await Ye(e,i,_),await it(r),process.exit(0)}(ze[0])}}catch(t){process.stderr.write(`${t instanceof Error?t.stack??t.message:String(t)}\n`),process.exitCode=1}
@@ -1,2 +1,2 @@
1
- // omo:yZZM5xvlPQeXwsxHS_tj6M2gx4f_aY4zcH9QIgW0R6w:_CjlfnfdjRWkyBun7ZF6QEVpPySoKtaT_LszNSF2F18
2
- import{createHash as e,randomUUID as t}from"node:crypto";import{chmodSync as i,existsSync as r,mkdirSync as n,readFileSync as o,renameSync as s,rmSync as a,writeFileSync as c}from"node:fs";import{join as l}from"node:path";import{DatabaseSync as d}from"node:sqlite";function u(t){return e("sha256").update(o(t)).digest("hex")}import{tmpdir as h}from"node:os";import{join as p}from"node:path";var m=Number.MAX_SAFE_INTEGER;function f(e){if(void 0===e)return!1;let{compat:t}=e;return"object"==typeof t&&null!==t&&"supportsImageDetailOriginal"in t&&!1===t.supportsImageDetailOriginal||("anthropic-messages"===e.api||"anthropic"===e.provider||/claude/i.test(e.id))}class g extends Error{constructor(){super("Computer use is off for this session; the user can turn it on with /computer on."),this.name="ComputerDisabledError"}}class y{#e;#t;#i=new Set;#r;#n;#o=!1;constructor(e){this.#e=e.service,this.#t=e.settings}get service(){return this.#e}settings(){return this.#t()}get enabled(){return this.#r??this.#t().enabled}get active(){return this.#o}get running(){return void 0!==this.#n}setEnabled(e){this.#r=e}onActivationChange(e){return this.#i.add(e),()=>this.#i.delete(e)}async activate(e){if(!this.enabled)throw new g;let t=this.#t();await this.#s(t,e);let i=await this.#e.ensureStopPath(t.stopHotkey);return this.#a(!0),i}async deactivate(){await this.close(),this.#a(!1)}async close(){this.#n=void 0,await this.#e.close()}async stopPathStatus(){return this.running?this.#e.stopPathStatus():void 0}async stop(){return this.running?this.#e.stop():void 0}async resume(){return this.running?this.#e.resume():void 0}async capabilities(){return this.running?this.#e.capabilities():void 0}async#s(e,t){let i=function(e,t){let{auditLog:i,screenshotGc:r}=e;return{display:e.display,macosCanary:e.macosCanary,allowHostRelayOnlyStop:e.allowHostRelayOnlyStop,auditPath:i.enabled?p(t.sessionManager.getSessionDir(),".computer-audit.jsonl"):null,artifactDir:h(),screenshotGc:{staleMs:r.enabled?r.staleMs:m,scanIntervalMs:r.scanIntervalMs},captureCaps:{maxWidth:e.maxWidth,maxHeight:e.maxHeight,coordinateSafe:f(t.model),maxBytes:e.screenshotMaxBytes}}}(e,t),r=JSON.stringify(i);this.#n?.key!==r&&(this.#n={key:r,done:this.#e.open(i)});let n=this.#n;try{await n.done}catch(e){throw this.#n===n&&(this.#n=void 0),e}}#a(e){if(this.#o!==e){this.#o=e;for(let t of this.#i)t(e)}}}import{Errors as b}from"typebox/value";class w extends Error{code="COMPUTER_INVALID_ARGUMENTS";reason;constructor(e){super(`COMPUTER_INVALID_ARGUMENTS: ${e}`),this.name="ComputerArgumentsError",this.reason=e}}function v(e){return new Map(e.map(e=>[String(Reflect.get(e.properties.action??{},"const")),e]))}function x(e,t,i){let r=[...e.keys()].join(", ");if("object"!=typeof t||null===t)return new w(`${i} must be an object`);let n=Reflect.get(t,"action");if("string"!=typeof n)return new w(`${i}: "action" must be one of ${r}`);let o=e.get(n);if(void 0===o)return new w(`${i}: unknown action "${n}"; expected one of ${r}`);let s=Object.keys(t).filter(e=>!(e in o.properties));if(s.length>0)return new w(`${i}: action "${n}" does not take ${s.join(", ")}`);let[a]=b(o,t),c=void 0===a||""===a.instancePath?"":` at ${a.instancePath}`;return new w(`${i}: action "${n}"${c}: ${a?.message??"invalid arguments"}`)}import{Type as k}from"typebox";import{Check as O}from"typebox/value";var E=k.Union([k.Literal("left"),k.Literal("right"),k.Literal("middle")]),S={timeout:k.Optional(k.Number({exclusiveMinimum:0,description:"Maximum time in seconds for this action."})),include_screenshot:k.Optional(k.Boolean({description:"Capture a screenshot after the action."}))},P={x:k.Number(),y:k.Number()},C={additionalProperties:!1},R=[k.Object({action:k.Literal("screenshot"),...S},C),k.Object({action:k.Literal("click"),...P,button:k.Optional(E),...S},C),k.Object({action:k.Literal("double_click"),...P,button:k.Optional(E),...S},C),k.Object({action:k.Literal("move"),...P,button:k.Optional(E),...S},C),k.Object({action:k.Literal("drag"),...P,to_x:k.Number(),to_y:k.Number(),button:k.Optional(E),...S},C),k.Object({action:k.Literal("scroll"),...P,scroll_x:k.Number(),scroll_y:k.Number(),...S},C),k.Object({action:k.Literal("type"),text:k.String(),...S},C),k.Object({action:k.Literal("keypress"),keys:k.Array(k.String(),{minItems:1}),...S},C),k.Object({action:k.Literal("wait"),ms:k.Integer({minimum:0}),...S},C)],$=k.Union([...R]),T=k.Object({action:k.Literal("batch"),actions:k.Array($,{minItems:1}),...S},C),A=k.Union([$,T]),_=["screenshot","click","double_click","move","drag","scroll","type","keypress","wait"],I={x:k.Optional(k.Number({description:"click, double_click, move, drag (start), scroll (required): x pixel"})),y:k.Optional(k.Number({description:"click, double_click, move, drag (start), scroll (required): y pixel"})),button:k.Optional(k.Enum(["left","right","middle"],{type:"string",description:"click, double_click, move, drag: mouse button (default left)"})),to_x:k.Optional(k.Number({description:"drag (required): end x pixel"})),to_y:k.Optional(k.Number({description:"drag (required): end y pixel"})),scroll_x:k.Optional(k.Number({description:"scroll (required): horizontal scroll distance in pixels on every OS (one wheel notch is about 40 px); positive scrolls right"})),scroll_y:k.Optional(k.Number({description:"scroll (required): vertical scroll distance in pixels on every OS (one wheel notch is about 40 px); positive moves the view toward the end of the content (down)"})),text:k.Optional(k.String({description:"type (required): text to type"})),keys:k.Optional(k.Array(k.String(),{minItems:1,description:"keypress (required): keys pressed together"})),ms:k.Optional(k.Integer({minimum:0,description:"wait (required): milliseconds"})),...S},M=k.Object({action:k.Enum([..._,"batch"],{type:"string",description:"The action to perform, or batch to run `actions` in order"}),actions:k.Optional(k.Array(k.Object({action:k.Enum([..._],{type:"string",description:"The action to perform"}),...I},C),{minItems:1,description:"batch (required): actions to execute in order"})),...I},C),L=v(R),N=v([...R,T]);var U=new Set(["screenshot","wait"]);var D={capabilities:"read",displays:"read",windows:"read",window:"read",focusedWindow:"read",screenshot:"read",click:"exec",doubleClick:"exec",move:"exec",drag:"exec",scroll:"exec",type:"exec",press:"exec",elementAt:"read",focusedElement:"read",ref:"read","clipboard.read":"read","clipboard.write":"exec"},j={screenshot:"read",click:"exec",doubleClick:"exec",move:"exec",drag:"exec",scroll:"exec",type:"exec",press:"exec",raise:"exec",ax:"read",find:"read",ref:"read"},q={value:"read",setValue:"exec",bounds:"read",attributes:"read",actions:"read",perform:"exec",press:"exec",click:"exec",focus:"exec",parent:"read",children:"read"},H={window:{label:"window",methods:j},ref:{label:"element",methods:q}};class F extends Error{reason;constructor(e,t){super(t),this.name="ComputerCallError",this.reason=e}}function V(e,t){return Object.hasOwn(e,t)?e[t]:void 0}function W(e){return Object.keys(e).join(", ")}function J(e){return"read"===function(e){let[t,i,...r]=e;if(void 0===t)throw new F("empty","Action 'call' requires a non-empty 'chain'.");if(r.length>0)throw new F("tooLong","Call chains support one handle hop at most; use computer.run(fn) for longer sequences.");let n=V(D,t.method);if(void 0===n)throw new F("unknownMethod",`Unknown desktop method "${t.method}". Desktop helpers support: ${W(D)}.`);if(void 0===i)return n;let o=Object.hasOwn(H,t.method)?H[t.method]:void 0;if(void 0===o)throw new F("notChainable",`Only desktop.window(id)/desktop.ref(ref) results accept a chained call; got desktop.${t.method}().`);let s=V(o.methods,i.method);if(void 0===s)throw new F("unknownMethod",`Unknown ${o.label} method "${i.method}". Supported ${o.label} methods: ${W(o.methods)}.`);return s}(e)}var B="senpi-desktop/1",G=["audit","stopPath.changed","engine.log"],K=["PermissionDenied","CaptureFailed","InputFailed","BackgroundUnavailable","WindowNotFound","InvalidTarget","InvalidKey","InvalidCoordinateFrame","StaleRef","AxUnsupported","AxFailed","Timeout","Closed","Internal","StopPathUnavailable","Suspended","ScreenLocked","Cancelled","CursorRestoreFailed","FocusRestoreFailed","TransactionFailed"],X={name:"computer_actions",label:"Computer actions",description:["Drive the user's real desktop with OpenAI computer-use actions (experimental): screenshot, click, double_click, move, drag, scroll, type, keypress, wait, or a batch of them.","x,y are pixels of the latest screenshot. A batch stops at the first failed action; an in-batch screenshot becomes the frame for the actions after it.","Pass only the fields the chosen action takes (each field's description names its actions); anything else is refused with COMPUTER_INVALID_ARGUMENTS before any input.","Errors carry COMPUTER_* codes with a recovery hint. COMPUTER_SUSPENDED or COMPUTER_SUPERVISOR_NOT_LIVE means the user stopped you: stop and wait."].join("\n"),exposure:"search",searchText:"OpenAI computer-use actions (experimental): screenshot, click, type, keypress, scroll, drag, batch",searchKeywords:["computer use","cua","openai computer","click","screenshot","keypress"],searchGroup:"desktop",parameters:M,executionMode:"sequential"},z={Suspended:"COMPUTER_SUSPENDED",StopPathUnavailable:"COMPUTER_SUPERVISOR_NOT_LIVE",PermissionDenied:"COMPUTER_PERMISSION_REQUIRED",InvalidCoordinateFrame:"COMPUTER_DISPLAY_STALE",ScreenLocked:"COMPUTER_SCREEN_LOCKED",CaptureFailed:"COMPUTER_SCREENSHOT_FAILED",CursorRestoreFailed:"COMPUTER_CURSOR_RESTORE_FAILED",FocusRestoreFailed:"COMPUTER_FOCUS_RESTORE_FAILED",BackgroundUnavailable:"COMPUTER_BACKGROUND_UNAVAILABLE",Cancelled:"COMPUTER_CANCELLED",Timeout:"COMPUTER_CANCELLED",timeout:"COMPUTER_CANCELLED",aborted:"COMPUTER_CANCELLED"};function Y(e,t,i){let r=e.startsWith("COMPUTER_")?e:z[e]??"COMPUTER_ERROR",n=function(e,t){let i=`Stop and wait for the user (stop chord: ${t}); only the user resumes, with /computer resume.`;switch(e){case"COMPUTER_COORD_INVALID":return"Capture a fresh screenshot and use coordinates within its frame.";case"COMPUTER_DISPLAY_STALE":return"Capture a fresh screenshot before acting; the display changed since the last screenshot.";case"COMPUTER_SUSPENDED":case"COMPUTER_SUPERVISOR_NOT_LIVE":case"COMPUTER_CANCELLED":return i;case"COMPUTER_PERMISSION_REQUIRED":return"Grant Screen Recording and Accessibility to the app that launched senpi, then restart it.";case"COMPUTER_PERMISSION_DENIED":return"A permission rule denied this action; do not retry it.";case"COMPUTER_CURSOR_RESTORE_FAILED":case"COMPUTER_FOCUS_RESTORE_FAILED":return"Input may have completed, but the previous state was not restored. Ask the user to inspect the desktop before retrying.";case"COMPUTER_BACKGROUND_UNAVAILABLE":return"This window cannot take background input; use the computer tool's accessibility actions instead.";default:return}}(r,i);return{code:r,message:`${r}: ${t}${void 0===n?"":` ${n}`}`}}import{Type as Q}from"typebox";var Z=Q.Object({method:Q.String({description:"desktop helper name, e.g. screenshot, window, click, clipboard.read"}),args:Q.Optional(Q.Array(Q.Unknown(),{description:"positional helper arguments"}))},{additionalProperties:!1}),ee=Q.Number({minimum:1,maximum:600,description:"run: budget in seconds (default 60)"}),te=[Q.Object({action:Q.Literal("call"),chain:Q.Array(Z,{description:"one desktop helper call, optionally followed by one call on the window/element it returns"})},{additionalProperties:!1}),Q.Object({action:Q.Literal("run"),code:Q.String({description:"JavaScript async function body; `desktop`, `wait`, `assert`, `tool` in scope; `return` sets the value"}),read_only:Q.Optional(Q.Boolean({description:"true = inspection only: screenshots and AX reads, input/mutation blocked"})),timeout:Q.Optional(ee)},{additionalProperties:!1}),Q.Object({action:Q.Literal("capabilities")},{additionalProperties:!1}),Q.Object({action:Q.Literal("close")},{additionalProperties:!1})],ie=Q.Union([...te]),re=Q.Object({action:Q.Enum(["call","run","capabilities","close"],{type:"string",description:"call: one desktop helper chain; run: a JavaScript body; capabilities: host report; close: end the session"}),chain:Q.Optional(Q.Array(Z,{description:"call (required): one desktop helper call, optionally followed by one call on the window/element it returns"})),code:Q.Optional(Q.String({description:"run (required): JavaScript async function body; `desktop`, `wait`, `assert`, `tool` in scope; `return` sets the value"})),read_only:Q.Optional(Q.Boolean({description:"run: true = inspection only: screenshots and AX reads, input/mutation blocked"})),timeout:Q.Optional(ee)},{additionalProperties:!1});class ne extends Error{reason;constructor(e,t){super(t),this.name="ComputerRunError",this.reason=e}}class oe{#c=[];text(e){this.#c.push({type:"text",text:e})}image(e,t){this.#c.push({type:"image",data:e,mimeType:t})}finish(){return[...this.#c]}}function se(e,t){return(i,r)=>e.resume(Promise.resolve().then(()=>(function(e,t,i){let r=Object.hasOwn(t,i)?t[i]:"exec";if(e.readOnly&&"exec"===r)throw new ne("readOnly",`read-only run: '${i}' requires read_only: false`);e.signal.throwIfAborted()}(e.context,t,i),r(e))))}var ae=new Set(["engine.hello","session.open","session.close","capabilities","displays","windows","capture","click","moveMouse","drag","scroll","typeText","keyChord","raiseWindow","clipboard.read","clipboard.write","ax.snapshot","ax.query","ax.elementAt","ax.focused","ax.node","ax.attributes","ax.children","ax.parent","ax.perform","ax.setValue","ax.focus","ax.click","stopPath.start","stopPath.status","stopPath.heartbeat","stopPath.stop","stopPath.resume","$/cancel","$/test.advanceClock"]),ce=new Set(K),le=new Set(["global","host-relay","none"]),de=["unknown","hostOnly","testOnly"],ue={suspended:"boolean",globalLive:"boolean",hostRelayLive:"boolean",heartbeatFresh:"boolean",stopPath:"string",reason:"string?"},he={backend:"string",displayServer:"string?",capture:"boolean",input:"boolean",ax:"boolean",backgroundWindowInput:"boolean",capturePermission:"string",inputPermission:"string",axPermission:"string",displayCount:"number",focusGuard:"boolean",stopPath:"string",stopReason:"string?",integrityLevel:"string?",screenLocked:"boolean"},pe={action:"string",target:"string",delivery:"string",frameId:"string?",code:"string?",durationMs:"number",focusRestored:"boolean?",textLength:"number?",textDelivered:"number?",textSha256:"string?"};function me(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function fe(e,t){return!!me(e)&&Object.entries(t).every(([t,i])=>{let r=e[t];return i.endsWith("?")?null==r||typeof r===i.slice(0,-1):typeof r===i})}function ge(e){return Array.isArray(e)&&e.every(e=>"string"==typeof e)}function ye(e,t){return"string"==typeof e&&t.has(e)}function be(e){return fe(e,ue)&&ye(e.stopPath,le)}function we(e){return fe(e,he)&&ge(e.deliveryModes)}import{spawn as ve}from"node:child_process";import{createInterface as xe}from"node:readline";class ke extends Error{code="abi-mismatch";enginePath;expected;actual;constructor(e,t){let i={abi:B,protocolVersion:"1"};super(`desktop engine ABI mismatch at ${e}: expected abi ${i.abi} protocol ${i.protocolVersion}, engine reported abi ${t.abi} protocol ${t.protocolVersion}`),this.name="DesktopEngineAbiMismatchError",this.enginePath=e,this.expected=i,this.actual=t}}import{spawnSync as Oe}from"node:child_process";import{accessSync as Ee,constants as Se,existsSync as Pe,readFileSync as Ce}from"node:fs";import{dirname as Re,join as $e}from"node:path";import{fileURLToPath as Te}from"node:url";var Ae,_e="senpi-desktop-engine",Ie="com.apple.quarantine",Me=$e(Re(Te(import.meta.url)),"..");function Le(e=process.platform,t=process.arch,i=("linux"===e&&e===process.platform?function(){return Ae??=function(e,t){let i="object"==typeof e&&null!==e?Reflect.get(e,"header"):void 0,r="object"==typeof i&&null!==i?Reflect.get(i,"glibcVersionRuntime"):void 0;return"string"==typeof r&&r.length>0?"glibc":/\/ld-musl-[^/\s]+\.so\.1$/m.test(t()??"")?"musl":"glibc"}(process.report?.getReport(),Ne),Ae}():void 0)){return"linux"===e&&"musl"===i?`${e}-${t}-musl`:`${e}-${t}`}function Ne(){try{return Ce("/proc/self/maps","utf8")}catch(e){if(e instanceof Error&&"code"in e)return;throw e}}function Ue(e=process.platform){return"win32"===e?`${_e}.exe`:_e}function De(e={}){let t=e.platform??process.platform,i=Le(t,e.arch,e.libc),r=function(e={}){let t=Le(e.platform,e.arch,e.libc),i=Ue(e.platform),r=e.packageDir??Me,n=e.execDir??Re(process.execPath),o=e.repoRoot??$e(r,"..",".."),s=$e("native","prebuilds",t,i),a=e.runtimeDir??process.env.OMO_PACKAGE_DIR;return[...a?[$e(a,s)]:[],$e(n,s),$e(r,s),$e(o,"target","release",i)]}(e),n=e.isQuarantined??(e=>je(e,t)),o=[],s=[];for(let e of r)if(Pe(e))if(n(e))s.push(e),o.push(`${e}: blocked because ${Ie} is present (macOS Gatekeeper)`);else{if(qe(e))return{path:e,diagnostic:null};o.push(`${e}: not executable (chmod +x)`)}else o.push(`${e}: missing`);let a=s.length>0?"quarantined":"native-unavailable";return{path:null,diagnostic:{code:a,host:i,attemptedPaths:r,message:"quarantined"===a?`The ${_e} binary for ${i} is quarantined by macOS Gatekeeper: ${s.join(", ")}.`:`No ${_e} binary is available for ${i}.`,cause:o.join("; ")}}}function je(e,t=process.platform){if("darwin"!==t)return!1;let i=Oe("/usr/bin/xattr",["-p",Ie,e],{stdio:["ignore","ignore","ignore"],timeout:2e3});return void 0===i.error&&0===i.status}function qe(e){try{return Ee(e,Se.X_OK),!0}catch(e){if(e instanceof Error&&"code"in e)return!1;throw e}}import{createHash as He,randomUUID as Fe}from"node:crypto";import{accessSync as Ve,chmodSync as We,constants as Je,existsSync as Be,mkdirSync as Ge,mkdtempSync as Ke,readFileSync as Xe,readdirSync as ze,renameSync as Ye,rmSync as Qe,writeFileSync as Ze}from"node:fs";import{homedir as et}from"node:os";import{join as tt}from"node:path";var it="senpi-desktop-engine-checksums.txt",rt=["darwin-arm64","darwin-x64","linux-x64","win32-x64"];function nt(e){switch(e){case"darwin-arm64":case"darwin-x64":case"linux-x64":return`senpi-desktop-engine-${e}`;case"win32-x64":return`senpi-desktop-engine-${e}.exe`;default:return null}}import{spawnSync as ot}from"node:child_process";function st(e){let t=ot("/usr/bin/codesign",["--verify","--strict",'-R=identifier "ai.sisyphuslabs.senpi-desktop-engine" and anchor apple generic and certificate leaf[subject.OU] = "523JNR86LZ" and certificate 1[field.1.2.840.113635.100.6.2.6] exists and certificate leaf[field.1.2.840.113635.100.6.1.13] exists',e],{stdio:"ignore",timeout:5e3});return void 0===t.error&&0===t.status}var at="-musl";async function ct(e){let{host:t,version:i}=e,r=[],n=e=>({path:null,diagnostic:{code:"native-unavailable",host:t,attemptedPaths:r,message:`No senpi-desktop-engine binary is available for ${t}.`,cause:e}});try{let o=t.indexOf("-");if(o<1||o===t.length-1)return n(`Invalid host: ${t}`);let s=t.slice(0,o),a=t.slice(o+1),c="linux"===s&&a.endsWith(at)?"musl":"glibc",l="musl"===c?a.slice(0,-5):a,d=De({...e.locatorOptions,platform:s,arch:l,libc:c});if(r=d.diagnostic?.attemptedPaths??[],null!==d.path){let r=e.locatorOptions?.runtimeDir??process.env.OMO_PACKAGE_DIR,o=r&&tt(r,"native","prebuilds",t,Ue(s));if("darwin"===s&&d.path===o&&r&&(e.isReleaseEngine??st)(d.path)){let e=JSON.parse(Xe(tt(r,"package.json"),"utf8"));return"object"==typeof e&&null!==e&&"omo"===Reflect.get(e,"name")&&Reflect.get(e,"version")===i?{path:d.path,sha256:He("sha256").update(Xe(d.path)).digest("hex")}:n("Extracted desktop engine does not belong to the requested omo release")}return{path:d.path}}if("quarantined"===d.diagnostic.code)return n(d.diagnostic.cause);let u=nt(t);if(null===u)return n(`No desktop engine release asset exists for ${t}.`);if(!/^[0-9]+\.[0-9]+\.[0-9]+(?:[-+][0-9A-Za-z.-]+)?$/.test(i))return n(`Invalid omo release version: ${i}`);let h=e.cacheDir??tt(et(),".omo","cache","senpi-desktop-engine"),p=tt(h,i,t);if(Be(p))for(let e of ze(p)){let t=/^([0-9a-f]{64})-[0-9a-f-]{36}$/.exec(e);if(null===t)continue;let i=tt(p,e,u);if(r=[...r,i],Be(i)&&He("sha256").update(Xe(i)).digest("hex")===t[1]&&!je(i,s))try{return Ve(i,Je.X_OK),{path:i,sha256:t[1]}}catch(e){if(!(e instanceof Error&&"code"in e))throw e}}if(!1===e.allowDownload)return n("No installed release engine");let m=e.fetch??globalThis.fetch,f=`https://github.com/code-yeongyu/oh-my-openagent/releases/download/v${i}`;r=[...r,tt(p,u)];let[g,y]=await Promise.all([m(`${f}/${u}`,{signal:AbortSignal.timeout(3e4)}),m(`${f}/${it}`,{signal:AbortSignal.timeout(3e4)})]);if(!g.ok)return n(`${u}: HTTP ${g.status}`);if(!y.ok)return n(`${it}: HTTP ${y.status}`);let b,w=(await y.text()).trimEnd().split(/\r?\n/),v=new Set;for(let e of w){let t=/^([a-fA-F0-9]{64}) ([A-Za-z0-9.-]+)$/.exec(e),i=t?.[2];if(void 0===i||!rt.some(e=>nt(e)===i))return n("Invalid desktop engine checksum entry or asset name");if(v.has(i))return n(`Duplicate SHA-256 checksum for ${i}`);v.add(i),i===u&&(b=t?.[1])}if(void 0===b)return n(`No SHA-256 checksum for ${u}`);let x=Buffer.from(await g.arrayBuffer()),k=He("sha256").update(x).digest("hex");if(k.toLowerCase()!==b.toLowerCase())return n(`SHA-256 mismatch for ${u}`);Ge(p,{recursive:!0});let O=Ke(tt(p,".download-")),E=tt(p,`${k}-${Fe()}`);try{let e=tt(O,u);Ze(e,x),We(e,493),Ye(O,E)}finally{Qe(O,{recursive:!0,force:!0})}return{path:tt(E,u),sha256:k}}catch(e){return n(e instanceof Error?e.message:String(e))}}async function lt(e,h,p=ct){let m=await p(e);if(null===m.path)return m;let f=e.isReleaseEngine??st;return e.host.startsWith("darwin-")&&void 0!==m.sha256&&f(m.path)?(await Promise.resolve().then(()=>{}),function(e,h,p){n(e.directory,{recursive:!0});let m=l(e.directory,"senpi-desktop-engine"),f=new d(l(e.directory,"launch.lock"));try{if(f.exec("PRAGMA busy_timeout = 30000"),f.exec("BEGIN EXCLUSIVE"),!r(m)||u(m)!==e.sha256){let r=l(e.directory,`.engine-${t()}`);try{if(c(r,o(e.path),{flag:"wx",mode:493}),i(r,493),u(r)!==e.sha256)throw Error("Desktop engine source SHA-256 changed");if(!p(r))throw Error("Desktop engine release signature verification failed");s(r,m)}finally{a(r,{force:!0})}}if(u(m)!==e.sha256)throw Error("Stable desktop engine SHA-256 mismatch");return c(l(e.directory,"release.json"),JSON.stringify({version:e.version,sha256:e.sha256})),{path:m,value:h(m)}}finally{f.close()}}({path:m.path,sha256:m.sha256,version:e.version,directory:tt(e.installDir??tt(et(),".omo","engines","senpi-desktop-engine"),e.host)},t=>je(t)?{path:null,diagnostic:{code:"quarantined",host:e.host,attemptedPaths:[t],message:"The stable desktop engine is quarantined by macOS Gatekeeper.",cause:`${t}: blocked because com.apple.quarantine is present`}}:{path:t,value:h(t)},f).value):{path:m.path,value:h(m.path)}}class dt extends Error{diagnostic;constructor(e){super(`${e.message} ${e.cause}`),this.name="DesktopEngineUnavailableError",this.diagnostic=e}}function ut(e){return()=>ht(e??function(){let e=De();if(null===e.path)throw new dt(e.diagnostic);return e.path}())}function ht(e){return ve(e,["--stdio"],{stdio:"pipe",windowsHide:!0})}class pt{path;exited;#l;#d="";#u="";#h=!0;constructor(e,t){this.#l=e,this.path=e.spawnfile,e.stderr.setEncoding("utf8"),e.stderr.on("data",e=>{this.#d=(this.#d+e).slice(-4096)}),e.stdin.on("error",e=>this.#p(`stdin: ${e.message}`)),e.on("error",e=>this.#p(`spawn: ${e.message}`)),xe({input:e.stdout}).on("line",t.onLine),this.exited=new Promise(i=>{e.on("close",(e,r)=>{this.#h=!1,t.onExit(this.#m(e,r)),i()})})}get alive(){return this.#h}write(e){this.#h&&!this.#l.stdin.writableEnded&&this.#l.stdin.write(`${JSON.stringify({jsonrpc:"2.0",...e})}\n`)}end(){this.#l.stdin.end()}kill(){this.#h&&(this.#h=!1,this.#l.kill())}#p(e){this.#u=""===this.#u?e:`${this.#u}; ${e}`}#m(e,t){return`desktop engine exited (code ${e??"null"}, signal ${t??"null"})${""===this.#u?"":`; ${this.#u}`}; stderr: ${this.#d.trim()||"<empty>"}`}}class mt extends Error{code;engineRestarted;constructor(e,t,i=!1){super(t),this.name="DesktopServiceError",this.code=e,this.engineRestarted=i}}class ft extends Error{method;rpcCode;data;constructor(e,t){super(t.message),this.name="DesktopEngineRpcError",this.method=e,this.rpcCode=t.code,this.data=function(e){if(!me(e))return null;let t=K.find(t=>t===e.code);if(void 0!==t)return{code:t,hint:"string"==typeof e.hint?e.hint:null};let i=de.find(t=>t===e.reason);return void 0===i?null:{reason:i}}(t.data)}}class gt{#f;#g;#y=new Map;#b=1;#m;constructor(e,t){this.#g=t,this.#f=new pt(e,{onLine:e=>this.#w(e),onExit:e=>this.#v(e)})}get enginePath(){return this.#f.path}get alive(){return void 0===this.#m&&this.#f.alive}get exited(){return this.#f.exited}request(e,t,i={}){if(!this.alive)return Promise.reject(new mt("Closed",this.#m??"desktop engine was killed"));if(i.signal?.aborted)return Promise.reject(new mt("Cancelled",`${e} was cancelled before it was sent`));let r=this.#b++,{promise:n,resolve:o,reject:s}=Promise.withResolvers(),a={method:e,resolve:o,reject:s,release:()=>{},cancelled:void 0};this.#y.set(r,a);let{signal:c,timeoutMs:l}=i,d=()=>this.#x(r,new mt("Cancelled",`${e} was cancelled`)),u=void 0===l?void 0:setTimeout(()=>this.#x(r,new mt("Timeout",`${e} timed out after ${l} ms`)),l);return c?.addEventListener("abort",d,{once:!0}),a.release=()=>{clearTimeout(u),c?.removeEventListener("abort",d)},this.#f.write({id:r,method:e,params:t}),n}end(){this.#f.end()}kill(){this.#f.kill()}#x(e,t){let i=this.#y.get(e);if(void 0===i||void 0!==i.cancelled)return;i.release(),i.cancelled=t;let r=setTimeout(()=>{this.#k(e),i.reject(new mt(t.code,`${t.message}; desktop engine restarted; captures and ax refs were reset`,!0)),this.#f.kill()},750);i.release=()=>clearTimeout(r),this.#f.write({method:"$/cancel",params:{id:e}})}#k(e){let t=this.#y.get(e);return this.#y.delete(e),t?.release(),t}#w(e){let t=function(e){try{return JSON.parse(e)}catch(e){if(e instanceof SyntaxError)return;throw e}}(e);if(!me(t))return this.#f.kill(),void(this.#m=`desktop engine wrote a non-protocol line ${JSON.stringify(e.slice(0,200))}`);if("string"==typeof t.method&&void 0===t.id)return void this.#g.onNotification(t.method,t.params);let i="number"==typeof t.id?this.#k(t.id):void 0;if(void 0===i)return;if(void 0!==i.cancelled)return void i.reject(i.cancelled);if("result"in t)return void i.resolve(t.result);let{error:r}=t;me(r)&&"number"==typeof r.code&&"string"==typeof r.message?i.reject(new ft(i.method,{code:r.code,message:r.message,data:r.data})):i.reject(new mt("Internal",`desktop engine sent a malformed reply to ${i.method}`))}#v(e){this.#m??=e;let t=new mt("Closed",this.#m);for(let e of[...this.#y.keys()])this.#k(e)?.reject(t);this.#g.onExit()}}var yt={id:"string",name:"string",x:"number",y:"number",width:"number",height:"number",scale:"number",pixelX:"number",pixelY:"number",pixelWidth:"number",pixelHeight:"number",isPrimary:"boolean"},bt={id:"string",title:"string",app:"string",pid:"number?",x:"number",y:"number",width:"number",height:"number",focused:"boolean",elevated:"boolean?"},wt={ref:"string",role:"string",nativeRole:"string",title:"string?",value:"string?",description:"string?",enabled:"boolean",focused:"boolean",x:"number?",y:"number?",width:"number?",height:"number?",childCount:"number"},vt={mode:"string",data:"string?",mimeType:"string?",artifactPath:"string?",width:"number",height:"number",sourceWidth:"number",sourceHeight:"number",scale:"number",target:"string",frameId:"string",note:"string?"},xt=e=>fe(e,yt),kt=e=>fe(e,bt),Ot=e=>fe(e,wt)&&(void 0===e.actions||null===e.actions||ge(e.actions)),Et=e=>fe(e,vt),St=e=>me(e)&&"string"==typeof e.text,Pt=e=>Array.isArray(e)&&e.every(e=>ge(e)&&2===e.length);function Ct(e){return t=>Array.isArray(t)&&t.every(e)}function Rt(e){return t=>null===t||e(t)}function $t(e,t,i){if(!i(t))throw new mt("Internal",`desktop engine sent a malformed ${e} result`);return t}function Tt(e={}){let{button:t,count:i,modifiers:r,delivery:n}=e;return{button:t,count:i,modifiers:r,deliveryMode:n}}function At(e){return"string"!=typeof e?e:e.split("+").map(e=>e.trim()).filter(e=>e.length>0)}class _t{#O;method;constructor(e,t,i){this.#O=t,this.method=se(e,i)}send(e,t,i){return this.method(e,async({call:e})=>{await e(t,i)})}screenshot(e){return this.method("screenshot",t=>async function(e,t,i={}){let{snapshot:r,output:n,screenshots:o}=e.context,s={maxWidth:r.captureMaxWidth,maxHeight:r.captureMaxHeight,maxBytes:r.captureMaxBytes},a=$t("capture",await e.call("capture",{target:t,caps:s}),Et),c=a.artifactPath??void 0;void 0!==c&&o.push({path:c,width:a.width,height:a.height,sourceWidth:a.sourceWidth,sourceHeight:a.sourceHeight,target:a.target}),!0!==i.silent&&(n.text(function(e){let t=`${e.width}x${e.height}`,i=e.width!==e.sourceWidth||e.height!==e.sourceHeight?` (scaled from ${e.sourceWidth}x${e.sourceHeight})`:"",r=e.artifactPath?` -> ${e.artifactPath}`:"";return`screenshot ${e.target} ${t}${i}${r}`}(a)),"artifact-only"!==a.mode&&a.data&&a.mimeType?n.image(a.data,a.mimeType):n.text(a.note??"screenshot is available only as the artifact above"));let{width:l,height:d,sourceWidth:u,sourceHeight:h,scale:p,frameId:m}=a;return{target:a.target,frameId:m,width:l,height:d,sourceWidth:u,sourceHeight:h,scale:p,...void 0===c?{}:{path:c}}}(t,this.#O,e))}click(e,t,i){return this.send("click","click",{target:this.#O,x:e,y:t,opts:Tt(i)})}doubleClick(e,t,i){let r=Tt({...i,count:2});return this.send("doubleClick","click",{target:this.#O,x:e,y:t,opts:r})}move(e,t){return this.send("move","moveMouse",{target:this.#O,x:e,y:t})}drag(e,t){let i=e.map(([e,t])=>({x:e,y:t}));return this.send("drag","drag",{target:this.#O,path:i,opts:Tt(t)})}scroll(e,t,i={}){let{dx:r=0,dy:n=0}=i;return this.send("scroll","scroll",{target:this.#O,x:e,y:t,dx:r,dy:n,opts:Tt(i)})}type(e,t){return this.send("type","typeText",{target:this.#O,text:e,opts:Tt(t)})}press(e,t){let i={target:this.#O,keys:At(e),opts:Tt(t)};return this.send("press","keyChord",i)}}class It extends _t{id;app;title;pid;bounds;focused;constructor(e,t){super(e,t.id,j),this.id=t.id,this.app=t.app,this.title=t.title,this.pid=t.pid??void 0,this.bounds={x:t.x,y:t.y,width:t.width,height:t.height},this.focused=t.focused}raise(){return this.send("raise","raiseWindow",{windowId:this.id})}ax(e){return this.method("ax",async({call:t})=>$t("ax.snapshot",await t("ax.snapshot",{target:this.id,opts:e}),St).text)}find(e){return this.method("find",async t=>$t("ax.query",await t.call("ax.query",{target:this.id,query:e}),Ct(Ot)).map(e=>new Lt(t,e)))}ref(e){return this.method("ref",t=>Mt(t,e))}}async function Mt(e,t){return new Lt(e,$t("ax.node",await e.call("ax.node",{ref:t}),Ot))}class Lt{ref;role;nativeRole;title;description;enabled;focused;childCount;#E;constructor(e,t){this.#E=se(e,q),this.ref=t.ref,this.role=t.role,this.nativeRole=t.nativeRole,this.title=t.title??void 0,this.description=t.description??void 0,this.enabled=t.enabled,this.focused=t.focused,this.childCount=t.childCount}#S(e,t,i){return this.#E(e,async({call:e})=>{await e(t,{ref:this.ref,...i})})}#P(e,t){return this.#E(e,async({call:e})=>t($t("ax.node",await e("ax.node",{ref:this.ref}),Ot)))}value(){return this.#P("value",e=>e.value??void 0)}setValue(e){return this.#S("setValue","ax.setValue",{value:e})}bounds(){return this.#P("bounds",({x:e,y:t,width:i,height:r})=>null==e||null==t||null==i||null==r?null:{x:e,y:t,width:i,height:r})}attributes(){return this.#E("attributes",async({call:e})=>Object.fromEntries($t("ax.attributes",await e("ax.attributes",{ref:this.ref}),Pt)))}actions(){return this.#P("actions",e=>e.actions??[])}perform(e){return this.#S("perform","ax.perform",{action:e})}press(){return this.#S("press","ax.perform",{action:"press"})}click(e){return this.#S("click","ax.click",{opts:Tt(e)})}focus(){return this.#S("focus","ax.focus",{})}parent(){return this.#E("parent",async e=>{let t=$t("ax.parent",await e.call("ax.parent",{ref:this.ref}),Rt(Ot));return null===t?null:new Lt(e,t)})}children(){return this.#E("children",async e=>$t("ax.children",await e.call("ax.children",{ref:this.ref}),Ct(Ot)).map(t=>new Lt(e,t)))}}function Nt(e,t={}){let i=t.app?.toLocaleLowerCase(),r=t.title?.toLocaleLowerCase();return(!i||e.app.toLocaleLowerCase().includes(i))&&(!r||e.title.toLocaleLowerCase().includes(r))}function Ut(e){let t=se(e,D),i=async({call:e})=>$t("windows",await e("windows",{}),Ct(kt)),r=async(t,i)=>{let r=$t(t,await e.call(t,i),Rt(Ot));return null===r?null:new Lt(e,r)},n=new _t(e,"desktop",D);return{capabilities:()=>t("capabilities",async({call:e})=>$t("capabilities",await e("capabilities",{}),we)),displays:()=>t("displays",async({call:e})=>$t("displays",await e("displays",{}),Ct(xt))),windows:e=>t("windows",async t=>(await i(t)).filter(t=>Nt(t,e))),window:r=>t("window",async t=>{let n=(await i(t)).filter(e=>"string"==typeof r?e.id===r:Nt(e,r)),[o,...s]=n;if(void 0===o)throw new ne("window",`no window matches ${JSON.stringify(r)}`);if(s.length>0){let e=n.map(e=>`${e.id} ${e.app} ${JSON.stringify(e.title)}`);throw new ne("window",`multiple windows match ${JSON.stringify(r)}:\n${e.join("\n")}`)}return new It(e,o)}),focusedWindow:()=>t("focusedWindow",async t=>{let r=(await i(t)).find(e=>e.focused);return void 0===r?null:new It(e,r)}),screenshot:n.screenshot.bind(n),click:n.click.bind(n),doubleClick:n.doubleClick.bind(n),move:n.move.bind(n),drag:n.drag.bind(n),scroll:n.scroll.bind(n),type:n.type.bind(n),press:n.press.bind(n),elementAt:(e,i)=>t("elementAt",()=>r("ax.elementAt",{target:"desktop",x:e,y:i})),focusedElement:()=>t("focusedElement",()=>r("ax.focused",{})),ref:e=>t("ref",t=>Mt(t,e)),clipboard:{read:()=>t("clipboard.read",async({call:e})=>$t("clipboard.read",await e("clipboard.read",{}),St).text),write:e=>t("clipboard.write",async({call:t})=>{await t("clipboard.write",{text:e})})}}}import{randomUUID as Dt}from"node:crypto";import{format as jt}from"node:util";import qt from"node:vm";function Ht(e,t){t.throwIfAborted();let{promise:i,resolve:r,reject:n}=Promise.withResolvers(),o=()=>{clearTimeout(s),n(t.reason)},s=setTimeout(()=>{t.removeEventListener("abort",o),r()},e);return t.addEventListener("abort",o,{once:!0}),i}function Ft(e,t){return async(i,r={})=>{if("number"==typeof i)return Ht(i,e);if("function"!=typeof i)throw new ne("wait","wait(...) expects milliseconds or a predicate function to poll");let n=Math.max(r.interval??100,10);return async function(e,t,i,r){let n=new AbortController,o=setTimeout(()=>n.abort(),i);try{for(;;){let o=await e();if(t.throwIfAborted(),o)return o;if(n.signal.aborted)throw new ne("wait",`wait(predicate) timed out after ${i} ms; the predicate never returned truthy`);await Ht(r,t)}}finally{clearTimeout(o)}}(()=>i(),e,function(e,t){let i=Math.max(1,e-1e3);return 0===t||t===Number.POSITIVE_INFINITY?i:void 0!==t&&Number.isFinite(t)&&t>0?Math.min(t,i):Math.min(3e4,i)}(t,r.timeout),n)}}var Vt="computer-run.js";function Wt(e){return me(e)&&"ERR_SCRIPT_EXECUTION_TIMEOUT"===e.code}function Jt(e){if(void 0!==e){try{return structuredClone(e)}catch(e){if(!(e instanceof DOMException))throw e}try{return JSON.parse(JSON.stringify(e)??"null")}catch(t){if(!(t instanceof TypeError))throw t;return String(e)}}}async function Bt(e,t){let{code:i,snapshot:r,timeoutMs:n}=e,o=Dt(),s=new AbortController,{signal:a}=s,c=Date.now()+n,l=e=>s.abort(e),d=()=>new ne("timeout",`computer run timed out after ${n} ms`),u=setTimeout(()=>l(d()),n),h=()=>l(new ne("aborted","computer run was aborted"));e.signal?.addEventListener("abort",h,{once:!0}),e.signal?.aborted&&h();let p=[],m=t.service.onAudit(e=>p.push(function(e,t,i){let{action:r,target:n,delivery:o,durationMs:s,focusRestored:a,textLength:c,textSha256:l,keys:d}=e,u=e.code??null;return{timestamp:(new Date).toISOString(),sessionId:t,runId:i,action:r,target:n,delivery:o,frameId:e.frameId??null,code:u,status:null===u?"success":"Suspended"===u?"suspended":"error",durationMs:s,...null==a?{}:{focusRestored:a},...null==c?{}:{textLength:c},...null==l?{}:{textSha256:l},...null==d?{}:{keys:d}}}(e,r.sessionId,o))),f={signal:a,readOnly:r.readOnly,snapshot:r,output:new oe,screenshots:[]},g=new qt.Script(""),y=()=>{if(!a.aborted)try{g.runInContext(x,{timeout:Math.max(1,c-Date.now())})}catch(e){l(Wt(e)?d():e)}},b=e=>{let t=()=>setImmediate(y);return e.then(t,t),e},w=Ft(a,n),v=(...e)=>f.output.text(jt(...e)),x=qt.createContext({desktop:Ut({context:f,call:(e,i)=>t.service.call(e,i,{signal:a}),resume:b}),wait:(e,t)=>b(w(e,t)),assert:(e,t)=>{if(!e)throw new ne("assertion",t??"Assertion failed")},tool:new Proxy({},{get:(e,i)=>e=>(a.throwIfAborted(),b(t.executeTool(String(i),e,{signal:a})))}),console:{log:v,info:v,warn:v,error:v,debug:v}},{name:Vt,microtaskMode:"afterEvaluate"});try{a.throwIfAborted();let e=new qt.Script(`(async () => {\n${i}\n})()`,{filename:Vt,lineOffset:-1}).runInContext(x,{timeout:n}),t=await new Promise((t,i)=>{a.addEventListener("abort",()=>i(a.reason),{once:!0}),a.throwIfAborted(),Promise.resolve(e).then(t,i),setImmediate(y)});return{displays:f.output.finish(),returnValue:Jt(t),screenshots:[...f.screenshots],audit:[...p]}}catch(e){throw Wt(e)?d():e}finally{clearTimeout(u),e.signal?.removeEventListener("abort",h),m(),a.aborted||s.abort(new ne("ended","computer run has ended"))}}class Gt extends Error{method;constructor(e,t){super(`desktop engine notification ${JSON.stringify(e)} ${t}`),this.name="DesktopNotificationError",this.method=e}}function Kt(e,t){return e.add(t),()=>{e.delete(t)}}class Xt{#C=new Set;#R=new Set;#$=new Set;onAudit(e){return Kt(this.#C,e)}onStopPathChange(e){return Kt(this.#R,e)}onError(e){return Kt(this.#$,e)}emitError(e){for(let t of this.#$)t(e)}dispatch(e,t){let i=G.find(t=>t===e);void 0!==i?this.#T(i,t):this.emitError(new Gt(e,"is not part of the engine protocol"))}#T(e,t){switch(e){case"audit":if(fe(i=t,pe)&&ye(i.action,ae)&&(void 0===i.code||null===i.code||ye(i.code,ce))&&(void 0===i.keys||null===i.keys||ge(i.keys)))for(let e of this.#C)e(t);else this.emitError(new Gt(e,"is malformed"));return;case"stopPath.changed":if(be(t))for(let e of this.#R)e(t);else this.emitError(new Gt(e,"is malformed"));return;case"engine.log":return;default:!function(e){throw Error(`unhandled engine notification ${JSON.stringify(e)}`)}(e)}var i}}class zt{#A;#_=new Xt;#I=Promise.resolve();#M;#L;#N;constructor(e={}){this.#A=e.createChild??ut(),this.#_.onStopPathChange(e=>{this.#N=e})}onAudit(e){return this.#_.onAudit(e)}onStopPathChange(e){return this.#_.onStopPathChange(e)}onError(e){return this.#_.onError(e)}open(e){return this.#U(async()=>{this.#L={params:e,chord:this.#L?.chord};let t=this.#M;return!0===t?.rpc.alive?this.#D(t,e):(void 0!==t&&this.#j(t),(await this.#q(this.#L)).capabilities)})}ensureStopPath(e){return this.#U(async()=>{let t=await this.#H();if(t.armedChord===e)return this.#R(t,"stopPath.status",{});let i=await this.#R(t,"stopPath.start",{chord:e});return t.armedChord=e,void 0!==this.#L&&(this.#L.chord=e),i})}async call(e,t,i={}){return(await this.#F()).rpc.request(e,t,i)}async capabilities(){let e=await this.call("capabilities",{},{timeoutMs:1e4});if(!we(e))throw Yt("capabilities");return e}async stopPathStatus(){return this.#R(await this.#F(),"stopPath.status",{})}async stop(){return this.#R(await this.#F(),"stopPath.stop",{source:"host-relay"})}async resume(){let e=await this.#F();return this.#R(e,"stopPath.resume",{token:e.resumeToken})}close(){return this.#U(async()=>{this.#L=void 0;let e=this.#M;if(void 0===e)return;if(this.#j(e),!e.rpc.alive)return;try{await Qt((async()=>{await e.rpc.request("session.close",{}),e.rpc.end(),await e.rpc.exited})(),1500,"Timed out closing desktop engine")}finally{e.rpc.kill()}})}#U(e){let t=this.#I.then(e);return this.#I=t.then(()=>{},()=>{}),t}#F(){let e=this.#M;return!0===e?.rpc.alive?Promise.resolve(e):this.#U(()=>this.#H())}async#H(){let e=this.#M;if(!0===e?.rpc.alive)return e;if(void 0!==e&&this.#j(e),void 0===this.#L)throw new mt("Closed","desktop session is not open");return(await this.#q(this.#L)).connection}async#q(e){let t=new gt(await this.#A(),{onNotification:(e,t)=>this.#_.dispatch(e,t),onExit:()=>{this.#M?.rpc===t&&this.#j(this.#M)}}),i={rpc:t,resumeToken:"",armedChord:void 0,heartbeat:void 0};try{let t=await Qt(this.#V(i,e),1e4,"Timed out starting desktop engine");return this.#M=i,i.heartbeat=setInterval(()=>this.#W(i),500),{connection:i,capabilities:t}}catch(e){throw t.kill(),e}}async#V(e,t){let i=function(e){if(me(e)&&"string"==typeof e.abi&&"string"==typeof e.protocolVersion)return{abi:e.abi,protocolVersion:e.protocolVersion}}(await e.rpc.request("engine.hello",{}));if(void 0===i)throw Yt("engine.hello");if(i.abi!==B||"1"!==i.protocolVersion)throw new ke(e.rpc.enginePath,i);let r=await this.#D(e,t.params);return void 0!==t.chord&&(await this.#R(e,"stopPath.start",{chord:t.chord}),e.armedChord=t.chord),!0===this.#N?.suspended&&await this.#R(e,"stopPath.stop",{source:"host-relay"}),r}async#D(e,t){let i=function(e){if(me(e)&&"string"==typeof e.resumeToken&&we(e.capabilities))return{capabilities:e.capabilities,resumeToken:e.resumeToken}}(await e.rpc.request("session.open",t,{timeoutMs:1e4}));if(void 0===i)throw Yt("session.open");return e.resumeToken=i.resumeToken,i.capabilities}async#R(e,t,i){let r=await e.rpc.request(t,i);if(!be(r))throw Yt(t);return this.#N=r,r}#W(e){e.rpc.request("stopPath.heartbeat",{}).catch(e=>{if(!(e instanceof mt&&"Closed"===e.code)){if(!(e instanceof mt||e instanceof ft))throw e;this.#_.emitError(e)}})}#j(e){clearInterval(e.heartbeat),this.#M===e&&(this.#M=void 0)}}function Yt(e){return new mt("Internal",`desktop engine sent a malformed ${e} result`)}function Qt(e,t,i){return new Promise((r,n)=>{let o=setTimeout(()=>n(new mt("Timeout",i)),t);e.then(e=>{clearTimeout(o),r(e)},e=>{clearTimeout(o),n(e)})})}import{Check as Zt}from"typebox/value";import{readFileSync as ei}from"node:fs";import{dirname as ti,join as ii}from"node:path";import{fileURLToPath as ri}from"node:url";var ni,oi=["COMPUTER_PRELUDE_JAVASCRIPT","COMPUTER_PRELUDE_PYTHON","COMPUTER_DECLARATIONS","COMPUTER_DOCUMENTATION","COMPUTER_SAFETY"],si=ii(ti(ri(import.meta.url)),"assets.generated.json");function ai(){if(void 0===ni){let e=JSON.parse(ei(si,"utf8"));ni=function(e){let t=e&&"object"==typeof e?e:void 0,i=oi.filter(e=>"string"!=typeof t?.[e]);if(i.length>0)throw Error(`senpi-desktop-prelude asset JSON is malformed at ${si}: missing ${i.join(", ")}`);return e}(e)}return ni}var ci={get javascript(){return ai().COMPUTER_PRELUDE_JAVASCRIPT},get python(){return ai().COMPUTER_PRELUDE_PYTHON},get declarations(){return ai().COMPUTER_DECLARATIONS},get documentation(){return ai().COMPUTER_DOCUMENTATION},get safety(){return ai().COMPUTER_SAFETY},exports:["computer"],methodAllowlist:["actions","attributes","ax","bounds","capabilities","children","click","clipboard.read","clipboard.write","displays","doubleClick","drag","elementAt","find","focus","focusedElement","focusedWindow","move","parent","perform","press","raise","ref","screenshot","scroll","setValue","type","value","window","windows"]},li={name:"computer",label:"Computer",description:["Drive the user's real desktop (experimental): windows, screenshots, native mouse and keyboard input, the OS accessibility (AX) tree, and the clipboard. Not a browser.",'- `{action:"call", chain}` runs one desktop helper, optionally followed by one call on the window/element it returns, e.g. `[{method:"window",args:[{app:"Code"}]},{method:"screenshot"}]`.','- `{action:"run", code, read_only?, timeout?}` runs a JavaScript async function body with `desktop`, `wait`, `assert`, and `tool` in scope; `read_only: true` blocks input.','- `{action:"capabilities"}` reports backend, permissions, `stopPath`, and `focusGuard`. `{action:"close"}` ends the desktop session.',"Pass only the fields of the chosen action; any other field is refused with COMPUTER_INVALID_ARGUMENTS.","In eval cells prefer the `computer` global, which wraps these actions. Pointer x,y are pixels of the latest screenshot of the same target."].join("\n"),exposure:"search",searchText:"Operate the real desktop (experimental): screenshots, clicks, typing, key chords, window list, accessibility tree, clipboard; macOS/Linux/Windows",searchKeywords:["computer use","computer-use","cua","desktop","gui","screenshot","click","type","keyboard","mouse","window","accessibility","ax","clipboard","automation"],searchGroup:"desktop",promptSnippet:"Operate the real desktop (experimental): screenshots, native input, accessibility tree, clipboard",promptGuidelines:ci.safety.split("\n").filter(e=>e.startsWith("- ")).map(e=>e.slice(2)),kernelPrelude:ci,parameters:re,executionMode:"sequential"},di=v(te);function ui(e){return"string"==typeof e?e:JSON.stringify(e,null,2)??String(e)}function hi(e,t){return{content:[{type:"text",text:void 0===e?t:ui(e)}],details:{value:e}}}async function pi(e,t,i,r){let{handle:n,executeTool:o}=e;await n.activate(t);let s=function(e,t,i){return{cwd:t.cwd,sessionId:t.sessionManager.getSessionId(),captureMaxWidth:e.maxWidth,captureMaxHeight:e.maxHeight,captureMaxBytes:e.screenshotMaxBytes,display:e.display,readOnly:i,stopHotkey:e.stopHotkey,allowHostRelayOnlyStop:e.allowHostRelayOnlyStop}}(n.settings(),t,i.readOnly),a=1e3*i.timeoutSeconds,c=await Bt({code:i.code,snapshot:s,timeoutMs:a,...void 0===r?{}:{signal:r}},{service:n.service,executeTool:o}),l=[...c.displays];return void 0!==c.returnValue&&l.push({type:"text",text:ui(c.returnValue)}),0===l.length&&l.push({type:"text",text:"Done."}),{content:l,details:{value:c.returnValue,readOnly:i.readOnly,screenshots:c.screenshots,audit:c.audit}}}function mi(e){let{handle:t}=e,i=(t,i,r)=>pi(e,t,i,r);return{...li,async execute(e,r,n,o,s){let a=function(e){if(Zt(ie,e))return e;throw x(di,e,"computer")}(r);switch(a.action){case"call":{let e=J(a.chain),t=function(e){let t=e=>`${e.method}(...${JSON.stringify(e.args??[])})`,[i,r]=e;if(void 0===i)throw TypeError("renderCallChain: empty chain");return void 0===r?`return await desktop.${t(i)};`:`return await (await desktop.${t(i)}).${t(r)};`}(a.chain);return i(s,{code:t,readOnly:e,timeoutSeconds:60},n)}case"run":{let e=a.timeout??60;return i(s,{code:a.code,readOnly:!0===a.read_only,timeoutSeconds:e},n)}case"capabilities":return await t.activate(s),hi(await t.service.capabilities(),"capabilities unavailable");case"close":return await t.close(),hi(void 0,"Closed the desktop session.");default:return function(e){throw TypeError(`unhandled computer action ${JSON.stringify(e)}`)}(a)}}}}function fi(e){let t=null;return{...X,async execute(i,r,n,o,s){let a,c=e.handle.settings().stopHotkey;try{a=function(e){if(O(A,e))return e;let t="object"==typeof e&&null!==e?Reflect.get(e,"actions"):void 0;if("batch"===Reflect.get(e??{},"action")&&Array.isArray(t)){let e=t.findIndex(e=>!O($,e));if(e>=0)throw x(L,t[e],`computer_actions actions[${e}]`)}throw x(N,e,"computer_actions")}(r)}catch(e){if(!(e instanceof w))throw e;let t=Y(e.code,e.reason,c);return{content:[{type:"text",text:t.message}],details:{value:t},isError:!0}}let l,d=Math.min(a.timeout??60,600),u=function(e){let t="batch"===e.action?e.actions:[e];return Array.isArray(t)&&t.length>0&&t.every(e=>"object"==typeof e&&null!==e&&U.has(String(Reflect.get(e,"action"))))}(a),h=function(e,t){return`const actions = ${JSON.stringify(e)};\nlet bounds = ${JSON.stringify(t)};\nconst steps = [];\nconst outside = (x, y) => bounds !== null && (x < 0 || y < 0 || x >= bounds.width || y >= bounds.height);\nconst shoot = async () => { const shot = await desktop.screenshot(); bounds = { width: shot.width, height: shot.height }; };\nfor (const [index, a] of actions.entries()) {\n\tconst points = a.action === "drag" ? [[a.x, a.y], [a.to_x, a.to_y]] : "x" in a ? [[a.x, a.y]] : [];\n\tconst off = points.find(([x, y]) => outside(x, y));\n\tif (off !== undefined) {\n\t\tconst message = a.action + " coordinates (" + off[0] + "," + off[1] + ") are outside the latest screenshot bounds " + bounds.width + "x" + bounds.height + ".";\n\t\tsteps.push({ index, action: a.action, status: "error", code: "COMPUTER_COORD_INVALID", message });\n\t\treturn { steps, bounds, failedIndex: index };\n\t}\n\ttry {\n\t\tconst button = a.button === undefined ? {} : { button: a.button };\n\t\tswitch (a.action) {\n\t\t\tcase "screenshot": await shoot(); break;\n\t\t\tcase "click": await desktop.click(a.x, a.y, button); break;\n\t\t\tcase "double_click": await desktop.doubleClick(a.x, a.y, button); break;\n\t\t\tcase "move": await desktop.move(a.x, a.y); break;\n\t\t\tcase "drag": await desktop.drag([[a.x, a.y], [a.to_x, a.to_y]], button); break;\n\t\t\tcase "scroll": await desktop.scroll(a.x, a.y, { dx: a.scroll_x, dy: a.scroll_y }); break;\n\t\t\tcase "type": await desktop.type(a.text); break;\n\t\t\tcase "keypress": await desktop.press(a.keys); break;\n\t\t\tcase "wait": await wait(a.ms); break;\n\t\t}\n\t\tif (a.include_screenshot === true && a.action !== "screenshot") await shoot();\n\t\tsteps.push({ index, action: a.action, status: "success" });\n\t} catch (error) {\n\t\tconst code = error?.data?.code ?? error?.reason ?? error?.name ?? "Error";\n\t\tsteps.push({ index, action: a.action, status: "error", code, message: String(error?.message ?? error) });\n\t\treturn { steps, bounds, failedIndex: index };\n\t}\n}\nreturn { steps, bounds, failedIndex: null };`}(function(e){return"batch"===e.action?e.actions:[e]}(a),t);try{l=await pi(e,s,{code:h,readOnly:u,timeoutSeconds:d},n)}catch(e){if(!(e instanceof Error))throw e;let t=Reflect.get(e,"reason")??Reflect.get(e,"code")??e.name,i=Y(String(t),e.message,c);return{content:[{type:"text",text:i.message}],details:{value:i},isError:!0}}let p=l.details.value;if("object"!=typeof(m=p)||null===m||!Array.isArray(Reflect.get(m,"steps")))return l;var m;t=p.bounds;let f=l.content.filter(e=>"image"===e.type),g=null===p.failedIndex?void 0:p.steps[p.failedIndex];if(void 0===g){let e=`${p.steps.length} action(s) done: ${p.steps.map(e=>e.action).join(", ")}.`;return{...l,content:[...f,{type:"text",text:e}]}}let y=Y(g.code??"Error",g.message??"action failed",c),b=`Action ${g.index+1} (${g.action}) failed. ${y.message}`;return{content:[...f,{type:"text",text:b}],details:{...l.details,value:{...p,failure:y}},isError:!0}}}}import{Type as gi}from"typebox";import{Check as yi,Errors as bi}from"typebox/value";gi.Object({enabled:gi.Optional(gi.Boolean({description:"Register the computer tool (experimental; default: host supported)"})),display:gi.Optional(gi.String({description:"`all` composites every display; otherwise a display id"})),maxWidth:gi.Optional(gi.Integer({minimum:1,default:3840})),maxHeight:gi.Optional(gi.Integer({minimum:1,default:2400})),screenshotMaxBytes:gi.Optional(gi.Integer({minimum:1,default:5e6})),stopHotkey:gi.Optional(gi.String({minLength:1,description:"Stop chord, e.g. ctrl+alt+shift+escape"})),allowHostRelayOnlyStop:gi.Optional(gi.Boolean({default:!1})),macosCanary:gi.Optional(gi.Union([gi.Literal("session"),gi.Literal("off")],{default:"session"})),auditLog:gi.Optional(gi.Object({enabled:gi.Optional(gi.Boolean({default:!0}))},{additionalProperties:!1})),screenshotGc:gi.Optional(gi.Object({enabled:gi.Optional(gi.Boolean({default:!0})),staleMs:gi.Optional(gi.Integer({minimum:0,default:432e5})),scanIntervalMs:gi.Optional(gi.Integer({minimum:0,default:18e5}))},{additionalProperties:!1})),enginePath:gi.Optional(gi.String({minLength:1,description:"Override the located engine binary"})),cuaAdapter:gi.Optional(gi.Boolean({default:!1,description:"Also register computer_actions (OpenAI computer-use actions)"}))},{additionalProperties:!1});import{accessSync as wi,constants as vi,existsSync as xi,readFileSync as ki}from"node:fs";import{dirname as Oi,join as Ei}from"node:path";function Si(e,t){let i;try{i=JSON.parse(ki(Ei(e,"package.json"),"utf8"))}catch{return}if("object"!=typeof i||null===i)return;let r=Reflect.get(i,"name"),n=Reflect.get(i,"version");return"string"==typeof r&&t.includes(r)&&"string"==typeof n&&n.length>0?n:void 0}function Pi(e=process.env){return t=>{if(void 0!==t)return function(e){let t=Le(),i=function(e,t){if(!xi(e))return{code:"native-unavailable",host:t,attemptedPaths:[e],message:`No senpi-desktop-engine binary is available for ${t}.`,cause:`${e}: missing`};if(je(e))return{code:"quarantined",host:t,attemptedPaths:[e],message:`The senpi-desktop-engine binary for ${t} is quarantined by macOS Gatekeeper.`,cause:`${e}: blocked because com.apple.quarantine is present`};try{return void wi(e,vi.X_OK)}catch{return{code:"native-unavailable",host:t,attemptedPaths:[e],message:`No senpi-desktop-engine binary is available for ${t}.`,cause:`${e}: not executable (chmod +x)`}}}(e,t);return void 0!==i?()=>{throw new dt(i)}:ut(e)}(t);let i=function(e){let t=e.OMO_PACKAGE_DIR?.trim();if(t){let e=Si(t,["omo"]);if(void 0!==e)return e}let i=e.OMO_BIN?.trim();return i?Si(Oi(Oi(i)),["omo-ai"]):void 0}(e);return void 0===i?ut():function(e){let t=e.acquire??ct,i=e.spawnEngine??ht;return async()=>{let r=await lt({version:e.version,host:e.host??Le()},i,t);if(null===r.path)throw new dt(r.diagnostic);return r.value}}({version:i})}}class Ci extends Error{diagnostic;constructor(e,t){super(`Desktop engine unavailable (${e}): ${t.message}`,{cause:t}),this.name="ComputerEngineUnavailableError",this.diagnostic=e}}class Ri extends zt{#J="not started";#B;constructor(e={}){super(e),this.#B=e.onError}get engineState(){return this.#J}async open(e){try{let t=await super.open(e);return this.#J="ready",t}catch(e){if(!(e instanceof Error))throw e;this.#B?.(e);let t=function(e){return e instanceof dt?e.diagnostic.code:e instanceof ke?"abi-mismatch":void 0}(e);if(void 0===t)throw e;throw this.#J=t,new Ci(t,e)}}async call(e,t,i={}){return this.#G(super.call(e,t,i))}ensureStopPath(e){return this.#G(super.ensureStopPath(e))}stopPathStatus(){return this.#G(super.stopPathStatus())}stop(){return this.#G(super.stop())}resume(){return this.#G(super.resume())}async#G(e){try{return await e}catch(e){if(!(e instanceof Error))throw e;throw this.#B?.(e),e}}}function $i(e){let t=e.engineChild??Pi(),i=new Ri({createChild:t(e.settings.enginePath),onError:t=>e.onEngineError(function(e){return e instanceof dt?e.diagnostic.code:e instanceof ke?"abi-mismatch":e instanceof ft?null!==e.data&&"code"in e.data?e.data.code:"other":e instanceof mt?e.code:"other"}(t))}),r=new y({service:i,settings:()=>e.settings}),n={handle:r,executeTool:e.executeTool};return{handle:r,service:i,computerTool:mi(n),computerActionsTool:fi(n)}}export{$i as createComputerUseRuntime};
1
+ // omo:hDi9G5VPsHwNZ4rHKbr8tYzOKiU4NAy5rZf4MOeNMOg:dSygQa-zwaYjXR-a9Zx0cnOtWFKvdwV4yihitaCen5M
2
+ import{createHash as e,randomUUID as t}from"node:crypto";import{chmodSync as i,existsSync as r,mkdirSync as n,readFileSync as o,renameSync as s,rmSync as a,writeFileSync as c}from"node:fs";import{join as l}from"node:path";import{DatabaseSync as d}from"node:sqlite";function u(t){return e("sha256").update(o(t)).digest("hex")}import{tmpdir as h}from"node:os";import{join as p}from"node:path";var m=Number.MAX_SAFE_INTEGER;function f(e){if(void 0===e)return!1;let{compat:t}=e;return"object"==typeof t&&null!==t&&"supportsImageDetailOriginal"in t&&!1===t.supportsImageDetailOriginal||("anthropic-messages"===e.api||"anthropic"===e.provider||/claude/i.test(e.id))}class g extends Error{constructor(){super("Computer use is off for this session; the user can turn it on with /computer on."),this.name="ComputerDisabledError"}}class y{#e;#t;#i=new Set;#r;#n;#o=!1;constructor(e){this.#e=e.service,this.#t=e.settings}get service(){return this.#e}settings(){return this.#t()}get enabled(){return this.#r??this.#t().enabled}get active(){return this.#o}get running(){return void 0!==this.#n}setEnabled(e){this.#r=e}onActivationChange(e){return this.#i.add(e),()=>this.#i.delete(e)}async activate(e){if(!this.enabled)throw new g;let t=this.#t();await this.#s(t,e);let i=await this.#e.ensureStopPath(t.stopHotkey);return this.#a(!0),i}async deactivate(){await this.close(),this.#a(!1)}async close(){this.#n=void 0,await this.#e.close()}async stopPathStatus(){return this.running?this.#e.stopPathStatus():void 0}async stop(){return this.running?this.#e.stop():void 0}async resume(){return this.running?this.#e.resume():void 0}async capabilities(){return this.running?this.#e.capabilities():void 0}async#s(e,t){let i=function(e,t){let{auditLog:i,screenshotGc:r}=e;return{display:e.display,macosCanary:e.macosCanary,allowHostRelayOnlyStop:e.allowHostRelayOnlyStop,auditPath:i.enabled?p(t.sessionManager.getSessionDir(),".computer-audit.jsonl"):null,artifactDir:h(),screenshotGc:{staleMs:r.enabled?r.staleMs:m,scanIntervalMs:r.scanIntervalMs},captureCaps:{maxWidth:e.maxWidth,maxHeight:e.maxHeight,coordinateSafe:f(t.model),maxBytes:e.screenshotMaxBytes}}}(e,t),r=JSON.stringify(i);this.#n?.key!==r&&(this.#n={key:r,done:this.#e.open(i)});let n=this.#n;try{await n.done}catch(e){throw this.#n===n&&(this.#n=void 0),e}}#a(e){if(this.#o!==e){this.#o=e;for(let t of this.#i)t(e)}}}import{Errors as b}from"typebox/value";class w extends Error{code="COMPUTER_INVALID_ARGUMENTS";reason;constructor(e){super(`COMPUTER_INVALID_ARGUMENTS: ${e}`),this.name="ComputerArgumentsError",this.reason=e}}function v(e){return new Map(e.map(e=>[String(Reflect.get(e.properties.action??{},"const")),e]))}function x(e,t,i){let r=[...e.keys()].join(", ");if("object"!=typeof t||null===t)return new w(`${i} must be an object`);let n=Reflect.get(t,"action");if("string"!=typeof n)return new w(`${i}: "action" must be one of ${r}`);let o=e.get(n);if(void 0===o)return new w(`${i}: unknown action "${n}"; expected one of ${r}`);let s=Object.keys(t).filter(e=>!(e in o.properties));if(s.length>0)return new w(`${i}: action "${n}" does not take ${s.join(", ")}`);let[a]=b(o,t),c=void 0===a||""===a.instancePath?"":` at ${a.instancePath}`;return new w(`${i}: action "${n}"${c}: ${a?.message??"invalid arguments"}`)}import{Type as k}from"typebox";import{Check as O}from"typebox/value";var E=k.Union([k.Literal("left"),k.Literal("right"),k.Literal("middle")]),S={timeout:k.Optional(k.Number({exclusiveMinimum:0,description:"Maximum time in seconds for this action."})),include_screenshot:k.Optional(k.Boolean({description:"Capture a screenshot after the action."}))},P={x:k.Number(),y:k.Number()},C={additionalProperties:!1},R=[k.Object({action:k.Literal("screenshot"),...S},C),k.Object({action:k.Literal("click"),...P,button:k.Optional(E),...S},C),k.Object({action:k.Literal("double_click"),...P,button:k.Optional(E),...S},C),k.Object({action:k.Literal("move"),...P,button:k.Optional(E),...S},C),k.Object({action:k.Literal("drag"),...P,to_x:k.Number(),to_y:k.Number(),button:k.Optional(E),...S},C),k.Object({action:k.Literal("scroll"),...P,scroll_x:k.Number(),scroll_y:k.Number(),...S},C),k.Object({action:k.Literal("type"),text:k.String(),...S},C),k.Object({action:k.Literal("keypress"),keys:k.Array(k.String(),{minItems:1}),...S},C),k.Object({action:k.Literal("wait"),ms:k.Integer({minimum:0}),...S},C)],$=k.Union([...R]),T=k.Object({action:k.Literal("batch"),actions:k.Array($,{minItems:1}),...S},C),_=k.Union([$,T]),A=["screenshot","click","double_click","move","drag","scroll","type","keypress","wait"],I={x:k.Optional(k.Number({description:"click, double_click, move, drag (start), scroll (required): x pixel"})),y:k.Optional(k.Number({description:"click, double_click, move, drag (start), scroll (required): y pixel"})),button:k.Optional(k.Enum(["left","right","middle"],{type:"string",description:"click, double_click, move, drag: mouse button (default left)"})),to_x:k.Optional(k.Number({description:"drag (required): end x pixel"})),to_y:k.Optional(k.Number({description:"drag (required): end y pixel"})),scroll_x:k.Optional(k.Number({description:"scroll (required): horizontal scroll distance in pixels on every OS (one wheel notch is about 40 px); positive scrolls right"})),scroll_y:k.Optional(k.Number({description:"scroll (required): vertical scroll distance in pixels on every OS (one wheel notch is about 40 px); positive moves the view toward the end of the content (down)"})),text:k.Optional(k.String({description:"type (required): text to type"})),keys:k.Optional(k.Array(k.String(),{minItems:1,description:"keypress (required): keys pressed together"})),ms:k.Optional(k.Integer({minimum:0,description:"wait (required): milliseconds"})),...S},M=k.Object({action:k.Enum([...A,"batch"],{type:"string",description:"The action to perform, or batch to run `actions` in order"}),actions:k.Optional(k.Array(k.Object({action:k.Enum([...A],{type:"string",description:"The action to perform"}),...I},C),{minItems:1,description:"batch (required): actions to execute in order"})),...I},C),L=v(R),N=v([...R,T]);var U=new Set(["screenshot","wait"]);class D extends Error{reason;constructor(e,t){super(t),this.name="ComputerRunError",this.reason=e}}class j{#c=[];text(e){this.#c.push({type:"text",text:e})}image(e,t){this.#c.push({type:"image",data:e,mimeType:t})}finish(){return[...this.#c]}}function q(e,t){return(i,r)=>e.resume(Promise.resolve().then(()=>(function(e,t,i){let r=Object.hasOwn(t,i)?t[i]:"exec";if(e.readOnly&&"exec"===r)throw new D("readOnly",`read-only run: '${i}' requires read_only: false`);e.signal.throwIfAborted()}(e.context,t,i),r(e))))}var H={capabilities:"read",displays:"read",windows:"read",window:"read",focusedWindow:"read",screenshot:"read",click:"exec",doubleClick:"exec",move:"exec",drag:"exec",scroll:"exec",type:"exec",press:"exec",elementAt:"read",focusedElement:"read",ref:"read","clipboard.read":"read","clipboard.write":"exec"},F={screenshot:"read",click:"exec",doubleClick:"exec",move:"exec",drag:"exec",scroll:"exec",type:"exec",press:"exec",raise:"exec",ax:"read",find:"read",ref:"read"},V={value:"read",setValue:"exec",bounds:"read",attributes:"read",actions:"read",perform:"exec",press:"exec",click:"exec",focus:"exec",parent:"read",children:"read"},W={window:{label:"window",methods:F},ref:{label:"element",methods:V}};class J extends Error{reason;constructor(e,t){super(t),this.name="ComputerCallError",this.reason=e}}function B(e,t){return Object.hasOwn(e,t)?e[t]:void 0}function G(e){return Object.keys(e).join(", ")}function K(e){return"read"===function(e){let[t,i,...r]=e;if(void 0===t)throw new J("empty","Action 'call' requires a non-empty 'chain'.");if(r.length>0)throw new J("tooLong","Call chains support one handle hop at most; use computer.run(fn) for longer sequences.");let n=B(H,t.method);if(void 0===n)throw new J("unknownMethod",`Unknown desktop method "${t.method}". Desktop helpers support: ${G(H)}.`);if(void 0===i)return n;let o=Object.hasOwn(W,t.method)?W[t.method]:void 0;if(void 0===o)throw new J("notChainable",`Only desktop.window(id)/desktop.ref(ref) results accept a chained call; got desktop.${t.method}().`);let s=B(o.methods,i.method);if(void 0===s)throw new J("unknownMethod",`Unknown ${o.label} method "${i.method}". Supported ${o.label} methods: ${G(o.methods)}.`);return s}(e)}var X="senpi-desktop/1",z=["audit","stopPath.changed","engine.log"],Y=["PermissionDenied","CaptureFailed","InputFailed","BackgroundUnavailable","WindowNotFound","InvalidTarget","InvalidKey","InvalidCoordinateFrame","StaleRef","AxUnsupported","AxFailed","Timeout","Closed","Internal","StopPathUnavailable","Suspended","ScreenLocked","Cancelled","CursorRestoreFailed","FocusRestoreFailed","TransactionFailed"],Q=new Set(["engine.hello","session.open","session.close","capabilities","displays","windows","capture","click","moveMouse","drag","scroll","typeText","keyChord","raiseWindow","clipboard.read","clipboard.write","ax.snapshot","ax.query","ax.elementAt","ax.focused","ax.node","ax.attributes","ax.children","ax.parent","ax.perform","ax.setValue","ax.focus","ax.click","stopPath.start","stopPath.status","stopPath.heartbeat","stopPath.stop","stopPath.resume","$/cancel","$/test.advanceClock"]),Z=new Set(Y),ee=new Set(["global","host-relay","none"]),te=["unknown","hostOnly","testOnly"],ie={suspended:"boolean",globalLive:"boolean",hostRelayLive:"boolean",heartbeatFresh:"boolean",stopPath:"string",reason:"string?"},re={backend:"string",displayServer:"string?",capture:"boolean",input:"boolean",ax:"boolean",backgroundWindowInput:"boolean",capturePermission:"string",inputPermission:"string",axPermission:"string",displayCount:"number",focusGuard:"boolean",stopPath:"string",stopReason:"string?",integrityLevel:"string?",screenLocked:"boolean"},ne={action:"string",target:"string",delivery:"string",frameId:"string?",code:"string?",durationMs:"number",focusRestored:"boolean?",textLength:"number?",textDelivered:"number?",textSha256:"string?"};function oe(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function se(e,t){return!!oe(e)&&Object.entries(t).every(([t,i])=>{let r=e[t];return i.endsWith("?")?null==r||typeof r===i.slice(0,-1):typeof r===i})}function ae(e){return Array.isArray(e)&&e.every(e=>"string"==typeof e)}function ce(e,t){return"string"==typeof e&&t.has(e)}function le(e){return se(e,ie)&&ce(e.stopPath,ee)}function de(e){return se(e,re)&&ae(e.deliveryModes)}function ue(e){if(!oe(e))return null;let t=Y.find(t=>t===e.code);if(void 0!==t){let i=function(e){if(!oe(e)||"screen_recording"!==e.permission&&"accessibility"!==e.permission||"string"!=typeof e.settingsUrl||"string"!=typeof e.app||"boolean"!=typeof e.relaunchRequired)return;return{permission:e.permission,settingsUrl:e.settingsUrl,app:e.app,relaunchRequired:e.relaunchRequired}}(e.permission);return{code:t,hint:"string"==typeof e.hint?e.hint:null,...void 0===i?{}:{permission:i}}}let i=te.find(t=>t===e.reason);return void 0===i?null:{reason:i}}import{spawn as he}from"node:child_process";import{createInterface as pe}from"node:readline";class me extends Error{code="abi-mismatch";enginePath;expected;actual;constructor(e,t){let i={abi:X,protocolVersion:"1"};super(`desktop engine ABI mismatch at ${e}: expected abi ${i.abi} protocol ${i.protocolVersion}, engine reported abi ${t.abi} protocol ${t.protocolVersion}`),this.name="DesktopEngineAbiMismatchError",this.enginePath=e,this.expected=i,this.actual=t}}import{spawnSync as fe}from"node:child_process";import{createHash as ge}from"node:crypto";import{accessSync as ye,constants as be,existsSync as we,readFileSync as ve,realpathSync as xe}from"node:fs";import{dirname as ke,join as Oe,sep as Ee}from"node:path";import{fileURLToPath as Se}from"node:url";var Pe="senpi-desktop-engine-checksums.txt",Ce=["darwin-arm64","darwin-x64","linux-x64","win32-x64"];function Re(e){switch(e){case"darwin-arm64":case"darwin-x64":case"linux-x64":return`senpi-desktop-engine-${e}`;case"win32-x64":return`senpi-desktop-engine-${e}.exe`;default:return null}}function $e(e){let t=new Map;for(let i of e.trimEnd().split(/\r?\n/)){let e=/^([a-fA-F0-9]{64}) ([A-Za-z0-9.-]+)$/.exec(i),r=e?.[2],n=e?.[1];if(void 0===r||void 0===n||!Ce.some(e=>Re(e)===r))return{checksums:null,error:"Invalid desktop engine checksum entry or asset name"};if(t.has(r))return{checksums:null,error:`Duplicate SHA-256 checksum for ${r}`};t.set(r,n)}return{checksums:t,error:null}}var Te,_e="senpi-desktop-engine",Ae="com.apple.quarantine",Ie=Oe(ke(Se(import.meta.url)),"..");function Me(e=process.platform,t=process.arch,i=("linux"===e&&e===process.platform?function(){return Te??=function(e,t){let i="object"==typeof e&&null!==e?Reflect.get(e,"header"):void 0,r="object"==typeof i&&null!==i?Reflect.get(i,"glibcVersionRuntime"):void 0;return"string"==typeof r&&r.length>0?"glibc":/\/ld-musl-[^/\s]+\.so\.1$/m.test(t()??"")?"musl":"glibc"}(process.report?.getReport(),Le),Te}():void 0)){return"linux"===e&&"musl"===i?`${e}-${t}-musl`:`${e}-${t}`}function Le(){try{return ve("/proc/self/maps","utf8")}catch(e){if(e instanceof Error&&"code"in e)return;throw e}}function Ne(e=process.platform){return"win32"===e?`${_e}.exe`:_e}function Ue(e={}){let t=Me(e.platform,e.arch,e.libc),i=Ne(e.platform),r=e.packageDir??Ie,n=e.execDir??ke(process.execPath),o=e.repoRoot??Oe(r,"..",".."),s=Oe("native","prebuilds",t,i),a=e.runtimeDir??process.env.OMO_PACKAGE_DIR;return[...a?[Oe(a,s)]:[],Oe(n,s),Oe(r,s),Oe(o,"target","release",i)]}function De(e={}){let t=e.platform??process.platform,i=Me(t,e.arch,e.libc),r=Ue(e),n=e.execDir??ke(process.execPath),o=e.runtimeDir??process.env.OMO_PACKAGE_DIR?1:0,s=e.isQuarantined??(e=>qe(e,t)),a=[],c=[];for(let[e,t]of r.entries())if(we(t)){if(s(t)){if(e!==o||!je(t,n,i)){c.push(t),a.push(`${t}: blocked because ${Ae} is present (macOS Gatekeeper)`);continue}a.push(`${t}: quarantined; accepted: inside the launcher's install and matching native/prebuilds/senpi-desktop-engine-checksums.txt`)}if(He(t))return{path:t,diagnostic:null};a.push(`${t}: not executable (chmod +x)`)}else a.push(`${t}: missing`);let l=c.length>0?"quarantined":"native-unavailable",d=a.every(e=>e.endsWith(": missing"))&&null===Re(i)?"no-release-asset":void 0;return{path:null,diagnostic:{code:l,host:i,attemptedPaths:r,message:"quarantined"===l?`The ${_e} binary for ${i} is quarantined by macOS Gatekeeper: ${c.join(", ")}.`:"no-release-asset"===d?`No senpi-desktop-engine is built for ${i}; computer use is unavailable on this host.`:`No ${_e} binary is available for ${i}.`,cause:a.join("; "),...void 0===d?{}:{reason:d}}}}function je(e,t,i){try{let r=`${Oe(xe(t),"native","prebuilds")}${Ee}`;if(!xe(e).startsWith(r))return!1;let n=Re(i);if(null===n)return!1;let o=$e(ve(Oe(t,"native","prebuilds",Pe),"utf8"));if(null!==o.error)return!1;let s=o.checksums.get(n);return void 0!==s&&ge("sha256").update(ve(e)).digest("hex")===s.toLowerCase()}catch(e){if(e instanceof Error&&"code"in e)return!1;throw e}}function qe(e,t=process.platform){if("darwin"!==t)return!1;let i=fe("/usr/bin/xattr",["-p",Ae,e],{stdio:["ignore","ignore","ignore"],timeout:2e3});return void 0===i.error&&0===i.status}function He(e){try{return ye(e,be.X_OK),!0}catch(e){if(e instanceof Error&&"code"in e)return!1;throw e}}import{createHash as Fe,randomUUID as Ve}from"node:crypto";import{accessSync as We,chmodSync as Je,constants as Be,existsSync as Ge,mkdirSync as Ke,mkdtempSync as Xe,readFileSync as ze,readdirSync as Ye,renameSync as Qe,rmSync as Ze,writeFileSync as et}from"node:fs";import{homedir as tt}from"node:os";import{join as it}from"node:path";import{spawnSync as rt}from"node:child_process";function nt(e){let t=rt("/usr/bin/codesign",["--verify","--strict",'-R=identifier "ai.sisyphuslabs.senpi-desktop-engine" and anchor apple generic and certificate leaf[subject.OU] = "523JNR86LZ" and certificate 1[field.1.2.840.113635.100.6.2.6] exists and certificate leaf[field.1.2.840.113635.100.6.1.13] exists',e],{stdio:"ignore",timeout:5e3});return void 0===t.error&&0===t.status}var ot="-musl";function st(e,t){let{host:i,version:r}=e,n=Re(i),o=[];if(null===n)return{path:null,attemptedPaths:o};let s=i.slice(0,i.indexOf("-")),a=e.cacheDir??it(tt(),".omo","cache","senpi-desktop-engine"),c=it(a,r,i);if(Ge(c))for(let e of Ye(c)){let i=/^([0-9a-f]{64})-[0-9a-f-]{36}$/.exec(e);if(null===i)continue;let r=it(c,e,n);if(o=[...o,r],t?.(r),Ge(r)&&Fe("sha256").update(ze(r)).digest("hex")===i[1]&&!qe(r,s))try{return We(r,Be.X_OK),{path:r,sha256:i[1]}}catch(e){if(!(e instanceof Error&&"code"in e))throw e}}return{path:null,attemptedPaths:o}}async function at(e){let{host:t,version:i}=e,r=[],n=e=>({path:null,diagnostic:{code:"native-unavailable",host:t,attemptedPaths:r,message:`No senpi-desktop-engine binary is available for ${t}.`,cause:e}});try{let o=t.indexOf("-");if(o<1||o===t.length-1)return n(`Invalid host: ${t}`);let s=t.slice(0,o),a=t.slice(o+1),c="linux"===s&&a.endsWith(ot)?"musl":"glibc",l="musl"===c?a.slice(0,-5):a,d=De({...e.locatorOptions,platform:s,arch:l,libc:c});if(r=d.diagnostic?.attemptedPaths??[],null!==d.path){let r=e.locatorOptions?.runtimeDir??process.env.OMO_PACKAGE_DIR,o=r&&it(r,"native","prebuilds",t,Ne(s));if("darwin"===s&&d.path===o&&r&&(e.isReleaseEngine??nt)(d.path)){let e=JSON.parse(ze(it(r,"package.json"),"utf8"));return"object"==typeof e&&null!==e&&"omo"===Reflect.get(e,"name")&&Reflect.get(e,"version")===i?{path:d.path,sha256:Fe("sha256").update(ze(d.path)).digest("hex")}:n("Extracted desktop engine does not belong to the requested omo release")}return{path:d.path}}if("quarantined"===d.diagnostic.code)return n(d.diagnostic.cause);let u=Re(t);if(null===u)return{path:null,diagnostic:{...d.diagnostic,reason:"no-release-asset",message:`No senpi-desktop-engine is built for ${t}; computer use is unavailable on this host.`}};if(!/^[0-9]+\.[0-9]+\.[0-9]+(?:[-+][0-9A-Za-z.-]+)?$/.test(i))return n(`Invalid omo release version: ${i}`);let h=e.cacheDir??it(tt(),".omo","cache","senpi-desktop-engine"),p=it(h,i,t),m=st(e,e=>{r=[...r,e]});if(null!==m.path)return m;if(!1===e.allowDownload)return n("No installed release engine");let f=e.fetch??globalThis.fetch,g=`https://github.com/code-yeongyu/oh-my-openagent/releases/download/v${i}`;r=[...r,it(p,u)];let[y,b]=await Promise.all([f(`${g}/${u}`,{signal:AbortSignal.timeout(3e4)}),f(`${g}/${Pe}`,{signal:AbortSignal.timeout(3e4)})]);if(!y.ok)return n(`${u}: HTTP ${y.status}`);if(!b.ok)return n(`${Pe}: HTTP ${b.status}`);let w=$e(await b.text());if(null!==w.error)return n(w.error);let v=w.checksums.get(u);if(void 0===v)return n(`No SHA-256 checksum for ${u}`);let x=Buffer.from(await y.arrayBuffer()),k=Fe("sha256").update(x).digest("hex");if(k.toLowerCase()!==v.toLowerCase())return n(`SHA-256 mismatch for ${u}`);Ke(p,{recursive:!0});let O=Xe(it(p,".download-")),E=it(p,`${k}-${Ve()}`);try{let e=it(O,u);et(e,x),Je(e,493),Qe(O,E)}finally{Ze(O,{recursive:!0,force:!0})}return{path:it(E,u),sha256:k}}catch(e){return n(e instanceof Error?e.message:String(e))}}async function ct(e,h,p=at){let m=await p(e);if(null===m.path)return m;let f=e.isReleaseEngine??nt;return e.host.startsWith("darwin-")&&void 0!==m.sha256&&f(m.path)?(await Promise.resolve().then(()=>{}),function(e,h,p){n(e.directory,{recursive:!0});let m=l(e.directory,"senpi-desktop-engine"),f=new d(l(e.directory,"launch.lock"));try{if(f.exec("PRAGMA busy_timeout = 30000"),f.exec("BEGIN EXCLUSIVE"),!r(m)||u(m)!==e.sha256){let r=l(e.directory,`.engine-${t()}`);try{if(c(r,o(e.path),{flag:"wx",mode:493}),i(r,493),u(r)!==e.sha256)throw Error("Desktop engine source SHA-256 changed");if(!p(r))throw Error("Desktop engine release signature verification failed");s(r,m)}finally{a(r,{force:!0})}}if(u(m)!==e.sha256)throw Error("Stable desktop engine SHA-256 mismatch");return c(l(e.directory,"release.json"),JSON.stringify({version:e.version,sha256:e.sha256})),{path:m,value:h(m)}}finally{f.close()}}({path:m.path,sha256:m.sha256,version:e.version,directory:it(e.installDir??it(tt(),".omo","engines","senpi-desktop-engine"),e.host)},t=>qe(t)?{path:null,diagnostic:{code:"quarantined",host:e.host,attemptedPaths:[t],message:"The stable desktop engine is quarantined by macOS Gatekeeper.",cause:`${t}: blocked because com.apple.quarantine is present`}}:{path:t,value:h(t)},f).value):{path:m.path,value:h(m.path)}}class lt extends Error{diagnostic;constructor(e){super(`${e.message} ${e.cause}`),this.name="DesktopEngineUnavailableError",this.diagnostic=e}}function dt(e){return()=>ut(e??function(){let e=De();if(null===e.path)throw new lt(e.diagnostic);return e.path}())}function ut(e){return he(e,["--stdio"],{stdio:"pipe",windowsHide:!0})}class ht{path;exited;#l;#d="";#u="";#h=!0;constructor(e,t){this.#l=e,this.path=e.spawnfile,e.stderr.setEncoding("utf8"),e.stderr.on("data",e=>{this.#d=(this.#d+e).slice(-4096)}),e.stdin.on("error",e=>this.#p(`stdin: ${e.message}`)),e.on("error",e=>this.#p(`spawn: ${e.message}`)),pe({input:e.stdout}).on("line",t.onLine),this.exited=new Promise(i=>{e.on("close",(e,r)=>{this.#h=!1,t.onExit(this.#m(e,r)),i()})})}get alive(){return this.#h}write(e){this.#h&&!this.#l.stdin.writableEnded&&this.#l.stdin.write(`${JSON.stringify({jsonrpc:"2.0",...e})}\n`)}end(){this.#l.stdin.end()}kill(){this.#h&&(this.#h=!1,this.#l.kill())}#p(e){this.#u=""===this.#u?e:`${this.#u}; ${e}`}#m(e,t){return`desktop engine exited (code ${e??"null"}, signal ${t??"null"})${""===this.#u?"":`; ${this.#u}`}; stderr: ${this.#d.trim()||"<empty>"}`}}class pt extends Error{code;engineRestarted;constructor(e,t,i=!1){super(t),this.name="DesktopServiceError",this.code=e,this.engineRestarted=i}}class mt extends Error{method;rpcCode;data;constructor(e,t){super(t.message),this.name="DesktopEngineRpcError",this.method=e,this.rpcCode=t.code,this.data=ue(t.data)}}class ft{#f;#g;#y=new Map;#b=1;#m;constructor(e,t){this.#g=t,this.#f=new ht(e,{onLine:e=>this.#w(e),onExit:e=>this.#v(e)})}get enginePath(){return this.#f.path}get alive(){return void 0===this.#m&&this.#f.alive}get exited(){return this.#f.exited}request(e,t,i={}){if(!this.alive)return Promise.reject(new pt("Closed",this.#m??"desktop engine was killed"));if(i.signal?.aborted)return Promise.reject(new pt("Cancelled",`${e} was cancelled before it was sent`));let r=this.#b++,{promise:n,resolve:o,reject:s}=Promise.withResolvers(),a={method:e,resolve:o,reject:s,release:()=>{},cancelled:void 0};this.#y.set(r,a);let{signal:c,timeoutMs:l}=i,d=()=>this.#x(r,new pt("Cancelled",`${e} was cancelled`)),u=void 0===l?void 0:setTimeout(()=>this.#x(r,new pt("Timeout",`${e} timed out after ${l} ms`)),l);return c?.addEventListener("abort",d,{once:!0}),a.release=()=>{clearTimeout(u),c?.removeEventListener("abort",d)},this.#f.write({id:r,method:e,params:t}),n}end(){this.#f.end()}kill(){this.#f.kill()}#x(e,t){let i=this.#y.get(e);if(void 0===i||void 0!==i.cancelled)return;i.release(),i.cancelled=t;let r=setTimeout(()=>{this.#k(e),i.reject(new pt(t.code,`${t.message}; desktop engine restarted; captures and ax refs were reset`,!0)),this.#f.kill()},750);i.release=()=>clearTimeout(r),this.#f.write({method:"$/cancel",params:{id:e}})}#k(e){let t=this.#y.get(e);return this.#y.delete(e),t?.release(),t}#w(e){let t=function(e){try{return JSON.parse(e)}catch(e){if(e instanceof SyntaxError)return;throw e}}(e);if(!oe(t))return this.#f.kill(),void(this.#m=`desktop engine wrote a non-protocol line ${JSON.stringify(e.slice(0,200))}`);if("string"==typeof t.method&&void 0===t.id)return void this.#g.onNotification(t.method,t.params);let i="number"==typeof t.id?this.#k(t.id):void 0;if(void 0===i)return;if(void 0!==i.cancelled)return void i.reject(i.cancelled);if("result"in t)return void i.resolve(t.result);let{error:r}=t;oe(r)&&"number"==typeof r.code&&"string"==typeof r.message?i.reject(new mt(i.method,{code:r.code,message:r.message,data:r.data})):i.reject(new pt("Internal",`desktop engine sent a malformed reply to ${i.method}`))}#v(e){this.#m??=e;let t=new pt("Closed",this.#m);for(let e of[...this.#y.keys()])this.#k(e)?.reject(t);this.#g.onExit()}}var gt={id:"string",name:"string",x:"number",y:"number",width:"number",height:"number",scale:"number",pixelX:"number",pixelY:"number",pixelWidth:"number",pixelHeight:"number",isPrimary:"boolean"},yt={id:"string",title:"string",app:"string",pid:"number?",x:"number",y:"number",width:"number",height:"number",focused:"boolean",elevated:"boolean?"},bt={ref:"string",role:"string",nativeRole:"string",title:"string?",value:"string?",description:"string?",enabled:"boolean",focused:"boolean",x:"number?",y:"number?",width:"number?",height:"number?",childCount:"number"},wt={mode:"string",data:"string?",mimeType:"string?",artifactPath:"string?",width:"number",height:"number",sourceWidth:"number",sourceHeight:"number",scale:"number",target:"string",frameId:"string",note:"string?"},vt=e=>se(e,gt),xt=e=>se(e,yt),kt=e=>se(e,bt)&&(void 0===e.actions||null===e.actions||ae(e.actions)),Ot=e=>se(e,wt),Et=e=>oe(e)&&"string"==typeof e.text,St=e=>Array.isArray(e)&&e.every(e=>ae(e)&&2===e.length);function Pt(e){return t=>Array.isArray(t)&&t.every(e)}function Ct(e){return t=>null===t||e(t)}function Rt(e,t,i){if(!i(t))throw new pt("Internal",`desktop engine sent a malformed ${e} result`);return t}function $t(e={}){let{button:t,count:i,modifiers:r,delivery:n}=e;return{button:t,count:i,modifiers:r,deliveryMode:n}}function Tt(e){return"string"!=typeof e?e:e.split("+").map(e=>e.trim()).filter(e=>e.length>0)}class _t{#O;method;constructor(e,t,i){this.#O=t,this.method=q(e,i)}send(e,t,i){return this.method(e,async({call:e})=>{await e(t,i)})}screenshot(e){return this.method("screenshot",t=>async function(e,t,i={}){let{snapshot:r,output:n,screenshots:o}=e.context,s={maxWidth:r.captureMaxWidth,maxHeight:r.captureMaxHeight,maxBytes:r.captureMaxBytes},a=Rt("capture",await e.call("capture",{target:t,caps:s}),Ot),c=a.artifactPath??void 0;void 0!==c&&o.push({path:c,width:a.width,height:a.height,sourceWidth:a.sourceWidth,sourceHeight:a.sourceHeight,target:a.target}),!0!==i.silent&&(n.text(function(e){let t=`${e.width}x${e.height}`,i=e.width!==e.sourceWidth||e.height!==e.sourceHeight?` (scaled from ${e.sourceWidth}x${e.sourceHeight})`:"",r=e.artifactPath?` -> ${e.artifactPath}`:"";return`screenshot ${e.target} ${t}${i}${r}`}(a)),"artifact-only"!==a.mode&&a.data&&a.mimeType?n.image(a.data,a.mimeType):n.text(a.note??"screenshot is available only as the artifact above"));let{width:l,height:d,sourceWidth:u,sourceHeight:h,scale:p,frameId:m}=a;return{target:a.target,frameId:m,width:l,height:d,sourceWidth:u,sourceHeight:h,scale:p,...void 0===c?{}:{path:c}}}(t,this.#O,e))}click(e,t,i){return this.send("click","click",{target:this.#O,x:e,y:t,opts:$t(i)})}doubleClick(e,t,i){let r=$t({...i,count:2});return this.send("doubleClick","click",{target:this.#O,x:e,y:t,opts:r})}move(e,t){return this.send("move","moveMouse",{target:this.#O,x:e,y:t})}drag(e,t){let i=e.map(([e,t])=>({x:e,y:t}));return this.send("drag","drag",{target:this.#O,path:i,opts:$t(t)})}scroll(e,t,i={}){let{dx:r=0,dy:n=0}=i;return this.send("scroll","scroll",{target:this.#O,x:e,y:t,dx:r,dy:n,opts:$t(i)})}type(e,t){return this.send("type","typeText",{target:this.#O,text:e,opts:$t(t)})}press(e,t){let i={target:this.#O,keys:Tt(e),opts:$t(t)};return this.send("press","keyChord",i)}}class At extends _t{id;app;title;pid;bounds;focused;constructor(e,t){super(e,t.id,F),this.id=t.id,this.app=t.app,this.title=t.title,this.pid=t.pid??void 0,this.bounds={x:t.x,y:t.y,width:t.width,height:t.height},this.focused=t.focused}raise(){return this.send("raise","raiseWindow",{windowId:this.id})}ax(e){return this.method("ax",async({call:t})=>Rt("ax.snapshot",await t("ax.snapshot",{target:this.id,opts:e}),Et).text)}find(e){return this.method("find",async t=>Rt("ax.query",await t.call("ax.query",{target:this.id,query:e}),Pt(kt)).map(e=>new Mt(t,e)))}ref(e){return this.method("ref",t=>It(t,e))}}async function It(e,t){return new Mt(e,Rt("ax.node",await e.call("ax.node",{ref:t}),kt))}class Mt{ref;role;nativeRole;title;description;enabled;focused;childCount;#E;constructor(e,t){this.#E=q(e,V),this.ref=t.ref,this.role=t.role,this.nativeRole=t.nativeRole,this.title=t.title??void 0,this.description=t.description??void 0,this.enabled=t.enabled,this.focused=t.focused,this.childCount=t.childCount}#S(e,t,i){return this.#E(e,async({call:e})=>{await e(t,{ref:this.ref,...i})})}#P(e,t){return this.#E(e,async({call:e})=>t(Rt("ax.node",await e("ax.node",{ref:this.ref}),kt)))}value(){return this.#P("value",e=>e.value??void 0)}setValue(e){return this.#S("setValue","ax.setValue",{value:e})}bounds(){return this.#P("bounds",({x:e,y:t,width:i,height:r})=>null==e||null==t||null==i||null==r?null:{x:e,y:t,width:i,height:r})}attributes(){return this.#E("attributes",async({call:e})=>Object.fromEntries(Rt("ax.attributes",await e("ax.attributes",{ref:this.ref}),St)))}actions(){return this.#P("actions",e=>e.actions??[])}perform(e){return this.#S("perform","ax.perform",{action:e})}press(){return this.#S("press","ax.perform",{action:"press"})}click(e){return this.#S("click","ax.click",{opts:$t(e)})}focus(){return this.#S("focus","ax.focus",{})}parent(){return this.#E("parent",async e=>{let t=Rt("ax.parent",await e.call("ax.parent",{ref:this.ref}),Ct(kt));return null===t?null:new Mt(e,t)})}children(){return this.#E("children",async e=>Rt("ax.children",await e.call("ax.children",{ref:this.ref}),Pt(kt)).map(t=>new Mt(e,t)))}}function Lt(e,t={}){let i=t.app?.toLocaleLowerCase(),r=t.title?.toLocaleLowerCase();return(!i||e.app.toLocaleLowerCase().includes(i))&&(!r||e.title.toLocaleLowerCase().includes(r))}function Nt(e){let t=q(e,H),i=async({call:e})=>Rt("windows",await e("windows",{}),Pt(xt)),r=async(t,i)=>{let r=Rt(t,await e.call(t,i),Ct(kt));return null===r?null:new Mt(e,r)},n=new _t(e,"desktop",H);return{capabilities:()=>t("capabilities",async({call:e})=>Rt("capabilities",await e("capabilities",{}),de)),displays:()=>t("displays",async({call:e})=>Rt("displays",await e("displays",{}),Pt(vt))),windows:e=>t("windows",async t=>(await i(t)).filter(t=>Lt(t,e))),window:r=>t("window",async t=>{let n=(await i(t)).filter(e=>"string"==typeof r?e.id===r:Lt(e,r)),[o,...s]=n;if(void 0===o)throw new D("window",`no window matches ${JSON.stringify(r)}`);if(s.length>0){let e=n.map(e=>`${e.id} ${e.app} ${JSON.stringify(e.title)}`);throw new D("window",`multiple windows match ${JSON.stringify(r)}:\n${e.join("\n")}`)}return new At(e,o)}),focusedWindow:()=>t("focusedWindow",async t=>{let r=(await i(t)).find(e=>e.focused);return void 0===r?null:new At(e,r)}),screenshot:n.screenshot.bind(n),click:n.click.bind(n),doubleClick:n.doubleClick.bind(n),move:n.move.bind(n),drag:n.drag.bind(n),scroll:n.scroll.bind(n),type:n.type.bind(n),press:n.press.bind(n),elementAt:(e,i)=>t("elementAt",()=>r("ax.elementAt",{target:"desktop",x:e,y:i})),focusedElement:()=>t("focusedElement",()=>r("ax.focused",{})),ref:e=>t("ref",t=>It(t,e)),clipboard:{read:()=>t("clipboard.read",async({call:e})=>Rt("clipboard.read",await e("clipboard.read",{}),Et).text),write:e=>t("clipboard.write",async({call:t})=>{await t("clipboard.write",{text:e})})}}}import{randomUUID as Ut}from"node:crypto";import{format as Dt}from"node:util";import jt from"node:vm";function qt(e,t){t.throwIfAborted();let{promise:i,resolve:r,reject:n}=Promise.withResolvers(),o=()=>{clearTimeout(s),n(t.reason)},s=setTimeout(()=>{t.removeEventListener("abort",o),r()},e);return t.addEventListener("abort",o,{once:!0}),i}function Ht(e,t){return async(i,r={})=>{if("number"==typeof i)return qt(i,e);if("function"!=typeof i)throw new D("wait","wait(...) expects milliseconds or a predicate function to poll");let n=Math.max(r.interval??100,10);return async function(e,t,i,r){let n=new AbortController,o=setTimeout(()=>n.abort(),i);try{for(;;){let o=await e();if(t.throwIfAborted(),o)return o;if(n.signal.aborted)throw new D("wait",`wait(predicate) timed out after ${i} ms; the predicate never returned truthy`);await qt(r,t)}}finally{clearTimeout(o)}}(()=>i(),e,function(e,t){let i=Math.max(1,e-1e3);return 0===t||t===Number.POSITIVE_INFINITY?i:void 0!==t&&Number.isFinite(t)&&t>0?Math.min(t,i):Math.min(3e4,i)}(t,r.timeout),n)}}var Ft="computer-run.js";function Vt(e){return oe(e)&&"ERR_SCRIPT_EXECUTION_TIMEOUT"===e.code}function Wt(e){if(void 0!==e){try{return structuredClone(e)}catch(e){if(!(e instanceof DOMException))throw e}try{return JSON.parse(JSON.stringify(e)??"null")}catch(t){if(!(t instanceof TypeError))throw t;return String(e)}}}async function Jt(e,t){let{code:i,snapshot:r,timeoutMs:n}=e,o=Ut(),s=new AbortController,{signal:a}=s,c=Date.now()+n,l=e=>s.abort(e),d=()=>new D("timeout",`computer run timed out after ${n} ms`),u=setTimeout(()=>l(d()),n),h=()=>l(new D("aborted","computer run was aborted"));e.signal?.addEventListener("abort",h,{once:!0}),e.signal?.aborted&&h();let p=[],m=t.service.onAudit(e=>p.push(function(e,t,i){let{action:r,target:n,delivery:o,durationMs:s,focusRestored:a,textLength:c,textSha256:l,keys:d}=e,u=e.code??null;return{timestamp:(new Date).toISOString(),sessionId:t,runId:i,action:r,target:n,delivery:o,frameId:e.frameId??null,code:u,status:null===u?"success":"Suspended"===u?"suspended":"error",durationMs:s,...null==a?{}:{focusRestored:a},...null==c?{}:{textLength:c},...null==l?{}:{textSha256:l},...null==d?{}:{keys:d}}}(e,r.sessionId,o))),f={signal:a,readOnly:r.readOnly,snapshot:r,output:new j,screenshots:[]},g=new jt.Script(""),y=()=>{if(!a.aborted)try{g.runInContext(x,{timeout:Math.max(1,c-Date.now())})}catch(e){l(Vt(e)?d():e)}},b=e=>{let t=()=>setImmediate(y);return e.then(t,t),e},w=Ht(a,n),v=(...e)=>f.output.text(Dt(...e)),x=jt.createContext({desktop:Nt({context:f,call:(e,i)=>t.service.call(e,i,{signal:a}),resume:b}),wait:(e,t)=>b(w(e,t)),assert:(e,t)=>{if(!e)throw new D("assertion",t??"Assertion failed")},tool:new Proxy({},{get:(e,i)=>e=>(a.throwIfAborted(),b(t.executeTool(String(i),e,{signal:a})))}),console:{log:v,info:v,warn:v,error:v,debug:v}},{name:Ft,microtaskMode:"afterEvaluate"});try{a.throwIfAborted();let e=new jt.Script(`(async () => {\n${i}\n})()`,{filename:Ft,lineOffset:-1}).runInContext(x,{timeout:n}),t=await new Promise((t,i)=>{a.addEventListener("abort",()=>i(a.reason),{once:!0}),a.throwIfAborted(),Promise.resolve(e).then(t,i),setImmediate(y)});return{displays:f.output.finish(),returnValue:Wt(t),screenshots:[...f.screenshots],audit:[...p]}}catch(e){throw Vt(e)?d():e}finally{clearTimeout(u),e.signal?.removeEventListener("abort",h),m(),a.aborted||s.abort(new D("ended","computer run has ended"))}}class Bt extends Error{method;constructor(e,t){super(`desktop engine notification ${JSON.stringify(e)} ${t}`),this.name="DesktopNotificationError",this.method=e}}function Gt(e,t){return e.add(t),()=>{e.delete(t)}}class Kt{#C=new Set;#R=new Set;#$=new Set;onAudit(e){return Gt(this.#C,e)}onStopPathChange(e){return Gt(this.#R,e)}onError(e){return Gt(this.#$,e)}emitError(e){for(let t of this.#$)t(e)}dispatch(e,t){let i=z.find(t=>t===e);void 0!==i?this.#T(i,t):this.emitError(new Bt(e,"is not part of the engine protocol"))}#T(e,t){switch(e){case"audit":if(se(i=t,ne)&&ce(i.action,Q)&&(void 0===i.code||null===i.code||ce(i.code,Z))&&(void 0===i.keys||null===i.keys||ae(i.keys)))for(let e of this.#C)e(t);else this.emitError(new Bt(e,"is malformed"));return;case"stopPath.changed":if(le(t))for(let e of this.#R)e(t);else this.emitError(new Bt(e,"is malformed"));return;case"engine.log":return;default:!function(e){throw Error(`unhandled engine notification ${JSON.stringify(e)}`)}(e)}var i}}class Xt{#_;#A=new Kt;#I=Promise.resolve();#M;#L;#N;constructor(e={}){this.#_=e.createChild??dt(),this.#A.onStopPathChange(e=>{this.#N=e})}onAudit(e){return this.#A.onAudit(e)}onStopPathChange(e){return this.#A.onStopPathChange(e)}onError(e){return this.#A.onError(e)}open(e){return this.#U(async()=>{this.#L={params:e,chord:this.#L?.chord};let t=this.#M;return!0===t?.rpc.alive?this.#D(t,e):(void 0!==t&&this.#j(t),(await this.#q(this.#L)).capabilities)})}ensureStopPath(e){return this.#U(async()=>{let t=await this.#H();if(t.armedChord===e)return this.#R(t,"stopPath.status",{});let i=await this.#R(t,"stopPath.start",{chord:e});return t.armedChord=e,void 0!==this.#L&&(this.#L.chord=e),i})}async call(e,t,i={}){return(await this.#F()).rpc.request(e,t,i)}async capabilities(){let e=await this.call("capabilities",{},{timeoutMs:1e4});if(!de(e))throw zt("capabilities");return e}async stopPathStatus(){return this.#R(await this.#F(),"stopPath.status",{})}async stop(){return this.#R(await this.#F(),"stopPath.stop",{source:"host-relay"})}async resume(){let e=await this.#F();return this.#R(e,"stopPath.resume",{token:e.resumeToken})}close(){return this.#U(async()=>{this.#L=void 0;let e=this.#M;if(void 0===e)return;if(this.#j(e),!e.rpc.alive)return;try{await Yt((async()=>{await e.rpc.request("session.close",{}),e.rpc.end(),await e.rpc.exited})(),1500,"Timed out closing desktop engine")}finally{e.rpc.kill()}})}#U(e){let t=this.#I.then(e);return this.#I=t.then(()=>{},()=>{}),t}#F(){let e=this.#M;return!0===e?.rpc.alive?Promise.resolve(e):this.#U(()=>this.#H())}async#H(){let e=this.#M;if(!0===e?.rpc.alive)return e;if(void 0!==e&&this.#j(e),void 0===this.#L)throw new pt("Closed","desktop session is not open");return(await this.#q(this.#L)).connection}async#q(e){let t=new ft(await this.#_(),{onNotification:(e,t)=>this.#A.dispatch(e,t),onExit:()=>{this.#M?.rpc===t&&this.#j(this.#M)}}),i={rpc:t,resumeToken:"",armedChord:void 0,heartbeat:void 0};try{let t=await Yt(this.#V(i,e),1e4,"Timed out starting desktop engine");return this.#M=i,i.heartbeat=setInterval(()=>this.#W(i),500),{connection:i,capabilities:t}}catch(e){throw t.kill(),e}}async#V(e,t){let i=function(e){if(oe(e)&&"string"==typeof e.abi&&"string"==typeof e.protocolVersion)return{abi:e.abi,protocolVersion:e.protocolVersion}}(await e.rpc.request("engine.hello",{}));if(void 0===i)throw zt("engine.hello");if(i.abi!==X||"1"!==i.protocolVersion)throw new me(e.rpc.enginePath,i);let r=await this.#D(e,t.params);return void 0!==t.chord&&(await this.#R(e,"stopPath.start",{chord:t.chord}),e.armedChord=t.chord),!0===this.#N?.suspended&&await this.#R(e,"stopPath.stop",{source:"host-relay"}),r}async#D(e,t){let i=function(e){if(oe(e)&&"string"==typeof e.resumeToken&&de(e.capabilities))return{capabilities:e.capabilities,resumeToken:e.resumeToken}}(await e.rpc.request("session.open",t,{timeoutMs:1e4}));if(void 0===i)throw zt("session.open");return e.resumeToken=i.resumeToken,i.capabilities}async#R(e,t,i){let r=await e.rpc.request(t,i);if(!le(r))throw zt(t);return this.#N=r,r}#W(e){e.rpc.request("stopPath.heartbeat",{}).catch(e=>{if(!(e instanceof pt&&"Closed"===e.code)){if(!(e instanceof pt||e instanceof mt))throw e;this.#A.emitError(e)}})}#j(e){clearInterval(e.heartbeat),this.#M===e&&(this.#M=void 0)}}function zt(e){return new pt("Internal",`desktop engine sent a malformed ${e} result`)}function Yt(e,t,i){return new Promise((r,n)=>{let o=setTimeout(()=>n(new pt("Timeout",i)),t);e.then(e=>{clearTimeout(o),r(e)},e=>{clearTimeout(o),n(e)})})}var Qt={name:"computer_actions",label:"Computer actions",description:["Drive the user's real desktop with OpenAI computer-use actions (experimental): screenshot, click, double_click, move, drag, scroll, type, keypress, wait, or a batch of them.","x,y are pixels of the latest screenshot. A batch stops at the first failed action; an in-batch screenshot becomes the frame for the actions after it.","Pass only the fields the chosen action takes (each field's description names its actions); anything else is refused with COMPUTER_INVALID_ARGUMENTS before any input.","Errors carry COMPUTER_* codes with a recovery hint. COMPUTER_SUSPENDED or COMPUTER_SUPERVISOR_NOT_LIVE means the user stopped you: stop and wait."].join("\n"),exposure:"search",searchText:"OpenAI computer-use actions (experimental): screenshot, click, type, keypress, scroll, drag, batch",searchKeywords:["computer use","cua","openai computer","click","screenshot","keypress"],searchGroup:"desktop",parameters:M,executionMode:"sequential"},Zt={Suspended:"COMPUTER_SUSPENDED",StopPathUnavailable:"COMPUTER_SUPERVISOR_NOT_LIVE",PermissionDenied:"COMPUTER_PERMISSION_REQUIRED",InvalidCoordinateFrame:"COMPUTER_DISPLAY_STALE",ScreenLocked:"COMPUTER_SCREEN_LOCKED",CaptureFailed:"COMPUTER_SCREENSHOT_FAILED",CursorRestoreFailed:"COMPUTER_CURSOR_RESTORE_FAILED",FocusRestoreFailed:"COMPUTER_FOCUS_RESTORE_FAILED",BackgroundUnavailable:"COMPUTER_BACKGROUND_UNAVAILABLE",Cancelled:"COMPUTER_CANCELLED",Timeout:"COMPUTER_CANCELLED",timeout:"COMPUTER_CANCELLED",aborted:"COMPUTER_CANCELLED"};function ei(e,t,i,r){let n=e.startsWith("COMPUTER_")?e:Zt[e]??"COMPUTER_ERROR",o=function(e,t){let i=`Stop and wait for the user (stop chord: ${t}); only the user resumes, with /computer resume.`;switch(e){case"COMPUTER_COORD_INVALID":return"Capture a fresh screenshot and use coordinates within its frame.";case"COMPUTER_DISPLAY_STALE":return"Capture a fresh screenshot before acting; the display changed since the last screenshot.";case"COMPUTER_SUSPENDED":case"COMPUTER_SUPERVISOR_NOT_LIVE":case"COMPUTER_CANCELLED":return i;case"COMPUTER_PERMISSION_REQUIRED":return"Do not retry until the user says the grant is done and the app was relaunched.";case"COMPUTER_PERMISSION_DENIED":return"A permission rule denied this action; do not retry it.";case"COMPUTER_CURSOR_RESTORE_FAILED":case"COMPUTER_FOCUS_RESTORE_FAILED":return"Input may have completed, but the previous state was not restored. Ask the user to inspect the desktop before retrying.";case"COMPUTER_BACKGROUND_UNAVAILABLE":return"This window cannot take background input; use the computer tool's accessibility actions instead.";default:return}}(n,i);return{code:n,message:`${n}: ${t}${void 0===o?"":` ${o}`}`,...r??{}}}import{Type as ti}from"typebox";var ii=ti.Object({method:ti.String({description:"desktop helper name, e.g. screenshot, window, click, clipboard.read"}),args:ti.Optional(ti.Array(ti.Unknown(),{description:"positional helper arguments"}))},{additionalProperties:!1}),ri=ti.Number({minimum:1,maximum:600,description:"run: budget in seconds (default 60)"}),ni=[ti.Object({action:ti.Literal("call"),chain:ti.Array(ii,{description:"one desktop helper call, optionally followed by one call on the window/element it returns"})},{additionalProperties:!1}),ti.Object({action:ti.Literal("run"),code:ti.String({description:"JavaScript async function body; `desktop`, `wait`, `assert`, `tool` in scope; `return` sets the value"}),read_only:ti.Optional(ti.Boolean({description:"true = inspection only: screenshots and AX reads, input/mutation blocked"})),timeout:ti.Optional(ri)},{additionalProperties:!1}),ti.Object({action:ti.Literal("capabilities")},{additionalProperties:!1}),ti.Object({action:ti.Literal("close")},{additionalProperties:!1})],oi=ti.Union([...ni]),si=ti.Object({action:ti.Enum(["call","run","capabilities","close"],{type:"string",description:"call: one desktop helper chain; run: a JavaScript body; capabilities: host report; close: end the session"}),chain:ti.Optional(ti.Array(ii,{description:"call (required): one desktop helper call, optionally followed by one call on the window/element it returns"})),code:ti.Optional(ti.String({description:"run (required): JavaScript async function body; `desktop`, `wait`, `assert`, `tool` in scope; `return` sets the value"})),read_only:ti.Optional(ti.Boolean({description:"run: true = inspection only: screenshots and AX reads, input/mutation blocked"})),timeout:ti.Optional(ri)},{additionalProperties:!1});import{Check as ai}from"typebox/value";import{readFileSync as ci}from"node:fs";import{dirname as li,join as di}from"node:path";import{fileURLToPath as ui}from"node:url";var hi,pi=["COMPUTER_PRELUDE_JAVASCRIPT","COMPUTER_PRELUDE_PYTHON","COMPUTER_DECLARATIONS","COMPUTER_DOCUMENTATION","COMPUTER_SAFETY"],mi=di(li(ui(import.meta.url)),"assets.generated.json");function fi(){if(void 0===hi){let e=JSON.parse(ci(mi,"utf8"));hi=function(e){let t=e&&"object"==typeof e?e:void 0,i=pi.filter(e=>"string"!=typeof t?.[e]);if(i.length>0)throw Error(`senpi-desktop-prelude asset JSON is malformed at ${mi}: missing ${i.join(", ")}`);return e}(e)}return hi}var gi={get javascript(){return fi().COMPUTER_PRELUDE_JAVASCRIPT},get python(){return fi().COMPUTER_PRELUDE_PYTHON},get declarations(){return fi().COMPUTER_DECLARATIONS},get documentation(){return fi().COMPUTER_DOCUMENTATION},get safety(){return fi().COMPUTER_SAFETY},exports:["computer"],methodAllowlist:["actions","attributes","ax","bounds","capabilities","children","click","clipboard.read","clipboard.write","displays","doubleClick","drag","elementAt","find","focus","focusedElement","focusedWindow","move","parent","perform","press","raise","ref","screenshot","scroll","setValue","type","value","window","windows"]},yi={name:"computer",label:"Computer",description:["Drive the user's real desktop (experimental): windows, screenshots, native mouse and keyboard input, the OS accessibility (AX) tree, and the clipboard. Not a browser.",'- `{action:"call", chain}` runs one desktop helper, optionally followed by one call on the window/element it returns, e.g. `[{method:"window",args:[{app:"Code"}]},{method:"screenshot"}]`.','- `{action:"run", code, read_only?, timeout?}` runs a JavaScript async function body with `desktop`, `wait`, `assert`, and `tool` in scope; `read_only: true` blocks input.','- `{action:"capabilities"}` reports backend, permissions, `stopPath`, and `focusGuard`; availability is unknown until `computer.capabilities()` returns in this session, so make no availability claim before it and repeat the host and reason on `native-unavailable`. `{action:"close"}` ends the desktop session.',"Pass only the fields of the chosen action; any other field is refused with COMPUTER_INVALID_ARGUMENTS.","In eval cells prefer the `computer` global, which wraps these actions. Pointer x,y are pixels of the latest screenshot of the same target."].join("\n"),exposure:"search",searchText:"Operate the real desktop (experimental): screenshots, clicks, typing, key chords, window list, accessibility tree, clipboard; macOS/Linux/Windows",searchKeywords:["computer use","computer-use","cua","desktop","gui","screenshot","click","type","keyboard","mouse","window","accessibility","ax","clipboard","automation"],searchGroup:"desktop",promptSnippet:"Operate the real desktop (experimental): screenshots, native input, accessibility tree, clipboard",promptGuidelines:gi.safety.split("\n").filter(e=>e.startsWith("- ")).map(e=>e.slice(2)),kernelPrelude:gi,parameters:si,executionMode:"sequential"},bi=v(ni);function wi(e){return"string"==typeof e?e:JSON.stringify(e,null,2)??String(e)}function vi(e,t){return{content:[{type:"text",text:void 0===e?t:wi(e)}],details:{value:e}}}async function xi(e,t,i,r){let{handle:n,executeTool:o}=e;await n.activate(t);let s=function(e,t,i){return{cwd:t.cwd,sessionId:t.sessionManager.getSessionId(),captureMaxWidth:e.maxWidth,captureMaxHeight:e.maxHeight,captureMaxBytes:e.screenshotMaxBytes,display:e.display,readOnly:i,stopHotkey:e.stopHotkey,allowHostRelayOnlyStop:e.allowHostRelayOnlyStop}}(n.settings(),t,i.readOnly),a=1e3*i.timeoutSeconds,c=await Jt({code:i.code,snapshot:s,timeoutMs:a,...void 0===r?{}:{signal:r}},{service:n.service,executeTool:o}),l=[...c.displays];return void 0!==c.returnValue&&l.push({type:"text",text:wi(c.returnValue)}),0===l.length&&l.push({type:"text",text:"Done."}),{content:l,details:{value:c.returnValue,readOnly:i.readOnly,screenshots:c.screenshots,audit:c.audit}}}function ki(e){let{handle:t}=e,i=(t,i,r)=>xi(e,t,i,r);return{...yi,async execute(e,r,n,o,s){let a=function(e){if(ai(oi,e))return e;throw x(bi,e,"computer")}(r);switch(a.action){case"call":{let e=K(a.chain),r=function(e){let t=e=>`${e.method}(...${JSON.stringify(e.args??[])})`,[i,r]=e;if(void 0===i)throw TypeError("renderCallChain: empty chain");return void 0===r?`return await desktop.${t(i)};`:`return await (await desktop.${t(i)}).${t(r)};`}(a.chain);return Oi(i(s,{code:r,readOnly:e,timeoutSeconds:60},n),t)}case"run":{let e=a.timeout??60;return Oi(i(s,{code:a.code,readOnly:!0===a.read_only,timeoutSeconds:e},n),t)}case"capabilities":return await t.activate(s),vi(await t.service.capabilities(),"capabilities unavailable");case"close":return await t.close(),vi(void 0,"Closed the desktop session.");default:return function(e){throw TypeError(`unhandled computer action ${JSON.stringify(e)}`)}(a)}}}}async function Oi(e,t){try{return await e}catch(e){if(!(e instanceof mt&&null!==e.data&&"code"in e.data&&"PermissionDenied"===e.data.code))throw e;let i=ei(e.data.code,e.message,t.settings().stopHotkey,e.data.permission);return{content:[{type:"text",text:JSON.stringify(i,null,2)}],details:{value:i},isError:!0}}}function Ei(e){let t=null;return{...Qt,async execute(i,r,n,o,s){let a,c=e.handle.settings().stopHotkey;try{a=function(e){if(O(_,e))return e;let t="object"==typeof e&&null!==e?Reflect.get(e,"actions"):void 0;if("batch"===Reflect.get(e??{},"action")&&Array.isArray(t)){let e=t.findIndex(e=>!O($,e));if(e>=0)throw x(L,t[e],`computer_actions actions[${e}]`)}throw x(N,e,"computer_actions")}(r)}catch(e){if(!(e instanceof w))throw e;let t=ei(e.code,e.reason,c);return{content:[{type:"text",text:t.message}],details:{value:t},isError:!0}}let l,d=Math.min(a.timeout??60,600),u=function(e){let t="batch"===e.action?e.actions:[e];return Array.isArray(t)&&t.length>0&&t.every(e=>"object"==typeof e&&null!==e&&U.has(String(Reflect.get(e,"action"))))}(a),h=function(e,t){return`const actions = ${JSON.stringify(e)};\nlet bounds = ${JSON.stringify(t)};\nconst steps = [];\nconst outside = (x, y) => bounds !== null && (x < 0 || y < 0 || x >= bounds.width || y >= bounds.height);\nconst shoot = async () => { const shot = await desktop.screenshot(); bounds = { width: shot.width, height: shot.height }; };\nfor (const [index, a] of actions.entries()) {\n\tconst points = a.action === "drag" ? [[a.x, a.y], [a.to_x, a.to_y]] : "x" in a ? [[a.x, a.y]] : [];\n\tconst off = points.find(([x, y]) => outside(x, y));\n\tif (off !== undefined) {\n\t\tconst message = a.action + " coordinates (" + off[0] + "," + off[1] + ") are outside the latest screenshot bounds " + bounds.width + "x" + bounds.height + ".";\n\t\tsteps.push({ index, action: a.action, status: "error", code: "COMPUTER_COORD_INVALID", message });\n\t\treturn { steps, bounds, failedIndex: index };\n\t}\n\ttry {\n\t\tconst button = a.button === undefined ? {} : { button: a.button };\n\t\tswitch (a.action) {\n\t\t\tcase "screenshot": await shoot(); break;\n\t\t\tcase "click": await desktop.click(a.x, a.y, button); break;\n\t\t\tcase "double_click": await desktop.doubleClick(a.x, a.y, button); break;\n\t\t\tcase "move": await desktop.move(a.x, a.y); break;\n\t\t\tcase "drag": await desktop.drag([[a.x, a.y], [a.to_x, a.to_y]], button); break;\n\t\t\tcase "scroll": await desktop.scroll(a.x, a.y, { dx: a.scroll_x, dy: a.scroll_y }); break;\n\t\t\tcase "type": await desktop.type(a.text); break;\n\t\t\tcase "keypress": await desktop.press(a.keys); break;\n\t\t\tcase "wait": await wait(a.ms); break;\n\t\t}\n\t\tif (a.include_screenshot === true && a.action !== "screenshot") await shoot();\n\t\tsteps.push({ index, action: a.action, status: "success" });\n\t} catch (error) {\n\t\tconst code = error?.data?.code ?? error?.reason ?? error?.name ?? "Error";\n\t\tsteps.push({ index, action: a.action, status: "error", code, message: String(error?.message ?? error), permission: error?.data?.permission });\n\t\treturn { steps, bounds, failedIndex: index };\n\t}\n}\nreturn { steps, bounds, failedIndex: null };`}(function(e){return"batch"===e.action?e.actions:[e]}(a),t);try{l=await xi(e,s,{code:h,readOnly:u,timeoutSeconds:d},n)}catch(e){if(!(e instanceof Error))throw e;let t=e instanceof mt&&null!==e.data&&"code"in e.data?e.data:void 0,i=t?.code??Reflect.get(e,"reason")??Reflect.get(e,"code")??e.name,r=ei(String(i),e.message,c,t?.permission);return{content:[{type:"text",text:r.message}],details:{value:r},isError:!0}}let p=l.details.value;if("object"!=typeof(m=p)||null===m||!Array.isArray(Reflect.get(m,"steps")))return l;var m;t=p.bounds;let f=l.content.filter(e=>"image"===e.type),g=null===p.failedIndex?void 0:p.steps[p.failedIndex];if(void 0===g){let e=`${p.steps.length} action(s) done: ${p.steps.map(e=>e.action).join(", ")}.`;return{...l,content:[...f,{type:"text",text:e}]}}let y=ei(g.code??"Error",g.message??"action failed",c,g.permission),b=`Action ${g.index+1} (${g.action}) failed. ${void 0===y.permission?y.message:JSON.stringify(y)}`;return{content:[...f,{type:"text",text:b}],details:{...l.details,value:{...p,failure:y}},isError:!0}}}}import{Type as Si}from"typebox";import{Check as Pi,Errors as Ci}from"typebox/value";Si.Object({enabled:Si.Optional(Si.Boolean({description:"Register the computer tool (experimental; default: host supported)"})),display:Si.Optional(Si.String({description:"`all` composites every display; otherwise a display id"})),maxWidth:Si.Optional(Si.Integer({minimum:1,default:3840})),maxHeight:Si.Optional(Si.Integer({minimum:1,default:2400})),screenshotMaxBytes:Si.Optional(Si.Integer({minimum:1,default:5e6})),stopHotkey:Si.Optional(Si.String({minLength:1,description:"Stop chord, e.g. ctrl+alt+shift+escape"})),allowHostRelayOnlyStop:Si.Optional(Si.Boolean({default:!1})),macosCanary:Si.Optional(Si.Union([Si.Literal("session"),Si.Literal("off")],{default:"session"})),auditLog:Si.Optional(Si.Object({enabled:Si.Optional(Si.Boolean({default:!0}))},{additionalProperties:!1})),screenshotGc:Si.Optional(Si.Object({enabled:Si.Optional(Si.Boolean({default:!0})),staleMs:Si.Optional(Si.Integer({minimum:0,default:432e5})),scanIntervalMs:Si.Optional(Si.Integer({minimum:0,default:18e5}))},{additionalProperties:!1})),enginePath:Si.Optional(Si.String({minLength:1,description:"Override the located engine binary"})),cuaAdapter:Si.Optional(Si.Boolean({default:!1,description:"Also register computer_actions (OpenAI computer-use actions)"}))},{additionalProperties:!1});import{accessSync as Ri,constants as $i,existsSync as Ti,readFileSync as _i}from"node:fs";import{dirname as Ai,join as Ii}from"node:path";import{homedir as Mi}from"node:os";function Li(e,t){let i;try{i=JSON.parse(_i(Ii(e,"package.json"),"utf8"))}catch{return}if("object"!=typeof i||null===i)return;let r=Reflect.get(i,"name"),n=Reflect.get(i,"version");return"string"==typeof r&&t.includes(r)&&"string"==typeof n&&n.length>0?n:void 0}function Ni(e){let t=e.OMO_PACKAGE_DIR?.trim();if(t){let e=Li(t,["omo"]);if(void 0!==e)return e}let i=e.OMO_BIN?.trim();return i?Li(Ai(Ai(i)),["omo-ai"]):void 0}function Ui(e=process.env,t){return i=>{if(void 0!==i)return function(e){let t=Me(),i=function(e,t){if(!Ti(e))return{code:"native-unavailable",host:t,attemptedPaths:[e],message:`No senpi-desktop-engine binary is available for ${t}.`,cause:`${e}: missing`};if(qe(e))return{code:"quarantined",host:t,attemptedPaths:[e],message:`The senpi-desktop-engine binary for ${t} is quarantined by macOS Gatekeeper.`,cause:`${e}: blocked because com.apple.quarantine is present`};try{return void Ri(e,$i.X_OK)}catch{return{code:"native-unavailable",host:t,attemptedPaths:[e],message:`No senpi-desktop-engine binary is available for ${t}.`,cause:`${e}: not executable (chmod +x)`}}}(e,t);return void 0!==i?()=>{throw new lt(i)}:dt(e)}(i);let r=Ni(e);return void 0!==r?function(e){let t=e.acquire??at,i=e.spawnEngine??ut;return async()=>{let r=await ct({version:e.version,host:e.host??Me()},i,t);if(null===r.path)throw new lt(r.diagnostic);return r.value}}({version:r}):void 0===t?dt():()=>{let e=De(t);if(null===e.path)throw new lt(e.diagnostic);return dt(e.path)()}}}function Di(e,t,i={}){if(void 0!==e)return`found ${e} (explicit)`;let r={...i,runtimeDir:i.runtimeDir??t.OMO_PACKAGE_DIR??""},n=De(r);if(null!==n.path){let e=Ue(r),t=r.runtimeDir?["runtime-dir","sidecar","package-prebuild","dev-build"]:["sidecar","package-prebuild","dev-build"];return`found ${n.path} (${t[e.indexOf(n.path)]})`}let{host:o,reason:s,cause:a,code:c}=n.diagnostic;if("no-release-asset"===s)return`No senpi-desktop-engine is built for ${o}`;let l=Ni(t);if(void 0!==l&&"quarantined"!==c){let e=st({host:o,version:l,cacheDir:Ii(t.HOME??Mi(),".omo","cache","senpi-desktop-engine")});if(null!==e.path)return`found ${e.path} (cache, omo v${l})`;let i=Re(o);if(null!==i)return`would download ${i} from omo v${l} on first use`}return`native-unavailable for ${o}: ${a}`}class ji extends Error{diagnostic;constructor(e,t){super(`Desktop engine unavailable (${e}): ${t.message}`,{cause:t}),this.name="ComputerEngineUnavailableError",this.diagnostic=e}}class qi extends Xt{#J="not started";#B;constructor(e={}){super(e),this.#B=e.onError}get engineState(){return this.#J}async open(e){try{let t=await super.open(e);return this.#J="ready",t}catch(e){if(!(e instanceof Error))throw e;this.#B?.(e);let t=function(e){return e instanceof lt?e.diagnostic.code:e instanceof me?"abi-mismatch":void 0}(e);if(void 0===t)throw e;throw this.#J=t,new ji(t,e)}}async call(e,t,i={}){return this.#G(super.call(e,t,i))}ensureStopPath(e){return this.#G(super.ensureStopPath(e))}stopPathStatus(){return this.#G(super.stopPathStatus())}stop(){return this.#G(super.stop())}resume(){return this.#G(super.resume())}async#G(e){try{return await e}catch(e){if(!(e instanceof Error))throw e;throw this.#B?.(e),e}}}function Hi(e){let t=e.engineChild??Ui(),i=new qi({createChild:t(e.settings.enginePath),onError:t=>e.onEngineError(function(e){return e instanceof lt?e.diagnostic.code:e instanceof me?"abi-mismatch":e instanceof mt?null!==e.data&&"code"in e.data?e.data.code:"other":e instanceof pt?e.code:"other"}(t))}),r=new y({service:i,settings:()=>e.settings}),n={handle:r,executeTool:e.executeTool};return{handle:r,service:i,computerTool:ki(n),computerActionsTool:Ei(n),describeEngineSource:Di}}export{Hi as createComputerUseRuntime};