@ashx-j/lunr-dev 0.2.13-dev.8.1 → 0.2.19-dev.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (484) hide show
  1. package/CHANGELOG.md +60 -1
  2. package/README.md +7 -1
  3. package/dist/builtin-extensions/ashxj-thinking.d.ts +1 -0
  4. package/dist/builtin-extensions/ashxj-thinking.d.ts.map +1 -1
  5. package/dist/builtin-extensions/ashxj-thinking.js +44 -19
  6. package/dist/builtin-extensions/ashxj-thinking.js.map +1 -1
  7. package/dist/builtin-extensions/ashxj-tui.d.ts +14 -0
  8. package/dist/builtin-extensions/ashxj-tui.d.ts.map +1 -1
  9. package/dist/builtin-extensions/ashxj-tui.js +37 -3
  10. package/dist/builtin-extensions/ashxj-tui.js.map +1 -1
  11. package/dist/builtin-extensions/index.d.ts +1 -15
  12. package/dist/builtin-extensions/index.d.ts.map +1 -1
  13. package/dist/builtin-extensions/index.js +8 -21
  14. package/dist/builtin-extensions/index.js.map +1 -1
  15. package/dist/builtin-extensions/lunr-computer-use.d.ts +3 -0
  16. package/dist/builtin-extensions/lunr-computer-use.d.ts.map +1 -0
  17. package/dist/builtin-extensions/lunr-computer-use.js +157 -0
  18. package/dist/builtin-extensions/lunr-computer-use.js.map +1 -0
  19. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.d.ts.map +1 -1
  20. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js +6 -2
  21. package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js.map +1 -1
  22. package/dist/builtin-extensions/pi-lsp-extension/src/index.d.ts +4 -0
  23. package/dist/builtin-extensions/pi-lsp-extension/src/index.d.ts.map +1 -1
  24. package/dist/builtin-extensions/pi-lsp-extension/src/index.js +172 -171
  25. package/dist/builtin-extensions/pi-lsp-extension/src/index.js.map +1 -1
  26. package/dist/builtin-extensions/pi-lsp-extension/src/runtime.d.ts +50 -0
  27. package/dist/builtin-extensions/pi-lsp-extension/src/runtime.d.ts.map +1 -0
  28. package/dist/builtin-extensions/pi-lsp-extension/src/runtime.js +131 -0
  29. package/dist/builtin-extensions/pi-lsp-extension/src/runtime.js.map +1 -0
  30. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.d.ts +7 -0
  31. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.d.ts.map +1 -0
  32. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js +211 -0
  33. package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js.map +1 -0
  34. package/dist/builtin-extensions/pi-mcp-adapter/direct-tools.d.ts +0 -5
  35. package/dist/builtin-extensions/pi-mcp-adapter/direct-tools.d.ts.map +1 -1
  36. package/dist/builtin-extensions/pi-mcp-adapter/direct-tools.js +0 -202
  37. package/dist/builtin-extensions/pi-mcp-adapter/direct-tools.js.map +1 -1
  38. package/dist/builtin-extensions/pi-mcp-adapter/index.d.ts.map +1 -1
  39. package/dist/builtin-extensions/pi-mcp-adapter/index.js +276 -109
  40. package/dist/builtin-extensions/pi-mcp-adapter/index.js.map +1 -1
  41. package/dist/builtin-extensions/pi-mcp-adapter/init.d.ts +4 -1
  42. package/dist/builtin-extensions/pi-mcp-adapter/init.d.ts.map +1 -1
  43. package/dist/builtin-extensions/pi-mcp-adapter/init.js +10 -3
  44. package/dist/builtin-extensions/pi-mcp-adapter/init.js.map +1 -1
  45. package/dist/builtin-extensions/pi-mcp-adapter/metadata-cache.d.ts.map +1 -1
  46. package/dist/builtin-extensions/pi-mcp-adapter/metadata-cache.js +6 -1
  47. package/dist/builtin-extensions/pi-mcp-adapter/metadata-cache.js.map +1 -1
  48. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.d.ts +6 -1
  49. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.d.ts.map +1 -1
  50. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js +33 -8
  51. package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js.map +1 -1
  52. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.d.ts.map +1 -1
  53. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js +2 -1
  54. package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js.map +1 -1
  55. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.d.ts +1 -1
  56. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.d.ts.map +1 -1
  57. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js +1 -1
  58. package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js.map +1 -1
  59. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts +1 -1
  60. package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
  61. package/dist/builtin-extensions/pi-subagents/src/extension/index.js +68 -15
  62. package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
  63. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
  64. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +6 -2
  65. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
  66. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.d.ts +1 -1
  67. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.d.ts.map +1 -1
  68. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js +5 -2
  69. package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js.map +1 -1
  70. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/request-params.d.ts +10 -0
  71. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/request-params.d.ts.map +1 -0
  72. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/request-params.js +38 -0
  73. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/request-params.js.map +1 -0
  74. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
  75. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +3 -16
  76. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
  77. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts +1 -1
  78. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts.map +1 -1
  79. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js +2 -0
  80. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js.map +1 -1
  81. package/dist/builtin-extensions/pi-subagents/src/shared/fork-context.d.ts.map +1 -1
  82. package/dist/builtin-extensions/pi-subagents/src/shared/fork-context.js +1 -1
  83. package/dist/builtin-extensions/pi-subagents/src/shared/fork-context.js.map +1 -1
  84. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts +1 -1
  85. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts.map +1 -1
  86. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js +1 -1
  87. package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js.map +1 -1
  88. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +2 -1
  89. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
  90. package/dist/builtin-extensions/pi-subagents/src/tui/render.js +72 -31
  91. package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
  92. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.d.ts +1 -1
  93. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.d.ts.map +1 -1
  94. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js +2 -1
  95. package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js.map +1 -1
  96. package/dist/builtin-extensions/pi-web-access/extract.d.ts.map +1 -1
  97. package/dist/builtin-extensions/pi-web-access/extract.js +105 -54
  98. package/dist/builtin-extensions/pi-web-access/extract.js.map +1 -1
  99. package/dist/builtin-extensions/pi-web-access/gemini-search.d.ts +1 -1
  100. package/dist/builtin-extensions/pi-web-access/gemini-search.d.ts.map +1 -1
  101. package/dist/builtin-extensions/pi-web-access/gemini-search.js +82 -65
  102. package/dist/builtin-extensions/pi-web-access/gemini-search.js.map +1 -1
  103. package/dist/builtin-extensions/pi-web-access/github-extract.d.ts.map +1 -1
  104. package/dist/builtin-extensions/pi-web-access/github-extract.js +2 -0
  105. package/dist/builtin-extensions/pi-web-access/github-extract.js.map +1 -1
  106. package/dist/builtin-extensions/pi-web-access/index.d.ts.map +1 -1
  107. package/dist/builtin-extensions/pi-web-access/index.js +259 -168
  108. package/dist/builtin-extensions/pi-web-access/index.js.map +1 -1
  109. package/dist/builtin-extensions/pi-web-access/lazy.d.ts +18 -0
  110. package/dist/builtin-extensions/pi-web-access/lazy.d.ts.map +1 -0
  111. package/dist/builtin-extensions/pi-web-access/lazy.js +19 -0
  112. package/dist/builtin-extensions/pi-web-access/lazy.js.map +1 -0
  113. package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts +6 -0
  114. package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts.map +1 -0
  115. package/dist/builtin-extensions/pi-web-access/session-cleanup.js +17 -0
  116. package/dist/builtin-extensions/pi-web-access/session-cleanup.js.map +1 -0
  117. package/dist/catalog/publication.json +12 -12
  118. package/dist/cli-runtime.d.ts +3 -0
  119. package/dist/cli-runtime.d.ts.map +1 -0
  120. package/dist/cli-runtime.js +73 -0
  121. package/dist/cli-runtime.js.map +1 -0
  122. package/dist/cli.d.ts.map +1 -1
  123. package/dist/cli.js +14 -53
  124. package/dist/cli.js.map +1 -1
  125. package/dist/config.d.ts +1 -0
  126. package/dist/config.d.ts.map +1 -1
  127. package/dist/config.js +1 -0
  128. package/dist/config.js.map +1 -1
  129. package/dist/core/agent-session-services.d.ts.map +1 -1
  130. package/dist/core/agent-session-services.js +1 -1
  131. package/dist/core/agent-session-services.js.map +1 -1
  132. package/dist/core/agent-session.d.ts +3 -0
  133. package/dist/core/agent-session.d.ts.map +1 -1
  134. package/dist/core/agent-session.js +56 -12
  135. package/dist/core/agent-session.js.map +1 -1
  136. package/dist/core/compaction/compaction.d.ts.map +1 -1
  137. package/dist/core/compaction/compaction.js +10 -5
  138. package/dist/core/compaction/compaction.js.map +1 -1
  139. package/dist/core/computer-use/adapter.d.ts +23 -0
  140. package/dist/core/computer-use/adapter.d.ts.map +1 -0
  141. package/dist/core/computer-use/adapter.js +116 -0
  142. package/dist/core/computer-use/adapter.js.map +1 -0
  143. package/dist/core/computer-use/lease.d.ts +18 -0
  144. package/dist/core/computer-use/lease.d.ts.map +1 -0
  145. package/dist/core/computer-use/lease.js +129 -0
  146. package/dist/core/computer-use/lease.js.map +1 -0
  147. package/dist/core/computer-use/macos-runtime.d.ts +14 -0
  148. package/dist/core/computer-use/macos-runtime.d.ts.map +1 -0
  149. package/dist/core/computer-use/macos-runtime.js +148 -0
  150. package/dist/core/computer-use/macos-runtime.js.map +1 -0
  151. package/dist/core/computer-use/policy.d.ts +19 -0
  152. package/dist/core/computer-use/policy.d.ts.map +1 -0
  153. package/dist/core/computer-use/policy.js +66 -0
  154. package/dist/core/computer-use/policy.js.map +1 -0
  155. package/dist/core/computer-use/release.generated.d.ts +31 -0
  156. package/dist/core/computer-use/release.generated.d.ts.map +1 -0
  157. package/dist/core/computer-use/release.generated.js +36 -0
  158. package/dist/core/computer-use/release.generated.js.map +1 -0
  159. package/dist/core/computer-use/runtime.d.ts +13 -0
  160. package/dist/core/computer-use/runtime.d.ts.map +1 -0
  161. package/dist/core/computer-use/runtime.js +158 -0
  162. package/dist/core/computer-use/runtime.js.map +1 -0
  163. package/dist/core/computer-use/schemas.d.ts +88 -0
  164. package/dist/core/computer-use/schemas.d.ts.map +1 -0
  165. package/dist/core/computer-use/schemas.js +80 -0
  166. package/dist/core/computer-use/schemas.js.map +1 -0
  167. package/dist/core/computer-use/windows-desktop.d.ts +3 -0
  168. package/dist/core/computer-use/windows-desktop.d.ts.map +1 -0
  169. package/dist/core/computer-use/windows-desktop.js +48 -0
  170. package/dist/core/computer-use/windows-desktop.js.map +1 -0
  171. package/dist/core/computer-use/workflow.d.ts +24 -0
  172. package/dist/core/computer-use/workflow.d.ts.map +1 -0
  173. package/dist/core/computer-use/workflow.js +330 -0
  174. package/dist/core/computer-use/workflow.js.map +1 -0
  175. package/dist/core/extensions/host-static.d.ts.map +1 -1
  176. package/dist/core/extensions/host-static.js +34 -12
  177. package/dist/core/extensions/host-static.js.map +1 -1
  178. package/dist/core/extensions/loader.d.ts +1 -2
  179. package/dist/core/extensions/loader.d.ts.map +1 -1
  180. package/dist/core/extensions/loader.js +10 -64
  181. package/dist/core/extensions/loader.js.map +1 -1
  182. package/dist/core/extensions/types.d.ts +2 -2
  183. package/dist/core/extensions/types.d.ts.map +1 -1
  184. package/dist/core/extensions/types.js.map +1 -1
  185. package/dist/core/footer-data-provider.d.ts.map +1 -1
  186. package/dist/core/footer-data-provider.js +2 -0
  187. package/dist/core/footer-data-provider.js.map +1 -1
  188. package/dist/core/keybindings.d.ts +2 -2
  189. package/dist/core/keybindings.d.ts.map +1 -1
  190. package/dist/core/keybindings.js +2 -2
  191. package/dist/core/keybindings.js.map +1 -1
  192. package/dist/core/model-runtime.d.ts +0 -3
  193. package/dist/core/model-runtime.d.ts.map +1 -1
  194. package/dist/core/model-runtime.js +1 -10
  195. package/dist/core/model-runtime.js.map +1 -1
  196. package/dist/core/package-manager.d.ts.map +1 -1
  197. package/dist/core/package-manager.js +1 -1
  198. package/dist/core/package-manager.js.map +1 -1
  199. package/dist/core/permissions.d.ts +1 -3
  200. package/dist/core/permissions.d.ts.map +1 -1
  201. package/dist/core/permissions.js +33 -25
  202. package/dist/core/permissions.js.map +1 -1
  203. package/dist/core/plan-mode.d.ts.map +1 -1
  204. package/dist/core/plan-mode.js +9 -0
  205. package/dist/core/plan-mode.js.map +1 -1
  206. package/dist/core/rollback.d.ts.map +1 -1
  207. package/dist/core/rollback.js +13 -90
  208. package/dist/core/rollback.js.map +1 -1
  209. package/dist/core/sdk.d.ts +1 -1
  210. package/dist/core/sdk.d.ts.map +1 -1
  211. package/dist/core/sdk.js +1 -1
  212. package/dist/core/sdk.js.map +1 -1
  213. package/dist/core/session-manager.d.ts +0 -1
  214. package/dist/core/session-manager.d.ts.map +1 -1
  215. package/dist/core/session-manager.js +21 -79
  216. package/dist/core/session-manager.js.map +1 -1
  217. package/dist/core/settings-manager.d.ts +6 -0
  218. package/dist/core/settings-manager.d.ts.map +1 -1
  219. package/dist/core/settings-manager.js +19 -0
  220. package/dist/core/settings-manager.js.map +1 -1
  221. package/dist/core/slash-commands.d.ts.map +1 -1
  222. package/dist/core/slash-commands.js +0 -1
  223. package/dist/core/slash-commands.js.map +1 -1
  224. package/dist/core/timings.d.ts +2 -1
  225. package/dist/core/timings.d.ts.map +1 -1
  226. package/dist/core/timings.js +17 -2
  227. package/dist/core/timings.js.map +1 -1
  228. package/dist/dev-cli.js +0 -0
  229. package/dist/gateway/agent-bridge.d.ts +6 -1
  230. package/dist/gateway/agent-bridge.d.ts.map +1 -1
  231. package/dist/gateway/agent-bridge.js +23 -6
  232. package/dist/gateway/agent-bridge.js.map +1 -1
  233. package/dist/gateway/commands.d.ts +1 -1
  234. package/dist/gateway/commands.d.ts.map +1 -1
  235. package/dist/gateway/commands.js +1 -18
  236. package/dist/gateway/commands.js.map +1 -1
  237. package/dist/gateway/cron.d.ts +1 -1
  238. package/dist/gateway/cron.d.ts.map +1 -1
  239. package/dist/gateway/cron.js +23 -7
  240. package/dist/gateway/cron.js.map +1 -1
  241. package/dist/main.d.ts +2 -2
  242. package/dist/main.d.ts.map +1 -1
  243. package/dist/main.js +57 -48
  244. package/dist/main.js.map +1 -1
  245. package/dist/modes/interactive/components/footer.d.ts +4 -2
  246. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  247. package/dist/modes/interactive/components/footer.js +23 -32
  248. package/dist/modes/interactive/components/footer.js.map +1 -1
  249. package/dist/modes/interactive/components/processes-selector.d.ts +2 -3
  250. package/dist/modes/interactive/components/processes-selector.d.ts.map +1 -1
  251. package/dist/modes/interactive/components/processes-selector.js +5 -10
  252. package/dist/modes/interactive/components/processes-selector.js.map +1 -1
  253. package/dist/modes/interactive/components/settings-selector.d.ts +4 -0
  254. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  255. package/dist/modes/interactive/components/settings-selector.js +20 -0
  256. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  257. package/dist/modes/interactive/interactive-mode.d.ts +12 -21
  258. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  259. package/dist/modes/interactive/interactive-mode.js +138 -152
  260. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  261. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  262. package/dist/modes/interactive/theme/theme.js +95 -84
  263. package/dist/modes/interactive/theme/theme.js.map +1 -1
  264. package/dist/modes/interactive/thinking-level-slash.d.ts +4 -0
  265. package/dist/modes/interactive/thinking-level-slash.d.ts.map +1 -0
  266. package/dist/modes/interactive/thinking-level-slash.js +23 -0
  267. package/dist/modes/interactive/thinking-level-slash.js.map +1 -0
  268. package/dist/node-runtime/adapter-AZMY335J.js +279 -0
  269. package/dist/node-runtime/agent-session-services-RSGP5GDN.js +39 -0
  270. package/dist/node-runtime/benchmark-request-UC7PD3V3.js +57 -0
  271. package/dist/node-runtime/brave-UWDA3I22.js +143 -0
  272. package/dist/node-runtime/builtin-extensions-7STLFW3A.js +29 -0
  273. package/dist/node-runtime/chunk-2IDTZAG5.js +1415 -0
  274. package/dist/node-runtime/chunk-3GHXVUAK.js +21 -0
  275. package/dist/node-runtime/chunk-3RCWXWAY.js +466 -0
  276. package/dist/node-runtime/chunk-3WFAEVKS.js +115 -0
  277. package/dist/node-runtime/chunk-3X3KZKMI.js +49 -0
  278. package/dist/node-runtime/chunk-4HXHDDCF.js +16 -0
  279. package/dist/node-runtime/chunk-4SJWFTUP.js +24 -0
  280. package/dist/node-runtime/chunk-4ZWGEEAS.js +69 -0
  281. package/dist/node-runtime/chunk-53YJI7JU.js +137 -0
  282. package/dist/node-runtime/chunk-5NWQCSKR.js +19218 -0
  283. package/dist/node-runtime/chunk-5OLJGVCB.js +68 -0
  284. package/dist/node-runtime/chunk-5Q45AVQG.js +108 -0
  285. package/dist/node-runtime/chunk-5SQDLSZJ.js +949 -0
  286. package/dist/node-runtime/chunk-6SPPH4FY.js +1269 -0
  287. package/dist/node-runtime/chunk-6UB6NKA3.js +860 -0
  288. package/dist/node-runtime/chunk-7AFOFSDY.js +105 -0
  289. package/dist/node-runtime/chunk-7N3YHTYF.js +26 -0
  290. package/dist/node-runtime/chunk-ARC4KOTI.js +11178 -0
  291. package/dist/node-runtime/chunk-AUXVGBO4.js +19 -0
  292. package/dist/node-runtime/chunk-AY6CAJSL.js +30 -0
  293. package/dist/node-runtime/chunk-BHO7O6E5.js +296 -0
  294. package/dist/node-runtime/chunk-BI3DHYCN.js +8845 -0
  295. package/dist/node-runtime/chunk-BKAZ6BKX.js +2185 -0
  296. package/dist/node-runtime/chunk-BR7YDUKA.js +109 -0
  297. package/dist/node-runtime/chunk-BRJX2PRC.js +53 -0
  298. package/dist/node-runtime/chunk-C4O2RSQQ.js +37 -0
  299. package/dist/node-runtime/chunk-CCZJ3PYY.js +17 -0
  300. package/dist/node-runtime/chunk-CGBXPL3E.js +1171 -0
  301. package/dist/node-runtime/chunk-CH6OL6P2.js +295 -0
  302. package/dist/node-runtime/chunk-CJECDQKP.js +19 -0
  303. package/dist/node-runtime/chunk-DAPBPCBP.js +53 -0
  304. package/dist/node-runtime/chunk-DDGMHUOW.js +305 -0
  305. package/dist/node-runtime/chunk-DMMTJQMQ.js +43 -0
  306. package/dist/node-runtime/chunk-DVGWF6A2.js +1180 -0
  307. package/dist/node-runtime/chunk-EH2LJQPM.js +64 -0
  308. package/dist/node-runtime/chunk-EHMBW7FA.js +772 -0
  309. package/dist/node-runtime/chunk-FLYMHKCS.js +966 -0
  310. package/dist/node-runtime/chunk-FVDOXRUD.js +96 -0
  311. package/dist/node-runtime/chunk-GZQHMEWL.js +126 -0
  312. package/dist/node-runtime/chunk-H2EOZYMP.js +57 -0
  313. package/dist/node-runtime/chunk-HQCKFM2O.js +56 -0
  314. package/dist/node-runtime/chunk-HRS4HMDX.js +610 -0
  315. package/dist/node-runtime/chunk-HYHJIRDW.js +19 -0
  316. package/dist/node-runtime/chunk-I6R76AG7.js +22 -0
  317. package/dist/node-runtime/chunk-ISQDQIZN.js +296 -0
  318. package/dist/node-runtime/chunk-J7QGQD45.js +24921 -0
  319. package/dist/node-runtime/chunk-JHYKXIMM.js +378 -0
  320. package/dist/node-runtime/chunk-JT6YCS5B.js +5648 -0
  321. package/dist/node-runtime/chunk-JZHEUQRL.js +180 -0
  322. package/dist/node-runtime/chunk-K72NVGUB.js +2834 -0
  323. package/dist/node-runtime/chunk-KKSIVROT.js +88 -0
  324. package/dist/node-runtime/chunk-LCACDWHJ.js +1743 -0
  325. package/dist/node-runtime/chunk-LTXUQJI4.js +173 -0
  326. package/dist/node-runtime/chunk-LWJXTA6Z.js +6814 -0
  327. package/dist/node-runtime/chunk-M3LZLQW2.js +98 -0
  328. package/dist/node-runtime/chunk-MGSB2C3M.js +46 -0
  329. package/dist/node-runtime/chunk-MGWCVY6Y.js +47 -0
  330. package/dist/node-runtime/chunk-MJQDX3BA.js +72 -0
  331. package/dist/node-runtime/chunk-MUMMMTW4.js +8392 -0
  332. package/dist/node-runtime/chunk-MX3GJNXJ.js +986 -0
  333. package/dist/node-runtime/chunk-NUIFPZWX.js +209 -0
  334. package/dist/node-runtime/chunk-OBMWP3I5.js +68 -0
  335. package/dist/node-runtime/chunk-OR4L3IB2.js +42 -0
  336. package/dist/node-runtime/chunk-OTT6JMPU.js +807 -0
  337. package/dist/node-runtime/chunk-PCIGF2XK.js +250 -0
  338. package/dist/node-runtime/chunk-PL6JKXWI.js +3622 -0
  339. package/dist/node-runtime/chunk-PVCDKGR6.js +55 -0
  340. package/dist/node-runtime/chunk-Q4Q6D4IY.js +364 -0
  341. package/dist/node-runtime/chunk-Q5ZU2VRT.js +83 -0
  342. package/dist/node-runtime/chunk-QFWG2RVL.js +5477 -0
  343. package/dist/node-runtime/chunk-RQ2Q5IYR.js +72 -0
  344. package/dist/node-runtime/chunk-RQ5DNUNG.js +429 -0
  345. package/dist/node-runtime/chunk-RRIZE6QQ.js +17 -0
  346. package/dist/node-runtime/chunk-SN6G4OU6.js +4753 -0
  347. package/dist/node-runtime/chunk-SWSN6HAB.js +53 -0
  348. package/dist/node-runtime/chunk-T5GM5BFH.js +7558 -0
  349. package/dist/node-runtime/chunk-TAP7QTUT.js +1346 -0
  350. package/dist/node-runtime/chunk-U6C7VTR5.js +2033 -0
  351. package/dist/node-runtime/chunk-URD2SLIT.js +1019 -0
  352. package/dist/node-runtime/chunk-VRB2IYGG.js +53 -0
  353. package/dist/node-runtime/chunk-W3CVH5RX.js +62 -0
  354. package/dist/node-runtime/chunk-W7S2REEG.js +9478 -0
  355. package/dist/node-runtime/chunk-XBWPBZBN.js +125 -0
  356. package/dist/node-runtime/chunk-XTHQ7XR7.js +509 -0
  357. package/dist/node-runtime/chunk-ZCHMJ34K.js +130 -0
  358. package/dist/node-runtime/chunk-ZRDIMBEQ.js +651 -0
  359. package/dist/node-runtime/chunk-ZSEZY3II.js +247 -0
  360. package/dist/node-runtime/cli-runtime.js +81 -0
  361. package/dist/node-runtime/clipboard-OZ63BBC6.js +12 -0
  362. package/dist/node-runtime/clipboard-image-7QR6GXVA.js +13 -0
  363. package/dist/node-runtime/command-6UXQ6XZN.js +13 -0
  364. package/dist/node-runtime/commands-LGR5VT5X.js +293 -0
  365. package/dist/node-runtime/config-FMEOZSWE.js +77 -0
  366. package/dist/node-runtime/curator-server-XCM43VEF.js +3816 -0
  367. package/dist/node-runtime/customize-XEXL2DGQ.js +12 -0
  368. package/dist/node-runtime/direct-tool-executor-TDJS7TBD.js +191 -0
  369. package/dist/node-runtime/exa-LL64QZR2.js +329 -0
  370. package/dist/node-runtime/export-html-E4DT6ZJQ.js +150 -0
  371. package/dist/node-runtime/extension-input-RV5N6APL.js +14 -0
  372. package/dist/node-runtime/extension-selector-CPD5LWDD.js +14 -0
  373. package/dist/node-runtime/extract-IUCVZCWC.js +17 -0
  374. package/dist/node-runtime/file-sync-HCOP2QVF.js +117 -0
  375. package/dist/node-runtime/gateway-3OLC4GQN.js +2139 -0
  376. package/dist/node-runtime/gemini-api-QE7ANVDZ.js +29 -0
  377. package/dist/node-runtime/gemini-search-NCIDF7NE.js +330 -0
  378. package/dist/node-runtime/gemini-url-context-OKIN7AIP.js +103 -0
  379. package/dist/node-runtime/gemini-web-MM446SEH.js +14 -0
  380. package/dist/node-runtime/github-extract-F64RZOEA.js +619 -0
  381. package/dist/node-runtime/goal-CZQ7FFQJ.js +1831 -0
  382. package/dist/node-runtime/image-resize-6ZPBFMWW.js +11 -0
  383. package/dist/node-runtime/index.js +863 -0
  384. package/dist/node-runtime/init-EKE277AG.js +30 -0
  385. package/dist/node-runtime/install-cli-TH7IJJQQ.js +308 -0
  386. package/dist/node-runtime/interactive-mode-S5M26CQ7.js +59 -0
  387. package/dist/node-runtime/interactive-view-N6F4KUIT.js +247 -0
  388. package/dist/node-runtime/lsp-manager-3ASUSO4T.js +1104 -0
  389. package/dist/node-runtime/lunr-computer-use-4X3KUNF4.js +206 -0
  390. package/dist/node-runtime/lunr-cron-KKBOGAEF.js +274 -0
  391. package/dist/node-runtime/main.js +57 -0
  392. package/dist/node-runtime/mcp-auth-flow-YL6RWPYG.js +33 -0
  393. package/dist/node-runtime/mcp-panel-IIGMXQGP.js +501 -0
  394. package/dist/node-runtime/mcp-setup-panel-FEK7663I.js +355 -0
  395. package/dist/node-runtime/memory-cap-3S4XRLNP.js +20 -0
  396. package/dist/node-runtime/model-tiers-NJLHUEGK.js +20 -0
  397. package/dist/node-runtime/openai-search-B3MSNCQA.js +288 -0
  398. package/dist/node-runtime/package-manager-cli-C4EJOO5Q.js +751 -0
  399. package/dist/node-runtime/parallel-AI2MNSCU.js +265 -0
  400. package/dist/node-runtime/parser-manager-TQHWYDH7.js +152 -0
  401. package/dist/node-runtime/pdf-extract-IPE6H4HP.js +57 -0
  402. package/dist/node-runtime/perplexity-QVJW3I35.js +12 -0
  403. package/dist/node-runtime/pi-intercom-EEMBGQID.js +2215 -0
  404. package/dist/node-runtime/pi-mcp-adapter-DPTJGAAL.js +428 -0
  405. package/dist/node-runtime/pi-ollama-cloud-4VZRMULP.js +1440 -0
  406. package/dist/node-runtime/pi-prompt-template-model-4QT4LLXF.js +3946 -0
  407. package/dist/node-runtime/pi-subagents-VKCLYIBY.js +6050 -0
  408. package/dist/node-runtime/pi-web-access-BV6DSZOP.js +1867 -0
  409. package/dist/node-runtime/print-mode-VWIRFDAC.js +12 -0
  410. package/dist/node-runtime/proxy-modes-R64LU6WZ.js +688 -0
  411. package/dist/node-runtime/rpc-entry.js +65 -0
  412. package/dist/node-runtime/rpc-mode-SJNSOA4G.js +13 -0
  413. package/dist/node-runtime/runtime-3SB5ATHQ.js +21 -0
  414. package/dist/node-runtime/runtime-bridges-UJ5WJJLN.js +14 -0
  415. package/dist/node-runtime/session-manager-QEMZBMTM.js +33 -0
  416. package/dist/node-runtime/session-selector-URVJLOTK.js +14 -0
  417. package/dist/node-runtime/settings-manager-K6IPIQTI.js +23 -0
  418. package/dist/node-runtime/src-GPFAU3N6.js +2427 -0
  419. package/dist/node-runtime/subagent-executor-EFLTO32A.js +8501 -0
  420. package/dist/node-runtime/summary-review-YSMXKITO.js +228 -0
  421. package/dist/node-runtime/tavily-WEZFVFP7.js +154 -0
  422. package/dist/node-runtime/timings-UAD5BEAS.js +16 -0
  423. package/dist/node-runtime/tool-renderer-MV5O452K.js +204 -0
  424. package/dist/node-runtime/update-cli-I6OVDRPL.js +75 -0
  425. package/dist/node-runtime/v4-5MNC3H7G.js +424 -0
  426. package/dist/node-runtime/video-extract-ETA5RA7U.js +304 -0
  427. package/dist/node-runtime/workflow-SA34S4VX.js +325 -0
  428. package/dist/node-runtime/workspace-index-6DBXSTJ6.js +163 -0
  429. package/dist/node-runtime/youtube-extract-SRVGNN26.js +264 -0
  430. package/dist/rpc.d.ts +3 -0
  431. package/dist/rpc.d.ts.map +1 -0
  432. package/dist/rpc.js +18 -0
  433. package/dist/rpc.js.map +1 -0
  434. package/dist/startup/benchmark-request.d.ts +3 -0
  435. package/dist/startup/benchmark-request.d.ts.map +1 -0
  436. package/dist/startup/benchmark-request.js +65 -0
  437. package/dist/startup/benchmark-request.js.map +1 -0
  438. package/dist/startup/{interactive-shell.d.ts → interactive-view.d.ts} +18 -18
  439. package/dist/startup/interactive-view.d.ts.map +1 -0
  440. package/dist/startup/{interactive-shell.js → interactive-view.js} +119 -52
  441. package/dist/startup/interactive-view.js.map +1 -0
  442. package/dist/startup/launch-routing.d.ts.map +1 -1
  443. package/dist/startup/launch-routing.js +9 -10
  444. package/dist/startup/launch-routing.js.map +1 -1
  445. package/dist/startup/startup-milestones.d.ts +1 -1
  446. package/dist/startup/startup-milestones.d.ts.map +1 -1
  447. package/dist/startup/startup-milestones.js +3 -2
  448. package/dist/startup/startup-milestones.js.map +1 -1
  449. package/dist/utils/await-with-abort.d.ts +2 -0
  450. package/dist/utils/await-with-abort.d.ts.map +1 -0
  451. package/dist/utils/await-with-abort.js +19 -0
  452. package/dist/utils/await-with-abort.js.map +1 -0
  453. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  454. package/dist/utils/syntax-highlight.js +10 -4
  455. package/dist/utils/syntax-highlight.js.map +1 -1
  456. package/docs/compaction.md +5 -3
  457. package/docs/computer-use.md +277 -0
  458. package/docs/development.md +5 -33
  459. package/docs/features.md +2 -3
  460. package/docs/interactive-startup.md +105 -0
  461. package/docs/keybindings.md +2 -2
  462. package/docs/terminal-setup.md +1 -1
  463. package/docs/usage.md +1 -2
  464. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  465. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  466. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  467. package/examples/extensions/gondolin/package-lock.json +2 -2
  468. package/examples/extensions/gondolin/package.json +1 -1
  469. package/examples/extensions/hidden-thinking-label.ts +1 -1
  470. package/examples/extensions/sandbox/package-lock.json +2 -2
  471. package/examples/extensions/sandbox/package.json +1 -1
  472. package/examples/extensions/with-deps/package-lock.json +2 -2
  473. package/examples/extensions/with-deps/package.json +1 -1
  474. package/install-lock/package-lock.json +3827 -0
  475. package/install-lock/package.json +18 -0
  476. package/native/computer-use/LICENSE.md +21 -0
  477. package/npm-shrinkwrap.json +3808 -0
  478. package/package.json +30 -24
  479. package/dist/core/swarm.d.ts +0 -23
  480. package/dist/core/swarm.d.ts.map +0 -1
  481. package/dist/core/swarm.js +0 -45
  482. package/dist/core/swarm.js.map +0 -1
  483. package/dist/startup/interactive-shell.d.ts.map +0 -1
  484. package/dist/startup/interactive-shell.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lease.d.ts","sourceRoot":"","sources":["../../../src/core/computer-use/lease.ts"],"names":[],"mappings":"AAOA,qBAAa,YAAY;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IACzC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,IAAI,CAAuC;IACnD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAyB;IACpD,IAAI,MAAM,IAAI,WAAW,CAExB;IACD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,YAAY,SAAS,SAA+C,EAEnE;YAEa,KAAK;YAwBL,aAAa;YAab,UAAU;YAUV,OAAO;IAwBf,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ7C;IAED,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAepE;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAU3B;CACD","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { mkdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { userInfo } from \"node:os\";\nimport { join } from \"node:path\";\nimport lockfile from \"proper-lockfile\";\nimport { assertOwnedPath } from \"./runtime.ts\";\n\nexport class DesktopLease {\n\tprivate readonly identity = randomUUID();\n\tprivate owned = false;\n\tprivate tail: Promise<unknown> = Promise.resolve();\n\tprivate closed = false;\n\tprivate readonly controller = new AbortController();\n\tget signal(): AbortSignal {\n\t\treturn this.controller.signal;\n\t}\n\tprivate readonly directory: string;\n\tconstructor(directory = join(userInfo().homedir, \".lunr\", \"desktop\")) {\n\t\tthis.directory = directory;\n\t}\n\n\tprivate async owner(): Promise<{ pid: number; identity: string; processes: number[] } | undefined> {\n\t\ttry {\n\t\t\tconst value: unknown = JSON.parse(await readFile(join(this.directory, \"workflow-owner.json\"), \"utf8\"));\n\t\t\tif (\n\t\t\t\t!value ||\n\t\t\t\ttypeof value !== \"object\" ||\n\t\t\t\t!(\"pid\" in value) ||\n\t\t\t\ttypeof value.pid !== \"number\" ||\n\t\t\t\t!Number.isInteger(value.pid) ||\n\t\t\t\tvalue.pid < 1 ||\n\t\t\t\t!(\"identity\" in value) ||\n\t\t\t\ttypeof value.identity !== \"string\"\n\t\t\t)\n\t\t\t\tthrow new Error(\"Invalid desktop owner record; refusing takeover.\");\n\t\t\tconst processes = \"processes\" in value ? value.processes : [];\n\t\t\tif (!Array.isArray(processes) || !processes.every((pid) => Number.isInteger(pid) && pid > 0))\n\t\t\t\tthrow new Error(\"Invalid runtime owner record; refusing takeover.\");\n\t\t\treturn { pid: value.pid, identity: value.identity, processes };\n\t\t} catch (error) {\n\t\t\tif (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") return undefined;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate async withOwnerLock(operation: () => Promise<void>): Promise<void> {\n\t\tconst release = await lockfile.lock(this.directory, {\n\t\t\tlockfilePath: join(this.directory, \"workflow-acquire.lock\"),\n\t\t\tretries: 0,\n\t\t\tstale: 10000,\n\t\t});\n\t\ttry {\n\t\t\tawait operation();\n\t\t} finally {\n\t\t\tawait release();\n\t\t}\n\t}\n\n\tprivate async writeOwner(owner: { pid: number; identity: string; processes?: number[] }): Promise<void> {\n\t\tconst temporary = join(this.directory, `workflow-owner-${randomUUID()}.tmp`);\n\t\ttry {\n\t\t\tawait writeFile(temporary, JSON.stringify(owner), { mode: 0o600, flag: \"wx\" });\n\t\t\tawait rename(temporary, join(this.directory, \"workflow-owner.json\"));\n\t\t} finally {\n\t\t\tawait rm(temporary, { force: true });\n\t\t}\n\t}\n\n\tprivate async acquire(): Promise<void> {\n\t\tawait assertOwnedPath(this.directory);\n\t\tawait mkdir(this.directory, { recursive: true, mode: 0o700 });\n\t\tawait this.withOwnerLock(async () => {\n\t\t\tconst owner = await this.owner();\n\t\t\tif (owner) {\n\t\t\t\tconst alive = [owner.pid, ...owner.processes].some((pid) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tprocess.kill(pid, 0);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\treturn !(error instanceof Error && \"code\" in error && error.code === \"ESRCH\");\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tif (alive)\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\"Desktop busy: another lunR workflow owns this user's desktop. Retry only after it ends.\",\n\t\t\t\t\t);\n\t\t\t}\n\t\t\tawait this.writeOwner({ pid: process.pid, identity: this.identity });\n\t\t\tthis.owned = true;\n\t\t});\n\t}\n\n\tasync trackProcess(pid: number): Promise<void> {\n\t\tawait this.withOwnerLock(async () => {\n\t\t\tconst owner = await this.owner();\n\t\t\tif (!owner || owner.identity !== this.identity || !Number.isInteger(pid) || pid < 1)\n\t\t\t\tthrow new Error(\"Cannot bind runtime to the desktop lease.\");\n\t\t\tif (!owner.processes.includes(pid)) owner.processes.push(pid);\n\t\t\tawait this.writeOwner(owner);\n\t\t});\n\t}\n\n\trun<T>(operation: () => Promise<T>, signal?: AbortSignal): Promise<T> {\n\t\tconst result = this.tail.then(async () => {\n\t\t\tif (this.closed) throw new Error(\"Desktop workflow ended. Start a new workflow and observe again.\");\n\t\t\tsignal?.throwIfAborted();\n\t\t\tif (!this.owned) await this.acquire();\n\t\t\tif ((await this.owner())?.identity !== this.identity) {\n\t\t\t\tthis.closed = true;\n\t\t\t\tthis.controller.abort(new Error(\"Desktop lease lost.\"));\n\t\t\t\tthrow new Error(\"Desktop lease lost. Input refused.\");\n\t\t\t}\n\t\t\tsignal?.throwIfAborted();\n\t\t\treturn operation();\n\t\t});\n\t\tthis.tail = result.catch(() => undefined);\n\t\treturn result;\n\t}\n\n\tasync close(): Promise<void> {\n\t\tthis.closed = true;\n\t\tthis.controller.abort();\n\t\tawait this.tail;\n\t\tif (this.owned) {\n\t\t\tawait this.withOwnerLock(async () => {\n\t\t\t\tif ((await this.owner())?.identity === this.identity) await rm(join(this.directory, \"workflow-owner.json\"));\n\t\t\t});\n\t\t\tthis.owned = false;\n\t\t}\n\t}\n}\n"]}
@@ -0,0 +1,129 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
3
+ import { userInfo } from "node:os";
4
+ import { join } from "node:path";
5
+ import lockfile from "proper-lockfile";
6
+ import { assertOwnedPath } from "./runtime.js";
7
+ export class DesktopLease {
8
+ identity = randomUUID();
9
+ owned = false;
10
+ tail = Promise.resolve();
11
+ closed = false;
12
+ controller = new AbortController();
13
+ get signal() {
14
+ return this.controller.signal;
15
+ }
16
+ directory;
17
+ constructor(directory = join(userInfo().homedir, ".lunr", "desktop")) {
18
+ this.directory = directory;
19
+ }
20
+ async owner() {
21
+ try {
22
+ const value = JSON.parse(await readFile(join(this.directory, "workflow-owner.json"), "utf8"));
23
+ if (!value ||
24
+ typeof value !== "object" ||
25
+ !("pid" in value) ||
26
+ typeof value.pid !== "number" ||
27
+ !Number.isInteger(value.pid) ||
28
+ value.pid < 1 ||
29
+ !("identity" in value) ||
30
+ typeof value.identity !== "string")
31
+ throw new Error("Invalid desktop owner record; refusing takeover.");
32
+ const processes = "processes" in value ? value.processes : [];
33
+ if (!Array.isArray(processes) || !processes.every((pid) => Number.isInteger(pid) && pid > 0))
34
+ throw new Error("Invalid runtime owner record; refusing takeover.");
35
+ return { pid: value.pid, identity: value.identity, processes };
36
+ }
37
+ catch (error) {
38
+ if (error instanceof Error && "code" in error && error.code === "ENOENT")
39
+ return undefined;
40
+ throw error;
41
+ }
42
+ }
43
+ async withOwnerLock(operation) {
44
+ const release = await lockfile.lock(this.directory, {
45
+ lockfilePath: join(this.directory, "workflow-acquire.lock"),
46
+ retries: 0,
47
+ stale: 10000,
48
+ });
49
+ try {
50
+ await operation();
51
+ }
52
+ finally {
53
+ await release();
54
+ }
55
+ }
56
+ async writeOwner(owner) {
57
+ const temporary = join(this.directory, `workflow-owner-${randomUUID()}.tmp`);
58
+ try {
59
+ await writeFile(temporary, JSON.stringify(owner), { mode: 0o600, flag: "wx" });
60
+ await rename(temporary, join(this.directory, "workflow-owner.json"));
61
+ }
62
+ finally {
63
+ await rm(temporary, { force: true });
64
+ }
65
+ }
66
+ async acquire() {
67
+ await assertOwnedPath(this.directory);
68
+ await mkdir(this.directory, { recursive: true, mode: 0o700 });
69
+ await this.withOwnerLock(async () => {
70
+ const owner = await this.owner();
71
+ if (owner) {
72
+ const alive = [owner.pid, ...owner.processes].some((pid) => {
73
+ try {
74
+ process.kill(pid, 0);
75
+ return true;
76
+ }
77
+ catch (error) {
78
+ return !(error instanceof Error && "code" in error && error.code === "ESRCH");
79
+ }
80
+ });
81
+ if (alive)
82
+ throw new Error("Desktop busy: another lunR workflow owns this user's desktop. Retry only after it ends.");
83
+ }
84
+ await this.writeOwner({ pid: process.pid, identity: this.identity });
85
+ this.owned = true;
86
+ });
87
+ }
88
+ async trackProcess(pid) {
89
+ await this.withOwnerLock(async () => {
90
+ const owner = await this.owner();
91
+ if (!owner || owner.identity !== this.identity || !Number.isInteger(pid) || pid < 1)
92
+ throw new Error("Cannot bind runtime to the desktop lease.");
93
+ if (!owner.processes.includes(pid))
94
+ owner.processes.push(pid);
95
+ await this.writeOwner(owner);
96
+ });
97
+ }
98
+ run(operation, signal) {
99
+ const result = this.tail.then(async () => {
100
+ if (this.closed)
101
+ throw new Error("Desktop workflow ended. Start a new workflow and observe again.");
102
+ signal?.throwIfAborted();
103
+ if (!this.owned)
104
+ await this.acquire();
105
+ if ((await this.owner())?.identity !== this.identity) {
106
+ this.closed = true;
107
+ this.controller.abort(new Error("Desktop lease lost."));
108
+ throw new Error("Desktop lease lost. Input refused.");
109
+ }
110
+ signal?.throwIfAborted();
111
+ return operation();
112
+ });
113
+ this.tail = result.catch(() => undefined);
114
+ return result;
115
+ }
116
+ async close() {
117
+ this.closed = true;
118
+ this.controller.abort();
119
+ await this.tail;
120
+ if (this.owned) {
121
+ await this.withOwnerLock(async () => {
122
+ if ((await this.owner())?.identity === this.identity)
123
+ await rm(join(this.directory, "workflow-owner.json"));
124
+ });
125
+ this.owned = false;
126
+ }
127
+ }
128
+ }
129
+ //# sourceMappingURL=lease.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lease.js","sourceRoot":"","sources":["../../../src/core/computer-use/lease.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { mkdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { userInfo } from \"node:os\";\nimport { join } from \"node:path\";\nimport lockfile from \"proper-lockfile\";\nimport { assertOwnedPath } from \"./runtime.ts\";\n\nexport class DesktopLease {\n\tprivate readonly identity = randomUUID();\n\tprivate owned = false;\n\tprivate tail: Promise<unknown> = Promise.resolve();\n\tprivate closed = false;\n\tprivate readonly controller = new AbortController();\n\tget signal(): AbortSignal {\n\t\treturn this.controller.signal;\n\t}\n\tprivate readonly directory: string;\n\tconstructor(directory = join(userInfo().homedir, \".lunr\", \"desktop\")) {\n\t\tthis.directory = directory;\n\t}\n\n\tprivate async owner(): Promise<{ pid: number; identity: string; processes: number[] } | undefined> {\n\t\ttry {\n\t\t\tconst value: unknown = JSON.parse(await readFile(join(this.directory, \"workflow-owner.json\"), \"utf8\"));\n\t\t\tif (\n\t\t\t\t!value ||\n\t\t\t\ttypeof value !== \"object\" ||\n\t\t\t\t!(\"pid\" in value) ||\n\t\t\t\ttypeof value.pid !== \"number\" ||\n\t\t\t\t!Number.isInteger(value.pid) ||\n\t\t\t\tvalue.pid < 1 ||\n\t\t\t\t!(\"identity\" in value) ||\n\t\t\t\ttypeof value.identity !== \"string\"\n\t\t\t)\n\t\t\t\tthrow new Error(\"Invalid desktop owner record; refusing takeover.\");\n\t\t\tconst processes = \"processes\" in value ? value.processes : [];\n\t\t\tif (!Array.isArray(processes) || !processes.every((pid) => Number.isInteger(pid) && pid > 0))\n\t\t\t\tthrow new Error(\"Invalid runtime owner record; refusing takeover.\");\n\t\t\treturn { pid: value.pid, identity: value.identity, processes };\n\t\t} catch (error) {\n\t\t\tif (error instanceof Error && \"code\" in error && error.code === \"ENOENT\") return undefined;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tprivate async withOwnerLock(operation: () => Promise<void>): Promise<void> {\n\t\tconst release = await lockfile.lock(this.directory, {\n\t\t\tlockfilePath: join(this.directory, \"workflow-acquire.lock\"),\n\t\t\tretries: 0,\n\t\t\tstale: 10000,\n\t\t});\n\t\ttry {\n\t\t\tawait operation();\n\t\t} finally {\n\t\t\tawait release();\n\t\t}\n\t}\n\n\tprivate async writeOwner(owner: { pid: number; identity: string; processes?: number[] }): Promise<void> {\n\t\tconst temporary = join(this.directory, `workflow-owner-${randomUUID()}.tmp`);\n\t\ttry {\n\t\t\tawait writeFile(temporary, JSON.stringify(owner), { mode: 0o600, flag: \"wx\" });\n\t\t\tawait rename(temporary, join(this.directory, \"workflow-owner.json\"));\n\t\t} finally {\n\t\t\tawait rm(temporary, { force: true });\n\t\t}\n\t}\n\n\tprivate async acquire(): Promise<void> {\n\t\tawait assertOwnedPath(this.directory);\n\t\tawait mkdir(this.directory, { recursive: true, mode: 0o700 });\n\t\tawait this.withOwnerLock(async () => {\n\t\t\tconst owner = await this.owner();\n\t\t\tif (owner) {\n\t\t\t\tconst alive = [owner.pid, ...owner.processes].some((pid) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tprocess.kill(pid, 0);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\treturn !(error instanceof Error && \"code\" in error && error.code === \"ESRCH\");\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tif (alive)\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\"Desktop busy: another lunR workflow owns this user's desktop. Retry only after it ends.\",\n\t\t\t\t\t);\n\t\t\t}\n\t\t\tawait this.writeOwner({ pid: process.pid, identity: this.identity });\n\t\t\tthis.owned = true;\n\t\t});\n\t}\n\n\tasync trackProcess(pid: number): Promise<void> {\n\t\tawait this.withOwnerLock(async () => {\n\t\t\tconst owner = await this.owner();\n\t\t\tif (!owner || owner.identity !== this.identity || !Number.isInteger(pid) || pid < 1)\n\t\t\t\tthrow new Error(\"Cannot bind runtime to the desktop lease.\");\n\t\t\tif (!owner.processes.includes(pid)) owner.processes.push(pid);\n\t\t\tawait this.writeOwner(owner);\n\t\t});\n\t}\n\n\trun<T>(operation: () => Promise<T>, signal?: AbortSignal): Promise<T> {\n\t\tconst result = this.tail.then(async () => {\n\t\t\tif (this.closed) throw new Error(\"Desktop workflow ended. Start a new workflow and observe again.\");\n\t\t\tsignal?.throwIfAborted();\n\t\t\tif (!this.owned) await this.acquire();\n\t\t\tif ((await this.owner())?.identity !== this.identity) {\n\t\t\t\tthis.closed = true;\n\t\t\t\tthis.controller.abort(new Error(\"Desktop lease lost.\"));\n\t\t\t\tthrow new Error(\"Desktop lease lost. Input refused.\");\n\t\t\t}\n\t\t\tsignal?.throwIfAborted();\n\t\t\treturn operation();\n\t\t});\n\t\tthis.tail = result.catch(() => undefined);\n\t\treturn result;\n\t}\n\n\tasync close(): Promise<void> {\n\t\tthis.closed = true;\n\t\tthis.controller.abort();\n\t\tawait this.tail;\n\t\tif (this.owned) {\n\t\t\tawait this.withOwnerLock(async () => {\n\t\t\t\tif ((await this.owner())?.identity === this.identity) await rm(join(this.directory, \"workflow-owner.json\"));\n\t\t\t});\n\t\t\tthis.owned = false;\n\t\t}\n\t}\n}\n"]}
@@ -0,0 +1,14 @@
1
+ export declare function macLaunchArguments(app: string, socket: string, home: string, lifetime: string): string[];
2
+ export declare class MacRuntime {
3
+ private directory?;
4
+ private lifetime?;
5
+ private exited?;
6
+ private pid?;
7
+ get processId(): number | undefined;
8
+ private socket?;
9
+ private closing?;
10
+ start(app: string, signal: AbortSignal): Promise<string>;
11
+ close(): Promise<void>;
12
+ private stop;
13
+ }
14
+ //# sourceMappingURL=macos-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"macos-runtime.d.ts","sourceRoot":"","sources":["../../../src/core/computer-use/macos-runtime.ts"],"names":[],"mappings":"AAYA,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAwBxG;AAoCD,qBAAa,UAAU;IACtB,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,CAAa;IAC9B,OAAO,CAAC,MAAM,CAAC,CAAgB;IAC/B,OAAO,CAAC,GAAG,CAAC,CAAS;IACrB,IAAI,SAAS,IAAI,MAAM,GAAG,SAAS,CAElC;IACD,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,OAAO,CAAC,CAAgB;IAE1B,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CA8C7D;IAED,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAGrB;YAEa,IAAI;CAoBlB","sourcesContent":["import { execFile, spawn } from \"node:child_process\";\nimport { constants } from \"node:fs\";\nimport { type FileHandle, mkdtemp, open, realpath, rm } from \"node:fs/promises\";\nimport { connect } from \"node:net\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { setTimeout as delay } from \"node:timers/promises\";\nimport { promisify } from \"node:util\";\nimport { CUA_VERSION, runtimeEnvironment } from \"./runtime.ts\";\n\nconst exec = promisify(execFile);\n\nexport function macLaunchArguments(app: string, socket: string, home: string, lifetime: string): string[] {\n\tconst environment = {\n\t\tHOME: home,\n\t\t...Object.fromEntries(Object.entries(runtimeEnvironment()).filter(([name]) => name.startsWith(\"CUA_\"))),\n\t};\n\treturn [\n\t\t\"-n\",\n\t\t\"-g\",\n\t\t\"-W\",\n\t\t\"-a\",\n\t\tapp,\n\t\t\"--stdin\",\n\t\tlifetime,\n\t\t...Object.entries(environment).flatMap(([name, value]) => [\"--env\", `${name}=${value}`]),\n\t\t\"--args\",\n\t\t\"serve\",\n\t\t\"--embedded\",\n\t\t\"--parent-liveness-stdio\",\n\t\t\"--socket\",\n\t\tsocket,\n\t\t\"--permission-mode\",\n\t\t\"standard\",\n\t\t\"--no-overlay\",\n\t];\n}\n\nfunction request(socket: string, method: string, args?: Record<string, unknown>): Promise<Record<string, unknown>> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst stream = connect(socket);\n\t\tlet buffer = \"\";\n\t\tstream.setTimeout(1000, () => stream.destroy(new Error(\"Private computer endpoint timed out.\")));\n\t\tstream.on(\"error\", reject);\n\t\tstream.on(\"connect\", () => stream.write(`${JSON.stringify({ method, args })}\\n`));\n\t\tstream.on(\"data\", (chunk) => {\n\t\t\tbuffer += chunk.toString();\n\t\t\tif (buffer.length > 65536) {\n\t\t\t\tstream.destroy(new Error(\"Invalid private endpoint metadata.\"));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!buffer.includes(\"\\n\")) return;\n\t\t\ttry {\n\t\t\t\tconst reply: unknown = JSON.parse(buffer.slice(0, buffer.indexOf(\"\\n\")));\n\t\t\t\tif (\n\t\t\t\t\t!reply ||\n\t\t\t\t\ttypeof reply !== \"object\" ||\n\t\t\t\t\t!(\"result\" in reply) ||\n\t\t\t\t\t!reply.result ||\n\t\t\t\t\ttypeof reply.result !== \"object\"\n\t\t\t\t)\n\t\t\t\t\tthrow new Error(\"Private endpoint refused metadata.\");\n\t\t\t\tresolve(Object.fromEntries(Object.entries(reply.result)));\n\t\t\t} catch (error) {\n\t\t\t\treject(error);\n\t\t\t}\n\t\t\tstream.destroy();\n\t\t});\n\t\tstream.on(\"end\", () => reject(new Error(\"Private computer endpoint closed.\")));\n\t});\n}\n\nexport class MacRuntime {\n\tprivate directory?: string;\n\tprivate lifetime?: FileHandle;\n\tprivate exited?: Promise<void>;\n\tprivate pid?: number;\n\tget processId(): number | undefined {\n\t\treturn this.pid;\n\t}\n\tprivate socket?: string;\n\tprivate closing?: Promise<void>;\n\n\tasync start(app: string, signal: AbortSignal): Promise<string> {\n\t\tconst directory = await mkdtemp(join(await realpath(tmpdir()), \"lunr-cua-\"));\n\t\tthis.directory = directory;\n\t\tconst socket = join(directory, \"driver.sock\");\n\t\tthis.socket = socket;\n\t\tconst lifetime = join(directory, \"lifetime\");\n\t\tawait exec(\"/usr/bin/mkfifo\", [\"-m\", \"600\", lifetime], { timeout: 5000, signal });\n\t\tthis.lifetime = await open(lifetime, constants.O_RDWR);\n\t\tsignal.throwIfAborted();\n\t\tconst launcher = spawn(\"/usr/bin/open\", macLaunchArguments(app, socket, directory, lifetime), {\n\t\t\tenv: runtimeEnvironment(),\n\t\t\tstdio: \"ignore\",\n\t\t});\n\t\tthis.exited = new Promise<void>((resolve, reject) => {\n\t\t\tlauncher.once(\"error\", reject);\n\t\t\tlauncher.once(\"exit\", (code) =>\n\t\t\t\tcode === 0 ? resolve() : reject(new Error(`LaunchServices exited ${code}.`)),\n\t\t\t);\n\t\t});\n\t\tvoid this.exited.catch(() => undefined);\n\t\tconst deadline = Date.now() + 15000;\n\t\twhile (Date.now() < deadline) {\n\t\t\tsignal.throwIfAborted();\n\t\t\ttry {\n\t\t\t\tconst metadata = await request(socket, \"metadata\");\n\t\t\t\tif (\n\t\t\t\t\tmetadata.driver_version !== CUA_VERSION ||\n\t\t\t\t\tmetadata.embedded !== true ||\n\t\t\t\t\ttypeof metadata.pid !== \"number\" ||\n\t\t\t\t\tmetadata.pid < 1\n\t\t\t\t)\n\t\t\t\t\tthrow new Error(\"Private runtime has incompatible metadata.\");\n\t\t\t\tthis.pid = metadata.pid;\n\t\t\t\treturn socket;\n\t\t\t} catch {\n\t\t\t\tawait Promise.race([\n\t\t\t\t\tdelay(100, undefined, { signal }),\n\t\t\t\t\tthis.exited.then(() => {\n\t\t\t\t\t\tthrow new Error(\"Computer app exited during startup.\");\n\t\t\t\t\t}),\n\t\t\t\t]);\n\t\t\t}\n\t\t}\n\t\tthrow new Error(\n\t\t\t\"Private macOS runtime startup timed out. Check CuaDriver Accessibility and Screen Recording grants.\",\n\t\t);\n\t}\n\n\tclose(): Promise<void> {\n\t\tthis.closing ??= this.stop();\n\t\treturn this.closing;\n\t}\n\n\tprivate async stop(): Promise<void> {\n\t\tawait this.lifetime?.close();\n\t\tthis.lifetime = undefined;\n\t\tif (this.socket && this.pid)\n\t\t\tawait request(this.socket, \"shutdown_if_pid\", { expected_pid: this.pid }).catch(() => undefined);\n\t\tif (this.exited) {\n\t\t\tconst timeout = new AbortController();\n\t\t\ttry {\n\t\t\t\tawait Promise.race([\n\t\t\t\t\tthis.exited,\n\t\t\t\t\tdelay(10000, undefined, { signal: timeout.signal }).then(() => {\n\t\t\t\t\t\tthrow new Error(\"Owned macOS app shutdown is unconfirmed. Desktop lease retained.\");\n\t\t\t\t\t}),\n\t\t\t\t]);\n\t\t\t} finally {\n\t\t\t\ttimeout.abort();\n\t\t\t}\n\t\t}\n\t\tif (this.directory) await rm(this.directory, { recursive: true, force: true });\n\t}\n}\n"]}
@@ -0,0 +1,148 @@
1
+ import { execFile, spawn } from "node:child_process";
2
+ import { constants } from "node:fs";
3
+ import { mkdtemp, open, realpath, rm } from "node:fs/promises";
4
+ import { connect } from "node:net";
5
+ import { tmpdir } from "node:os";
6
+ import { join } from "node:path";
7
+ import { setTimeout as delay } from "node:timers/promises";
8
+ import { promisify } from "node:util";
9
+ import { CUA_VERSION, runtimeEnvironment } from "./runtime.js";
10
+ const exec = promisify(execFile);
11
+ export function macLaunchArguments(app, socket, home, lifetime) {
12
+ const environment = {
13
+ HOME: home,
14
+ ...Object.fromEntries(Object.entries(runtimeEnvironment()).filter(([name]) => name.startsWith("CUA_"))),
15
+ };
16
+ return [
17
+ "-n",
18
+ "-g",
19
+ "-W",
20
+ "-a",
21
+ app,
22
+ "--stdin",
23
+ lifetime,
24
+ ...Object.entries(environment).flatMap(([name, value]) => ["--env", `${name}=${value}`]),
25
+ "--args",
26
+ "serve",
27
+ "--embedded",
28
+ "--parent-liveness-stdio",
29
+ "--socket",
30
+ socket,
31
+ "--permission-mode",
32
+ "standard",
33
+ "--no-overlay",
34
+ ];
35
+ }
36
+ function request(socket, method, args) {
37
+ return new Promise((resolve, reject) => {
38
+ const stream = connect(socket);
39
+ let buffer = "";
40
+ stream.setTimeout(1000, () => stream.destroy(new Error("Private computer endpoint timed out.")));
41
+ stream.on("error", reject);
42
+ stream.on("connect", () => stream.write(`${JSON.stringify({ method, args })}\n`));
43
+ stream.on("data", (chunk) => {
44
+ buffer += chunk.toString();
45
+ if (buffer.length > 65536) {
46
+ stream.destroy(new Error("Invalid private endpoint metadata."));
47
+ return;
48
+ }
49
+ if (!buffer.includes("\n"))
50
+ return;
51
+ try {
52
+ const reply = JSON.parse(buffer.slice(0, buffer.indexOf("\n")));
53
+ if (!reply ||
54
+ typeof reply !== "object" ||
55
+ !("result" in reply) ||
56
+ !reply.result ||
57
+ typeof reply.result !== "object")
58
+ throw new Error("Private endpoint refused metadata.");
59
+ resolve(Object.fromEntries(Object.entries(reply.result)));
60
+ }
61
+ catch (error) {
62
+ reject(error);
63
+ }
64
+ stream.destroy();
65
+ });
66
+ stream.on("end", () => reject(new Error("Private computer endpoint closed.")));
67
+ });
68
+ }
69
+ export class MacRuntime {
70
+ directory;
71
+ lifetime;
72
+ exited;
73
+ pid;
74
+ get processId() {
75
+ return this.pid;
76
+ }
77
+ socket;
78
+ closing;
79
+ async start(app, signal) {
80
+ const directory = await mkdtemp(join(await realpath(tmpdir()), "lunr-cua-"));
81
+ this.directory = directory;
82
+ const socket = join(directory, "driver.sock");
83
+ this.socket = socket;
84
+ const lifetime = join(directory, "lifetime");
85
+ await exec("/usr/bin/mkfifo", ["-m", "600", lifetime], { timeout: 5000, signal });
86
+ this.lifetime = await open(lifetime, constants.O_RDWR);
87
+ signal.throwIfAborted();
88
+ const launcher = spawn("/usr/bin/open", macLaunchArguments(app, socket, directory, lifetime), {
89
+ env: runtimeEnvironment(),
90
+ stdio: "ignore",
91
+ });
92
+ this.exited = new Promise((resolve, reject) => {
93
+ launcher.once("error", reject);
94
+ launcher.once("exit", (code) => code === 0 ? resolve() : reject(new Error(`LaunchServices exited ${code}.`)));
95
+ });
96
+ void this.exited.catch(() => undefined);
97
+ const deadline = Date.now() + 15000;
98
+ while (Date.now() < deadline) {
99
+ signal.throwIfAborted();
100
+ try {
101
+ const metadata = await request(socket, "metadata");
102
+ if (metadata.driver_version !== CUA_VERSION ||
103
+ metadata.embedded !== true ||
104
+ typeof metadata.pid !== "number" ||
105
+ metadata.pid < 1)
106
+ throw new Error("Private runtime has incompatible metadata.");
107
+ this.pid = metadata.pid;
108
+ return socket;
109
+ }
110
+ catch {
111
+ await Promise.race([
112
+ delay(100, undefined, { signal }),
113
+ this.exited.then(() => {
114
+ throw new Error("Computer app exited during startup.");
115
+ }),
116
+ ]);
117
+ }
118
+ }
119
+ throw new Error("Private macOS runtime startup timed out. Check CuaDriver Accessibility and Screen Recording grants.");
120
+ }
121
+ close() {
122
+ this.closing ??= this.stop();
123
+ return this.closing;
124
+ }
125
+ async stop() {
126
+ await this.lifetime?.close();
127
+ this.lifetime = undefined;
128
+ if (this.socket && this.pid)
129
+ await request(this.socket, "shutdown_if_pid", { expected_pid: this.pid }).catch(() => undefined);
130
+ if (this.exited) {
131
+ const timeout = new AbortController();
132
+ try {
133
+ await Promise.race([
134
+ this.exited,
135
+ delay(10000, undefined, { signal: timeout.signal }).then(() => {
136
+ throw new Error("Owned macOS app shutdown is unconfirmed. Desktop lease retained.");
137
+ }),
138
+ ]);
139
+ }
140
+ finally {
141
+ timeout.abort();
142
+ }
143
+ }
144
+ if (this.directory)
145
+ await rm(this.directory, { recursive: true, force: true });
146
+ }
147
+ }
148
+ //# sourceMappingURL=macos-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"macos-runtime.js","sourceRoot":"","sources":["../../../src/core/computer-use/macos-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile, spawn } from \"node:child_process\";\nimport { constants } from \"node:fs\";\nimport { type FileHandle, mkdtemp, open, realpath, rm } from \"node:fs/promises\";\nimport { connect } from \"node:net\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { setTimeout as delay } from \"node:timers/promises\";\nimport { promisify } from \"node:util\";\nimport { CUA_VERSION, runtimeEnvironment } from \"./runtime.ts\";\n\nconst exec = promisify(execFile);\n\nexport function macLaunchArguments(app: string, socket: string, home: string, lifetime: string): string[] {\n\tconst environment = {\n\t\tHOME: home,\n\t\t...Object.fromEntries(Object.entries(runtimeEnvironment()).filter(([name]) => name.startsWith(\"CUA_\"))),\n\t};\n\treturn [\n\t\t\"-n\",\n\t\t\"-g\",\n\t\t\"-W\",\n\t\t\"-a\",\n\t\tapp,\n\t\t\"--stdin\",\n\t\tlifetime,\n\t\t...Object.entries(environment).flatMap(([name, value]) => [\"--env\", `${name}=${value}`]),\n\t\t\"--args\",\n\t\t\"serve\",\n\t\t\"--embedded\",\n\t\t\"--parent-liveness-stdio\",\n\t\t\"--socket\",\n\t\tsocket,\n\t\t\"--permission-mode\",\n\t\t\"standard\",\n\t\t\"--no-overlay\",\n\t];\n}\n\nfunction request(socket: string, method: string, args?: Record<string, unknown>): Promise<Record<string, unknown>> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst stream = connect(socket);\n\t\tlet buffer = \"\";\n\t\tstream.setTimeout(1000, () => stream.destroy(new Error(\"Private computer endpoint timed out.\")));\n\t\tstream.on(\"error\", reject);\n\t\tstream.on(\"connect\", () => stream.write(`${JSON.stringify({ method, args })}\\n`));\n\t\tstream.on(\"data\", (chunk) => {\n\t\t\tbuffer += chunk.toString();\n\t\t\tif (buffer.length > 65536) {\n\t\t\t\tstream.destroy(new Error(\"Invalid private endpoint metadata.\"));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!buffer.includes(\"\\n\")) return;\n\t\t\ttry {\n\t\t\t\tconst reply: unknown = JSON.parse(buffer.slice(0, buffer.indexOf(\"\\n\")));\n\t\t\t\tif (\n\t\t\t\t\t!reply ||\n\t\t\t\t\ttypeof reply !== \"object\" ||\n\t\t\t\t\t!(\"result\" in reply) ||\n\t\t\t\t\t!reply.result ||\n\t\t\t\t\ttypeof reply.result !== \"object\"\n\t\t\t\t)\n\t\t\t\t\tthrow new Error(\"Private endpoint refused metadata.\");\n\t\t\t\tresolve(Object.fromEntries(Object.entries(reply.result)));\n\t\t\t} catch (error) {\n\t\t\t\treject(error);\n\t\t\t}\n\t\t\tstream.destroy();\n\t\t});\n\t\tstream.on(\"end\", () => reject(new Error(\"Private computer endpoint closed.\")));\n\t});\n}\n\nexport class MacRuntime {\n\tprivate directory?: string;\n\tprivate lifetime?: FileHandle;\n\tprivate exited?: Promise<void>;\n\tprivate pid?: number;\n\tget processId(): number | undefined {\n\t\treturn this.pid;\n\t}\n\tprivate socket?: string;\n\tprivate closing?: Promise<void>;\n\n\tasync start(app: string, signal: AbortSignal): Promise<string> {\n\t\tconst directory = await mkdtemp(join(await realpath(tmpdir()), \"lunr-cua-\"));\n\t\tthis.directory = directory;\n\t\tconst socket = join(directory, \"driver.sock\");\n\t\tthis.socket = socket;\n\t\tconst lifetime = join(directory, \"lifetime\");\n\t\tawait exec(\"/usr/bin/mkfifo\", [\"-m\", \"600\", lifetime], { timeout: 5000, signal });\n\t\tthis.lifetime = await open(lifetime, constants.O_RDWR);\n\t\tsignal.throwIfAborted();\n\t\tconst launcher = spawn(\"/usr/bin/open\", macLaunchArguments(app, socket, directory, lifetime), {\n\t\t\tenv: runtimeEnvironment(),\n\t\t\tstdio: \"ignore\",\n\t\t});\n\t\tthis.exited = new Promise<void>((resolve, reject) => {\n\t\t\tlauncher.once(\"error\", reject);\n\t\t\tlauncher.once(\"exit\", (code) =>\n\t\t\t\tcode === 0 ? resolve() : reject(new Error(`LaunchServices exited ${code}.`)),\n\t\t\t);\n\t\t});\n\t\tvoid this.exited.catch(() => undefined);\n\t\tconst deadline = Date.now() + 15000;\n\t\twhile (Date.now() < deadline) {\n\t\t\tsignal.throwIfAborted();\n\t\t\ttry {\n\t\t\t\tconst metadata = await request(socket, \"metadata\");\n\t\t\t\tif (\n\t\t\t\t\tmetadata.driver_version !== CUA_VERSION ||\n\t\t\t\t\tmetadata.embedded !== true ||\n\t\t\t\t\ttypeof metadata.pid !== \"number\" ||\n\t\t\t\t\tmetadata.pid < 1\n\t\t\t\t)\n\t\t\t\t\tthrow new Error(\"Private runtime has incompatible metadata.\");\n\t\t\t\tthis.pid = metadata.pid;\n\t\t\t\treturn socket;\n\t\t\t} catch {\n\t\t\t\tawait Promise.race([\n\t\t\t\t\tdelay(100, undefined, { signal }),\n\t\t\t\t\tthis.exited.then(() => {\n\t\t\t\t\t\tthrow new Error(\"Computer app exited during startup.\");\n\t\t\t\t\t}),\n\t\t\t\t]);\n\t\t\t}\n\t\t}\n\t\tthrow new Error(\n\t\t\t\"Private macOS runtime startup timed out. Check CuaDriver Accessibility and Screen Recording grants.\",\n\t\t);\n\t}\n\n\tclose(): Promise<void> {\n\t\tthis.closing ??= this.stop();\n\t\treturn this.closing;\n\t}\n\n\tprivate async stop(): Promise<void> {\n\t\tawait this.lifetime?.close();\n\t\tthis.lifetime = undefined;\n\t\tif (this.socket && this.pid)\n\t\t\tawait request(this.socket, \"shutdown_if_pid\", { expected_pid: this.pid }).catch(() => undefined);\n\t\tif (this.exited) {\n\t\t\tconst timeout = new AbortController();\n\t\t\ttry {\n\t\t\t\tawait Promise.race([\n\t\t\t\t\tthis.exited,\n\t\t\t\t\tdelay(10000, undefined, { signal: timeout.signal }).then(() => {\n\t\t\t\t\t\tthrow new Error(\"Owned macOS app shutdown is unconfirmed. Desktop lease retained.\");\n\t\t\t\t\t}),\n\t\t\t\t]);\n\t\t\t} finally {\n\t\t\t\ttimeout.abort();\n\t\t\t}\n\t\t}\n\t\tif (this.directory) await rm(this.directory, { recursive: true, force: true });\n\t}\n}\n"]}
@@ -0,0 +1,19 @@
1
+ type ComputerSettings = {
2
+ enabled: boolean;
3
+ foreground: boolean;
4
+ };
5
+ export declare function computerSettingsChanged(settings: ComputerSettings): void;
6
+ export declare function onComputerSettingsChanged(listener: (settings: ComputerSettings) => void): () => void;
7
+ export declare const COMPUTER_TOOLS: readonly ["computer_load", "computer_apps", "computer_observe", "computer_click", "computer_drag", "computer_key", "computer_text", "computer_window", "computer_launch", "computer_scroll", "computer_end"];
8
+ export declare function computerPolicy(name: string, input: Record<string, unknown>): {
9
+ observation: boolean;
10
+ foreground: boolean;
11
+ } | undefined;
12
+ export declare function computerRefusal(name: string, input: Record<string, unknown>, policy: {
13
+ enabled: boolean;
14
+ foreground: boolean;
15
+ child: boolean;
16
+ vision: boolean;
17
+ }): string | undefined;
18
+ export {};
19
+ //# sourceMappingURL=policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../../src/core/computer-use/policy.ts"],"names":[],"mappings":"AAAA,KAAK,gBAAgB,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC;AAElE,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAExE;AACD,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,GAAG,MAAM,IAAI,CAKpG;AAED,eAAO,MAAM,cAAc,8MAYjB,CAAC;AAEX,wBAAgB,cAAc,CAC7B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B;IAAE,WAAW,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAoB3D;AAED,wBAAgB,eAAe,CAC9B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,MAAM,EAAE;IACP,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;CAChB,GACC,MAAM,GAAG,SAAS,CAgBpB","sourcesContent":["type ComputerSettings = { enabled: boolean; foreground: boolean };\nconst settingsListeners = new Set<(settings: ComputerSettings) => void>();\nexport function computerSettingsChanged(settings: ComputerSettings): void {\n\tfor (const listener of settingsListeners) listener(settings);\n}\nexport function onComputerSettingsChanged(listener: (settings: ComputerSettings) => void): () => void {\n\tsettingsListeners.add(listener);\n\treturn () => {\n\t\tsettingsListeners.delete(listener);\n\t};\n}\n\nexport const COMPUTER_TOOLS = [\n\t\"computer_load\",\n\t\"computer_apps\",\n\t\"computer_observe\",\n\t\"computer_click\",\n\t\"computer_drag\",\n\t\"computer_key\",\n\t\"computer_text\",\n\t\"computer_window\",\n\t\"computer_launch\",\n\t\"computer_scroll\",\n\t\"computer_end\",\n] as const;\n\nexport function computerPolicy(\n\tname: string,\n\tinput: Record<string, unknown>,\n): { observation: boolean; foreground: boolean } | undefined {\n\tif (!name.startsWith(\"computer_\")) return undefined;\n\tswitch (name) {\n\t\tcase \"computer_load\":\n\t\tcase \"computer_apps\":\n\t\tcase \"computer_observe\":\n\t\tcase \"computer_end\":\n\t\t\treturn { observation: true, foreground: false };\n\t\tcase \"computer_click\":\n\t\tcase \"computer_drag\":\n\t\tcase \"computer_key\":\n\t\tcase \"computer_text\":\n\t\tcase \"computer_scroll\":\n\t\t\treturn { observation: false, foreground: input.foreground === true || input.desktop === true };\n\t\tcase \"computer_window\":\n\t\tcase \"computer_launch\":\n\t\t\treturn { observation: false, foreground: true };\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown computer operation: ${name}`);\n\t}\n}\n\nexport function computerRefusal(\n\tname: string,\n\tinput: Record<string, unknown>,\n\tpolicy: {\n\t\tenabled: boolean;\n\t\tforeground: boolean;\n\t\tchild: boolean;\n\t\tvision: boolean;\n\t},\n): string | undefined {\n\tconst operation = computerPolicy(name, input);\n\tif (!operation) return \"Unknown computer operation.\";\n\tif (policy.child) return \"Computer tools are available only to main agents.\";\n\tif (!policy.enabled) return \"Computer use is disabled in settings.\";\n\tif (operation.foreground && !policy.foreground) return \"Foreground control is disabled. Use background operations.\";\n\tif (\n\t\t!policy.vision &&\n\t\t((name !== \"computer_window\" && (input.x !== undefined || input.y !== undefined)) ||\n\t\t\tname === \"computer_drag\" ||\n\t\t\tinput.screenshot === true ||\n\t\t\tinput.desktop === true)\n\t) {\n\t\treturn \"This model cannot receive images. Use accessibility elements or select an image-capable model.\";\n\t}\n\treturn undefined;\n}\n"]}
@@ -0,0 +1,66 @@
1
+ const settingsListeners = new Set();
2
+ export function computerSettingsChanged(settings) {
3
+ for (const listener of settingsListeners)
4
+ listener(settings);
5
+ }
6
+ export function onComputerSettingsChanged(listener) {
7
+ settingsListeners.add(listener);
8
+ return () => {
9
+ settingsListeners.delete(listener);
10
+ };
11
+ }
12
+ export const COMPUTER_TOOLS = [
13
+ "computer_load",
14
+ "computer_apps",
15
+ "computer_observe",
16
+ "computer_click",
17
+ "computer_drag",
18
+ "computer_key",
19
+ "computer_text",
20
+ "computer_window",
21
+ "computer_launch",
22
+ "computer_scroll",
23
+ "computer_end",
24
+ ];
25
+ export function computerPolicy(name, input) {
26
+ if (!name.startsWith("computer_"))
27
+ return undefined;
28
+ switch (name) {
29
+ case "computer_load":
30
+ case "computer_apps":
31
+ case "computer_observe":
32
+ case "computer_end":
33
+ return { observation: true, foreground: false };
34
+ case "computer_click":
35
+ case "computer_drag":
36
+ case "computer_key":
37
+ case "computer_text":
38
+ case "computer_scroll":
39
+ return { observation: false, foreground: input.foreground === true || input.desktop === true };
40
+ case "computer_window":
41
+ case "computer_launch":
42
+ return { observation: false, foreground: true };
43
+ default:
44
+ throw new Error(`Unknown computer operation: ${name}`);
45
+ }
46
+ }
47
+ export function computerRefusal(name, input, policy) {
48
+ const operation = computerPolicy(name, input);
49
+ if (!operation)
50
+ return "Unknown computer operation.";
51
+ if (policy.child)
52
+ return "Computer tools are available only to main agents.";
53
+ if (!policy.enabled)
54
+ return "Computer use is disabled in settings.";
55
+ if (operation.foreground && !policy.foreground)
56
+ return "Foreground control is disabled. Use background operations.";
57
+ if (!policy.vision &&
58
+ ((name !== "computer_window" && (input.x !== undefined || input.y !== undefined)) ||
59
+ name === "computer_drag" ||
60
+ input.screenshot === true ||
61
+ input.desktop === true)) {
62
+ return "This model cannot receive images. Use accessibility elements or select an image-capable model.";
63
+ }
64
+ return undefined;
65
+ }
66
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../../../src/core/computer-use/policy.ts"],"names":[],"mappings":"AACA,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAwC,CAAC;AAC1E,MAAM,UAAU,uBAAuB,CAAC,QAA0B,EAAQ;IACzE,KAAK,MAAM,QAAQ,IAAI,iBAAiB;QAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAAA,CAC7D;AACD,MAAM,UAAU,yBAAyB,CAAC,QAA8C,EAAc;IACrG,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAChC,OAAO,GAAG,EAAE,CAAC;QACZ,iBAAiB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAAA,CACnC,CAAC;AAAA,CACF;AAED,MAAM,CAAC,MAAM,cAAc,GAAG;IAC7B,eAAe;IACf,eAAe;IACf,kBAAkB;IAClB,gBAAgB;IAChB,eAAe;IACf,cAAc;IACd,eAAe;IACf,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,cAAc;CACL,CAAC;AAEX,MAAM,UAAU,cAAc,CAC7B,IAAY,EACZ,KAA8B,EAC8B;IAC5D,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,SAAS,CAAC;IACpD,QAAQ,IAAI,EAAE,CAAC;QACd,KAAK,eAAe,CAAC;QACrB,KAAK,eAAe,CAAC;QACrB,KAAK,kBAAkB,CAAC;QACxB,KAAK,cAAc;YAClB,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;QACjD,KAAK,gBAAgB,CAAC;QACtB,KAAK,eAAe,CAAC;QACrB,KAAK,cAAc,CAAC;QACpB,KAAK,eAAe,CAAC;QACrB,KAAK,iBAAiB;YACrB,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QAChG,KAAK,iBAAiB,CAAC;QACvB,KAAK,iBAAiB;YACrB,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;QACjD;YACC,MAAM,IAAI,KAAK,CAAC,+BAA+B,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;AAAA,CACD;AAED,MAAM,UAAU,eAAe,CAC9B,IAAY,EACZ,KAA8B,EAC9B,MAKC,EACoB;IACrB,MAAM,SAAS,GAAG,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC9C,IAAI,CAAC,SAAS;QAAE,OAAO,6BAA6B,CAAC;IACrD,IAAI,MAAM,CAAC,KAAK;QAAE,OAAO,mDAAmD,CAAC;IAC7E,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,uCAAuC,CAAC;IACpE,IAAI,SAAS,CAAC,UAAU,IAAI,CAAC,MAAM,CAAC,UAAU;QAAE,OAAO,4DAA4D,CAAC;IACpH,IACC,CAAC,MAAM,CAAC,MAAM;QACd,CAAC,CAAC,IAAI,KAAK,iBAAiB,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,SAAS,IAAI,KAAK,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC;YAChF,IAAI,KAAK,eAAe;YACxB,KAAK,CAAC,UAAU,KAAK,IAAI;YACzB,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC,EACvB,CAAC;QACF,OAAO,gGAAgG,CAAC;IACzG,CAAC;IACD,OAAO,SAAS,CAAC;AAAA,CACjB","sourcesContent":["type ComputerSettings = { enabled: boolean; foreground: boolean };\nconst settingsListeners = new Set<(settings: ComputerSettings) => void>();\nexport function computerSettingsChanged(settings: ComputerSettings): void {\n\tfor (const listener of settingsListeners) listener(settings);\n}\nexport function onComputerSettingsChanged(listener: (settings: ComputerSettings) => void): () => void {\n\tsettingsListeners.add(listener);\n\treturn () => {\n\t\tsettingsListeners.delete(listener);\n\t};\n}\n\nexport const COMPUTER_TOOLS = [\n\t\"computer_load\",\n\t\"computer_apps\",\n\t\"computer_observe\",\n\t\"computer_click\",\n\t\"computer_drag\",\n\t\"computer_key\",\n\t\"computer_text\",\n\t\"computer_window\",\n\t\"computer_launch\",\n\t\"computer_scroll\",\n\t\"computer_end\",\n] as const;\n\nexport function computerPolicy(\n\tname: string,\n\tinput: Record<string, unknown>,\n): { observation: boolean; foreground: boolean } | undefined {\n\tif (!name.startsWith(\"computer_\")) return undefined;\n\tswitch (name) {\n\t\tcase \"computer_load\":\n\t\tcase \"computer_apps\":\n\t\tcase \"computer_observe\":\n\t\tcase \"computer_end\":\n\t\t\treturn { observation: true, foreground: false };\n\t\tcase \"computer_click\":\n\t\tcase \"computer_drag\":\n\t\tcase \"computer_key\":\n\t\tcase \"computer_text\":\n\t\tcase \"computer_scroll\":\n\t\t\treturn { observation: false, foreground: input.foreground === true || input.desktop === true };\n\t\tcase \"computer_window\":\n\t\tcase \"computer_launch\":\n\t\t\treturn { observation: false, foreground: true };\n\t\tdefault:\n\t\t\tthrow new Error(`Unknown computer operation: ${name}`);\n\t}\n}\n\nexport function computerRefusal(\n\tname: string,\n\tinput: Record<string, unknown>,\n\tpolicy: {\n\t\tenabled: boolean;\n\t\tforeground: boolean;\n\t\tchild: boolean;\n\t\tvision: boolean;\n\t},\n): string | undefined {\n\tconst operation = computerPolicy(name, input);\n\tif (!operation) return \"Unknown computer operation.\";\n\tif (policy.child) return \"Computer tools are available only to main agents.\";\n\tif (!policy.enabled) return \"Computer use is disabled in settings.\";\n\tif (operation.foreground && !policy.foreground) return \"Foreground control is disabled. Use background operations.\";\n\tif (\n\t\t!policy.vision &&\n\t\t((name !== \"computer_window\" && (input.x !== undefined || input.y !== undefined)) ||\n\t\t\tname === \"computer_drag\" ||\n\t\t\tinput.screenshot === true ||\n\t\t\tinput.desktop === true)\n\t) {\n\t\treturn \"This model cannot receive images. Use accessibility elements or select an image-capable model.\";\n\t}\n\treturn undefined;\n}\n"]}
@@ -0,0 +1,31 @@
1
+ export declare const computerRelease: {
2
+ readonly version: "0.28.1";
3
+ readonly tag: "cua-driver-rs-v0.28.1";
4
+ readonly sourceCommit: "d8028a7943087ee258dc1b4d19dc12a7cd27669c";
5
+ readonly repository: "https://github.com/trycua/cua";
6
+ readonly prerelease: true;
7
+ readonly approval: "development-only; production release not approved";
8
+ readonly artifacts: readonly [{
9
+ readonly platform: "win32";
10
+ readonly arch: "x64";
11
+ readonly packageName: "@ashx-j/lunr-computer-win32-x64";
12
+ readonly name: "cua-driver-rs-0.28.1-windows-x86_64-binary.zip";
13
+ readonly bytes: 28930759;
14
+ readonly sha256: "ab90418a54f84102f549cde4537daef3a0e20ba8254b7e24524a50fc5f4174d3";
15
+ }, {
16
+ readonly platform: "win32";
17
+ readonly arch: "arm64";
18
+ readonly packageName: "@ashx-j/lunr-computer-win32-arm64";
19
+ readonly name: "cua-driver-rs-0.28.1-windows-arm64-binary.zip";
20
+ readonly bytes: 27246194;
21
+ readonly sha256: "d260e6110e029680d543d317f3c3c09569475f8d65855fcedda202e2ee989bf0";
22
+ }, {
23
+ readonly platform: "darwin";
24
+ readonly arch: "arm64";
25
+ readonly packageName: "@ashx-j/lunr-computer-darwin-arm64";
26
+ readonly name: "cua-driver-rs-0.28.1-darwin-arm64.tar.gz";
27
+ readonly bytes: 70074352;
28
+ readonly sha256: "b3cb3781feb9855dfcdd616bc5c9c8e627453e3e16a073c1446326691a549b24";
29
+ }];
30
+ };
31
+ //# sourceMappingURL=release.generated.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release.generated.d.ts","sourceRoot":"","sources":["../../../src/core/computer-use/release.generated.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiClB,CAAC","sourcesContent":["// Generated by scripts/generate-computer-use-manifest.mjs.\nexport const computerRelease = {\n \"version\": \"0.28.1\",\n \"tag\": \"cua-driver-rs-v0.28.1\",\n \"sourceCommit\": \"d8028a7943087ee258dc1b4d19dc12a7cd27669c\",\n \"repository\": \"https://github.com/trycua/cua\",\n \"prerelease\": true,\n \"approval\": \"development-only; production release not approved\",\n \"artifacts\": [\n {\n \"platform\": \"win32\",\n \"arch\": \"x64\",\n \"packageName\": \"@ashx-j/lunr-computer-win32-x64\",\n \"name\": \"cua-driver-rs-0.28.1-windows-x86_64-binary.zip\",\n \"bytes\": 28930759,\n \"sha256\": \"ab90418a54f84102f549cde4537daef3a0e20ba8254b7e24524a50fc5f4174d3\"\n },\n {\n \"platform\": \"win32\",\n \"arch\": \"arm64\",\n \"packageName\": \"@ashx-j/lunr-computer-win32-arm64\",\n \"name\": \"cua-driver-rs-0.28.1-windows-arm64-binary.zip\",\n \"bytes\": 27246194,\n \"sha256\": \"d260e6110e029680d543d317f3c3c09569475f8d65855fcedda202e2ee989bf0\"\n },\n {\n \"platform\": \"darwin\",\n \"arch\": \"arm64\",\n \"packageName\": \"@ashx-j/lunr-computer-darwin-arm64\",\n \"name\": \"cua-driver-rs-0.28.1-darwin-arm64.tar.gz\",\n \"bytes\": 70074352,\n \"sha256\": \"b3cb3781feb9855dfcdd616bc5c9c8e627453e3e16a073c1446326691a549b24\"\n }\n ]\n} as const;\n"]}
@@ -0,0 +1,36 @@
1
+ // Generated by scripts/generate-computer-use-manifest.mjs.
2
+ export const computerRelease = {
3
+ "version": "0.28.1",
4
+ "tag": "cua-driver-rs-v0.28.1",
5
+ "sourceCommit": "d8028a7943087ee258dc1b4d19dc12a7cd27669c",
6
+ "repository": "https://github.com/trycua/cua",
7
+ "prerelease": true,
8
+ "approval": "development-only; production release not approved",
9
+ "artifacts": [
10
+ {
11
+ "platform": "win32",
12
+ "arch": "x64",
13
+ "packageName": "@ashx-j/lunr-computer-win32-x64",
14
+ "name": "cua-driver-rs-0.28.1-windows-x86_64-binary.zip",
15
+ "bytes": 28930759,
16
+ "sha256": "ab90418a54f84102f549cde4537daef3a0e20ba8254b7e24524a50fc5f4174d3"
17
+ },
18
+ {
19
+ "platform": "win32",
20
+ "arch": "arm64",
21
+ "packageName": "@ashx-j/lunr-computer-win32-arm64",
22
+ "name": "cua-driver-rs-0.28.1-windows-arm64-binary.zip",
23
+ "bytes": 27246194,
24
+ "sha256": "d260e6110e029680d543d317f3c3c09569475f8d65855fcedda202e2ee989bf0"
25
+ },
26
+ {
27
+ "platform": "darwin",
28
+ "arch": "arm64",
29
+ "packageName": "@ashx-j/lunr-computer-darwin-arm64",
30
+ "name": "cua-driver-rs-0.28.1-darwin-arm64.tar.gz",
31
+ "bytes": 70074352,
32
+ "sha256": "b3cb3781feb9855dfcdd616bc5c9c8e627453e3e16a073c1446326691a549b24"
33
+ }
34
+ ]
35
+ };
36
+ //# sourceMappingURL=release.generated.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release.generated.js","sourceRoot":"","sources":["../../../src/core/computer-use/release.generated.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,SAAS,EAAE,QAAQ;IACnB,KAAK,EAAE,uBAAuB;IAC9B,cAAc,EAAE,0CAA0C;IAC1D,YAAY,EAAE,+BAA+B;IAC7C,YAAY,EAAE,IAAI;IAClB,UAAU,EAAE,mDAAmD;IAC/D,WAAW,EAAE;QACX;YACE,UAAU,EAAE,OAAO;YACnB,MAAM,EAAE,KAAK;YACb,aAAa,EAAE,iCAAiC;YAChD,MAAM,EAAE,gDAAgD;YACxD,OAAO,EAAE,QAAQ;YACjB,QAAQ,EAAE,kEAAkE;SAC7E;QACD;YACE,UAAU,EAAE,OAAO;YACnB,MAAM,EAAE,OAAO;YACf,aAAa,EAAE,mCAAmC;YAClD,MAAM,EAAE,+CAA+C;YACvD,OAAO,EAAE,QAAQ;YACjB,QAAQ,EAAE,kEAAkE;SAC7E;QACD;YACE,UAAU,EAAE,QAAQ;YACpB,MAAM,EAAE,OAAO;YACf,aAAa,EAAE,oCAAoC;YACnD,MAAM,EAAE,0CAA0C;YAClD,OAAO,EAAE,QAAQ;YACjB,QAAQ,EAAE,kEAAkE;SAC7E;KACF;CACO,CAAC","sourcesContent":["// Generated by scripts/generate-computer-use-manifest.mjs.\nexport const computerRelease = {\n \"version\": \"0.28.1\",\n \"tag\": \"cua-driver-rs-v0.28.1\",\n \"sourceCommit\": \"d8028a7943087ee258dc1b4d19dc12a7cd27669c\",\n \"repository\": \"https://github.com/trycua/cua\",\n \"prerelease\": true,\n \"approval\": \"development-only; production release not approved\",\n \"artifacts\": [\n {\n \"platform\": \"win32\",\n \"arch\": \"x64\",\n \"packageName\": \"@ashx-j/lunr-computer-win32-x64\",\n \"name\": \"cua-driver-rs-0.28.1-windows-x86_64-binary.zip\",\n \"bytes\": 28930759,\n \"sha256\": \"ab90418a54f84102f549cde4537daef3a0e20ba8254b7e24524a50fc5f4174d3\"\n },\n {\n \"platform\": \"win32\",\n \"arch\": \"arm64\",\n \"packageName\": \"@ashx-j/lunr-computer-win32-arm64\",\n \"name\": \"cua-driver-rs-0.28.1-windows-arm64-binary.zip\",\n \"bytes\": 27246194,\n \"sha256\": \"d260e6110e029680d543d317f3c3c09569475f8d65855fcedda202e2ee989bf0\"\n },\n {\n \"platform\": \"darwin\",\n \"arch\": \"arm64\",\n \"packageName\": \"@ashx-j/lunr-computer-darwin-arm64\",\n \"name\": \"cua-driver-rs-0.28.1-darwin-arm64.tar.gz\",\n \"bytes\": 70074352,\n \"sha256\": \"b3cb3781feb9855dfcdd616bc5c9c8e627453e3e16a073c1446326691a549b24\"\n }\n ]\n} as const;\n"]}
@@ -0,0 +1,13 @@
1
+ export declare const CUA_VERSION: "0.28.1";
2
+ export declare function resolveRuntimeArchive(packageDirectory?: string, platform?: string, arch?: string): Promise<{
3
+ archive: string;
4
+ sha256: string;
5
+ }>;
6
+ export declare function runtimeEnvironment(inherited?: NodeJS.ProcessEnv): Record<string, string>;
7
+ export declare function assertOwnedPath(path: string): Promise<void>;
8
+ export declare function runtimeInventory(root: string, signal?: AbortSignal): Promise<Record<string, string>>;
9
+ export declare function installRuntime(signal?: AbortSignal): Promise<{
10
+ command: string;
11
+ app?: string;
12
+ }>;
13
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/core/computer-use/runtime.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,WAAW,UAA0B,CAAC;AAEnD,wBAAsB,qBAAqB,CAC1C,gBAAgB,SAAkB,EAClC,QAAQ,GAAE,MAAyB,EACnC,IAAI,GAAE,MAAqB,GACzB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CA8B9C;AAED,wBAAgB,kBAAkB,CAAC,SAAS,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAYrG;AAQD,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAejE;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CA6B1G;AAED,wBAAsB,cAAc,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAoDrG","sourcesContent":["import { execFile } from \"node:child_process\";\nimport { createHash, randomUUID } from \"node:crypto\";\nimport { createReadStream } from \"node:fs\";\nimport { lstat, mkdir, readdir, readFile, readlink, realpath, rename, rm } from \"node:fs/promises\";\nimport { createRequire } from \"node:module\";\nimport { userInfo } from \"node:os\";\nimport { dirname, isAbsolute, join, relative, resolve } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport lockfile from \"proper-lockfile\";\nimport { getPackageDir } from \"../../config.ts\";\n\nimport { computerRelease } from \"./release.generated.ts\";\n\nconst exec = promisify(execFile);\nexport const CUA_VERSION = computerRelease.version;\n\nexport async function resolveRuntimeArchive(\n\tpackageDirectory = getPackageDir(),\n\tplatform: string = process.platform,\n\tarch: string = process.arch,\n): Promise<{ archive: string; sha256: string }> {\n\tconst payload = computerRelease.artifacts.find((item) => item.platform === platform && item.arch === arch);\n\tif (!payload) throw new Error(\"Computer use is unsupported on this platform or architecture.\");\n\tlet archive = join(packageDirectory, \"native\", \"computer-use\", payload.name);\n\ttry {\n\t\tawait lstat(archive);\n\t} catch (error) {\n\t\tif (!(error instanceof Error && \"code\" in error && error.code === \"ENOENT\")) throw error;\n\t\tlet manifestPath: string;\n\t\ttry {\n\t\t\tmanifestPath = createRequire(join(packageDirectory, \"package.json\")).resolve(\n\t\t\t\t`${payload.packageName}/package.json`,\n\t\t\t);\n\t\t} catch {\n\t\t\tthrow new Error(\n\t\t\t\t\"Computer-use payload is missing. Reinstall lunR with optional dependencies enabled. No runtime was downloaded.\",\n\t\t\t);\n\t\t}\n\t\tconst manifest = JSON.parse(await readFile(manifestPath, \"utf8\"));\n\t\tconst cli = JSON.parse(await readFile(join(packageDirectory, \"package.json\"), \"utf8\"));\n\t\tif (manifest.name !== payload.packageName || manifest.version !== cli.version)\n\t\t\tthrow new Error(\n\t\t\t\t\"Computer-use payload package version does not match lunR. Reinstall lunR with optional dependencies enabled.\",\n\t\t\t);\n\t\tarchive = join(dirname(manifestPath), payload.name);\n\t}\n\tconst info = await lstat(archive);\n\tif (!info.isFile() || info.isSymbolicLink() || info.size !== payload.bytes)\n\t\tthrow new Error(\"Bundled computer-use archive is not a regular file of the pinned size.\");\n\treturn { archive, sha256: payload.sha256 };\n}\n\nexport function runtimeEnvironment(inherited: NodeJS.ProcessEnv = process.env): Record<string, string> {\n\treturn {\n\t\t...Object.fromEntries(\n\t\t\tObject.entries(inherited).filter(\n\t\t\t\t(entry): entry is [string, string] => entry[1] !== undefined && !entry[0].toUpperCase().startsWith(\"CUA_\"),\n\t\t\t),\n\t\t),\n\t\tCUA_DRIVER_RS_TELEMETRY_ENABLED: \"false\",\n\t\tCUA_DRIVER_RS_UPDATE_CHECK: \"false\",\n\t\tCUA_DRIVER_PERMISSION_MODE: \"standard\",\n\t\tCUA_DRIVER_DISABLE_UNRESTRICTED: \"true\",\n\t};\n}\n\nasync function digest(path: string, signal?: AbortSignal): Promise<string> {\n\tconst hash = createHash(\"sha256\");\n\tfor await (const chunk of createReadStream(path, { signal })) hash.update(chunk);\n\treturn hash.digest(\"hex\");\n}\n\nexport async function assertOwnedPath(path: string): Promise<void> {\n\tlet current = resolve(path);\n\tfor (;;) {\n\t\ttry {\n\t\t\tconst info = await lstat(current);\n\t\t\tif (info.isSymbolicLink() || resolve(await realpath(current)).toLowerCase() !== current.toLowerCase()) {\n\t\t\t\tthrow new Error(`Computer runtime path redirects elsewhere: ${current}`);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (!(error instanceof Error && \"code\" in error && error.code === \"ENOENT\")) throw error;\n\t\t}\n\t\tconst parent = dirname(current);\n\t\tif (parent === current) return;\n\t\tcurrent = parent;\n\t}\n}\n\nexport async function runtimeInventory(root: string, signal?: AbortSignal): Promise<Record<string, string>> {\n\tconst inventory: Record<string, string> = {};\n\tasync function walk(path: string): Promise<void> {\n\t\tfor (const item of await readdir(path, { withFileTypes: true })) {\n\t\t\tconst entry = join(path, item.name);\n\t\t\tconst key = relative(root, entry);\n\t\t\tif (item.isSymbolicLink()) {\n\t\t\t\tconst target = await readlink(entry);\n\t\t\t\tconst resolved = relative(root, resolve(dirname(entry), target));\n\t\t\t\tif (\n\t\t\t\t\tisAbsolute(target) ||\n\t\t\t\t\tresolved === \"..\" ||\n\t\t\t\t\tresolved.startsWith(`..${process.platform === \"win32\" ? \"\\\\\" : \"/\"}`) ||\n\t\t\t\t\tisAbsolute(resolved)\n\t\t\t\t)\n\t\t\t\t\tthrow new Error(\"Runtime symlink escapes its bundle.\");\n\t\t\t\tinventory[key] = `link:${target}`;\n\t\t\t} else if (item.isDirectory()) {\n\t\t\t\tawait assertOwnedPath(entry);\n\t\t\t\tinventory[key] = \"directory\";\n\t\t\t\tawait walk(entry);\n\t\t\t} else if (item.isFile()) {\n\t\t\t\tawait assertOwnedPath(entry);\n\t\t\t\tinventory[key] = await digest(entry, signal);\n\t\t\t} else throw new Error(\"Unexpected runtime filesystem entry.\");\n\t\t}\n\t}\n\tawait walk(root);\n\treturn Object.fromEntries(Object.entries(inventory).sort(([a], [b]) => a.localeCompare(b)));\n}\n\nexport async function installRuntime(signal?: AbortSignal): Promise<{ command: string; app?: string }> {\n\tsignal?.throwIfAborted();\n\tconst platform = `${process.platform}-${process.arch}`;\n\tconst { archive, sha256 } = await resolveRuntimeArchive();\n\tif (process.platform === \"win32\" && process.env.SESSIONNAME === \"Services\")\n\t\tthrow new Error(\"Computer use requires a logged-in interactive desktop.\");\n\tif ((await digest(archive, signal)) !== sha256)\n\t\tthrow new Error(\"Bundled computer-use archive failed SHA-256 verification.\");\n\tconst root = join(userInfo().homedir, \".lunr\", \"desktop\");\n\tawait assertOwnedPath(root);\n\tawait mkdir(root, { recursive: true, mode: 0o700 });\n\tconst release = await lockfile.lock(root, { retries: 0, stale: 120000 });\n\tconst temporary = join(root, `extract-${randomUUID()}`);\n\tconst destination = join(root, `runtime-${platform}`);\n\ttry {\n\t\tawait assertOwnedPath(destination);\n\t\tawait mkdir(temporary, { mode: 0o700 });\n\t\tawait exec(\n\t\t\tprocess.platform === \"win32\"\n\t\t\t\t? join(process.env.SystemRoot ?? \"C:\\\\Windows\", \"System32\", \"tar.exe\")\n\t\t\t\t: \"/usr/bin/tar\",\n\t\t\t[\"-xf\", archive, \"-C\", temporary],\n\t\t\t{\n\t\t\t\ttimeout: 30000,\n\t\t\t\twindowsHide: true,\n\t\t\t\tsignal,\n\t\t\t},\n\t\t);\n\t\tconst extracted =\n\t\t\tprocess.platform === \"darwin\" ? join(temporary, `cua-driver-rs-${CUA_VERSION}-darwin-arm64`) : temporary;\n\t\tconst expected = await runtimeInventory(extracted, signal);\n\t\ttry {\n\t\t\tawait lstat(destination);\n\t\t\tif (JSON.stringify(await runtimeInventory(destination, signal)) !== JSON.stringify(expected))\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"Cached computer runtime differs from the verified archive. Remove the inactive lunR runtime directory before reinstalling; it was not executed or overwritten.\",\n\t\t\t\t);\n\t\t} catch (error) {\n\t\t\tif (!(error instanceof Error && \"code\" in error && error.code === \"ENOENT\")) throw error;\n\t\t\tawait rename(extracted, destination);\n\t\t}\n\t\tsignal?.throwIfAborted();\n\t\tif (process.platform === \"darwin\") {\n\t\t\tconst app = join(destination, \"CuaDriver.app\");\n\t\t\tawait exec(\"/usr/bin/codesign\", [\"--verify\", \"--deep\", \"--strict\", app], { timeout: 15000, signal });\n\t\t\treturn { app, command: join(app, \"Contents\", \"MacOS\", \"cua-driver\") };\n\t\t}\n\t\treturn { command: join(destination, \"cua-driver.exe\") };\n\t} finally {\n\t\tawait rm(temporary, { recursive: true, force: true });\n\t\tawait release();\n\t}\n}\n"]}