@elizaos/agent 0.25.8 → 2.0.0-alpha.83

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 (607) hide show
  1. package/LICENSE +1 -1
  2. package/package.json +994 -34
  3. package/packages/agent/src/actions/emote.d.ts +14 -0
  4. package/packages/agent/src/actions/emote.d.ts.map +1 -0
  5. package/packages/agent/src/actions/emote.js +91 -0
  6. package/packages/agent/src/actions/restart.d.ts +19 -0
  7. package/packages/agent/src/actions/restart.d.ts.map +1 -0
  8. package/packages/agent/src/actions/restart.js +86 -0
  9. package/packages/agent/src/actions/send-message.d.ts +3 -0
  10. package/packages/agent/src/actions/send-message.d.ts.map +1 -0
  11. package/packages/agent/src/actions/send-message.js +144 -0
  12. package/packages/agent/src/actions/stream-control.d.ts +15 -0
  13. package/packages/agent/src/actions/stream-control.d.ts.map +1 -0
  14. package/packages/agent/src/actions/stream-control.js +357 -0
  15. package/packages/agent/src/actions/switch-stream-source.d.ts +16 -0
  16. package/packages/agent/src/actions/switch-stream-source.d.ts.map +1 -0
  17. package/packages/agent/src/actions/switch-stream-source.js +94 -0
  18. package/packages/agent/src/actions/terminal.d.ts +14 -0
  19. package/packages/agent/src/actions/terminal.d.ts.map +1 -0
  20. package/packages/agent/src/actions/terminal.js +154 -0
  21. package/packages/agent/src/api/agent-admin-routes.d.ts +38 -0
  22. package/packages/agent/src/api/agent-admin-routes.d.ts.map +1 -0
  23. package/packages/agent/src/api/agent-admin-routes.js +93 -0
  24. package/packages/agent/src/api/agent-lifecycle-routes.d.ts +16 -0
  25. package/packages/agent/src/api/agent-lifecycle-routes.d.ts.map +1 -0
  26. package/packages/agent/src/api/agent-lifecycle-routes.js +80 -0
  27. package/packages/agent/src/api/agent-model.d.ts +12 -0
  28. package/packages/agent/src/api/agent-model.d.ts.map +1 -0
  29. package/packages/agent/src/api/agent-model.js +123 -0
  30. package/packages/agent/src/api/agent-transfer-routes.d.ts +16 -0
  31. package/packages/agent/src/api/agent-transfer-routes.d.ts.map +1 -0
  32. package/packages/agent/src/api/agent-transfer-routes.js +124 -0
  33. package/packages/agent/src/api/apps-routes.d.ts +19 -0
  34. package/packages/agent/src/api/apps-routes.d.ts.map +1 -0
  35. package/packages/agent/src/api/apps-routes.js +128 -0
  36. package/packages/agent/src/api/auth-routes.d.ts +11 -0
  37. package/packages/agent/src/api/auth-routes.d.ts.map +1 -0
  38. package/packages/agent/src/api/auth-routes.js +54 -0
  39. package/packages/agent/src/api/bsc-trade.d.ts +34 -0
  40. package/packages/agent/src/api/bsc-trade.d.ts.map +1 -0
  41. package/packages/agent/src/api/bsc-trade.js +567 -0
  42. package/packages/agent/src/api/bug-report-routes.d.ts +7 -0
  43. package/packages/agent/src/api/bug-report-routes.d.ts.map +1 -0
  44. package/packages/agent/src/api/bug-report-routes.js +124 -0
  45. package/packages/agent/src/api/character-routes.d.ts +50 -0
  46. package/packages/agent/src/api/character-routes.d.ts.map +1 -0
  47. package/packages/agent/src/api/character-routes.js +302 -0
  48. package/packages/agent/src/api/cloud-billing-routes.d.ts +14 -0
  49. package/packages/agent/src/api/cloud-billing-routes.d.ts.map +1 -0
  50. package/packages/agent/src/api/cloud-billing-routes.js +400 -0
  51. package/packages/agent/src/api/cloud-compat-routes.d.ts +15 -0
  52. package/packages/agent/src/api/cloud-compat-routes.d.ts.map +1 -0
  53. package/packages/agent/src/api/cloud-compat-routes.js +131 -0
  54. package/packages/agent/src/api/cloud-routes.d.ts +62 -0
  55. package/packages/agent/src/api/cloud-routes.d.ts.map +1 -0
  56. package/packages/agent/src/api/cloud-routes.js +339 -0
  57. package/packages/agent/src/api/cloud-status-routes.d.ts +15 -0
  58. package/packages/agent/src/api/cloud-status-routes.d.ts.map +1 -0
  59. package/packages/agent/src/api/cloud-status-routes.js +165 -0
  60. package/packages/agent/src/api/compat-utils.d.ts +49 -0
  61. package/packages/agent/src/api/compat-utils.d.ts.map +1 -0
  62. package/packages/agent/src/api/compat-utils.js +126 -0
  63. package/packages/agent/src/api/connector-health.d.ts +34 -0
  64. package/packages/agent/src/api/connector-health.d.ts.map +1 -0
  65. package/packages/agent/src/api/connector-health.js +109 -0
  66. package/packages/agent/src/api/coordinator-wiring.d.ts +46 -0
  67. package/packages/agent/src/api/coordinator-wiring.d.ts.map +1 -0
  68. package/packages/agent/src/api/coordinator-wiring.js +101 -0
  69. package/packages/agent/src/api/credit-detection.d.ts +9 -0
  70. package/packages/agent/src/api/credit-detection.d.ts.map +1 -0
  71. package/packages/agent/src/api/credit-detection.js +41 -0
  72. package/packages/agent/src/api/database.d.ts +33 -0
  73. package/packages/agent/src/api/database.d.ts.map +1 -0
  74. package/packages/agent/src/api/database.js +1019 -0
  75. package/packages/agent/src/api/diagnostics-routes.d.ts +46 -0
  76. package/packages/agent/src/api/diagnostics-routes.d.ts.map +1 -0
  77. package/packages/agent/src/api/diagnostics-routes.js +241 -0
  78. package/packages/agent/src/api/drop-service.d.ts +26 -0
  79. package/packages/agent/src/api/drop-service.d.ts.map +1 -0
  80. package/packages/agent/src/api/drop-service.js +134 -0
  81. package/packages/agent/src/api/early-logs.d.ts +29 -0
  82. package/packages/agent/src/api/early-logs.d.ts.map +1 -0
  83. package/packages/agent/src/api/early-logs.js +96 -0
  84. package/packages/agent/src/api/http-helpers.d.ts +50 -0
  85. package/packages/agent/src/api/http-helpers.d.ts.map +1 -0
  86. package/packages/agent/src/api/http-helpers.js +145 -0
  87. package/packages/agent/src/api/index.d.ts +61 -0
  88. package/packages/agent/src/api/index.d.ts.map +1 -0
  89. package/packages/agent/src/api/index.js +59 -0
  90. package/packages/agent/src/api/knowledge-routes.d.ts +23 -0
  91. package/packages/agent/src/api/knowledge-routes.d.ts.map +1 -0
  92. package/packages/agent/src/api/knowledge-routes.js +931 -0
  93. package/packages/agent/src/api/knowledge-service-loader.d.ts +51 -0
  94. package/packages/agent/src/api/knowledge-service-loader.d.ts.map +1 -0
  95. package/packages/agent/src/api/knowledge-service-loader.js +34 -0
  96. package/packages/agent/src/api/memory-bounds.d.ts +51 -0
  97. package/packages/agent/src/api/memory-bounds.d.ts.map +1 -0
  98. package/packages/agent/src/api/memory-bounds.js +81 -0
  99. package/packages/agent/src/api/memory-routes.d.ts +9 -0
  100. package/packages/agent/src/api/memory-routes.d.ts.map +1 -0
  101. package/packages/agent/src/api/memory-routes.js +241 -0
  102. package/packages/agent/src/api/merkle-tree.d.ts +90 -0
  103. package/packages/agent/src/api/merkle-tree.d.ts.map +1 -0
  104. package/packages/agent/src/api/merkle-tree.js +174 -0
  105. package/packages/agent/src/api/models-routes.d.ts +14 -0
  106. package/packages/agent/src/api/models-routes.d.ts.map +1 -0
  107. package/packages/agent/src/api/models-routes.js +37 -0
  108. package/packages/agent/src/api/nfa-routes.d.ts +5 -0
  109. package/packages/agent/src/api/nfa-routes.d.ts.map +1 -0
  110. package/packages/agent/src/api/nfa-routes.js +125 -0
  111. package/packages/agent/src/api/og-tracker.d.ts +28 -0
  112. package/packages/agent/src/api/og-tracker.d.ts.map +1 -0
  113. package/packages/agent/src/api/og-tracker.js +60 -0
  114. package/packages/agent/src/api/parse-action-block.d.ts +36 -0
  115. package/packages/agent/src/api/parse-action-block.d.ts.map +1 -0
  116. package/packages/agent/src/api/parse-action-block.js +110 -0
  117. package/packages/agent/src/api/permissions-routes.d.ts +32 -0
  118. package/packages/agent/src/api/permissions-routes.d.ts.map +1 -0
  119. package/packages/agent/src/api/permissions-routes.js +149 -0
  120. package/packages/agent/src/api/plugin-validation.d.ts +86 -0
  121. package/packages/agent/src/api/plugin-validation.d.ts.map +1 -0
  122. package/packages/agent/src/api/plugin-validation.js +259 -0
  123. package/packages/agent/src/api/provider-switch-config.d.ts +37 -0
  124. package/packages/agent/src/api/provider-switch-config.d.ts.map +1 -0
  125. package/packages/agent/src/api/provider-switch-config.js +317 -0
  126. package/packages/agent/src/api/registry-routes.d.ts +26 -0
  127. package/packages/agent/src/api/registry-routes.d.ts.map +1 -0
  128. package/packages/agent/src/api/registry-routes.js +90 -0
  129. package/packages/agent/src/api/registry-service.d.ts +77 -0
  130. package/packages/agent/src/api/registry-service.d.ts.map +1 -0
  131. package/packages/agent/src/api/registry-service.js +190 -0
  132. package/packages/agent/src/api/route-helpers.d.ts +16 -0
  133. package/packages/agent/src/api/route-helpers.d.ts.map +1 -0
  134. package/packages/agent/src/api/route-helpers.js +1 -0
  135. package/packages/agent/src/api/sandbox-routes.d.ts +12 -0
  136. package/packages/agent/src/api/sandbox-routes.d.ts.map +1 -0
  137. package/packages/agent/src/api/sandbox-routes.js +1334 -0
  138. package/packages/agent/src/api/server.d.ts +418 -0
  139. package/packages/agent/src/api/server.d.ts.map +1 -0
  140. package/packages/agent/src/api/server.js +13614 -0
  141. package/packages/agent/src/api/signal-routes.d.ts +39 -0
  142. package/packages/agent/src/api/signal-routes.d.ts.map +1 -0
  143. package/packages/agent/src/api/signal-routes.js +168 -0
  144. package/packages/agent/src/api/stream-persistence.d.ts +64 -0
  145. package/packages/agent/src/api/stream-persistence.d.ts.map +1 -0
  146. package/packages/agent/src/api/stream-persistence.js +231 -0
  147. package/packages/agent/src/api/stream-route-state.d.ts +50 -0
  148. package/packages/agent/src/api/stream-route-state.d.ts.map +1 -0
  149. package/packages/agent/src/api/stream-route-state.js +1 -0
  150. package/packages/agent/src/api/stream-routes.d.ts +45 -0
  151. package/packages/agent/src/api/stream-routes.d.ts.map +1 -0
  152. package/packages/agent/src/api/stream-routes.js +809 -0
  153. package/packages/agent/src/api/stream-voice-routes.d.ts +36 -0
  154. package/packages/agent/src/api/stream-voice-routes.d.ts.map +1 -0
  155. package/packages/agent/src/api/stream-voice-routes.js +133 -0
  156. package/packages/agent/src/api/streaming-text.d.ts +9 -0
  157. package/packages/agent/src/api/streaming-text.d.ts.map +1 -0
  158. package/packages/agent/src/api/streaming-text.js +85 -0
  159. package/packages/agent/src/api/streaming-types.d.ts +30 -0
  160. package/packages/agent/src/api/streaming-types.d.ts.map +1 -0
  161. package/packages/agent/src/api/streaming-types.js +1 -0
  162. package/packages/agent/src/api/subscription-routes.d.ts +20 -0
  163. package/packages/agent/src/api/subscription-routes.d.ts.map +1 -0
  164. package/packages/agent/src/api/subscription-routes.js +191 -0
  165. package/packages/agent/src/api/terminal-run-limits.d.ts +5 -0
  166. package/packages/agent/src/api/terminal-run-limits.d.ts.map +1 -0
  167. package/packages/agent/src/api/terminal-run-limits.js +22 -0
  168. package/packages/agent/src/api/training-backend-check.d.ts +8 -0
  169. package/packages/agent/src/api/training-backend-check.d.ts.map +1 -0
  170. package/packages/agent/src/api/training-backend-check.js +28 -0
  171. package/packages/agent/src/api/training-routes.d.ts +44 -0
  172. package/packages/agent/src/api/training-routes.d.ts.map +1 -0
  173. package/packages/agent/src/api/training-routes.js +195 -0
  174. package/packages/agent/src/api/training-service-like.d.ts +38 -0
  175. package/packages/agent/src/api/training-service-like.d.ts.map +1 -0
  176. package/packages/agent/src/api/training-service-like.js +1 -0
  177. package/packages/agent/src/api/trajectory-routes.d.ts +17 -0
  178. package/packages/agent/src/api/trajectory-routes.d.ts.map +1 -0
  179. package/packages/agent/src/api/trajectory-routes.js +405 -0
  180. package/packages/agent/src/api/trigger-routes.d.ts +72 -0
  181. package/packages/agent/src/api/trigger-routes.d.ts.map +1 -0
  182. package/packages/agent/src/api/trigger-routes.js +268 -0
  183. package/packages/agent/src/api/twitter-verify.d.ts +25 -0
  184. package/packages/agent/src/api/twitter-verify.d.ts.map +1 -0
  185. package/packages/agent/src/api/twitter-verify.js +168 -0
  186. package/packages/agent/src/api/tx-service.d.ts +47 -0
  187. package/packages/agent/src/api/tx-service.d.ts.map +1 -0
  188. package/packages/agent/src/api/tx-service.js +156 -0
  189. package/packages/agent/src/api/wallet-dex-prices.d.ts +43 -0
  190. package/packages/agent/src/api/wallet-dex-prices.d.ts.map +1 -0
  191. package/packages/agent/src/api/wallet-dex-prices.js +149 -0
  192. package/packages/agent/src/api/wallet-evm-balance.d.ts +65 -0
  193. package/packages/agent/src/api/wallet-evm-balance.d.ts.map +1 -0
  194. package/packages/agent/src/api/wallet-evm-balance.js +663 -0
  195. package/packages/agent/src/api/wallet-routes.d.ts +33 -0
  196. package/packages/agent/src/api/wallet-routes.d.ts.map +1 -0
  197. package/packages/agent/src/api/wallet-routes.js +292 -0
  198. package/packages/agent/src/api/wallet-rpc.d.ts +61 -0
  199. package/packages/agent/src/api/wallet-rpc.d.ts.map +1 -0
  200. package/packages/agent/src/api/wallet-rpc.js +367 -0
  201. package/packages/agent/src/api/wallet-trading-profile.d.ts +51 -0
  202. package/packages/agent/src/api/wallet-trading-profile.d.ts.map +1 -0
  203. package/packages/agent/src/api/wallet-trading-profile.js +547 -0
  204. package/packages/agent/src/api/wallet.d.ts +31 -0
  205. package/packages/agent/src/api/wallet.d.ts.map +1 -0
  206. package/packages/agent/src/api/wallet.js +513 -0
  207. package/packages/agent/src/api/whatsapp-routes.d.ts +39 -0
  208. package/packages/agent/src/api/whatsapp-routes.d.ts.map +1 -0
  209. package/packages/agent/src/api/whatsapp-routes.js +182 -0
  210. package/packages/agent/src/api/zip-utils.d.ts +8 -0
  211. package/packages/agent/src/api/zip-utils.d.ts.map +1 -0
  212. package/packages/agent/src/api/zip-utils.js +115 -0
  213. package/packages/agent/src/auth/anthropic.d.ts +25 -0
  214. package/packages/agent/src/auth/anthropic.d.ts.map +1 -0
  215. package/packages/agent/src/auth/anthropic.js +40 -0
  216. package/packages/agent/src/auth/apply-stealth.d.ts +8 -0
  217. package/packages/agent/src/auth/apply-stealth.d.ts.map +1 -0
  218. package/packages/agent/src/auth/apply-stealth.js +35 -0
  219. package/packages/agent/src/auth/claude-code-stealth.d.ts +2 -0
  220. package/packages/agent/src/auth/claude-code-stealth.d.ts.map +1 -0
  221. package/packages/agent/src/auth/claude-code-stealth.js +104 -0
  222. package/packages/agent/src/auth/credentials.d.ts +55 -0
  223. package/packages/agent/src/auth/credentials.d.ts.map +1 -0
  224. package/packages/agent/src/auth/credentials.js +182 -0
  225. package/packages/agent/src/auth/index.d.ts +7 -0
  226. package/packages/agent/src/auth/index.d.ts.map +1 -0
  227. package/packages/agent/src/auth/index.js +3 -0
  228. package/packages/agent/src/auth/openai-codex.d.ts +27 -0
  229. package/packages/agent/src/auth/openai-codex.d.ts.map +1 -0
  230. package/packages/agent/src/auth/openai-codex.js +72 -0
  231. package/packages/agent/src/auth/types.d.ts +18 -0
  232. package/packages/agent/src/auth/types.d.ts.map +1 -0
  233. package/packages/agent/src/auth/types.js +8 -0
  234. package/packages/agent/src/awareness/registry.d.ts +27 -0
  235. package/packages/agent/src/awareness/registry.d.ts.map +1 -0
  236. package/packages/agent/src/awareness/registry.js +161 -0
  237. package/packages/agent/src/benchmark-server.d.ts +2 -0
  238. package/packages/agent/src/benchmark-server.d.ts.map +1 -0
  239. package/packages/agent/src/benchmark-server.js +773 -0
  240. package/packages/agent/src/bin.d.ts +3 -0
  241. package/packages/agent/src/bin.d.ts.map +1 -0
  242. package/packages/agent/src/bin.js +6 -0
  243. package/packages/agent/src/cli/index.d.ts +2 -0
  244. package/packages/agent/src/cli/index.d.ts.map +1 -0
  245. package/packages/agent/src/cli/index.js +40 -0
  246. package/packages/agent/src/cli/parse-duration.d.ts +5 -0
  247. package/packages/agent/src/cli/parse-duration.d.ts.map +1 -0
  248. package/packages/agent/src/cli/parse-duration.js +27 -0
  249. package/packages/agent/src/cloud/auth.d.ts +19 -0
  250. package/packages/agent/src/cloud/auth.d.ts.map +1 -0
  251. package/packages/agent/src/cloud/auth.js +107 -0
  252. package/packages/agent/src/cloud/backup.d.ts +18 -0
  253. package/packages/agent/src/cloud/backup.d.ts.map +1 -0
  254. package/packages/agent/src/cloud/backup.js +42 -0
  255. package/packages/agent/src/cloud/base-url.d.ts +3 -0
  256. package/packages/agent/src/cloud/base-url.d.ts.map +1 -0
  257. package/packages/agent/src/cloud/base-url.js +40 -0
  258. package/packages/agent/src/cloud/bridge-client.d.ts +56 -0
  259. package/packages/agent/src/cloud/bridge-client.d.ts.map +1 -0
  260. package/packages/agent/src/cloud/bridge-client.js +190 -0
  261. package/packages/agent/src/cloud/cloud-manager.d.ts +32 -0
  262. package/packages/agent/src/cloud/cloud-manager.d.ts.map +1 -0
  263. package/packages/agent/src/cloud/cloud-manager.js +119 -0
  264. package/packages/agent/src/cloud/cloud-proxy.d.ts +20 -0
  265. package/packages/agent/src/cloud/cloud-proxy.d.ts.map +1 -0
  266. package/packages/agent/src/cloud/cloud-proxy.js +34 -0
  267. package/packages/agent/src/cloud/index.d.ts +7 -0
  268. package/packages/agent/src/cloud/index.d.ts.map +1 -0
  269. package/packages/agent/src/cloud/index.js +6 -0
  270. package/packages/agent/src/cloud/reconnect.d.ts +26 -0
  271. package/packages/agent/src/cloud/reconnect.d.ts.map +1 -0
  272. package/packages/agent/src/cloud/reconnect.js +86 -0
  273. package/packages/agent/src/cloud/validate-url.d.ts +2 -0
  274. package/packages/agent/src/cloud/validate-url.d.ts.map +1 -0
  275. package/packages/agent/src/cloud/validate-url.js +162 -0
  276. package/packages/agent/src/config/character-schema.d.ts +25 -0
  277. package/packages/agent/src/config/character-schema.d.ts.map +1 -0
  278. package/packages/agent/src/config/character-schema.js +39 -0
  279. package/packages/agent/src/config/config.d.ts +6 -0
  280. package/packages/agent/src/config/config.d.ts.map +1 -0
  281. package/packages/agent/src/config/config.js +118 -0
  282. package/packages/agent/src/config/env-vars.d.ts +3 -0
  283. package/packages/agent/src/config/env-vars.d.ts.map +1 -0
  284. package/packages/agent/src/config/env-vars.js +76 -0
  285. package/packages/agent/src/config/includes.d.ts +26 -0
  286. package/packages/agent/src/config/includes.d.ts.map +1 -0
  287. package/packages/agent/src/config/includes.js +148 -0
  288. package/packages/agent/src/config/index.d.ts +16 -0
  289. package/packages/agent/src/config/index.d.ts.map +1 -0
  290. package/packages/agent/src/config/index.js +15 -0
  291. package/packages/agent/src/config/object-utils.d.ts +2 -0
  292. package/packages/agent/src/config/object-utils.d.ts.map +1 -0
  293. package/packages/agent/src/config/object-utils.js +6 -0
  294. package/packages/agent/src/config/paths.d.ts +13 -0
  295. package/packages/agent/src/config/paths.d.ts.map +1 -0
  296. package/packages/agent/src/config/paths.js +67 -0
  297. package/packages/agent/src/config/plugin-auto-enable.d.ts +16 -0
  298. package/packages/agent/src/config/plugin-auto-enable.d.ts.map +1 -0
  299. package/packages/agent/src/config/plugin-auto-enable.js +384 -0
  300. package/packages/agent/src/config/schema.d.ts +87 -0
  301. package/packages/agent/src/config/schema.d.ts.map +1 -0
  302. package/packages/agent/src/config/schema.js +928 -0
  303. package/packages/agent/src/config/telegram-custom-commands.d.ts +25 -0
  304. package/packages/agent/src/config/telegram-custom-commands.d.ts.map +1 -0
  305. package/packages/agent/src/config/telegram-custom-commands.js +71 -0
  306. package/packages/agent/src/config/types.agent-defaults.d.ts +331 -0
  307. package/packages/agent/src/config/types.agent-defaults.d.ts.map +1 -0
  308. package/packages/agent/src/config/types.agent-defaults.js +1 -0
  309. package/packages/agent/src/config/types.agents.d.ts +110 -0
  310. package/packages/agent/src/config/types.agents.d.ts.map +1 -0
  311. package/packages/agent/src/config/types.agents.js +1 -0
  312. package/packages/agent/src/config/types.d.ts +8 -0
  313. package/packages/agent/src/config/types.d.ts.map +1 -0
  314. package/packages/agent/src/config/types.eliza.d.ts +636 -0
  315. package/packages/agent/src/config/types.eliza.d.ts.map +1 -0
  316. package/packages/agent/src/config/types.eliza.js +1 -0
  317. package/packages/agent/src/config/types.gateway.d.ts +216 -0
  318. package/packages/agent/src/config/types.gateway.d.ts.map +1 -0
  319. package/packages/agent/src/config/types.gateway.js +1 -0
  320. package/packages/agent/src/config/types.hooks.d.ts +107 -0
  321. package/packages/agent/src/config/types.hooks.d.ts.map +1 -0
  322. package/packages/agent/src/config/types.hooks.js +1 -0
  323. package/packages/agent/src/config/types.js +7 -0
  324. package/packages/agent/src/config/types.messages.d.ts +176 -0
  325. package/packages/agent/src/config/types.messages.d.ts.map +1 -0
  326. package/packages/agent/src/config/types.messages.js +1 -0
  327. package/packages/agent/src/config/types.tools.d.ts +400 -0
  328. package/packages/agent/src/config/types.tools.d.ts.map +1 -0
  329. package/packages/agent/src/config/types.tools.js +1 -0
  330. package/packages/agent/src/config/zod-schema.agent-runtime.d.ts +1062 -0
  331. package/packages/agent/src/config/zod-schema.agent-runtime.d.ts.map +1 -0
  332. package/packages/agent/src/config/zod-schema.agent-runtime.js +721 -0
  333. package/packages/agent/src/config/zod-schema.core.d.ts +1021 -0
  334. package/packages/agent/src/config/zod-schema.core.d.ts.map +1 -0
  335. package/packages/agent/src/config/zod-schema.core.js +694 -0
  336. package/packages/agent/src/config/zod-schema.d.ts +4817 -0
  337. package/packages/agent/src/config/zod-schema.d.ts.map +1 -0
  338. package/packages/agent/src/config/zod-schema.hooks.d.ts +88 -0
  339. package/packages/agent/src/config/zod-schema.hooks.d.ts.map +1 -0
  340. package/packages/agent/src/config/zod-schema.hooks.js +133 -0
  341. package/packages/agent/src/config/zod-schema.js +778 -0
  342. package/packages/agent/src/config/zod-schema.providers-core.d.ts +2976 -0
  343. package/packages/agent/src/config/zod-schema.providers-core.d.ts.map +1 -0
  344. package/packages/agent/src/config/zod-schema.providers-core.js +1006 -0
  345. package/packages/agent/src/config/zod-schema.session.d.ts +183 -0
  346. package/packages/agent/src/config/zod-schema.session.d.ts.map +1 -0
  347. package/packages/agent/src/config/zod-schema.session.js +86 -0
  348. package/packages/agent/src/contracts/apps.d.ts +42 -0
  349. package/packages/agent/src/contracts/apps.d.ts.map +1 -0
  350. package/packages/agent/src/contracts/apps.js +4 -0
  351. package/packages/agent/src/contracts/awareness.d.ts +38 -0
  352. package/packages/agent/src/contracts/awareness.d.ts.map +1 -0
  353. package/packages/agent/src/contracts/awareness.js +7 -0
  354. package/packages/agent/src/contracts/config.d.ts +146 -0
  355. package/packages/agent/src/contracts/config.d.ts.map +1 -0
  356. package/packages/agent/src/contracts/config.js +4 -0
  357. package/packages/agent/src/contracts/drop.d.ts +20 -0
  358. package/packages/agent/src/contracts/drop.d.ts.map +1 -0
  359. package/packages/agent/src/contracts/drop.js +4 -0
  360. package/packages/agent/src/contracts/index.d.ts +9 -0
  361. package/packages/agent/src/contracts/index.d.ts.map +1 -0
  362. package/packages/agent/src/contracts/index.js +8 -0
  363. package/packages/agent/src/contracts/onboarding.d.ts +379 -0
  364. package/packages/agent/src/contracts/onboarding.d.ts.map +1 -0
  365. package/packages/agent/src/contracts/onboarding.js +290 -0
  366. package/packages/agent/src/contracts/permissions.d.ts +35 -0
  367. package/packages/agent/src/contracts/permissions.d.ts.map +1 -0
  368. package/packages/agent/src/contracts/permissions.js +4 -0
  369. package/packages/agent/src/contracts/verification.d.ts +9 -0
  370. package/packages/agent/src/contracts/verification.d.ts.map +1 -0
  371. package/packages/agent/src/contracts/verification.js +4 -0
  372. package/packages/agent/src/contracts/wallet.d.ts +409 -0
  373. package/packages/agent/src/contracts/wallet.d.ts.map +1 -0
  374. package/packages/agent/src/contracts/wallet.js +60 -0
  375. package/packages/agent/src/diagnostics/integration-observability.d.ts +40 -0
  376. package/packages/agent/src/diagnostics/integration-observability.d.ts.map +1 -0
  377. package/packages/agent/src/diagnostics/integration-observability.js +68 -0
  378. package/packages/agent/src/emotes/catalog.d.ts +31 -0
  379. package/packages/agent/src/emotes/catalog.d.ts.map +1 -0
  380. package/packages/agent/src/emotes/catalog.js +618 -0
  381. package/packages/agent/src/hooks/discovery.d.ts +13 -0
  382. package/packages/agent/src/hooks/discovery.d.ts.map +1 -0
  383. package/packages/agent/src/hooks/discovery.js +184 -0
  384. package/packages/agent/src/hooks/eligibility.d.ts +12 -0
  385. package/packages/agent/src/hooks/eligibility.d.ts.map +1 -0
  386. package/packages/agent/src/hooks/eligibility.js +100 -0
  387. package/packages/agent/src/hooks/index.d.ts +3 -0
  388. package/packages/agent/src/hooks/index.d.ts.map +1 -0
  389. package/packages/agent/src/hooks/index.js +2 -0
  390. package/packages/agent/src/hooks/loader.d.ts +34 -0
  391. package/packages/agent/src/hooks/loader.d.ts.map +1 -0
  392. package/packages/agent/src/hooks/loader.js +176 -0
  393. package/packages/agent/src/hooks/registry.d.ts +11 -0
  394. package/packages/agent/src/hooks/registry.d.ts.map +1 -0
  395. package/packages/agent/src/hooks/registry.js +58 -0
  396. package/packages/agent/src/hooks/types.d.ts +104 -0
  397. package/packages/agent/src/hooks/types.d.ts.map +1 -0
  398. package/packages/agent/src/hooks/types.js +8 -0
  399. package/packages/agent/src/index.d.ts +20 -0
  400. package/packages/agent/src/index.d.ts.map +1 -0
  401. package/packages/agent/src/index.js +19 -0
  402. package/packages/agent/src/onboarding-presets.d.ts +78 -0
  403. package/packages/agent/src/onboarding-presets.d.ts.map +1 -0
  404. package/packages/agent/src/onboarding-presets.js +1352 -0
  405. package/packages/agent/src/plugins/custom-rtmp/index.d.ts +12 -0
  406. package/packages/agent/src/plugins/custom-rtmp/index.d.ts.map +1 -0
  407. package/packages/agent/src/plugins/custom-rtmp/index.js +26 -0
  408. package/packages/agent/src/providers/admin-trust.d.ts +4 -0
  409. package/packages/agent/src/providers/admin-trust.d.ts.map +1 -0
  410. package/packages/agent/src/providers/admin-trust.js +53 -0
  411. package/packages/agent/src/providers/session-bridge.d.ts +24 -0
  412. package/packages/agent/src/providers/session-bridge.d.ts.map +1 -0
  413. package/packages/agent/src/providers/session-bridge.js +85 -0
  414. package/packages/agent/src/providers/session-utils.d.ts +20 -0
  415. package/packages/agent/src/providers/session-utils.d.ts.map +1 -0
  416. package/packages/agent/src/providers/session-utils.js +33 -0
  417. package/packages/agent/src/providers/simple-mode.d.ts +4 -0
  418. package/packages/agent/src/providers/simple-mode.d.ts.map +1 -0
  419. package/packages/agent/src/providers/simple-mode.js +85 -0
  420. package/packages/agent/src/providers/ui-catalog.d.ts +3 -0
  421. package/packages/agent/src/providers/ui-catalog.d.ts.map +1 -0
  422. package/packages/agent/src/providers/ui-catalog.js +123 -0
  423. package/packages/agent/src/providers/workspace-provider.d.ts +22 -0
  424. package/packages/agent/src/providers/workspace-provider.d.ts.map +1 -0
  425. package/packages/agent/src/providers/workspace-provider.js +167 -0
  426. package/packages/agent/src/providers/workspace.d.ts +54 -0
  427. package/packages/agent/src/providers/workspace.d.ts.map +1 -0
  428. package/packages/agent/src/providers/workspace.js +405 -0
  429. package/packages/agent/src/runtime/agent-event-service.d.ts +35 -0
  430. package/packages/agent/src/runtime/agent-event-service.d.ts.map +1 -0
  431. package/packages/agent/src/runtime/agent-event-service.js +16 -0
  432. package/packages/agent/src/runtime/cloud-onboarding.d.ts +55 -0
  433. package/packages/agent/src/runtime/cloud-onboarding.d.ts.map +1 -0
  434. package/packages/agent/src/runtime/cloud-onboarding.js +279 -0
  435. package/packages/agent/src/runtime/core-plugins.d.ts +14 -0
  436. package/packages/agent/src/runtime/core-plugins.d.ts.map +1 -0
  437. package/packages/agent/src/runtime/core-plugins.js +51 -0
  438. package/packages/agent/src/runtime/custom-actions.d.ts +40 -0
  439. package/packages/agent/src/runtime/custom-actions.d.ts.map +1 -0
  440. package/packages/agent/src/runtime/custom-actions.js +454 -0
  441. package/packages/agent/src/runtime/eliza-plugin.d.ts +16 -0
  442. package/packages/agent/src/runtime/eliza-plugin.d.ts.map +1 -0
  443. package/packages/agent/src/runtime/eliza-plugin.js +108 -0
  444. package/packages/agent/src/runtime/eliza.d.ts +205 -0
  445. package/packages/agent/src/runtime/eliza.d.ts.map +1 -0
  446. package/packages/agent/src/runtime/eliza.js +3935 -0
  447. package/packages/agent/src/runtime/embedding-presets.d.ts +19 -0
  448. package/packages/agent/src/runtime/embedding-presets.d.ts.map +1 -0
  449. package/packages/agent/src/runtime/embedding-presets.js +53 -0
  450. package/packages/agent/src/runtime/index.d.ts +9 -0
  451. package/packages/agent/src/runtime/index.d.ts.map +1 -0
  452. package/packages/agent/src/runtime/index.js +8 -0
  453. package/packages/agent/src/runtime/onboarding-names.d.ts +11 -0
  454. package/packages/agent/src/runtime/onboarding-names.d.ts.map +1 -0
  455. package/packages/agent/src/runtime/onboarding-names.js +74 -0
  456. package/packages/agent/src/runtime/release-plugin-policy.d.ts +20 -0
  457. package/packages/agent/src/runtime/release-plugin-policy.d.ts.map +1 -0
  458. package/packages/agent/src/runtime/release-plugin-policy.js +87 -0
  459. package/packages/agent/src/runtime/restart.d.ts +45 -0
  460. package/packages/agent/src/runtime/restart.d.ts.map +1 -0
  461. package/packages/agent/src/runtime/restart.js +45 -0
  462. package/packages/agent/src/runtime/trajectory-persistence.d.ts +214 -0
  463. package/packages/agent/src/runtime/trajectory-persistence.d.ts.map +1 -0
  464. package/packages/agent/src/runtime/trajectory-persistence.js +1957 -0
  465. package/packages/agent/src/runtime/version.d.ts +2 -0
  466. package/packages/agent/src/runtime/version.d.ts.map +1 -0
  467. package/packages/agent/src/runtime/version.js +5 -0
  468. package/packages/agent/src/security/audit-log.d.ts +49 -0
  469. package/packages/agent/src/security/audit-log.d.ts.map +1 -0
  470. package/packages/agent/src/security/audit-log.js +161 -0
  471. package/packages/agent/src/security/network-policy.d.ts +6 -0
  472. package/packages/agent/src/security/network-policy.d.ts.map +1 -0
  473. package/packages/agent/src/security/network-policy.js +85 -0
  474. package/packages/agent/src/server/index.d.ts +3 -0
  475. package/packages/agent/src/server/index.d.ts.map +1 -0
  476. package/packages/agent/src/server/index.js +1 -0
  477. package/packages/agent/src/services/agent-export.d.ts +100 -0
  478. package/packages/agent/src/services/agent-export.d.ts.map +1 -0
  479. package/packages/agent/src/services/agent-export.js +729 -0
  480. package/packages/agent/src/services/app-manager.d.ts +34 -0
  481. package/packages/agent/src/services/app-manager.d.ts.map +1 -0
  482. package/packages/agent/src/services/app-manager.js +425 -0
  483. package/packages/agent/src/services/browser-capture.d.ts +39 -0
  484. package/packages/agent/src/services/browser-capture.d.ts.map +1 -0
  485. package/packages/agent/src/services/browser-capture.js +162 -0
  486. package/packages/agent/src/services/coding-agent-context.d.ts +310 -0
  487. package/packages/agent/src/services/coding-agent-context.d.ts.map +1 -0
  488. package/packages/agent/src/services/coding-agent-context.js +281 -0
  489. package/packages/agent/src/services/fallback-training-service.d.ts +78 -0
  490. package/packages/agent/src/services/fallback-training-service.d.ts.map +1 -0
  491. package/packages/agent/src/services/fallback-training-service.js +126 -0
  492. package/packages/agent/src/services/index.d.ts +18 -0
  493. package/packages/agent/src/services/index.d.ts.map +1 -0
  494. package/packages/agent/src/services/index.js +17 -0
  495. package/packages/agent/src/services/mcp-marketplace.d.ts +89 -0
  496. package/packages/agent/src/services/mcp-marketplace.d.ts.map +1 -0
  497. package/packages/agent/src/services/mcp-marketplace.js +200 -0
  498. package/packages/agent/src/services/plugin-manager-types.d.ts +139 -0
  499. package/packages/agent/src/services/plugin-manager-types.d.ts.map +1 -0
  500. package/packages/agent/src/services/plugin-manager-types.js +18 -0
  501. package/packages/agent/src/services/privy-wallets.d.ts +18 -0
  502. package/packages/agent/src/services/privy-wallets.d.ts.map +1 -0
  503. package/packages/agent/src/services/privy-wallets.js +225 -0
  504. package/packages/agent/src/services/registry-client-app-meta.d.ts +6 -0
  505. package/packages/agent/src/services/registry-client-app-meta.d.ts.map +1 -0
  506. package/packages/agent/src/services/registry-client-app-meta.js +147 -0
  507. package/packages/agent/src/services/registry-client-endpoints.d.ts +7 -0
  508. package/packages/agent/src/services/registry-client-endpoints.d.ts.map +1 -0
  509. package/packages/agent/src/services/registry-client-endpoints.js +183 -0
  510. package/packages/agent/src/services/registry-client-local.d.ts +4 -0
  511. package/packages/agent/src/services/registry-client-local.d.ts.map +1 -0
  512. package/packages/agent/src/services/registry-client-local.js +377 -0
  513. package/packages/agent/src/services/registry-client-network.d.ts +9 -0
  514. package/packages/agent/src/services/registry-client-network.d.ts.map +1 -0
  515. package/packages/agent/src/services/registry-client-network.js +109 -0
  516. package/packages/agent/src/services/registry-client-queries.d.ts +15 -0
  517. package/packages/agent/src/services/registry-client-queries.d.ts.map +1 -0
  518. package/packages/agent/src/services/registry-client-queries.js +150 -0
  519. package/packages/agent/src/services/registry-client-types.d.ts +115 -0
  520. package/packages/agent/src/services/registry-client-types.d.ts.map +1 -0
  521. package/packages/agent/src/services/registry-client-types.js +1 -0
  522. package/packages/agent/src/services/registry-client.d.ts +39 -0
  523. package/packages/agent/src/services/registry-client.d.ts.map +1 -0
  524. package/packages/agent/src/services/registry-client.js +249 -0
  525. package/packages/agent/src/services/remote-signing-service.d.ts +58 -0
  526. package/packages/agent/src/services/remote-signing-service.d.ts.map +1 -0
  527. package/packages/agent/src/services/remote-signing-service.js +185 -0
  528. package/packages/agent/src/services/sandbox-engine.d.ts +96 -0
  529. package/packages/agent/src/services/sandbox-engine.d.ts.map +1 -0
  530. package/packages/agent/src/services/sandbox-engine.js +604 -0
  531. package/packages/agent/src/services/sandbox-manager.d.ts +104 -0
  532. package/packages/agent/src/services/sandbox-manager.d.ts.map +1 -0
  533. package/packages/agent/src/services/sandbox-manager.js +353 -0
  534. package/packages/agent/src/services/self-updater.d.ts +21 -0
  535. package/packages/agent/src/services/self-updater.d.ts.map +1 -0
  536. package/packages/agent/src/services/self-updater.js +162 -0
  537. package/packages/agent/src/services/signal-pairing.d.ts +37 -0
  538. package/packages/agent/src/services/signal-pairing.d.ts.map +1 -0
  539. package/packages/agent/src/services/signal-pairing.js +124 -0
  540. package/packages/agent/src/services/signing-policy.d.ts +44 -0
  541. package/packages/agent/src/services/signing-policy.d.ts.map +1 -0
  542. package/packages/agent/src/services/signing-policy.js +165 -0
  543. package/packages/agent/src/services/skill-catalog-client.d.ts +47 -0
  544. package/packages/agent/src/services/skill-catalog-client.d.ts.map +1 -0
  545. package/packages/agent/src/services/skill-catalog-client.js +130 -0
  546. package/packages/agent/src/services/skill-marketplace.d.ts +42 -0
  547. package/packages/agent/src/services/skill-marketplace.d.ts.map +1 -0
  548. package/packages/agent/src/services/skill-marketplace.js +680 -0
  549. package/packages/agent/src/services/stream-manager.d.ts +121 -0
  550. package/packages/agent/src/services/stream-manager.d.ts.map +1 -0
  551. package/packages/agent/src/services/stream-manager.js +604 -0
  552. package/packages/agent/src/services/tts-stream-bridge.d.ts +83 -0
  553. package/packages/agent/src/services/tts-stream-bridge.d.ts.map +1 -0
  554. package/packages/agent/src/services/tts-stream-bridge.js +349 -0
  555. package/packages/agent/src/services/update-checker.d.ts +29 -0
  556. package/packages/agent/src/services/update-checker.d.ts.map +1 -0
  557. package/packages/agent/src/services/update-checker.js +134 -0
  558. package/packages/agent/src/services/version-compat.d.ts +99 -0
  559. package/packages/agent/src/services/version-compat.d.ts.map +1 -0
  560. package/packages/agent/src/services/version-compat.js +195 -0
  561. package/packages/agent/src/services/whatsapp-pairing.d.ts +41 -0
  562. package/packages/agent/src/services/whatsapp-pairing.d.ts.map +1 -0
  563. package/packages/agent/src/services/whatsapp-pairing.js +209 -0
  564. package/packages/agent/src/shared/ui-catalog-prompt.d.ts +52 -0
  565. package/packages/agent/src/shared/ui-catalog-prompt.d.ts.map +1 -0
  566. package/packages/agent/src/shared/ui-catalog-prompt.js +1028 -0
  567. package/packages/agent/src/test-support/process-helpers.d.ts +13 -0
  568. package/packages/agent/src/test-support/process-helpers.d.ts.map +1 -0
  569. package/packages/agent/src/test-support/process-helpers.js +23 -0
  570. package/packages/agent/src/test-support/route-test-helpers.d.ts +37 -0
  571. package/packages/agent/src/test-support/route-test-helpers.d.ts.map +1 -0
  572. package/packages/agent/src/test-support/route-test-helpers.js +54 -0
  573. package/packages/agent/src/test-support/test-helpers.d.ts +77 -0
  574. package/packages/agent/src/test-support/test-helpers.d.ts.map +1 -0
  575. package/packages/agent/src/test-support/test-helpers.js +210 -0
  576. package/packages/agent/src/testing/index.d.ts +4 -0
  577. package/packages/agent/src/testing/index.d.ts.map +1 -0
  578. package/packages/agent/src/testing/index.js +3 -0
  579. package/packages/agent/src/triggers/action.d.ts +3 -0
  580. package/packages/agent/src/triggers/action.d.ts.map +1 -0
  581. package/packages/agent/src/triggers/action.js +267 -0
  582. package/packages/agent/src/triggers/runtime.d.ts +24 -0
  583. package/packages/agent/src/triggers/runtime.d.ts.map +1 -0
  584. package/packages/agent/src/triggers/runtime.js +322 -0
  585. package/packages/agent/src/triggers/scheduling.d.ts +70 -0
  586. package/packages/agent/src/triggers/scheduling.d.ts.map +1 -0
  587. package/packages/agent/src/triggers/scheduling.js +355 -0
  588. package/packages/agent/src/triggers/types.d.ts +115 -0
  589. package/packages/agent/src/triggers/types.d.ts.map +1 -0
  590. package/packages/agent/src/triggers/types.js +1 -0
  591. package/packages/agent/src/utils/exec-safety.d.ts +2 -0
  592. package/packages/agent/src/utils/exec-safety.d.ts.map +1 -0
  593. package/packages/agent/src/utils/exec-safety.js +21 -0
  594. package/packages/agent/src/utils/number-parsing.d.ts +26 -0
  595. package/packages/agent/src/utils/number-parsing.d.ts.map +1 -0
  596. package/packages/agent/src/utils/number-parsing.js +52 -0
  597. package/packages/agent/src/utils/spoken-text.d.ts +2 -0
  598. package/packages/agent/src/utils/spoken-text.d.ts.map +1 -0
  599. package/packages/agent/src/utils/spoken-text.js +56 -0
  600. package/packages/agent/src/version-resolver.d.ts +3 -0
  601. package/packages/agent/src/version-resolver.d.ts.map +1 -0
  602. package/packages/agent/src/version-resolver.js +51 -0
  603. package/jest.config.js +0 -17
  604. package/src/__tests__/client-type-identification.test.ts +0 -59
  605. package/src/defaultCharacter.ts +0 -530
  606. package/src/index.ts +0 -865
  607. package/tsconfig.json +0 -16
@@ -0,0 +1,1334 @@
1
+ /** Sandbox capability API routes: status, exec, browser, screen, audio, computer use. */
2
+ import { execFileSync, execSync } from "node:child_process";
3
+ import { readFileSync, unlinkSync, writeFileSync } from "node:fs";
4
+ import { platform, tmpdir } from "node:os";
5
+ import { join } from "node:path";
6
+ import { readJsonBody as parseJsonBody, readRequestBody, sendJson as sendJsonResponse, } from "./http-helpers";
7
+ const MAX_COMPUTER_INPUT_LENGTH = 4096;
8
+ const MAX_KEYPRESS_LENGTH = 128;
9
+ const SAFE_KEYPRESS_PATTERN = /^[A-Za-z0-9+_.,: -]+$/;
10
+ const ALLOWED_AUDIO_FORMATS = new Set(["wav", "mp3", "ogg", "flac", "m4a"]);
11
+ const MIN_AUDIO_RECORD_DURATION_MS = 250;
12
+ const MAX_AUDIO_RECORD_DURATION_MS = 30_000;
13
+ // ── Route handler ────────────────────────────────────────────────────────────
14
+ /** Returns `true` if handled, `false` to fall through. */
15
+ export async function handleSandboxRoute(req, res, pathname, method, state) {
16
+ if (!pathname.startsWith("/api/sandbox")) {
17
+ return false;
18
+ }
19
+ const mgr = state.sandboxManager;
20
+ // Platform info doesn't require a running manager
21
+ if (method === "GET" && pathname === "/api/sandbox/platform") {
22
+ sendJson(res, 200, getPlatformInfo());
23
+ return true;
24
+ }
25
+ // ── POST /api/sandbox/docker/start ────────────────────────────────
26
+ // Attempt to start Docker Desktop (works on macOS/Windows desktop builds)
27
+ if (method === "POST" && pathname === "/api/sandbox/docker/start") {
28
+ try {
29
+ const result = attemptDockerStart();
30
+ sendJson(res, 200, result);
31
+ }
32
+ catch (err) {
33
+ sendJson(res, 500, {
34
+ success: false,
35
+ error: `Failed to start Docker: ${err instanceof Error ? err.message : String(err)}`,
36
+ });
37
+ }
38
+ return true;
39
+ }
40
+ if (!mgr) {
41
+ sendJson(res, 503, {
42
+ error: "Sandbox manager not initialized",
43
+ });
44
+ return true;
45
+ }
46
+ // ── GET /api/sandbox/status ─────────────────────────────────────────
47
+ if (method === "GET" && pathname === "/api/sandbox/status") {
48
+ sendJson(res, 200, mgr.getStatus());
49
+ return true;
50
+ }
51
+ // ── GET /api/sandbox/events ─────────────────────────────────────────
52
+ if (method === "GET" && pathname === "/api/sandbox/events") {
53
+ const events = mgr.getEventLog();
54
+ sendJson(res, 200, { events: events.slice(-100) });
55
+ return true;
56
+ }
57
+ // ── POST /api/sandbox/start ─────────────────────────────────────────
58
+ if (method === "POST" && pathname === "/api/sandbox/start") {
59
+ try {
60
+ await mgr.start();
61
+ sendJson(res, 200, mgr.getStatus());
62
+ }
63
+ catch (err) {
64
+ sendJson(res, 500, {
65
+ error: `Failed to start sandbox: ${err instanceof Error ? err.message : String(err)}`,
66
+ });
67
+ }
68
+ return true;
69
+ }
70
+ // ── POST /api/sandbox/stop ──────────────────────────────────────────
71
+ if (method === "POST" && pathname === "/api/sandbox/stop") {
72
+ try {
73
+ await mgr.stop();
74
+ sendJson(res, 200, mgr.getStatus());
75
+ }
76
+ catch (err) {
77
+ sendJson(res, 500, {
78
+ error: `Failed to stop sandbox: ${err instanceof Error ? err.message : String(err)}`,
79
+ });
80
+ }
81
+ return true;
82
+ }
83
+ // ── POST /api/sandbox/recover ───────────────────────────────────────
84
+ if (method === "POST" && pathname === "/api/sandbox/recover") {
85
+ try {
86
+ await mgr.recover();
87
+ sendJson(res, 200, mgr.getStatus());
88
+ }
89
+ catch (err) {
90
+ sendJson(res, 500, {
91
+ error: `Recovery failed: ${err instanceof Error ? err.message : String(err)}`,
92
+ });
93
+ }
94
+ return true;
95
+ }
96
+ // ── POST /api/sandbox/exec ──────────────────────────────────────────
97
+ if (method === "POST" && pathname === "/api/sandbox/exec") {
98
+ const parsed = await readJsonBody(req, res);
99
+ if (!parsed)
100
+ return true;
101
+ if (!parsed.command || typeof parsed.command !== "string") {
102
+ sendJson(res, 400, { error: "Missing 'command' field" });
103
+ return true;
104
+ }
105
+ const result = await mgr.exec({
106
+ command: parsed.command,
107
+ workdir: parsed.workdir,
108
+ timeoutMs: parsed.timeoutMs,
109
+ });
110
+ sendJson(res, result.exitCode === 0 ? 200 : 422, result);
111
+ return true;
112
+ }
113
+ // ── GET /api/sandbox/browser ────────────────────────────────────────
114
+ if (method === "GET" && pathname === "/api/sandbox/browser") {
115
+ sendJson(res, 200, {
116
+ cdpEndpoint: mgr.getBrowserCdpEndpoint(),
117
+ wsEndpoint: mgr.getBrowserWsEndpoint(),
118
+ noVncEndpoint: mgr.getBrowserNoVncEndpoint(),
119
+ });
120
+ return true;
121
+ }
122
+ // ── Capability bridges ──────────────────────────────────────────────
123
+ if (method === "GET" && pathname === "/api/sandbox/screen/screenshot") {
124
+ try {
125
+ const screenshot = captureScreenshot();
126
+ res.writeHead(200, {
127
+ "Content-Type": "image/png",
128
+ "Content-Length": screenshot.length,
129
+ });
130
+ res.end(screenshot);
131
+ }
132
+ catch (err) {
133
+ sendJson(res, 500, {
134
+ error: `Screenshot failed: ${err instanceof Error ? err.message : String(err)}`,
135
+ });
136
+ }
137
+ return true;
138
+ }
139
+ // ── POST /api/sandbox/screen/screenshot ─────────────────────────────
140
+ // Returns base64-encoded screenshot for easy consumption by agents
141
+ if (method === "POST" && pathname === "/api/sandbox/screen/screenshot") {
142
+ const rawBody = await readBody(req);
143
+ if (!rawBody || !rawBody.trim()) {
144
+ sendJson(res, 200, {
145
+ format: "png",
146
+ encoding: "base64",
147
+ width: null,
148
+ height: null,
149
+ data: captureScreenshot().toString("base64"),
150
+ });
151
+ return true;
152
+ }
153
+ let regionInput;
154
+ try {
155
+ regionInput = JSON.parse(rawBody);
156
+ }
157
+ catch {
158
+ sendJson(res, 400, { error: "Invalid JSON body" });
159
+ return true;
160
+ }
161
+ const region = resolveScreenshotRegion(regionInput);
162
+ if (region.error) {
163
+ sendJson(res, 400, { error: region.error });
164
+ return true;
165
+ }
166
+ try {
167
+ const screenshot = captureScreenshot(region.region);
168
+ const base64 = screenshot.toString("base64");
169
+ sendJson(res, 200, {
170
+ format: "png",
171
+ encoding: "base64",
172
+ width: null, // platform-dependent
173
+ height: null,
174
+ data: base64,
175
+ });
176
+ }
177
+ catch (err) {
178
+ sendJson(res, 500, {
179
+ error: `Screenshot failed: ${err instanceof Error ? err.message : String(err)}`,
180
+ });
181
+ }
182
+ return true;
183
+ }
184
+ // ── GET /api/sandbox/screen/windows ─────────────────────────────────
185
+ if (method === "GET" && pathname === "/api/sandbox/screen/windows") {
186
+ try {
187
+ const windows = listWindows();
188
+ sendJson(res, 200, { windows });
189
+ }
190
+ catch (err) {
191
+ sendJson(res, 200, { windows: [], error: String(err) });
192
+ }
193
+ return true;
194
+ }
195
+ // ── POST /api/sandbox/audio/record ──────────────────────────────────
196
+ if (method === "POST" && pathname === "/api/sandbox/audio/record") {
197
+ const body = await readBody(req);
198
+ let durationMs = 5000;
199
+ if (body) {
200
+ let parsed;
201
+ try {
202
+ parsed = JSON.parse(body);
203
+ }
204
+ catch {
205
+ sendJson(res, 400, {
206
+ error: "Invalid JSON in request body",
207
+ });
208
+ return true;
209
+ }
210
+ if (parsed === null ||
211
+ typeof parsed !== "object" ||
212
+ Array.isArray(parsed)) {
213
+ sendJson(res, 400, { error: "Request body must be a JSON object" });
214
+ return true;
215
+ }
216
+ const bodyValues = parsed;
217
+ if (Object.hasOwn(bodyValues, "durationMs")) {
218
+ const durationValue = bodyValues.durationMs;
219
+ if (typeof durationValue !== "number") {
220
+ sendJson(res, 400, {
221
+ error: "durationMs must be a finite number",
222
+ });
223
+ return true;
224
+ }
225
+ // Defense in depth: JSON.parse only produces finite numbers, but this guard
226
+ // keeps behavior explicit against future parser/runtime changes.
227
+ if (!Number.isFinite(durationValue)) {
228
+ sendJson(res, 400, {
229
+ error: "durationMs must be a finite number",
230
+ });
231
+ return true;
232
+ }
233
+ if (!Number.isInteger(durationValue)) {
234
+ sendJson(res, 400, {
235
+ error: "durationMs must be an integer number of milliseconds",
236
+ });
237
+ return true;
238
+ }
239
+ if (durationValue < MIN_AUDIO_RECORD_DURATION_MS ||
240
+ durationValue > MAX_AUDIO_RECORD_DURATION_MS) {
241
+ sendJson(res, 400, {
242
+ error: `durationMs must be between ${MIN_AUDIO_RECORD_DURATION_MS} and ${MAX_AUDIO_RECORD_DURATION_MS} milliseconds`,
243
+ });
244
+ return true;
245
+ }
246
+ durationMs = durationValue;
247
+ }
248
+ }
249
+ try {
250
+ const audio = await recordAudio(durationMs);
251
+ sendJson(res, 200, {
252
+ format: "wav",
253
+ encoding: "base64",
254
+ durationMs,
255
+ data: audio.toString("base64"),
256
+ });
257
+ }
258
+ catch (err) {
259
+ sendJson(res, 500, {
260
+ error: `Audio recording failed: ${err instanceof Error ? err.message : String(err)}`,
261
+ });
262
+ }
263
+ return true;
264
+ }
265
+ // ── POST /api/sandbox/audio/play ────────────────────────────────────
266
+ if (method === "POST" && pathname === "/api/sandbox/audio/play") {
267
+ const parsed = await readJsonBody(req, res);
268
+ if (!parsed)
269
+ return true;
270
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
271
+ sendJson(res, 400, { error: "Body must be a JSON object" });
272
+ return true;
273
+ }
274
+ const payload = parsed;
275
+ if (typeof payload.data !== "string" || !payload.data.trim()) {
276
+ sendJson(res, 400, { error: "Missing 'data' field (base64 audio)" });
277
+ return true;
278
+ }
279
+ const formatResult = resolveAudioFormat(payload.format);
280
+ if (formatResult.error) {
281
+ sendJson(res, 400, { error: formatResult.error });
282
+ return true;
283
+ }
284
+ try {
285
+ await playAudio(Buffer.from(payload.data, "base64"), formatResult.format);
286
+ sendJson(res, 200, { success: true });
287
+ }
288
+ catch (err) {
289
+ sendJson(res, 500, {
290
+ error: `Audio playback failed: ${err instanceof Error ? err.message : String(err)}`,
291
+ });
292
+ }
293
+ return true;
294
+ }
295
+ // ── POST /api/sandbox/computer/click ────────────────────────────────
296
+ if (method === "POST" && pathname === "/api/sandbox/computer/click") {
297
+ const parsed = await readJsonBody(req, res);
298
+ if (!parsed)
299
+ return true;
300
+ const clickPayload = resolveClickPayload(parsed);
301
+ if (clickPayload.error) {
302
+ sendJson(res, 400, { error: clickPayload.error });
303
+ return true;
304
+ }
305
+ try {
306
+ const { x, y, button } = clickPayload;
307
+ performClick(x, y, button);
308
+ sendJson(res, 200, { success: true, x, y, button });
309
+ }
310
+ catch (err) {
311
+ sendJson(res, 500, {
312
+ error: `Click failed: ${err instanceof Error ? err.message : String(err)}`,
313
+ });
314
+ }
315
+ return true;
316
+ }
317
+ // ── POST /api/sandbox/computer/type ─────────────────────────────────
318
+ if (method === "POST" && pathname === "/api/sandbox/computer/type") {
319
+ const parsed = await readJsonBody(req, res);
320
+ if (!parsed)
321
+ return true;
322
+ const typePayload = resolveTypePayload(parsed);
323
+ if (typePayload.error) {
324
+ sendJson(res, 400, { error: typePayload.error });
325
+ return true;
326
+ }
327
+ try {
328
+ const { text } = typePayload;
329
+ performType(text);
330
+ sendJson(res, 200, { success: true, length: text.length });
331
+ }
332
+ catch (err) {
333
+ sendJson(res, 500, {
334
+ error: `Type failed: ${err instanceof Error ? err.message : String(err)}`,
335
+ });
336
+ }
337
+ return true;
338
+ }
339
+ // ── POST /api/sandbox/computer/keypress ─────────────────────────────
340
+ if (method === "POST" && pathname === "/api/sandbox/computer/keypress") {
341
+ const parsed = await readJsonBody(req, res);
342
+ if (!parsed)
343
+ return true;
344
+ const keypressPayload = resolveKeypressPayload(parsed);
345
+ if (keypressPayload.error) {
346
+ sendJson(res, 400, { error: keypressPayload.error });
347
+ return true;
348
+ }
349
+ try {
350
+ const { keys } = keypressPayload;
351
+ performKeypress(keys);
352
+ sendJson(res, 200, { success: true, keys });
353
+ }
354
+ catch (err) {
355
+ sendJson(res, 500, {
356
+ error: `Keypress failed: ${err instanceof Error ? err.message : String(err)}`,
357
+ });
358
+ }
359
+ return true;
360
+ }
361
+ // ── Signing routes ─────────────────────────────────────────────────
362
+ if (method === "POST" && pathname === "/api/sandbox/sign") {
363
+ const signer = state.signingService;
364
+ if (!signer) {
365
+ sendJson(res, 503, { error: "Signing service not configured" });
366
+ return true;
367
+ }
368
+ const body = await readJsonBody(req, res);
369
+ if (body === null)
370
+ return true;
371
+ const parsed = resolveSigningRequestPayload(body);
372
+ if ("error" in parsed) {
373
+ sendJson(res, 400, { error: parsed.error });
374
+ return true;
375
+ }
376
+ try {
377
+ const result = await signer.submitSigningRequest(parsed.request);
378
+ sendJson(res, result.success ? 200 : 403, result);
379
+ }
380
+ catch (err) {
381
+ sendJson(res, 400, {
382
+ error: `Invalid request: ${err instanceof Error ? err.message : String(err)}`,
383
+ });
384
+ }
385
+ return true;
386
+ }
387
+ if (method === "POST" && pathname === "/api/sandbox/sign/approve") {
388
+ const signer = state.signingService;
389
+ if (!signer) {
390
+ sendJson(res, 503, { error: "Signing service not configured" });
391
+ return true;
392
+ }
393
+ const body = await readJsonBody(req, res);
394
+ if (!body)
395
+ return true;
396
+ try {
397
+ const { requestId } = body;
398
+ const result = await signer.approveRequest(requestId);
399
+ sendJson(res, result.success ? 200 : 403, result);
400
+ }
401
+ catch (err) {
402
+ sendJson(res, 400, { error: String(err) });
403
+ }
404
+ return true;
405
+ }
406
+ if (method === "POST" && pathname === "/api/sandbox/sign/reject") {
407
+ const signer = state.signingService;
408
+ if (!signer) {
409
+ sendJson(res, 503, { error: "Signing service not configured" });
410
+ return true;
411
+ }
412
+ const body = await readJsonBody(req, res);
413
+ if (!body)
414
+ return true;
415
+ try {
416
+ const { requestId } = body;
417
+ const rejected = signer.rejectRequest(requestId);
418
+ sendJson(res, 200, { rejected });
419
+ }
420
+ catch (err) {
421
+ sendJson(res, 400, { error: String(err) });
422
+ }
423
+ return true;
424
+ }
425
+ if (method === "GET" && pathname === "/api/sandbox/sign/pending") {
426
+ const signer = state.signingService;
427
+ if (!signer) {
428
+ sendJson(res, 503, { error: "Signing service not configured" });
429
+ return true;
430
+ }
431
+ sendJson(res, 200, { pending: signer.getPendingApprovals() });
432
+ return true;
433
+ }
434
+ if (method === "GET" && pathname === "/api/sandbox/sign/address") {
435
+ const signer = state.signingService;
436
+ if (!signer) {
437
+ sendJson(res, 503, { error: "Signing service not configured" });
438
+ return true;
439
+ }
440
+ try {
441
+ const address = await signer.getAddress();
442
+ sendJson(res, 200, { address });
443
+ }
444
+ catch (err) {
445
+ sendJson(res, 500, { error: String(err) });
446
+ }
447
+ return true;
448
+ }
449
+ // ── GET /api/sandbox/capabilities ───────────────────────────────────
450
+ if (method === "GET" && pathname === "/api/sandbox/capabilities") {
451
+ sendJson(res, 200, detectCapabilities());
452
+ return true;
453
+ }
454
+ // ── Fallthrough ─────────────────────────────────────────────────────
455
+ sendJson(res, 404, { error: `Unknown sandbox route: ${method} ${pathname}` });
456
+ return true;
457
+ }
458
+ function asObject(value) {
459
+ if (!value || typeof value !== "object" || Array.isArray(value))
460
+ return null;
461
+ return value;
462
+ }
463
+ function resolveSigningRequestPayload(input) {
464
+ const obj = asObject(input);
465
+ if (!obj) {
466
+ return { error: "Signing payload must be a JSON object" };
467
+ }
468
+ const requestId = obj.requestId;
469
+ const chainId = parseFiniteInteger(obj.chainId);
470
+ const to = obj.to;
471
+ const value = obj.value;
472
+ const data = obj.data;
473
+ const nonce = obj.nonce === undefined ? undefined : parseFiniteInteger(obj.nonce);
474
+ const rawGasLimit = obj.gasLimit;
475
+ const createdAt = parseFiniteInteger(obj.createdAt);
476
+ if (typeof requestId !== "string" || !requestId.trim()) {
477
+ return { error: "Signing payload requires a non-empty string 'requestId'" };
478
+ }
479
+ if (chainId === null || chainId < 0) {
480
+ return { error: "Signing payload requires an integer 'chainId' >= 0" };
481
+ }
482
+ if (typeof to !== "string" || !/^0x[0-9a-fA-F]{40}$/.test(to.trim())) {
483
+ return {
484
+ error: "Signing payload requires a hex 'to' address (e.g., 0x followed by 40 hex characters)",
485
+ };
486
+ }
487
+ if (typeof value !== "string" || !value.trim()) {
488
+ return { error: "Signing payload requires a non-empty string 'value'" };
489
+ }
490
+ if (typeof data !== "string" || !data.trim()) {
491
+ return { error: "Signing payload requires a non-empty string 'data'" };
492
+ }
493
+ if (nonce === null) {
494
+ return { error: "'nonce' must be a non-negative integer when provided" };
495
+ }
496
+ if (createdAt === null) {
497
+ return { error: "Signing payload requires an integer 'createdAt'" };
498
+ }
499
+ if (rawGasLimit !== undefined && typeof rawGasLimit !== "string") {
500
+ return {
501
+ error: "Signing payload 'gasLimit' must be a string when provided",
502
+ };
503
+ }
504
+ const gasLimit = rawGasLimit?.trim();
505
+ if (gasLimit === "") {
506
+ return {
507
+ error: "Signing payload 'gasLimit' cannot be empty when provided",
508
+ };
509
+ }
510
+ return {
511
+ request: {
512
+ requestId: requestId.trim(),
513
+ chainId,
514
+ to: to.trim(),
515
+ value: value.trim(),
516
+ data,
517
+ ...(nonce === undefined ? {} : { nonce }),
518
+ ...(gasLimit === undefined ? {} : { gasLimit }),
519
+ createdAt,
520
+ },
521
+ };
522
+ }
523
+ function parseFiniteInteger(value) {
524
+ if (typeof value !== "number" || !Number.isFinite(value))
525
+ return null;
526
+ if (!Number.isInteger(value))
527
+ return null;
528
+ return value;
529
+ }
530
+ function resolveScreenshotRegion(input) {
531
+ if (input === undefined || input === null)
532
+ return {};
533
+ const obj = asObject(input);
534
+ if (!obj)
535
+ return { error: "Screenshot region payload must be a JSON object" };
536
+ const hasRegionField = "x" in obj || "y" in obj || "width" in obj || "height" in obj;
537
+ if (!hasRegionField)
538
+ return {};
539
+ const x = parseFiniteInteger(obj.x);
540
+ const y = parseFiniteInteger(obj.y);
541
+ const width = parseFiniteInteger(obj.width);
542
+ const height = parseFiniteInteger(obj.height);
543
+ if (x === null || y === null || width === null || height === null) {
544
+ return {
545
+ error: "Region requires integer x, y, width, and height values",
546
+ };
547
+ }
548
+ if (width <= 0 || height <= 0) {
549
+ return { error: "Region width and height must be greater than 0" };
550
+ }
551
+ return {
552
+ region: { x, y, width, height },
553
+ };
554
+ }
555
+ function resolveClickPayload(input) {
556
+ const obj = asObject(input);
557
+ if (!obj) {
558
+ return {
559
+ x: 0,
560
+ y: 0,
561
+ button: "left",
562
+ error: "Click payload must be a JSON object",
563
+ };
564
+ }
565
+ const x = parseFiniteInteger(obj.x);
566
+ const y = parseFiniteInteger(obj.y);
567
+ if (x === null || y === null) {
568
+ return {
569
+ x: 0,
570
+ y: 0,
571
+ button: "left",
572
+ error: "Click payload requires integer x and y coordinates",
573
+ };
574
+ }
575
+ const rawButton = obj.button;
576
+ let button = "left";
577
+ if (rawButton !== undefined) {
578
+ if (rawButton !== "left" && rawButton !== "right") {
579
+ return {
580
+ x,
581
+ y,
582
+ button,
583
+ error: "button must be either 'left' or 'right'",
584
+ };
585
+ }
586
+ button = rawButton;
587
+ }
588
+ return { x, y, button };
589
+ }
590
+ function resolveTypePayload(input) {
591
+ const obj = asObject(input);
592
+ if (!obj)
593
+ return { text: "", error: "Type payload must be a JSON object" };
594
+ if (typeof obj.text !== "string") {
595
+ return { text: "", error: "Type payload requires a string 'text' field" };
596
+ }
597
+ if (obj.text.length === 0) {
598
+ return { text: "", error: "text cannot be empty" };
599
+ }
600
+ if (obj.text.length > MAX_COMPUTER_INPUT_LENGTH) {
601
+ return {
602
+ text: "",
603
+ error: `text exceeds maximum length (${MAX_COMPUTER_INPUT_LENGTH})`,
604
+ };
605
+ }
606
+ return { text: obj.text };
607
+ }
608
+ function resolveKeypressPayload(input) {
609
+ const obj = asObject(input);
610
+ if (!obj) {
611
+ return { keys: "", error: "Keypress payload must be a JSON object" };
612
+ }
613
+ if (typeof obj.keys !== "string") {
614
+ return {
615
+ keys: "",
616
+ error: "Keypress payload requires a string 'keys' field",
617
+ };
618
+ }
619
+ const keys = obj.keys.trim();
620
+ if (!keys)
621
+ return { keys: "", error: "keys cannot be empty" };
622
+ if (keys.length > MAX_KEYPRESS_LENGTH) {
623
+ return {
624
+ keys: "",
625
+ error: `keys exceeds maximum length (${MAX_KEYPRESS_LENGTH})`,
626
+ };
627
+ }
628
+ if (!SAFE_KEYPRESS_PATTERN.test(keys)) {
629
+ return {
630
+ keys: "",
631
+ error: "keys contains unsupported characters; allowed: letters, numbers, space, +, _, ., ,, :, -",
632
+ };
633
+ }
634
+ return { keys };
635
+ }
636
+ function resolveAudioFormat(input) {
637
+ if (input === undefined || input === null)
638
+ return { format: "wav" };
639
+ if (typeof input !== "string") {
640
+ return { format: "wav", error: "format must be a string" };
641
+ }
642
+ const normalized = input.trim().toLowerCase();
643
+ if (!normalized)
644
+ return { format: "wav" };
645
+ if (!/^[a-z0-9]+$/.test(normalized)) {
646
+ return {
647
+ format: "wav",
648
+ error: "format contains unsupported characters; use one of: wav, mp3, ogg, flac, m4a",
649
+ };
650
+ }
651
+ if (!ALLOWED_AUDIO_FORMATS.has(normalized)) {
652
+ return {
653
+ format: "wav",
654
+ error: "format must be one of: wav, mp3, ogg, flac, m4a",
655
+ };
656
+ }
657
+ return { format: normalized };
658
+ }
659
+ function runCommand(command, args, timeout) {
660
+ execFileSync(command, args, {
661
+ timeout,
662
+ stdio: ["ignore", "pipe", "pipe"],
663
+ });
664
+ }
665
+ function captureScreenshot(region) {
666
+ const os = platform();
667
+ const tmpFile = join(tmpdir(), `sandbox-screenshot-${Date.now()}.png`);
668
+ try {
669
+ if (os === "darwin") {
670
+ if (region) {
671
+ runCommand("screencapture", [
672
+ `-R${region.x},${region.y},${region.width},${region.height}`,
673
+ "-x",
674
+ tmpFile,
675
+ ], 10000);
676
+ }
677
+ else {
678
+ runCommand("screencapture", ["-x", tmpFile], 10000);
679
+ }
680
+ }
681
+ else if (os === "linux") {
682
+ // Try tools in preference order
683
+ if (commandExists("import")) {
684
+ if (region) {
685
+ runCommand("import", [
686
+ "-window",
687
+ "root",
688
+ "-crop",
689
+ `${region.width}x${region.height}+${region.x}+${region.y}`,
690
+ tmpFile,
691
+ ], 10000);
692
+ }
693
+ else {
694
+ runCommand("import", ["-window", "root", tmpFile], 10000);
695
+ }
696
+ }
697
+ else if (commandExists("scrot")) {
698
+ runCommand("scrot", [tmpFile], 10000);
699
+ }
700
+ else if (commandExists("gnome-screenshot")) {
701
+ runCommand("gnome-screenshot", ["-f", tmpFile], 10000);
702
+ }
703
+ else {
704
+ throw new Error("No screenshot tool available. Install ImageMagick, scrot, or gnome-screenshot.");
705
+ }
706
+ }
707
+ else if (os === "win32") {
708
+ // PowerShell screenshot
709
+ const psCmd = [
710
+ `Add-Type -AssemblyName System.Windows.Forms`,
711
+ `$screen = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds`,
712
+ `$bitmap = New-Object System.Drawing.Bitmap($screen.Width, $screen.Height)`,
713
+ `$graphics = [System.Drawing.Graphics]::FromImage($bitmap)`,
714
+ `$graphics.CopyFromScreen($screen.Location, [System.Drawing.Point]::Empty, $screen.Size)`,
715
+ `$bitmap.Save('${tmpFile.replace(/\//g, "\\")}')`,
716
+ `$graphics.Dispose()`,
717
+ `$bitmap.Dispose()`,
718
+ ].join("; ");
719
+ execSync(`powershell -Command "${psCmd}"`, {
720
+ timeout: 15000,
721
+ stdio: ["ignore", "pipe", "pipe"],
722
+ });
723
+ }
724
+ else {
725
+ throw new Error(`Screenshot not supported on platform: ${os}`);
726
+ }
727
+ const data = readFileSync(tmpFile);
728
+ try {
729
+ unlinkSync(tmpFile);
730
+ }
731
+ catch {
732
+ /* cleanup best effort */
733
+ }
734
+ return data;
735
+ }
736
+ catch (err) {
737
+ // Clean up temp file on error
738
+ try {
739
+ unlinkSync(tmpFile);
740
+ }
741
+ catch {
742
+ /* ignore */
743
+ }
744
+ throw err;
745
+ }
746
+ }
747
+ function listWindows() {
748
+ const os = platform();
749
+ if (os === "darwin") {
750
+ try {
751
+ const script = `
752
+ tell application "System Events"
753
+ set windowList to {}
754
+ repeat with proc in (every process whose visible is true)
755
+ try
756
+ repeat with w in (every window of proc)
757
+ set end of windowList to (name of proc) & "|||" & (name of w) & "|||" & (id of w as text)
758
+ end repeat
759
+ end try
760
+ end repeat
761
+ return windowList as text
762
+ end tell`;
763
+ const output = execSync(`osascript -e '${script}'`, {
764
+ encoding: "utf-8",
765
+ timeout: 10000,
766
+ stdio: ["ignore", "pipe", "ignore"],
767
+ });
768
+ return output
769
+ .split(", ")
770
+ .filter(Boolean)
771
+ .map((entry) => {
772
+ const parts = entry.split("|||");
773
+ return {
774
+ app: parts[0] ?? "unknown",
775
+ title: parts[1] ?? "unknown",
776
+ id: parts[2] ?? "0",
777
+ };
778
+ });
779
+ }
780
+ catch {
781
+ return [];
782
+ }
783
+ }
784
+ if (os === "linux") {
785
+ try {
786
+ const output = execSync('wmctrl -l 2>/dev/null || xdotool search --name "" getwindowname 2>/dev/null', {
787
+ encoding: "utf-8",
788
+ timeout: 5000,
789
+ });
790
+ return output
791
+ .split("\n")
792
+ .filter(Boolean)
793
+ .map((line, i) => ({
794
+ id: String(i),
795
+ title: line.trim(),
796
+ app: "unknown",
797
+ }));
798
+ }
799
+ catch {
800
+ return [];
801
+ }
802
+ }
803
+ if (os === "win32") {
804
+ try {
805
+ const output = execSync(`powershell -Command "Get-Process | Where-Object {$_.MainWindowTitle} | Select-Object Id, MainWindowTitle | ConvertTo-Json"`, { encoding: "utf-8", timeout: 10000 });
806
+ const processes = JSON.parse(output);
807
+ const list = Array.isArray(processes) ? processes : [processes];
808
+ return list.map((p) => ({
809
+ id: String(p.Id),
810
+ title: p.MainWindowTitle,
811
+ app: "unknown",
812
+ }));
813
+ }
814
+ catch {
815
+ return [];
816
+ }
817
+ }
818
+ return [];
819
+ }
820
+ async function recordAudio(durationMs) {
821
+ const os = platform();
822
+ const durationSec = Math.ceil(durationMs / 1000);
823
+ const tmpFile = join(tmpdir(), `sandbox-audio-${Date.now()}.wav`);
824
+ if (os === "darwin") {
825
+ // Use sox (rec) on macOS
826
+ if (commandExists("rec")) {
827
+ execSync(`rec -q ${tmpFile} trim 0 ${durationSec}`, {
828
+ timeout: durationMs + 5000,
829
+ stdio: ["ignore", "pipe", "pipe"],
830
+ });
831
+ }
832
+ else if (commandExists("ffmpeg")) {
833
+ execSync(`ffmpeg -f avfoundation -i ":0" -t ${durationSec} -y ${tmpFile} 2>/dev/null`, { timeout: durationMs + 10000, stdio: ["ignore", "pipe", "pipe"] });
834
+ }
835
+ else {
836
+ throw new Error("No audio recording tool available. Install sox or ffmpeg.");
837
+ }
838
+ }
839
+ else if (os === "linux") {
840
+ if (commandExists("arecord")) {
841
+ execSync(`arecord -d ${durationSec} -f cd ${tmpFile}`, {
842
+ timeout: durationMs + 5000,
843
+ stdio: ["ignore", "pipe", "pipe"],
844
+ });
845
+ }
846
+ else if (commandExists("ffmpeg")) {
847
+ execSync(`ffmpeg -f pulse -i default -t ${durationSec} -y ${tmpFile} 2>/dev/null`, { timeout: durationMs + 10000, stdio: ["ignore", "pipe", "pipe"] });
848
+ }
849
+ else {
850
+ throw new Error("No audio recording tool available. Install alsa-utils or ffmpeg.");
851
+ }
852
+ }
853
+ else if (os === "win32") {
854
+ // Use ffmpeg on Windows (most portable)
855
+ if (commandExists("ffmpeg")) {
856
+ execSync(`ffmpeg -f dshow -i audio="Microphone" -t ${durationSec} -y "${tmpFile.replace(/\//g, "\\")}" 2>NUL`, { timeout: durationMs + 10000, stdio: ["ignore", "pipe", "pipe"] });
857
+ }
858
+ else {
859
+ throw new Error("No audio recording tool available. Install ffmpeg.");
860
+ }
861
+ }
862
+ else {
863
+ throw new Error(`Audio recording not supported on platform: ${os}`);
864
+ }
865
+ const data = readFileSync(tmpFile);
866
+ try {
867
+ unlinkSync(tmpFile);
868
+ }
869
+ catch {
870
+ /* cleanup */
871
+ }
872
+ return data;
873
+ }
874
+ async function playAudio(data, format) {
875
+ const os = platform();
876
+ const tmpFile = join(tmpdir(), `sandbox-play-${Date.now()}.${format}`);
877
+ writeFileSync(tmpFile, data);
878
+ try {
879
+ if (os === "darwin") {
880
+ runCommand("afplay", [tmpFile], 60000);
881
+ }
882
+ else if (os === "linux") {
883
+ if (commandExists("aplay")) {
884
+ runCommand("aplay", [tmpFile], 60000);
885
+ }
886
+ else if (commandExists("paplay")) {
887
+ runCommand("paplay", [tmpFile], 60000);
888
+ }
889
+ else if (commandExists("ffplay")) {
890
+ runCommand("ffplay", ["-autoexit", "-nodisp", tmpFile], 60000);
891
+ }
892
+ else {
893
+ throw new Error("No audio playback tool available.");
894
+ }
895
+ }
896
+ else if (os === "win32") {
897
+ const escapedPath = tmpFile.replace(/\//g, "\\").replace(/'/g, "''");
898
+ runCommand("powershell", [
899
+ "-Command",
900
+ `(New-Object Media.SoundPlayer '${escapedPath}').PlaySync()`,
901
+ ], 60000);
902
+ }
903
+ }
904
+ finally {
905
+ try {
906
+ unlinkSync(tmpFile);
907
+ }
908
+ catch {
909
+ /* cleanup */
910
+ }
911
+ }
912
+ }
913
+ function toAppleScriptStringLiteral(value) {
914
+ return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
915
+ }
916
+ function performClick(x, y, button) {
917
+ const os = platform();
918
+ if (os === "darwin") {
919
+ // Use cliclick on macOS (brew install cliclick)
920
+ if (commandExists("cliclick")) {
921
+ const btn = button === "right" ? "rc" : "c";
922
+ runCommand("cliclick", [`${btn}:${x},${y}`], 5000);
923
+ }
924
+ else {
925
+ // AppleScript fallback
926
+ runCommand("osascript", ["-e", `tell application "System Events" to click at {${x}, ${y}}`], 5000);
927
+ }
928
+ }
929
+ else if (os === "linux") {
930
+ if (commandExists("xdotool")) {
931
+ const btn = button === "right" ? "3" : "1";
932
+ runCommand("xdotool", ["mousemove", String(x), String(y), "click", btn], 5000);
933
+ }
934
+ else {
935
+ throw new Error("xdotool required for mouse control on Linux.");
936
+ }
937
+ }
938
+ else if (os === "win32") {
939
+ // Use Win32 API via PowerShell to perform an actual mouse click
940
+ const psScript = [
941
+ `Add-Type -AssemblyName System.Windows.Forms`,
942
+ `[System.Windows.Forms.Cursor]::Position = New-Object System.Drawing.Point(${x},${y})`,
943
+ `Add-Type -MemberDefinition '[DllImport("user32.dll")] public static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);' -Name Win32Mouse -Namespace Win32`,
944
+ button === "right"
945
+ ? `[Win32.Win32Mouse]::mouse_event(0x0008, 0, 0, 0, 0); [Win32.Win32Mouse]::mouse_event(0x0010, 0, 0, 0, 0)` // right down + up
946
+ : `[Win32.Win32Mouse]::mouse_event(0x0002, 0, 0, 0, 0); [Win32.Win32Mouse]::mouse_event(0x0004, 0, 0, 0, 0)`, // left down + up
947
+ ].join("; ");
948
+ runCommand("powershell", ["-Command", psScript], 5000);
949
+ }
950
+ }
951
+ function performType(text) {
952
+ const os = platform();
953
+ if (os === "darwin") {
954
+ if (commandExists("cliclick")) {
955
+ runCommand("cliclick", [`t:${text}`], 10000);
956
+ }
957
+ else {
958
+ runCommand("osascript", [
959
+ "-e",
960
+ `tell application "System Events" to keystroke ${toAppleScriptStringLiteral(text)}`,
961
+ ], 10000);
962
+ }
963
+ }
964
+ else if (os === "linux") {
965
+ if (commandExists("xdotool")) {
966
+ runCommand("xdotool", ["type", "--", text], 10000);
967
+ }
968
+ else {
969
+ throw new Error("xdotool required for keyboard input on Linux.");
970
+ }
971
+ }
972
+ else if (os === "win32") {
973
+ const escaped = text.replace(/'/g, "''");
974
+ runCommand("powershell", [
975
+ "-Command",
976
+ `Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.SendKeys]::SendWait('${escaped}')`,
977
+ ], 10000);
978
+ }
979
+ }
980
+ function performKeypress(keys) {
981
+ const os = platform();
982
+ if (os === "darwin") {
983
+ if (commandExists("cliclick")) {
984
+ runCommand("cliclick", [`kp:${keys}`], 5000);
985
+ }
986
+ else {
987
+ const symbolicKeyCodes = {
988
+ return: 36,
989
+ enter: 36,
990
+ tab: 48,
991
+ space: 49,
992
+ escape: 53,
993
+ esc: 53,
994
+ left: 123,
995
+ right: 124,
996
+ down: 125,
997
+ up: 126,
998
+ };
999
+ const normalized = keys.trim().toLowerCase();
1000
+ const mappedCode = symbolicKeyCodes[normalized];
1001
+ const numericCode = mappedCode ??
1002
+ (Number.isInteger(Number(keys.trim())) ? Number(keys.trim()) : null);
1003
+ if (numericCode !== null) {
1004
+ runCommand("osascript", ["-e", `tell application "System Events" to key code ${numericCode}`], 5000);
1005
+ }
1006
+ else {
1007
+ runCommand("osascript", [
1008
+ "-e",
1009
+ `tell application "System Events" to keystroke ${toAppleScriptStringLiteral(keys)}`,
1010
+ ], 5000);
1011
+ }
1012
+ }
1013
+ }
1014
+ else if (os === "linux") {
1015
+ if (commandExists("xdotool")) {
1016
+ runCommand("xdotool", ["key", keys], 5000);
1017
+ }
1018
+ else {
1019
+ throw new Error("xdotool required for key input on Linux.");
1020
+ }
1021
+ }
1022
+ else if (os === "win32") {
1023
+ const escaped = keys.replace(/'/g, "''");
1024
+ runCommand("powershell", [
1025
+ "-Command",
1026
+ `Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.SendKeys]::SendWait('${escaped}')`,
1027
+ ], 5000);
1028
+ }
1029
+ }
1030
+ function detectCapabilities() {
1031
+ const os = platform();
1032
+ const caps = {};
1033
+ // Screenshot
1034
+ if (os === "darwin") {
1035
+ caps.screenshot = { available: true, tool: "screencapture (built-in)" };
1036
+ }
1037
+ else if (os === "linux") {
1038
+ if (commandExists("import"))
1039
+ caps.screenshot = { available: true, tool: "ImageMagick import" };
1040
+ else if (commandExists("scrot"))
1041
+ caps.screenshot = { available: true, tool: "scrot" };
1042
+ else if (commandExists("gnome-screenshot"))
1043
+ caps.screenshot = { available: true, tool: "gnome-screenshot" };
1044
+ else
1045
+ caps.screenshot = {
1046
+ available: false,
1047
+ tool: "none (install ImageMagick, scrot, or gnome-screenshot)",
1048
+ };
1049
+ }
1050
+ else if (os === "win32") {
1051
+ caps.screenshot = { available: true, tool: "PowerShell System.Drawing" };
1052
+ }
1053
+ else {
1054
+ caps.screenshot = { available: false, tool: "unsupported platform" };
1055
+ }
1056
+ // Audio record
1057
+ if (os === "darwin") {
1058
+ if (commandExists("rec"))
1059
+ caps.audioRecord = { available: true, tool: "sox rec" };
1060
+ else if (commandExists("ffmpeg"))
1061
+ caps.audioRecord = { available: true, tool: "ffmpeg" };
1062
+ else
1063
+ caps.audioRecord = {
1064
+ available: false,
1065
+ tool: "none (install sox or ffmpeg)",
1066
+ };
1067
+ }
1068
+ else if (os === "linux") {
1069
+ if (commandExists("arecord"))
1070
+ caps.audioRecord = { available: true, tool: "arecord" };
1071
+ else if (commandExists("ffmpeg"))
1072
+ caps.audioRecord = { available: true, tool: "ffmpeg" };
1073
+ else
1074
+ caps.audioRecord = {
1075
+ available: false,
1076
+ tool: "none (install alsa-utils or ffmpeg)",
1077
+ };
1078
+ }
1079
+ else if (os === "win32") {
1080
+ if (commandExists("ffmpeg"))
1081
+ caps.audioRecord = { available: true, tool: "ffmpeg" };
1082
+ else
1083
+ caps.audioRecord = { available: false, tool: "none (install ffmpeg)" };
1084
+ }
1085
+ else {
1086
+ caps.audioRecord = { available: false, tool: "unsupported" };
1087
+ }
1088
+ // Audio play
1089
+ if (os === "darwin")
1090
+ caps.audioPlay = { available: true, tool: "afplay (built-in)" };
1091
+ else if (os === "linux") {
1092
+ if (commandExists("aplay"))
1093
+ caps.audioPlay = { available: true, tool: "aplay" };
1094
+ else if (commandExists("paplay"))
1095
+ caps.audioPlay = { available: true, tool: "paplay" };
1096
+ else if (commandExists("ffplay"))
1097
+ caps.audioPlay = { available: true, tool: "ffplay" };
1098
+ else
1099
+ caps.audioPlay = { available: false, tool: "none" };
1100
+ }
1101
+ else if (os === "win32") {
1102
+ caps.audioPlay = { available: true, tool: "PowerShell SoundPlayer" };
1103
+ }
1104
+ else {
1105
+ caps.audioPlay = { available: false, tool: "unsupported" };
1106
+ }
1107
+ // Mouse/keyboard control
1108
+ if (os === "darwin") {
1109
+ if (commandExists("cliclick"))
1110
+ caps.computerUse = { available: true, tool: "cliclick" };
1111
+ else
1112
+ caps.computerUse = { available: true, tool: "AppleScript (limited)" };
1113
+ }
1114
+ else if (os === "linux") {
1115
+ if (commandExists("xdotool"))
1116
+ caps.computerUse = { available: true, tool: "xdotool" };
1117
+ else
1118
+ caps.computerUse = { available: false, tool: "none (install xdotool)" };
1119
+ }
1120
+ else if (os === "win32") {
1121
+ caps.computerUse = { available: true, tool: "PowerShell SendKeys" };
1122
+ }
1123
+ else {
1124
+ caps.computerUse = { available: false, tool: "unsupported" };
1125
+ }
1126
+ // Window listing
1127
+ if (os === "darwin")
1128
+ caps.windowList = { available: true, tool: "AppleScript" };
1129
+ else if (os === "linux") {
1130
+ if (commandExists("wmctrl"))
1131
+ caps.windowList = { available: true, tool: "wmctrl" };
1132
+ else if (commandExists("xdotool"))
1133
+ caps.windowList = { available: true, tool: "xdotool" };
1134
+ else
1135
+ caps.windowList = {
1136
+ available: false,
1137
+ tool: "none (install wmctrl or xdotool)",
1138
+ };
1139
+ }
1140
+ else if (os === "win32") {
1141
+ caps.windowList = { available: true, tool: "PowerShell Get-Process" };
1142
+ }
1143
+ else {
1144
+ caps.windowList = { available: false, tool: "unsupported" };
1145
+ }
1146
+ // Browser
1147
+ caps.browser = { available: true, tool: "CDP via sandbox browser container" };
1148
+ // Shell
1149
+ caps.shell = { available: true, tool: "docker exec" };
1150
+ return caps;
1151
+ }
1152
+ function getPlatformInfo() {
1153
+ const os = platform();
1154
+ let dockerInstalled = false;
1155
+ let dockerRunning = false;
1156
+ let appleContainerAvailable = false;
1157
+ // Check if docker binary exists (installed)
1158
+ try {
1159
+ const which = os === "win32" ? "where" : "which";
1160
+ execSync(`${which} docker`, { stdio: "ignore", timeout: 3000 });
1161
+ dockerInstalled = true;
1162
+ }
1163
+ catch {
1164
+ /* not installed */
1165
+ }
1166
+ // Check if docker daemon is running (docker info succeeds only when daemon is up)
1167
+ if (dockerInstalled) {
1168
+ try {
1169
+ execSync("docker info", { stdio: "ignore", timeout: 5000 });
1170
+ dockerRunning = true;
1171
+ }
1172
+ catch {
1173
+ /* installed but not running */
1174
+ }
1175
+ }
1176
+ if (os === "darwin") {
1177
+ try {
1178
+ execSync("which container", { stdio: "ignore", timeout: 3000 });
1179
+ appleContainerAvailable = true;
1180
+ }
1181
+ catch {
1182
+ /* */
1183
+ }
1184
+ }
1185
+ return {
1186
+ platform: os,
1187
+ arch: require("node:os").arch(),
1188
+ dockerInstalled,
1189
+ dockerRunning,
1190
+ // Legacy compat: dockerAvailable = running (old clients check this)
1191
+ dockerAvailable: dockerRunning,
1192
+ appleContainerAvailable,
1193
+ wsl2: os === "win32" ? isWsl2Available() : false,
1194
+ recommended: os === "darwin" && appleContainerAvailable ? "apple-container" : "docker",
1195
+ };
1196
+ }
1197
+ function isWsl2Available() {
1198
+ try {
1199
+ execSync("wsl --status", { stdio: "ignore", timeout: 5000 });
1200
+ return true;
1201
+ }
1202
+ catch {
1203
+ return false;
1204
+ }
1205
+ }
1206
+ function attemptDockerStart() {
1207
+ const os = platform();
1208
+ try {
1209
+ if (os === "darwin") {
1210
+ execSync('open -a "Docker"', { timeout: 5000, stdio: "ignore" });
1211
+ return {
1212
+ success: true,
1213
+ message: "Docker Desktop is starting on macOS. Give it a moment~",
1214
+ waitMs: 15000,
1215
+ };
1216
+ }
1217
+ if (os === "win32") {
1218
+ // Try common install locations
1219
+ const paths = [
1220
+ '"C:\\Program Files\\Docker\\Docker\\Docker Desktop.exe"',
1221
+ '"C:\\Program Files (x86)\\Docker\\Docker\\Docker Desktop.exe"',
1222
+ ];
1223
+ let started = false;
1224
+ for (const p of paths) {
1225
+ try {
1226
+ execSync(`start "" ${p}`, {
1227
+ timeout: 5000,
1228
+ stdio: "ignore",
1229
+ shell: "cmd.exe",
1230
+ });
1231
+ started = true;
1232
+ break;
1233
+ }
1234
+ catch {
1235
+ /* try next path */
1236
+ }
1237
+ }
1238
+ if (!started) {
1239
+ // Try via start menu
1240
+ execSync('start "" "Docker Desktop"', {
1241
+ timeout: 5000,
1242
+ stdio: "ignore",
1243
+ shell: "cmd.exe",
1244
+ });
1245
+ }
1246
+ return {
1247
+ success: true,
1248
+ message: "Docker Desktop is starting on Windows. This may take 30 seconds~",
1249
+ waitMs: 30000,
1250
+ };
1251
+ }
1252
+ if (os === "linux") {
1253
+ // Try systemctl first (most common)
1254
+ try {
1255
+ execSync("sudo systemctl start docker", {
1256
+ timeout: 10000,
1257
+ stdio: "ignore",
1258
+ });
1259
+ return {
1260
+ success: true,
1261
+ message: "Docker daemon started via systemctl",
1262
+ waitMs: 5000,
1263
+ };
1264
+ }
1265
+ catch {
1266
+ /* systemctl may not be available */
1267
+ }
1268
+ // Try service command
1269
+ try {
1270
+ execSync("sudo service docker start", {
1271
+ timeout: 10000,
1272
+ stdio: "ignore",
1273
+ });
1274
+ return {
1275
+ success: true,
1276
+ message: "Docker daemon started via service",
1277
+ waitMs: 5000,
1278
+ };
1279
+ }
1280
+ catch {
1281
+ /* */
1282
+ }
1283
+ return {
1284
+ success: false,
1285
+ message: "Could not auto-start Docker on Linux. Run: sudo systemctl start docker",
1286
+ waitMs: 0,
1287
+ };
1288
+ }
1289
+ return {
1290
+ success: false,
1291
+ message: `Auto-start not supported on ${os}`,
1292
+ waitMs: 0,
1293
+ };
1294
+ }
1295
+ catch (err) {
1296
+ return {
1297
+ success: false,
1298
+ message: `Failed: ${err instanceof Error ? err.message : String(err)}`,
1299
+ waitMs: 0,
1300
+ };
1301
+ }
1302
+ }
1303
+ // ── Helpers ──────────────────────────────────────────────────────────────────
1304
+ function commandExists(cmd) {
1305
+ try {
1306
+ const which = platform() === "win32" ? "where" : "which";
1307
+ execSync(`${which} ${cmd}`, { stdio: "ignore", timeout: 3000 });
1308
+ return true;
1309
+ }
1310
+ catch {
1311
+ return false;
1312
+ }
1313
+ }
1314
+ function sendJson(res, status, data) {
1315
+ sendJsonResponse(res, data, status);
1316
+ }
1317
+ function readBody(req) {
1318
+ return readRequestBody(req, {
1319
+ maxBytes: 10 * 1024 * 1024,
1320
+ returnNullOnTooLarge: true,
1321
+ returnNullOnError: true,
1322
+ destroyOnTooLarge: true,
1323
+ });
1324
+ }
1325
+ function readJsonBody(req, res) {
1326
+ return parseJsonBody(req, res, {
1327
+ maxBytes: 10 * 1024 * 1024,
1328
+ requireObject: false,
1329
+ readErrorStatus: 400,
1330
+ parseErrorStatus: 400,
1331
+ readErrorMessage: "Missing request body",
1332
+ parseErrorMessage: "Invalid JSON in request body",
1333
+ });
1334
+ }