auvrynt 1.0.2 → 1.0.5

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 (550) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +366 -233
  3. package/addons/auvrynt_bridge/auvrynt_bridge.gd +500 -0
  4. package/addons/auvrynt_bridge/plugin.cfg +7 -0
  5. package/bin/auvrynt-launcher.cjs +77 -0
  6. package/dist/artifact-registry.js +1 -0
  7. package/dist/aseprite-tools.js +1 -0
  8. package/dist/auth/connection-registry.js +145 -0
  9. package/dist/auth/connection-status.js +176 -0
  10. package/dist/auth/oauth-provider.js +617 -0
  11. package/dist/auth/room-registry.js +131 -0
  12. package/dist/auth/session-registry.js +531 -0
  13. package/dist/background-lifecycle.js +1 -0
  14. package/dist/blender-client.js +1 -109
  15. package/dist/blender-tools.js +1 -930
  16. package/dist/browser-stability.js +1 -0
  17. package/dist/cli/commands/help-command.js +10 -0
  18. package/dist/cli/commands/init-command.js +190 -0
  19. package/dist/cli/commands/integration-commands.js +88 -0
  20. package/dist/cli/commands/serve-command.js +83 -0
  21. package/dist/cli/commands/setup-command.js +81 -0
  22. package/dist/cli/commands/status-commands.js +166 -0
  23. package/dist/cli/commands/tunnel-command.js +127 -0
  24. package/dist/cli/commands/user-config-commands.js +105 -0
  25. package/dist/cli/dashboard-actions.js +516 -0
  26. package/dist/cli/dashboard-native-actions.js +282 -0
  27. package/dist/cli/foreground-server.js +270 -0
  28. package/dist/cli/instance-control.js +21 -0
  29. package/dist/cli/instance-lock.js +123 -0
  30. package/dist/cli/integration-bootstrap.js +206 -0
  31. package/dist/cli/lifecycle-manager.js +493 -0
  32. package/dist/cli/runtime-support.js +74 -0
  33. package/dist/cli/serena-detected-default.js +27 -0
  34. package/dist/cli/tunnel-health-monitor.js +182 -0
  35. package/dist/cli.js +82 -739
  36. package/dist/config.js +1 -243
  37. package/dist/connection-registry.js +1 -73
  38. package/dist/connection-status.js +1 -139
  39. package/dist/control-retry.js +1 -0
  40. package/dist/crash-recovery.js +1 -0
  41. package/dist/db/client.js +16 -3
  42. package/dist/db/schema.js +30 -0
  43. package/dist/dotnet-tools.js +1 -223
  44. package/dist/git-worktrees.js +1 -134
  45. package/dist/git.js +1 -41
  46. package/dist/godot-animation-tilemap.js +1 -82
  47. package/dist/godot-csharp-build.js +1 -93
  48. package/dist/godot-csharp-project.js +1 -157
  49. package/dist/godot-csharp-runner.js +1 -146
  50. package/dist/godot-csharp-semantic.js +1 -161
  51. package/dist/godot-csharp-validate.js +1 -71
  52. package/dist/godot-dotnet-env.js +1 -169
  53. package/dist/godot-editor-bridge.js +1 -140
  54. package/dist/godot-gdscript.js +1 -824
  55. package/dist/godot-project-settings.js +1 -223
  56. package/dist/godot-runtime-testing.js +1 -249
  57. package/dist/godot-tools.js +1 -183
  58. package/dist/http-rate-limit.js +1 -0
  59. package/dist/http-server-hardening.js +1 -0
  60. package/dist/image-tools.js +1 -157
  61. package/dist/infrastructure/command-reference.js +32 -0
  62. package/dist/infrastructure/config.js +424 -0
  63. package/dist/infrastructure/context7-auth.js +55 -0
  64. package/dist/infrastructure/http-rate-limit.js +42 -0
  65. package/dist/infrastructure/http-server-hardening.js +23 -0
  66. package/dist/infrastructure/integration-queue.js +46 -0
  67. package/dist/infrastructure/logger.js +129 -0
  68. package/dist/infrastructure/mcp-event-store.js +103 -0
  69. package/dist/infrastructure/ngrok-auth-pool.js +208 -0
  70. package/dist/infrastructure/request-context.js +14 -0
  71. package/dist/infrastructure/shutdown.js +37 -0
  72. package/dist/infrastructure/sse-heartbeat.js +47 -0
  73. package/dist/infrastructure/tool-capabilities.js +67 -0
  74. package/dist/infrastructure/tool-result-budget.js +175 -0
  75. package/dist/infrastructure/user-config.js +167 -0
  76. package/dist/integration-discovery.js +1 -98
  77. package/dist/integration-queue.js +1 -0
  78. package/dist/integrations/agent-reach/agent-reach-tools.js +196 -0
  79. package/dist/integrations/agent-reach/native-channels.js +468 -0
  80. package/dist/integrations/aseprite/aseprite-analysis-tools.js +368 -0
  81. package/dist/integrations/aseprite/aseprite-editing-tools.js +647 -0
  82. package/dist/integrations/aseprite/aseprite-live-tools.js +297 -0
  83. package/dist/integrations/aseprite/aseprite-safety-tools.js +594 -0
  84. package/dist/integrations/aseprite/aseprite-specialized-tools.js +289 -0
  85. package/dist/integrations/aseprite/aseprite-tools.js +837 -0
  86. package/dist/integrations/blender/blender-catalog-mesh.js +593 -0
  87. package/dist/integrations/blender/blender-catalog-object.js +906 -0
  88. package/dist/integrations/blender/blender-catalog-scene.js +266 -0
  89. package/dist/integrations/blender/blender-catalog-select.js +581 -0
  90. package/dist/integrations/blender/blender-catalog-stubs.js +7512 -0
  91. package/dist/integrations/blender/blender-catalog.js +165 -0
  92. package/dist/integrations/blender/blender-client.js +105 -0
  93. package/dist/integrations/blender/blender-tools.js +2243 -0
  94. package/dist/integrations/context7/context7-tools.js +106 -0
  95. package/dist/integrations/dotnet/dotnet-tools.js +195 -0
  96. package/dist/integrations/godot/godot-animation-tilemap.js +74 -0
  97. package/dist/integrations/godot/godot-csharp-build.js +91 -0
  98. package/dist/integrations/godot/godot-csharp-project.js +155 -0
  99. package/dist/integrations/godot/godot-csharp-runner.js +118 -0
  100. package/dist/integrations/godot/godot-csharp-semantic.js +146 -0
  101. package/dist/integrations/godot/godot-csharp-validate.js +71 -0
  102. package/dist/integrations/godot/godot-dotnet-env.js +134 -0
  103. package/dist/integrations/godot/godot-editor-bridge.js +328 -0
  104. package/dist/integrations/godot/godot-gdscript.js +536 -0
  105. package/dist/integrations/godot/godot-project-settings.js +178 -0
  106. package/dist/integrations/godot/godot-runtime-testing.js +263 -0
  107. package/dist/integrations/godot/godot-tools.js +193 -0
  108. package/dist/integrations/images/image-tools.js +414 -0
  109. package/dist/integrations/images/png-codec.js +251 -0
  110. package/dist/integrations/images/view-image.js +99 -0
  111. package/dist/integrations/images/window-capture.js +148 -0
  112. package/dist/integrations/integration-discovery.js +185 -0
  113. package/dist/integrations/obsidian/obsidian-tools.js +205 -0
  114. package/dist/integrations/playwright/browser-session.js +516 -0
  115. package/dist/integrations/playwright/browser-stability.js +36 -0
  116. package/dist/integrations/playwright/playwright-runtime.js +105 -0
  117. package/dist/integrations/playwright/web-tools.js +504 -0
  118. package/dist/integrations/roblox/roblox-helpers.js +381 -0
  119. package/dist/integrations/roblox/roblox-studio-client.js +112 -0
  120. package/dist/integrations/roblox/roblox-tools.js +106 -0
  121. package/dist/integrations/serena/serena-manager.js +464 -0
  122. package/dist/integrations/serena/serena-tools.js +411 -0
  123. package/dist/logger.js +1 -76
  124. package/dist/mcp-event-store.js +1 -0
  125. package/dist/oauth-provider.js +1 -377
  126. package/dist/pi-tools.js +1 -81
  127. package/dist/playwright-runtime.js +1 -0
  128. package/dist/process/background-lifecycle.js +189 -0
  129. package/dist/process/control-retry.js +42 -0
  130. package/dist/process/crash-recovery.js +23 -0
  131. package/dist/process/processes.js +456 -0
  132. package/dist/processes.js +1 -218
  133. package/dist/request-context.js +1 -0
  134. package/dist/review-checkpoints.js +1 -142
  135. package/dist/room-registry.js +1 -0
  136. package/dist/roots.js +1 -53
  137. package/dist/search-discovery.js +1 -271
  138. package/dist/serena-manager.js +1 -443
  139. package/dist/serena-tools.js +1 -411
  140. package/dist/server/dashboard-page-styles.js +331 -0
  141. package/dist/server/dashboard-page.js +1509 -0
  142. package/dist/server/dashboard-routes.js +46 -0
  143. package/dist/server/dashboard.js +240 -0
  144. package/dist/server/http-helpers.js +30 -0
  145. package/dist/server/integration-profile-update.js +37 -0
  146. package/dist/server/mcp-policy.js +169 -0
  147. package/dist/server/mcp-server-factory.js +127 -0
  148. package/dist/server/mcp-tool-registrar.js +182 -0
  149. package/dist/server/openai-session-hint.js +14 -0
  150. package/dist/server/tool-groups.js +29 -0
  151. package/dist/server/tool-logging.js +33 -0
  152. package/dist/server/tool-registration-shared.js +59 -0
  153. package/dist/server/tools/aseprite-advanced-tools-registration.js +547 -0
  154. package/dist/server/tools/aseprite-tools-registration.js +213 -0
  155. package/dist/server/tools/blender-tools-registration.js +690 -0
  156. package/dist/server/tools/core-file-tools-registration.js +459 -0
  157. package/dist/server/tools/dotnet-godot-window-tools-registration.js +120 -0
  158. package/dist/server/tools/godot-csharp-tools-registration.js +252 -0
  159. package/dist/server/tools/godot-gdscript-tools-registration.js +189 -0
  160. package/dist/server/tools/process-project-tools-registration.js +155 -0
  161. package/dist/server/tools/roblox-tools-registration.js +514 -0
  162. package/dist/server/tools/web-image-tools-registration.js +326 -0
  163. package/dist/server/tools/workspace-lifecycle-tools-registration.js +130 -0
  164. package/dist/server/ui-assets.js +97 -0
  165. package/dist/server/workspace-analytics.js +92 -0
  166. package/dist/server.js +453 -2713
  167. package/dist/session-registry.js +1 -0
  168. package/dist/shutdown.js +1 -0
  169. package/dist/skills.js +1 -45
  170. package/dist/sse-heartbeat.js +1 -0
  171. package/dist/tool-capabilities.js +1 -0
  172. package/dist/tool-result-budget.js +1 -0
  173. package/dist/tools/pi-tools.js +81 -0
  174. package/dist/tunnels/cloudflare-tunnel.js +217 -0
  175. package/dist/tunnels/cloudflared-service.js +174 -0
  176. package/dist/tunnels/ngrok-tunnel.js +220 -0
  177. package/dist/tunnels/tunnel-manager.js +186 -0
  178. package/dist/tunnels/tunnel-types.js +1 -0
  179. package/dist/tunnels/tunnel-utils.js +62 -0
  180. package/dist/ui/.vite/manifest.json +9 -2487
  181. package/dist/ui/assets/heavy-payload-D42A9ceL.js +1 -0
  182. package/dist/ui/assets/lightweight-diff-Cv4g9Hdr.js +13 -0
  183. package/dist/ui/assets/review-payload-DKIg1cKF.js +1 -0
  184. package/dist/ui/assets/workspace-app-CeK3NhmB.css +1 -0
  185. package/dist/ui/assets/{workspace-app-C5QsE314.js → workspace-app-CkUXnpl4.js} +6 -6
  186. package/dist/ui/brand-theme.js +23 -0
  187. package/dist/ui/workspace-app.html +15 -15
  188. package/dist/user-config.js +1 -57
  189. package/dist/view-image.js +1 -104
  190. package/dist/web-tools.js +1 -200
  191. package/dist/window-capture.js +1 -74
  192. package/dist/workspace/artifact-registry.js +69 -0
  193. package/dist/workspace/git-worktrees.js +141 -0
  194. package/dist/workspace/git.js +42 -0
  195. package/dist/workspace/review-checkpoints.js +142 -0
  196. package/dist/workspace/roots.js +56 -0
  197. package/dist/workspace/search-discovery.js +264 -0
  198. package/dist/workspace/skills.js +45 -0
  199. package/dist/workspace/workspace-store.js +219 -0
  200. package/dist/workspace/workspaces.js +314 -0
  201. package/dist/workspace-store.js +1 -125
  202. package/dist/workspaces.js +1 -226
  203. package/docs/CREATOR_STORE_FREE_ASSETS.md +162 -0
  204. package/docs/DEVELOPMENT_TOOLS.md +136 -93
  205. package/docs/assets/auvrynt-icon.png +0 -0
  206. package/docs/assets/auvrynt-icon.svg +20 -0
  207. package/docs/chatgpt-coding-workflow.md +143 -143
  208. package/docs/configuration.md +156 -124
  209. package/docs/diagnostics.md +79 -0
  210. package/docs/gotchas.md +244 -202
  211. package/docs/multi-agent-and-long-projects.md +91 -0
  212. package/docs/security.md +138 -100
  213. package/docs/setup.md +171 -131
  214. package/docs/source-layout.md +60 -0
  215. package/extensions/auvrynt_bridge/auvrynt_bridge.lua +594 -0
  216. package/extensions/auvrynt_bridge/live_analysis.lua +181 -0
  217. package/extensions/auvrynt_bridge/live_animation.lua +134 -0
  218. package/extensions/auvrynt_bridge/live_commands.lua +24 -0
  219. package/extensions/auvrynt_bridge/live_common.lua +130 -0
  220. package/extensions/auvrynt_bridge/live_document.lua +78 -0
  221. package/extensions/auvrynt_bridge/live_drawing.lua +125 -0
  222. package/extensions/auvrynt_bridge/live_effects.lua +91 -0
  223. package/extensions/auvrynt_bridge/live_palette_template.lua +167 -0
  224. package/extensions/auvrynt_bridge/live_selection.lua +110 -0
  225. package/extensions/auvrynt_bridge/live_structure.lua +129 -0
  226. package/extensions/auvrynt_bridge/package.json +17 -0
  227. package/guides/ASEPRITE_AGENT_GUIDE.md +133 -0
  228. package/guides/BLENDER_AGENT_GUIDE.md +472 -0
  229. package/guides/GODOT_AGENT_GUIDE.md +298 -0
  230. package/guides/PROJECT_ROUTER.md +165 -0
  231. package/guides/ROBLOX_AGENT_GUIDE.md +75 -0
  232. package/guides/SOFTWARE_AGENT_GUIDE.md +104 -0
  233. package/guides/WEB_AGENT_GUIDE.md +287 -0
  234. package/package.json +78 -70
  235. package/scripts/dev-server.mjs +121 -120
  236. package/scripts/live-tunnel-smoke.mjs +538 -0
  237. package/scripts/repo-hygiene.mjs +74 -0
  238. package/scripts/restart-after-crash.mjs +49 -0
  239. package/scripts/run-tests.mjs +166 -0
  240. package/dist/ui/assets/abap-CLvhMVsD.js +0 -1
  241. package/dist/ui/assets/actionscript-3--17pq3dv.js +0 -1
  242. package/dist/ui/assets/ada-C5qYipkI.js +0 -1
  243. package/dist/ui/assets/andromeeda-vGVdxbeo.js +0 -1
  244. package/dist/ui/assets/angular-html-BJqQFYI6.js +0 -1
  245. package/dist/ui/assets/angular-ts-CMJECO0Y.js +0 -1
  246. package/dist/ui/assets/apache-U0d_L8uA.js +0 -1
  247. package/dist/ui/assets/apex-CGTLDQj6.js +0 -1
  248. package/dist/ui/assets/apl-DWeXpBBr.js +0 -1
  249. package/dist/ui/assets/applescript-CCn79oCD.js +0 -1
  250. package/dist/ui/assets/ara-4CJ0cIlV.js +0 -1
  251. package/dist/ui/assets/asciidoc-DE70LPWp.js +0 -1
  252. package/dist/ui/assets/asm-Cmm7eHzH.js +0 -1
  253. package/dist/ui/assets/astro-CLbttLOq.js +0 -1
  254. package/dist/ui/assets/aurora-x-CDeNXAV0.js +0 -1
  255. package/dist/ui/assets/awk-BWXHIvNe.js +0 -1
  256. package/dist/ui/assets/ayu-dark-DluEY0Gj.js +0 -1
  257. package/dist/ui/assets/ayu-light-C3h-C4tm.js +0 -1
  258. package/dist/ui/assets/ayu-mirage-Bqwy1Gya.js +0 -1
  259. package/dist/ui/assets/ballerina-B7ZEbQpA.js +0 -1
  260. package/dist/ui/assets/bat-Bo4NYOV-.js +0 -1
  261. package/dist/ui/assets/beancount-D-usSTwE.js +0 -1
  262. package/dist/ui/assets/berry-DKpUyyne.js +0 -1
  263. package/dist/ui/assets/bibtex-Ci_nEsc7.js +0 -1
  264. package/dist/ui/assets/bicep-CUHmPFLl.js +0 -1
  265. package/dist/ui/assets/bird2-C2hNVINV.js +0 -1
  266. package/dist/ui/assets/blade-BOzY0P2V.js +0 -1
  267. package/dist/ui/assets/bsl-BkkzgIyY.js +0 -1
  268. package/dist/ui/assets/c-BG-8uJvh.js +0 -1
  269. package/dist/ui/assets/c3-CnJL0r0V.js +0 -1
  270. package/dist/ui/assets/cadence-CQ2zXKGN.js +0 -1
  271. package/dist/ui/assets/cairo-DLTphjLi.js +0 -1
  272. package/dist/ui/assets/catppuccin-frappe-3VR1Za6u.js +0 -1
  273. package/dist/ui/assets/catppuccin-latte-DwIHMF0Q.js +0 -1
  274. package/dist/ui/assets/catppuccin-macchiato-DYnBP6_5.js +0 -1
  275. package/dist/ui/assets/catppuccin-mocha-DYhrFGRu.js +0 -1
  276. package/dist/ui/assets/clarity-SemFz856.js +0 -1
  277. package/dist/ui/assets/clojure-DqKBuwfJ.js +0 -1
  278. package/dist/ui/assets/cmake-Bj61d0ZC.js +0 -1
  279. package/dist/ui/assets/cobol-I_17IuGe.js +0 -1
  280. package/dist/ui/assets/codeowners-C8r90Shi.js +0 -1
  281. package/dist/ui/assets/codeql-oeQT6MSM.js +0 -1
  282. package/dist/ui/assets/coffee-C0B8hmok.js +0 -1
  283. package/dist/ui/assets/common-lisp-Cv5bFMCO.js +0 -1
  284. package/dist/ui/assets/coq-BrsZFFmf.js +0 -1
  285. package/dist/ui/assets/cpp-DDJXt6Vs.js +0 -1
  286. package/dist/ui/assets/crystal-Bexqace6.js +0 -1
  287. package/dist/ui/assets/csharp-Ct8U2NOr.js +0 -1
  288. package/dist/ui/assets/css-DSQhw_9R.js +0 -1
  289. package/dist/ui/assets/csv-Dx-8-gkx.js +0 -1
  290. package/dist/ui/assets/cue-CE9AQfxI.js +0 -1
  291. package/dist/ui/assets/cypher-ClKdZ_lG.js +0 -1
  292. package/dist/ui/assets/d-qD-0Kul2.js +0 -1
  293. package/dist/ui/assets/dark-plus-Cs2F2srj.js +0 -1
  294. package/dist/ui/assets/dart-DkHntEIa.js +0 -1
  295. package/dist/ui/assets/dax-BkyTk9wS.js +0 -1
  296. package/dist/ui/assets/desktop-Dlh5hvp9.js +0 -1
  297. package/dist/ui/assets/diff-woXpYk--.js +0 -1
  298. package/dist/ui/assets/docker-IyjqRm3v.js +0 -1
  299. package/dist/ui/assets/dotenv-_5a1GRtc.js +0 -1
  300. package/dist/ui/assets/dracula-BHWKrbxM.js +0 -1
  301. package/dist/ui/assets/dracula-soft-5eyTD99u.js +0 -1
  302. package/dist/ui/assets/dream-maker-DW3nJb8Q.js +0 -1
  303. package/dist/ui/assets/edge-Z8YYkHOr.js +0 -1
  304. package/dist/ui/assets/elixir-CG9uKtAF.js +0 -1
  305. package/dist/ui/assets/elm-GfWG2IfT.js +0 -1
  306. package/dist/ui/assets/emacs-lisp-C9PiwqqW.js +0 -1
  307. package/dist/ui/assets/erb-xe89e73J.js +0 -1
  308. package/dist/ui/assets/erlang-Cphh6RMH.js +0 -1
  309. package/dist/ui/assets/everforest-dark-sB-x3p7T.js +0 -1
  310. package/dist/ui/assets/everforest-light-Df2xbC6M.js +0 -1
  311. package/dist/ui/assets/fennel-DQxkIbk2.js +0 -1
  312. package/dist/ui/assets/fish-BJitypiv.js +0 -1
  313. package/dist/ui/assets/fluent-C03EYrpw.js +0 -1
  314. package/dist/ui/assets/fortran-fixed-form-DEKoE2YW.js +0 -1
  315. package/dist/ui/assets/fortran-free-form-CYNrtFtB.js +0 -1
  316. package/dist/ui/assets/fsharp-D13ZGOAj.js +0 -1
  317. package/dist/ui/assets/gdresource-C0sCabJj.js +0 -1
  318. package/dist/ui/assets/gdscript-Cp2uCuqX.js +0 -1
  319. package/dist/ui/assets/gdshader-CBce3t8t.js +0 -1
  320. package/dist/ui/assets/genie-CV2tkWYe.js +0 -1
  321. package/dist/ui/assets/gherkin-DExj1W_8.js +0 -1
  322. package/dist/ui/assets/git-commit-BSykSTBG.js +0 -1
  323. package/dist/ui/assets/git-rebase-CoTL_uSE.js +0 -1
  324. package/dist/ui/assets/github-dark-C-LZuMrd.js +0 -1
  325. package/dist/ui/assets/github-dark-default-DXG-b-1a.js +0 -1
  326. package/dist/ui/assets/github-dark-dimmed-Bx1FflLF.js +0 -1
  327. package/dist/ui/assets/github-dark-high-contrast-B_tTalzw.js +0 -1
  328. package/dist/ui/assets/github-light-EUqPIrTm.js +0 -1
  329. package/dist/ui/assets/github-light-default-BXViO-2h.js +0 -1
  330. package/dist/ui/assets/github-light-high-contrast-B68TUdTA.js +0 -1
  331. package/dist/ui/assets/gleam-CSRkHgEL.js +0 -1
  332. package/dist/ui/assets/glimmer-js-DAn4UCSu.js +0 -1
  333. package/dist/ui/assets/glimmer-ts-Tjyi6Gh5.js +0 -1
  334. package/dist/ui/assets/glsl-CtTDZoqR.js +0 -1
  335. package/dist/ui/assets/gn-ilITqXS6.js +0 -1
  336. package/dist/ui/assets/gnuplot-7GGW24-e.js +0 -1
  337. package/dist/ui/assets/go-BJwz_mda.js +0 -1
  338. package/dist/ui/assets/graphql-D5gcC_Jk.js +0 -1
  339. package/dist/ui/assets/groovy-CacY0gHj.js +0 -1
  340. package/dist/ui/assets/gruvbox-dark-hard-C820rvS2.js +0 -1
  341. package/dist/ui/assets/gruvbox-dark-medium-BPjhmG05.js +0 -1
  342. package/dist/ui/assets/gruvbox-dark-soft-MrdJrrXF.js +0 -1
  343. package/dist/ui/assets/gruvbox-light-hard-BC_s9l72.js +0 -1
  344. package/dist/ui/assets/gruvbox-light-medium-BAWPOn9u.js +0 -1
  345. package/dist/ui/assets/gruvbox-light-soft-BSMLrYjP.js +0 -1
  346. package/dist/ui/assets/hack-BJXY27dt.js +0 -1
  347. package/dist/ui/assets/haml-BLfFoZf7.js +0 -1
  348. package/dist/ui/assets/handlebars-Dw6CWkvN.js +0 -1
  349. package/dist/ui/assets/haskell-D8IpX4py.js +0 -1
  350. package/dist/ui/assets/haxe-OTjmBuCE.js +0 -1
  351. package/dist/ui/assets/hcl-Dh228itO.js +0 -1
  352. package/dist/ui/assets/heavy-payload-Dcg0-F-S.js +0 -4
  353. package/dist/ui/assets/hjson-CxZEssPk.js +0 -1
  354. package/dist/ui/assets/hlsl-Cvrh5tZx.js +0 -1
  355. package/dist/ui/assets/horizon-CE9ld1lL.js +0 -1
  356. package/dist/ui/assets/horizon-bright-Br1oVSNq.js +0 -1
  357. package/dist/ui/assets/houston-CsvMBhTu.js +0 -1
  358. package/dist/ui/assets/html-CAcAWvoN.js +0 -1
  359. package/dist/ui/assets/html-derivative-8aSW2E_7.js +0 -1
  360. package/dist/ui/assets/http-B2YR_3V1.js +0 -1
  361. package/dist/ui/assets/hurl-BnDJ9Zhf.js +0 -1
  362. package/dist/ui/assets/hxml-B0Qn7Nwc.js +0 -1
  363. package/dist/ui/assets/hy-CZbG8q4J.js +0 -1
  364. package/dist/ui/assets/imba-DsUTQ-LC.js +0 -1
  365. package/dist/ui/assets/ini-B5eOa1yu.js +0 -1
  366. package/dist/ui/assets/java-Doxi4W8u.js +0 -1
  367. package/dist/ui/assets/javascript-BbRdEqti.js +0 -1
  368. package/dist/ui/assets/jinja-CS3Tpv_Q.js +0 -1
  369. package/dist/ui/assets/jison-BkPGYVHR.js +0 -1
  370. package/dist/ui/assets/json-BMt1m3m8.js +0 -1
  371. package/dist/ui/assets/json5-BR5RXkoi.js +0 -1
  372. package/dist/ui/assets/jsonc-CYpm1nAK.js +0 -1
  373. package/dist/ui/assets/jsonl-CmCQp5Yx.js +0 -1
  374. package/dist/ui/assets/jsonnet-CJTPZ8u_.js +0 -1
  375. package/dist/ui/assets/jssm-DXw9l8Rf.js +0 -1
  376. package/dist/ui/assets/jsx-CQKrJXXY.js +0 -1
  377. package/dist/ui/assets/julia-BuN7i2du.js +0 -1
  378. package/dist/ui/assets/just-BswEPFPu.js +0 -1
  379. package/dist/ui/assets/kanagawa-dragon-CXtmUGW6.js +0 -1
  380. package/dist/ui/assets/kanagawa-lotus-BN08jTvb.js +0 -1
  381. package/dist/ui/assets/kanagawa-wave-CTweb8Dz.js +0 -1
  382. package/dist/ui/assets/kdl-CsD5j6eV.js +0 -1
  383. package/dist/ui/assets/kotlin-DhhofPvG.js +0 -1
  384. package/dist/ui/assets/kusto-BUv0MjJC.js +0 -1
  385. package/dist/ui/assets/laserwave-C_8bwKvT.js +0 -1
  386. package/dist/ui/assets/latex-DU2VyFfA.js +0 -1
  387. package/dist/ui/assets/lean-CewbzKMR.js +0 -1
  388. package/dist/ui/assets/less-DVTAwKKz.js +0 -1
  389. package/dist/ui/assets/light-plus-DVQuIRkW.js +0 -1
  390. package/dist/ui/assets/liquid-Cmz1L3dq.js +0 -1
  391. package/dist/ui/assets/llvm-Cm23YOpf.js +0 -1
  392. package/dist/ui/assets/log-BNLmms1o.js +0 -1
  393. package/dist/ui/assets/logo-Cluzi2Zq.js +0 -1
  394. package/dist/ui/assets/lua-CfVXhkaJ.js +0 -1
  395. package/dist/ui/assets/luau-CNKltnaQ.js +0 -1
  396. package/dist/ui/assets/make-Dixweg8N.js +0 -1
  397. package/dist/ui/assets/markdown-BYOwaDjH.js +0 -1
  398. package/dist/ui/assets/marko-C5bfqGiA.js +0 -1
  399. package/dist/ui/assets/material-theme-Bm3Qr25_.js +0 -1
  400. package/dist/ui/assets/material-theme-darker-2IIEA8gg.js +0 -1
  401. package/dist/ui/assets/material-theme-lighter-uhdI0v04.js +0 -1
  402. package/dist/ui/assets/material-theme-ocean-CHQ94UKr.js +0 -1
  403. package/dist/ui/assets/material-theme-palenight-B5W6OYN7.js +0 -1
  404. package/dist/ui/assets/matlab-D7qyCx1q.js +0 -1
  405. package/dist/ui/assets/mdc-CVBXYfyq.js +0 -1
  406. package/dist/ui/assets/mdx-DQZ5AkYe.js +0 -1
  407. package/dist/ui/assets/mermaid-Bk4SNUv9.js +0 -1
  408. package/dist/ui/assets/min-dark-BSWPekZh.js +0 -1
  409. package/dist/ui/assets/min-light-DDpmG2fV.js +0 -1
  410. package/dist/ui/assets/mipsasm-BMqwQI7S.js +0 -1
  411. package/dist/ui/assets/mojo-BgCJLMeH.js +0 -1
  412. package/dist/ui/assets/monokai-CdkpiU2Y.js +0 -1
  413. package/dist/ui/assets/moonbit-CaWjb8XO.js +0 -1
  414. package/dist/ui/assets/move-B1IS1UjX.js +0 -1
  415. package/dist/ui/assets/narrat-_X_XdTYD.js +0 -1
  416. package/dist/ui/assets/nextflow-Bbiyy34d.js +0 -1
  417. package/dist/ui/assets/nextflow-groovy-Dc_ddanL.js +0 -1
  418. package/dist/ui/assets/nginx-CzJafxLa.js +0 -1
  419. package/dist/ui/assets/night-owl-DhmEMT88.js +0 -1
  420. package/dist/ui/assets/night-owl-light-eJ-hLW7d.js +0 -1
  421. package/dist/ui/assets/nim-DABKtHtM.js +0 -1
  422. package/dist/ui/assets/nix-IvuFDN5E.js +0 -1
  423. package/dist/ui/assets/nord-Cb4Vim4T.js +0 -1
  424. package/dist/ui/assets/nushell-DcLAeLz5.js +0 -1
  425. package/dist/ui/assets/objective-c-D1A_Heim.js +0 -1
  426. package/dist/ui/assets/objective-cpp-BsSzOQcm.js +0 -1
  427. package/dist/ui/assets/ocaml-O90oeIOV.js +0 -1
  428. package/dist/ui/assets/odin-B1RWQWA5.js +0 -1
  429. package/dist/ui/assets/one-dark-pro-CLwyXe_n.js +0 -1
  430. package/dist/ui/assets/one-light-D7Lr4KcI.js +0 -1
  431. package/dist/ui/assets/openscad-BUDT5pXO.js +0 -1
  432. package/dist/ui/assets/pascal-4ZHwLPI5.js +0 -1
  433. package/dist/ui/assets/perl-CBh7L3lZ.js +0 -1
  434. package/dist/ui/assets/php-DFbI9q5p.js +0 -1
  435. package/dist/ui/assets/pierre-dark-sU4Zdns8.js +0 -1
  436. package/dist/ui/assets/pierre-dark-soft-HXgun5vs.js +0 -1
  437. package/dist/ui/assets/pierre-light-DWBk51d8.js +0 -1
  438. package/dist/ui/assets/pierre-light-soft-CodEzPxf.js +0 -1
  439. package/dist/ui/assets/pkl-ot-7Btpt.js +0 -1
  440. package/dist/ui/assets/plastic-DQwYfKfQ.js +0 -1
  441. package/dist/ui/assets/plsql-DGHpHOYJ.js +0 -1
  442. package/dist/ui/assets/po-BiJDBrnU.js +0 -1
  443. package/dist/ui/assets/poimandres-DRFjx7u4.js +0 -1
  444. package/dist/ui/assets/polar-C7UOKdEL.js +0 -1
  445. package/dist/ui/assets/postcss-BXeXVLqQ.js +0 -1
  446. package/dist/ui/assets/powerquery-DNMTfnFr.js +0 -1
  447. package/dist/ui/assets/powershell-DshXNtvi.js +0 -1
  448. package/dist/ui/assets/prisma-BsRQq5mF.js +0 -1
  449. package/dist/ui/assets/prolog-iXnhIJG7.js +0 -1
  450. package/dist/ui/assets/proto-DB4EqR-F.js +0 -1
  451. package/dist/ui/assets/pug-C_PxC7gO.js +0 -1
  452. package/dist/ui/assets/puppet-CDv2pdJW.js +0 -1
  453. package/dist/ui/assets/purescript-9MfHhQsQ.js +0 -1
  454. package/dist/ui/assets/python-gzcpVVnB.js +0 -1
  455. package/dist/ui/assets/qml-DtngoFFK.js +0 -1
  456. package/dist/ui/assets/qmldir-DCQb3MpD.js +0 -1
  457. package/dist/ui/assets/qss-Fe1Jh2GI.js +0 -1
  458. package/dist/ui/assets/r-DohkcevW.js +0 -1
  459. package/dist/ui/assets/racket-DcIDlBhZ.js +0 -1
  460. package/dist/ui/assets/raku-B3gFvitq.js +0 -1
  461. package/dist/ui/assets/razor-C4t8J0_E.js +0 -1
  462. package/dist/ui/assets/red-CJ3rzSJv.js +0 -1
  463. package/dist/ui/assets/reg-CRGYupPL.js +0 -1
  464. package/dist/ui/assets/regexp-OGbTbjgY.js +0 -1
  465. package/dist/ui/assets/rel-BtDbiS_P.js +0 -1
  466. package/dist/ui/assets/review-payload-C5Qz60Kq.js +0 -1
  467. package/dist/ui/assets/riscv-Ckw8ddFX.js +0 -1
  468. package/dist/ui/assets/ron-VUp2lXgN.js +0 -1
  469. package/dist/ui/assets/rose-pine-BthvhNj6.js +0 -1
  470. package/dist/ui/assets/rose-pine-dawn-Dg85fqjY.js +0 -1
  471. package/dist/ui/assets/rose-pine-moon-hon4tzzS.js +0 -1
  472. package/dist/ui/assets/rosmsg-CAekHB0j.js +0 -1
  473. package/dist/ui/assets/rst-CfBbbcvC.js +0 -1
  474. package/dist/ui/assets/ruby-Bw0mpxHY.js +0 -1
  475. package/dist/ui/assets/rust-Cfkwpbl8.js +0 -1
  476. package/dist/ui/assets/sas-Cs3s9JOf.js +0 -1
  477. package/dist/ui/assets/sass-DXrisJhu.js +0 -1
  478. package/dist/ui/assets/scala-DKOlJaKm.js +0 -1
  479. package/dist/ui/assets/scheme-DQCgrYNe.js +0 -1
  480. package/dist/ui/assets/scss-sRxNJS54.js +0 -1
  481. package/dist/ui/assets/sdbl-bTVj8UrX.js +0 -1
  482. package/dist/ui/assets/shaderlab-TOUzSsQk.js +0 -1
  483. package/dist/ui/assets/shellscript-B0X6wh0R.js +0 -1
  484. package/dist/ui/assets/shellsession-D2FdOioR.js +0 -1
  485. package/dist/ui/assets/slack-dark-DnToyrRv.js +0 -1
  486. package/dist/ui/assets/slack-ochin-B2OO5cIa.js +0 -1
  487. package/dist/ui/assets/smalltalk-B16xEiuN.js +0 -1
  488. package/dist/ui/assets/snazzy-light-4G7pJPwS.js +0 -1
  489. package/dist/ui/assets/solarized-dark-DV17i1UV.js +0 -1
  490. package/dist/ui/assets/solarized-light-DSh2HLQt.js +0 -1
  491. package/dist/ui/assets/solidity-CKzVLygQ.js +0 -1
  492. package/dist/ui/assets/soy-s6g9OjJ1.js +0 -1
  493. package/dist/ui/assets/sparql-D_iOobhT.js +0 -1
  494. package/dist/ui/assets/splunk-BC2Px7Mm.js +0 -1
  495. package/dist/ui/assets/sql-DVTnh5V-.js +0 -1
  496. package/dist/ui/assets/ssh-config-BgfXC-Er.js +0 -1
  497. package/dist/ui/assets/stata-DFIDiXF9.js +0 -1
  498. package/dist/ui/assets/stylus-B6D30XZt.js +0 -1
  499. package/dist/ui/assets/surrealql-DVfrsLyg.js +0 -1
  500. package/dist/ui/assets/svelte-D5GsxESq.js +0 -1
  501. package/dist/ui/assets/swift-DonLKvLd.js +0 -1
  502. package/dist/ui/assets/synthwave-84-nFMaYfgc.js +0 -1
  503. package/dist/ui/assets/system-verilog-DJ5XKQeo.js +0 -1
  504. package/dist/ui/assets/systemd-BxMlprV5.js +0 -1
  505. package/dist/ui/assets/talonscript-CohzipZa.js +0 -1
  506. package/dist/ui/assets/tasl-DMoTqEGO.js +0 -1
  507. package/dist/ui/assets/tcl-CZd0xW_V.js +0 -1
  508. package/dist/ui/assets/templ-DI-Zyqzd.js +0 -1
  509. package/dist/ui/assets/terraform-DswuEJGm.js +0 -1
  510. package/dist/ui/assets/tex-WHHmlbJI.js +0 -1
  511. package/dist/ui/assets/tokyo-night-oM2G3aXe.js +0 -1
  512. package/dist/ui/assets/toml-CcmNWLt0.js +0 -1
  513. package/dist/ui/assets/ts-tags-Dwpo2RFJ.js +0 -1
  514. package/dist/ui/assets/tsv-sltzmVWM.js +0 -1
  515. package/dist/ui/assets/tsx-ph_idaAW.js +0 -1
  516. package/dist/ui/assets/turtle-ByJddavk.js +0 -1
  517. package/dist/ui/assets/twig-YO17jFjR.js +0 -1
  518. package/dist/ui/assets/typescript-CbAxjhkl.js +0 -1
  519. package/dist/ui/assets/typespec-B88KGewJ.js +0 -1
  520. package/dist/ui/assets/typst-DI99ib-x.js +0 -1
  521. package/dist/ui/assets/useFileDiffInstance-B2DLX3Vg.js +0 -244
  522. package/dist/ui/assets/v-DETTlOr0.js +0 -1
  523. package/dist/ui/assets/vala-zf12oZj6.js +0 -1
  524. package/dist/ui/assets/vb-Djn5o6TS.js +0 -1
  525. package/dist/ui/assets/verilog-CiiDBU1e.js +0 -1
  526. package/dist/ui/assets/vesper-D5bVUKB1.js +0 -1
  527. package/dist/ui/assets/vhdl-BroJfC0k.js +0 -1
  528. package/dist/ui/assets/viml-DvXPmvsu.js +0 -1
  529. package/dist/ui/assets/vitesse-black-fwtXNY1n.js +0 -1
  530. package/dist/ui/assets/vitesse-dark-BZCL-v6S.js +0 -1
  531. package/dist/ui/assets/vitesse-light-VbXTXTou.js +0 -1
  532. package/dist/ui/assets/vue-CraHL-Ps.js +0 -1
  533. package/dist/ui/assets/vue-html-e9tyZNtS.js +0 -1
  534. package/dist/ui/assets/vue-vine-CofmxaUb.js +0 -1
  535. package/dist/ui/assets/vyper-CgoNMtux.js +0 -1
  536. package/dist/ui/assets/wasm-BnjxR4X6.js +0 -1
  537. package/dist/ui/assets/wasm-ByWQv1Qj.js +0 -1
  538. package/dist/ui/assets/wenyan-C8pVoKbM.js +0 -1
  539. package/dist/ui/assets/wgsl-BsKzXJz4.js +0 -1
  540. package/dist/ui/assets/wikitext-ClFFjSW2.js +0 -1
  541. package/dist/ui/assets/wit-DdvCle-K.js +0 -1
  542. package/dist/ui/assets/wolfram-DLL8P-h_.js +0 -1
  543. package/dist/ui/assets/workspace-app-8--oTbCd.css +0 -1
  544. package/dist/ui/assets/xml-BWSdPZHm.js +0 -1
  545. package/dist/ui/assets/xsl-BtCt7Hx8.js +0 -1
  546. package/dist/ui/assets/yaml-BZiTw7cQ.js +0 -1
  547. package/dist/ui/assets/zenscript-BnlCZFoB.js +0 -1
  548. package/dist/ui/assets/zig-CMLA9XwU.js +0 -1
  549. package/docs/assets/auvrynt-logo-light.png +0 -0
  550. package/docs/assets/auvrynt-screenshot.png +0 -0
@@ -0,0 +1,504 @@
1
+ import { lookup } from "node:dns/promises";
2
+ import { BlockList, isIP } from "node:net";
3
+ import { writeFile, mkdir } from "node:fs/promises";
4
+ import { dirname, join, relative } from "node:path";
5
+ import { inspectProject } from "../../search-discovery.js";
6
+ import { loadPlaywright } from "./playwright-runtime.js";
7
+ import { closeBrowserWithDeadline, settleWithin, shouldEmbedScreenshot, } from "./browser-stability.js";
8
+ const blockedAddresses = new BlockList();
9
+ blockedAddresses.addSubnet("0.0.0.0", 8, "ipv4");
10
+ blockedAddresses.addSubnet("10.0.0.0", 8, "ipv4");
11
+ blockedAddresses.addSubnet("100.64.0.0", 10, "ipv4");
12
+ blockedAddresses.addSubnet("127.0.0.0", 8, "ipv4");
13
+ blockedAddresses.addSubnet("169.254.0.0", 16, "ipv4");
14
+ blockedAddresses.addSubnet("172.16.0.0", 12, "ipv4");
15
+ blockedAddresses.addSubnet("192.0.0.0", 24, "ipv4");
16
+ blockedAddresses.addSubnet("192.0.2.0", 24, "ipv4");
17
+ blockedAddresses.addSubnet("192.88.99.0", 24, "ipv4");
18
+ blockedAddresses.addSubnet("192.168.0.0", 16, "ipv4");
19
+ blockedAddresses.addSubnet("198.18.0.0", 15, "ipv4");
20
+ blockedAddresses.addSubnet("198.51.100.0", 24, "ipv4");
21
+ blockedAddresses.addSubnet("203.0.113.0", 24, "ipv4");
22
+ blockedAddresses.addSubnet("224.0.0.0", 4, "ipv4");
23
+ blockedAddresses.addSubnet("240.0.0.0", 4, "ipv4");
24
+ blockedAddresses.addAddress("::", "ipv6");
25
+ blockedAddresses.addAddress("::1", "ipv6");
26
+ blockedAddresses.addSubnet("fc00::", 7, "ipv6");
27
+ blockedAddresses.addSubnet("fe80::", 10, "ipv6");
28
+ blockedAddresses.addSubnet("ff00::", 8, "ipv6");
29
+ blockedAddresses.addSubnet("2001:db8::", 32, "ipv6");
30
+ const MAX_BROWSER_JOBS = 4;
31
+ const MAX_BROWSER_DIAGNOSTICS = 100;
32
+ const BROWSER_CONTEXT_CLOSE_TIMEOUT_MS = 3_000;
33
+ const BROWSER_CLOSE_TIMEOUT_MS = 8_000;
34
+ const MAX_INLINE_SCREENSHOT_BYTES = 512 * 1024;
35
+ const MAX_INLINE_RESPONSIVE_BYTES = 1024 * 1024;
36
+ const LAUNCH_ARGS = [
37
+ "--disable-gpu",
38
+ "--disable-breakpad",
39
+ "--disable-crash-reporter",
40
+ "--noerrdialogs",
41
+ ];
42
+ const LAUNCH_OPTIONS = {
43
+ headless: true,
44
+ args: LAUNCH_ARGS,
45
+ ...(process.platform === "win32" ? { channel: "chromium" } : {}),
46
+ };
47
+ let activeBrowserJobs = 0;
48
+ async function closeContextWithTimeout(context) {
49
+ if (!context)
50
+ return;
51
+ await settleWithin(() => context.close(), BROWSER_CONTEXT_CLOSE_TIMEOUT_MS);
52
+ }
53
+ async function closeBrowserWithTimeout(browser) {
54
+ await closeBrowserWithDeadline(browser, BROWSER_CLOSE_TIMEOUT_MS);
55
+ }
56
+ function inlineScreenshotContent(buffer, label) {
57
+ if (shouldEmbedScreenshot(buffer.length, 0, MAX_INLINE_SCREENSHOT_BYTES, MAX_INLINE_SCREENSHOT_BYTES)) {
58
+ return [{ type: "image", data: buffer.toString("base64"), mimeType: "image/png" }];
59
+ }
60
+ return [{
61
+ type: "text",
62
+ text: `${label} was saved, but its ${buffer.length}-byte PNG was not embedded because it exceeded the stable MCP inline-image limit.`,
63
+ }];
64
+ }
65
+ function acquireBrowserSlot() {
66
+ if (activeBrowserJobs >= MAX_BROWSER_JOBS) {
67
+ throw new Error(`Browser capacity reached (max ${MAX_BROWSER_JOBS} concurrent jobs).`);
68
+ }
69
+ activeBrowserJobs += 1;
70
+ let released = false;
71
+ return () => {
72
+ if (released)
73
+ return;
74
+ released = true;
75
+ activeBrowserJobs = Math.max(0, activeBrowserJobs - 1);
76
+ };
77
+ }
78
+ function normalizedHostname(parsed) {
79
+ const hostname = parsed.hostname.toLowerCase();
80
+ return hostname.startsWith("[") && hostname.endsWith("]") ? hostname.slice(1, -1) : hostname;
81
+ }
82
+ function isExplicitLocalHost(hostname) {
83
+ return hostname === "localhost" || hostname.endsWith(".localhost") || hostname === "0.0.0.0" || hostname === "::1" || hostname.startsWith("127.");
84
+ }
85
+ function addressBlocked(address, allowLoopback) {
86
+ const family = isIP(address);
87
+ if (!family)
88
+ return true;
89
+ const type = family === 4 ? "ipv4" : "ipv6";
90
+ if (allowLoopback) {
91
+ if (family === 4 && address.startsWith("127."))
92
+ return false;
93
+ if (family === 6 && address === "::1")
94
+ return false;
95
+ }
96
+ if (blockedAddresses.check(address, type))
97
+ return true;
98
+ if (family === 6) {
99
+ const firstGroup = Number.parseInt(address.split(":", 1)[0] || "0", 16);
100
+ return firstGroup < 0x2000 || firstGroup > 0x3fff;
101
+ }
102
+ return false;
103
+ }
104
+ function parseWebUrl(urlStr) {
105
+ let parsed;
106
+ try {
107
+ parsed = new URL(urlStr);
108
+ }
109
+ catch {
110
+ throw new Error(`Invalid URL format: ${urlStr}`);
111
+ }
112
+ const protocol = parsed.protocol.toLowerCase();
113
+ if (protocol !== "http:" && protocol !== "https:") {
114
+ throw new Error(`Blocked unsafe scheme "${protocol}". Only http: and https: are allowed.`);
115
+ }
116
+ if (parsed.username || parsed.password) {
117
+ throw new Error("Blocked URL containing embedded credentials.");
118
+ }
119
+ return parsed;
120
+ }
121
+ export function validateWebUrl(urlStr) {
122
+ const parsed = parseWebUrl(urlStr);
123
+ const hostname = normalizedHostname(parsed);
124
+ if (isExplicitLocalHost(hostname))
125
+ return parsed.href;
126
+ const family = isIP(hostname);
127
+ if (family && addressBlocked(hostname, false)) {
128
+ throw new Error(`Blocked SSRF request to non-public address: ${hostname}`);
129
+ }
130
+ return parsed.href;
131
+ }
132
+ async function assertSafeResolvedHost(parsed, allowLoopback) {
133
+ const hostname = normalizedHostname(parsed);
134
+ if (isExplicitLocalHost(hostname)) {
135
+ if (allowLoopback)
136
+ return;
137
+ throw new Error(`Blocked SSRF request to loopback address: ${hostname}`);
138
+ }
139
+ const family = isIP(hostname);
140
+ if (family) {
141
+ if (addressBlocked(hostname, allowLoopback)) {
142
+ throw new Error(`Blocked SSRF request to non-public address: ${hostname}`);
143
+ }
144
+ return;
145
+ }
146
+ let resolved;
147
+ try {
148
+ resolved = await lookup(hostname, { all: true, verbatim: true });
149
+ }
150
+ catch (error) {
151
+ const reason = error instanceof Error ? error.message : String(error);
152
+ throw new Error(`Could not resolve ${hostname}: ${reason}`);
153
+ }
154
+ if (resolved.length === 0)
155
+ throw new Error(`Could not resolve ${hostname}.`);
156
+ for (const address of resolved) {
157
+ if (addressBlocked(address.address, allowLoopback)) {
158
+ throw new Error(`Blocked SSRF request: ${hostname} resolved to non-public address ${address.address}`);
159
+ }
160
+ }
161
+ }
162
+ export async function assertSafeWebUrl(urlStr, allowLoopback = false) {
163
+ const parsed = parseWebUrl(urlStr);
164
+ await assertSafeResolvedHost(parsed, allowLoopback);
165
+ return parsed.href;
166
+ }
167
+ async function assertSafeWebSocketUrl(urlStr, allowLoopback) {
168
+ let parsed;
169
+ try {
170
+ parsed = new URL(urlStr);
171
+ }
172
+ catch {
173
+ throw new Error(`Invalid WebSocket URL format: ${urlStr}`);
174
+ }
175
+ if (parsed.protocol !== "ws:" && parsed.protocol !== "wss:") {
176
+ throw new Error(`Blocked WebSocket scheme: ${parsed.protocol}`);
177
+ }
178
+ if (parsed.username || parsed.password) {
179
+ throw new Error("Blocked WebSocket URL containing embedded credentials.");
180
+ }
181
+ await assertSafeResolvedHost(parsed, allowLoopback);
182
+ }
183
+ async function installRequestGuard(context, initialUrl, blockedRequests) {
184
+ const parsed = parseWebUrl(initialUrl);
185
+ const allowLoopback = isExplicitLocalHost(normalizedHostname(parsed));
186
+ const safeInitialUrl = await assertSafeWebUrl(initialUrl, allowLoopback);
187
+ await context.route("**/*", async (route) => {
188
+ const requestUrl = route.request().url();
189
+ try {
190
+ const parsedRequest = new URL(requestUrl);
191
+ if (["data:", "blob:", "about:"].includes(parsedRequest.protocol)) {
192
+ await route.continue();
193
+ return;
194
+ }
195
+ await assertSafeWebUrl(requestUrl, allowLoopback);
196
+ await route.continue();
197
+ }
198
+ catch (error) {
199
+ if (blockedRequests.length < MAX_BROWSER_DIAGNOSTICS) {
200
+ const reason = error instanceof Error ? error.message : String(error);
201
+ blockedRequests.push(`${requestUrl} (${reason})`);
202
+ }
203
+ await route.abort("blockedbyclient");
204
+ }
205
+ });
206
+ await context.routeWebSocket("**/*", async (webSocket) => {
207
+ const socketUrl = webSocket.url();
208
+ try {
209
+ await assertSafeWebSocketUrl(socketUrl, allowLoopback);
210
+ webSocket.connectToServer();
211
+ }
212
+ catch (error) {
213
+ if (blockedRequests.length < MAX_BROWSER_DIAGNOSTICS) {
214
+ const reason = error instanceof Error ? error.message : String(error);
215
+ blockedRequests.push(`${socketUrl} (${reason})`);
216
+ }
217
+ await webSocket.close({ code: 1008, reason: "Blocked by Auvrynt network policy" });
218
+ }
219
+ });
220
+ return safeInitialUrl;
221
+ }
222
+ export async function startDevServer(registry, processManager, input, ownerClientId) {
223
+ let command = input.command;
224
+ if (!command) {
225
+ const summary = await inspectProject(registry, {
226
+ workspaceId: input.workspaceId,
227
+ path: input.workingDirectory,
228
+ });
229
+ command = summary.recommendedCommands.run;
230
+ if (!command) {
231
+ throw new Error("No development run command detected in project. Please specify command parameter.");
232
+ }
233
+ }
234
+ const result = processManager.startProcess({
235
+ workspaceId: input.workspaceId,
236
+ ownerClientId,
237
+ command,
238
+ workingDirectory: input.workingDirectory,
239
+ });
240
+ return {
241
+ processId: result.processId,
242
+ command,
243
+ status: result.status,
244
+ detectedUrls: result.detectedUrls,
245
+ recentOutput: result.recentOutput,
246
+ };
247
+ }
248
+ export async function capturePageScreenshot(registry, input) {
249
+ const workspace = registry.getWorkspace(input.workspaceId);
250
+ const validatedUrl = validateWebUrl(input.url);
251
+ const absoluteOutputPath = registry.resolveArtifactPath(workspace, input.outputPath, "playwright");
252
+ let playwright;
253
+ try {
254
+ playwright = await loadPlaywright();
255
+ }
256
+ catch (error) {
257
+ const message = error instanceof Error ? error.message : String(error);
258
+ return {
259
+ content: [{
260
+ type: "text",
261
+ text: `Playwright browser support is unavailable: ${message}. Run 'auvrynt start' to repair it automatically.`,
262
+ }],
263
+ isError: true,
264
+ };
265
+ }
266
+ let releaseSlot;
267
+ let browser;
268
+ let context;
269
+ try {
270
+ releaseSlot = acquireBrowserSlot();
271
+ const width = Math.min(Math.max(input.viewportWidth ?? 1280, 320), 3840);
272
+ const height = Math.min(Math.max(input.viewportHeight ?? 800, 240), 2160);
273
+ browser = await playwright.chromium.launch(LAUNCH_OPTIONS);
274
+ context = await browser.newContext({ viewport: { width, height }, serviceWorkers: "block" });
275
+ const blockedRequests = [];
276
+ const safeUrl = await installRequestGuard(context, validatedUrl, blockedRequests);
277
+ const page = await context.newPage();
278
+ const consoleErrors = [];
279
+ const failedRequests = [];
280
+ page.on("console", (msg) => {
281
+ if (msg.type() === "error" && consoleErrors.length < MAX_BROWSER_DIAGNOSTICS)
282
+ consoleErrors.push(msg.text());
283
+ });
284
+ page.on("requestfailed", (req) => {
285
+ if (failedRequests.length < MAX_BROWSER_DIAGNOSTICS) {
286
+ failedRequests.push(`${req.url()} (${req.failure()?.errorText ?? "failed"})`);
287
+ }
288
+ });
289
+ await page.goto(safeUrl, {
290
+ waitUntil: input.waitUntil ?? "domcontentloaded",
291
+ timeout: 15_000,
292
+ });
293
+ if (input.delayMs && input.delayMs > 0) {
294
+ await page.waitForTimeout(Math.min(input.delayMs, 5_000));
295
+ }
296
+ await mkdir(dirname(absoluteOutputPath), { recursive: true });
297
+ const buffer = await page.screenshot({ fullPage: input.fullPage ?? false, type: "png" });
298
+ await writeFile(absoluteOutputPath, buffer);
299
+ const relPath = relative(workspace.root, absoluteOutputPath).replace(/\\/g, "/");
300
+ return {
301
+ content: [
302
+ ...inlineScreenshotContent(buffer, `Screenshot ${relPath}`),
303
+ {
304
+ type: "text",
305
+ text: `Saved screenshot to ${relPath}${consoleErrors.length > 0 ? `\nConsole Errors: ${consoleErrors.join("; ")}` : ""}${failedRequests.length > 0 ? `\nFailed Requests: ${failedRequests.join("; ")}` : ""}${blockedRequests.length > 0 ? `\nBlocked Requests: ${blockedRequests.join("; ")}` : ""}`,
306
+ },
307
+ ],
308
+ };
309
+ }
310
+ catch (error) {
311
+ const msg = error instanceof Error ? error.message : String(error);
312
+ return { content: [{ type: "text", text: `Browser screenshot failed: ${msg}` }], isError: true };
313
+ }
314
+ finally {
315
+ await closeContextWithTimeout(context);
316
+ await closeBrowserWithTimeout(browser);
317
+ releaseSlot?.();
318
+ }
319
+ }
320
+ export async function inspectPage(registry, input) {
321
+ registry.getWorkspace(input.workspaceId);
322
+ const validatedUrl = validateWebUrl(input.url);
323
+ let playwright;
324
+ try {
325
+ playwright = await loadPlaywright();
326
+ }
327
+ catch (error) {
328
+ const message = error instanceof Error ? error.message : String(error);
329
+ return {
330
+ content: [{
331
+ type: "text",
332
+ text: `Playwright browser support is unavailable: ${message}. Run 'auvrynt start' to repair it automatically.`,
333
+ }],
334
+ isError: true,
335
+ };
336
+ }
337
+ let releaseSlot;
338
+ let browser;
339
+ let context;
340
+ try {
341
+ releaseSlot = acquireBrowserSlot();
342
+ browser = await playwright.chromium.launch(LAUNCH_OPTIONS);
343
+ context = await browser.newContext({ viewport: { width: 1280, height: 800 }, serviceWorkers: "block" });
344
+ const blockedRequests = [];
345
+ const safeUrl = await installRequestGuard(context, validatedUrl, blockedRequests);
346
+ const page = await context.newPage();
347
+ const consoleErrors = [];
348
+ const failedRequests = [];
349
+ page.on("console", (msg) => {
350
+ if (msg.type() === "error" && consoleErrors.length < MAX_BROWSER_DIAGNOSTICS)
351
+ consoleErrors.push(msg.text());
352
+ });
353
+ page.on("requestfailed", (req) => {
354
+ if (failedRequests.length < MAX_BROWSER_DIAGNOSTICS) {
355
+ failedRequests.push(`${req.url()} (${req.failure()?.errorText ?? "failed"})`);
356
+ }
357
+ });
358
+ await page.goto(safeUrl, { waitUntil: "domcontentloaded", timeout: 15_000 });
359
+ const title = await page.title();
360
+ const maxElements = Math.min(Math.max(input.maxElements ?? 20, 1), 100);
361
+ const elementsSummary = await page.evaluate((maxElem) => {
362
+ const headings = Array.from(document.querySelectorAll("h1, h2, h3"))
363
+ .slice(0, maxElem)
364
+ .map((el) => `${el.tagName}: ${el.textContent?.trim()}`);
365
+ const buttons = Array.from(document.querySelectorAll("button, input[type='button'], input[type='submit']"))
366
+ .slice(0, maxElem)
367
+ .map((el) => el.textContent?.trim() || el.value || "button");
368
+ const links = Array.from(document.querySelectorAll("a[href]"))
369
+ .slice(0, maxElem)
370
+ .map((el) => `${el.textContent?.trim() || "link"} -> ${el.href}`);
371
+ return { headings, buttons, links };
372
+ }, maxElements);
373
+ const accessibility = input.includeAccessibilityTree
374
+ ? await page.evaluate((maxElem) => Array.from(document.querySelectorAll("[role], button, a[href], input, select, textarea, h1, h2, h3, h4, h5, h6")).slice(0, maxElem).map((el) => ({
375
+ tag: el.tagName.toLowerCase(),
376
+ role: el.getAttribute("role"),
377
+ label: el.getAttribute("aria-label"),
378
+ text: el.textContent?.trim().slice(0, 160) || null,
379
+ disabled: el.disabled || el.getAttribute("aria-disabled") === "true",
380
+ })), maxElements)
381
+ : undefined;
382
+ const computedStyles = input.includeComputedStyles
383
+ ? await page.evaluate((maxElem) => Array.from(document.querySelectorAll("body, h1, h2, h3, button, a, input"))
384
+ .slice(0, maxElem)
385
+ .map((el) => {
386
+ const styles = getComputedStyle(el);
387
+ return {
388
+ element: el.tagName.toLowerCase(),
389
+ display: styles.display,
390
+ position: styles.position,
391
+ color: styles.color,
392
+ backgroundColor: styles.backgroundColor,
393
+ fontSize: styles.fontSize,
394
+ fontFamily: styles.fontFamily,
395
+ };
396
+ }), maxElements)
397
+ : undefined;
398
+ return {
399
+ content: [{
400
+ type: "text",
401
+ text: JSON.stringify({
402
+ url: safeUrl,
403
+ title,
404
+ elements: elementsSummary,
405
+ accessibility,
406
+ computedStyles,
407
+ consoleErrors,
408
+ failedRequests,
409
+ blockedRequests,
410
+ }, null, 2),
411
+ }],
412
+ };
413
+ }
414
+ catch (error) {
415
+ const msg = error instanceof Error ? error.message : String(error);
416
+ return { content: [{ type: "text", text: `Inspect page failed: ${msg}` }], isError: true };
417
+ }
418
+ finally {
419
+ await closeContextWithTimeout(context);
420
+ await closeBrowserWithTimeout(browser);
421
+ releaseSlot?.();
422
+ }
423
+ }
424
+ export async function testResponsivePage(registry, input) {
425
+ const workspace = registry.getWorkspace(input.workspaceId);
426
+ const validatedUrl = validateWebUrl(input.url);
427
+ const outputDirectory = registry.resolveArtifactPath(workspace, input.outputDirectory, "playwright");
428
+ const requestedViewports = input.viewports ?? [
429
+ { name: "mobile", width: 390, height: 844 },
430
+ { name: "tablet", width: 768, height: 1024 },
431
+ { name: "desktop", width: 1440, height: 900 },
432
+ ];
433
+ if (requestedViewports.length < 1 || requestedViewports.length > 6) {
434
+ return { content: [{ type: "text", text: "Responsive testing requires 1 to 6 viewports." }], isError: true };
435
+ }
436
+ const viewports = requestedViewports.map((viewport, index) => ({
437
+ name: viewport.name.trim().replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 64) || `viewport_${index + 1}`,
438
+ width: Math.min(Math.max(Math.trunc(viewport.width), 240), 3840),
439
+ height: Math.min(Math.max(Math.trunc(viewport.height), 240), 2160),
440
+ }));
441
+ const names = new Set(viewports.map((viewport) => viewport.name.toLowerCase()));
442
+ if (names.size !== viewports.length) {
443
+ return { content: [{ type: "text", text: "Responsive viewport names must be unique after filename sanitization." }], isError: true };
444
+ }
445
+ let playwright;
446
+ try {
447
+ playwright = await loadPlaywright();
448
+ }
449
+ catch (error) {
450
+ const message = error instanceof Error ? error.message : String(error);
451
+ return {
452
+ content: [{ type: "text", text: `Playwright browser support is unavailable: ${message}. Run 'auvrynt start' to repair it automatically.` }],
453
+ isError: true,
454
+ };
455
+ }
456
+ let releaseSlot;
457
+ let browser;
458
+ try {
459
+ releaseSlot = acquireBrowserSlot();
460
+ browser = await playwright.chromium.launch(LAUNCH_OPTIONS);
461
+ await mkdir(outputDirectory, { recursive: true });
462
+ const content = [];
463
+ const results = [];
464
+ let inlineScreenshotBytes = 0;
465
+ for (const viewport of viewports) {
466
+ const context = await browser.newContext({ viewport: { width: viewport.width, height: viewport.height }, serviceWorkers: "block" });
467
+ try {
468
+ const blockedRequests = [];
469
+ const safeUrl = await installRequestGuard(context, validatedUrl, blockedRequests);
470
+ const page = await context.newPage();
471
+ await page.goto(safeUrl, { waitUntil: "domcontentloaded", timeout: 15_000 });
472
+ const buffer = await page.screenshot({ fullPage: input.fullPage ?? true, type: "png" });
473
+ const outputPath = join(outputDirectory, `${viewport.name}.png`);
474
+ await writeFile(outputPath, buffer);
475
+ const relPath = relative(workspace.root, outputPath).replace(/\\/g, "/");
476
+ results.push({ ...viewport, path: relPath, blockedRequests });
477
+ if (shouldEmbedScreenshot(buffer.length, inlineScreenshotBytes, MAX_INLINE_SCREENSHOT_BYTES, MAX_INLINE_RESPONSIVE_BYTES)) {
478
+ inlineScreenshotBytes += buffer.length;
479
+ content.push({ type: "image", data: buffer.toString("base64"), mimeType: "image/png" });
480
+ }
481
+ else {
482
+ content.push({
483
+ type: "text",
484
+ text: `${viewport.name} screenshot was saved but not embedded (${buffer.length} bytes) to keep the MCP response stable.`,
485
+ });
486
+ }
487
+ content.push({ type: "text", text: `${viewport.name}: ${viewport.width}x${viewport.height} → ${relPath}` });
488
+ }
489
+ finally {
490
+ await closeContextWithTimeout(context);
491
+ }
492
+ }
493
+ content.push({ type: "text", text: JSON.stringify({ url: validatedUrl, results }, null, 2) });
494
+ return { content };
495
+ }
496
+ catch (error) {
497
+ const message = error instanceof Error ? error.message : String(error);
498
+ return { content: [{ type: "text", text: `Responsive page test failed: ${message}` }], isError: true };
499
+ }
500
+ finally {
501
+ await closeBrowserWithTimeout(browser);
502
+ releaseSlot?.();
503
+ }
504
+ }