windows-development-sandbox 1.20.0 → 1.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (337) hide show
  1. package/config.example.json +8 -1
  2. package/dist/app/features/access/access.def.js +5 -2
  3. package/dist/app/features/access/access.run.js +7 -3
  4. package/dist/app/features/accounts/accounts.def.d.ts +29 -1
  5. package/dist/app/features/accounts/accounts.def.js +10 -4
  6. package/dist/app/features/accounts/accounts.run.d.ts +1 -0
  7. package/dist/app/features/accounts/accounts.run.js +7 -2
  8. package/dist/app/features/accounts/services.def.d.ts +4 -1
  9. package/dist/app/features/accounts/services.def.js +15 -14
  10. package/dist/app/features/accounts/services.run.d.ts +1 -0
  11. package/dist/app/features/accounts/services.run.js +41 -15
  12. package/dist/app/features/defs.d.ts +39 -2
  13. package/dist/app/features/engine/engine.run.js +1 -1
  14. package/dist/app/features/github/github.def.d.ts +44 -3
  15. package/dist/app/features/github/github.def.js +145 -63
  16. package/dist/app/features/github/github.run.d.ts +9 -2
  17. package/dist/app/features/github/github.run.js +43 -5
  18. package/dist/app/features/health/health.def.js +8 -2
  19. package/dist/app/features/logs/logs.def.js +0 -8
  20. package/dist/app/features/projects/projects.def.js +2 -2
  21. package/dist/app/features/projects/projects.run.js +5 -5
  22. package/dist/app/features/sandbox/sandbox.def.js +7 -3
  23. package/dist/app/features/sessions/sessions.def.d.ts +4 -4
  24. package/dist/app/features/sessions/sessions.def.js +0 -5
  25. package/dist/app/features/sessions/sessions.run.d.ts +1 -1
  26. package/dist/app/features/sessions/sessions.run.js +2 -2
  27. package/dist/app/features/settings/categories.def.js +2 -0
  28. package/dist/app/features/settings/settings-rows.js +1 -1
  29. package/dist/app/features/settings/settings.def.js +1 -1
  30. package/dist/app/features/settings/settings.run.js +3 -3
  31. package/dist/app/features/storage/storage.run.js +18 -9
  32. package/dist/app/features/updates/update-lines.js +2 -2
  33. package/dist/app/features/updates/updates.def.js +1 -1
  34. package/dist/app/features/updates/updates.run.js +1 -1
  35. package/dist/app/features/web/web.def.js +2 -2
  36. package/dist/app/features/web/web.run.js +12 -4
  37. package/dist/app/kernel/errors.d.ts +7 -0
  38. package/dist/app/kernel/errors.js +18 -3
  39. package/dist/app/kernel/rpc.d.ts +5 -0
  40. package/dist/app/kernel/view.d.ts +11 -1
  41. package/dist/bin/agent-sandbox.js +2 -2
  42. package/dist/bin/{chunk-DK4NTBUF.js → chunk-7YPEDAJD.js} +172 -48
  43. package/dist/bin/{chunk-2IMT7ZCT.js → chunk-QFSJX2KW.js} +1 -1
  44. package/dist/bin/{chunk-Z2P5OGKL.js → chunk-USTRSHIE.js} +2436 -1693
  45. package/dist/bin/claude-host.js +2 -2
  46. package/dist/bin/claude-sbx.js +2 -2
  47. package/dist/bin/codex-sbx.js +2 -2
  48. package/dist/bin/gemini-sbx.js +2 -2
  49. package/dist/bin/sandbox.js +2 -2
  50. package/dist/bin/sbx-hide.js +2 -2
  51. package/dist/bin/sbx-show.js +2 -2
  52. package/dist/cli/manifest.d.ts +2 -2
  53. package/dist/cli/manifest.js +2 -1
  54. package/dist/cli/menu/coverage-exempt.d.ts +17 -0
  55. package/dist/cli/menu/coverage-exempt.js +61 -0
  56. package/dist/cli/menu/io-menu.d.ts +2 -0
  57. package/dist/cli/menu/io-menu.js +50 -5
  58. package/dist/cli/menu/pages/accounts-page.js +1 -1
  59. package/dist/cli/menu/pages/agents-page.js +8 -2
  60. package/dist/cli/menu/pages/maintenance-page.d.ts +6 -0
  61. package/dist/cli/menu/pages/maintenance-page.js +9 -2
  62. package/dist/cli/menu/pages/sessions-page.d.ts +2 -0
  63. package/dist/cli/menu/pages/sessions-page.js +12 -4
  64. package/dist/cli/menu/pages/settings-page.js +12 -1
  65. package/dist/cli/menu/remote-menu.js +1 -1
  66. package/dist/cli/menu/shell.d.ts +5 -0
  67. package/dist/cli/menu/shell.js +13 -0
  68. package/dist/cli/report.js +2 -0
  69. package/dist/cli/tui/app.d.ts +5 -0
  70. package/dist/cli/tui/app.js +2 -0
  71. package/dist/core/config/defaults.js +3 -1
  72. package/dist/core/schema/accounts.d.ts +6 -0
  73. package/dist/core/schema/accounts.js +13 -11
  74. package/dist/core/schema/config.d.ts +20 -8
  75. package/dist/core/schema/config.js +4 -4
  76. package/dist/core/schema/github.js +1 -1
  77. package/dist/core/schema/profile.js +8 -4
  78. package/dist/core/schema/resume.js +1 -1
  79. package/dist/core/schema/sandbox.js +3 -3
  80. package/dist/core/schema/vpn.js +1 -1
  81. package/dist/core/schema/web.js +3 -3
  82. package/dist/core/types.d.ts +6 -0
  83. package/dist/core/util/errors.d.ts +11 -1
  84. package/dist/core/util/errors.js +7 -1
  85. package/dist/core/util/index.d.ts +1 -1
  86. package/dist/core/util/index.js +1 -1
  87. package/dist/guest/accounts/adapter.d.ts +2 -0
  88. package/dist/guest/accounts/adapters.js +4 -0
  89. package/dist/guest/accounts/apply.d.ts +6 -2
  90. package/dist/guest/accounts/kinds/cfx.d.ts +7 -0
  91. package/dist/guest/accounts/kinds/cfx.js +33 -3
  92. package/dist/guest/accounts/kinds/comet.d.ts +7 -0
  93. package/dist/guest/accounts/kinds/comet.js +50 -0
  94. package/dist/guest/accounts/kinds/perplexity.d.ts +2 -0
  95. package/dist/guest/accounts/kinds/perplexity.js +12 -0
  96. package/dist/guest/accounts/watch.d.ts +2 -0
  97. package/dist/guest/accounts/watch.js +12 -2
  98. package/dist/guest/agents/agent-installer.js +1 -1
  99. package/dist/guest/agents/profile-links.d.ts +2 -0
  100. package/dist/guest/agents/profile-links.js +18 -4
  101. package/dist/guest/apps/after-install.js +19 -0
  102. package/dist/guest/apps/app-installer.d.ts +11 -0
  103. package/dist/guest/apps/app-installer.js +69 -6
  104. package/dist/guest/apps/comet-unpack.d.ts +20 -0
  105. package/dist/guest/apps/comet-unpack.js +127 -0
  106. package/dist/guest/apps/index.d.ts +1 -1
  107. package/dist/guest/apps/index.js +1 -1
  108. package/dist/guest/apps/resolvers-agents-web.d.ts +2 -0
  109. package/dist/guest/apps/resolvers-agents-web.js +7 -0
  110. package/dist/guest/apps/resolvers.js +2 -0
  111. package/dist/guest/apps/shortcuts.d.ts +2 -0
  112. package/dist/guest/apps/shortcuts.js +1 -0
  113. package/dist/guest/apps/unpack.js +14 -4
  114. package/dist/guest/boot/boot.d.ts +45 -16
  115. package/dist/guest/boot/boot.js +316 -145
  116. package/dist/guest/boot/graph.d.ts +252 -0
  117. package/dist/guest/boot/graph.js +257 -0
  118. package/dist/guest/boot/guide-lines.d.ts +25 -0
  119. package/dist/guest/boot/guide-lines.js +41 -0
  120. package/dist/guest/boot/guide.d.ts +1 -4
  121. package/dist/guest/boot/guide.js +6 -8
  122. package/dist/guest/boot/runner.d.ts +77 -0
  123. package/dist/guest/boot/runner.js +215 -0
  124. package/dist/guest/browser/cdp.d.ts +71 -0
  125. package/dist/guest/browser/cdp.js +306 -0
  126. package/dist/guest/browser/comet.d.ts +28 -0
  127. package/dist/guest/browser/comet.js +155 -0
  128. package/dist/guest/daemon/project-provisioner.js +6 -1
  129. package/dist/guest/devtools/fivem.d.ts +1 -1
  130. package/dist/guest/devtools/fivem.js +243 -3
  131. package/dist/guest/entries/daemon.js +2 -0
  132. package/dist/guest/runtime/log.d.ts +12 -0
  133. package/dist/guest/runtime/log.js +29 -5
  134. package/dist/guest/runtime/pools.d.ts +24 -0
  135. package/dist/guest/runtime/pools.js +60 -0
  136. package/dist/guest/runtime/process.d.ts +4 -0
  137. package/dist/guest/runtime/process.js +38 -1
  138. package/dist/guest/runtime/status.d.ts +5 -1
  139. package/dist/guest/runtime/status.js +19 -0
  140. package/dist/guest/setup/addon-mcp.d.ts +1 -1
  141. package/dist/guest/setup/addon-mcp.js +52 -12
  142. package/dist/guest/setup/agent-addons.d.ts +3 -2
  143. package/dist/guest/setup/agent-addons.js +12 -3
  144. package/dist/guest/setup/environment.d.ts +1 -1
  145. package/dist/guest/setup/environment.js +25 -12
  146. package/dist/guest/setup/headroom.d.ts +8 -3
  147. package/dist/guest/setup/headroom.js +44 -15
  148. package/dist/guest/setup/path-plan.d.ts +28 -0
  149. package/dist/guest/setup/path-plan.js +69 -2
  150. package/dist/guest/setup/shell-path.d.ts +1 -1
  151. package/dist/guest/setup/shell-path.js +3 -3
  152. package/dist/guest/toolchains/fivem/artifacts.d.ts +48 -1
  153. package/dist/guest/toolchains/fivem/artifacts.js +97 -4
  154. package/dist/guest/toolchains/fivem/fivem.d.ts +32 -1
  155. package/dist/guest/toolchains/fivem/fivem.js +168 -3
  156. package/dist/guest/toolchains/fivem/scaffold.d.ts +35 -0
  157. package/dist/guest/toolchains/fivem/scaffold.js +105 -0
  158. package/dist/guest/toolchains/fivem/serve-plan.d.ts +34 -0
  159. package/dist/guest/toolchains/fivem/serve-plan.js +61 -0
  160. package/dist/guest/toolchains/languages/go.js +1 -1
  161. package/dist/guest/toolchains/languages/node.js +2 -1
  162. package/dist/guest/toolchains/languages/php.d.ts +2 -0
  163. package/dist/guest/toolchains/languages/php.js +13 -1
  164. package/dist/guest/toolchains/languages/python-tools.js +1 -1
  165. package/dist/guest/toolchains/languages/ruby.js +1 -1
  166. package/dist/guest/toolchains/native/binstall.js +1 -1
  167. package/dist/guest/toolchains/native/msvc/packages.js +10 -4
  168. package/dist/guest/toolchains/native/rust.d.ts +2 -0
  169. package/dist/guest/toolchains/native/rust.js +11 -4
  170. package/dist/guest/toolchains/native/unreal.d.ts +2 -0
  171. package/dist/guest/toolchains/native/unreal.js +16 -6
  172. package/dist/guest/toolchains/native/vcruntime.d.ts +2 -0
  173. package/dist/guest/toolchains/native/vcruntime.js +10 -2
  174. package/dist/guest/toolchains/native/visual-studio.d.ts +3 -0
  175. package/dist/guest/toolchains/native/visual-studio.js +44 -26
  176. package/dist/guest/toolchains/native/vs-request.d.ts +2 -0
  177. package/dist/guest/toolchains/native/vs-request.js +2 -0
  178. package/dist/guest/toolchains/plan.js +19 -8
  179. package/dist/guest/toolchains/scheduler.d.ts +2 -21
  180. package/dist/guest/toolchains/scheduler.js +7 -121
  181. package/dist/guest/toolchains/setup.d.ts +15 -2
  182. package/dist/guest/toolchains/setup.js +39 -20
  183. package/dist/guest/toolchains/split.d.ts +28 -0
  184. package/dist/guest/toolchains/split.js +60 -0
  185. package/dist/guest/toolchains/steam/client.js +2 -1
  186. package/dist/guest/toolchains/step-scheduler.d.ts +51 -0
  187. package/dist/guest/toolchains/step-scheduler.js +147 -0
  188. package/dist/guest/toolchains/step.d.ts +13 -0
  189. package/dist/guest/toolchains/tools/git.js +18 -0
  190. package/dist/guest/vpn/openvpn.js +3 -4
  191. package/dist/guest/vpn/wireguard.js +11 -4
  192. package/dist/host/accounts/deliver.js +7 -0
  193. package/dist/host/accounts/handoff.js +2 -6
  194. package/dist/host/accounts/index.d.ts +1 -1
  195. package/dist/host/accounts/index.js +1 -1
  196. package/dist/host/accounts/kinds/cfx.d.ts +1 -1
  197. package/dist/host/accounts/kinds/cfx.js +47 -4
  198. package/dist/host/accounts/kinds/comet.d.ts +2 -0
  199. package/dist/host/accounts/kinds/comet.js +6 -0
  200. package/dist/host/accounts/kinds/perplexity.d.ts +2 -0
  201. package/dist/host/accounts/kinds/perplexity.js +30 -0
  202. package/dist/host/accounts/leases.d.ts +7 -1
  203. package/dist/host/accounts/leases.js +13 -2
  204. package/dist/host/accounts/source.d.ts +7 -1
  205. package/dist/host/accounts/source.js +27 -0
  206. package/dist/host/accounts/sources.js +4 -0
  207. package/dist/host/github/deliver.d.ts +1 -1
  208. package/dist/host/github/deliver.js +20 -1
  209. package/dist/host/github/index.d.ts +2 -1
  210. package/dist/host/github/index.js +1 -0
  211. package/dist/host/github/token.d.ts +13 -1
  212. package/dist/host/github/token.js +19 -2
  213. package/dist/host/github/verify.d.ts +27 -0
  214. package/dist/host/github/verify.js +61 -0
  215. package/dist/host/launch/hints/fivem.d.ts +3 -1
  216. package/dist/host/launch/hints/fivem.js +68 -2
  217. package/dist/host/launch/session-file.js +4 -0
  218. package/dist/host/launch/toolchains.d.ts +2 -1
  219. package/dist/host/launch/toolchains.js +5 -3
  220. package/dist/host/profile/claude-login.d.ts +2 -2
  221. package/dist/host/profile/claude-login.js +4 -3
  222. package/dist/host/vpn/nordvpn.d.ts +2 -4
  223. package/dist/host/vpn/nordvpn.js +2 -24
  224. package/dist/runtime/agent.js +405 -90
  225. package/dist/runtime/daemon.js +3010 -1383
  226. package/dist/runtime/db.js +333 -90
  227. package/dist/runtime/main.js +4720 -1954
  228. package/dist/runtime/netproxy.js +286 -69
  229. package/dist/runtime/tool.js +2852 -1780
  230. package/dist/runtime/view.js +286 -69
  231. package/dist/selftest/accounts.test.js +1 -1
  232. package/dist/selftest/agent-paths.test.js +39 -1
  233. package/dist/selftest/agent-settings.test.js +6 -0
  234. package/dist/selftest/agents-web.test.d.ts +2 -0
  235. package/dist/selftest/agents-web.test.js +647 -0
  236. package/dist/selftest/app.test.js +5 -2
  237. package/dist/selftest/boot-runner.test.d.ts +2 -0
  238. package/dist/selftest/boot-runner.test.js +456 -0
  239. package/dist/selftest/channel.test.js +15 -0
  240. package/dist/selftest/fivem.test.js +249 -3
  241. package/dist/selftest/github.test.js +94 -9
  242. package/dist/selftest/guest-boot.test.js +3 -0
  243. package/dist/selftest/health.test.js +1 -1
  244. package/dist/selftest/index.js +8 -0
  245. package/dist/selftest/layout.test.js +5 -0
  246. package/dist/selftest/menu-coverage.test.d.ts +2 -0
  247. package/dist/selftest/menu-coverage.test.js +46 -0
  248. package/dist/selftest/menu-screens.js +37 -1
  249. package/dist/selftest/persisted-installs.test.js +6 -3
  250. package/dist/selftest/service-accounts.test.js +3 -2
  251. package/dist/selftest/support/engine-golden.js +27 -0
  252. package/dist/selftest/support/fixtures.d.ts +6 -0
  253. package/dist/selftest/support/web-preview.d.ts +34 -1
  254. package/dist/selftest/support/web-preview.js +21 -18
  255. package/dist/selftest/toolchains.test.js +23 -1
  256. package/dist/selftest/ui-text.test.d.ts +7 -0
  257. package/dist/selftest/ui-text.test.js +300 -0
  258. package/dist/shared/accounts/anthropic.d.ts +1 -1
  259. package/dist/shared/accounts/anthropic.js +9 -8
  260. package/dist/shared/accounts/index.d.ts +2 -0
  261. package/dist/shared/accounts/index.js +2 -0
  262. package/dist/shared/accounts/kinds/comet.d.ts +12 -0
  263. package/dist/shared/accounts/kinds/comet.js +64 -0
  264. package/dist/shared/accounts/kinds/perplexity.d.ts +8 -0
  265. package/dist/shared/accounts/kinds/perplexity.js +37 -0
  266. package/dist/shared/accounts/kinds.d.ts +24 -5
  267. package/dist/shared/accounts/kinds.js +86 -4
  268. package/dist/shared/accounts/payloads.d.ts +81 -0
  269. package/dist/shared/accounts/payloads.js +39 -1
  270. package/dist/shared/apps/agent-addons.d.ts +33 -5
  271. package/dist/shared/apps/agent-addons.js +95 -3
  272. package/dist/shared/apps/catalogue-agents-web.d.ts +14 -0
  273. package/dist/shared/apps/catalogue-agents-web.js +112 -0
  274. package/dist/shared/apps/catalogue-modding.js +32 -1
  275. package/dist/shared/apps/catalogue.d.ts +27 -3
  276. package/dist/shared/apps/catalogue.js +2 -1
  277. package/dist/shared/apps/index.d.ts +3 -1
  278. package/dist/shared/apps/index.js +3 -1
  279. package/dist/shared/channel/schema.d.ts +21 -3
  280. package/dist/shared/channel/schema.js +7 -0
  281. package/dist/shared/channel/secrets.d.ts +19 -0
  282. package/dist/shared/concurrency/index.d.ts +3 -0
  283. package/dist/shared/concurrency/index.js +3 -0
  284. package/dist/shared/concurrency/installer-retry.d.ts +6 -0
  285. package/dist/shared/concurrency/installer-retry.js +10 -0
  286. package/dist/shared/concurrency/limiter.d.ts +19 -0
  287. package/dist/shared/concurrency/limiter.js +67 -0
  288. package/dist/shared/concurrency/pools.d.ts +7 -0
  289. package/dist/shared/concurrency/pools.js +9 -0
  290. package/dist/shared/download/archive.d.ts +2 -0
  291. package/dist/shared/download/archive.js +11 -1
  292. package/dist/shared/download/bounded-fetch.d.ts +13 -0
  293. package/dist/shared/download/bounded-fetch.js +40 -0
  294. package/dist/shared/download/downloader.d.ts +5 -0
  295. package/dist/shared/download/downloader.js +50 -38
  296. package/dist/shared/download/index.d.ts +2 -1
  297. package/dist/shared/download/index.js +2 -1
  298. package/dist/shared/readiness.d.ts +2 -2
  299. package/dist/shared/readiness.js +2 -2
  300. package/dist/web/index.html +1 -1
  301. package/dist/web/{main-OUUQYNK4.js → main-CCILLX2M.js} +67 -67
  302. package/native/csharp/HcsHost/AssemblyInfo.cs +3 -3
  303. package/native/csharp/HostTools/AssemblyInfo.cs +3 -3
  304. package/native/csharp/StorageHelper/AssemblyInfo.cs +3 -3
  305. package/package.json +1 -1
  306. package/sandbox/addons/browser-use-mcp/requirements.in +1 -0
  307. package/sandbox/addons/browser-use-mcp/requirements.txt +2350 -0
  308. package/sandbox/addons/chrome-devtools-mcp/package-lock.json +38 -0
  309. package/sandbox/addons/chrome-devtools-mcp/package.json +7 -0
  310. package/sandbox/addons/comet-mcp/package-lock.json +1277 -0
  311. package/sandbox/addons/comet-mcp/package.json +7 -0
  312. package/sandbox/addons/perplexity-mcp/package-lock.json +1655 -0
  313. package/sandbox/addons/perplexity-mcp/package.json +7 -0
  314. package/sandbox/scripts/add-firewall-port.ps1 +18 -4
  315. package/sandbox/scripts/set-machine-environment.ps1 +30 -15
  316. package/sandbox/templates/fivem/README.txt +6 -2
  317. package/sandbox/templates/fivem/cs/Client/Client.csproj +15 -0
  318. package/sandbox/templates/fivem/cs/Client/ClientMain.cs +20 -0
  319. package/sandbox/templates/fivem/cs/Server/Server.csproj +14 -0
  320. package/sandbox/templates/fivem/cs/Server/ServerMain.cs +20 -0
  321. package/sandbox/templates/fivem/cs/fxmanifest.lua +11 -0
  322. package/sandbox/templates/fivem/js/client.js +12 -0
  323. package/sandbox/templates/fivem/js/fxmanifest.lua +9 -0
  324. package/sandbox/templates/fivem/js/server.js +6 -0
  325. package/sandbox/templates/fivem/lua/client.lua +8 -0
  326. package/sandbox/templates/fivem/lua/fxmanifest.lua +10 -0
  327. package/sandbox/templates/fivem/lua/server.lua +6 -0
  328. package/sandbox/templates/fivem/server.cfg +37 -0
  329. package/sandbox/templates/fivem/ts/build.js +17 -0
  330. package/sandbox/templates/fivem/ts/fxmanifest.lua +9 -0
  331. package/sandbox/templates/fivem/ts/package.json +16 -0
  332. package/sandbox/templates/fivem/ts/src/client/client.ts +12 -0
  333. package/sandbox/templates/fivem/ts/src/client/tsconfig.json +13 -0
  334. package/sandbox/templates/fivem/ts/src/server/server.ts +6 -0
  335. package/sandbox/templates/fivem/ts/src/server/tsconfig.json +13 -0
  336. package/schemas/config.schema.json +56 -27
  337. package/schemas/sandbox-config.schema.json +37 -14
@@ -2,7 +2,19 @@
2
2
  // come from, and the rules for handing it over (one sandbox at a time, handed back when renewed). Pure, web-safe: no
3
3
  // Node built-ins. The payload shapes are in payloads.ts, the host side in host/accounts, the sandbox side in
4
4
  // guest/accounts.
5
- export const SERVICE_KINDS = ['epic', 'steam', 'unity', 'cfx', 'keystore', 'play', 'expo', 'appstore'];
5
+ export const SERVICE_KINDS = [
6
+ 'epic',
7
+ 'steam',
8
+ 'unity',
9
+ 'cfx',
10
+ 'keystore',
11
+ 'play',
12
+ 'expo',
13
+ 'appstore',
14
+ 'perplexity',
15
+ 'comet',
16
+ ];
17
+ /** The toolchains a sign-in can serve. */
6
18
  export const USED_BY = [
7
19
  'unreal',
8
20
  'steam',
@@ -14,9 +26,16 @@ export const USED_BY = [
14
26
  'godot',
15
27
  'dotnet',
16
28
  ];
29
+ /** The apps (apps.install ids) that turn each app user on. */
30
+ export const APP_USERS = {
31
+ perplexity: ['perplexity-mcp'],
32
+ comet: ['comet'],
33
+ };
17
34
  export const ACCOUNT_SOURCES = ['pc', 'file', 'typed', 'sandbox'];
18
35
  const AGENT_CAN_USE = 'The agent in the sandbox can use this sign-in while it is there.';
19
36
  const ONE_PLACE = 'It works in one sandbox at a time: a second sandbox starts without it while the first one runs.';
37
+ /** A Perplexity API key: pplx- and its body. */
38
+ export const PERPLEXITY_KEY_PATTERN = /^pplx-[A-Za-z0-9_-]{8,200}$/;
20
39
  export const SERVICE_SPECS = {
21
40
  epic: {
22
41
  kind: 'epic',
@@ -70,19 +89,28 @@ export const SERVICE_SPECS = {
70
89
  kind: 'cfx',
71
90
  label: 'Cfx.re (FiveM / RedM server key)',
72
91
  usedBy: ['fivem'],
73
- sources: ['typed'],
92
+ sources: ['typed', 'file'],
74
93
  singleHolder: false,
75
94
  returns: false,
95
+ // `import cfx --from` reads a whole server.cfg (they often run to tens of KB); the payload itself is tiny.
76
96
  maxBytes: 4 * 1024,
97
+ maxFileBytes: 256 * 1024,
77
98
  warnings: [AGENT_CAN_USE + ' Anyone with the key can run a server under your Cfx.re account.'],
78
99
  fields: [
79
- { name: 'licenseKey', label: 'Server licence key (cfxk_...)', secret: true, pattern: /^cfxk_[A-Za-z0-9_]+$/ },
100
+ {
101
+ name: 'licenseKey',
102
+ label: 'Server licence key (cfxk_...)',
103
+ secret: true,
104
+ pattern: /^cfxk_[A-Za-z0-9_]+$/,
105
+ only: 'typed',
106
+ },
80
107
  {
81
108
  name: 'steamWebApiKey',
82
109
  label: 'Steam Web API key (optional)',
83
110
  secret: true,
84
111
  optional: true,
85
112
  pattern: /^[A-F0-9]{32}$/,
113
+ only: 'typed',
86
114
  },
87
115
  ],
88
116
  },
@@ -137,6 +165,47 @@ export const SERVICE_SPECS = {
137
165
  { name: 'keyId', label: 'Key ID', secret: false, pattern: /^[A-Z0-9]{10}$/ },
138
166
  ],
139
167
  },
168
+ perplexity: {
169
+ kind: 'perplexity',
170
+ label: 'Perplexity API key',
171
+ usedBy: ['perplexity'],
172
+ sources: ['pc', 'file', 'typed'],
173
+ singleHolder: false,
174
+ returns: false,
175
+ maxBytes: 1024,
176
+ maxFileBytes: 64 * 1024,
177
+ warnings: [
178
+ AGENT_CAN_USE + ' It can read the key and spend your API credit: use a separate API key with a spending limit.',
179
+ 'Perplexity Pro does not include API use; the API key is billed separately.',
180
+ 'Only the variable PERPLEXITY_API_KEY of the agent gets it: nothing in the sandbox writes it to a file.',
181
+ ],
182
+ fields: [
183
+ {
184
+ name: 'apiKey',
185
+ label: 'Perplexity API key (pplx-...)',
186
+ secret: true,
187
+ pattern: PERPLEXITY_KEY_PATTERN,
188
+ only: 'typed',
189
+ },
190
+ ],
191
+ },
192
+ comet: {
193
+ kind: 'comet',
194
+ label: 'Comet (Perplexity browser)',
195
+ usedBy: ['comet'],
196
+ sources: ['sandbox'],
197
+ singleHolder: false,
198
+ returns: true,
199
+ maxBytes: 256 * 1024,
200
+ warnings: [
201
+ AGENT_CAN_USE +
202
+ ' It can act as you in Comet and spend your Perplexity Computer credits; agentic browsing is open to prompt injection from the pages it reads.',
203
+ "Your Comet sign-in can't be copied from this PC: Windows locks it to your PC account. Sign in once inside a sandbox and it is kept for the next ones.",
204
+ 'Only the perplexity.ai sign-in cookies are kept: never saved passwords, other sites, localStorage or history. Never import your main browser profile.',
205
+ 'Several sandboxes can use it at once: the sign-in the last one hands back is kept.',
206
+ ],
207
+ fields: [],
208
+ },
140
209
  };
141
210
  /** Where a sandbox leaves a renewed sign-in, under the data folder: state\accounts\<kind>.json. */
142
211
  export const HANDOFF_PARTS = ['state', 'accounts'];
@@ -145,7 +214,20 @@ const ANDROID_USERS = ['flutter', 'reactNative', 'godot', 'unity'];
145
214
  export function isServiceKind(value) {
146
215
  return SERVICE_KINDS.includes(value);
147
216
  }
148
- /** Whether a sign-in is wanted when these toolchains are on. */
217
+ /** How the apps that use a sign-in are named in sentences ("for sandboxes that use ..."). */
218
+ const APP_USER_TEXT = {
219
+ perplexity: 'the Perplexity MCP app',
220
+ comet: 'the Comet app',
221
+ };
222
+ /** What a sign-in serves, for a sentence: "unreal", "reactNative or flutter", "the Comet app". */
223
+ export function usedByText(usedBy) {
224
+ return usedBy.map((u) => (u in APP_USER_TEXT ? APP_USER_TEXT[u] : u)).join(' or ');
225
+ }
226
+ /** The app users that the chosen apps (apps.install) turn on. */
227
+ export function appUsersOn(install) {
228
+ return Object.keys(APP_USERS).filter((u) => APP_USERS[u].some((id) => install.includes(id)));
229
+ }
230
+ /** Whether a sign-in is wanted when these toolchains (and apps) are on. */
149
231
  export function serviceWanted(kind, on) {
150
232
  const spec = SERVICE_SPECS[kind];
151
233
  if (spec.usedBy.some((u) => on.has(u)))
@@ -48,6 +48,49 @@ export declare const AppstorePayloadSchema: z.ZodObject<{
48
48
  keyId: z.ZodString;
49
49
  p8: z.ZodString;
50
50
  }, z.core.$strict>;
51
+ /** A Perplexity API key (PERPLEXITY_API_KEY), billed separately from Perplexity Pro. */
52
+ export declare const PerplexityPayloadSchema: z.ZodObject<{
53
+ apiKey: z.ZodString;
54
+ }, z.core.$strict>;
55
+ /** The only sites whose cookies a Comet sign-in keeps (each with its subdomains). Fixed: never a setting. */
56
+ export declare const COMET_COOKIE_DOMAINS: readonly string[];
57
+ /** At most this many cookies are kept. */
58
+ export declare const MAX_COMET_COOKIES = 200;
59
+ /** Whether a cookie's domain (".www.perplexity.ai", "perplexity.ai" ...) is one of COMET_COOKIE_DOMAINS or below it. */
60
+ export declare function cometCookieDomainAllowed(domain: string): boolean;
61
+ /** One cookie as CDP's Storage.setCookies takes it (expires: seconds since 1970; none for a session cookie). */
62
+ export declare const CometCookieSchema: z.ZodObject<{
63
+ name: z.ZodString;
64
+ value: z.ZodString;
65
+ domain: z.ZodString;
66
+ path: z.ZodString;
67
+ expires: z.ZodOptional<z.ZodNumber>;
68
+ secure: z.ZodBoolean;
69
+ httpOnly: z.ZodBoolean;
70
+ sameSite: z.ZodOptional<z.ZodEnum<{
71
+ Strict: "Strict";
72
+ Lax: "Lax";
73
+ None: "None";
74
+ }>>;
75
+ }, z.core.$strict>;
76
+ export type CometCookie = z.output<typeof CometCookieSchema>;
77
+ /** Comet's sign-in: the allow-listed perplexity.ai cookies only (no passwords, localStorage or history). */
78
+ export declare const CometPayloadSchema: z.ZodObject<{
79
+ cookies: z.ZodArray<z.ZodObject<{
80
+ name: z.ZodString;
81
+ value: z.ZodString;
82
+ domain: z.ZodString;
83
+ path: z.ZodString;
84
+ expires: z.ZodOptional<z.ZodNumber>;
85
+ secure: z.ZodBoolean;
86
+ httpOnly: z.ZodBoolean;
87
+ sameSite: z.ZodOptional<z.ZodEnum<{
88
+ Strict: "Strict";
89
+ Lax: "Lax";
90
+ None: "None";
91
+ }>>;
92
+ }, z.core.$strict>>;
93
+ }, z.core.$strict>;
51
94
  export declare const PAYLOADS: {
52
95
  readonly epic: z.ZodObject<{
53
96
  data: z.ZodString;
@@ -89,6 +132,25 @@ export declare const PAYLOADS: {
89
132
  keyId: z.ZodString;
90
133
  p8: z.ZodString;
91
134
  }, z.core.$strict>;
135
+ readonly perplexity: z.ZodObject<{
136
+ apiKey: z.ZodString;
137
+ }, z.core.$strict>;
138
+ readonly comet: z.ZodObject<{
139
+ cookies: z.ZodArray<z.ZodObject<{
140
+ name: z.ZodString;
141
+ value: z.ZodString;
142
+ domain: z.ZodString;
143
+ path: z.ZodString;
144
+ expires: z.ZodOptional<z.ZodNumber>;
145
+ secure: z.ZodBoolean;
146
+ httpOnly: z.ZodBoolean;
147
+ sameSite: z.ZodOptional<z.ZodEnum<{
148
+ Strict: "Strict";
149
+ Lax: "Lax";
150
+ None: "None";
151
+ }>>;
152
+ }, z.core.$strict>>;
153
+ }, z.core.$strict>;
92
154
  };
93
155
  export type Payload<K extends ServiceKind> = z.output<(typeof PAYLOADS)[K]>;
94
156
  export type AnyPayload = Payload<ServiceKind>;
@@ -137,6 +199,25 @@ export declare const ServiceAccountsSchema: z.ZodObject<{
137
199
  keyId: z.ZodString;
138
200
  p8: z.ZodString;
139
201
  }, z.core.$strict>>;
202
+ perplexity: z.ZodOptional<z.ZodObject<{
203
+ apiKey: z.ZodString;
204
+ }, z.core.$strict>>;
205
+ comet: z.ZodOptional<z.ZodObject<{
206
+ cookies: z.ZodArray<z.ZodObject<{
207
+ name: z.ZodString;
208
+ value: z.ZodString;
209
+ domain: z.ZodString;
210
+ path: z.ZodString;
211
+ expires: z.ZodOptional<z.ZodNumber>;
212
+ secure: z.ZodBoolean;
213
+ httpOnly: z.ZodBoolean;
214
+ sameSite: z.ZodOptional<z.ZodEnum<{
215
+ Strict: "Strict";
216
+ Lax: "Lax";
217
+ None: "None";
218
+ }>>;
219
+ }, z.core.$strict>>;
220
+ }, z.core.$strict>>;
140
221
  }, z.core.$strict>;
141
222
  export type ServiceAccounts = z.output<typeof ServiceAccountsSchema>;
142
223
  /** A launch's id (generate.ts: "<ms>-<6 hex>"). */
@@ -1,7 +1,7 @@
1
1
  // The shape of each saved sign-in (what the host seals, what travels in the one-shot secrets file, what a sandbox may
2
2
  // hand back). Pure zod, web-safe. Every text is size-bounded: the sandbox may have written it.
3
3
  import { z } from 'zod';
4
- import { SERVICE_KINDS } from './kinds.js';
4
+ import { PERPLEXITY_KEY_PATTERN, SERVICE_KINDS } from './kinds.js';
5
5
  const KB = 1024;
6
6
  const base64 = (maxBytes) => z
7
7
  .string()
@@ -91,6 +91,40 @@ export const AppstorePayloadSchema = z.strictObject({
91
91
  .max(8 * KB)
92
92
  .regex(/^-----BEGIN PRIVATE KEY-----\r?\n[A-Za-z0-9+/=\r\n]+-----END PRIVATE KEY-----\s*$/),
93
93
  });
94
+ /** A Perplexity API key (PERPLEXITY_API_KEY), billed separately from Perplexity Pro. */
95
+ export const PerplexityPayloadSchema = z.strictObject({
96
+ apiKey: z.string().max(256).regex(PERPLEXITY_KEY_PATTERN),
97
+ });
98
+ /** The only sites whose cookies a Comet sign-in keeps (each with its subdomains). Fixed: never a setting. */
99
+ export const COMET_COOKIE_DOMAINS = ['perplexity.ai'];
100
+ /** At most this many cookies are kept. */
101
+ export const MAX_COMET_COOKIES = 200;
102
+ /** Whether a cookie's domain (".www.perplexity.ai", "perplexity.ai" ...) is one of COMET_COOKIE_DOMAINS or below it. */
103
+ export function cometCookieDomainAllowed(domain) {
104
+ const host = domain.trim().toLowerCase().replace(/^\./, '');
105
+ return COMET_COOKIE_DOMAINS.some((d) => host === d || host.endsWith('.' + d));
106
+ }
107
+ /** Printable text without control characters (a cookie the sandbox hands back could hold anything). */
108
+ const cookieText = (min, max) => z
109
+ .string()
110
+ .min(min)
111
+ .max(max)
112
+ .regex(/^[ -~]*$/);
113
+ /** One cookie as CDP's Storage.setCookies takes it (expires: seconds since 1970; none for a session cookie). */
114
+ export const CometCookieSchema = z.strictObject({
115
+ name: cookieText(1, 256).regex(/^[^\s;,=]+$/),
116
+ value: cookieText(0, 8192).regex(/^[^;]*$/),
117
+ domain: cookieText(1, 253).refine(cometCookieDomainAllowed, 'not a perplexity.ai cookie'),
118
+ path: cookieText(1, 1024).regex(/^\//),
119
+ expires: z.number().int().min(0).max(4102444800).optional(),
120
+ secure: z.boolean(),
121
+ httpOnly: z.boolean(),
122
+ sameSite: z.enum(['Strict', 'Lax', 'None']).optional(),
123
+ });
124
+ /** Comet's sign-in: the allow-listed perplexity.ai cookies only (no passwords, localStorage or history). */
125
+ export const CometPayloadSchema = z.strictObject({
126
+ cookies: z.array(CometCookieSchema).min(1).max(MAX_COMET_COOKIES),
127
+ });
94
128
  export const PAYLOADS = {
95
129
  epic: EpicPayloadSchema,
96
130
  steam: SteamPayloadSchema,
@@ -100,6 +134,8 @@ export const PAYLOADS = {
100
134
  play: PlayPayloadSchema,
101
135
  expo: ExpoPayloadSchema,
102
136
  appstore: AppstorePayloadSchema,
137
+ perplexity: PerplexityPayloadSchema,
138
+ comet: CometPayloadSchema,
103
139
  };
104
140
  /** The secrets-file field: the sign-ins this launch hands over, each optional. */
105
141
  export const ServiceAccountsSchema = z.strictObject({
@@ -111,6 +147,8 @@ export const ServiceAccountsSchema = z.strictObject({
111
147
  play: PlayPayloadSchema.optional(),
112
148
  expo: ExpoPayloadSchema.optional(),
113
149
  appstore: AppstorePayloadSchema.optional(),
150
+ perplexity: PerplexityPayloadSchema.optional(),
151
+ comet: CometPayloadSchema.optional(),
114
152
  });
115
153
  /** A launch's id (generate.ts: "<ms>-<6 hex>"). */
116
154
  export const LaunchIdSchema = z.string().regex(/^[A-Za-z0-9-]{1,64}$/);
@@ -43,17 +43,45 @@ export declare const HEADROOM_ENV: Readonly<Record<string, string>>;
43
43
  export declare function headroomEnv(base: Readonly<Record<string, string | undefined>>): Record<string, string>;
44
44
  /** The guide line while the proxy runs. */
45
45
  export declare function headroomGuideLine(logFile: string): string;
46
- /** A user-scope MCP server in Claude Code's .claude.json. */
47
- export interface McpServerConfig {
46
+ /** A user-scope MCP server in Claude Code's .claude.json: a program it starts, or a remote server over HTTP. */
47
+ export type McpServerConfig = {
48
48
  readonly type: 'stdio';
49
49
  readonly command: string;
50
50
  readonly args: readonly string[];
51
51
  readonly env: Readonly<Record<string, string>>;
52
- }
52
+ } | {
53
+ readonly type: 'http';
54
+ readonly url: string;
55
+ };
53
56
  /** The name prefix of the sandbox's own MCP servers: names with it are the sandbox's to add and remove. */
54
57
  export declare const ADDON_MCP_PREFIX = "sbx-";
55
- /** The MCP server of an installed add-on: `node <folder>\<script> <args>` (Node is on PATH in every sandbox). */
56
- export declare function addonMcpServer(folder: string, mcp: AddonMcp): McpServerConfig;
58
+ /** What the sandbox knows about an installed add-on beyond its folder: its program, and variables found at boot. */
59
+ export interface AddonPlace {
60
+ /** The add-on's program (for `program` servers). */
61
+ readonly exe?: string | null;
62
+ /** Variables only the sandbox can tell (a path), added to the entry's fixed ones. */
63
+ readonly env?: Readonly<Record<string, string>>;
64
+ }
65
+ /**
66
+ * The MCP server of an installed add-on: `node <folder>\<script> <args>` (Node is on PATH in every sandbox), its own
67
+ * program, or its remote address. Null when a program server's program is missing.
68
+ */
69
+ export declare function addonMcpServer(folder: string, mcp: AddonMcp, place?: AddonPlace): McpServerConfig | null;
70
+ /** An add-on's server as Codex runs it: the Claude Code one, plus the agent variables Codex must pass on. */
71
+ export type CodexMcpServer = McpServerConfig & {
72
+ readonly envVars?: readonly string[];
73
+ };
74
+ /**
75
+ * Codex's config.toml with the add-ons' servers as [mcp_servers.<name>] tables: every table of a `known` sbx-...
76
+ * server is removed first (an add-on turned off), then the servers on are added at the end. Your own servers and
77
+ * settings stay as they are. A server whose name is used some other way in the file (an inline table, dotted keys)
78
+ * is left out (`skipped`), so the file never gets the same key twice. `changed` is false when nothing changes.
79
+ */
80
+ export declare function codexWithAddonMcpServers(toml: string, servers: Readonly<Record<string, CodexMcpServer>>, known: readonly string[]): {
81
+ toml: string;
82
+ changed: boolean;
83
+ skipped: string[];
84
+ };
57
85
  /**
58
86
  * The user-scope MCP servers with the add-ons' servers set: every sbx-... server that `known` lists and that is not in
59
87
  * `servers` is removed (an add-on turned off); servers of your own are never touched.
@@ -73,10 +73,102 @@ export function headroomGuideLine(logFile) {
73
73
  }
74
74
  /** The name prefix of the sandbox's own MCP servers: names with it are the sandbox's to add and remove. */
75
75
  export const ADDON_MCP_PREFIX = 'sbx-';
76
- /** The MCP server of an installed add-on: `node <folder>\<script> <args>` (Node is on PATH in every sandbox). */
77
- export function addonMcpServer(folder, mcp) {
76
+ /**
77
+ * The MCP server of an installed add-on: `node <folder>\<script> <args>` (Node is on PATH in every sandbox), its own
78
+ * program, or its remote address. Null when a program server's program is missing.
79
+ */
80
+ export function addonMcpServer(folder, mcp, place = {}) {
81
+ if (mcp.url)
82
+ return { type: 'http', url: mcp.url };
83
+ const env = { ...(mcp.env ?? {}), ...(place.env ?? {}) };
84
+ if (mcp.program)
85
+ return place.exe ? { type: 'stdio', command: place.exe, args: [...(mcp.args ?? [])], env } : null;
86
+ if (!mcp.script)
87
+ return null;
78
88
  const script = folder.replace(/[\\/]+$/, '') + '\\' + mcp.script.replace(/\//g, '\\');
79
- return { type: 'stdio', command: 'node', args: [script, ...(mcp.args ?? [])], env: {} };
89
+ return { type: 'stdio', command: 'node', args: [script, ...(mcp.args ?? [])], env };
90
+ }
91
+ /** A TOML string (JSON's escapes are TOML's basic-string escapes). */
92
+ const tomlString = (s) => JSON.stringify(s);
93
+ /** A TOML key: bare when it can be, else quoted. */
94
+ const tomlKey = (k) => (/^[A-Za-z0-9_-]+$/.test(k) ? k : tomlString(k));
95
+ /** A table header's dotted key, its parts unquoted ([mcp_servers."sbx-x".env] -> mcp_servers, sbx-x, env). */
96
+ function headerPath(line) {
97
+ const m = /^\s*\[\[?\s*(.*?)\s*\]\]?\s*(#.*)?$/.exec(line);
98
+ if (!m)
99
+ return null;
100
+ const parts = [];
101
+ const re = /\s*(?:"((?:[^"\\]|\\.)*)"|'([^']*)'|([A-Za-z0-9_-]+))\s*(\.|$)/y;
102
+ let at = 0;
103
+ while (at < m[1].length) {
104
+ re.lastIndex = at;
105
+ const part = re.exec(m[1]);
106
+ if (!part)
107
+ return null;
108
+ try {
109
+ parts.push(part[1] !== undefined ? JSON.parse('"' + part[1] + '"') : (part[2] ?? part[3]));
110
+ }
111
+ catch {
112
+ return null; // An escape JSON does not know: not one of the sandbox's names.
113
+ }
114
+ at = re.lastIndex;
115
+ if (!part[4])
116
+ break;
117
+ }
118
+ return parts;
119
+ }
120
+ /** The TOML tables of one server. */
121
+ function codexServerToml(name, server) {
122
+ const head = '[mcp_servers.' + tomlKey(name) + ']';
123
+ const mark = '# Set by the sandbox while this add-on is on in Apps (removed when it is off).';
124
+ if (server.type === 'http')
125
+ return [head, mark, 'url = ' + tomlString(server.url)];
126
+ const lines = [
127
+ head,
128
+ mark,
129
+ 'command = ' + tomlString(server.command),
130
+ 'args = [' + server.args.map(tomlString).join(', ') + ']',
131
+ ];
132
+ if (server.envVars?.length)
133
+ lines.push('env_vars = [' + server.envVars.map(tomlString).join(', ') + ']');
134
+ const env = Object.entries(server.env);
135
+ if (env.length)
136
+ lines.push('', '[mcp_servers.' + tomlKey(name) + '.env]', ...env.map(([k, v]) => tomlKey(k) + ' = ' + tomlString(v)));
137
+ return lines;
138
+ }
139
+ /**
140
+ * Codex's config.toml with the add-ons' servers as [mcp_servers.<name>] tables: every table of a `known` sbx-...
141
+ * server is removed first (an add-on turned off), then the servers on are added at the end. Your own servers and
142
+ * settings stay as they are. A server whose name is used some other way in the file (an inline table, dotted keys)
143
+ * is left out (`skipped`), so the file never gets the same key twice. `changed` is false when nothing changes.
144
+ */
145
+ export function codexWithAddonMcpServers(toml, servers, known) {
146
+ const ours = (p) => p !== null && p[0] === 'mcp_servers' && p.length >= 2 && known.includes(p[1]) && p[1].startsWith(ADDON_MCP_PREFIX);
147
+ const kept = [];
148
+ let skipping = false;
149
+ for (const line of toml.split(/\r?\n/)) {
150
+ if (/^\s*\[/.test(line))
151
+ skipping = ours(headerPath(line));
152
+ if (!skipping)
153
+ kept.push(line);
154
+ }
155
+ while (kept.length && kept[kept.length - 1].trim() === '')
156
+ kept.pop();
157
+ const rest = kept.join('\n');
158
+ const skipped = [];
159
+ const blocks = [];
160
+ for (const [name, server] of Object.entries(servers)) {
161
+ const escaped = name.replace(/[.*+?^${}()|[\]\\-]/g, '\\$&');
162
+ if (new RegExp('(^|[\\s.{,])["\']?' + escaped + '["\']?\\s*[.=]', 'm').test(rest)) {
163
+ skipped.push(name);
164
+ continue;
165
+ }
166
+ blocks.push(codexServerToml(name, server).join('\n'));
167
+ }
168
+ const text = [rest, ...blocks].filter((b) => b !== '').join('\n\n') + '\n';
169
+ const normalised = toml.replace(/\r\n/g, '\n');
170
+ const changed = text !== normalised && !(text === '\n' && normalised === '');
171
+ return { toml: changed ? text : toml, changed, skipped };
80
172
  }
81
173
  /**
82
174
  * The user-scope MCP servers with the add-ons' servers set: every sbx-... server that `known` lists and that is not in
@@ -0,0 +1,14 @@
1
+ import type { AppEntry } from './catalogue.js';
2
+ import type { AppSigner } from '../signer.js';
3
+ /** Pinned packages, installed from the lock files in sandbox\addons\<id> (renewing them: docs/toolchains.md). */
4
+ export declare const PERPLEXITY_MCP_VERSION = "1.3.0";
5
+ export declare const COMET_MCP_VERSION = "2.3.0";
6
+ export declare const CHROME_DEVTOOLS_MCP_VERSION = "1.12.0";
7
+ export declare const BROWSER_USE_VERSION = "0.13.14";
8
+ /** Perplexity Computer's official MCP server (HTTP; OAuth with your Perplexity account; uses Computer credits). */
9
+ export declare const PERPLEXITY_COMPUTER_MCP_URL = "https://www.perplexity.ai/rest/computer/mcp";
10
+ /** Comet's Windows installer: a redirect to the current release (no checksum is published; its signer is checked). */
11
+ export declare const COMET_DOWNLOAD_URL = "https://www.perplexity.ai/rest/browser/download?platform=win_x64&channel=stable";
12
+ /** Who signs Comet: Perplexity AI, Inc., with an EV code-signing certificate from GlobalSign. */
13
+ export declare const COMET_SIGNER: AppSigner;
14
+ export declare const AGENTS_WEB_APPS: readonly AppEntry[];
@@ -0,0 +1,112 @@
1
+ /** Pinned packages, installed from the lock files in sandbox\addons\<id> (renewing them: docs/toolchains.md). */
2
+ export const PERPLEXITY_MCP_VERSION = '1.3.0';
3
+ export const COMET_MCP_VERSION = '2.3.0';
4
+ export const CHROME_DEVTOOLS_MCP_VERSION = '1.12.0';
5
+ export const BROWSER_USE_VERSION = '0.13.14';
6
+ /** Perplexity Computer's official MCP server (HTTP; OAuth with your Perplexity account; uses Computer credits). */
7
+ export const PERPLEXITY_COMPUTER_MCP_URL = 'https://www.perplexity.ai/rest/computer/mcp';
8
+ /** Comet's Windows installer: a redirect to the current release (no checksum is published; its signer is checked). */
9
+ export const COMET_DOWNLOAD_URL = 'https://www.perplexity.ai/rest/browser/download?platform=win_x64&channel=stable';
10
+ /** Who signs Comet: Perplexity AI, Inc., with an EV code-signing certificate from GlobalSign. */
11
+ export const COMET_SIGNER = {
12
+ subject: ['^CN="?PERPLEXITY AI, INC\\.?"?(,|$)', '(^|, )O="?PERPLEXITY AI, INC\\.?"?(,|$)'],
13
+ issuer: ['^CN=GlobalSign GCC R45 EV CodeSigning CA 2020(,|$)'],
14
+ };
15
+ /** Microsoft Edge, already in every sandbox: the browser Chrome DevTools MCP starts. */
16
+ const EDGE_EXE = 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe';
17
+ export const AGENTS_WEB_APPS = [
18
+ {
19
+ id: 'perplexity-mcp',
20
+ name: 'Perplexity MCP (API)',
21
+ category: 'agents',
22
+ about: "Web search, answers and deep research from Perplexity's API in Claude Code and Codex (perplexity_search, perplexity_ask, perplexity_research, perplexity_reason): Perplexity's own @perplexity-ai/mcp-server. Needs your Perplexity API key in Accounts; API use is billed separately from Perplexity Pro.",
23
+ size: '30 MB',
24
+ source: { locked: 'npm', package: '@perplexity-ai/mcp-server', version: PERPLEXITY_MCP_VERSION },
25
+ exe: 'perplexity-mcp.cmd',
26
+ service: true,
27
+ mcp: {
28
+ name: 'sbx-perplexity',
29
+ script: 'node_modules/@perplexity-ai/mcp-server/dist/index.js',
30
+ envVars: ['PERPLEXITY_API_KEY'],
31
+ codex: true,
32
+ },
33
+ plugsInto: 'Claude Code and Codex as the MCP server sbx-perplexity; the key comes from Accounts as PERPLEXITY_API_KEY, never from a file',
34
+ userOnly: true,
35
+ },
36
+ {
37
+ id: 'perplexity-computer-mcp',
38
+ name: 'Perplexity Computer MCP',
39
+ category: 'agents',
40
+ about: "Hands tasks to Perplexity Computer, Perplexity's cloud agent (it browses and works in its own cloud computer), from Claude Code and Codex: Perplexity's official remote MCP server. Nothing is installed. Sign in with your Perplexity account the first time (Claude Code: /mcp; Codex: codex mcp login sbx-perplexity-computer); tasks spend your Computer credits.",
41
+ size: '0 MB',
42
+ source: { remote: true },
43
+ exe: '',
44
+ service: true,
45
+ mcp: { name: 'sbx-perplexity-computer', url: PERPLEXITY_COMPUTER_MCP_URL, codex: true },
46
+ plugsInto: 'Claude Code and Codex as the remote MCP server sbx-perplexity-computer; its sign-in is kept with your agent login',
47
+ userOnly: true,
48
+ },
49
+ {
50
+ id: 'comet',
51
+ name: 'Comet (Perplexity browser)',
52
+ category: 'browsers',
53
+ about: "Perplexity's agentic browser (Chromium), unpacked to run portable with its own profile on the sandbox's disk. With accounts.comet.share on, your perplexity.ai sign-in is kept for the next sandboxes. Its assistant acts on the pages it reads, so a page can try to steer it: browse only what you would let it act on.",
54
+ size: '600 MB',
55
+ source: { resolve: 'comet' },
56
+ unpack: 'chromium',
57
+ exe: 'comet.exe',
58
+ needs: ['7zip'],
59
+ signer: COMET_SIGNER,
60
+ userOnly: true,
61
+ },
62
+ {
63
+ id: 'comet-mcp',
64
+ name: 'Comet MCP',
65
+ category: 'agents',
66
+ about: "Lets Claude Code and Codex hand web tasks to Comet's own assistant and read its answers (hanzili/comet-mcp). Needs the Comet app: start Comet from its shortcut first, so the agent uses the sandbox's Comet profile and your sign-in.",
67
+ size: '15 MB',
68
+ source: { locked: 'npm', package: 'comet-mcp', version: COMET_MCP_VERSION },
69
+ exe: 'comet-mcp.cmd',
70
+ service: true,
71
+ mcp: { name: 'sbx-comet', script: 'node_modules/comet-mcp/dist/index.js', codex: true },
72
+ plugsInto: "Claude Code and Codex as the MCP server sbx-comet, talking to Comet's DevTools on 127.0.0.1:9222",
73
+ userOnly: true,
74
+ },
75
+ {
76
+ id: 'chrome-devtools-mcp',
77
+ name: 'Chrome DevTools MCP',
78
+ category: 'agents',
79
+ about: "Lets Claude Code and Codex drive and inspect a browser with DevTools: navigate, click, read the console and network, record performance traces (ChromeDevTools/chrome-devtools-mcp). It starts Microsoft Edge with a throwaway profile; Google's usage statistics and CrUX lookups are off.",
80
+ size: '40 MB',
81
+ source: { locked: 'npm', package: 'chrome-devtools-mcp', version: CHROME_DEVTOOLS_MCP_VERSION },
82
+ exe: 'chrome-devtools-mcp.cmd',
83
+ service: true,
84
+ mcp: {
85
+ name: 'sbx-chrome-devtools',
86
+ script: 'node_modules/chrome-devtools-mcp/build/src/bin/chrome-devtools-mcp.js',
87
+ args: ['--executablePath', EDGE_EXE, '--isolated', '--no-usage-statistics', '--no-performance-crux'],
88
+ codex: true,
89
+ },
90
+ plugsInto: 'Claude Code and Codex as the MCP server sbx-chrome-devtools (with Edge)',
91
+ userOnly: true,
92
+ },
93
+ {
94
+ id: 'browser-use-mcp',
95
+ name: 'Browser Use MCP',
96
+ category: 'agents',
97
+ about: "Browser automation for agents from Browser Use (browser-use --mcp): open pages, click, type, read them, and hand a whole task to Browser Use's own agent (that one needs an OpenAI or Anthropic API key). It finds Edge in the sandbox; its telemetry is off.",
98
+ size: '250 MB',
99
+ source: { locked: 'uv', package: 'browser-use', version: BROWSER_USE_VERSION },
100
+ exe: 'browser-use.exe',
101
+ service: true,
102
+ mcp: {
103
+ name: 'sbx-browser-use',
104
+ program: true,
105
+ args: ['--mcp'],
106
+ env: { ANONYMIZED_TELEMETRY: 'false' },
107
+ codex: true,
108
+ },
109
+ plugsInto: 'Claude Code and Codex as the MCP server sbx-browser-use',
110
+ userOnly: true,
111
+ },
112
+ ];
@@ -1 +1,32 @@
1
- export const MODDING_APPS = [];
1
+ export const MODDING_APPS = [
2
+ {
3
+ id: 'lua-language-server',
4
+ name: 'Lua Language Server',
5
+ category: 'cli',
6
+ about: 'The Lua language server (LuaLS): completion, diagnostics and go-to-definition for Lua in editors and agents that speak LSP. FiveM resources use Lua 5.4 (lua54 in fxmanifest.lua).',
7
+ size: '15 MB',
8
+ source: { github: 'LuaLS/lua-language-server', asset: '^lua-language-server-[\\d.]+-win32-x64\\.zip$' },
9
+ exe: 'lua-language-server.exe',
10
+ cli: true,
11
+ },
12
+ {
13
+ id: 'stylua',
14
+ name: 'StyLua',
15
+ category: 'cli',
16
+ about: 'An opinionated Lua formatter (`stylua .`), configured with a stylua.toml in the project.',
17
+ size: '6 MB',
18
+ source: { github: 'JohnnyMorganz/StyLua', asset: '^stylua-windows-x86_64\\.zip$' },
19
+ exe: 'stylua.exe',
20
+ cli: true,
21
+ },
22
+ {
23
+ id: 'selene',
24
+ name: 'selene',
25
+ category: 'cli',
26
+ about: 'A Lua linter (`selene .`), configured with a selene.toml (std = "lua54", and a standard library file for the FiveM / RedM globals).',
27
+ size: '7 MB',
28
+ source: { github: 'Kampfkarren/selene', asset: '^selene-[\\d.]+-windows\\.zip$' },
29
+ exe: 'selene.exe',
30
+ cli: true,
31
+ },
32
+ ];