auvrynt 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +239 -0
- package/dist/blender-client.js +109 -0
- package/dist/blender-tools.js +930 -0
- package/dist/cli.js +370 -0
- package/dist/config.js +211 -0
- package/dist/connection-status.js +91 -0
- package/dist/db/client.js +22 -0
- package/dist/db/schema.js +29 -0
- package/dist/dotnet-tools.js +223 -0
- package/dist/git-worktrees.js +134 -0
- package/dist/git.js +41 -0
- package/dist/godot-animation-tilemap.js +82 -0
- package/dist/godot-csharp-build.js +93 -0
- package/dist/godot-csharp-project.js +157 -0
- package/dist/godot-csharp-runner.js +146 -0
- package/dist/godot-csharp-semantic.js +161 -0
- package/dist/godot-csharp-validate.js +71 -0
- package/dist/godot-dotnet-env.js +169 -0
- package/dist/godot-editor-bridge.js +140 -0
- package/dist/godot-gdscript.js +824 -0
- package/dist/godot-project-settings.js +223 -0
- package/dist/godot-runtime-testing.js +249 -0
- package/dist/godot-tools.js +183 -0
- package/dist/image-tools.js +157 -0
- package/dist/logger.js +76 -0
- package/dist/oauth-provider.js +266 -0
- package/dist/pi-tools.js +81 -0
- package/dist/processes.js +218 -0
- package/dist/review-checkpoints.js +142 -0
- package/dist/roots.js +53 -0
- package/dist/search-discovery.js +271 -0
- package/dist/serena-manager.js +443 -0
- package/dist/serena-tools.js +411 -0
- package/dist/server.js +2835 -0
- package/dist/skills.js +45 -0
- package/dist/ui/.vite/manifest.json +2520 -0
- package/dist/ui/assets/abap-CLvhMVsD.js +1 -0
- package/dist/ui/assets/actionscript-3--17pq3dv.js +1 -0
- package/dist/ui/assets/ada-C5qYipkI.js +1 -0
- package/dist/ui/assets/andromeeda-vGVdxbeo.js +1 -0
- package/dist/ui/assets/angular-html-BJqQFYI6.js +1 -0
- package/dist/ui/assets/angular-ts-CMJECO0Y.js +1 -0
- package/dist/ui/assets/apache-U0d_L8uA.js +1 -0
- package/dist/ui/assets/apex-CGTLDQj6.js +1 -0
- package/dist/ui/assets/apl-DWeXpBBr.js +1 -0
- package/dist/ui/assets/applescript-CCn79oCD.js +1 -0
- package/dist/ui/assets/ara-4CJ0cIlV.js +1 -0
- package/dist/ui/assets/asciidoc-DE70LPWp.js +1 -0
- package/dist/ui/assets/asm-Cmm7eHzH.js +1 -0
- package/dist/ui/assets/astro-CLbttLOq.js +1 -0
- package/dist/ui/assets/aurora-x-CDeNXAV0.js +1 -0
- package/dist/ui/assets/awk-BWXHIvNe.js +1 -0
- package/dist/ui/assets/ayu-dark-DluEY0Gj.js +1 -0
- package/dist/ui/assets/ayu-light-C3h-C4tm.js +1 -0
- package/dist/ui/assets/ayu-mirage-Bqwy1Gya.js +1 -0
- package/dist/ui/assets/ballerina-B7ZEbQpA.js +1 -0
- package/dist/ui/assets/bat-Bo4NYOV-.js +1 -0
- package/dist/ui/assets/beancount-D-usSTwE.js +1 -0
- package/dist/ui/assets/berry-DKpUyyne.js +1 -0
- package/dist/ui/assets/bibtex-Ci_nEsc7.js +1 -0
- package/dist/ui/assets/bicep-CUHmPFLl.js +1 -0
- package/dist/ui/assets/bird2-C2hNVINV.js +1 -0
- package/dist/ui/assets/blade-BOzY0P2V.js +1 -0
- package/dist/ui/assets/bsl-BkkzgIyY.js +1 -0
- package/dist/ui/assets/c-BG-8uJvh.js +1 -0
- package/dist/ui/assets/c3-CnJL0r0V.js +1 -0
- package/dist/ui/assets/cadence-CQ2zXKGN.js +1 -0
- package/dist/ui/assets/cairo-DLTphjLi.js +1 -0
- package/dist/ui/assets/catppuccin-frappe-3VR1Za6u.js +1 -0
- package/dist/ui/assets/catppuccin-latte-DwIHMF0Q.js +1 -0
- package/dist/ui/assets/catppuccin-macchiato-DYnBP6_5.js +1 -0
- package/dist/ui/assets/catppuccin-mocha-DYhrFGRu.js +1 -0
- package/dist/ui/assets/clarity-SemFz856.js +1 -0
- package/dist/ui/assets/clojure-DqKBuwfJ.js +1 -0
- package/dist/ui/assets/cmake-Bj61d0ZC.js +1 -0
- package/dist/ui/assets/cobol-I_17IuGe.js +1 -0
- package/dist/ui/assets/codeowners-C8r90Shi.js +1 -0
- package/dist/ui/assets/codeql-oeQT6MSM.js +1 -0
- package/dist/ui/assets/coffee-C0B8hmok.js +1 -0
- package/dist/ui/assets/common-lisp-Cv5bFMCO.js +1 -0
- package/dist/ui/assets/coq-BrsZFFmf.js +1 -0
- package/dist/ui/assets/cpp-DDJXt6Vs.js +1 -0
- package/dist/ui/assets/crystal-Bexqace6.js +1 -0
- package/dist/ui/assets/csharp-Ct8U2NOr.js +1 -0
- package/dist/ui/assets/css-DSQhw_9R.js +1 -0
- package/dist/ui/assets/csv-Dx-8-gkx.js +1 -0
- package/dist/ui/assets/cue-CE9AQfxI.js +1 -0
- package/dist/ui/assets/cypher-ClKdZ_lG.js +1 -0
- package/dist/ui/assets/d-qD-0Kul2.js +1 -0
- package/dist/ui/assets/dark-plus-Cs2F2srj.js +1 -0
- package/dist/ui/assets/dart-DkHntEIa.js +1 -0
- package/dist/ui/assets/dax-BkyTk9wS.js +1 -0
- package/dist/ui/assets/desktop-Dlh5hvp9.js +1 -0
- package/dist/ui/assets/diff-woXpYk--.js +1 -0
- package/dist/ui/assets/docker-IyjqRm3v.js +1 -0
- package/dist/ui/assets/dotenv-_5a1GRtc.js +1 -0
- package/dist/ui/assets/dracula-BHWKrbxM.js +1 -0
- package/dist/ui/assets/dracula-soft-5eyTD99u.js +1 -0
- package/dist/ui/assets/dream-maker-DW3nJb8Q.js +1 -0
- package/dist/ui/assets/edge-Z8YYkHOr.js +1 -0
- package/dist/ui/assets/elixir-CG9uKtAF.js +1 -0
- package/dist/ui/assets/elm-GfWG2IfT.js +1 -0
- package/dist/ui/assets/emacs-lisp-C9PiwqqW.js +1 -0
- package/dist/ui/assets/erb-xe89e73J.js +1 -0
- package/dist/ui/assets/erlang-Cphh6RMH.js +1 -0
- package/dist/ui/assets/everforest-dark-sB-x3p7T.js +1 -0
- package/dist/ui/assets/everforest-light-Df2xbC6M.js +1 -0
- package/dist/ui/assets/fennel-DQxkIbk2.js +1 -0
- package/dist/ui/assets/fish-BJitypiv.js +1 -0
- package/dist/ui/assets/fluent-C03EYrpw.js +1 -0
- package/dist/ui/assets/fortran-fixed-form-DEKoE2YW.js +1 -0
- package/dist/ui/assets/fortran-free-form-CYNrtFtB.js +1 -0
- package/dist/ui/assets/fsharp-D13ZGOAj.js +1 -0
- package/dist/ui/assets/gdresource-C0sCabJj.js +1 -0
- package/dist/ui/assets/gdscript-Cp2uCuqX.js +1 -0
- package/dist/ui/assets/gdshader-CBce3t8t.js +1 -0
- package/dist/ui/assets/genie-CV2tkWYe.js +1 -0
- package/dist/ui/assets/gherkin-DExj1W_8.js +1 -0
- package/dist/ui/assets/git-commit-BSykSTBG.js +1 -0
- package/dist/ui/assets/git-rebase-CoTL_uSE.js +1 -0
- package/dist/ui/assets/github-dark-C-LZuMrd.js +1 -0
- package/dist/ui/assets/github-dark-default-DXG-b-1a.js +1 -0
- package/dist/ui/assets/github-dark-dimmed-Bx1FflLF.js +1 -0
- package/dist/ui/assets/github-dark-high-contrast-B_tTalzw.js +1 -0
- package/dist/ui/assets/github-light-EUqPIrTm.js +1 -0
- package/dist/ui/assets/github-light-default-BXViO-2h.js +1 -0
- package/dist/ui/assets/github-light-high-contrast-B68TUdTA.js +1 -0
- package/dist/ui/assets/gleam-CSRkHgEL.js +1 -0
- package/dist/ui/assets/glimmer-js-DAn4UCSu.js +1 -0
- package/dist/ui/assets/glimmer-ts-Tjyi6Gh5.js +1 -0
- package/dist/ui/assets/glsl-CtTDZoqR.js +1 -0
- package/dist/ui/assets/gn-ilITqXS6.js +1 -0
- package/dist/ui/assets/gnuplot-7GGW24-e.js +1 -0
- package/dist/ui/assets/go-BJwz_mda.js +1 -0
- package/dist/ui/assets/graphql-D5gcC_Jk.js +1 -0
- package/dist/ui/assets/groovy-CacY0gHj.js +1 -0
- package/dist/ui/assets/gruvbox-dark-hard-C820rvS2.js +1 -0
- package/dist/ui/assets/gruvbox-dark-medium-BPjhmG05.js +1 -0
- package/dist/ui/assets/gruvbox-dark-soft-MrdJrrXF.js +1 -0
- package/dist/ui/assets/gruvbox-light-hard-BC_s9l72.js +1 -0
- package/dist/ui/assets/gruvbox-light-medium-BAWPOn9u.js +1 -0
- package/dist/ui/assets/gruvbox-light-soft-BSMLrYjP.js +1 -0
- package/dist/ui/assets/hack-BJXY27dt.js +1 -0
- package/dist/ui/assets/haml-BLfFoZf7.js +1 -0
- package/dist/ui/assets/handlebars-Dw6CWkvN.js +1 -0
- package/dist/ui/assets/haskell-D8IpX4py.js +1 -0
- package/dist/ui/assets/haxe-OTjmBuCE.js +1 -0
- package/dist/ui/assets/hcl-Dh228itO.js +1 -0
- package/dist/ui/assets/heavy-payload-Dcg0-F-S.js +4 -0
- package/dist/ui/assets/hjson-CxZEssPk.js +1 -0
- package/dist/ui/assets/hlsl-Cvrh5tZx.js +1 -0
- package/dist/ui/assets/horizon-CE9ld1lL.js +1 -0
- package/dist/ui/assets/horizon-bright-Br1oVSNq.js +1 -0
- package/dist/ui/assets/houston-CsvMBhTu.js +1 -0
- package/dist/ui/assets/html-CAcAWvoN.js +1 -0
- package/dist/ui/assets/html-derivative-8aSW2E_7.js +1 -0
- package/dist/ui/assets/http-B2YR_3V1.js +1 -0
- package/dist/ui/assets/hurl-BnDJ9Zhf.js +1 -0
- package/dist/ui/assets/hxml-B0Qn7Nwc.js +1 -0
- package/dist/ui/assets/hy-CZbG8q4J.js +1 -0
- package/dist/ui/assets/imba-DsUTQ-LC.js +1 -0
- package/dist/ui/assets/ini-B5eOa1yu.js +1 -0
- package/dist/ui/assets/java-Doxi4W8u.js +1 -0
- package/dist/ui/assets/javascript-BbRdEqti.js +1 -0
- package/dist/ui/assets/jinja-CS3Tpv_Q.js +1 -0
- package/dist/ui/assets/jison-BkPGYVHR.js +1 -0
- package/dist/ui/assets/json-BMt1m3m8.js +1 -0
- package/dist/ui/assets/json5-BR5RXkoi.js +1 -0
- package/dist/ui/assets/jsonc-CYpm1nAK.js +1 -0
- package/dist/ui/assets/jsonl-CmCQp5Yx.js +1 -0
- package/dist/ui/assets/jsonnet-CJTPZ8u_.js +1 -0
- package/dist/ui/assets/jssm-DXw9l8Rf.js +1 -0
- package/dist/ui/assets/jsx-CQKrJXXY.js +1 -0
- package/dist/ui/assets/julia-BuN7i2du.js +1 -0
- package/dist/ui/assets/just-BswEPFPu.js +1 -0
- package/dist/ui/assets/kanagawa-dragon-CXtmUGW6.js +1 -0
- package/dist/ui/assets/kanagawa-lotus-BN08jTvb.js +1 -0
- package/dist/ui/assets/kanagawa-wave-CTweb8Dz.js +1 -0
- package/dist/ui/assets/kdl-CsD5j6eV.js +1 -0
- package/dist/ui/assets/kotlin-DhhofPvG.js +1 -0
- package/dist/ui/assets/kusto-BUv0MjJC.js +1 -0
- package/dist/ui/assets/laserwave-C_8bwKvT.js +1 -0
- package/dist/ui/assets/latex-DU2VyFfA.js +1 -0
- package/dist/ui/assets/lean-CewbzKMR.js +1 -0
- package/dist/ui/assets/less-DVTAwKKz.js +1 -0
- package/dist/ui/assets/light-plus-DVQuIRkW.js +1 -0
- package/dist/ui/assets/liquid-Cmz1L3dq.js +1 -0
- package/dist/ui/assets/llvm-Cm23YOpf.js +1 -0
- package/dist/ui/assets/log-BNLmms1o.js +1 -0
- package/dist/ui/assets/logo-Cluzi2Zq.js +1 -0
- package/dist/ui/assets/lua-CfVXhkaJ.js +1 -0
- package/dist/ui/assets/luau-CNKltnaQ.js +1 -0
- package/dist/ui/assets/make-Dixweg8N.js +1 -0
- package/dist/ui/assets/markdown-BYOwaDjH.js +1 -0
- package/dist/ui/assets/marko-C5bfqGiA.js +1 -0
- package/dist/ui/assets/material-theme-Bm3Qr25_.js +1 -0
- package/dist/ui/assets/material-theme-darker-2IIEA8gg.js +1 -0
- package/dist/ui/assets/material-theme-lighter-uhdI0v04.js +1 -0
- package/dist/ui/assets/material-theme-ocean-CHQ94UKr.js +1 -0
- package/dist/ui/assets/material-theme-palenight-B5W6OYN7.js +1 -0
- package/dist/ui/assets/matlab-D7qyCx1q.js +1 -0
- package/dist/ui/assets/mdc-CVBXYfyq.js +1 -0
- package/dist/ui/assets/mdx-DQZ5AkYe.js +1 -0
- package/dist/ui/assets/mermaid-Bk4SNUv9.js +1 -0
- package/dist/ui/assets/min-dark-BSWPekZh.js +1 -0
- package/dist/ui/assets/min-light-DDpmG2fV.js +1 -0
- package/dist/ui/assets/mipsasm-BMqwQI7S.js +1 -0
- package/dist/ui/assets/mojo-BgCJLMeH.js +1 -0
- package/dist/ui/assets/monokai-CdkpiU2Y.js +1 -0
- package/dist/ui/assets/moonbit-CaWjb8XO.js +1 -0
- package/dist/ui/assets/move-B1IS1UjX.js +1 -0
- package/dist/ui/assets/narrat-_X_XdTYD.js +1 -0
- package/dist/ui/assets/nextflow-Bbiyy34d.js +1 -0
- package/dist/ui/assets/nextflow-groovy-Dc_ddanL.js +1 -0
- package/dist/ui/assets/nginx-CzJafxLa.js +1 -0
- package/dist/ui/assets/night-owl-DhmEMT88.js +1 -0
- package/dist/ui/assets/night-owl-light-eJ-hLW7d.js +1 -0
- package/dist/ui/assets/nim-DABKtHtM.js +1 -0
- package/dist/ui/assets/nix-IvuFDN5E.js +1 -0
- package/dist/ui/assets/nord-Cb4Vim4T.js +1 -0
- package/dist/ui/assets/nushell-DcLAeLz5.js +1 -0
- package/dist/ui/assets/objective-c-D1A_Heim.js +1 -0
- package/dist/ui/assets/objective-cpp-BsSzOQcm.js +1 -0
- package/dist/ui/assets/ocaml-O90oeIOV.js +1 -0
- package/dist/ui/assets/odin-B1RWQWA5.js +1 -0
- package/dist/ui/assets/one-dark-pro-CLwyXe_n.js +1 -0
- package/dist/ui/assets/one-light-D7Lr4KcI.js +1 -0
- package/dist/ui/assets/openscad-BUDT5pXO.js +1 -0
- package/dist/ui/assets/pascal-4ZHwLPI5.js +1 -0
- package/dist/ui/assets/perl-CBh7L3lZ.js +1 -0
- package/dist/ui/assets/php-DFbI9q5p.js +1 -0
- package/dist/ui/assets/pierre-dark-sU4Zdns8.js +1 -0
- package/dist/ui/assets/pierre-dark-soft-HXgun5vs.js +1 -0
- package/dist/ui/assets/pierre-light-DWBk51d8.js +1 -0
- package/dist/ui/assets/pierre-light-soft-CodEzPxf.js +1 -0
- package/dist/ui/assets/pkl-ot-7Btpt.js +1 -0
- package/dist/ui/assets/plastic-DQwYfKfQ.js +1 -0
- package/dist/ui/assets/plsql-DGHpHOYJ.js +1 -0
- package/dist/ui/assets/po-BiJDBrnU.js +1 -0
- package/dist/ui/assets/poimandres-DRFjx7u4.js +1 -0
- package/dist/ui/assets/polar-C7UOKdEL.js +1 -0
- package/dist/ui/assets/postcss-BXeXVLqQ.js +1 -0
- package/dist/ui/assets/powerquery-DNMTfnFr.js +1 -0
- package/dist/ui/assets/powershell-DshXNtvi.js +1 -0
- package/dist/ui/assets/prisma-BsRQq5mF.js +1 -0
- package/dist/ui/assets/prolog-iXnhIJG7.js +1 -0
- package/dist/ui/assets/proto-DB4EqR-F.js +1 -0
- package/dist/ui/assets/pug-C_PxC7gO.js +1 -0
- package/dist/ui/assets/puppet-CDv2pdJW.js +1 -0
- package/dist/ui/assets/purescript-9MfHhQsQ.js +1 -0
- package/dist/ui/assets/python-gzcpVVnB.js +1 -0
- package/dist/ui/assets/qml-DtngoFFK.js +1 -0
- package/dist/ui/assets/qmldir-DCQb3MpD.js +1 -0
- package/dist/ui/assets/qss-Fe1Jh2GI.js +1 -0
- package/dist/ui/assets/r-DohkcevW.js +1 -0
- package/dist/ui/assets/racket-DcIDlBhZ.js +1 -0
- package/dist/ui/assets/raku-B3gFvitq.js +1 -0
- package/dist/ui/assets/razor-C4t8J0_E.js +1 -0
- package/dist/ui/assets/red-CJ3rzSJv.js +1 -0
- package/dist/ui/assets/reg-CRGYupPL.js +1 -0
- package/dist/ui/assets/regexp-OGbTbjgY.js +1 -0
- package/dist/ui/assets/rel-BtDbiS_P.js +1 -0
- package/dist/ui/assets/review-payload-C5Qz60Kq.js +1 -0
- package/dist/ui/assets/riscv-Ckw8ddFX.js +1 -0
- package/dist/ui/assets/ron-VUp2lXgN.js +1 -0
- package/dist/ui/assets/rose-pine-BthvhNj6.js +1 -0
- package/dist/ui/assets/rose-pine-dawn-Dg85fqjY.js +1 -0
- package/dist/ui/assets/rose-pine-moon-hon4tzzS.js +1 -0
- package/dist/ui/assets/rosmsg-CAekHB0j.js +1 -0
- package/dist/ui/assets/rst-CfBbbcvC.js +1 -0
- package/dist/ui/assets/ruby-Bw0mpxHY.js +1 -0
- package/dist/ui/assets/rust-Cfkwpbl8.js +1 -0
- package/dist/ui/assets/sas-Cs3s9JOf.js +1 -0
- package/dist/ui/assets/sass-DXrisJhu.js +1 -0
- package/dist/ui/assets/scala-DKOlJaKm.js +1 -0
- package/dist/ui/assets/scheme-DQCgrYNe.js +1 -0
- package/dist/ui/assets/scss-sRxNJS54.js +1 -0
- package/dist/ui/assets/sdbl-bTVj8UrX.js +1 -0
- package/dist/ui/assets/shaderlab-TOUzSsQk.js +1 -0
- package/dist/ui/assets/shellscript-B0X6wh0R.js +1 -0
- package/dist/ui/assets/shellsession-D2FdOioR.js +1 -0
- package/dist/ui/assets/slack-dark-DnToyrRv.js +1 -0
- package/dist/ui/assets/slack-ochin-B2OO5cIa.js +1 -0
- package/dist/ui/assets/smalltalk-B16xEiuN.js +1 -0
- package/dist/ui/assets/snazzy-light-4G7pJPwS.js +1 -0
- package/dist/ui/assets/solarized-dark-DV17i1UV.js +1 -0
- package/dist/ui/assets/solarized-light-DSh2HLQt.js +1 -0
- package/dist/ui/assets/solidity-CKzVLygQ.js +1 -0
- package/dist/ui/assets/soy-s6g9OjJ1.js +1 -0
- package/dist/ui/assets/sparql-D_iOobhT.js +1 -0
- package/dist/ui/assets/splunk-BC2Px7Mm.js +1 -0
- package/dist/ui/assets/sql-DVTnh5V-.js +1 -0
- package/dist/ui/assets/ssh-config-BgfXC-Er.js +1 -0
- package/dist/ui/assets/stata-DFIDiXF9.js +1 -0
- package/dist/ui/assets/stylus-B6D30XZt.js +1 -0
- package/dist/ui/assets/surrealql-DVfrsLyg.js +1 -0
- package/dist/ui/assets/svelte-D5GsxESq.js +1 -0
- package/dist/ui/assets/swift-DonLKvLd.js +1 -0
- package/dist/ui/assets/synthwave-84-nFMaYfgc.js +1 -0
- package/dist/ui/assets/system-verilog-DJ5XKQeo.js +1 -0
- package/dist/ui/assets/systemd-BxMlprV5.js +1 -0
- package/dist/ui/assets/talonscript-CohzipZa.js +1 -0
- package/dist/ui/assets/tasl-DMoTqEGO.js +1 -0
- package/dist/ui/assets/tcl-CZd0xW_V.js +1 -0
- package/dist/ui/assets/templ-DI-Zyqzd.js +1 -0
- package/dist/ui/assets/terraform-DswuEJGm.js +1 -0
- package/dist/ui/assets/tex-WHHmlbJI.js +1 -0
- package/dist/ui/assets/tokyo-night-oM2G3aXe.js +1 -0
- package/dist/ui/assets/toml-CcmNWLt0.js +1 -0
- package/dist/ui/assets/ts-tags-Dwpo2RFJ.js +1 -0
- package/dist/ui/assets/tsv-sltzmVWM.js +1 -0
- package/dist/ui/assets/tsx-ph_idaAW.js +1 -0
- package/dist/ui/assets/turtle-ByJddavk.js +1 -0
- package/dist/ui/assets/twig-YO17jFjR.js +1 -0
- package/dist/ui/assets/typescript-CbAxjhkl.js +1 -0
- package/dist/ui/assets/typespec-B88KGewJ.js +1 -0
- package/dist/ui/assets/typst-DI99ib-x.js +1 -0
- package/dist/ui/assets/useFileDiffInstance-B2DLX3Vg.js +244 -0
- package/dist/ui/assets/v-DETTlOr0.js +1 -0
- package/dist/ui/assets/vala-zf12oZj6.js +1 -0
- package/dist/ui/assets/vb-Djn5o6TS.js +1 -0
- package/dist/ui/assets/verilog-CiiDBU1e.js +1 -0
- package/dist/ui/assets/vesper-D5bVUKB1.js +1 -0
- package/dist/ui/assets/vhdl-BroJfC0k.js +1 -0
- package/dist/ui/assets/viml-DvXPmvsu.js +1 -0
- package/dist/ui/assets/vitesse-black-fwtXNY1n.js +1 -0
- package/dist/ui/assets/vitesse-dark-BZCL-v6S.js +1 -0
- package/dist/ui/assets/vitesse-light-VbXTXTou.js +1 -0
- package/dist/ui/assets/vue-CraHL-Ps.js +1 -0
- package/dist/ui/assets/vue-html-e9tyZNtS.js +1 -0
- package/dist/ui/assets/vue-vine-CofmxaUb.js +1 -0
- package/dist/ui/assets/vyper-CgoNMtux.js +1 -0
- package/dist/ui/assets/wasm-BnjxR4X6.js +1 -0
- package/dist/ui/assets/wasm-ByWQv1Qj.js +1 -0
- package/dist/ui/assets/wenyan-C8pVoKbM.js +1 -0
- package/dist/ui/assets/wgsl-BsKzXJz4.js +1 -0
- package/dist/ui/assets/wikitext-ClFFjSW2.js +1 -0
- package/dist/ui/assets/wit-DdvCle-K.js +1 -0
- package/dist/ui/assets/wolfram-DLL8P-h_.js +1 -0
- package/dist/ui/assets/workspace-app-8--oTbCd.css +1 -0
- package/dist/ui/assets/workspace-app-C5QsE314.js +118 -0
- package/dist/ui/assets/xml-BWSdPZHm.js +1 -0
- package/dist/ui/assets/xsl-BtCt7Hx8.js +1 -0
- package/dist/ui/assets/yaml-BZiTw7cQ.js +1 -0
- package/dist/ui/assets/zenscript-BnlCZFoB.js +1 -0
- package/dist/ui/assets/zig-CMLA9XwU.js +1 -0
- package/dist/ui/workspace-app.html +15 -0
- package/dist/user-config.js +57 -0
- package/dist/view-image.js +104 -0
- package/dist/web-tools.js +200 -0
- package/dist/window-capture.js +74 -0
- package/dist/workspace-store.js +125 -0
- package/dist/workspaces.js +226 -0
- package/docs/DEVELOPMENT_TOOLS.md +95 -0
- package/docs/assets/auvrynt-logo-light.png +0 -0
- package/docs/assets/auvrynt-screenshot.png +0 -0
- package/docs/chatgpt-coding-workflow.md +143 -0
- package/docs/configuration.md +132 -0
- package/docs/gotchas.md +215 -0
- package/docs/security.md +100 -0
- package/docs/setup.md +132 -0
- package/package.json +70 -0
- package/scripts/dev-server.mjs +120 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { index, primaryKey, sqliteTable, text } from "drizzle-orm/sqlite-core";
|
|
2
|
+
export const workspaceSessions = sqliteTable("workspace_sessions", {
|
|
3
|
+
id: text("id").primaryKey(),
|
|
4
|
+
root: text("root").notNull(),
|
|
5
|
+
status: text("status").notNull().default("active"),
|
|
6
|
+
mode: text("mode").notNull().default("checkout"),
|
|
7
|
+
sourceRoot: text("source_root"),
|
|
8
|
+
baseRef: text("base_ref"),
|
|
9
|
+
baseSha: text("base_sha"),
|
|
10
|
+
managed: text("managed").notNull().default("false"),
|
|
11
|
+
createdAt: text("created_at").notNull(),
|
|
12
|
+
lastUsedAt: text("last_used_at").notNull(),
|
|
13
|
+
}, (table) => [
|
|
14
|
+
index("workspace_sessions_root_idx").on(table.root, table.lastUsedAt),
|
|
15
|
+
index("workspace_sessions_status_idx").on(table.status, table.lastUsedAt),
|
|
16
|
+
]);
|
|
17
|
+
export const loadedAgentFiles = sqliteTable("loaded_agent_files", {
|
|
18
|
+
workspaceSessionId: text("workspace_session_id")
|
|
19
|
+
.notNull()
|
|
20
|
+
.references(() => workspaceSessions.id, { onDelete: "cascade" }),
|
|
21
|
+
path: text("path").notNull(),
|
|
22
|
+
contentHash: text("content_hash").notNull(),
|
|
23
|
+
content: text("content").notNull(),
|
|
24
|
+
loadedAt: text("loaded_at").notNull(),
|
|
25
|
+
lastSeenAt: text("last_seen_at").notNull(),
|
|
26
|
+
}, (table) => [
|
|
27
|
+
primaryKey({ columns: [table.workspaceSessionId, table.path] }),
|
|
28
|
+
index("loaded_agent_files_path_idx").on(table.path),
|
|
29
|
+
]);
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { execFile } from "node:child_process";
|
|
3
|
+
import { promisify } from "node:util";
|
|
4
|
+
import { dirname } from "node:path";
|
|
5
|
+
const execFileAsync = promisify(execFile);
|
|
6
|
+
export function parseDotnetBuildOutput(output) {
|
|
7
|
+
const errors = [];
|
|
8
|
+
const warnings = [];
|
|
9
|
+
const lines = output.split(/\r?\n/);
|
|
10
|
+
// Example MSBuild diagnostic line:
|
|
11
|
+
// C:\project\Program.cs(12,15): error CS1002: ; expected [C:\project\project.csproj]
|
|
12
|
+
const diagRegex = /^(.*?)\((\d+),(\d+)\):\s*(error|warning)\s*([A-Z0-9]+)?:\s*(.*?)(?:\[.*\])?$/;
|
|
13
|
+
for (const line of lines) {
|
|
14
|
+
const match = line.trim().match(diagRegex);
|
|
15
|
+
if (match) {
|
|
16
|
+
const [, filePath, lineNum, colNum, severity, code, message] = match;
|
|
17
|
+
const diag = {
|
|
18
|
+
path: filePath,
|
|
19
|
+
line: Number(lineNum),
|
|
20
|
+
column: Number(colNum),
|
|
21
|
+
code: code ?? undefined,
|
|
22
|
+
message: message.trim(),
|
|
23
|
+
};
|
|
24
|
+
if (severity.toLowerCase() === "error") {
|
|
25
|
+
errors.push(diag);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
warnings.push(diag);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const success = errors.length === 0 && !output.includes("Build FAILED");
|
|
33
|
+
return { success, errors, warnings };
|
|
34
|
+
}
|
|
35
|
+
export function parseDotnetTestOutput(output) {
|
|
36
|
+
let passed = 0;
|
|
37
|
+
let failed = 0;
|
|
38
|
+
let skipped = 0;
|
|
39
|
+
const failedTestNames = [];
|
|
40
|
+
const assertionMessages = [];
|
|
41
|
+
// Summary line: Passed! - Failed: 1, Passed: 5, Skipped: 0, Total: 6
|
|
42
|
+
const summaryMatch = output.match(/Failed:\s*(\d+),\s*Passed:\s*(\d+),\s*Skipped:\s*(\d+)/i);
|
|
43
|
+
if (summaryMatch) {
|
|
44
|
+
failed = Number(summaryMatch[1]);
|
|
45
|
+
passed = Number(summaryMatch[2]);
|
|
46
|
+
skipped = Number(summaryMatch[3]);
|
|
47
|
+
}
|
|
48
|
+
const lines = output.split(/\r?\n/);
|
|
49
|
+
for (const line of lines) {
|
|
50
|
+
if (line.includes("Failed ") || line.includes("Failed:")) {
|
|
51
|
+
const nameMatch = line.match(/Failed\s+([A-Za-z0-9_.]+)/);
|
|
52
|
+
if (nameMatch && !failedTestNames.includes(nameMatch[1])) {
|
|
53
|
+
failedTestNames.push(nameMatch[1]);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (line.includes("Assert.") || line.includes("Expected:") || line.includes("Actual:")) {
|
|
57
|
+
assertionMessages.push(line.trim());
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return { passed, failed, skipped, failedTestNames, assertionMessages };
|
|
61
|
+
}
|
|
62
|
+
export async function inspectDotnetProject(registry, input) {
|
|
63
|
+
const workspace = registry.getWorkspace(input.workspaceId);
|
|
64
|
+
const absolutePath = registry.resolvePath(workspace, input.projectPath);
|
|
65
|
+
let xmlContent = "";
|
|
66
|
+
try {
|
|
67
|
+
xmlContent = await readFile(absolutePath, "utf8");
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
throw new Error(`Unable to read .NET project file: ${input.projectPath}`);
|
|
71
|
+
}
|
|
72
|
+
const sdkStyle = xmlContent.includes('<Project Sdk=') || xmlContent.includes('Sdk="Microsoft.NET.Sdk');
|
|
73
|
+
const tfmMatch = xmlContent.match(/<TargetFrameworks?>(.*?)<\/TargetFrameworks?>/i);
|
|
74
|
+
const targetFrameworks = tfmMatch ? tfmMatch[1].split(";").map((t) => t.trim()) : [];
|
|
75
|
+
const outputTypeMatch = xmlContent.match(/<OutputType>(.*?)<\/OutputType>/i);
|
|
76
|
+
const outputType = outputTypeMatch ? outputTypeMatch[1].trim() : "Exe";
|
|
77
|
+
const nullableMatch = xmlContent.match(/<Nullable>(.*?)<\/Nullable>/i);
|
|
78
|
+
const nullable = nullableMatch ? nullableMatch[1].trim() : "enable";
|
|
79
|
+
const implicitUsingsMatch = xmlContent.match(/<ImplicitUsings>(.*?)<\/ImplicitUsings>/i);
|
|
80
|
+
const implicitUsings = implicitUsingsMatch ? implicitUsingsMatch[1].trim() : "enable";
|
|
81
|
+
const packageReferences = [];
|
|
82
|
+
const pkgRegex = /<PackageReference\s+Include="([^"]+)"/g;
|
|
83
|
+
let pkgMatch;
|
|
84
|
+
while ((pkgMatch = pkgRegex.exec(xmlContent)) !== null) {
|
|
85
|
+
packageReferences.push(pkgMatch[1]);
|
|
86
|
+
}
|
|
87
|
+
const projectReferences = [];
|
|
88
|
+
const projRefRegex = /<ProjectReference\s+Include="([^"]+)"/g;
|
|
89
|
+
let projRefMatch;
|
|
90
|
+
while ((projRefMatch = projRefRegex.exec(xmlContent)) !== null) {
|
|
91
|
+
projectReferences.push(projRefMatch[1]);
|
|
92
|
+
}
|
|
93
|
+
let testFramework;
|
|
94
|
+
if (packageReferences.some((p) => p.includes("xunit")))
|
|
95
|
+
testFramework = "xUnit";
|
|
96
|
+
else if (packageReferences.some((p) => p.includes("nunit")))
|
|
97
|
+
testFramework = "NUnit";
|
|
98
|
+
else if (packageReferences.some((p) => p.includes("MSTest")))
|
|
99
|
+
testFramework = "MSTest";
|
|
100
|
+
return {
|
|
101
|
+
projectPath: input.projectPath,
|
|
102
|
+
sdkStyle,
|
|
103
|
+
targetFrameworks,
|
|
104
|
+
outputType,
|
|
105
|
+
nullable,
|
|
106
|
+
implicitUsings,
|
|
107
|
+
packageReferences,
|
|
108
|
+
projectReferences,
|
|
109
|
+
testFramework,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
export async function dotnetRestore(registry, input) {
|
|
113
|
+
const workspace = registry.getWorkspace(input.workspaceId);
|
|
114
|
+
const absolutePath = registry.resolvePath(workspace, input.projectPath);
|
|
115
|
+
const cwd = dirname(absolutePath);
|
|
116
|
+
const start = Date.now();
|
|
117
|
+
try {
|
|
118
|
+
const { stdout, stderr } = await execFileAsync("dotnet", ["restore", absolutePath], { cwd });
|
|
119
|
+
return {
|
|
120
|
+
success: true,
|
|
121
|
+
durationMs: Date.now() - start,
|
|
122
|
+
output: (stdout + "\n" + stderr).slice(0, 1000),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
return {
|
|
127
|
+
success: false,
|
|
128
|
+
durationMs: Date.now() - start,
|
|
129
|
+
output: (err.stdout ?? "") + "\n" + (err.stderr ?? err.message),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
export async function dotnetBuild(registry, input) {
|
|
134
|
+
const workspace = registry.getWorkspace(input.workspaceId);
|
|
135
|
+
const absolutePath = registry.resolvePath(workspace, input.projectPath);
|
|
136
|
+
const cwd = dirname(absolutePath);
|
|
137
|
+
const args = ["build", absolutePath];
|
|
138
|
+
if (input.configuration)
|
|
139
|
+
args.push("-c", input.configuration);
|
|
140
|
+
if (input.noRestore)
|
|
141
|
+
args.push("--no-restore");
|
|
142
|
+
const start = Date.now();
|
|
143
|
+
try {
|
|
144
|
+
const { stdout, stderr } = await execFileAsync("dotnet", args, { cwd });
|
|
145
|
+
const fullOutput = stdout + "\n" + stderr;
|
|
146
|
+
const parsed = parseDotnetBuildOutput(fullOutput);
|
|
147
|
+
return {
|
|
148
|
+
success: parsed.success,
|
|
149
|
+
durationMs: Date.now() - start,
|
|
150
|
+
errors: parsed.errors,
|
|
151
|
+
warnings: parsed.warnings,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
catch (err) {
|
|
155
|
+
const fullOutput = (err.stdout ?? "") + "\n" + (err.stderr ?? err.message);
|
|
156
|
+
const parsed = parseDotnetBuildOutput(fullOutput);
|
|
157
|
+
return {
|
|
158
|
+
success: false,
|
|
159
|
+
durationMs: Date.now() - start,
|
|
160
|
+
errors: parsed.errors.length > 0 ? parsed.errors : [{ message: err.message }],
|
|
161
|
+
warnings: parsed.warnings,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
export async function dotnetTest(registry, input) {
|
|
166
|
+
const workspace = registry.getWorkspace(input.workspaceId);
|
|
167
|
+
const absolutePath = registry.resolvePath(workspace, input.projectPath);
|
|
168
|
+
const cwd = dirname(absolutePath);
|
|
169
|
+
const args = ["test", absolutePath];
|
|
170
|
+
if (input.configuration)
|
|
171
|
+
args.push("-c", input.configuration);
|
|
172
|
+
if (input.filter)
|
|
173
|
+
args.push("--filter", input.filter);
|
|
174
|
+
if (input.noBuild)
|
|
175
|
+
args.push("--no-build");
|
|
176
|
+
const start = Date.now();
|
|
177
|
+
try {
|
|
178
|
+
const { stdout, stderr } = await execFileAsync("dotnet", args, { cwd });
|
|
179
|
+
const parsed = parseDotnetTestOutput(stdout + "\n" + stderr);
|
|
180
|
+
return {
|
|
181
|
+
...parsed,
|
|
182
|
+
durationMs: Date.now() - start,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
catch (err) {
|
|
186
|
+
const parsed = parseDotnetTestOutput((err.stdout ?? "") + "\n" + (err.stderr ?? err.message));
|
|
187
|
+
return {
|
|
188
|
+
...parsed,
|
|
189
|
+
durationMs: Date.now() - start,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
export async function dotnetRun(registry, processManager, input) {
|
|
194
|
+
const workspace = registry.getWorkspace(input.workspaceId);
|
|
195
|
+
const absolutePath = registry.resolvePath(workspace, input.projectPath);
|
|
196
|
+
const configArg = input.configuration ? `-c ${input.configuration}` : "";
|
|
197
|
+
const extraArgs = input.arguments?.length ? `-- ${input.arguments.join(" ")}` : "";
|
|
198
|
+
const command = `dotnet run --project "${absolutePath}" ${configArg} ${extraArgs}`.trim();
|
|
199
|
+
const result = processManager.startProcess({
|
|
200
|
+
workspaceId: input.workspaceId,
|
|
201
|
+
command,
|
|
202
|
+
environment: input.environment,
|
|
203
|
+
});
|
|
204
|
+
return {
|
|
205
|
+
processId: result.processId,
|
|
206
|
+
status: result.status,
|
|
207
|
+
detectedUrls: result.detectedUrls,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
export async function dotnetFormat(registry, input) {
|
|
211
|
+
const workspace = registry.getWorkspace(input.workspaceId);
|
|
212
|
+
const absolutePath = registry.resolvePath(workspace, input.projectPath);
|
|
213
|
+
const args = ["format", absolutePath];
|
|
214
|
+
if (input.verifyOnly)
|
|
215
|
+
args.push("--verify-no-changes");
|
|
216
|
+
try {
|
|
217
|
+
const { stdout, stderr } = await execFileAsync("dotnet", args, { cwd: dirname(absolutePath) });
|
|
218
|
+
return { success: true, output: (stdout + "\n" + stderr).slice(0, 1000) };
|
|
219
|
+
}
|
|
220
|
+
catch (err) {
|
|
221
|
+
return { success: false, output: (err.stdout ?? "") + "\n" + (err.stderr ?? err.message) };
|
|
222
|
+
}
|
|
223
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { execFile } from "node:child_process";
|
|
3
|
+
import { promisify } from "node:util";
|
|
4
|
+
import { mkdir, realpath, rm, stat } from "node:fs/promises";
|
|
5
|
+
import { basename, join, relative, resolve } from "node:path";
|
|
6
|
+
import { assertAllowedPath, isPathInsideRoot } from "./roots.js";
|
|
7
|
+
const execFileAsync = promisify(execFile);
|
|
8
|
+
export class GitWorktreeError extends Error {
|
|
9
|
+
code;
|
|
10
|
+
constructor(code, message) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.code = code;
|
|
13
|
+
this.name = "GitWorktreeError";
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export async function createManagedWorktree(input) {
|
|
17
|
+
const sourcePath = assertAllowedPath(input.sourcePath, input.config.allowedRoots);
|
|
18
|
+
try {
|
|
19
|
+
const sourceStats = await stat(sourcePath);
|
|
20
|
+
if (!sourceStats.isDirectory()) {
|
|
21
|
+
throw new GitWorktreeError("GIT_REPOSITORY_NOT_FOUND", `Cannot open workspace in worktree mode because the source path is not a directory: ${input.sourcePath}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
if (error instanceof GitWorktreeError)
|
|
26
|
+
throw error;
|
|
27
|
+
throw new GitWorktreeError("GIT_REPOSITORY_NOT_FOUND", `Cannot open workspace in worktree mode because the source path does not exist: ${input.sourcePath}`);
|
|
28
|
+
}
|
|
29
|
+
const sourceRoot = await resolveGitRoot(sourcePath, input.config.allowedRoots);
|
|
30
|
+
const baseRef = input.baseRef ?? "HEAD";
|
|
31
|
+
const baseSha = await resolveBaseCommit(sourceRoot, baseRef);
|
|
32
|
+
const dirtySource = (await git(["status", "--porcelain=v1"], sourceRoot)).trim().length > 0;
|
|
33
|
+
const worktreePath = managedWorktreePath({
|
|
34
|
+
worktreeRoot: input.config.worktreeRoot,
|
|
35
|
+
repoRoot: sourceRoot,
|
|
36
|
+
});
|
|
37
|
+
await mkdir(input.config.worktreeRoot, { recursive: true });
|
|
38
|
+
assertAllowedPath(worktreePath, [input.config.worktreeRoot]);
|
|
39
|
+
try {
|
|
40
|
+
await git(["worktree", "add", "--detach", worktreePath, baseSha], sourceRoot);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
await rm(worktreePath, { recursive: true, force: true });
|
|
44
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
45
|
+
throw new GitWorktreeError("GIT_WORKTREE_CREATE_FAILED", `Git failed to create the managed worktree. ${message}`);
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
sourceRoot,
|
|
49
|
+
path: worktreePath,
|
|
50
|
+
baseRef,
|
|
51
|
+
baseSha,
|
|
52
|
+
dirtySource,
|
|
53
|
+
detached: true,
|
|
54
|
+
managed: true,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
async function resolveGitRoot(path, allowedRoots) {
|
|
58
|
+
try {
|
|
59
|
+
const output = await git(["rev-parse", "--show-toplevel"], path);
|
|
60
|
+
return await assertGitRootAllowed(output.trim(), allowedRoots);
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
if (isGitUnavailable(error)) {
|
|
64
|
+
throw new GitWorktreeError("GIT_NOT_AVAILABLE", "Cannot open workspace in worktree mode because Git is not available on this machine.");
|
|
65
|
+
}
|
|
66
|
+
throw new GitWorktreeError("GIT_REPOSITORY_NOT_FOUND", `Cannot open workspace in worktree mode because this path is not inside a Git repository: ${path}. Use mode=\"checkout\" to work directly in this directory, or initialize Git and create an initial commit first.`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async function assertGitRootAllowed(gitRoot, allowedRoots) {
|
|
70
|
+
try {
|
|
71
|
+
return assertAllowedPath(gitRoot, allowedRoots);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
const canonicalGitRoot = await realpath(gitRoot);
|
|
75
|
+
for (const allowedRoot of allowedRoots) {
|
|
76
|
+
const canonicalAllowedRoot = await realpath(allowedRoot).catch(() => undefined);
|
|
77
|
+
if (!canonicalAllowedRoot || !isPathInsideRoot(canonicalGitRoot, canonicalAllowedRoot)) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
const logicalGitRoot = resolve(allowedRoot, relative(canonicalAllowedRoot, canonicalGitRoot));
|
|
81
|
+
return assertAllowedPath(logicalGitRoot, allowedRoots);
|
|
82
|
+
}
|
|
83
|
+
return assertAllowedPath(canonicalGitRoot, allowedRoots);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
async function resolveBaseCommit(sourceRoot, baseRef) {
|
|
87
|
+
try {
|
|
88
|
+
return (await git(["rev-parse", "--verify", `${baseRef}^{commit}`], sourceRoot)).trim();
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
if (baseRef === "HEAD") {
|
|
92
|
+
throw new GitWorktreeError("GIT_REPOSITORY_HAS_NO_COMMITS", "Cannot open workspace in worktree mode because the repository has no commits yet. Create an initial commit first, or use mode=\"checkout\".");
|
|
93
|
+
}
|
|
94
|
+
throw new GitWorktreeError("GIT_INVALID_BASE_REF", `Cannot open workspace in worktree mode because baseRef ${JSON.stringify(baseRef)} does not resolve to a commit.`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function managedWorktreePath(input) {
|
|
98
|
+
const repoName = sanitizePathSegment(basename(input.repoRoot)) || "repo";
|
|
99
|
+
const worktreeId = randomBytes(4).toString("hex");
|
|
100
|
+
return join(input.worktreeRoot, `${repoName}-${worktreeId}`);
|
|
101
|
+
}
|
|
102
|
+
function sanitizePathSegment(value) {
|
|
103
|
+
return value
|
|
104
|
+
.replace(/[^a-zA-Z0-9._-]+/g, "-")
|
|
105
|
+
.replace(/^-+|-+$/g, "")
|
|
106
|
+
.slice(0, 80);
|
|
107
|
+
}
|
|
108
|
+
async function git(args, cwd) {
|
|
109
|
+
try {
|
|
110
|
+
const { stdout } = await execFileAsync("git", args, {
|
|
111
|
+
cwd,
|
|
112
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
113
|
+
});
|
|
114
|
+
return stdout;
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
if (isGitUnavailable(error))
|
|
118
|
+
throw error;
|
|
119
|
+
const stderr = typeof error === "object" && error && "stderr" in error
|
|
120
|
+
? String(error.stderr ?? "").trim()
|
|
121
|
+
: "";
|
|
122
|
+
const stdout = typeof error === "object" && error && "stdout" in error
|
|
123
|
+
? String(error.stdout ?? "").trim()
|
|
124
|
+
: "";
|
|
125
|
+
const details = stderr || stdout || (error instanceof Error ? error.message : String(error));
|
|
126
|
+
throw new Error(details);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function isGitUnavailable(error) {
|
|
130
|
+
return Boolean(typeof error === "object" &&
|
|
131
|
+
error &&
|
|
132
|
+
"code" in error &&
|
|
133
|
+
error.code === "ENOENT");
|
|
134
|
+
}
|
package/dist/git.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { execFile } from "node:child_process";
|
|
3
|
+
import { promisify } from "node:util";
|
|
4
|
+
const execFileAsync = promisify(execFile);
|
|
5
|
+
export async function git(cwd, args, options = {}) {
|
|
6
|
+
const { stdout, stderr } = await execFileAsync("git", args, {
|
|
7
|
+
cwd,
|
|
8
|
+
env: options.env ? { ...process.env, ...options.env } : process.env,
|
|
9
|
+
maxBuffer: options.maxBuffer ?? 10 * 1024 * 1024,
|
|
10
|
+
});
|
|
11
|
+
return { stdout, stderr };
|
|
12
|
+
}
|
|
13
|
+
export async function getGitEligibility(cwd) {
|
|
14
|
+
try {
|
|
15
|
+
await git(cwd, ["rev-parse", "--is-inside-work-tree"]);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return {
|
|
19
|
+
ok: false,
|
|
20
|
+
reason: "not_git",
|
|
21
|
+
message: "workspace is not inside a git repository",
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
const gitRoot = (await git(cwd, ["rev-parse", "--show-toplevel"])).stdout.trim();
|
|
25
|
+
try {
|
|
26
|
+
await git(gitRoot, ["rev-parse", "--verify", "--quiet", "HEAD^{commit}"]);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return {
|
|
30
|
+
ok: false,
|
|
31
|
+
gitRoot,
|
|
32
|
+
reason: "no_head",
|
|
33
|
+
message: "repository has no HEAD commit",
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return { ok: true, gitRoot };
|
|
37
|
+
}
|
|
38
|
+
export function safeWorkspaceRefSegment(workspaceId) {
|
|
39
|
+
const safe = workspaceId.replace(/[^A-Za-z0-9._-]/g, "-");
|
|
40
|
+
return safe.length > 0 ? safe : createHash("sha256").update(workspaceId).digest("hex").slice(0, 16);
|
|
41
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// Bridge-based animation listing (requires live editor bridge)
|
|
2
|
+
export async function listAnimations(input, bridgeClient) {
|
|
3
|
+
if (!bridgeClient.status)
|
|
4
|
+
throw new Error("Godot Editor Bridge is not connected.");
|
|
5
|
+
const result = await bridgeClient.sendRequest("animation.list", {
|
|
6
|
+
nodePath: input.animationPlayerNodePath,
|
|
7
|
+
});
|
|
8
|
+
return result.animations ?? [];
|
|
9
|
+
}
|
|
10
|
+
export async function getAnimation(input, bridgeClient) {
|
|
11
|
+
if (!bridgeClient.status)
|
|
12
|
+
throw new Error("Godot Editor Bridge is not connected.");
|
|
13
|
+
return bridgeClient.sendRequest("animation.get", {
|
|
14
|
+
nodePath: input.animationPlayerNodePath,
|
|
15
|
+
animationName: input.animationName,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
export async function createAnimation(input, bridgeClient) {
|
|
19
|
+
if (!bridgeClient.status)
|
|
20
|
+
throw new Error("Godot Editor Bridge is not connected.");
|
|
21
|
+
await bridgeClient.sendRequest("animation.create", {
|
|
22
|
+
nodePath: input.animationPlayerNodePath,
|
|
23
|
+
animationName: input.animationName,
|
|
24
|
+
length: input.lengthSeconds ?? 1.0,
|
|
25
|
+
loop: input.loop ?? false,
|
|
26
|
+
});
|
|
27
|
+
return { created: true, name: input.animationName };
|
|
28
|
+
}
|
|
29
|
+
export async function validateAnimation(input, bridgeClient) {
|
|
30
|
+
if (!bridgeClient.status)
|
|
31
|
+
throw new Error("Godot Editor Bridge is not connected.");
|
|
32
|
+
const anim = await getAnimation(input, bridgeClient);
|
|
33
|
+
const issues = [];
|
|
34
|
+
if (anim.lengthSeconds === 0)
|
|
35
|
+
issues.push("Animation length is zero.");
|
|
36
|
+
for (const track of anim.tracks) {
|
|
37
|
+
if (track.keys.length === 0)
|
|
38
|
+
issues.push(`Track '${track.targetPath}' has no keys.`);
|
|
39
|
+
}
|
|
40
|
+
return { valid: issues.length === 0, issues };
|
|
41
|
+
}
|
|
42
|
+
// ─── TileMap Tools ─────────────────────────────────────────────────────────
|
|
43
|
+
export async function getTileLayers(input, bridgeClient) {
|
|
44
|
+
if (!bridgeClient.status)
|
|
45
|
+
throw new Error("Godot Editor Bridge is not connected.");
|
|
46
|
+
const result = await bridgeClient.sendRequest("tilemap.get_layers", { nodePath: input.tileMapNodePath });
|
|
47
|
+
return result.layers ?? [];
|
|
48
|
+
}
|
|
49
|
+
export async function inspectTileset(input, bridgeClient) {
|
|
50
|
+
if (!bridgeClient.status)
|
|
51
|
+
throw new Error("Godot Editor Bridge is not connected.");
|
|
52
|
+
return bridgeClient.sendRequest("tilemap.inspect_tileset", { nodePath: input.tileMapNodePath });
|
|
53
|
+
}
|
|
54
|
+
export async function validateTilemap(input, bridgeClient) {
|
|
55
|
+
if (!bridgeClient.status)
|
|
56
|
+
throw new Error("Godot Editor Bridge is not connected.");
|
|
57
|
+
const result = await bridgeClient.sendRequest("tilemap.validate", { nodePath: input.tileMapNodePath });
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
// ─── Physics Tools ─────────────────────────────────────────────────────────
|
|
61
|
+
export async function getPhysicsConfiguration(input, bridgeClient) {
|
|
62
|
+
if (!bridgeClient.status)
|
|
63
|
+
throw new Error("Godot Editor Bridge is not connected.");
|
|
64
|
+
return bridgeClient.sendRequest("physics.get_configuration", { nodePath: input.nodePath ?? "/" });
|
|
65
|
+
}
|
|
66
|
+
export async function validateCollisions(input, bridgeClient) {
|
|
67
|
+
if (!bridgeClient.status)
|
|
68
|
+
throw new Error("Godot Editor Bridge is not connected.");
|
|
69
|
+
const result = await bridgeClient.sendRequest("physics.validate_collisions", { nodePath: input.nodePath ?? "/" });
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
// ─── Camera Tools ──────────────────────────────────────────────────────────
|
|
73
|
+
export async function getCameraState(input, bridgeClient) {
|
|
74
|
+
if (!bridgeClient.status)
|
|
75
|
+
throw new Error("Godot Editor Bridge is not connected.");
|
|
76
|
+
return bridgeClient.sendRequest("camera.get_state", { nodePath: input.cameraNodePath });
|
|
77
|
+
}
|
|
78
|
+
export async function validateCamera(input, bridgeClient) {
|
|
79
|
+
if (!bridgeClient.status)
|
|
80
|
+
throw new Error("Godot Editor Bridge is not connected.");
|
|
81
|
+
return bridgeClient.sendRequest("camera.validate", { nodePath: input.cameraNodePath });
|
|
82
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
import { dirname } from "node:path";
|
|
4
|
+
import { parseDotnetBuildOutput } from "./dotnet-tools.js";
|
|
5
|
+
import { inspectGodotDotnetProject } from "./godot-csharp-project.js";
|
|
6
|
+
const execFileAsync = promisify(execFile);
|
|
7
|
+
export function parseGodotBuildDiagnostics(output) {
|
|
8
|
+
const base = parseDotnetBuildOutput(output);
|
|
9
|
+
const mapDiag = (d) => {
|
|
10
|
+
let source = "csharp";
|
|
11
|
+
if (d.code?.startsWith("CS"))
|
|
12
|
+
source = "csharp";
|
|
13
|
+
else if (d.code?.startsWith("MSB"))
|
|
14
|
+
source = "msbuild";
|
|
15
|
+
else if (d.code?.startsWith("NU"))
|
|
16
|
+
source = "nuget";
|
|
17
|
+
else if (d.message.toLowerCase().includes("godot"))
|
|
18
|
+
source = "godot";
|
|
19
|
+
return {
|
|
20
|
+
source,
|
|
21
|
+
code: d.code,
|
|
22
|
+
message: d.message,
|
|
23
|
+
path: d.path,
|
|
24
|
+
line: d.line,
|
|
25
|
+
column: d.column,
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
return {
|
|
29
|
+
success: base.success,
|
|
30
|
+
errors: base.errors.map(mapDiag),
|
|
31
|
+
warnings: base.warnings.map(mapDiag),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export async function godotDotnetBuild(registry, input) {
|
|
35
|
+
const workspace = registry.getWorkspace(input.workspaceId);
|
|
36
|
+
const targetDir = registry.resolvePath(workspace, input.projectPath);
|
|
37
|
+
const details = await inspectGodotDotnetProject(registry, { workspaceId: input.workspaceId, projectPath: input.projectPath });
|
|
38
|
+
const buildTarget = details.slnPath ? registry.resolvePath(workspace, details.slnPath) : (details.csprojPath ? registry.resolvePath(workspace, details.csprojPath) : targetDir);
|
|
39
|
+
const config = input.configuration ?? "Debug";
|
|
40
|
+
const args = ["build", buildTarget, "-c", config];
|
|
41
|
+
if (input.noRestore)
|
|
42
|
+
args.push("--no-restore");
|
|
43
|
+
const start = Date.now();
|
|
44
|
+
try {
|
|
45
|
+
const { stdout, stderr } = await execFileAsync("dotnet", args, { cwd: dirname(buildTarget) });
|
|
46
|
+
const fullOutput = stdout + "\n" + stderr;
|
|
47
|
+
const parsed = parseGodotBuildDiagnostics(fullOutput);
|
|
48
|
+
return {
|
|
49
|
+
success: parsed.success,
|
|
50
|
+
configuration: config,
|
|
51
|
+
targetFrameworks: details.targetFrameworks,
|
|
52
|
+
outputAssemblies: details.assemblyName ? [`${details.assemblyName}.dll`] : [],
|
|
53
|
+
errors: parsed.errors,
|
|
54
|
+
warnings: parsed.warnings,
|
|
55
|
+
durationMs: Date.now() - start,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
const fullOutput = (err.stdout ?? "") + "\n" + (err.stderr ?? err.message);
|
|
60
|
+
const parsed = parseGodotBuildDiagnostics(fullOutput);
|
|
61
|
+
return {
|
|
62
|
+
success: false,
|
|
63
|
+
configuration: config,
|
|
64
|
+
targetFrameworks: details.targetFrameworks,
|
|
65
|
+
outputAssemblies: [],
|
|
66
|
+
errors: parsed.errors.length > 0 ? parsed.errors : [{ source: "csharp", message: err.message }],
|
|
67
|
+
warnings: parsed.warnings,
|
|
68
|
+
durationMs: Date.now() - start,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export async function godotDotnetClean(registry, input) {
|
|
73
|
+
const workspace = registry.getWorkspace(input.workspaceId);
|
|
74
|
+
const targetDir = registry.resolvePath(workspace, input.projectPath);
|
|
75
|
+
const config = input.configuration ?? "Debug";
|
|
76
|
+
const args = ["clean", targetDir, "-c", config];
|
|
77
|
+
const start = Date.now();
|
|
78
|
+
try {
|
|
79
|
+
const { stdout, stderr } = await execFileAsync("dotnet", args, { cwd: targetDir });
|
|
80
|
+
return {
|
|
81
|
+
success: true,
|
|
82
|
+
durationMs: Date.now() - start,
|
|
83
|
+
output: (stdout + "\n" + stderr).slice(0, 1000),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
return {
|
|
88
|
+
success: false,
|
|
89
|
+
durationMs: Date.now() - start,
|
|
90
|
+
output: (err.stdout ?? "") + "\n" + (err.stderr ?? err.message),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|