@ashx-j/lunr 0.2.25 → 0.2.26

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 (220) hide show
  1. package/CHANGELOG.md +16 -1
  2. package/dist/builtin-extensions/index.d.ts.map +1 -1
  3. package/dist/builtin-extensions/index.js +1 -0
  4. package/dist/builtin-extensions/index.js.map +1 -1
  5. package/dist/builtin-extensions/lunr-computer-use.d.ts +3 -0
  6. package/dist/builtin-extensions/lunr-computer-use.d.ts.map +1 -0
  7. package/dist/builtin-extensions/lunr-computer-use.js +179 -0
  8. package/dist/builtin-extensions/lunr-computer-use.js.map +1 -0
  9. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
  10. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +1 -1
  11. package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
  12. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts +4 -4
  13. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.d.ts.map +1 -1
  14. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js +8 -5
  15. package/dist/builtin-extensions/pi-subagents/src/extension/tool-description.js.map +1 -1
  16. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts +1 -0
  17. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.d.ts.map +1 -1
  18. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js +11 -2
  19. package/dist/builtin-extensions/pi-subagents/src/runs/background/subagent-runner.js.map +1 -1
  20. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.d.ts.map +1 -1
  21. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js +3 -3
  22. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/chain-execution.js.map +1 -1
  23. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.d.ts.map +1 -1
  24. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js +15 -1
  25. package/dist/builtin-extensions/pi-subagents/src/runs/foreground/execution.js.map +1 -1
  26. package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.d.ts +1 -0
  27. package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.d.ts.map +1 -1
  28. package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.js +5 -0
  29. package/dist/builtin-extensions/pi-subagents/src/runs/shared/chain-outputs.js.map +1 -1
  30. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts +1 -1
  31. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts.map +1 -1
  32. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js +2 -0
  33. package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js.map +1 -1
  34. package/dist/builtin-extensions/pi-subagents/src/tui/communication.d.ts.map +1 -1
  35. package/dist/builtin-extensions/pi-subagents/src/tui/communication.js +1 -1
  36. package/dist/builtin-extensions/pi-subagents/src/tui/communication.js.map +1 -1
  37. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +1 -0
  38. package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
  39. package/dist/builtin-extensions/pi-subagents/src/tui/render.js +5 -3
  40. package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
  41. package/dist/core/computer-use/adapter.d.ts +28 -0
  42. package/dist/core/computer-use/adapter.d.ts.map +1 -0
  43. package/dist/core/computer-use/adapter.js +133 -0
  44. package/dist/core/computer-use/adapter.js.map +1 -0
  45. package/dist/core/computer-use/image.d.ts +27 -0
  46. package/dist/core/computer-use/image.d.ts.map +1 -0
  47. package/dist/core/computer-use/image.js +72 -0
  48. package/dist/core/computer-use/image.js.map +1 -0
  49. package/dist/core/computer-use/lease.d.ts +18 -0
  50. package/dist/core/computer-use/lease.d.ts.map +1 -0
  51. package/dist/core/computer-use/lease.js +129 -0
  52. package/dist/core/computer-use/lease.js.map +1 -0
  53. package/dist/core/computer-use/macos-runtime.d.ts +14 -0
  54. package/dist/core/computer-use/macos-runtime.d.ts.map +1 -0
  55. package/dist/core/computer-use/macos-runtime.js +148 -0
  56. package/dist/core/computer-use/macos-runtime.js.map +1 -0
  57. package/dist/core/computer-use/policy.d.ts +19 -0
  58. package/dist/core/computer-use/policy.d.ts.map +1 -0
  59. package/dist/core/computer-use/policy.js +67 -0
  60. package/dist/core/computer-use/policy.js.map +1 -0
  61. package/dist/core/computer-use/release.generated.d.ts +31 -0
  62. package/dist/core/computer-use/release.generated.d.ts.map +1 -0
  63. package/dist/core/computer-use/release.generated.js +36 -0
  64. package/dist/core/computer-use/release.generated.js.map +1 -0
  65. package/dist/core/computer-use/runtime.d.ts +13 -0
  66. package/dist/core/computer-use/runtime.d.ts.map +1 -0
  67. package/dist/core/computer-use/runtime.js +158 -0
  68. package/dist/core/computer-use/runtime.js.map +1 -0
  69. package/dist/core/computer-use/schemas.d.ts +100 -0
  70. package/dist/core/computer-use/schemas.d.ts.map +1 -0
  71. package/dist/core/computer-use/schemas.js +79 -0
  72. package/dist/core/computer-use/schemas.js.map +1 -0
  73. package/dist/core/computer-use/windows-desktop.d.ts +3 -0
  74. package/dist/core/computer-use/windows-desktop.d.ts.map +1 -0
  75. package/dist/core/computer-use/windows-desktop.js +48 -0
  76. package/dist/core/computer-use/windows-desktop.js.map +1 -0
  77. package/dist/core/computer-use/workflow.d.ts +38 -0
  78. package/dist/core/computer-use/workflow.d.ts.map +1 -0
  79. package/dist/core/computer-use/workflow.js +560 -0
  80. package/dist/core/computer-use/workflow.js.map +1 -0
  81. package/dist/core/extensions/loader.d.ts.map +1 -1
  82. package/dist/core/extensions/loader.js +4 -0
  83. package/dist/core/extensions/loader.js.map +1 -1
  84. package/dist/core/permissions.d.ts +1 -1
  85. package/dist/core/permissions.d.ts.map +1 -1
  86. package/dist/core/permissions.js +14 -3
  87. package/dist/core/permissions.js.map +1 -1
  88. package/dist/core/plan-mode.d.ts.map +1 -1
  89. package/dist/core/plan-mode.js +9 -0
  90. package/dist/core/plan-mode.js.map +1 -1
  91. package/dist/core/settings-manager.d.ts +6 -0
  92. package/dist/core/settings-manager.d.ts.map +1 -1
  93. package/dist/core/settings-manager.js +19 -0
  94. package/dist/core/settings-manager.js.map +1 -1
  95. package/dist/core/subagent-event-transport.d.ts +3 -0
  96. package/dist/core/subagent-event-transport.d.ts.map +1 -0
  97. package/dist/core/subagent-event-transport.js +61 -0
  98. package/dist/core/subagent-event-transport.js.map +1 -0
  99. package/dist/gateway/adapters/discord.d.ts.map +1 -1
  100. package/dist/gateway/adapters/discord.js +2 -2
  101. package/dist/gateway/adapters/discord.js.map +1 -1
  102. package/dist/gateway/approval.d.ts.map +1 -1
  103. package/dist/gateway/approval.js +3 -3
  104. package/dist/gateway/approval.js.map +1 -1
  105. package/dist/gateway/authz.d.ts +4 -4
  106. package/dist/gateway/authz.d.ts.map +1 -1
  107. package/dist/gateway/authz.js +8 -12
  108. package/dist/gateway/authz.js.map +1 -1
  109. package/dist/gateway/commands.d.ts.map +1 -1
  110. package/dist/gateway/commands.js +2 -6
  111. package/dist/gateway/commands.js.map +1 -1
  112. package/dist/gateway/cron.d.ts.map +1 -1
  113. package/dist/gateway/cron.js +20 -6
  114. package/dist/gateway/cron.js.map +1 -1
  115. package/dist/gateway/index.d.ts.map +1 -1
  116. package/dist/gateway/index.js +3 -3
  117. package/dist/gateway/index.js.map +1 -1
  118. package/dist/gateway/mobile-commands.d.ts.map +1 -1
  119. package/dist/gateway/mobile-commands.js +8 -8
  120. package/dist/gateway/mobile-commands.js.map +1 -1
  121. package/dist/gateway/presenter.d.ts.map +1 -1
  122. package/dist/gateway/presenter.js +3 -3
  123. package/dist/gateway/presenter.js.map +1 -1
  124. package/dist/gateway/router.d.ts.map +1 -1
  125. package/dist/gateway/router.js +5 -7
  126. package/dist/gateway/router.js.map +1 -1
  127. package/dist/gateway/setup.d.ts.map +1 -1
  128. package/dist/gateway/setup.js +6 -4
  129. package/dist/gateway/setup.js.map +1 -1
  130. package/dist/modes/interactive/components/settings-selector.d.ts +4 -0
  131. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  132. package/dist/modes/interactive/components/settings-selector.js +20 -0
  133. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  134. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  135. package/dist/modes/interactive/interactive-mode.js +8 -0
  136. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  137. package/dist/modes/print-mode.d.ts.map +1 -1
  138. package/dist/modes/print-mode.js +9 -1
  139. package/dist/modes/print-mode.js.map +1 -1
  140. package/dist/node-runtime/adapter-VFG7WNPX.js +17 -0
  141. package/dist/node-runtime/{agent-session-services-YXXFCP5J.js → agent-session-services-5YXS2PLF.js} +10 -8
  142. package/dist/node-runtime/{builtin-extensions-ZLAX7TUH.js → builtin-extensions-I2HIFEMY.js} +3 -2
  143. package/dist/node-runtime/{chunk-3XPLBUEM.js → chunk-2CFDTH5B.js} +7 -3
  144. package/dist/node-runtime/chunk-2IDTZAG5.js +1415 -0
  145. package/dist/node-runtime/{chunk-QTU6AKNJ.js → chunk-3MISGG4S.js} +11 -15
  146. package/dist/node-runtime/chunk-4SBQAI4T.js +2185 -0
  147. package/dist/node-runtime/{chunk-TORR5XBV.js → chunk-5B5QN3ZQ.js} +12 -12
  148. package/dist/node-runtime/chunk-5B6VKFEV.js +180 -0
  149. package/dist/node-runtime/{chunk-AD6VXAO7.js → chunk-5Q4A37RB.js} +15 -104
  150. package/dist/node-runtime/{chunk-4TLO4PO2.js → chunk-7IQGBKBJ.js} +7 -1401
  151. package/dist/node-runtime/{chunk-OCVIXVTZ.js → chunk-D5UCKPBQ.js} +12 -1
  152. package/dist/node-runtime/{chunk-7S3T6YEA.js → chunk-DVQSHCVP.js} +1 -1
  153. package/dist/node-runtime/{chunk-HFVZUPFJ.js → chunk-E75WFZ33.js} +2 -2
  154. package/dist/node-runtime/chunk-FY4A63RK.js +73 -0
  155. package/dist/node-runtime/{chunk-6XL67VVY.js → chunk-I74LN5JG.js} +15 -0
  156. package/dist/node-runtime/chunk-IKU6Y7DL.js +287 -0
  157. package/dist/node-runtime/{chunk-WF7PGWRZ.js → chunk-L24TPBS4.js} +5 -4
  158. package/dist/node-runtime/{chunk-VQFSUJJG.js → chunk-LJTIVM7I.js} +7 -7
  159. package/dist/node-runtime/{chunk-DSIKTUPW.js → chunk-LWJXTA6Z.js} +274 -2433
  160. package/dist/node-runtime/{chunk-E4D3IGP2.js → chunk-P7XBVXGT.js} +6 -7
  161. package/dist/node-runtime/{chunk-OVX6X377.js → chunk-PTFBPO3C.js} +1 -1
  162. package/dist/node-runtime/{chunk-RC7DMV45.js → chunk-RCR3XAQY.js} +34 -6
  163. package/dist/node-runtime/chunk-RGQAEOM5.js +81 -0
  164. package/dist/node-runtime/{chunk-YCUZEGJG.js → chunk-SN2KSMPQ.js} +6 -3
  165. package/dist/node-runtime/{chunk-NRKGMJYU.js → chunk-SPVDBUOS.js} +1 -1
  166. package/dist/node-runtime/{chunk-IJIFHRTB.js → chunk-T4DA4XE7.js} +19 -19
  167. package/dist/node-runtime/chunk-U5F4IC7R.js +53 -0
  168. package/dist/node-runtime/{chunk-KWIYUUZK.js → chunk-UVWCDQYF.js} +27 -18
  169. package/dist/node-runtime/{chunk-ZXSGTGJ6.js → chunk-WIF24I7G.js} +21 -5
  170. package/dist/node-runtime/{chunk-2HHLJWGD.js → chunk-X3PGBLQ7.js} +2 -2
  171. package/dist/node-runtime/chunk-XHIRAZ26.js +108 -0
  172. package/dist/node-runtime/{chunk-YDO2F2IA.js → chunk-YWOJIGFY.js} +1 -1
  173. package/dist/node-runtime/{command-6WDOYKS6.js → command-FSBU2EVZ.js} +3 -3
  174. package/dist/node-runtime/{commands-NZLSOHPE.js → commands-EMBQQVVT.js} +4 -2
  175. package/dist/node-runtime/{commands-QC6VUZJQ.js → commands-NAAL7KNT.js} +5 -4
  176. package/dist/node-runtime/{direct-tool-executor-77GW4F5P.js → direct-tool-executor-4D7UXYU4.js} +7 -4
  177. package/dist/node-runtime/{gateway-INAYBF4Q.js → gateway-DQM333YV.js} +18 -19
  178. package/dist/node-runtime/index.js +23 -19
  179. package/dist/node-runtime/{init-HS6NQXSK.js → init-P5AUV77I.js} +4 -2
  180. package/dist/node-runtime/{install-cli-KL4UDDAD.js → install-cli-NN4YAU44.js} +1 -1
  181. package/dist/node-runtime/{interactive-mode-Z5M7WYYZ.js → interactive-mode-YOHZVMKX.js} +11 -9
  182. package/dist/node-runtime/lunr-computer-use-Y23CCDIJ.js +158 -0
  183. package/dist/node-runtime/{lunr-cron-LWIZJM2N.js → lunr-cron-USHC4LXH.js} +6 -4
  184. package/dist/node-runtime/main.js +16 -14
  185. package/dist/node-runtime/{mcp-auth-flow-QIXHW6QN.js → mcp-auth-flow-QVLFVLEO.js} +2 -1
  186. package/dist/node-runtime/{mobile-commands-J7OJEKFO.js → mobile-commands-O5LCHL32.js} +4 -3
  187. package/dist/node-runtime/{package-manager-cli-VYZM5WHN.js → package-manager-cli-Q7BL6KZO.js} +7 -6
  188. package/dist/node-runtime/{pi-mcp-adapter-5UKBZP44.js → pi-mcp-adapter-3PHF4KZ4.js} +5 -5
  189. package/dist/node-runtime/{pi-subagents-DNY7EAIG.js → pi-subagents-7IBSSGEW.js} +24 -18
  190. package/dist/node-runtime/{print-mode-XSFM26EL.js → print-mode-XQ76CYMT.js} +2 -1
  191. package/dist/node-runtime/{proxy-modes-LGEUYD7R.js → proxy-modes-5FAPSZEZ.js} +7 -4
  192. package/dist/node-runtime/rpc-entry.js +16 -14
  193. package/dist/node-runtime/runtime-EFPPD2UW.js +21 -0
  194. package/dist/node-runtime/{runtime-bridges-VRDDR73P.js → runtime-bridges-7WVCLI76.js} +3 -2
  195. package/dist/node-runtime/{settings-manager-J4SPQPDJ.js → settings-manager-DJDM5AHM.js} +2 -1
  196. package/dist/node-runtime/{setup-CQ2NLVK5.js → setup-PFBWRNUI.js} +10 -9
  197. package/dist/node-runtime/{subagent-executor-KZZQGAKV.js → subagent-executor-LPZ4BHWE.js} +29 -11
  198. package/dist/node-runtime/{update-cli-GTFJC7XK.js → update-cli-HNMOTNGX.js} +2 -1
  199. package/dist/node-runtime/workflow-OHPBEFO4.js +637 -0
  200. package/dist/utils/image-resize-core.d.ts +2 -0
  201. package/dist/utils/image-resize-core.d.ts.map +1 -1
  202. package/dist/utils/image-resize-core.js +10 -0
  203. package/dist/utils/image-resize-core.js.map +1 -1
  204. package/docs/computer-use.md +362 -0
  205. package/docs/features.md +8 -6
  206. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  207. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  208. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  209. package/examples/extensions/gondolin/package-lock.json +2 -2
  210. package/examples/extensions/gondolin/package.json +1 -1
  211. package/examples/extensions/sandbox/package-lock.json +2 -2
  212. package/examples/extensions/sandbox/package.json +1 -1
  213. package/examples/extensions/with-deps/package-lock.json +2 -2
  214. package/examples/extensions/with-deps/package.json +1 -1
  215. package/install-lock/package-lock.json +3841 -0
  216. package/install-lock/package.json +18 -0
  217. package/native/computer-use/LICENSE.md +21 -0
  218. package/npm-shrinkwrap.json +3822 -0
  219. package/package.json +15 -9
  220. package/dist/node-runtime/{chunk-LQP3RB67.js → chunk-RAK2QA2B.js} +3 -3
@@ -0,0 +1,637 @@
1
+ import { createRequire as __lunrRequire } from "node:module"; const require = __lunrRequire(import.meta.url);
2
+ import {
3
+ DriverCallError
4
+ } from "./chunk-IKU6Y7DL.js";
5
+ import {
6
+ assertOwnedPath
7
+ } from "./chunk-5B6VKFEV.js";
8
+ import {
9
+ computerSchemas
10
+ } from "./chunk-RGQAEOM5.js";
11
+ import "./chunk-LWJXTA6Z.js";
12
+ import "./chunk-2IDTZAG5.js";
13
+ import "./chunk-BI3DHYCN.js";
14
+ import "./chunk-PL6JKXWI.js";
15
+ import {
16
+ resizeImage
17
+ } from "./chunk-5Q4A37RB.js";
18
+ import {
19
+ require_proper_lockfile
20
+ } from "./chunk-URD2SLIT.js";
21
+ import {
22
+ loadPhoton
23
+ } from "./chunk-RQ2Q5IYR.js";
24
+ import "./chunk-FQMM2EZ2.js";
25
+ import "./chunk-Q4Q6D4IY.js";
26
+ import {
27
+ __toESM
28
+ } from "./chunk-BRJX2PRC.js";
29
+
30
+ // packages/coding-agent/dist/core/computer-use/workflow.js
31
+ import { randomUUID as randomUUID2 } from "node:crypto";
32
+ import { setTimeout as delay } from "node:timers/promises";
33
+
34
+ // packages/coding-agent/dist/core/computer-use/image.js
35
+ import { createHash } from "node:crypto";
36
+ function screenshotDimensions(image) {
37
+ if (image.mimeType !== "image/png" || image.data.length > 64 * 1024 * 1024)
38
+ throw new Error("Expected a bounded PNG screenshot.");
39
+ let bytes = Buffer.from(image.data, "base64");
40
+ if (bytes.length < 24 || !bytes.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10])))
41
+ throw new Error("Invalid screenshot PNG.");
42
+ let width = bytes.readUInt32BE(16), height = bytes.readUInt32BE(20);
43
+ if (!width || !height || width > 16384 || height > 16384 || width * height > 4e7)
44
+ throw new Error("Screenshot dimensions exceed the supported capture budget.");
45
+ return { width, height };
46
+ }
47
+ async function prepareComputerImage(image, crop) {
48
+ let source = screenshotDimensions(image), region = crop ?? { x: 0, y: 0, ...source };
49
+ if (![region.x, region.y, region.width, region.height].every(Number.isInteger) || region.x < 0 || region.y < 0 || region.width < 1 || region.height < 1 || region.x + region.width > source.width || region.y + region.height > source.height)
50
+ throw new Error("Crop is outside the captured image.");
51
+ let bytes = Buffer.from(image.data, "base64"), fingerprint;
52
+ if (crop) {
53
+ let photon = await loadPhoton();
54
+ if (!photon)
55
+ throw new Error("Image processing is unavailable; crop refused.");
56
+ let original = photon.PhotonImage.new_from_byteslice(bytes);
57
+ try {
58
+ if (original.get_width() !== source.width || original.get_height() !== source.height)
59
+ throw new Error("Decoded screenshot dimensions changed.");
60
+ fingerprint = createHash("sha256").update(`${source.width}x${source.height}:`).update(original.get_raw_pixels()).digest("hex");
61
+ let cropped = photon.crop(original, region.x, region.y, region.x + region.width, region.y + region.height);
62
+ try {
63
+ bytes = cropped.get_bytes();
64
+ } finally {
65
+ cropped.free();
66
+ }
67
+ } finally {
68
+ original.free();
69
+ }
70
+ }
71
+ let ratio = Math.min(1, 1280 / Math.max(region.width, region.height), Math.sqrt(1e6 / (region.width * region.height))), resized = await resizeImage(bytes, "image/png", {
72
+ maxWidth: Math.max(1, Math.floor(region.width * ratio)),
73
+ maxHeight: Math.max(1, Math.floor(region.height * ratio)),
74
+ maxBytes: 1.5 * 1024 * 1024,
75
+ includePixelFingerprint: !crop
76
+ });
77
+ if (!resized || resized.originalWidth !== region.width || resized.originalHeight !== region.height || resized.width < 1 || resized.height < 1 || resized.width > 1280 || resized.height > 1280 || resized.width * resized.height > 1e6)
78
+ throw new Error("Screenshot could not be decoded within the image budget.");
79
+ if (fingerprint ??= resized.fingerprint, !fingerprint)
80
+ throw new Error("Screenshot pixel identity could not be verified.");
81
+ return {
82
+ fingerprint,
83
+ image: { type: "image", data: resized.data, mimeType: resized.mimeType },
84
+ width: resized.width,
85
+ height: resized.height,
86
+ sourceWidth: source.width,
87
+ sourceHeight: source.height,
88
+ region,
89
+ scaleX: region.width / resized.width,
90
+ scaleY: region.height / resized.height
91
+ };
92
+ }
93
+
94
+ // packages/coding-agent/dist/core/computer-use/lease.js
95
+ var import_proper_lockfile = __toESM(require_proper_lockfile(), 1);
96
+ import { randomUUID } from "node:crypto";
97
+ import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
98
+ import { userInfo } from "node:os";
99
+ import { join } from "node:path";
100
+ var DesktopLease = class {
101
+ identity = randomUUID();
102
+ owned = !1;
103
+ tail = Promise.resolve();
104
+ closed = !1;
105
+ controller = new AbortController();
106
+ get signal() {
107
+ return this.controller.signal;
108
+ }
109
+ directory;
110
+ constructor(directory = join(userInfo().homedir, ".lunr", "desktop")) {
111
+ this.directory = directory;
112
+ }
113
+ async owner() {
114
+ try {
115
+ let value = JSON.parse(await readFile(join(this.directory, "workflow-owner.json"), "utf8"));
116
+ if (!value || typeof value != "object" || !("pid" in value) || typeof value.pid != "number" || !Number.isInteger(value.pid) || value.pid < 1 || !("identity" in value) || typeof value.identity != "string")
117
+ throw new Error("Invalid desktop owner record; refusing takeover.");
118
+ let processes = "processes" in value ? value.processes : [];
119
+ if (!Array.isArray(processes) || !processes.every((pid) => Number.isInteger(pid) && pid > 0))
120
+ throw new Error("Invalid runtime owner record; refusing takeover.");
121
+ return { pid: value.pid, identity: value.identity, processes };
122
+ } catch (error) {
123
+ if (error instanceof Error && "code" in error && error.code === "ENOENT")
124
+ return;
125
+ throw error;
126
+ }
127
+ }
128
+ async withOwnerLock(operation) {
129
+ let release = await import_proper_lockfile.default.lock(this.directory, {
130
+ lockfilePath: join(this.directory, "workflow-acquire.lock"),
131
+ retries: 0,
132
+ stale: 1e4
133
+ });
134
+ try {
135
+ await operation();
136
+ } finally {
137
+ await release();
138
+ }
139
+ }
140
+ async writeOwner(owner) {
141
+ let temporary = join(this.directory, `workflow-owner-${randomUUID()}.tmp`);
142
+ try {
143
+ await writeFile(temporary, JSON.stringify(owner), { mode: 384, flag: "wx" }), await rename(temporary, join(this.directory, "workflow-owner.json"));
144
+ } finally {
145
+ await rm(temporary, { force: !0 });
146
+ }
147
+ }
148
+ async acquire() {
149
+ await assertOwnedPath(this.directory), await mkdir(this.directory, { recursive: !0, mode: 448 }), await this.withOwnerLock(async () => {
150
+ let owner = await this.owner();
151
+ if (owner && [owner.pid, ...owner.processes].some((pid) => {
152
+ try {
153
+ return process.kill(pid, 0), !0;
154
+ } catch (error) {
155
+ return !(error instanceof Error && "code" in error && error.code === "ESRCH");
156
+ }
157
+ }))
158
+ throw new Error("Desktop busy: another lunR workflow owns this user's desktop. Retry only after it ends.");
159
+ await this.writeOwner({ pid: process.pid, identity: this.identity }), this.owned = !0;
160
+ });
161
+ }
162
+ async trackProcess(pid) {
163
+ await this.withOwnerLock(async () => {
164
+ let owner = await this.owner();
165
+ if (!owner || owner.identity !== this.identity || !Number.isInteger(pid) || pid < 1)
166
+ throw new Error("Cannot bind runtime to the desktop lease.");
167
+ owner.processes.includes(pid) || owner.processes.push(pid), await this.writeOwner(owner);
168
+ });
169
+ }
170
+ run(operation, signal) {
171
+ let result = this.tail.then(async () => {
172
+ if (this.closed)
173
+ throw new Error("Desktop workflow ended. Start a new workflow and observe again.");
174
+ if (signal?.throwIfAborted(), this.owned || await this.acquire(), (await this.owner())?.identity !== this.identity)
175
+ throw this.closed = !0, this.controller.abort(new Error("Desktop lease lost.")), new Error("Desktop lease lost. Input refused.");
176
+ return signal?.throwIfAborted(), operation();
177
+ });
178
+ return this.tail = result.catch(() => {
179
+ }), result;
180
+ }
181
+ async close() {
182
+ this.closed = !0, this.controller.abort(), await this.tail, this.owned && (await this.withOwnerLock(async () => {
183
+ (await this.owner())?.identity === this.identity && await rm(join(this.directory, "workflow-owner.json"));
184
+ }), this.owned = !1);
185
+ }
186
+ };
187
+
188
+ // packages/coding-agent/dist/core/computer-use/workflow.js
189
+ function driverData(reply) {
190
+ if (reply.structuredContent && typeof reply.structuredContent == "object" && !Array.isArray(reply.structuredContent))
191
+ return Object.fromEntries(Object.entries(reply.structuredContent));
192
+ if (Array.isArray(reply.content)) {
193
+ for (let item of reply.content)
194
+ if (!(item.type !== "text" || typeof item.text != "string"))
195
+ try {
196
+ let value = JSON.parse(item.text);
197
+ if (value && typeof value == "object" && !Array.isArray(value))
198
+ return Object.fromEntries(Object.entries(value));
199
+ } catch {
200
+ }
201
+ }
202
+ return {};
203
+ }
204
+ function plainLaunchReason(reply) {
205
+ if (reply.structuredContent || !Array.isArray(reply.content))
206
+ return;
207
+ let text = reply.content.find((item) => item.type === "text")?.text;
208
+ if (typeof text == "string") {
209
+ if (/^App name lookup for .+ is (?:temporarily unavailable|unavailable).+No app was launched;/s.test(text))
210
+ return "app_lookup_unavailable";
211
+ if (/^App .+ was not found in shell:AppsFolder or by Windows PATH\/association lookup:/s.test(text))
212
+ return "app_not_found";
213
+ if (/^Launch of .+ timed out after 15s/s.test(text))
214
+ return "launch_timeout_unknown";
215
+ if (/^(?:Failed to launch|Task error): /s.test(text))
216
+ return "launch_native_error_unknown";
217
+ }
218
+ }
219
+ function driverRefused(reply) {
220
+ let data = driverData(reply), acknowledged = data.activated === !0 || data.success === !0 || data.verified === !0 || data.effect === "confirmed", uncertain = [data.status, data.effect].some((value) => value === "partial" || value === "unverifiable");
221
+ return reply.isError === !0 || plainLaunchReason(reply) !== void 0 || data.refusal !== void 0 && data.refusal !== null && data.refusal !== !1 || data.error !== void 0 && data.error !== null && data.error !== !1 || data.effect === "refused" || data.status === "refused" || data.status === "failed" || data.success === !1 || ["window_target_mismatch", "window_target_not_found", "background_unavailable", "foreground_unavailable", "type_text_incomplete", "verification_failed"].includes(String(data.code)) || data.status !== void 0 && !acknowledged && !uncertain && !["ok", "success", "completed"].includes(String(data.status)) || data.code !== void 0 && data.code !== 0 && !acknowledged && !uncertain;
222
+ }
223
+ function record(value) {
224
+ return value !== null && typeof value == "object" && !Array.isArray(value) ? Object.fromEntries(Object.entries(value)) : {};
225
+ }
226
+ function select(data, keys) {
227
+ let result = {};
228
+ for (let key of keys) {
229
+ let value = data[key];
230
+ ["name", "app_name", "title"].includes(key) && typeof value == "string" ? result[key] = value.slice(0, 240) : (["active", "running", "is_on_screen", "minimized"].includes(key) && typeof value == "boolean" || ["pid", "window_id", "x", "y", "width", "height"].includes(key) && typeof value == "number" && Number.isSafeInteger(value)) && (result[key] = value);
231
+ }
232
+ return result;
233
+ }
234
+ function typingRecovery(data, text) {
235
+ if (typeof text != "string")
236
+ return {};
237
+ let requested = data.requested_chars, delivered = data.delivered_chars;
238
+ if (typeof requested != "number" || !Number.isSafeInteger(requested) || requested < 0 || requested > 2e4 || requested !== Array.from(text).length)
239
+ return {};
240
+ let validDelivered = typeof delivered == "number" && Number.isSafeInteger(delivered) && delivered >= 0 && delivered <= requested;
241
+ return {
242
+ requested_chars: requested,
243
+ delivered_chars: validDelivered ? delivered : void 0,
244
+ retryable: validDelivered && data.retry_from_character === delivered && typeof data.retryable == "boolean" ? data.retryable : void 0,
245
+ retry_from_character: validDelivered && data.retry_from_character === delivered ? delivered : void 0
246
+ };
247
+ }
248
+ var nativeCodes = /* @__PURE__ */ new Set(["background_unavailable", "background_occluded", "background_uipi_blocked", "window_target_mismatch", "window_target_not_found", "type_text_incomplete", "foreground_unavailable", "foreground_rejected", "stale_target", "target_not_found", "verification_failed", "tool_invocation_failed"]);
249
+ function safeCode(value) {
250
+ return typeof value == "string" && nativeCodes.has(value) ? value : void 0;
251
+ }
252
+ function nativeReason(reply) {
253
+ let data = driverData(reply), code = safeCode(data.code) ?? safeCode(record(data.refusal).code) ?? safeCode(record(data.error).code) ?? safeCode(data.refusal) ?? safeCode(data.error);
254
+ return code || (plainLaunchReason(reply) ? plainLaunchReason(reply) : "native_error_unknown");
255
+ }
256
+ function outcome(reply, text) {
257
+ let data = driverData(reply), refused = driverRefused(reply), partial = data.effect === "partial" || data.status === "partial";
258
+ return {
259
+ phase: refused || partial ? "native_result" : "native_request",
260
+ code: refused || partial ? nativeReason(reply) : void 0,
261
+ native_code: safeCode(data.code) ?? safeCode(record(data.refusal).code) ?? safeCode(record(data.error).code),
262
+ status: typeof data.status == "string" && ["ok", "success", "completed", "partial", "refused", "failed"].includes(data.status) ? data.status : void 0,
263
+ effect: typeof data.effect == "string" && ["confirmed", "partial", "unverifiable", "refused"].includes(data.effect) ? data.effect : void 0,
264
+ verified: typeof data.verified == "boolean" ? data.verified : void 0,
265
+ success: typeof data.success == "boolean" ? data.success : void 0,
266
+ activated: typeof data.activated == "boolean" ? data.activated : void 0,
267
+ escalation: record(data.escalation).recommended === "foreground" ? "foreground" : void 0,
268
+ input: partial && typingRecovery(data, text).delivered_chars !== void 0 ? "partial" : refused || partial ? "uncertain" : "dispatched",
269
+ applicationEffect: "unverified",
270
+ ...typingRecovery(data, text)
271
+ };
272
+ }
273
+ function abortable(pending, signal) {
274
+ return new Promise((resolve, reject) => {
275
+ let abort = () => {
276
+ signal.removeEventListener("abort", abort), reject(signal.reason ?? new Error("Computer operation cancelled."));
277
+ };
278
+ signal.addEventListener("abort", abort, { once: !0 }), pending.then((value) => {
279
+ signal.removeEventListener("abort", abort), resolve(value);
280
+ }, (error) => {
281
+ signal.removeEventListener("abort", abort), reject(error);
282
+ }), signal.aborted && abort();
283
+ });
284
+ }
285
+ var freshActionGuidance = "Get a fresh capture of the exact target before any next action, including window focus. Copy its token exactly. No input was sent by this call; earlier calls may have had an effect.", CaptureError = class extends Error {
286
+ code;
287
+ constructor(code) {
288
+ super(code), this.code = code;
289
+ }
290
+ }, ObservationError = class extends Error {
291
+ code;
292
+ constructor(code, message) {
293
+ super(`Stale observation. ${message}`), this.code = code;
294
+ }
295
+ };
296
+ function targetFrom(input) {
297
+ if (input.desktop === !0) {
298
+ if (input.pid !== void 0 || input.window_id !== void 0)
299
+ throw new Error("Desktop target cannot include pid/window_id.");
300
+ return { desktop: !0 };
301
+ }
302
+ if (typeof input.pid != "number" || !Number.isInteger(input.pid) || input.pid < 1 || typeof input.window_id != "number" || !Number.isInteger(input.window_id) || input.window_id < 1)
303
+ throw new Error("Window target requires positive integer pid and window_id.");
304
+ return { pid: input.pid, window_id: input.window_id };
305
+ }
306
+ function sameTarget(a, b) {
307
+ return a.desktop === !0 ? b.desktop === !0 : b.desktop !== !0 && a.pid === b.pid && a.window_id === b.window_id;
308
+ }
309
+ var ComputerWorkflow = class {
310
+ observation;
311
+ lastCapture;
312
+ lastAction;
313
+ abort = new AbortController();
314
+ closing;
315
+ driver;
316
+ lease;
317
+ constructor(driver, lease = new DesktopLease()) {
318
+ this.driver = driver, this.lease = lease, this.driver.setProcessObserver?.((pid) => this.lease.trackProcess(pid));
319
+ }
320
+ fresh(input, previous) {
321
+ if (!previous)
322
+ throw new ObservationError("observation_unavailable", "No active observation is available.");
323
+ if (previous.token !== input.observation)
324
+ throw new ObservationError("observation_mismatch", "Token does not match the active observation.");
325
+ if (!sameTarget(previous.target, targetFrom(input)))
326
+ throw new ObservationError("observation_target_mismatch", "Token belongs to a different target.");
327
+ if (Date.now() - previous.time > 3e4)
328
+ throw new ObservationError("observation_expired", "The active observation is older than 30 seconds.");
329
+ return previous;
330
+ }
331
+ async capture(target, signal, previous, crop) {
332
+ let time = Date.now(), reply = await abortable(this.driver.call(target.desktop ? "get_desktop_state" : "get_window_state", target.desktop ? {} : { pid: target.pid, window_id: target.window_id, include_accessibility_tree: !1, include_screenshot: !0, max_dimension: 2560 }, signal), signal);
333
+ if (driverRefused(reply))
334
+ throw new CaptureError(nativeReason(reply));
335
+ let data = driverData(reply), images = Array.isArray(reply.content) ? reply.content.filter((item) => item.type === "image") : [];
336
+ if (images.length !== 1 || typeof images[0].data != "string" || typeof images[0].mimeType != "string")
337
+ throw new CaptureError("screenshot_unavailable");
338
+ let image = { type: "image", data: images[0].data, mimeType: images[0].mimeType }, dimensions;
339
+ try {
340
+ dimensions = screenshotDimensions(image);
341
+ } catch {
342
+ throw new CaptureError("image_decode_failed");
343
+ }
344
+ if (data.screenshot_frame_valid === !1 || data.screenshot_error != null || dimensions.width !== data.screenshot_width || dimensions.height !== data.screenshot_height)
345
+ throw new CaptureError("image_frame_invalid");
346
+ let geometry = JSON.stringify(select(record(data.window_bounds), ["x", "y", "width", "height"]));
347
+ if (crop && previous && (previous.sourceWidth !== dimensions.width || previous.sourceHeight !== dimensions.height || previous.geometry !== geometry))
348
+ throw new CaptureError("target_geometry_changed");
349
+ let prepared;
350
+ try {
351
+ prepared = await abortable(prepareComputerImage(image, crop), signal);
352
+ } catch (error) {
353
+ throw signal.aborted ? error : new CaptureError("image_decode_failed");
354
+ }
355
+ return signal.throwIfAborted(), { ...prepared, token: randomUUID2(), target, time, fingerprint: prepared.fingerprint, geometry };
356
+ }
357
+ imageResult(observation, extra = {}) {
358
+ this.observation = observation;
359
+ let { width, height, region, sourceWidth, sourceHeight, scaleX, scaleY, target, token } = observation, failed = extra.failed === !0;
360
+ return {
361
+ content: [{ type: "text", text: JSON.stringify({
362
+ ...extra,
363
+ observation: token,
364
+ target,
365
+ captured_at: observation.time,
366
+ expires_at: observation.time + 3e4,
367
+ image: { width, height },
368
+ mapping: { sourceWidth, sourceHeight, ...region, scaleX, scaleY },
369
+ coordinates: "Use returned-image pixels; mapping is applied automatically."
370
+ }) }, observation.image],
371
+ details: { observation: token, computer: { failed, workflow: "ready" } },
372
+ isError: failed
373
+ };
374
+ }
375
+ crop(input, previous) {
376
+ let crop = record(input.crop), { x, y, width, height } = crop;
377
+ if (typeof x != "number" || typeof y != "number" || typeof width != "number" || typeof height != "number" || ![x, y, width, height].every(Number.isFinite) || x < 0 || y < 0 || width <= 0 || height <= 0 || x + width > previous.width || y + height > previous.height || Object.keys(crop).some((key) => !["x", "y", "width", "height"].includes(key)))
378
+ throw new Error("Crop must fit the latest returned image.");
379
+ let left = Math.floor(previous.region.x + x * previous.scaleX), top = Math.floor(previous.region.y + y * previous.scaleY), right = Math.min(previous.sourceWidth, Math.ceil(previous.region.x + (x + width) * previous.scaleX)), bottom = Math.min(previous.sourceHeight, Math.ceil(previous.region.y + (y + height) * previous.scaleY));
380
+ return { x: left, y: top, width: right - left, height: bottom - top };
381
+ }
382
+ action(name, input, previous) {
383
+ let args = previous.target.desktop ? { scope: "desktop" } : { pid: previous.target.pid, window_id: previous.target.window_id };
384
+ if (previous.target.desktop && input.foreground !== !0)
385
+ throw new Error("Desktop input requires foreground=true.");
386
+ name !== "computer_window" && name !== "computer_hover" && (args.delivery_mode = input.foreground === !0 ? "foreground" : "background");
387
+ for (let key of ["x", "y", "from_x", "from_y", "to_x", "to_y"]) {
388
+ if (name === "computer_window")
389
+ break;
390
+ let value = input[key];
391
+ if (value === void 0)
392
+ continue;
393
+ let horizontal = key.endsWith("x");
394
+ if (typeof value != "number" || !Number.isFinite(value) || value < 0 || value >= (horizontal ? previous.width : previous.height))
395
+ throw new Error("Coordinate outside the observed image.");
396
+ args[key] = (horizontal ? previous.region.x : previous.region.y) + value * (horizontal ? previous.scaleX : previous.scaleY);
397
+ }
398
+ if (input.x === void 0 != (input.y === void 0))
399
+ throw new Error("Provide a complete x/y pair.");
400
+ if (previous.target.desktop && ["computer_key", "computer_text"].includes(name) && input.x !== void 0)
401
+ throw new Error("Desktop keyboard input uses the observed focused field. Change focus with a separate grounded click.");
402
+ let operation;
403
+ switch (name) {
404
+ case "computer_hover":
405
+ if (process.platform !== "win32" || !previous.target.desktop || input.desktop !== !0 || input.foreground !== !0 || input.x === void 0 || input.y === void 0)
406
+ throw new Error("Hover requires a Windows foreground desktop image and x/y coordinates.");
407
+ operation = "move_cursor";
408
+ break;
409
+ case "computer_click":
410
+ case "computer_scroll":
411
+ if (input.x === void 0 || input.y === void 0)
412
+ throw new Error("This action requires x/y image coordinates.");
413
+ operation = name === "computer_click" ? "click" : "scroll";
414
+ for (let key of name === "computer_click" ? ["button", "count", "modifier"] : ["direction", "amount", "by"])
415
+ input[key] !== void 0 && (args[key] = input[key]);
416
+ break;
417
+ case "computer_drag":
418
+ if (!["from_x", "from_y", "to_x", "to_y"].every((key) => typeof args[key] == "number"))
419
+ throw new Error("Drag requires both endpoints.");
420
+ operation = "drag";
421
+ break;
422
+ case "computer_key": {
423
+ if (input.key === void 0 == (input.keys === void 0))
424
+ throw new Error("Provide key OR keys.");
425
+ let keys = Array.isArray(input.keys) ? input.keys : void 0, last = keys?.at(-1), modifiers = /* @__PURE__ */ new Set(["ctrl", "control", "shift", "alt", "win", "windows", "cmd", "command"]), foregroundShortcut = process.platform === "win32" && input.foreground === !0 && input.x === void 0 && keys !== void 0 && keys.length >= 2 && keys.slice(0, -1).every((key) => typeof key == "string" && modifiers.has(key.toLowerCase())) && typeof last == "string" && !modifiers.has(last.toLowerCase());
426
+ operation = input.keys === void 0 || foregroundShortcut ? "press_key" : "hotkey", foregroundShortcut ? (args.key = last, args.modifiers = keys.slice(0, -1)) : args[input.keys === void 0 ? "key" : "keys"] = input.keys ?? input.key;
427
+ break;
428
+ }
429
+ case "computer_text":
430
+ operation = "type_text", args.text = input.text;
431
+ break;
432
+ case "computer_window":
433
+ if (previous.target.desktop)
434
+ throw new Error("Window management requires an exact window target.");
435
+ if (input.action === "frame") {
436
+ for (let key of ["x", "y", "width", "height"]) {
437
+ let value = input[key];
438
+ if (typeof value != "number" || !Number.isFinite(value) || ["width", "height"].includes(key) && value <= 0)
439
+ throw new Error("Frame requires valid x/y/width/height.");
440
+ args[key] = value;
441
+ }
442
+ operation = "set_window_frame";
443
+ } else if (input.action === "focus" && ["x", "y", "width", "height"].every((key) => input[key] === void 0))
444
+ operation = "bring_to_front";
445
+ else
446
+ throw new Error("Use frame or focus. Minimize/restore uses a fresh image click on the visible control.");
447
+ break;
448
+ default:
449
+ throw new Error("Unknown computer action.");
450
+ }
451
+ return { operation, args };
452
+ }
453
+ async execute(name, input, signal) {
454
+ let combined = AbortSignal.any([this.abort.signal, this.lease.signal, AbortSignal.timeout(9e4), ...signal ? [signal] : []]), inputDispatched = !1, failureCode = "workflow_unavailable", phase = "validation", currentPhase = () => phase, operationName = name, actionTarget, actionOutcome;
455
+ try {
456
+ let result = await this.lease.run(async () => {
457
+ failureCode = "invalid_arguments";
458
+ let previous = this.observation;
459
+ if (name !== "computer_apps" && (this.observation = void 0), !Object.hasOwn(computerSchemas, name))
460
+ throw new Error("Unknown computer operation.");
461
+ let schema = computerSchemas[name];
462
+ if (Object.keys(input).some((key) => !Object.hasOwn(schema.properties, key)))
463
+ throw new Error("Unsupported computer argument. Use image coordinates only.");
464
+ if (name === "computer_apps" || name === "computer_launch") {
465
+ let operation2 = name === "computer_launch" ? "launch_app" : input.pid === void 0 ? "list_apps" : "list_windows";
466
+ if (operationName = operation2, input.include_windows !== void 0 && (name !== "computer_apps" || typeof input.include_windows != "boolean" || input.include_windows && (input.pid !== void 0 || typeof input.query != "string" || !input.query.trim())))
467
+ throw new Error("include_windows requires a named app query without pid.");
468
+ if (input.pid !== void 0 && (typeof input.pid != "number" || !Number.isSafeInteger(input.pid) || input.pid < 1))
469
+ throw new Error("Window lookup requires a positive pid.");
470
+ if (name === "computer_launch" && (typeof input.name != "string" || !input.name.trim() || input.name.length > 500))
471
+ throw new Error("Launch requires a nonblank name.");
472
+ if (input.query !== void 0 && (typeof input.query != "string" || !input.query.trim() || Array.from(input.query).length > 240))
473
+ throw new Error("Discovery query must be a nonblank string of at most 240 characters.");
474
+ let query = typeof input.query == "string" ? input.query.trim() : void 0, needle = query?.toLowerCase(), offset = input.offset ?? 0;
475
+ if (typeof offset != "number" || !Number.isSafeInteger(offset) || offset < 0)
476
+ throw new Error("Discovery offset must be a nonnegative safe integer.");
477
+ let args2 = name === "computer_launch" ? { name: input.name } : input.pid === void 0 ? {} : { pid: input.pid };
478
+ combined.throwIfAborted(), inputDispatched = name === "computer_launch", phase = "native_request", failureCode = "discovery_failed";
479
+ let reply2 = await abortable(this.driver.call(operation2, args2, combined), combined), data = driverData(reply2), discovered = data.apps ?? data.windows, rows = Array.isArray(discovered) && needle ? discovered.filter((row) => {
480
+ let item = record(row);
481
+ return [item.name, item.app_name, item.title].some((value) => typeof value == "string" && value.toLowerCase().includes(needle));
482
+ }) : discovered, metadata = Array.isArray(rows) ? rows.slice(offset, offset + 50).map((row) => {
483
+ let item = record(row);
484
+ return {
485
+ ...select(item, ["pid", "window_id", "name", "app_name", "title", "active", "running", "is_on_screen", "minimized"]),
486
+ bounds: item.bounds ? select(record(item.bounds), ["x", "y", "width", "height"]) : void 0
487
+ };
488
+ }) : void 0, remaining = Array.isArray(rows) ? Math.max(0, rows.length - offset - (metadata?.length ?? 0)) : 0, failed2 = driverRefused(reply2), pid = typeof data.pid == "number" && Number.isSafeInteger(data.pid) && data.pid > 0 ? data.pid : void 0, launchWindows = Array.isArray(data.windows) ? data.windows.slice(0, 50).map((row) => {
489
+ let item = record(row);
490
+ return { ...select(item, ["window_id", "title", "is_on_screen", "minimized"]), bounds: item.bounds ? select(record(item.bounds), ["x", "y", "width", "height"]) : void 0 };
491
+ }) : [], returnedId = data.window_id ?? (Array.isArray(data.windows) && data.windows.length === 1 ? record(data.windows[0]).window_id : void 0), windowId = typeof returnedId == "number" && Number.isSafeInteger(returnedId) && returnedId > 0 ? returnedId : void 0, windowsByPid, guidance = remaining ? "Pass next_offset as offset with the same pid and query. Lists refresh per call." : input.pid !== void 0 ? "Use computer_observe({pid,window_id}) for an exact returned window." : "App query filters app identities, not every window title. Use computer_apps({pid}) to find windows for a running app.";
492
+ if (name === "computer_apps" && input.include_windows === !0 && !failed2) {
493
+ let pids = [...new Set((Array.isArray(rows) ? rows : []).map((row) => record(row).pid).filter((value) => typeof value == "number" && Number.isSafeInteger(value) && value > 0))];
494
+ if (pids.length > 5)
495
+ guidance = "More than five running processes matched. Narrow the query or choose one positive pid with computer_apps({pid}); no arbitrary process was selected.";
496
+ else {
497
+ windowsByPid = [];
498
+ let budget = 50;
499
+ for (let matchingPid of pids) {
500
+ combined.throwIfAborted();
501
+ try {
502
+ let windowsReply = await abortable(this.driver.call("list_windows", { pid: matchingPid }, combined), combined), windows = driverData(windowsReply).windows;
503
+ if (driverRefused(windowsReply) || !Array.isArray(windows)) {
504
+ windowsByPid.push({ pid: matchingPid, error: driverRefused(windowsReply) ? nativeReason(windowsReply) : "windows_unavailable" });
505
+ continue;
506
+ }
507
+ let subset = windows.slice(0, budget).map((row) => {
508
+ let item = record(row);
509
+ return {
510
+ ...select(item, ["pid", "window_id", "name", "app_name", "title", "active", "running", "is_on_screen", "minimized"]),
511
+ bounds: item.bounds ? select(record(item.bounds), ["x", "y", "width", "height"]) : void 0
512
+ };
513
+ }), omitted = windows.length - subset.length;
514
+ windowsByPid.push({ pid: matchingPid, windows: subset, omitted: omitted || void 0, next_offset: omitted ? subset.length : void 0 }), budget -= subset.length;
515
+ } catch (error) {
516
+ if (combined.aborted || error instanceof DriverCallError)
517
+ throw error;
518
+ windowsByPid.push({ pid: matchingPid, error: "window_lookup_failed" });
519
+ }
520
+ }
521
+ guidance = "Use computer_observe({pid,window_id}) for a returned window. For omitted windows use computer_apps({pid,offset:next_offset}). Per-PID failures need a targeted lookup.";
522
+ }
523
+ }
524
+ return name === "computer_launch" && (guidance = pid && windowId && !failed2 ? `Use computer_observe({pid:${pid},window_id:${windowId}}) before input.` : `Launch ${failed2 ? "may have completed despite an unsuccessful reply" : "returned no exact window"}. Use computer_apps({${pid ? `pid:${pid}` : `query:${JSON.stringify(input.name)}`}}) before another launch or input.`), { content: [{ type: "text", text: JSON.stringify({
525
+ kind: name === "computer_launch" ? "launch" : input.pid === void 0 ? "apps" : "windows",
526
+ operation: operation2,
527
+ ...name === "computer_launch" ? outcome(reply2) : { phase: "native_result", code: failed2 ? nativeReason(reply2) : void 0 },
528
+ input: name === "computer_launch" ? "not_applicable" : void 0,
529
+ launch: name === "computer_launch" ? plainLaunchReason(reply2) === "app_lookup_unavailable" ? "not_started" : failed2 ? "completion_uncertain" : "acknowledged" : void 0,
530
+ ...select(data, ["pid", "window_id", "name", "title"]),
531
+ window_id: name === "computer_launch" ? windowId : select(data, ["window_id"]).window_id,
532
+ windows: name === "computer_launch" ? launchWindows : void 0,
533
+ items: name === "computer_launch" ? void 0 : metadata,
534
+ windows_by_pid: windowsByPid,
535
+ query,
536
+ offset,
537
+ total: Array.isArray(rows) ? rows.length : void 0,
538
+ omitted: remaining || void 0,
539
+ next_offset: remaining ? offset + 50 : void 0,
540
+ guidance
541
+ }) }], details: { computer: { failed: failed2, workflow: "ready" } }, isError: failed2 };
542
+ }
543
+ let target = targetFrom(input);
544
+ if (actionTarget = target, name === "computer_observe") {
545
+ phase = "observation_capture";
546
+ let crop = input.crop === void 0 ? void 0 : this.crop(input, this.fresh(input, previous));
547
+ failureCode = "capture_failed";
548
+ let captured = await this.capture(target, combined, previous, crop), unchanged = this.lastCapture?.fingerprint === captured.fingerprint && sameTarget(this.lastCapture.target, target), repeats = crop ? 0 : unchanged ? (this.lastCapture?.repeats ?? 0) + 1 : 1;
549
+ return this.lastCapture = { fingerprint: captured.fingerprint, target, repeats }, repeats >= 3 ? {
550
+ content: [{ type: "text", text: JSON.stringify({ phase: "observation_capture", code: "unchanged_polling_limit", guidance: "Three captures are unchanged. Stop polling and reconsider the target or approach. No input token issued." }) }],
551
+ details: { computer: { failed: !0, workflow: "stopped" } },
552
+ isError: !0
553
+ } : this.imageResult(captured, { unchanged });
554
+ }
555
+ let grounded = this.fresh(input, previous), { operation, args } = this.action(name, input, grounded), { button = "left", count = 1, modifier = [], ...clickArgs } = args, signature = JSON.stringify({ operation, args: operation === "click" ? { ...clickArgs, button, count, modifier: Array.isArray(modifier) ? [...new Set(modifier)].sort() : modifier } : args });
556
+ if (this.lastAction?.unchanged && this.lastAction.signature === signature && this.lastAction.fingerprint === grounded.fingerprint)
557
+ throw new Error("The identical action had no visible change. Choose a different grounded action; never retry blindly.");
558
+ combined.throwIfAborted(), inputDispatched = !0, phase = "native_request", operationName = operation;
559
+ let reply = await abortable(this.driver.call(operation, args, combined), combined);
560
+ combined.throwIfAborted(), actionOutcome = outcome(reply, name === "computer_text" ? input.text : void 0);
561
+ let recoveryGuidance = actionOutcome.retry_from_character !== void 0 ? "Verify the field in a fresh image before considering any remaining suffix. retry_from_character is a zero-based Unicode code-point offset, not UTF-16. retryable is driver advice, not authorization to retry." : void 0, failed = driverRefused(reply) || driverData(reply).effect === "partial" || driverData(reply).status === "partial", backgroundUnavailable = actionOutcome.code === "background_unavailable";
562
+ name === "computer_hover" && await delay(700, void 0, { signal: combined }), phase = "post_action_capture";
563
+ try {
564
+ let after = await this.capture(target, combined), unchanged = after.fingerprint === grounded.fingerprint;
565
+ return this.lastAction = { signature, fingerprint: after.fingerprint, unchanged }, this.lastCapture = { fingerprint: after.fingerprint, target, repeats: failed && this.lastCapture?.fingerprint === after.fingerprint && sameTarget(this.lastCapture.target, target) ? this.lastCapture.repeats : 0 }, this.imageResult(after, {
566
+ kind: "action",
567
+ operation,
568
+ target,
569
+ ...actionOutcome,
570
+ failed,
571
+ unchanged,
572
+ guidance: [
573
+ "Inspect the post-action image before another action. No visible change does not prove failure; never repeat blindly.",
574
+ backgroundUnavailable ? "After this fresh capture, foreground input may be considered if permitted, not another background shortcut." : void 0,
575
+ recoveryGuidance
576
+ ].filter(Boolean).join(" ")
577
+ });
578
+ } catch (error) {
579
+ if (combined.throwIfAborted(), !(error instanceof CaptureError))
580
+ throw error;
581
+ return this.lastAction = { signature, fingerprint: grounded.fingerprint, unchanged: !0 }, { content: [{ type: "text", text: JSON.stringify({
582
+ kind: "action",
583
+ operation,
584
+ target,
585
+ ...actionOutcome,
586
+ phase: "post_action_capture",
587
+ capture_error: error.code,
588
+ observation: "unavailable",
589
+ guidance: `Input may have taken effect. ${["target_not_found", "window_target_not_found", "window_target_mismatch"].includes(error.code) ? "Use computer_apps({pid}) or observe the desktop to find the target." : "Get a fresh capture of the exact target"} before another action; never repeat blindly. ${recoveryGuidance ?? ""}`
590
+ }) }], details: { computer: { failed: !0, workflow: "ready" } }, isError: !0 };
591
+ }
592
+ }, combined);
593
+ return result.details.computer.workflow !== "ready" ? this.finish(result) : result;
594
+ } catch (error) {
595
+ error instanceof DriverCallError && !(currentPhase() === "post_action_capture" && actionOutcome) && (phase = error.phase, inputDispatched = error.dispatched);
596
+ let failurePhase = currentPhase(), fatal = combined.aborted || this.abort.signal.aborted || this.lease.signal.aborted || error instanceof DriverCallError || !(error instanceof ObservationError || error instanceof CaptureError || failurePhase === "validation" || failurePhase === "observation_capture" && !inputDispatched), code = error instanceof ObservationError || error instanceof CaptureError ? error.code : inputDispatched && failurePhase === "post_action_capture" ? "capture_transport_failed" : error instanceof DriverCallError ? error.dispatched ? "input_dispatch_failed" : "adapter_preflight_failed" : inputDispatched ? "input_dispatch_failed" : failurePhase === "validation" ? "invalid_arguments" : failureCode, message = name === "computer_launch" ? inputDispatched ? "Launch request began; activation may have occurred." : "No launch request was sent by this call." : inputDispatched ? "Input may have taken effect; request began." : "No input was sent by this call.", guidance = inputDispatched ? name === "computer_launch" ? `Use computer_apps({query:${JSON.stringify(input.name)}) before considering another launch.` : `Get a fresh capture of the exact target before another action. Input may have taken effect; inspect the field before deciding and never repeat blindly. ${actionOutcome?.retry_from_character !== void 0 ? "Verify the field in a fresh image before considering any remaining suffix. retry_from_character is a zero-based Unicode code-point offset, not UTF-16." : ""}` : freshActionGuidance, result = { content: [{ type: "text", text: JSON.stringify({
597
+ kind: name === "computer_apps" ? "apps" : name === "computer_launch" ? "launch" : name === "computer_observe" ? "observation" : "action",
598
+ operation: operationName,
599
+ target: actionTarget,
600
+ ...actionOutcome,
601
+ action_outcome: actionOutcome,
602
+ phase: failurePhase,
603
+ code,
604
+ input: name === "computer_apps" ? void 0 : name === "computer_launch" ? "not_applicable" : inputDispatched ? "uncertain" : "not_dispatched",
605
+ request: name === "computer_launch" ? inputDispatched ? "sent" : "not_sent" : void 0,
606
+ applicationEffect: "unverified",
607
+ observation: "unavailable",
608
+ capture_error: failurePhase === "post_action_capture" ? code : void 0,
609
+ message,
610
+ guidance
611
+ }) }], details: { computer: { failed: !0, workflow: fatal ? "stopped" : "ready" } }, isError: !0 };
612
+ return fatal ? this.finish(result) : result;
613
+ }
614
+ }
615
+ async finish(result) {
616
+ try {
617
+ return await this.close(), { ...result, details: { ...result.details, computer: { failed: result.details.computer.failed, workflow: "stopped" } } };
618
+ } catch {
619
+ return {
620
+ content: [...result.content, { type: "text", text: JSON.stringify({ phase: "cleanup", cleanup: "unconfirmed", guidance: "Desktop ownership retained until shutdown is confirmed." }) }],
621
+ details: { ...result.details, computer: { failed: !0, workflow: "cleanup_unconfirmed" } },
622
+ isError: !0
623
+ };
624
+ }
625
+ }
626
+ close() {
627
+ return this.abort.abort(), this.observation = void 0, this.closing ??= this.stop(), this.closing;
628
+ }
629
+ async stop() {
630
+ await this.driver.close(), await this.lease.close();
631
+ }
632
+ };
633
+ export {
634
+ ComputerWorkflow,
635
+ driverData,
636
+ driverRefused
637
+ };