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.
- package/LICENSE +21 -21
- package/README.md +366 -233
- package/addons/auvrynt_bridge/auvrynt_bridge.gd +500 -0
- package/addons/auvrynt_bridge/plugin.cfg +7 -0
- package/bin/auvrynt-launcher.cjs +77 -0
- package/dist/artifact-registry.js +1 -0
- package/dist/aseprite-tools.js +1 -0
- package/dist/auth/connection-registry.js +145 -0
- package/dist/auth/connection-status.js +176 -0
- package/dist/auth/oauth-provider.js +617 -0
- package/dist/auth/room-registry.js +131 -0
- package/dist/auth/session-registry.js +531 -0
- package/dist/background-lifecycle.js +1 -0
- package/dist/blender-client.js +1 -109
- package/dist/blender-tools.js +1 -930
- package/dist/browser-stability.js +1 -0
- package/dist/cli/commands/help-command.js +10 -0
- package/dist/cli/commands/init-command.js +190 -0
- package/dist/cli/commands/integration-commands.js +88 -0
- package/dist/cli/commands/serve-command.js +83 -0
- package/dist/cli/commands/setup-command.js +81 -0
- package/dist/cli/commands/status-commands.js +166 -0
- package/dist/cli/commands/tunnel-command.js +127 -0
- package/dist/cli/commands/user-config-commands.js +105 -0
- package/dist/cli/dashboard-actions.js +516 -0
- package/dist/cli/dashboard-native-actions.js +282 -0
- package/dist/cli/foreground-server.js +270 -0
- package/dist/cli/instance-control.js +21 -0
- package/dist/cli/instance-lock.js +123 -0
- package/dist/cli/integration-bootstrap.js +206 -0
- package/dist/cli/lifecycle-manager.js +493 -0
- package/dist/cli/runtime-support.js +74 -0
- package/dist/cli/serena-detected-default.js +27 -0
- package/dist/cli/tunnel-health-monitor.js +182 -0
- package/dist/cli.js +82 -739
- package/dist/config.js +1 -243
- package/dist/connection-registry.js +1 -73
- package/dist/connection-status.js +1 -139
- package/dist/control-retry.js +1 -0
- package/dist/crash-recovery.js +1 -0
- package/dist/db/client.js +16 -3
- package/dist/db/schema.js +30 -0
- package/dist/dotnet-tools.js +1 -223
- package/dist/git-worktrees.js +1 -134
- package/dist/git.js +1 -41
- package/dist/godot-animation-tilemap.js +1 -82
- package/dist/godot-csharp-build.js +1 -93
- package/dist/godot-csharp-project.js +1 -157
- package/dist/godot-csharp-runner.js +1 -146
- package/dist/godot-csharp-semantic.js +1 -161
- package/dist/godot-csharp-validate.js +1 -71
- package/dist/godot-dotnet-env.js +1 -169
- package/dist/godot-editor-bridge.js +1 -140
- package/dist/godot-gdscript.js +1 -824
- package/dist/godot-project-settings.js +1 -223
- package/dist/godot-runtime-testing.js +1 -249
- package/dist/godot-tools.js +1 -183
- package/dist/http-rate-limit.js +1 -0
- package/dist/http-server-hardening.js +1 -0
- package/dist/image-tools.js +1 -157
- package/dist/infrastructure/command-reference.js +32 -0
- package/dist/infrastructure/config.js +424 -0
- package/dist/infrastructure/context7-auth.js +55 -0
- package/dist/infrastructure/http-rate-limit.js +42 -0
- package/dist/infrastructure/http-server-hardening.js +23 -0
- package/dist/infrastructure/integration-queue.js +46 -0
- package/dist/infrastructure/logger.js +129 -0
- package/dist/infrastructure/mcp-event-store.js +103 -0
- package/dist/infrastructure/ngrok-auth-pool.js +208 -0
- package/dist/infrastructure/request-context.js +14 -0
- package/dist/infrastructure/shutdown.js +37 -0
- package/dist/infrastructure/sse-heartbeat.js +47 -0
- package/dist/infrastructure/tool-capabilities.js +67 -0
- package/dist/infrastructure/tool-result-budget.js +175 -0
- package/dist/infrastructure/user-config.js +167 -0
- package/dist/integration-discovery.js +1 -98
- package/dist/integration-queue.js +1 -0
- package/dist/integrations/agent-reach/agent-reach-tools.js +196 -0
- package/dist/integrations/agent-reach/native-channels.js +468 -0
- package/dist/integrations/aseprite/aseprite-analysis-tools.js +368 -0
- package/dist/integrations/aseprite/aseprite-editing-tools.js +647 -0
- package/dist/integrations/aseprite/aseprite-live-tools.js +297 -0
- package/dist/integrations/aseprite/aseprite-safety-tools.js +594 -0
- package/dist/integrations/aseprite/aseprite-specialized-tools.js +289 -0
- package/dist/integrations/aseprite/aseprite-tools.js +837 -0
- package/dist/integrations/blender/blender-catalog-mesh.js +593 -0
- package/dist/integrations/blender/blender-catalog-object.js +906 -0
- package/dist/integrations/blender/blender-catalog-scene.js +266 -0
- package/dist/integrations/blender/blender-catalog-select.js +581 -0
- package/dist/integrations/blender/blender-catalog-stubs.js +7512 -0
- package/dist/integrations/blender/blender-catalog.js +165 -0
- package/dist/integrations/blender/blender-client.js +105 -0
- package/dist/integrations/blender/blender-tools.js +2243 -0
- package/dist/integrations/context7/context7-tools.js +106 -0
- package/dist/integrations/dotnet/dotnet-tools.js +195 -0
- package/dist/integrations/godot/godot-animation-tilemap.js +74 -0
- package/dist/integrations/godot/godot-csharp-build.js +91 -0
- package/dist/integrations/godot/godot-csharp-project.js +155 -0
- package/dist/integrations/godot/godot-csharp-runner.js +118 -0
- package/dist/integrations/godot/godot-csharp-semantic.js +146 -0
- package/dist/integrations/godot/godot-csharp-validate.js +71 -0
- package/dist/integrations/godot/godot-dotnet-env.js +134 -0
- package/dist/integrations/godot/godot-editor-bridge.js +328 -0
- package/dist/integrations/godot/godot-gdscript.js +536 -0
- package/dist/integrations/godot/godot-project-settings.js +178 -0
- package/dist/integrations/godot/godot-runtime-testing.js +263 -0
- package/dist/integrations/godot/godot-tools.js +193 -0
- package/dist/integrations/images/image-tools.js +414 -0
- package/dist/integrations/images/png-codec.js +251 -0
- package/dist/integrations/images/view-image.js +99 -0
- package/dist/integrations/images/window-capture.js +148 -0
- package/dist/integrations/integration-discovery.js +185 -0
- package/dist/integrations/obsidian/obsidian-tools.js +205 -0
- package/dist/integrations/playwright/browser-session.js +516 -0
- package/dist/integrations/playwright/browser-stability.js +36 -0
- package/dist/integrations/playwright/playwright-runtime.js +105 -0
- package/dist/integrations/playwright/web-tools.js +504 -0
- package/dist/integrations/roblox/roblox-helpers.js +381 -0
- package/dist/integrations/roblox/roblox-studio-client.js +112 -0
- package/dist/integrations/roblox/roblox-tools.js +106 -0
- package/dist/integrations/serena/serena-manager.js +464 -0
- package/dist/integrations/serena/serena-tools.js +411 -0
- package/dist/logger.js +1 -76
- package/dist/mcp-event-store.js +1 -0
- package/dist/oauth-provider.js +1 -377
- package/dist/pi-tools.js +1 -81
- package/dist/playwright-runtime.js +1 -0
- package/dist/process/background-lifecycle.js +189 -0
- package/dist/process/control-retry.js +42 -0
- package/dist/process/crash-recovery.js +23 -0
- package/dist/process/processes.js +456 -0
- package/dist/processes.js +1 -218
- package/dist/request-context.js +1 -0
- package/dist/review-checkpoints.js +1 -142
- package/dist/room-registry.js +1 -0
- package/dist/roots.js +1 -53
- package/dist/search-discovery.js +1 -271
- package/dist/serena-manager.js +1 -443
- package/dist/serena-tools.js +1 -411
- package/dist/server/dashboard-page-styles.js +331 -0
- package/dist/server/dashboard-page.js +1509 -0
- package/dist/server/dashboard-routes.js +46 -0
- package/dist/server/dashboard.js +240 -0
- package/dist/server/http-helpers.js +30 -0
- package/dist/server/integration-profile-update.js +37 -0
- package/dist/server/mcp-policy.js +169 -0
- package/dist/server/mcp-server-factory.js +127 -0
- package/dist/server/mcp-tool-registrar.js +182 -0
- package/dist/server/openai-session-hint.js +14 -0
- package/dist/server/tool-groups.js +29 -0
- package/dist/server/tool-logging.js +33 -0
- package/dist/server/tool-registration-shared.js +59 -0
- package/dist/server/tools/aseprite-advanced-tools-registration.js +547 -0
- package/dist/server/tools/aseprite-tools-registration.js +213 -0
- package/dist/server/tools/blender-tools-registration.js +690 -0
- package/dist/server/tools/core-file-tools-registration.js +459 -0
- package/dist/server/tools/dotnet-godot-window-tools-registration.js +120 -0
- package/dist/server/tools/godot-csharp-tools-registration.js +252 -0
- package/dist/server/tools/godot-gdscript-tools-registration.js +189 -0
- package/dist/server/tools/process-project-tools-registration.js +155 -0
- package/dist/server/tools/roblox-tools-registration.js +514 -0
- package/dist/server/tools/web-image-tools-registration.js +326 -0
- package/dist/server/tools/workspace-lifecycle-tools-registration.js +130 -0
- package/dist/server/ui-assets.js +97 -0
- package/dist/server/workspace-analytics.js +92 -0
- package/dist/server.js +453 -2713
- package/dist/session-registry.js +1 -0
- package/dist/shutdown.js +1 -0
- package/dist/skills.js +1 -45
- package/dist/sse-heartbeat.js +1 -0
- package/dist/tool-capabilities.js +1 -0
- package/dist/tool-result-budget.js +1 -0
- package/dist/tools/pi-tools.js +81 -0
- package/dist/tunnels/cloudflare-tunnel.js +217 -0
- package/dist/tunnels/cloudflared-service.js +174 -0
- package/dist/tunnels/ngrok-tunnel.js +220 -0
- package/dist/tunnels/tunnel-manager.js +186 -0
- package/dist/tunnels/tunnel-types.js +1 -0
- package/dist/tunnels/tunnel-utils.js +62 -0
- package/dist/ui/.vite/manifest.json +9 -2487
- package/dist/ui/assets/heavy-payload-D42A9ceL.js +1 -0
- package/dist/ui/assets/lightweight-diff-Cv4g9Hdr.js +13 -0
- package/dist/ui/assets/review-payload-DKIg1cKF.js +1 -0
- package/dist/ui/assets/workspace-app-CeK3NhmB.css +1 -0
- package/dist/ui/assets/{workspace-app-C5QsE314.js → workspace-app-CkUXnpl4.js} +6 -6
- package/dist/ui/brand-theme.js +23 -0
- package/dist/ui/workspace-app.html +15 -15
- package/dist/user-config.js +1 -57
- package/dist/view-image.js +1 -104
- package/dist/web-tools.js +1 -200
- package/dist/window-capture.js +1 -74
- package/dist/workspace/artifact-registry.js +69 -0
- package/dist/workspace/git-worktrees.js +141 -0
- package/dist/workspace/git.js +42 -0
- package/dist/workspace/review-checkpoints.js +142 -0
- package/dist/workspace/roots.js +56 -0
- package/dist/workspace/search-discovery.js +264 -0
- package/dist/workspace/skills.js +45 -0
- package/dist/workspace/workspace-store.js +219 -0
- package/dist/workspace/workspaces.js +314 -0
- package/dist/workspace-store.js +1 -125
- package/dist/workspaces.js +1 -226
- package/docs/CREATOR_STORE_FREE_ASSETS.md +162 -0
- package/docs/DEVELOPMENT_TOOLS.md +136 -93
- package/docs/assets/auvrynt-icon.png +0 -0
- package/docs/assets/auvrynt-icon.svg +20 -0
- package/docs/chatgpt-coding-workflow.md +143 -143
- package/docs/configuration.md +156 -124
- package/docs/diagnostics.md +79 -0
- package/docs/gotchas.md +244 -202
- package/docs/multi-agent-and-long-projects.md +91 -0
- package/docs/security.md +138 -100
- package/docs/setup.md +171 -131
- package/docs/source-layout.md +60 -0
- package/extensions/auvrynt_bridge/auvrynt_bridge.lua +594 -0
- package/extensions/auvrynt_bridge/live_analysis.lua +181 -0
- package/extensions/auvrynt_bridge/live_animation.lua +134 -0
- package/extensions/auvrynt_bridge/live_commands.lua +24 -0
- package/extensions/auvrynt_bridge/live_common.lua +130 -0
- package/extensions/auvrynt_bridge/live_document.lua +78 -0
- package/extensions/auvrynt_bridge/live_drawing.lua +125 -0
- package/extensions/auvrynt_bridge/live_effects.lua +91 -0
- package/extensions/auvrynt_bridge/live_palette_template.lua +167 -0
- package/extensions/auvrynt_bridge/live_selection.lua +110 -0
- package/extensions/auvrynt_bridge/live_structure.lua +129 -0
- package/extensions/auvrynt_bridge/package.json +17 -0
- package/guides/ASEPRITE_AGENT_GUIDE.md +133 -0
- package/guides/BLENDER_AGENT_GUIDE.md +472 -0
- package/guides/GODOT_AGENT_GUIDE.md +298 -0
- package/guides/PROJECT_ROUTER.md +165 -0
- package/guides/ROBLOX_AGENT_GUIDE.md +75 -0
- package/guides/SOFTWARE_AGENT_GUIDE.md +104 -0
- package/guides/WEB_AGENT_GUIDE.md +287 -0
- package/package.json +78 -70
- package/scripts/dev-server.mjs +121 -120
- package/scripts/live-tunnel-smoke.mjs +538 -0
- package/scripts/repo-hygiene.mjs +74 -0
- package/scripts/restart-after-crash.mjs +49 -0
- package/scripts/run-tests.mjs +166 -0
- package/dist/ui/assets/abap-CLvhMVsD.js +0 -1
- package/dist/ui/assets/actionscript-3--17pq3dv.js +0 -1
- package/dist/ui/assets/ada-C5qYipkI.js +0 -1
- package/dist/ui/assets/andromeeda-vGVdxbeo.js +0 -1
- package/dist/ui/assets/angular-html-BJqQFYI6.js +0 -1
- package/dist/ui/assets/angular-ts-CMJECO0Y.js +0 -1
- package/dist/ui/assets/apache-U0d_L8uA.js +0 -1
- package/dist/ui/assets/apex-CGTLDQj6.js +0 -1
- package/dist/ui/assets/apl-DWeXpBBr.js +0 -1
- package/dist/ui/assets/applescript-CCn79oCD.js +0 -1
- package/dist/ui/assets/ara-4CJ0cIlV.js +0 -1
- package/dist/ui/assets/asciidoc-DE70LPWp.js +0 -1
- package/dist/ui/assets/asm-Cmm7eHzH.js +0 -1
- package/dist/ui/assets/astro-CLbttLOq.js +0 -1
- package/dist/ui/assets/aurora-x-CDeNXAV0.js +0 -1
- package/dist/ui/assets/awk-BWXHIvNe.js +0 -1
- package/dist/ui/assets/ayu-dark-DluEY0Gj.js +0 -1
- package/dist/ui/assets/ayu-light-C3h-C4tm.js +0 -1
- package/dist/ui/assets/ayu-mirage-Bqwy1Gya.js +0 -1
- package/dist/ui/assets/ballerina-B7ZEbQpA.js +0 -1
- package/dist/ui/assets/bat-Bo4NYOV-.js +0 -1
- package/dist/ui/assets/beancount-D-usSTwE.js +0 -1
- package/dist/ui/assets/berry-DKpUyyne.js +0 -1
- package/dist/ui/assets/bibtex-Ci_nEsc7.js +0 -1
- package/dist/ui/assets/bicep-CUHmPFLl.js +0 -1
- package/dist/ui/assets/bird2-C2hNVINV.js +0 -1
- package/dist/ui/assets/blade-BOzY0P2V.js +0 -1
- package/dist/ui/assets/bsl-BkkzgIyY.js +0 -1
- package/dist/ui/assets/c-BG-8uJvh.js +0 -1
- package/dist/ui/assets/c3-CnJL0r0V.js +0 -1
- package/dist/ui/assets/cadence-CQ2zXKGN.js +0 -1
- package/dist/ui/assets/cairo-DLTphjLi.js +0 -1
- package/dist/ui/assets/catppuccin-frappe-3VR1Za6u.js +0 -1
- package/dist/ui/assets/catppuccin-latte-DwIHMF0Q.js +0 -1
- package/dist/ui/assets/catppuccin-macchiato-DYnBP6_5.js +0 -1
- package/dist/ui/assets/catppuccin-mocha-DYhrFGRu.js +0 -1
- package/dist/ui/assets/clarity-SemFz856.js +0 -1
- package/dist/ui/assets/clojure-DqKBuwfJ.js +0 -1
- package/dist/ui/assets/cmake-Bj61d0ZC.js +0 -1
- package/dist/ui/assets/cobol-I_17IuGe.js +0 -1
- package/dist/ui/assets/codeowners-C8r90Shi.js +0 -1
- package/dist/ui/assets/codeql-oeQT6MSM.js +0 -1
- package/dist/ui/assets/coffee-C0B8hmok.js +0 -1
- package/dist/ui/assets/common-lisp-Cv5bFMCO.js +0 -1
- package/dist/ui/assets/coq-BrsZFFmf.js +0 -1
- package/dist/ui/assets/cpp-DDJXt6Vs.js +0 -1
- package/dist/ui/assets/crystal-Bexqace6.js +0 -1
- package/dist/ui/assets/csharp-Ct8U2NOr.js +0 -1
- package/dist/ui/assets/css-DSQhw_9R.js +0 -1
- package/dist/ui/assets/csv-Dx-8-gkx.js +0 -1
- package/dist/ui/assets/cue-CE9AQfxI.js +0 -1
- package/dist/ui/assets/cypher-ClKdZ_lG.js +0 -1
- package/dist/ui/assets/d-qD-0Kul2.js +0 -1
- package/dist/ui/assets/dark-plus-Cs2F2srj.js +0 -1
- package/dist/ui/assets/dart-DkHntEIa.js +0 -1
- package/dist/ui/assets/dax-BkyTk9wS.js +0 -1
- package/dist/ui/assets/desktop-Dlh5hvp9.js +0 -1
- package/dist/ui/assets/diff-woXpYk--.js +0 -1
- package/dist/ui/assets/docker-IyjqRm3v.js +0 -1
- package/dist/ui/assets/dotenv-_5a1GRtc.js +0 -1
- package/dist/ui/assets/dracula-BHWKrbxM.js +0 -1
- package/dist/ui/assets/dracula-soft-5eyTD99u.js +0 -1
- package/dist/ui/assets/dream-maker-DW3nJb8Q.js +0 -1
- package/dist/ui/assets/edge-Z8YYkHOr.js +0 -1
- package/dist/ui/assets/elixir-CG9uKtAF.js +0 -1
- package/dist/ui/assets/elm-GfWG2IfT.js +0 -1
- package/dist/ui/assets/emacs-lisp-C9PiwqqW.js +0 -1
- package/dist/ui/assets/erb-xe89e73J.js +0 -1
- package/dist/ui/assets/erlang-Cphh6RMH.js +0 -1
- package/dist/ui/assets/everforest-dark-sB-x3p7T.js +0 -1
- package/dist/ui/assets/everforest-light-Df2xbC6M.js +0 -1
- package/dist/ui/assets/fennel-DQxkIbk2.js +0 -1
- package/dist/ui/assets/fish-BJitypiv.js +0 -1
- package/dist/ui/assets/fluent-C03EYrpw.js +0 -1
- package/dist/ui/assets/fortran-fixed-form-DEKoE2YW.js +0 -1
- package/dist/ui/assets/fortran-free-form-CYNrtFtB.js +0 -1
- package/dist/ui/assets/fsharp-D13ZGOAj.js +0 -1
- package/dist/ui/assets/gdresource-C0sCabJj.js +0 -1
- package/dist/ui/assets/gdscript-Cp2uCuqX.js +0 -1
- package/dist/ui/assets/gdshader-CBce3t8t.js +0 -1
- package/dist/ui/assets/genie-CV2tkWYe.js +0 -1
- package/dist/ui/assets/gherkin-DExj1W_8.js +0 -1
- package/dist/ui/assets/git-commit-BSykSTBG.js +0 -1
- package/dist/ui/assets/git-rebase-CoTL_uSE.js +0 -1
- package/dist/ui/assets/github-dark-C-LZuMrd.js +0 -1
- package/dist/ui/assets/github-dark-default-DXG-b-1a.js +0 -1
- package/dist/ui/assets/github-dark-dimmed-Bx1FflLF.js +0 -1
- package/dist/ui/assets/github-dark-high-contrast-B_tTalzw.js +0 -1
- package/dist/ui/assets/github-light-EUqPIrTm.js +0 -1
- package/dist/ui/assets/github-light-default-BXViO-2h.js +0 -1
- package/dist/ui/assets/github-light-high-contrast-B68TUdTA.js +0 -1
- package/dist/ui/assets/gleam-CSRkHgEL.js +0 -1
- package/dist/ui/assets/glimmer-js-DAn4UCSu.js +0 -1
- package/dist/ui/assets/glimmer-ts-Tjyi6Gh5.js +0 -1
- package/dist/ui/assets/glsl-CtTDZoqR.js +0 -1
- package/dist/ui/assets/gn-ilITqXS6.js +0 -1
- package/dist/ui/assets/gnuplot-7GGW24-e.js +0 -1
- package/dist/ui/assets/go-BJwz_mda.js +0 -1
- package/dist/ui/assets/graphql-D5gcC_Jk.js +0 -1
- package/dist/ui/assets/groovy-CacY0gHj.js +0 -1
- package/dist/ui/assets/gruvbox-dark-hard-C820rvS2.js +0 -1
- package/dist/ui/assets/gruvbox-dark-medium-BPjhmG05.js +0 -1
- package/dist/ui/assets/gruvbox-dark-soft-MrdJrrXF.js +0 -1
- package/dist/ui/assets/gruvbox-light-hard-BC_s9l72.js +0 -1
- package/dist/ui/assets/gruvbox-light-medium-BAWPOn9u.js +0 -1
- package/dist/ui/assets/gruvbox-light-soft-BSMLrYjP.js +0 -1
- package/dist/ui/assets/hack-BJXY27dt.js +0 -1
- package/dist/ui/assets/haml-BLfFoZf7.js +0 -1
- package/dist/ui/assets/handlebars-Dw6CWkvN.js +0 -1
- package/dist/ui/assets/haskell-D8IpX4py.js +0 -1
- package/dist/ui/assets/haxe-OTjmBuCE.js +0 -1
- package/dist/ui/assets/hcl-Dh228itO.js +0 -1
- package/dist/ui/assets/heavy-payload-Dcg0-F-S.js +0 -4
- package/dist/ui/assets/hjson-CxZEssPk.js +0 -1
- package/dist/ui/assets/hlsl-Cvrh5tZx.js +0 -1
- package/dist/ui/assets/horizon-CE9ld1lL.js +0 -1
- package/dist/ui/assets/horizon-bright-Br1oVSNq.js +0 -1
- package/dist/ui/assets/houston-CsvMBhTu.js +0 -1
- package/dist/ui/assets/html-CAcAWvoN.js +0 -1
- package/dist/ui/assets/html-derivative-8aSW2E_7.js +0 -1
- package/dist/ui/assets/http-B2YR_3V1.js +0 -1
- package/dist/ui/assets/hurl-BnDJ9Zhf.js +0 -1
- package/dist/ui/assets/hxml-B0Qn7Nwc.js +0 -1
- package/dist/ui/assets/hy-CZbG8q4J.js +0 -1
- package/dist/ui/assets/imba-DsUTQ-LC.js +0 -1
- package/dist/ui/assets/ini-B5eOa1yu.js +0 -1
- package/dist/ui/assets/java-Doxi4W8u.js +0 -1
- package/dist/ui/assets/javascript-BbRdEqti.js +0 -1
- package/dist/ui/assets/jinja-CS3Tpv_Q.js +0 -1
- package/dist/ui/assets/jison-BkPGYVHR.js +0 -1
- package/dist/ui/assets/json-BMt1m3m8.js +0 -1
- package/dist/ui/assets/json5-BR5RXkoi.js +0 -1
- package/dist/ui/assets/jsonc-CYpm1nAK.js +0 -1
- package/dist/ui/assets/jsonl-CmCQp5Yx.js +0 -1
- package/dist/ui/assets/jsonnet-CJTPZ8u_.js +0 -1
- package/dist/ui/assets/jssm-DXw9l8Rf.js +0 -1
- package/dist/ui/assets/jsx-CQKrJXXY.js +0 -1
- package/dist/ui/assets/julia-BuN7i2du.js +0 -1
- package/dist/ui/assets/just-BswEPFPu.js +0 -1
- package/dist/ui/assets/kanagawa-dragon-CXtmUGW6.js +0 -1
- package/dist/ui/assets/kanagawa-lotus-BN08jTvb.js +0 -1
- package/dist/ui/assets/kanagawa-wave-CTweb8Dz.js +0 -1
- package/dist/ui/assets/kdl-CsD5j6eV.js +0 -1
- package/dist/ui/assets/kotlin-DhhofPvG.js +0 -1
- package/dist/ui/assets/kusto-BUv0MjJC.js +0 -1
- package/dist/ui/assets/laserwave-C_8bwKvT.js +0 -1
- package/dist/ui/assets/latex-DU2VyFfA.js +0 -1
- package/dist/ui/assets/lean-CewbzKMR.js +0 -1
- package/dist/ui/assets/less-DVTAwKKz.js +0 -1
- package/dist/ui/assets/light-plus-DVQuIRkW.js +0 -1
- package/dist/ui/assets/liquid-Cmz1L3dq.js +0 -1
- package/dist/ui/assets/llvm-Cm23YOpf.js +0 -1
- package/dist/ui/assets/log-BNLmms1o.js +0 -1
- package/dist/ui/assets/logo-Cluzi2Zq.js +0 -1
- package/dist/ui/assets/lua-CfVXhkaJ.js +0 -1
- package/dist/ui/assets/luau-CNKltnaQ.js +0 -1
- package/dist/ui/assets/make-Dixweg8N.js +0 -1
- package/dist/ui/assets/markdown-BYOwaDjH.js +0 -1
- package/dist/ui/assets/marko-C5bfqGiA.js +0 -1
- package/dist/ui/assets/material-theme-Bm3Qr25_.js +0 -1
- package/dist/ui/assets/material-theme-darker-2IIEA8gg.js +0 -1
- package/dist/ui/assets/material-theme-lighter-uhdI0v04.js +0 -1
- package/dist/ui/assets/material-theme-ocean-CHQ94UKr.js +0 -1
- package/dist/ui/assets/material-theme-palenight-B5W6OYN7.js +0 -1
- package/dist/ui/assets/matlab-D7qyCx1q.js +0 -1
- package/dist/ui/assets/mdc-CVBXYfyq.js +0 -1
- package/dist/ui/assets/mdx-DQZ5AkYe.js +0 -1
- package/dist/ui/assets/mermaid-Bk4SNUv9.js +0 -1
- package/dist/ui/assets/min-dark-BSWPekZh.js +0 -1
- package/dist/ui/assets/min-light-DDpmG2fV.js +0 -1
- package/dist/ui/assets/mipsasm-BMqwQI7S.js +0 -1
- package/dist/ui/assets/mojo-BgCJLMeH.js +0 -1
- package/dist/ui/assets/monokai-CdkpiU2Y.js +0 -1
- package/dist/ui/assets/moonbit-CaWjb8XO.js +0 -1
- package/dist/ui/assets/move-B1IS1UjX.js +0 -1
- package/dist/ui/assets/narrat-_X_XdTYD.js +0 -1
- package/dist/ui/assets/nextflow-Bbiyy34d.js +0 -1
- package/dist/ui/assets/nextflow-groovy-Dc_ddanL.js +0 -1
- package/dist/ui/assets/nginx-CzJafxLa.js +0 -1
- package/dist/ui/assets/night-owl-DhmEMT88.js +0 -1
- package/dist/ui/assets/night-owl-light-eJ-hLW7d.js +0 -1
- package/dist/ui/assets/nim-DABKtHtM.js +0 -1
- package/dist/ui/assets/nix-IvuFDN5E.js +0 -1
- package/dist/ui/assets/nord-Cb4Vim4T.js +0 -1
- package/dist/ui/assets/nushell-DcLAeLz5.js +0 -1
- package/dist/ui/assets/objective-c-D1A_Heim.js +0 -1
- package/dist/ui/assets/objective-cpp-BsSzOQcm.js +0 -1
- package/dist/ui/assets/ocaml-O90oeIOV.js +0 -1
- package/dist/ui/assets/odin-B1RWQWA5.js +0 -1
- package/dist/ui/assets/one-dark-pro-CLwyXe_n.js +0 -1
- package/dist/ui/assets/one-light-D7Lr4KcI.js +0 -1
- package/dist/ui/assets/openscad-BUDT5pXO.js +0 -1
- package/dist/ui/assets/pascal-4ZHwLPI5.js +0 -1
- package/dist/ui/assets/perl-CBh7L3lZ.js +0 -1
- package/dist/ui/assets/php-DFbI9q5p.js +0 -1
- package/dist/ui/assets/pierre-dark-sU4Zdns8.js +0 -1
- package/dist/ui/assets/pierre-dark-soft-HXgun5vs.js +0 -1
- package/dist/ui/assets/pierre-light-DWBk51d8.js +0 -1
- package/dist/ui/assets/pierre-light-soft-CodEzPxf.js +0 -1
- package/dist/ui/assets/pkl-ot-7Btpt.js +0 -1
- package/dist/ui/assets/plastic-DQwYfKfQ.js +0 -1
- package/dist/ui/assets/plsql-DGHpHOYJ.js +0 -1
- package/dist/ui/assets/po-BiJDBrnU.js +0 -1
- package/dist/ui/assets/poimandres-DRFjx7u4.js +0 -1
- package/dist/ui/assets/polar-C7UOKdEL.js +0 -1
- package/dist/ui/assets/postcss-BXeXVLqQ.js +0 -1
- package/dist/ui/assets/powerquery-DNMTfnFr.js +0 -1
- package/dist/ui/assets/powershell-DshXNtvi.js +0 -1
- package/dist/ui/assets/prisma-BsRQq5mF.js +0 -1
- package/dist/ui/assets/prolog-iXnhIJG7.js +0 -1
- package/dist/ui/assets/proto-DB4EqR-F.js +0 -1
- package/dist/ui/assets/pug-C_PxC7gO.js +0 -1
- package/dist/ui/assets/puppet-CDv2pdJW.js +0 -1
- package/dist/ui/assets/purescript-9MfHhQsQ.js +0 -1
- package/dist/ui/assets/python-gzcpVVnB.js +0 -1
- package/dist/ui/assets/qml-DtngoFFK.js +0 -1
- package/dist/ui/assets/qmldir-DCQb3MpD.js +0 -1
- package/dist/ui/assets/qss-Fe1Jh2GI.js +0 -1
- package/dist/ui/assets/r-DohkcevW.js +0 -1
- package/dist/ui/assets/racket-DcIDlBhZ.js +0 -1
- package/dist/ui/assets/raku-B3gFvitq.js +0 -1
- package/dist/ui/assets/razor-C4t8J0_E.js +0 -1
- package/dist/ui/assets/red-CJ3rzSJv.js +0 -1
- package/dist/ui/assets/reg-CRGYupPL.js +0 -1
- package/dist/ui/assets/regexp-OGbTbjgY.js +0 -1
- package/dist/ui/assets/rel-BtDbiS_P.js +0 -1
- package/dist/ui/assets/review-payload-C5Qz60Kq.js +0 -1
- package/dist/ui/assets/riscv-Ckw8ddFX.js +0 -1
- package/dist/ui/assets/ron-VUp2lXgN.js +0 -1
- package/dist/ui/assets/rose-pine-BthvhNj6.js +0 -1
- package/dist/ui/assets/rose-pine-dawn-Dg85fqjY.js +0 -1
- package/dist/ui/assets/rose-pine-moon-hon4tzzS.js +0 -1
- package/dist/ui/assets/rosmsg-CAekHB0j.js +0 -1
- package/dist/ui/assets/rst-CfBbbcvC.js +0 -1
- package/dist/ui/assets/ruby-Bw0mpxHY.js +0 -1
- package/dist/ui/assets/rust-Cfkwpbl8.js +0 -1
- package/dist/ui/assets/sas-Cs3s9JOf.js +0 -1
- package/dist/ui/assets/sass-DXrisJhu.js +0 -1
- package/dist/ui/assets/scala-DKOlJaKm.js +0 -1
- package/dist/ui/assets/scheme-DQCgrYNe.js +0 -1
- package/dist/ui/assets/scss-sRxNJS54.js +0 -1
- package/dist/ui/assets/sdbl-bTVj8UrX.js +0 -1
- package/dist/ui/assets/shaderlab-TOUzSsQk.js +0 -1
- package/dist/ui/assets/shellscript-B0X6wh0R.js +0 -1
- package/dist/ui/assets/shellsession-D2FdOioR.js +0 -1
- package/dist/ui/assets/slack-dark-DnToyrRv.js +0 -1
- package/dist/ui/assets/slack-ochin-B2OO5cIa.js +0 -1
- package/dist/ui/assets/smalltalk-B16xEiuN.js +0 -1
- package/dist/ui/assets/snazzy-light-4G7pJPwS.js +0 -1
- package/dist/ui/assets/solarized-dark-DV17i1UV.js +0 -1
- package/dist/ui/assets/solarized-light-DSh2HLQt.js +0 -1
- package/dist/ui/assets/solidity-CKzVLygQ.js +0 -1
- package/dist/ui/assets/soy-s6g9OjJ1.js +0 -1
- package/dist/ui/assets/sparql-D_iOobhT.js +0 -1
- package/dist/ui/assets/splunk-BC2Px7Mm.js +0 -1
- package/dist/ui/assets/sql-DVTnh5V-.js +0 -1
- package/dist/ui/assets/ssh-config-BgfXC-Er.js +0 -1
- package/dist/ui/assets/stata-DFIDiXF9.js +0 -1
- package/dist/ui/assets/stylus-B6D30XZt.js +0 -1
- package/dist/ui/assets/surrealql-DVfrsLyg.js +0 -1
- package/dist/ui/assets/svelte-D5GsxESq.js +0 -1
- package/dist/ui/assets/swift-DonLKvLd.js +0 -1
- package/dist/ui/assets/synthwave-84-nFMaYfgc.js +0 -1
- package/dist/ui/assets/system-verilog-DJ5XKQeo.js +0 -1
- package/dist/ui/assets/systemd-BxMlprV5.js +0 -1
- package/dist/ui/assets/talonscript-CohzipZa.js +0 -1
- package/dist/ui/assets/tasl-DMoTqEGO.js +0 -1
- package/dist/ui/assets/tcl-CZd0xW_V.js +0 -1
- package/dist/ui/assets/templ-DI-Zyqzd.js +0 -1
- package/dist/ui/assets/terraform-DswuEJGm.js +0 -1
- package/dist/ui/assets/tex-WHHmlbJI.js +0 -1
- package/dist/ui/assets/tokyo-night-oM2G3aXe.js +0 -1
- package/dist/ui/assets/toml-CcmNWLt0.js +0 -1
- package/dist/ui/assets/ts-tags-Dwpo2RFJ.js +0 -1
- package/dist/ui/assets/tsv-sltzmVWM.js +0 -1
- package/dist/ui/assets/tsx-ph_idaAW.js +0 -1
- package/dist/ui/assets/turtle-ByJddavk.js +0 -1
- package/dist/ui/assets/twig-YO17jFjR.js +0 -1
- package/dist/ui/assets/typescript-CbAxjhkl.js +0 -1
- package/dist/ui/assets/typespec-B88KGewJ.js +0 -1
- package/dist/ui/assets/typst-DI99ib-x.js +0 -1
- package/dist/ui/assets/useFileDiffInstance-B2DLX3Vg.js +0 -244
- package/dist/ui/assets/v-DETTlOr0.js +0 -1
- package/dist/ui/assets/vala-zf12oZj6.js +0 -1
- package/dist/ui/assets/vb-Djn5o6TS.js +0 -1
- package/dist/ui/assets/verilog-CiiDBU1e.js +0 -1
- package/dist/ui/assets/vesper-D5bVUKB1.js +0 -1
- package/dist/ui/assets/vhdl-BroJfC0k.js +0 -1
- package/dist/ui/assets/viml-DvXPmvsu.js +0 -1
- package/dist/ui/assets/vitesse-black-fwtXNY1n.js +0 -1
- package/dist/ui/assets/vitesse-dark-BZCL-v6S.js +0 -1
- package/dist/ui/assets/vitesse-light-VbXTXTou.js +0 -1
- package/dist/ui/assets/vue-CraHL-Ps.js +0 -1
- package/dist/ui/assets/vue-html-e9tyZNtS.js +0 -1
- package/dist/ui/assets/vue-vine-CofmxaUb.js +0 -1
- package/dist/ui/assets/vyper-CgoNMtux.js +0 -1
- package/dist/ui/assets/wasm-BnjxR4X6.js +0 -1
- package/dist/ui/assets/wasm-ByWQv1Qj.js +0 -1
- package/dist/ui/assets/wenyan-C8pVoKbM.js +0 -1
- package/dist/ui/assets/wgsl-BsKzXJz4.js +0 -1
- package/dist/ui/assets/wikitext-ClFFjSW2.js +0 -1
- package/dist/ui/assets/wit-DdvCle-K.js +0 -1
- package/dist/ui/assets/wolfram-DLL8P-h_.js +0 -1
- package/dist/ui/assets/workspace-app-8--oTbCd.css +0 -1
- package/dist/ui/assets/xml-BWSdPZHm.js +0 -1
- package/dist/ui/assets/xsl-BtCt7Hx8.js +0 -1
- package/dist/ui/assets/yaml-BZiTw7cQ.js +0 -1
- package/dist/ui/assets/zenscript-BnlCZFoB.js +0 -1
- package/dist/ui/assets/zig-CMLA9XwU.js +0 -1
- package/docs/assets/auvrynt-logo-light.png +0 -0
- package/docs/assets/auvrynt-screenshot.png +0 -0
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
+
import { readFile, rename, unlink, writeFile } from "node:fs/promises";
|
|
3
|
+
import { generateUnifiedPatch } from "@earendil-works/pi-coding-agent";
|
|
4
|
+
import * as z from "zod/v4";
|
|
5
|
+
import { logEvent } from "../../logger.js";
|
|
6
|
+
import { editFileTool, findFilesTool, grepFilesTool, listDirectoryTool, readFileTool, runShellTool, } from "../../pi-tools.js";
|
|
7
|
+
import { executeViewImage } from "../../view-image.js";
|
|
8
|
+
import { registerAppTool } from "../mcp-tool-registrar.js";
|
|
9
|
+
import { countTextLines } from "../workspace-analytics.js";
|
|
10
|
+
import { EDIT_TOOL_ANNOTATIONS, SHELL_TOOL_ANNOTATIONS, VIEW_IMAGE_TOOL_ANNOTATIONS, WRITE_TOOL_ANNOTATIONS, resultOutputSchema, toolWidgetDescriptorMeta, } from "../tool-registration-shared.js";
|
|
11
|
+
const MAX_WRITE_SIZE = 50 * 1024 * 1024;
|
|
12
|
+
async function safeWriteFile(filePath, content) {
|
|
13
|
+
const tempPath = `${filePath}.tmp.${randomUUID()}`;
|
|
14
|
+
try {
|
|
15
|
+
await writeFile(tempPath, content, "utf8");
|
|
16
|
+
await rename(tempPath, filePath);
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
await unlink(tempPath).catch(() => undefined);
|
|
20
|
+
throw error;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function contentText(content) {
|
|
24
|
+
return content.map((block) => block.type === "text" ? block.text : `[${block.mimeType} image]`).join("\n");
|
|
25
|
+
}
|
|
26
|
+
function textBlock(text) {
|
|
27
|
+
return { type: "text", text };
|
|
28
|
+
}
|
|
29
|
+
function textSummary(content) {
|
|
30
|
+
return {
|
|
31
|
+
blocks: content.length,
|
|
32
|
+
characters: content.filter((block) => block.type === "text")
|
|
33
|
+
.reduce((total, block) => total + block.text.length, 0),
|
|
34
|
+
images: content.filter((block) => block.type === "image").length,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function contentLineCount(content) {
|
|
38
|
+
return countTextLines(content);
|
|
39
|
+
}
|
|
40
|
+
async function readExistingTextFile(filePath) {
|
|
41
|
+
try {
|
|
42
|
+
return await readFile(filePath, "utf8");
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
if (error.code === "ENOENT")
|
|
46
|
+
return undefined;
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function countDiffStats(diff) {
|
|
51
|
+
if (!diff)
|
|
52
|
+
return { additions: 0, removals: 0 };
|
|
53
|
+
let additions = 0;
|
|
54
|
+
let removals = 0;
|
|
55
|
+
for (const line of diff.split(/\r?\n/)) {
|
|
56
|
+
if (line.startsWith("+++") || line.startsWith("---"))
|
|
57
|
+
continue;
|
|
58
|
+
if (line.startsWith("+"))
|
|
59
|
+
additions++;
|
|
60
|
+
if (line.startsWith("-"))
|
|
61
|
+
removals++;
|
|
62
|
+
}
|
|
63
|
+
return { additions, removals };
|
|
64
|
+
}
|
|
65
|
+
function contentLines(content) {
|
|
66
|
+
if (content.length === 0)
|
|
67
|
+
return [];
|
|
68
|
+
const lines = content.replace(/\r\n/g, "\n").split("\n");
|
|
69
|
+
if (lines.at(-1) === "")
|
|
70
|
+
lines.pop();
|
|
71
|
+
return lines;
|
|
72
|
+
}
|
|
73
|
+
function newFilePatch(path, content) {
|
|
74
|
+
const lines = contentLines(content);
|
|
75
|
+
const body = lines.map((line) => `+${line}`).join("\n");
|
|
76
|
+
return `--- /dev/null\n+++ b/${path}\n@@ -0,0 +1,${lines.length} @@\n${body}`;
|
|
77
|
+
}
|
|
78
|
+
export function registerCoreFileTools(server, config, workspaces, reviewCheckpoints, toolNames, workspaceChanges, logToolCall, logFailedToolResponse) {
|
|
79
|
+
registerAppTool(server, toolNames.read, {
|
|
80
|
+
title: "Read file",
|
|
81
|
+
description: [
|
|
82
|
+
"Read a file inside an open workspace. Use this for file inspection instead of shell commands like cat or sed. Call open_workspace first and pass workspaceId.",
|
|
83
|
+
"Use this tool to inspect relevant AGENTS.md or CLAUDE.md files listed by open_workspace before working in nested directories.",
|
|
84
|
+
config.skillsEnabled
|
|
85
|
+
? "If available skills were returned and a task matches one, read that skill's path before proceeding. Skill paths may be outside the workspace; only advertised SKILL.md files and files under already-loaded skill directories are readable."
|
|
86
|
+
: "",
|
|
87
|
+
].filter(Boolean).join(" "),
|
|
88
|
+
inputSchema: {
|
|
89
|
+
workspaceId: z.string().describe("Workspace identifier returned by open_workspace."),
|
|
90
|
+
path: z.string().describe(config.skillsEnabled
|
|
91
|
+
? "File path to read, relative to the workspace root. May also be an advertised skill path from open_workspace skills."
|
|
92
|
+
: "File path to read, relative to the workspace root."),
|
|
93
|
+
offset: z.number().int().positive().optional().describe("1-indexed line number to start reading from."),
|
|
94
|
+
limit: z.number().int().positive().optional().describe("Maximum number of lines to read."),
|
|
95
|
+
},
|
|
96
|
+
outputSchema: resultOutputSchema(),
|
|
97
|
+
...toolWidgetDescriptorMeta(config, "read"),
|
|
98
|
+
annotations: { readOnlyHint: true },
|
|
99
|
+
}, async ({ workspaceId, ...input }) => {
|
|
100
|
+
const startedAt = performance.now();
|
|
101
|
+
const workspace = workspaces.getWorkspace(workspaceId);
|
|
102
|
+
const readPath = workspaces.resolveReadPath(workspace, input.path);
|
|
103
|
+
const response = await readFileTool({ ...input, path: readPath.absolutePath }, {
|
|
104
|
+
cwd: workspace.root,
|
|
105
|
+
root: workspace.root,
|
|
106
|
+
readRoots: readPath.readRoots,
|
|
107
|
+
});
|
|
108
|
+
if (response.isError) {
|
|
109
|
+
logFailedToolResponse(config, { tool: toolNames.read, workspaceId, path: input.path }, response.content, startedAt);
|
|
110
|
+
return response;
|
|
111
|
+
}
|
|
112
|
+
workspaces.markReadPathLoaded(workspace, readPath);
|
|
113
|
+
logToolCall(config, {
|
|
114
|
+
tool: toolNames.read, workspaceId, path: input.path, success: true,
|
|
115
|
+
durationMs: Math.round(performance.now() - startedAt),
|
|
116
|
+
});
|
|
117
|
+
return {
|
|
118
|
+
...response,
|
|
119
|
+
_meta: {
|
|
120
|
+
tool: toolNames.read,
|
|
121
|
+
card: {
|
|
122
|
+
workspaceId, path: input.path,
|
|
123
|
+
summary: {
|
|
124
|
+
...textSummary(response.content),
|
|
125
|
+
lines: contentLineCount(contentText(response.content)),
|
|
126
|
+
offset: input.offset ?? 1,
|
|
127
|
+
limited: input.limit !== undefined,
|
|
128
|
+
},
|
|
129
|
+
payload: { content: response.content },
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
structuredContent: { result: contentText(response.content) },
|
|
133
|
+
};
|
|
134
|
+
});
|
|
135
|
+
registerAppTool(server, "view_image", {
|
|
136
|
+
title: "View image",
|
|
137
|
+
description: "View a local image file (.png, .jpg, .jpeg, .webp, .gif) inside an open workspace as visual MCP image content. Use this when asked to inspect, describe, analyze, or compare images. Call open_workspace first and pass workspaceId.",
|
|
138
|
+
inputSchema: {
|
|
139
|
+
workspaceId: z.string().describe("Workspace identifier returned by open_workspace."),
|
|
140
|
+
path: z.string().describe("Image file path, relative to the workspace root."),
|
|
141
|
+
},
|
|
142
|
+
...toolWidgetDescriptorMeta(config, "read"), annotations: VIEW_IMAGE_TOOL_ANNOTATIONS,
|
|
143
|
+
}, async ({ workspaceId, path }) => {
|
|
144
|
+
const startedAt = performance.now();
|
|
145
|
+
const response = await executeViewImage(workspaces, { workspaceId, path });
|
|
146
|
+
if (response.isError) {
|
|
147
|
+
logFailedToolResponse(config, { tool: "view_image", workspaceId, path }, response.content, startedAt);
|
|
148
|
+
return response;
|
|
149
|
+
}
|
|
150
|
+
logToolCall(config, {
|
|
151
|
+
tool: "view_image", workspaceId, path, success: true,
|
|
152
|
+
durationMs: Math.round(performance.now() - startedAt),
|
|
153
|
+
});
|
|
154
|
+
return response;
|
|
155
|
+
});
|
|
156
|
+
registerAppTool(server, toolNames.write, {
|
|
157
|
+
title: "Write file",
|
|
158
|
+
description: `Create or completely overwrite a file inside an open workspace. Prefer ${toolNames.edit} for targeted changes to existing files. Call open_workspace first and pass workspaceId.`,
|
|
159
|
+
inputSchema: {
|
|
160
|
+
workspaceId: z.string().describe("Workspace identifier returned by open_workspace."),
|
|
161
|
+
path: z.string().describe("File path to write, relative to the workspace root."),
|
|
162
|
+
content: z.string().describe("Complete new file content."),
|
|
163
|
+
expectedVersion: z.string().optional().describe("Expected SHA-256 hash (hex) of the current file content. If provided and the actual file hash differs, the write is rejected to prevent overwriting concurrent changes."),
|
|
164
|
+
},
|
|
165
|
+
outputSchema: resultOutputSchema(),
|
|
166
|
+
...toolWidgetDescriptorMeta(config, "write"), annotations: WRITE_TOOL_ANNOTATIONS,
|
|
167
|
+
}, async ({ workspaceId, expectedVersion, ...input }) => {
|
|
168
|
+
const startedAt = performance.now();
|
|
169
|
+
const workspace = workspaces.getWorkspace(workspaceId);
|
|
170
|
+
const absolutePath = workspaces.resolvePath(workspace, input.path);
|
|
171
|
+
if (input.content.length > MAX_WRITE_SIZE) {
|
|
172
|
+
throw new Error(`File content exceeds maximum write size of ${MAX_WRITE_SIZE} bytes (${input.content.length} bytes provided).`);
|
|
173
|
+
}
|
|
174
|
+
const previousContent = await readExistingTextFile(absolutePath);
|
|
175
|
+
if (expectedVersion && previousContent !== undefined) {
|
|
176
|
+
const currentHash = createHash("sha256").update(previousContent).digest("hex");
|
|
177
|
+
if (currentHash !== expectedVersion) {
|
|
178
|
+
logEvent(config.logging, "warn", "write_version_mismatch", {
|
|
179
|
+
path: input.path, expectedVersion, actualVersion: currentHash,
|
|
180
|
+
});
|
|
181
|
+
return {
|
|
182
|
+
content: [{ type: "text", text: `Write rejected: file content has changed since last read. Expected version ${expectedVersion.slice(0, 12)}… but actual version is ${currentHash.slice(0, 12)}…. Re-read the file before writing.` }],
|
|
183
|
+
isError: true,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
await safeWriteFile(absolutePath, input.content);
|
|
188
|
+
const changed = previousContent !== input.content;
|
|
189
|
+
const patch = !changed
|
|
190
|
+
? ""
|
|
191
|
+
: previousContent === undefined
|
|
192
|
+
? newFilePatch(input.path, input.content)
|
|
193
|
+
: generateUnifiedPatch(input.path, previousContent, input.content);
|
|
194
|
+
const stats = countDiffStats(patch);
|
|
195
|
+
if (changed) {
|
|
196
|
+
workspaceChanges.recordMutation({
|
|
197
|
+
workspaceId,
|
|
198
|
+
workspaceRoot: workspace.root,
|
|
199
|
+
path: input.path,
|
|
200
|
+
kind: previousContent === undefined ? "created" : "modified",
|
|
201
|
+
additions: stats.additions,
|
|
202
|
+
removals: stats.removals,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
const content = [{ type: "text", text: `Wrote ${contentLineCount(input.content)} lines to ${input.path}.` }];
|
|
206
|
+
logToolCall(config, {
|
|
207
|
+
tool: toolNames.write, workspaceId, path: input.path, success: true,
|
|
208
|
+
durationMs: Math.round(performance.now() - startedAt),
|
|
209
|
+
});
|
|
210
|
+
return {
|
|
211
|
+
content,
|
|
212
|
+
_meta: {
|
|
213
|
+
tool: toolNames.write,
|
|
214
|
+
card: {
|
|
215
|
+
workspaceId, path: input.path,
|
|
216
|
+
summary: { ...stats, lines: contentLineCount(input.content), characters: input.content.length },
|
|
217
|
+
payload: { content, patch },
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
structuredContent: { result: contentText(content) },
|
|
221
|
+
};
|
|
222
|
+
});
|
|
223
|
+
registerAppTool(server, toolNames.edit, {
|
|
224
|
+
title: "Edit file",
|
|
225
|
+
description: `Edit one file inside an open workspace by replacing exact text blocks. Prefer this over ${toolNames.write} for targeted changes. Each oldText must match a unique, non-overlapping region of the original file; merge nearby changes into one edit and keep oldText as small as possible while still unique. Call open_workspace first and pass workspaceId.`,
|
|
226
|
+
inputSchema: {
|
|
227
|
+
workspaceId: z.string().describe("Workspace identifier returned by open_workspace."),
|
|
228
|
+
path: z.string().describe("File path to edit, relative to the workspace root."),
|
|
229
|
+
edits: z.array(z.object({
|
|
230
|
+
oldText: z.string().describe("Exact text to replace. Must match uniquely in the original file."),
|
|
231
|
+
newText: z.string().describe("Replacement text."),
|
|
232
|
+
})).min(1),
|
|
233
|
+
},
|
|
234
|
+
outputSchema: resultOutputSchema({ status: z.literal("applied") }),
|
|
235
|
+
...toolWidgetDescriptorMeta(config, "edit"), annotations: EDIT_TOOL_ANNOTATIONS,
|
|
236
|
+
}, async ({ workspaceId, ...input }) => {
|
|
237
|
+
const startedAt = performance.now();
|
|
238
|
+
const workspace = workspaces.getWorkspace(workspaceId);
|
|
239
|
+
workspaces.resolvePath(workspace, input.path);
|
|
240
|
+
const response = await editFileTool(input, { cwd: workspace.root, root: workspace.root });
|
|
241
|
+
if (response.isError) {
|
|
242
|
+
logFailedToolResponse(config, { tool: toolNames.edit, workspaceId, path: input.path }, response.content, startedAt);
|
|
243
|
+
return response;
|
|
244
|
+
}
|
|
245
|
+
const stats = countDiffStats(response.details?.patch ?? response.details?.diff);
|
|
246
|
+
const content = [textBlock(`Edited ${input.path} (+${stats.additions} -${stats.removals}).`)];
|
|
247
|
+
if (stats.additions > 0 || stats.removals > 0) {
|
|
248
|
+
workspaceChanges.recordMutation({
|
|
249
|
+
workspaceId,
|
|
250
|
+
workspaceRoot: workspace.root,
|
|
251
|
+
path: input.path,
|
|
252
|
+
kind: "modified",
|
|
253
|
+
additions: stats.additions,
|
|
254
|
+
removals: stats.removals,
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
logToolCall(config, {
|
|
258
|
+
tool: toolNames.edit, workspaceId, path: input.path, success: true,
|
|
259
|
+
durationMs: Math.round(performance.now() - startedAt),
|
|
260
|
+
});
|
|
261
|
+
return {
|
|
262
|
+
content,
|
|
263
|
+
_meta: {
|
|
264
|
+
tool: toolNames.edit,
|
|
265
|
+
card: {
|
|
266
|
+
workspaceId, path: input.path, summary: { ...stats, editCount: input.edits.length },
|
|
267
|
+
payload: { diff: response.details?.diff, patch: response.details?.patch },
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
structuredContent: { status: "applied", result: contentText(content) },
|
|
271
|
+
};
|
|
272
|
+
});
|
|
273
|
+
if (config.widgets === "changes") {
|
|
274
|
+
registerAppTool(server, "show_changes", {
|
|
275
|
+
title: "Show changes",
|
|
276
|
+
description: "Show aggregate file changes in an open workspace since the last shown checkpoint or since the workspace was opened. After you create, edit, or overwrite files, call this once when the related file changes are complete so the user can inspect the combined diff.",
|
|
277
|
+
inputSchema: {
|
|
278
|
+
workspaceId: z.string().describe("Workspace identifier returned by open_workspace."),
|
|
279
|
+
since: z.enum(["last_shown", "workspace_open"]).optional().describe("Defaults to last_shown. Use workspace_open to compare against the initial open_workspace checkpoint."),
|
|
280
|
+
markReviewed: z.boolean().optional().describe("Defaults to true. When true, advances the last shown checkpoint to the current workspace state."),
|
|
281
|
+
},
|
|
282
|
+
outputSchema: resultOutputSchema(),
|
|
283
|
+
...toolWidgetDescriptorMeta(config, "show_changes"), annotations: { readOnlyHint: true },
|
|
284
|
+
}, async ({ workspaceId, since, markReviewed }) => {
|
|
285
|
+
const startedAt = performance.now();
|
|
286
|
+
const workspace = workspaces.getWorkspace(workspaceId);
|
|
287
|
+
const review = await reviewCheckpoints.reviewChanges({
|
|
288
|
+
workspaceId, root: workspace.root, since: since ?? "last_shown", markReviewed: markReviewed ?? true,
|
|
289
|
+
});
|
|
290
|
+
const content = [textBlock(review.result)];
|
|
291
|
+
logToolCall(config, {
|
|
292
|
+
tool: "show_changes", workspaceId, success: true,
|
|
293
|
+
durationMs: Math.round(performance.now() - startedAt),
|
|
294
|
+
});
|
|
295
|
+
return {
|
|
296
|
+
content,
|
|
297
|
+
_meta: {
|
|
298
|
+
tool: "show_changes",
|
|
299
|
+
card: { workspaceId, summary: review.summary, files: review.files, payload: { patch: review.patch } },
|
|
300
|
+
},
|
|
301
|
+
structuredContent: { result: contentText(content) },
|
|
302
|
+
};
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
if (!config.minimalTools) {
|
|
306
|
+
registerSearchTools(server, config, workspaces, toolNames, logToolCall, logFailedToolResponse);
|
|
307
|
+
}
|
|
308
|
+
registerAppTool(server, toolNames.shell, {
|
|
309
|
+
title: config.toolNaming === "short" ? "Bash" : "Run shell",
|
|
310
|
+
description: config.minimalTools
|
|
311
|
+
? `Run a shell command inside an open workspace. Use for tests, builds, git inspection, package scripts, search, file discovery, and directory inspection. In minimal tool mode, ${toolNames.grep}, ${toolNames.glob}, and ${toolNames.ls} are disabled; command-line search tools may be used instead. Prefer ${toolNames.read} for direct file reads and the dedicated edit/write tools for source changes. Shell commands execute with the local user's privileges and can modify files or run programs beyond what path-scoped file tools can do, so this tool requires the privileged auvrynt:process scope. Call open_workspace first and pass workspaceId.`
|
|
312
|
+
: `Run a shell command inside an open workspace for tests, builds, git inspection, package scripts, and commands that genuinely require a shell. Prefer ${toolNames.read}, ${toolNames.grep}, ${toolNames.glob}, and ${toolNames.ls} for inspection and the dedicated edit/write tools for source changes. Shell commands execute with the local user's privileges and can modify files or run programs beyond what path-scoped file tools can do, so this tool requires the privileged auvrynt:process scope. Call open_workspace first and pass workspaceId.`,
|
|
313
|
+
inputSchema: {
|
|
314
|
+
workspaceId: z.string().describe("Workspace identifier returned by open_workspace."),
|
|
315
|
+
command: z.string().describe(`Shell command to run. This executes with local-user privileges; prefer ${toolNames.edit} or ${toolNames.write} for ordinary source-file changes.`),
|
|
316
|
+
workingDirectory: z.string().optional().describe("Optional working directory relative to the workspace root. Defaults to the workspace root."),
|
|
317
|
+
timeout: z.number().positive().max(300).optional().describe("Timeout in seconds. Defaults to 30, max 300."),
|
|
318
|
+
},
|
|
319
|
+
outputSchema: resultOutputSchema(),
|
|
320
|
+
...toolWidgetDescriptorMeta(config, "shell"), annotations: SHELL_TOOL_ANNOTATIONS,
|
|
321
|
+
}, async ({ workspaceId, workingDirectory, ...input }) => {
|
|
322
|
+
const startedAt = performance.now();
|
|
323
|
+
const workspace = workspaces.getWorkspace(workspaceId);
|
|
324
|
+
const cwd = workspaces.resolveWorkingDirectory(workspace, workingDirectory);
|
|
325
|
+
const response = await runShellTool(input, { cwd, root: workspace.root });
|
|
326
|
+
if (response.isError) {
|
|
327
|
+
logFailedToolResponse(config, {
|
|
328
|
+
tool: toolNames.shell, workspaceId, workingDirectory: workingDirectory ?? ".",
|
|
329
|
+
command: input.command, commandLength: input.command.length,
|
|
330
|
+
}, response.content, startedAt);
|
|
331
|
+
return response;
|
|
332
|
+
}
|
|
333
|
+
logToolCall(config, {
|
|
334
|
+
tool: toolNames.shell, workspaceId, workingDirectory: workingDirectory ?? ".",
|
|
335
|
+
command: input.command, commandLength: input.command.length, success: true,
|
|
336
|
+
durationMs: Math.round(performance.now() - startedAt),
|
|
337
|
+
});
|
|
338
|
+
return {
|
|
339
|
+
...response,
|
|
340
|
+
_meta: {
|
|
341
|
+
tool: toolNames.shell,
|
|
342
|
+
card: {
|
|
343
|
+
workspaceId, path: workingDirectory,
|
|
344
|
+
summary: { command: input.command, workingDirectory: workingDirectory ?? ".", ...textSummary(response.content) },
|
|
345
|
+
payload: { content: response.content },
|
|
346
|
+
},
|
|
347
|
+
},
|
|
348
|
+
structuredContent: { result: contentText(response.content) },
|
|
349
|
+
};
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
function registerSearchTools(server, config, workspaces, toolNames, logToolCall, logFailedToolResponse) {
|
|
353
|
+
registerAppTool(server, toolNames.grep, {
|
|
354
|
+
title: config.toolNaming === "short" ? "Grep" : "Grep files",
|
|
355
|
+
description: "Search file contents inside an open workspace. Use this before broad reads when looking for symbols, text, or usage sites. Respects project ignore rules. Call open_workspace first and pass workspaceId.",
|
|
356
|
+
inputSchema: {
|
|
357
|
+
workspaceId: z.string().describe("Workspace identifier returned by open_workspace."),
|
|
358
|
+
pattern: z.string().describe("Search pattern."),
|
|
359
|
+
path: z.string().optional().describe("Optional path or glob scope relative to the workspace root."),
|
|
360
|
+
include: z.string().optional().describe("Optional include glob."),
|
|
361
|
+
},
|
|
362
|
+
outputSchema: resultOutputSchema(),
|
|
363
|
+
...toolWidgetDescriptorMeta(config, "search"), annotations: { readOnlyHint: true },
|
|
364
|
+
}, async ({ workspaceId, ...input }) => {
|
|
365
|
+
const startedAt = performance.now();
|
|
366
|
+
const workspace = workspaces.getWorkspace(workspaceId);
|
|
367
|
+
if (input.path)
|
|
368
|
+
workspaces.resolvePath(workspace, input.path);
|
|
369
|
+
const response = await grepFilesTool(input, { cwd: workspace.root, root: workspace.root });
|
|
370
|
+
if (response.isError) {
|
|
371
|
+
logFailedToolResponse(config, { tool: toolNames.grep, workspaceId, path: input.path }, response.content, startedAt);
|
|
372
|
+
return response;
|
|
373
|
+
}
|
|
374
|
+
logToolCall(config, {
|
|
375
|
+
tool: toolNames.grep, workspaceId, path: input.path, success: true,
|
|
376
|
+
durationMs: Math.round(performance.now() - startedAt),
|
|
377
|
+
});
|
|
378
|
+
return {
|
|
379
|
+
...response,
|
|
380
|
+
_meta: {
|
|
381
|
+
tool: toolNames.grep,
|
|
382
|
+
card: {
|
|
383
|
+
workspaceId, path: input.path,
|
|
384
|
+
summary: { pattern: input.pattern, scope: input.path ?? ".", ...textSummary(response.content) },
|
|
385
|
+
payload: { content: response.content },
|
|
386
|
+
},
|
|
387
|
+
},
|
|
388
|
+
structuredContent: { result: contentText(response.content) },
|
|
389
|
+
};
|
|
390
|
+
});
|
|
391
|
+
registerAppTool(server, toolNames.glob, {
|
|
392
|
+
title: config.toolNaming === "short" ? "Glob" : "Find files",
|
|
393
|
+
description: "Find files by glob pattern inside an open workspace. Use this to discover filenames or narrow file sets before reading. Respects project ignore rules. Call open_workspace first and pass workspaceId.",
|
|
394
|
+
inputSchema: {
|
|
395
|
+
workspaceId: z.string().describe("Workspace identifier returned by open_workspace."),
|
|
396
|
+
pattern: z.string().describe("File glob pattern."),
|
|
397
|
+
path: z.string().optional().describe("Optional path scope relative to the workspace root."),
|
|
398
|
+
},
|
|
399
|
+
outputSchema: resultOutputSchema(),
|
|
400
|
+
...toolWidgetDescriptorMeta(config, "search"), annotations: { readOnlyHint: true },
|
|
401
|
+
}, async ({ workspaceId, ...input }) => {
|
|
402
|
+
const startedAt = performance.now();
|
|
403
|
+
const workspace = workspaces.getWorkspace(workspaceId);
|
|
404
|
+
if (input.path)
|
|
405
|
+
workspaces.resolvePath(workspace, input.path);
|
|
406
|
+
const response = await findFilesTool(input, { cwd: workspace.root, root: workspace.root });
|
|
407
|
+
if (response.isError) {
|
|
408
|
+
logFailedToolResponse(config, { tool: toolNames.glob, workspaceId, path: input.path }, response.content, startedAt);
|
|
409
|
+
return response;
|
|
410
|
+
}
|
|
411
|
+
logToolCall(config, {
|
|
412
|
+
tool: toolNames.glob, workspaceId, path: input.path, success: true,
|
|
413
|
+
durationMs: Math.round(performance.now() - startedAt),
|
|
414
|
+
});
|
|
415
|
+
return {
|
|
416
|
+
...response,
|
|
417
|
+
_meta: {
|
|
418
|
+
tool: toolNames.glob,
|
|
419
|
+
card: {
|
|
420
|
+
workspaceId, path: input.path,
|
|
421
|
+
summary: { pattern: input.pattern, scope: input.path ?? ".", ...textSummary(response.content) },
|
|
422
|
+
payload: { content: response.content },
|
|
423
|
+
},
|
|
424
|
+
},
|
|
425
|
+
structuredContent: { result: contentText(response.content) },
|
|
426
|
+
};
|
|
427
|
+
});
|
|
428
|
+
registerAppTool(server, toolNames.ls, {
|
|
429
|
+
title: config.toolNaming === "short" ? "Ls" : "List directory",
|
|
430
|
+
description: "List a directory inside an open workspace. Use this for directory inspection before reading files. Call open_workspace first and pass workspaceId.",
|
|
431
|
+
inputSchema: {
|
|
432
|
+
workspaceId: z.string().describe("Workspace identifier returned by open_workspace."),
|
|
433
|
+
path: z.string().describe("Directory path to list, relative to the workspace root."),
|
|
434
|
+
},
|
|
435
|
+
outputSchema: resultOutputSchema(),
|
|
436
|
+
...toolWidgetDescriptorMeta(config, "directory"), annotations: { readOnlyHint: true },
|
|
437
|
+
}, async ({ workspaceId, ...input }) => {
|
|
438
|
+
const startedAt = performance.now();
|
|
439
|
+
const workspace = workspaces.getWorkspace(workspaceId);
|
|
440
|
+
workspaces.resolvePath(workspace, input.path);
|
|
441
|
+
const response = await listDirectoryTool(input, { cwd: workspace.root, root: workspace.root });
|
|
442
|
+
if (response.isError) {
|
|
443
|
+
logFailedToolResponse(config, { tool: toolNames.ls, workspaceId, path: input.path }, response.content, startedAt);
|
|
444
|
+
return response;
|
|
445
|
+
}
|
|
446
|
+
logToolCall(config, {
|
|
447
|
+
tool: toolNames.ls, workspaceId, path: input.path, success: true,
|
|
448
|
+
durationMs: Math.round(performance.now() - startedAt),
|
|
449
|
+
});
|
|
450
|
+
return {
|
|
451
|
+
...response,
|
|
452
|
+
_meta: {
|
|
453
|
+
tool: toolNames.ls,
|
|
454
|
+
card: { workspaceId, path: input.path, summary: textSummary(response.content), payload: { content: response.content } },
|
|
455
|
+
},
|
|
456
|
+
structuredContent: { result: contentText(response.content) },
|
|
457
|
+
};
|
|
458
|
+
});
|
|
459
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import * as z from "zod/v4";
|
|
2
|
+
import { dotnetBuild, dotnetFormat, dotnetRestore, dotnetRun, dotnetTest, inspectDotnetProject } from "../../dotnet-tools.js";
|
|
3
|
+
import { detectGodotProject, godotRun, inspectGodotScene } from "../../godot-tools.js";
|
|
4
|
+
import { captureWindow } from "../../window-capture.js";
|
|
5
|
+
import { registerAppTool } from "../mcp-tool-registrar.js";
|
|
6
|
+
import { MUTATING_ANNOTATIONS, PROCESS_ANNOTATIONS, READ_ONLY_ANNOTATIONS, WORKSPACE_ID_SCHEMA, toolWidgetDescriptorMeta, } from "../tool-registration-shared.js";
|
|
7
|
+
function jsonToolResult(action) {
|
|
8
|
+
return Promise.resolve()
|
|
9
|
+
.then(action)
|
|
10
|
+
.then((result) => ({ content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }))
|
|
11
|
+
.catch((error) => ({
|
|
12
|
+
content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }],
|
|
13
|
+
isError: true,
|
|
14
|
+
}));
|
|
15
|
+
}
|
|
16
|
+
export function registerDotnetGodotWindowTools(server, config, workspaces, processManager) {
|
|
17
|
+
registerAppTool(server, "inspect_dotnet_project", {
|
|
18
|
+
title: "Inspect .NET project",
|
|
19
|
+
description: "Parse a .csproj or .fsproj file and return SDK style, target frameworks, packages, test framework, and project references.",
|
|
20
|
+
inputSchema: { workspaceId: WORKSPACE_ID_SCHEMA, projectPath: z.string().describe("Workspace-relative path to .csproj or .fsproj.") },
|
|
21
|
+
...toolWidgetDescriptorMeta(config, "read"), annotations: READ_ONLY_ANNOTATIONS,
|
|
22
|
+
}, ({ workspaceId, projectPath }) => jsonToolResult(() => inspectDotnetProject(workspaces, { workspaceId, projectPath })));
|
|
23
|
+
registerAppTool(server, "dotnet_restore", {
|
|
24
|
+
title: "dotnet restore",
|
|
25
|
+
description: "Run dotnet restore on a .NET project. Returns success, duration, and key output.",
|
|
26
|
+
inputSchema: { workspaceId: WORKSPACE_ID_SCHEMA, projectPath: z.string().describe("Workspace-relative path to .csproj/.fsproj/.sln.") },
|
|
27
|
+
...toolWidgetDescriptorMeta(config, "shell"), annotations: PROCESS_ANNOTATIONS,
|
|
28
|
+
}, ({ workspaceId, projectPath }) => jsonToolResult(() => dotnetRestore(workspaces, { workspaceId, projectPath })));
|
|
29
|
+
registerAppTool(server, "dotnet_build", {
|
|
30
|
+
title: "dotnet build",
|
|
31
|
+
description: "Build a .NET project. Returns structured errors, warnings, and duration. Does not return raw build output.",
|
|
32
|
+
inputSchema: {
|
|
33
|
+
workspaceId: WORKSPACE_ID_SCHEMA,
|
|
34
|
+
projectPath: z.string().describe("Workspace-relative path to .csproj/.fsproj/.sln."),
|
|
35
|
+
configuration: z.enum(["Debug", "Release"]).optional().describe("Build configuration."),
|
|
36
|
+
noRestore: z.boolean().optional().describe("Skip restore step."),
|
|
37
|
+
},
|
|
38
|
+
...toolWidgetDescriptorMeta(config, "shell"), annotations: PROCESS_ANNOTATIONS,
|
|
39
|
+
}, ({ workspaceId, projectPath, configuration, noRestore }) => jsonToolResult(() => dotnetBuild(workspaces, { workspaceId, projectPath, configuration, noRestore })));
|
|
40
|
+
registerAppTool(server, "dotnet_test", {
|
|
41
|
+
title: "dotnet test",
|
|
42
|
+
description: "Run .NET tests. Returns pass/fail/skip counts, failed test names, and assertion messages.",
|
|
43
|
+
inputSchema: {
|
|
44
|
+
workspaceId: WORKSPACE_ID_SCHEMA,
|
|
45
|
+
projectPath: z.string().describe("Workspace-relative path to test .csproj/.sln."),
|
|
46
|
+
configuration: z.enum(["Debug", "Release"]).optional(),
|
|
47
|
+
filter: z.string().optional().describe("Test filter expression."),
|
|
48
|
+
noBuild: z.boolean().optional(),
|
|
49
|
+
},
|
|
50
|
+
...toolWidgetDescriptorMeta(config, "shell"), annotations: PROCESS_ANNOTATIONS,
|
|
51
|
+
}, ({ workspaceId, projectPath, configuration, filter, noBuild }) => jsonToolResult(() => dotnetTest(workspaces, { workspaceId, projectPath, configuration, filter, noBuild })));
|
|
52
|
+
registerAppTool(server, "dotnet_run", {
|
|
53
|
+
title: "dotnet run",
|
|
54
|
+
description: "Run a .NET project as a persistent process. Returns a processId. Use get_process_logs to tail output.",
|
|
55
|
+
inputSchema: {
|
|
56
|
+
workspaceId: WORKSPACE_ID_SCHEMA,
|
|
57
|
+
projectPath: z.string().describe("Workspace-relative path to .csproj."),
|
|
58
|
+
configuration: z.enum(["Debug", "Release"]).optional(),
|
|
59
|
+
arguments: z.array(z.string()).optional().describe("Arguments to pass to the application."),
|
|
60
|
+
environment: z.record(z.string(), z.string()).optional().describe("Environment variables."),
|
|
61
|
+
},
|
|
62
|
+
...toolWidgetDescriptorMeta(config, "shell"), annotations: PROCESS_ANNOTATIONS,
|
|
63
|
+
}, ({ workspaceId, projectPath, configuration, arguments: args, environment }) => jsonToolResult(() => dotnetRun(workspaces, processManager, { workspaceId, projectPath, configuration, arguments: args, environment })));
|
|
64
|
+
registerAppTool(server, "dotnet_format", {
|
|
65
|
+
title: "dotnet format",
|
|
66
|
+
description: "Format a .NET project. Use verifyOnly=true to check without modifying files.",
|
|
67
|
+
inputSchema: {
|
|
68
|
+
workspaceId: WORKSPACE_ID_SCHEMA,
|
|
69
|
+
projectPath: z.string().describe("Workspace-relative path to .csproj/.sln."),
|
|
70
|
+
verifyOnly: z.boolean().optional().describe("If true, check formatting without modifying files."),
|
|
71
|
+
},
|
|
72
|
+
...toolWidgetDescriptorMeta(config, "shell"), annotations: MUTATING_ANNOTATIONS,
|
|
73
|
+
}, ({ workspaceId, projectPath, verifyOnly }) => jsonToolResult(() => dotnetFormat(workspaces, { workspaceId, projectPath, verifyOnly })));
|
|
74
|
+
registerAppTool(server, "detect_godot_project", {
|
|
75
|
+
title: "Detect Godot project",
|
|
76
|
+
description: "Detect a Godot 4 project in the workspace. Reads project.godot for name, main scene, renderer, features, autoloads, and input actions.",
|
|
77
|
+
inputSchema: { workspaceId: WORKSPACE_ID_SCHEMA, path: z.string().optional().describe("Subdirectory to search, relative to workspace root.") },
|
|
78
|
+
...toolWidgetDescriptorMeta(config, "read"), annotations: READ_ONLY_ANNOTATIONS,
|
|
79
|
+
}, ({ workspaceId, path }) => jsonToolResult(() => detectGodotProject(workspaces, { workspaceId, path })));
|
|
80
|
+
registerAppTool(server, "godot_run", {
|
|
81
|
+
title: "Run Godot",
|
|
82
|
+
description: "Launch a Godot 4 game or editor as a persistent process. Returns a processId. Configure Godot executable via GODOT_EXECUTABLE env var.",
|
|
83
|
+
inputSchema: {
|
|
84
|
+
workspaceId: WORKSPACE_ID_SCHEMA,
|
|
85
|
+
projectPath: z.string().describe("Workspace-relative path to the project directory (containing project.godot)."),
|
|
86
|
+
scenePath: z.string().optional().describe("Workspace-relative scene path to run."),
|
|
87
|
+
editor: z.boolean().optional().describe("Open Godot editor instead of running game."),
|
|
88
|
+
debug: z.boolean().optional().describe("Enable debug mode."),
|
|
89
|
+
additionalArguments: z.array(z.string()).optional().describe("Additional CLI arguments."),
|
|
90
|
+
},
|
|
91
|
+
...toolWidgetDescriptorMeta(config, "shell"), annotations: PROCESS_ANNOTATIONS,
|
|
92
|
+
}, ({ workspaceId, projectPath, scenePath, editor, debug, additionalArguments }) => jsonToolResult(() => godotRun(workspaces, processManager, { workspaceId, projectPath, scenePath, editor, debug, additionalArguments })));
|
|
93
|
+
registerAppTool(server, "inspect_godot_scene", {
|
|
94
|
+
title: "Inspect Godot scene",
|
|
95
|
+
description: "Parse a Godot .tscn text scene file. Returns node tree, types, external resources, signals, and properties. Binary .scn files are not supported.",
|
|
96
|
+
inputSchema: { workspaceId: WORKSPACE_ID_SCHEMA, scenePath: z.string().describe("Workspace-relative path to .tscn scene file.") },
|
|
97
|
+
...toolWidgetDescriptorMeta(config, "read"), annotations: READ_ONLY_ANNOTATIONS,
|
|
98
|
+
}, ({ workspaceId, scenePath }) => jsonToolResult(() => inspectGodotScene(workspaces, { workspaceId, scenePath })));
|
|
99
|
+
registerAppTool(server, "capture_window", {
|
|
100
|
+
title: "Capture window",
|
|
101
|
+
description: "Capture a running application window tracked by Auvrynt. Returns the screenshot as MCP image content and saves it in the workspace. Windows only.",
|
|
102
|
+
inputSchema: {
|
|
103
|
+
workspaceId: WORKSPACE_ID_SCHEMA,
|
|
104
|
+
processId: z.string().optional().describe("Process ID from start_process to target."),
|
|
105
|
+
windowTitle: z.string().optional().describe("Window title substring to target."),
|
|
106
|
+
outputPath: z.string().describe("Workspace-relative path to save the screenshot PNG."),
|
|
107
|
+
},
|
|
108
|
+
...toolWidgetDescriptorMeta(config, "write"), annotations: MUTATING_ANNOTATIONS,
|
|
109
|
+
}, ({ workspaceId, processId, windowTitle, outputPath }) => captureWindow(workspaces, processManager, { workspaceId, processId, windowTitle, outputPath }));
|
|
110
|
+
registerAppTool(server, "godot_capture_game", {
|
|
111
|
+
title: "Capture Godot game",
|
|
112
|
+
description: "Capture a screenshot of a running Godot game tracked by an Auvrynt processId. Wraps capture_window.",
|
|
113
|
+
inputSchema: {
|
|
114
|
+
workspaceId: WORKSPACE_ID_SCHEMA,
|
|
115
|
+
processId: z.string().describe("Process ID from godot_run."),
|
|
116
|
+
outputPath: z.string().describe("Workspace-relative path to save the screenshot PNG."),
|
|
117
|
+
},
|
|
118
|
+
...toolWidgetDescriptorMeta(config, "write"), annotations: MUTATING_ANNOTATIONS,
|
|
119
|
+
}, ({ workspaceId, processId, outputPath }) => captureWindow(workspaces, processManager, { workspaceId, processId, outputPath }));
|
|
120
|
+
}
|