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,99 @@
1
+ import { extname } from "node:path";
2
+ import { readFile, stat } from "node:fs/promises";
3
+ import { inlineImageOrNotice } from "../../tool-result-budget.js";
4
+ const MAX_IMAGE_SIZE_BYTES = 20 * 1024 * 1024;
5
+ const SUPPORTED_MIME_TYPES = {
6
+ ".png": "image/png",
7
+ ".jpg": "image/jpeg",
8
+ ".jpeg": "image/jpeg",
9
+ ".webp": "image/webp",
10
+ ".gif": "image/gif",
11
+ };
12
+ export async function executeViewImage(registry, input) {
13
+ let workspace;
14
+ try {
15
+ workspace = registry.getWorkspace(input.workspaceId);
16
+ }
17
+ catch (error) {
18
+ const message = error instanceof Error ? error.message : String(error);
19
+ return {
20
+ content: [{ type: "text", text: message }],
21
+ isError: true,
22
+ };
23
+ }
24
+ const ext = extname(input.path).toLowerCase();
25
+ const mimeType = SUPPORTED_MIME_TYPES[ext];
26
+ if (!mimeType) {
27
+ return {
28
+ content: [
29
+ {
30
+ type: "text",
31
+ text: `Unsupported image extension "${ext}". Supported extensions: .png, .jpg, .jpeg, .webp, .gif`,
32
+ },
33
+ ],
34
+ isError: true,
35
+ };
36
+ }
37
+ let absolutePath;
38
+ try {
39
+ absolutePath = registry.resolvePath(workspace, input.path);
40
+ }
41
+ catch (error) {
42
+ const message = error instanceof Error ? error.message : String(error);
43
+ return {
44
+ content: [{ type: "text", text: message }],
45
+ isError: true,
46
+ };
47
+ }
48
+ let stats;
49
+ try {
50
+ stats = await stat(absolutePath);
51
+ }
52
+ catch {
53
+ return {
54
+ content: [{ type: "text", text: `File not found: ${input.path}` }],
55
+ isError: true,
56
+ };
57
+ }
58
+ if (stats.isDirectory()) {
59
+ return {
60
+ content: [
61
+ { type: "text", text: `Path is a directory, not a file: ${input.path}` },
62
+ ],
63
+ isError: true,
64
+ };
65
+ }
66
+ if (!stats.isFile()) {
67
+ return {
68
+ content: [
69
+ { type: "text", text: `Path is not a regular file: ${input.path}` },
70
+ ],
71
+ isError: true,
72
+ };
73
+ }
74
+ if (stats.size > MAX_IMAGE_SIZE_BYTES) {
75
+ const sizeMb = (stats.size / (1024 * 1024)).toFixed(2);
76
+ return {
77
+ content: [
78
+ {
79
+ type: "text",
80
+ text: `Image file size (${sizeMb} MB) exceeds maximum allowed limit of 20 MB.`,
81
+ },
82
+ ],
83
+ isError: true,
84
+ };
85
+ }
86
+ try {
87
+ const buffer = await readFile(absolutePath);
88
+ return {
89
+ content: inlineImageOrNotice(buffer, `Image ${input.path}`, mimeType),
90
+ };
91
+ }
92
+ catch (error) {
93
+ const message = error instanceof Error ? error.message : String(error);
94
+ return {
95
+ content: [{ type: "text", text: `Failed to read image file: ${message}` }],
96
+ isError: true,
97
+ };
98
+ }
99
+ }
@@ -0,0 +1,148 @@
1
+ import { readFile, mkdir } from "node:fs/promises";
2
+ import { dirname, relative } from "node:path";
3
+ import { execFile } from "node:child_process";
4
+ import { promisify } from "node:util";
5
+ import { inlineImageOrNotice } from "../../tool-result-budget.js";
6
+ const execFileAsync = promisify(execFile);
7
+ const MAX_WINDOW_TITLE_CHARS = 256;
8
+ export async function captureWindow(registry, processManager, input) {
9
+ const workspace = registry.getWorkspace(input.workspaceId);
10
+ const absoluteOutputPath = registry.resolveArtifactPath(workspace, input.outputPath, "captures");
11
+ if (process.platform !== "win32") {
12
+ return {
13
+ content: [{
14
+ type: "text",
15
+ text: `Window capture is currently supported on Windows hosts. Operating system "${process.platform}" is not supported.`,
16
+ }],
17
+ isError: true,
18
+ };
19
+ }
20
+ const title = input.windowTitle?.trim();
21
+ if (!input.processId && !title) {
22
+ return {
23
+ content: [{ type: "text", text: "Window capture requires processId or windowTitle. Full-screen capture is intentionally disabled." }],
24
+ isError: true,
25
+ };
26
+ }
27
+ if (title && title.length > MAX_WINDOW_TITLE_CHARS) {
28
+ return {
29
+ content: [{ type: "text", text: `windowTitle exceeds ${MAX_WINDOW_TITLE_CHARS} characters.` }],
30
+ isError: true,
31
+ };
32
+ }
33
+ let pid;
34
+ if (input.processId) {
35
+ const tracked = processManager.getTrackedProcess(input.workspaceId, input.processId);
36
+ if (tracked.status !== "running") {
37
+ return {
38
+ content: [{ type: "text", text: `Tracked process ${input.processId} is not running.` }],
39
+ isError: true,
40
+ };
41
+ }
42
+ pid = tracked.pid;
43
+ if (!pid) {
44
+ return {
45
+ content: [{ type: "text", text: `Tracked process ${input.processId} does not have a process ID.` }],
46
+ isError: true,
47
+ };
48
+ }
49
+ }
50
+ const psScript = String.raw `
51
+ $ErrorActionPreference = 'Stop'
52
+ Add-Type -AssemblyName System.Drawing
53
+ Add-Type -TypeDefinition @"
54
+ using System;
55
+ using System.Runtime.InteropServices;
56
+ public static class AuvryntNativeWindow {
57
+ [StructLayout(LayoutKind.Sequential)]
58
+ public struct RECT { public int Left; public int Top; public int Right; public int Bottom; }
59
+ [DllImport("user32.dll")]
60
+ public static extern bool GetWindowRect(IntPtr hWnd, out RECT rect);
61
+ [DllImport("user32.dll")]
62
+ public static extern bool PrintWindow(IntPtr hWnd, IntPtr hdcBlt, uint flags);
63
+ }
64
+ "@
65
+
66
+ function Find-WindowForProcess([int]$RootPid) {
67
+ $queue = [System.Collections.Generic.Queue[int]]::new()
68
+ $seen = [System.Collections.Generic.HashSet[int]]::new()
69
+ $queue.Enqueue($RootPid)
70
+ while ($queue.Count -gt 0) {
71
+ $currentPid = $queue.Dequeue()
72
+ if (-not $seen.Add($currentPid)) { continue }
73
+ $proc = Get-Process -Id $currentPid -ErrorAction SilentlyContinue
74
+ if ($proc -and $proc.MainWindowHandle -ne [IntPtr]::Zero) { return $proc.MainWindowHandle }
75
+ Get-CimInstance Win32_Process -Filter "ParentProcessId=$currentPid" -ErrorAction SilentlyContinue | ForEach-Object {
76
+ $queue.Enqueue([int]$_.ProcessId)
77
+ }
78
+ }
79
+ return [IntPtr]::Zero
80
+ }
81
+
82
+ $handle = [IntPtr]::Zero
83
+ if ($env:AUVRYNT_CAPTURE_PID) {
84
+ $handle = Find-WindowForProcess ([int]$env:AUVRYNT_CAPTURE_PID)
85
+ }
86
+ if ($handle -eq [IntPtr]::Zero -and $env:AUVRYNT_CAPTURE_TITLE) {
87
+ $needle = $env:AUVRYNT_CAPTURE_TITLE
88
+ $proc = Get-Process | Where-Object {
89
+ $_.MainWindowHandle -ne [IntPtr]::Zero -and
90
+ $_.MainWindowTitle.IndexOf($needle, [StringComparison]::OrdinalIgnoreCase) -ge 0
91
+ } | Select-Object -First 1
92
+ if ($proc) { $handle = $proc.MainWindowHandle }
93
+ }
94
+ if ($handle -eq [IntPtr]::Zero) { throw 'Target application window was not found.' }
95
+
96
+ $rect = New-Object AuvryntNativeWindow+RECT
97
+ if (-not [AuvryntNativeWindow]::GetWindowRect($handle, [ref]$rect)) { throw 'Could not read target window bounds.' }
98
+ $width = $rect.Right - $rect.Left
99
+ $height = $rect.Bottom - $rect.Top
100
+ if ($width -lt 1 -or $height -lt 1 -or $width -gt 16384 -or $height -gt 16384) {
101
+ throw "Invalid target window bounds: $($width)x$($height)"
102
+ }
103
+
104
+ $bmp = New-Object System.Drawing.Bitmap $width, $height
105
+ $graphics = [System.Drawing.Graphics]::FromImage($bmp)
106
+ try {
107
+ $hdc = $graphics.GetHdc()
108
+ try { $printed = [AuvryntNativeWindow]::PrintWindow($handle, $hdc, 2) }
109
+ finally { $graphics.ReleaseHdc($hdc) }
110
+ if (-not $printed) {
111
+ $graphics.CopyFromScreen($rect.Left, $rect.Top, 0, 0, $bmp.Size)
112
+ }
113
+ $bmp.Save($env:AUVRYNT_CAPTURE_OUTPUT, [System.Drawing.Imaging.ImageFormat]::Png)
114
+ } finally {
115
+ $graphics.Dispose()
116
+ $bmp.Dispose()
117
+ }
118
+ `;
119
+ await mkdir(dirname(absoluteOutputPath), { recursive: true });
120
+ try {
121
+ await execFileAsync("powershell", ["-NoProfile", "-NonInteractive", "-Command", psScript], {
122
+ env: {
123
+ ...process.env,
124
+ AUVRYNT_CAPTURE_PID: pid ? String(pid) : "",
125
+ AUVRYNT_CAPTURE_TITLE: title ?? "",
126
+ AUVRYNT_CAPTURE_OUTPUT: absoluteOutputPath,
127
+ },
128
+ maxBuffer: 1024 * 1024,
129
+ timeout: 20_000,
130
+ windowsHide: true,
131
+ });
132
+ const buffer = await readFile(absoluteOutputPath);
133
+ const relPath = relative(workspace.root, absoluteOutputPath).replace(/\\/g, "/");
134
+ return {
135
+ content: [
136
+ ...inlineImageOrNotice(buffer, `Window capture ${relPath}`, "image/png"),
137
+ { type: "text", text: `Captured target window screenshot to ${relPath}` },
138
+ ],
139
+ };
140
+ }
141
+ catch (error) {
142
+ const msg = error instanceof Error ? error.message : String(error);
143
+ return {
144
+ content: [{ type: "text", text: `Window capture failed: ${msg}` }],
145
+ isError: true,
146
+ };
147
+ }
148
+ }
@@ -0,0 +1,185 @@
1
+ import { existsSync } from "node:fs";
2
+ import { createConnection } from "node:net";
3
+ import { execFile } from "node:child_process";
4
+ import { promisify } from "node:util";
5
+ import { join } from "node:path";
6
+ import { homedir } from "node:os";
7
+ import { loadConfig } from "../config.js";
8
+ const execFileAsync = promisify(execFile);
9
+ const PROCESS_MARKERS = {
10
+ blender: ["blender.exe", "blender"],
11
+ aseprite: ["aseprite.exe", "aseprite"],
12
+ godot: ["godot.exe", "godot4.exe", "godot"],
13
+ cloudflare_tunnel: ["cloudflared.exe", "cloudflared"],
14
+ serena: ["serena.exe", "serena"],
15
+ roblox: ["robloxstudiobeta.exe", "robloxstudio.exe", "robloxplayerbeta.exe"],
16
+ };
17
+ export const DEFAULT_INTEGRATION_DISCOVERY_CACHE_MS = 10_000;
18
+ let cachedDiscovery;
19
+ let discoveryInFlight;
20
+ function probePort(host, port, timeoutMs = 350) {
21
+ return new Promise((resolve) => {
22
+ const socket = createConnection({ host, port });
23
+ let finished = false;
24
+ const finish = (available) => {
25
+ if (finished)
26
+ return;
27
+ finished = true;
28
+ socket.destroy();
29
+ resolve(available);
30
+ };
31
+ const timeout = setTimeout(() => finish(false), timeoutMs);
32
+ socket.once("connect", () => {
33
+ clearTimeout(timeout);
34
+ finish(true);
35
+ });
36
+ socket.once("error", () => {
37
+ clearTimeout(timeout);
38
+ finish(false);
39
+ });
40
+ });
41
+ }
42
+ async function runningProcessNames() {
43
+ if (process.platform !== "win32")
44
+ return [];
45
+ try {
46
+ const { stdout } = await execFileAsync("tasklist.exe", ["/FO", "CSV", "/NH"], {
47
+ timeout: 5_000,
48
+ windowsHide: true,
49
+ });
50
+ return stdout
51
+ .split(/\r?\n/)
52
+ .map((line) => line.match(/^"([^"]+)"/)?.[1]?.toLowerCase())
53
+ .filter((name) => Boolean(name));
54
+ }
55
+ catch {
56
+ return [];
57
+ }
58
+ }
59
+ async function findExecutable(command) {
60
+ const exes = process.platform === "win32" ? [`${command}.exe`, command] : [command];
61
+ const userBinDirs = [
62
+ join(homedir(), ".auvrynt", "bin"),
63
+ join(homedir(), ".local", "bin"),
64
+ join(homedir(), "AppData", "Roaming", "Python", "Scripts"),
65
+ ];
66
+ for (const dir of userBinDirs) {
67
+ for (const exe of exes) {
68
+ const fullPath = join(dir, exe);
69
+ if (existsSync(fullPath))
70
+ return fullPath;
71
+ }
72
+ }
73
+ try {
74
+ const cmd = process.platform === "win32" ? "where.exe" : "which";
75
+ const { stdout } = await execFileAsync(cmd, [command], {
76
+ timeout: 5_000,
77
+ windowsHide: true,
78
+ });
79
+ return stdout.split(/\r?\n/).map((line) => line.trim()).find(Boolean);
80
+ }
81
+ catch {
82
+ return undefined;
83
+ }
84
+ }
85
+ function findAsepriteInSource(sourcePath) {
86
+ if (!sourcePath)
87
+ return undefined;
88
+ const candidates = process.platform === "win32"
89
+ ? [join(sourcePath, "build", "bin", "aseprite.exe"), join(sourcePath, "bin", "aseprite.exe"), join(sourcePath, "aseprite.exe")]
90
+ : [join(sourcePath, "build", "bin", "aseprite"), join(sourcePath, "bin", "aseprite"), join(sourcePath, "aseprite")];
91
+ return candidates.find((candidate) => existsSync(candidate));
92
+ }
93
+ function hasProcess(processes, markers) {
94
+ return processes.some((processName) => markers.some((marker) => processName === marker || processName.includes(marker)));
95
+ }
96
+ export async function discoverLocalIntegrations(options = {}) {
97
+ const cacheMs = Math.max(0, options.cacheMs ?? DEFAULT_INTEGRATION_DISCOVERY_CACHE_MS);
98
+ const forceRefresh = options.forceRefresh === true || (options.pollMs ?? 0) > 0;
99
+ const now = Date.now();
100
+ if (!forceRefresh
101
+ && cacheMs > 0
102
+ && cachedDiscovery
103
+ && now - cachedDiscovery.cachedAt < cacheMs) {
104
+ return cloneDiscovery(cachedDiscovery.value);
105
+ }
106
+ const inFlight = discoveryInFlight ??= performDiscovery(options.pollMs ?? 0);
107
+ try {
108
+ const result = await inFlight;
109
+ cachedDiscovery = { value: result, cachedAt: Date.now() };
110
+ return cloneDiscovery(result);
111
+ }
112
+ finally {
113
+ if (discoveryInFlight === inFlight)
114
+ discoveryInFlight = undefined;
115
+ }
116
+ }
117
+ async function performDiscovery(pollMs) {
118
+ let configExecs = {};
119
+ try {
120
+ const config = loadConfig();
121
+ configExecs = config.executables;
122
+ }
123
+ catch { }
124
+ const blenderMcpPort = Number(process.env.AUVRYNT_BLENDER_MCP_PORT ?? 9876);
125
+ const boundedPollMs = Math.max(0, pollMs);
126
+ const pollPort = async (port) => {
127
+ const deadline = Date.now() + boundedPollMs;
128
+ do {
129
+ if (await probePort("127.0.0.1", port))
130
+ return true;
131
+ if (Date.now() >= deadline)
132
+ return false;
133
+ await new Promise((resolveDelay) => setTimeout(resolveDelay, 250));
134
+ } while (Date.now() <= deadline);
135
+ return false;
136
+ };
137
+ const configuredAseprite = configExecs.aseprite || findAsepriteInSource(configExecs.asepriteSource);
138
+ const [processes, cloudflaredSys, serenaSys, godotSys, blenderSys, asepriteSys, blenderLabMcp, auvryntBlenderBridge, auvryntGodotBridge] = await Promise.all([
139
+ runningProcessNames(),
140
+ configExecs.cloudflared ? undefined : findExecutable("cloudflared"),
141
+ configExecs.serena ? undefined : findExecutable("serena"),
142
+ configExecs.godot || configExecs.godotCsharp ? undefined : findExecutable("godot"),
143
+ configExecs.blender ? undefined : findExecutable("blender"),
144
+ configuredAseprite ? undefined : findExecutable("aseprite"),
145
+ pollPort(blenderMcpPort),
146
+ pollPort(49323),
147
+ pollPort(49322),
148
+ ]);
149
+ const cloudflared = configExecs.cloudflared || cloudflaredSys;
150
+ const serena = configExecs.serena || serenaSys;
151
+ const godot = configExecs.godot || godotSys;
152
+ const godotCsharp = configExecs.godotCsharp;
153
+ const blender = configExecs.blender || blenderSys;
154
+ const aseprite = configuredAseprite || asepriteSys;
155
+ return {
156
+ processes,
157
+ executables: {
158
+ cloudflared,
159
+ serena,
160
+ godot,
161
+ godotCsharp,
162
+ blender,
163
+ aseprite,
164
+ asepriteSource: configExecs.asepriteSource,
165
+ },
166
+ ports: {
167
+ blender_lab_mcp: blenderLabMcp,
168
+ auvrynt_blender_bridge: auvryntBlenderBridge,
169
+ auvrynt_godot_bridge: auvryntGodotBridge,
170
+ },
171
+ };
172
+ }
173
+ function cloneDiscovery(discovery) {
174
+ return {
175
+ processes: [...discovery.processes],
176
+ executables: { ...discovery.executables },
177
+ ports: { ...discovery.ports },
178
+ };
179
+ }
180
+ export function clearIntegrationDiscoveryCache() {
181
+ cachedDiscovery = undefined;
182
+ }
183
+ export function processDetected(discovery, integration) {
184
+ return hasProcess(discovery.processes, PROCESS_MARKERS[integration]);
185
+ }
@@ -0,0 +1,205 @@
1
+ import { createReadStream, existsSync } from "node:fs";
2
+ import { mkdir, readdir, readFile, stat, writeFile } from "node:fs/promises";
3
+ import { dirname, extname, join, relative, resolve, sep } from "node:path";
4
+ import * as z from "zod/v4";
5
+ import { registerAppTool } from "../../server/mcp-tool-registrar.js";
6
+ import { expandHomePath } from "../../roots.js";
7
+ import { createInterface } from "node:readline";
8
+ const READ_ONLY = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
9
+ const MUTATING = { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: false };
10
+ function text(payload, isError = false) {
11
+ return {
12
+ content: [{ type: "text", text: typeof payload === "string" ? payload : JSON.stringify(payload, null, 2) }],
13
+ ...(isError ? { isError: true } : {}),
14
+ };
15
+ }
16
+ function resolveVaultRoot(config) {
17
+ const raw = config.obsidian.vaultPath?.trim();
18
+ if (!raw) {
19
+ throw new Error("Obsidian vault path is not configured. Set AUVRYNT_OBSIDIAN_VAULT or config.obsidian.vaultPath to your vault folder.");
20
+ }
21
+ return resolve(expandHomePath(raw));
22
+ }
23
+ function assertInsideVault(vaultRoot, target) {
24
+ const absolute = resolve(vaultRoot, target);
25
+ const root = vaultRoot.endsWith(sep) ? vaultRoot : vaultRoot + sep;
26
+ if (absolute !== vaultRoot && !absolute.startsWith(root)) {
27
+ throw new Error("Path escapes the configured Obsidian vault.");
28
+ }
29
+ return absolute;
30
+ }
31
+ async function listMarkdownFiles(vaultRoot, subdir = "", limit = 200) {
32
+ const results = [];
33
+ async function walk(dir) {
34
+ if (results.length >= limit)
35
+ return;
36
+ const entries = await readdir(dir, { withFileTypes: true });
37
+ for (const entry of entries) {
38
+ if (results.length >= limit)
39
+ return;
40
+ if (entry.name.startsWith("."))
41
+ continue;
42
+ const full = join(dir, entry.name);
43
+ if (entry.isDirectory()) {
44
+ if (entry.name === "node_modules" || entry.name === ".obsidian")
45
+ continue;
46
+ await walk(full);
47
+ }
48
+ else if (entry.isFile() && ["md", "markdown"].includes(extname(entry.name).slice(1).toLowerCase())) {
49
+ results.push(relative(vaultRoot, full).replace(/\\/g, "/"));
50
+ }
51
+ }
52
+ }
53
+ const start = subdir ? assertInsideVault(vaultRoot, subdir) : vaultRoot;
54
+ if (!existsSync(start))
55
+ throw new Error(`Vault path not found: ${start}`);
56
+ await walk(start);
57
+ return results;
58
+ }
59
+ export function registerObsidianTools(server, config) {
60
+ registerAppTool(server, "obsidian_status", {
61
+ title: "Obsidian vault status",
62
+ description: "Report the configured Obsidian vault path and whether it exists on disk.",
63
+ inputSchema: {},
64
+ annotations: READ_ONLY,
65
+ _meta: {},
66
+ }, async () => {
67
+ try {
68
+ const vaultPath = config.obsidian.vaultPath
69
+ ? resolve(expandHomePath(config.obsidian.vaultPath))
70
+ : null;
71
+ const exists = vaultPath ? existsSync(vaultPath) : false;
72
+ let noteCount = null;
73
+ if (exists && vaultPath) {
74
+ noteCount = (await listMarkdownFiles(vaultPath, "", 5_000)).length;
75
+ }
76
+ return text({
77
+ configured: Boolean(vaultPath),
78
+ vaultPath,
79
+ exists,
80
+ noteCount,
81
+ });
82
+ }
83
+ catch (error) {
84
+ return text(error instanceof Error ? error.message : String(error), true);
85
+ }
86
+ });
87
+ registerAppTool(server, "obsidian_list_notes", {
88
+ title: "List Obsidian notes",
89
+ description: "List markdown notes under the configured Obsidian vault (relative paths).",
90
+ inputSchema: {
91
+ subdir: z.string().optional().describe("Optional subdirectory relative to the vault root."),
92
+ limit: z.number().int().min(1).max(2000).optional().describe("Max notes to return (default 200)."),
93
+ },
94
+ annotations: READ_ONLY,
95
+ _meta: {},
96
+ }, async ({ subdir, limit }) => {
97
+ try {
98
+ const vault = resolveVaultRoot(config);
99
+ const notes = await listMarkdownFiles(vault, subdir ?? "", limit ?? 200);
100
+ return text({ vault, count: notes.length, notes });
101
+ }
102
+ catch (error) {
103
+ return text(error instanceof Error ? error.message : String(error), true);
104
+ }
105
+ });
106
+ registerAppTool(server, "obsidian_read_note", {
107
+ title: "Read Obsidian note",
108
+ description: "Read a markdown note from the configured Obsidian vault by relative path.",
109
+ inputSchema: {
110
+ path: z.string().min(1).describe("Note path relative to the vault root (e.g. Projects/idea.md)."),
111
+ },
112
+ annotations: READ_ONLY,
113
+ _meta: {},
114
+ }, async ({ path }) => {
115
+ try {
116
+ const vault = resolveVaultRoot(config);
117
+ const absolute = assertInsideVault(vault, path);
118
+ const content = await readFile(absolute, "utf8");
119
+ const info = await stat(absolute);
120
+ return text({
121
+ path: relative(vault, absolute).replace(/\\/g, "/"),
122
+ bytes: info.size,
123
+ modifiedAt: info.mtime.toISOString(),
124
+ content,
125
+ });
126
+ }
127
+ catch (error) {
128
+ return text(error instanceof Error ? error.message : String(error), true);
129
+ }
130
+ });
131
+ registerAppTool(server, "obsidian_search", {
132
+ title: "Search Obsidian vault",
133
+ description: "Case-insensitive full-text search across markdown notes in the configured vault.",
134
+ inputSchema: {
135
+ query: z.string().min(1).describe("Text to search for."),
136
+ limit: z.number().int().min(1).max(100).optional().describe("Max matching notes (default 25)."),
137
+ },
138
+ annotations: READ_ONLY,
139
+ _meta: {},
140
+ }, async ({ query, limit }) => {
141
+ try {
142
+ const vault = resolveVaultRoot(config);
143
+ const notes = await listMarkdownFiles(vault, "", 5_000);
144
+ const needle = query.toLowerCase();
145
+ const max = limit ?? 25;
146
+ const matches = [];
147
+ for (const note of notes) {
148
+ if (matches.length >= max)
149
+ break;
150
+ const absolute = join(vault, note);
151
+ const stream = createReadStream(absolute, { encoding: "utf8" });
152
+ const rl = createInterface({ input: stream, crlfDelay: Infinity });
153
+ let lineNo = 0;
154
+ for await (const line of rl) {
155
+ lineNo += 1;
156
+ if (line.toLowerCase().includes(needle)) {
157
+ matches.push({ path: note, line: lineNo, preview: line.trim().slice(0, 240) });
158
+ if (matches.length >= max)
159
+ break;
160
+ }
161
+ }
162
+ }
163
+ return text({ vault, query, count: matches.length, matches });
164
+ }
165
+ catch (error) {
166
+ return text(error instanceof Error ? error.message : String(error), true);
167
+ }
168
+ });
169
+ registerAppTool(server, "obsidian_write_note", {
170
+ title: "Write Obsidian note",
171
+ description: "Create or overwrite a markdown note in the configured Obsidian vault.",
172
+ inputSchema: {
173
+ path: z.string().min(1).describe("Note path relative to the vault root. .md is appended if missing."),
174
+ content: z.string().describe("Full markdown body to write."),
175
+ append: z.boolean().optional().describe("If true, append to an existing note instead of replacing."),
176
+ },
177
+ annotations: MUTATING,
178
+ _meta: {},
179
+ }, async ({ path, content, append }) => {
180
+ try {
181
+ const vault = resolveVaultRoot(config);
182
+ let rel = path.replace(/\\/g, "/");
183
+ if (!rel.toLowerCase().endsWith(".md") && !rel.toLowerCase().endsWith(".markdown")) {
184
+ rel = `${rel}.md`;
185
+ }
186
+ const absolute = assertInsideVault(vault, rel);
187
+ await mkdir(dirname(absolute), { recursive: true });
188
+ if (append && existsSync(absolute)) {
189
+ const previous = await readFile(absolute, "utf8");
190
+ await writeFile(absolute, `${previous}${previous.endsWith("\n") ? "" : "\n"}${content}`, "utf8");
191
+ }
192
+ else {
193
+ await writeFile(absolute, content, "utf8");
194
+ }
195
+ return text({
196
+ path: relative(vault, absolute).replace(/\\/g, "/"),
197
+ bytes: Buffer.byteLength(content, "utf8"),
198
+ append: Boolean(append),
199
+ });
200
+ }
201
+ catch (error) {
202
+ return text(error instanceof Error ? error.message : String(error), true);
203
+ }
204
+ });
205
+ }