omo-ai 5.1.5 → 5.1.6

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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "_comment": "Derived from @code-yeongyu/senpi 2026.9.29-5 builtinProviders(). builtinProviderIds and oauthProviderIds are the engine registry verbatim; providers maps a source harness id onto the omo provider that serves the same endpoint; oauthLogins maps a source OAuth id onto the omo provider to run /login for. Re-derive all four whenever the senpi pin changes.",
2
+ "_comment": "Derived from @code-yeongyu/senpi 2026.9.30 builtinProviders(). builtinProviderIds and oauthProviderIds are the engine registry verbatim; providers maps a source harness id onto the omo provider that serves the same endpoint; oauthLogins maps a source OAuth id onto the omo provider to run /login for. Re-derive all four whenever the senpi pin changes.",
3
3
  "builtinProviderIds": [
4
4
  "alibaba-token-plan",
5
5
  "amazon-bedrock",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omo-ai",
3
- "version": "5.1.5",
3
+ "version": "5.1.6",
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": {
@@ -17,7 +17,7 @@
17
17
  "postinstall": "node bin/senpi-patch.mjs"
18
18
  },
19
19
  "dependencies": {
20
- "@code-yeongyu/senpi": "2026.9.29-5"
20
+ "@code-yeongyu/senpi": "2026.9.30"
21
21
  },
22
22
  "repository": {
23
23
  "type": "git",
@@ -7,6 +7,38 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [5.1.6] - 2026-09-30
11
+
12
+ **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.
13
+
14
+ ### Added
15
+
16
+ A new `accept-edits` permission preset lets the agent read and edit files in the project without asking, while shell commands, paths outside the project and other tools still wait for your approval. ([senpi#2430](https://github.com/code-yeongyu/senpi/issues/2430))
17
+
18
+ Chat bridges can ask the engine for a chat prompt surface, which drops the routing line, the handoff block and todo lines from replies meant for people in a conversation. Terminal and app prompts stay as they are. ([senpi#2398](https://github.com/code-yeongyu/senpi/issues/2398))
19
+
20
+ ### Changed
21
+
22
+ The engine's recommended OpenAI model is GPT-6.1 Sol at medium, one slot below GPT-6 Astra. Models you listed yourself in `recommendedModels` stay as you set them. ([senpi#2390](https://github.com/code-yeongyu/senpi/issues/2390))
23
+
24
+ ultrawork reuses QA and review evidence per target instead of rerunning everything after each patch, while keeping the nets that catch what the changer cannot see: each artifact records the commit and what it exercised; after an increment the session reruns the tests of every touched file and its importers, the scenarios that exercise them, and anything whose dependencies or environment moved, cites the capture for the rest, and still runs the full set once before the final message. Every re-review spawns a new reviewer with the delta diff and the cited blockers, at most twice. Defects inside the change's blast radius are fixed in the same run to the ideal state; defects outside it get a tracked issue and a line in the final message instead of growing the run. The memory line now also records every regression a check caught and each QA scenario with its invocation. ([#9294](https://github.com/code-yeongyu/oh-my-openagent/issues/9294), [#9298](https://github.com/code-yeongyu/oh-my-openagent/pull/9298))
25
+
26
+ ### Fixed
27
+
28
+ On a Claude subscription, a `write` or `edit` to a file outside the working directory runs once and returns one result. Before, Claude Code's own read check refused the call while the change still went through, so a retry could apply an edit twice. Thanks to @haamsuk-collab. ([senpi#2401](https://github.com/code-yeongyu/senpi/issues/2401))
29
+
30
+ A running session keeps working through an update that changes how the engine's dependencies are laid out. Bash, monitor and `eval` used to fail with `ENOENT` until you restarted. The first launch after an update takes 2 to 3 seconds longer once while the engine copies its dependencies. ([senpi#2408](https://github.com/code-yeongyu/senpi/issues/2408), [senpi#2409](https://github.com/code-yeongyu/senpi/issues/2409))
31
+
32
+ An answer sent to a terminal session's question through its control endpoint reaches the model with its text, and answering such a question no longer triggers the first-turn todo reminder. ([senpi#2407](https://github.com/code-yeongyu/senpi/issues/2407), [senpi#2419](https://github.com/code-yeongyu/senpi/issues/2419))
33
+
34
+ The prompt-cache keep-alive pings in real sessions again, with the same tool list as the turn it keeps warm. Thanks to @MoerAI. ([senpi#2389](https://github.com/code-yeongyu/senpi/issues/2389))
35
+
36
+ An `eval` cell's return value reaches the model whole up to the normal output budget instead of stopping after 768 bytes, and any output that is still cut says so. ([senpi#2402](https://github.com/code-yeongyu/senpi/issues/2402))
37
+
38
+ On macOS, computer use keeps its Accessibility and Screen Recording permissions across updates, because the signed desktop engine now always runs from the same path. ([#9282](https://github.com/code-yeongyu/oh-my-openagent/issues/9282), [#9288](https://github.com/code-yeongyu/oh-my-openagent/pull/9288))
39
+
40
+ On Windows, killing a running background task marks it as killed instead of reporting a crash. Thanks to @Dante-dan. ([#9228](https://github.com/code-yeongyu/oh-my-openagent/issues/9228), [#9233](https://github.com/code-yeongyu/oh-my-openagent/pull/9233))
41
+
10
42
  ## [5.1.5] - 2026-09-30
11
43
 
12
44
  **Big thanks to [@ashmoonori-afk](https://github.com/ashmoonori-afk), whose [#9209](https://github.com/code-yeongyu/oh-my-openagent/pull/9209) teaches memory recall to find Korean, Japanese and Chinese notes and to pick the right note out of a big memory.**
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- // omo:1kZRR0pWVWGZ425iwHP0eR10sHDFbjNM4RwymIpzDU4:wrcNysGCSmPQBapD2B6XCs6Q9IVy4wapNChJ-vEMgU8
2
+ // omo:E6wxsbgn9wHM1Vn0p76LjLmxCW2N_Wy3ZgZIQGgU3L8: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:QbH_7Q4ZkQHXUTlnnAsU2MGj2k3JfQKQlGt51JcoHq0:RMjRqzmh-1hGOL_IwPH57RgTaDndBZz6tFWfoee22eQ
2
- import{tmpdir as e}from"node:os";import{join as t}from"node:path";var i=Number.MAX_SAFE_INTEGER;function r(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 n extends Error{constructor(){super("Computer use is off for this session; the user can turn it on with /computer on."),this.name="ComputerDisabledError"}}class o{#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 n;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(n,o){let s=function(n,o){let{auditLog:s,screenshotGc:a}=n;return{display:n.display,macosCanary:n.macosCanary,allowHostRelayOnlyStop:n.allowHostRelayOnlyStop,auditPath:s.enabled?t(o.sessionManager.getSessionDir(),".computer-audit.jsonl"):null,artifactDir:e(),screenshotGc:{staleMs:a.enabled?a.staleMs:i,scanIntervalMs:a.scanIntervalMs},captureCaps:{maxWidth:n.maxWidth,maxHeight:n.maxHeight,coordinateSafe:r(o.model),maxBytes:n.screenshotMaxBytes}}}(n,o),a=JSON.stringify(s);this.#n?.key!==a&&(this.#n={key:a,done:this.#e.open(s)});let c=this.#n;try{await c.done}catch(e){throw this.#n===c&&(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 s}from"typebox/value";class a extends Error{code="COMPUTER_INVALID_ARGUMENTS";reason;constructor(e){super(`COMPUTER_INVALID_ARGUMENTS: ${e}`),this.name="ComputerArgumentsError",this.reason=e}}function c(e){return new Map(e.map(e=>[String(Reflect.get(e.properties.action??{},"const")),e]))}function l(e,t,i){let r=[...e.keys()].join(", ");if("object"!=typeof t||null===t)return new a(`${i} must be an object`);let n=Reflect.get(t,"action");if("string"!=typeof n)return new a(`${i}: "action" must be one of ${r}`);let o=e.get(n);if(void 0===o)return new a(`${i}: unknown action "${n}"; expected one of ${r}`);let c=Object.keys(t).filter(e=>!(e in o.properties));if(c.length>0)return new a(`${i}: action "${n}" does not take ${c.join(", ")}`);let[l]=s(o,t),d=void 0===l||""===l.instancePath?"":` at ${l.instancePath}`;return new a(`${i}: action "${n}"${d}: ${l?.message??"invalid arguments"}`)}import{Type as d}from"typebox";import{Check as u}from"typebox/value";var h=d.Union([d.Literal("left"),d.Literal("right"),d.Literal("middle")]),p={timeout:d.Optional(d.Number({exclusiveMinimum:0,description:"Maximum time in seconds for this action."})),include_screenshot:d.Optional(d.Boolean({description:"Capture a screenshot after the action."}))},m={x:d.Number(),y:d.Number()},f={additionalProperties:!1},g=[d.Object({action:d.Literal("screenshot"),...p},f),d.Object({action:d.Literal("click"),...m,button:d.Optional(h),...p},f),d.Object({action:d.Literal("double_click"),...m,button:d.Optional(h),...p},f),d.Object({action:d.Literal("move"),...m,button:d.Optional(h),...p},f),d.Object({action:d.Literal("drag"),...m,to_x:d.Number(),to_y:d.Number(),button:d.Optional(h),...p},f),d.Object({action:d.Literal("scroll"),...m,scroll_x:d.Number(),scroll_y:d.Number(),...p},f),d.Object({action:d.Literal("type"),text:d.String(),...p},f),d.Object({action:d.Literal("keypress"),keys:d.Array(d.String(),{minItems:1}),...p},f),d.Object({action:d.Literal("wait"),ms:d.Integer({minimum:0}),...p},f)],y=d.Union([...g]),b=d.Object({action:d.Literal("batch"),actions:d.Array(y,{minItems:1}),...p},f),w=d.Union([y,b]),v=["screenshot","click","double_click","move","drag","scroll","type","keypress","wait"],x={x:d.Optional(d.Number({description:"click, double_click, move, drag (start), scroll (required): x pixel"})),y:d.Optional(d.Number({description:"click, double_click, move, drag (start), scroll (required): y pixel"})),button:d.Optional(d.Enum(["left","right","middle"],{type:"string",description:"click, double_click, move, drag: mouse button (default left)"})),to_x:d.Optional(d.Number({description:"drag (required): end x pixel"})),to_y:d.Optional(d.Number({description:"drag (required): end y pixel"})),scroll_x:d.Optional(d.Number({description:"scroll (required): horizontal scroll distance in pixels on every OS (one wheel notch is about 40 px); positive scrolls right"})),scroll_y:d.Optional(d.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:d.Optional(d.String({description:"type (required): text to type"})),keys:d.Optional(d.Array(d.String(),{minItems:1,description:"keypress (required): keys pressed together"})),ms:d.Optional(d.Integer({minimum:0,description:"wait (required): milliseconds"})),...p},O=d.Object({action:d.Enum([...v,"batch"],{type:"string",description:"The action to perform, or batch to run `actions` in order"}),actions:d.Optional(d.Array(d.Object({action:d.Enum([...v],{type:"string",description:"The action to perform"}),...x},f),{minItems:1,description:"batch (required): actions to execute in order"})),...x},f),k=c(g),E=c([...g,b]);var S=new Set(["screenshot","wait"]);var P={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"},C={screenshot:"read",click:"exec",doubleClick:"exec",move:"exec",drag:"exec",scroll:"exec",type:"exec",press:"exec",raise:"exec",ax:"read",find:"read",ref:"read"},R={value:"read",setValue:"exec",bounds:"read",attributes:"read",actions:"read",perform:"exec",press:"exec",click:"exec",focus:"exec",parent:"read",children:"read"},$={window:{label:"window",methods:C},ref:{label:"element",methods:R}};class T extends Error{reason;constructor(e,t){super(t),this.name="ComputerCallError",this.reason=e}}function _(e,t){return Object.hasOwn(e,t)?e[t]:void 0}function A(e){return Object.keys(e).join(", ")}function I(e){return"read"===function(e){let[t,i,...r]=e;if(void 0===t)throw new T("empty","Action 'call' requires a non-empty 'chain'.");if(r.length>0)throw new T("tooLong","Call chains support one handle hop at most; use computer.run(fn) for longer sequences.");let n=_(P,t.method);if(void 0===n)throw new T("unknownMethod",`Unknown desktop method "${t.method}". Desktop helpers support: ${A(P)}.`);if(void 0===i)return n;let o=Object.hasOwn($,t.method)?$[t.method]:void 0;if(void 0===o)throw new T("notChainable",`Only desktop.window(id)/desktop.ref(ref) results accept a chained call; got desktop.${t.method}().`);let s=_(o.methods,i.method);if(void 0===s)throw new T("unknownMethod",`Unknown ${o.label} method "${i.method}". Supported ${o.label} methods: ${A(o.methods)}.`);return s}(e)}var M="senpi-desktop/1",L=["audit","stopPath.changed","engine.log"],N=["PermissionDenied","CaptureFailed","InputFailed","BackgroundUnavailable","WindowNotFound","InvalidTarget","InvalidKey","InvalidCoordinateFrame","StaleRef","AxUnsupported","AxFailed","Timeout","Closed","Internal","StopPathUnavailable","Suspended","ScreenLocked","Cancelled","CursorRestoreFailed","FocusRestoreFailed","TransactionFailed"],U={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:O,executionMode:"sequential"},D={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 j(e,t,i){let r=e.startsWith("COMPUTER_")?e:D[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 V=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}),F=q.Number({minimum:1,maximum:600,description:"run: budget in seconds (default 60)"}),H=[q.Object({action:q.Literal("call"),chain:q.Array(V,{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(F)},{additionalProperties:!1}),q.Object({action:q.Literal("capabilities")},{additionalProperties:!1}),q.Object({action:q.Literal("close")},{additionalProperties:!1})],W=q.Union([...H]),B=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(V,{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(F)},{additionalProperties:!1});class J extends Error{reason;constructor(e,t){super(t),this.name="ComputerRunError",this.reason=e}}class G{#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 K(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 J("readOnly",`read-only run: '${i}' requires read_only: false`);e.signal.throwIfAborted()}(e.context,t,i),r(e))))}var X=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(N),Y=new Set(["global","host-relay","none"]),Q=["unknown","hostOnly","testOnly"],Z={suspended:"boolean",globalLive:"boolean",hostRelayLive:"boolean",heartbeatFresh:"boolean",stopPath:"string",reason:"string?"},ee={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"},te={action:"string",target:"string",delivery:"string",frameId:"string?",code:"string?",durationMs:"number",focusRestored:"boolean?",textLength:"number?",textDelivered:"number?",textSha256:"string?"};function ie(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function re(e,t){return!!ie(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 ne(e){return Array.isArray(e)&&e.every(e=>"string"==typeof e)}function oe(e,t){return"string"==typeof e&&t.has(e)}function se(e){return re(e,Z)&&oe(e.stopPath,Y)}function ae(e){return re(e,ee)&&ne(e.deliveryModes)}import{spawn as ce}from"node:child_process";import{createInterface as le}from"node:readline";class de extends Error{code="abi-mismatch";enginePath;expected;actual;constructor(e,t){let i={abi:M,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 ue}from"node:child_process";import{accessSync as he,constants as pe,existsSync as me,readFileSync as fe}from"node:fs";import{dirname as ge,join as ye}from"node:path";import{fileURLToPath as be}from"node:url";var we,ve="senpi-desktop-engine",xe="com.apple.quarantine",Oe=ye(ge(be(import.meta.url)),"..");function ke(e=process.platform,t=process.arch,i=("linux"===e&&e===process.platform?function(){return we??=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(),Ee),we}():void 0)){return"linux"===e&&"musl"===i?`${e}-${t}-musl`:`${e}-${t}`}function Ee(){try{return fe("/proc/self/maps","utf8")}catch(e){if(e instanceof Error&&"code"in e)return;throw e}}function Se(e={}){let t=ke(e.platform,e.arch,e.libc),i=function(e=process.platform){return"win32"===e?`${ve}.exe`:ve}(e.platform),r=e.packageDir??Oe,n=e.execDir??ge(process.execPath),o=e.repoRoot??ye(r,"..",".."),s=ye("native","prebuilds",t,i),a=e.runtimeDir??process.env.OMO_PACKAGE_DIR;return[...a?[ye(a,s)]:[],ye(n,s),ye(r,s),ye(o,"target","release",i)]}function Pe(e={}){let t=e.platform??process.platform,i=ke(t,e.arch,e.libc),r=Se(e),n=e.isQuarantined??(e=>Ce(e,t)),o=[],s=[];for(let e of r)if(me(e))if(n(e))s.push(e),o.push(`${e}: blocked because ${xe} is present (macOS Gatekeeper)`);else{if(Re(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 ${ve} binary for ${i} is quarantined by macOS Gatekeeper: ${s.join(", ")}.`:`No ${ve} binary is available for ${i}.`,cause:o.join("; ")}}}function Ce(e,t=process.platform){if("darwin"!==t)return!1;let i=ue("/usr/bin/xattr",["-p",xe,e],{stdio:["ignore","ignore","ignore"],timeout:2e3});return void 0===i.error&&0===i.status}function Re(e){try{return he(e,pe.X_OK),!0}catch(e){if(e instanceof Error&&"code"in e)return!1;throw e}}import{createHash as $e,randomUUID as Te}from"node:crypto";import{accessSync as _e,chmodSync as Ae,constants as Ie,existsSync as Me,mkdirSync as Le,mkdtempSync as Ne,readFileSync as Ue,readdirSync as De,renameSync as je,rmSync as qe,writeFileSync as Ve}from"node:fs";import{homedir as Fe}from"node:os";import{join as He}from"node:path";var We="senpi-desktop-engine-checksums.txt",Be=["darwin-arm64","darwin-x64","linux-x64","win32-x64"];function Je(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}}var Ge="-musl";async function Ke(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(Ge)?"musl":"glibc",l="musl"===c?a.slice(0,-5):a,d=Pe({...e.locatorOptions,platform:s,arch:l,libc:c});if(r=d.diagnostic?.attemptedPaths??[],null!==d.path)return{path:d.path};if("quarantined"===d.diagnostic.code)return n(d.diagnostic.cause);let u=Je(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??He(Fe(),".omo","cache","senpi-desktop-engine"),p=He(h,i,t);if(Me(p))for(let e of De(p)){let t=/^([0-9a-f]{64})-[0-9a-f-]{36}$/.exec(e);if(null===t)continue;let i=He(p,e,u);if(r=[...r,i],Me(i)&&$e("sha256").update(Ue(i)).digest("hex")===t[1]&&!Ce(i,s))try{return _e(i,Ie.X_OK),{path:i}}catch(e){if(!(e instanceof Error&&"code"in e))throw e}}let m=e.fetch??globalThis.fetch,f=`https://github.com/code-yeongyu/oh-my-openagent/releases/download/v${i}`;r=[...r,He(p,u)];let[g,y]=await Promise.all([m(`${f}/${u}`,{signal:AbortSignal.timeout(3e4)}),m(`${f}/${We}`,{signal:AbortSignal.timeout(3e4)})]);if(!g.ok)return n(`${u}: HTTP ${g.status}`);if(!y.ok)return n(`${We}: 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||!Be.some(e=>Je(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()),O=$e("sha256").update(x).digest("hex");if(O.toLowerCase()!==b.toLowerCase())return n(`SHA-256 mismatch for ${u}`);Le(p,{recursive:!0});let k=Ne(He(p,".download-")),E=He(p,`${O}-${Te()}`);try{let e=He(k,u);Ve(e,x),Ae(e,493),je(k,E)}finally{qe(k,{recursive:!0,force:!0})}return{path:He(E,u)}}catch(e){return n(e instanceof Error?e.message:String(e))}}class Xe extends Error{diagnostic;constructor(e){super(`${e.message} ${e.cause}`),this.name="DesktopEngineUnavailableError",this.diagnostic=e}}function ze(e){return()=>Ye(e??function(){let e=Pe();if(null===e.path)throw new Xe(e.diagnostic);return e.path}())}function Ye(e){return ce(e,["--stdio"],{stdio:"pipe",windowsHide:!0})}class Qe{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}`)),le({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 Ze extends Error{code;engineRestarted;constructor(e,t,i=!1){super(t),this.name="DesktopServiceError",this.code=e,this.engineRestarted=i}}class et 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(!ie(e))return null;let t=N.find(t=>t===e.code);if(void 0!==t)return{code:t,hint:"string"==typeof e.hint?e.hint:null};let i=Q.find(t=>t===e.reason);return void 0===i?null:{reason:i}}(t.data)}}class tt{#f;#g;#y=new Map;#b=1;#m;constructor(e,t){this.#g=t,this.#f=new Qe(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 Ze("Closed",this.#m??"desktop engine was killed"));if(i.signal?.aborted)return Promise.reject(new Ze("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 Ze("Cancelled",`${e} was cancelled`)),u=void 0===l?void 0:setTimeout(()=>this.#x(r,new Ze("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.#O(e),i.reject(new Ze(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}})}#O(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(!ie(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.#O(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;ie(r)&&"number"==typeof r.code&&"string"==typeof r.message?i.reject(new et(i.method,{code:r.code,message:r.message,data:r.data})):i.reject(new Ze("Internal",`desktop engine sent a malformed reply to ${i.method}`))}#v(e){this.#m??=e;let t=new Ze("Closed",this.#m);for(let e of[...this.#y.keys()])this.#O(e)?.reject(t);this.#g.onExit()}}var it={id:"string",name:"string",x:"number",y:"number",width:"number",height:"number",scale:"number",pixelX:"number",pixelY:"number",pixelWidth:"number",pixelHeight:"number",isPrimary:"boolean"},rt={id:"string",title:"string",app:"string",pid:"number?",x:"number",y:"number",width:"number",height:"number",focused:"boolean",elevated:"boolean?"},nt={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"},ot={mode:"string",data:"string?",mimeType:"string?",artifactPath:"string?",width:"number",height:"number",sourceWidth:"number",sourceHeight:"number",scale:"number",target:"string",frameId:"string",note:"string?"},st=e=>re(e,it),at=e=>re(e,rt),ct=e=>re(e,nt)&&(void 0===e.actions||null===e.actions||ne(e.actions)),lt=e=>re(e,ot),dt=e=>ie(e)&&"string"==typeof e.text,ut=e=>Array.isArray(e)&&e.every(e=>ne(e)&&2===e.length);function ht(e){return t=>Array.isArray(t)&&t.every(e)}function pt(e){return t=>null===t||e(t)}function mt(e,t,i){if(!i(t))throw new Ze("Internal",`desktop engine sent a malformed ${e} result`);return t}function ft(e={}){let{button:t,count:i,modifiers:r,delivery:n}=e;return{button:t,count:i,modifiers:r,deliveryMode:n}}function gt(e){return"string"!=typeof e?e:e.split("+").map(e=>e.trim()).filter(e=>e.length>0)}class yt{#k;method;constructor(e,t,i){this.#k=t,this.method=K(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=mt("capture",await e.call("capture",{target:t,caps:s}),lt),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.#k,e))}click(e,t,i){return this.send("click","click",{target:this.#k,x:e,y:t,opts:ft(i)})}doubleClick(e,t,i){let r=ft({...i,count:2});return this.send("doubleClick","click",{target:this.#k,x:e,y:t,opts:r})}move(e,t){return this.send("move","moveMouse",{target:this.#k,x:e,y:t})}drag(e,t){let i=e.map(([e,t])=>({x:e,y:t}));return this.send("drag","drag",{target:this.#k,path:i,opts:ft(t)})}scroll(e,t,i={}){let{dx:r=0,dy:n=0}=i;return this.send("scroll","scroll",{target:this.#k,x:e,y:t,dx:r,dy:n,opts:ft(i)})}type(e,t){return this.send("type","typeText",{target:this.#k,text:e,opts:ft(t)})}press(e,t){let i={target:this.#k,keys:gt(e),opts:ft(t)};return this.send("press","keyChord",i)}}class bt extends yt{id;app;title;pid;bounds;focused;constructor(e,t){super(e,t.id,C),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})=>mt("ax.snapshot",await t("ax.snapshot",{target:this.id,opts:e}),dt).text)}find(e){return this.method("find",async t=>mt("ax.query",await t.call("ax.query",{target:this.id,query:e}),ht(ct)).map(e=>new vt(t,e)))}ref(e){return this.method("ref",t=>wt(t,e))}}async function wt(e,t){return new vt(e,mt("ax.node",await e.call("ax.node",{ref:t}),ct))}class vt{ref;role;nativeRole;title;description;enabled;focused;childCount;#E;constructor(e,t){this.#E=K(e,R),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(mt("ax.node",await e("ax.node",{ref:this.ref}),ct)))}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(mt("ax.attributes",await e("ax.attributes",{ref:this.ref}),ut)))}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:ft(e)})}focus(){return this.#S("focus","ax.focus",{})}parent(){return this.#E("parent",async e=>{let t=mt("ax.parent",await e.call("ax.parent",{ref:this.ref}),pt(ct));return null===t?null:new vt(e,t)})}children(){return this.#E("children",async e=>mt("ax.children",await e.call("ax.children",{ref:this.ref}),ht(ct)).map(t=>new vt(e,t)))}}function xt(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 Ot(e){let t=K(e,P),i=async({call:e})=>mt("windows",await e("windows",{}),ht(at)),r=async(t,i)=>{let r=mt(t,await e.call(t,i),pt(ct));return null===r?null:new vt(e,r)},n=new yt(e,"desktop",P);return{capabilities:()=>t("capabilities",async({call:e})=>mt("capabilities",await e("capabilities",{}),ae)),displays:()=>t("displays",async({call:e})=>mt("displays",await e("displays",{}),ht(st))),windows:e=>t("windows",async t=>(await i(t)).filter(t=>xt(t,e))),window:r=>t("window",async t=>{let n=(await i(t)).filter(e=>"string"==typeof r?e.id===r:xt(e,r)),[o,...s]=n;if(void 0===o)throw new J("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 J("window",`multiple windows match ${JSON.stringify(r)}:\n${e.join("\n")}`)}return new bt(e,o)}),focusedWindow:()=>t("focusedWindow",async t=>{let r=(await i(t)).find(e=>e.focused);return void 0===r?null:new bt(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=>wt(t,e)),clipboard:{read:()=>t("clipboard.read",async({call:e})=>mt("clipboard.read",await e("clipboard.read",{}),dt).text),write:e=>t("clipboard.write",async({call:t})=>{await t("clipboard.write",{text:e})})}}}import{randomUUID as kt}from"node:crypto";import{format as Et}from"node:util";import St from"node:vm";function Pt(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 Ct(e,t){return async(i,r={})=>{if("number"==typeof i)return Pt(i,e);if("function"!=typeof i)throw new J("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 J("wait",`wait(predicate) timed out after ${i} ms; the predicate never returned truthy`);await Pt(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 Rt="computer-run.js";function $t(e){return ie(e)&&"ERR_SCRIPT_EXECUTION_TIMEOUT"===e.code}function Tt(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 _t(e,t){let{code:i,snapshot:r,timeoutMs:n}=e,o=kt(),s=new AbortController,{signal:a}=s,c=Date.now()+n,l=e=>s.abort(e),d=()=>new J("timeout",`computer run timed out after ${n} ms`),u=setTimeout(()=>l(d()),n),h=()=>l(new J("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 G,screenshots:[]},g=new St.Script(""),y=()=>{if(!a.aborted)try{g.runInContext(x,{timeout:Math.max(1,c-Date.now())})}catch(e){l($t(e)?d():e)}},b=e=>{let t=()=>setImmediate(y);return e.then(t,t),e},w=Ct(a,n),v=(...e)=>f.output.text(Et(...e)),x=St.createContext({desktop:Ot({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 J("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:Rt,microtaskMode:"afterEvaluate"});try{a.throwIfAborted();let e=new St.Script(`(async () => {\n${i}\n})()`,{filename:Rt,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:Tt(t),screenshots:[...f.screenshots],audit:[...p]}}catch(e){throw $t(e)?d():e}finally{clearTimeout(u),e.signal?.removeEventListener("abort",h),m(),a.aborted||s.abort(new J("ended","computer run has ended"))}}class At extends Error{method;constructor(e,t){super(`desktop engine notification ${JSON.stringify(e)} ${t}`),this.name="DesktopNotificationError",this.method=e}}function It(e,t){return e.add(t),()=>{e.delete(t)}}class Mt{#C=new Set;#R=new Set;#$=new Set;onAudit(e){return It(this.#C,e)}onStopPathChange(e){return It(this.#R,e)}onError(e){return It(this.#$,e)}emitError(e){for(let t of this.#$)t(e)}dispatch(e,t){let i=L.find(t=>t===e);void 0!==i?this.#T(i,t):this.emitError(new At(e,"is not part of the engine protocol"))}#T(e,t){switch(e){case"audit":if(re(i=t,te)&&oe(i.action,X)&&(void 0===i.code||null===i.code||oe(i.code,z))&&(void 0===i.keys||null===i.keys||ne(i.keys)))for(let e of this.#C)e(t);else this.emitError(new At(e,"is malformed"));return;case"stopPath.changed":if(se(t))for(let e of this.#R)e(t);else this.emitError(new At(e,"is malformed"));return;case"engine.log":return;default:!function(e){throw Error(`unhandled engine notification ${JSON.stringify(e)}`)}(e)}var i}}class Lt{#_;#A=new Mt;#I=Promise.resolve();#M;#L;#N;constructor(e={}){this.#_=e.createChild??ze(),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.#V();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(!ae(e))throw Nt("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 Ut((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.#V())}async#V(){let e=this.#M;if(!0===e?.rpc.alive)return e;if(void 0!==e&&this.#j(e),void 0===this.#L)throw new Ze("Closed","desktop session is not open");return(await this.#q(this.#L)).connection}async#q(e){let t=new tt(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 Ut(this.#H(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#H(e,t){let i=function(e){if(ie(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 Nt("engine.hello");if(i.abi!==M||"1"!==i.protocolVersion)throw new de(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(ie(e)&&"string"==typeof e.resumeToken&&ae(e.capabilities))return{capabilities:e.capabilities,resumeToken:e.resumeToken}}(await e.rpc.request("session.open",t,{timeoutMs:1e4}));if(void 0===i)throw Nt("session.open");return e.resumeToken=i.resumeToken,i.capabilities}async#R(e,t,i){let r=await e.rpc.request(t,i);if(!se(r))throw Nt(t);return this.#N=r,r}#W(e){e.rpc.request("stopPath.heartbeat",{}).catch(e=>{if(!(e instanceof Ze&&"Closed"===e.code)){if(!(e instanceof Ze||e instanceof et))throw e;this.#A.emitError(e)}})}#j(e){clearInterval(e.heartbeat),this.#M===e&&(this.#M=void 0)}}function Nt(e){return new Ze("Internal",`desktop engine sent a malformed ${e} result`)}function Ut(e,t,i){return new Promise((r,n)=>{let o=setTimeout(()=>n(new Ze("Timeout",i)),t);e.then(e=>{clearTimeout(o),r(e)},e=>{clearTimeout(o),n(e)})})}import{Check as Dt}from"typebox/value";import{readFileSync as jt}from"node:fs";import{dirname as qt,join as Vt}from"node:path";import{fileURLToPath as Ft}from"node:url";var Ht,Wt=["COMPUTER_PRELUDE_JAVASCRIPT","COMPUTER_PRELUDE_PYTHON","COMPUTER_DECLARATIONS","COMPUTER_DOCUMENTATION","COMPUTER_SAFETY"],Bt=Vt(qt(Ft(import.meta.url)),"assets.generated.json");function Jt(){if(void 0===Ht){let e=JSON.parse(jt(Bt,"utf8"));Ht=function(e){let t=e&&"object"==typeof e?e:void 0,i=Wt.filter(e=>"string"!=typeof t?.[e]);if(i.length>0)throw Error(`senpi-desktop-prelude asset JSON is malformed at ${Bt}: missing ${i.join(", ")}`);return e}(e)}return Ht}var Gt={get javascript(){return Jt().COMPUTER_PRELUDE_JAVASCRIPT},get python(){return Jt().COMPUTER_PRELUDE_PYTHON},get declarations(){return Jt().COMPUTER_DECLARATIONS},get documentation(){return Jt().COMPUTER_DOCUMENTATION},get safety(){return Jt().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"]},Kt={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:Gt.safety.split("\n").filter(e=>e.startsWith("- ")).map(e=>e.slice(2)),kernelPrelude:Gt,parameters:B,executionMode:"sequential"},Xt=c(H);function zt(e){return"string"==typeof e?e:JSON.stringify(e,null,2)??String(e)}function Yt(e,t){return{content:[{type:"text",text:void 0===e?t:zt(e)}],details:{value:e}}}async function Qt(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 _t({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:zt(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 Zt(e){let{handle:t}=e,i=(t,i,r)=>Qt(e,t,i,r);return{...Kt,async execute(e,r,n,o,s){let a=function(e){if(Dt(W,e))return e;throw l(Xt,e,"computer")}(r);switch(a.action){case"call":{let e=I(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),Yt(await t.service.capabilities(),"capabilities unavailable");case"close":return await t.close(),Yt(void 0,"Closed the desktop session.");default:return function(e){throw TypeError(`unhandled computer action ${JSON.stringify(e)}`)}(a)}}}}function ei(e){let t=null;return{...U,async execute(i,r,n,o,s){let c,d=e.handle.settings().stopHotkey;try{c=function(e){if(u(w,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=>!u(y,e));if(e>=0)throw l(k,t[e],`computer_actions actions[${e}]`)}throw l(E,e,"computer_actions")}(r)}catch(e){if(!(e instanceof a))throw e;let t=j(e.code,e.reason,d);return{content:[{type:"text",text:t.message}],details:{value:t},isError:!0}}let h,p=Math.min(c.timeout??60,600),m=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&&S.has(String(Reflect.get(e,"action"))))}(c),f=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]}(c),t);try{h=await Qt(e,s,{code:f,readOnly:m,timeoutSeconds:p},n)}catch(e){if(!(e instanceof Error))throw e;let t=Reflect.get(e,"reason")??Reflect.get(e,"code")??e.name,i=j(String(t),e.message,d);return{content:[{type:"text",text:i.message}],details:{value:i},isError:!0}}let g=h.details.value;if("object"!=typeof(b=g)||null===b||!Array.isArray(Reflect.get(b,"steps")))return h;var b;t=g.bounds;let v=h.content.filter(e=>"image"===e.type),x=null===g.failedIndex?void 0:g.steps[g.failedIndex];if(void 0===x){let e=`${g.steps.length} action(s) done: ${g.steps.map(e=>e.action).join(", ")}.`;return{...h,content:[...v,{type:"text",text:e}]}}let O=j(x.code??"Error",x.message??"action failed",d),P=`Action ${x.index+1} (${x.action}) failed. ${O.message}`;return{content:[...v,{type:"text",text:P}],details:{...h.details,value:{...g,failure:O}},isError:!0}}}}import{Type as ti}from"typebox";import{Check as ii,Errors as ri}from"typebox/value";ti.Object({enabled:ti.Optional(ti.Boolean({description:"Register the computer tool (experimental; default: host supported)"})),display:ti.Optional(ti.String({description:"`all` composites every display; otherwise a display id"})),maxWidth:ti.Optional(ti.Integer({minimum:1,default:3840})),maxHeight:ti.Optional(ti.Integer({minimum:1,default:2400})),screenshotMaxBytes:ti.Optional(ti.Integer({minimum:1,default:5e6})),stopHotkey:ti.Optional(ti.String({minLength:1,description:"Stop chord, e.g. ctrl+alt+shift+escape"})),allowHostRelayOnlyStop:ti.Optional(ti.Boolean({default:!1})),macosCanary:ti.Optional(ti.Union([ti.Literal("session"),ti.Literal("off")],{default:"session"})),auditLog:ti.Optional(ti.Object({enabled:ti.Optional(ti.Boolean({default:!0}))},{additionalProperties:!1})),screenshotGc:ti.Optional(ti.Object({enabled:ti.Optional(ti.Boolean({default:!0})),staleMs:ti.Optional(ti.Integer({minimum:0,default:432e5})),scanIntervalMs:ti.Optional(ti.Integer({minimum:0,default:18e5}))},{additionalProperties:!1})),enginePath:ti.Optional(ti.String({minLength:1,description:"Override the located engine binary"})),cuaAdapter:ti.Optional(ti.Boolean({default:!1,description:"Also register computer_actions (OpenAI computer-use actions)"}))},{additionalProperties:!1});import{accessSync as ni,constants as oi,existsSync as si,readFileSync as ai}from"node:fs";import{dirname as ci,join as li}from"node:path";function di(e,t){let i;try{i=JSON.parse(ai(li(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 ui(e=process.env){return t=>{if(void 0!==t)return function(e){let t=ke(),i=function(e,t){if(!si(e))return{code:"native-unavailable",host:t,attemptedPaths:[e],message:`No senpi-desktop-engine binary is available for ${t}.`,cause:`${e}: missing`};if(Ce(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 ni(e,oi.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 Xe(i)}:ze(e)}(t);let i=function(e){let t=e.OMO_PACKAGE_DIR?.trim();if(t){let e=di(t,["omo"]);if(void 0!==e)return e}let i=e.OMO_BIN?.trim();return i?di(ci(ci(i)),["omo-ai"]):void 0}(e);return void 0===i?ze():function(e){let t,i=e.acquire??Ke,r=e.spawnEngine??Ye;return async()=>{if(void 0===t){let r=await i({version:e.version,host:e.host??ke()});if(null===r.path)throw new Xe(r.diagnostic);t=r.path}return r(t)}}({version:i})}}class hi extends Error{diagnostic;constructor(e,t){super(`Desktop engine unavailable (${e}): ${t.message}`,{cause:t}),this.name="ComputerEngineUnavailableError",this.diagnostic=e}}class pi extends Lt{#B="not started";#J;constructor(e={}){super(e),this.#J=e.onError}get engineState(){return this.#B}async open(e){try{let t=await super.open(e);return this.#B="ready",t}catch(e){if(!(e instanceof Error))throw e;this.#J?.(e);let t=function(e){return e instanceof Xe?e.diagnostic.code:e instanceof de?"abi-mismatch":void 0}(e);if(void 0===t)throw e;throw this.#B=t,new hi(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.#J?.(e),e}}}function mi(e){let t=e.engineChild??ui(),i=new pi({createChild:t(e.settings.enginePath),onError:t=>e.onEngineError(function(e){return e instanceof Xe?e.diagnostic.code:e instanceof de?"abi-mismatch":e instanceof et?null!==e.data&&"code"in e.data?e.data.code:"other":e instanceof Ze?e.code:"other"}(t))}),r=new o({service:i,settings:()=>e.settings}),n={handle:r,executeTool:e.executeTool};return{handle:r,service:i,computerTool:Zt(n),computerActionsTool:ei(n)}}export{mi as createComputerUseRuntime};
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};