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.
Files changed (364) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +239 -0
  3. package/dist/blender-client.js +109 -0
  4. package/dist/blender-tools.js +930 -0
  5. package/dist/cli.js +370 -0
  6. package/dist/config.js +211 -0
  7. package/dist/connection-status.js +91 -0
  8. package/dist/db/client.js +22 -0
  9. package/dist/db/schema.js +29 -0
  10. package/dist/dotnet-tools.js +223 -0
  11. package/dist/git-worktrees.js +134 -0
  12. package/dist/git.js +41 -0
  13. package/dist/godot-animation-tilemap.js +82 -0
  14. package/dist/godot-csharp-build.js +93 -0
  15. package/dist/godot-csharp-project.js +157 -0
  16. package/dist/godot-csharp-runner.js +146 -0
  17. package/dist/godot-csharp-semantic.js +161 -0
  18. package/dist/godot-csharp-validate.js +71 -0
  19. package/dist/godot-dotnet-env.js +169 -0
  20. package/dist/godot-editor-bridge.js +140 -0
  21. package/dist/godot-gdscript.js +824 -0
  22. package/dist/godot-project-settings.js +223 -0
  23. package/dist/godot-runtime-testing.js +249 -0
  24. package/dist/godot-tools.js +183 -0
  25. package/dist/image-tools.js +157 -0
  26. package/dist/logger.js +76 -0
  27. package/dist/oauth-provider.js +266 -0
  28. package/dist/pi-tools.js +81 -0
  29. package/dist/processes.js +218 -0
  30. package/dist/review-checkpoints.js +142 -0
  31. package/dist/roots.js +53 -0
  32. package/dist/search-discovery.js +271 -0
  33. package/dist/serena-manager.js +443 -0
  34. package/dist/serena-tools.js +411 -0
  35. package/dist/server.js +2835 -0
  36. package/dist/skills.js +45 -0
  37. package/dist/ui/.vite/manifest.json +2520 -0
  38. package/dist/ui/assets/abap-CLvhMVsD.js +1 -0
  39. package/dist/ui/assets/actionscript-3--17pq3dv.js +1 -0
  40. package/dist/ui/assets/ada-C5qYipkI.js +1 -0
  41. package/dist/ui/assets/andromeeda-vGVdxbeo.js +1 -0
  42. package/dist/ui/assets/angular-html-BJqQFYI6.js +1 -0
  43. package/dist/ui/assets/angular-ts-CMJECO0Y.js +1 -0
  44. package/dist/ui/assets/apache-U0d_L8uA.js +1 -0
  45. package/dist/ui/assets/apex-CGTLDQj6.js +1 -0
  46. package/dist/ui/assets/apl-DWeXpBBr.js +1 -0
  47. package/dist/ui/assets/applescript-CCn79oCD.js +1 -0
  48. package/dist/ui/assets/ara-4CJ0cIlV.js +1 -0
  49. package/dist/ui/assets/asciidoc-DE70LPWp.js +1 -0
  50. package/dist/ui/assets/asm-Cmm7eHzH.js +1 -0
  51. package/dist/ui/assets/astro-CLbttLOq.js +1 -0
  52. package/dist/ui/assets/aurora-x-CDeNXAV0.js +1 -0
  53. package/dist/ui/assets/awk-BWXHIvNe.js +1 -0
  54. package/dist/ui/assets/ayu-dark-DluEY0Gj.js +1 -0
  55. package/dist/ui/assets/ayu-light-C3h-C4tm.js +1 -0
  56. package/dist/ui/assets/ayu-mirage-Bqwy1Gya.js +1 -0
  57. package/dist/ui/assets/ballerina-B7ZEbQpA.js +1 -0
  58. package/dist/ui/assets/bat-Bo4NYOV-.js +1 -0
  59. package/dist/ui/assets/beancount-D-usSTwE.js +1 -0
  60. package/dist/ui/assets/berry-DKpUyyne.js +1 -0
  61. package/dist/ui/assets/bibtex-Ci_nEsc7.js +1 -0
  62. package/dist/ui/assets/bicep-CUHmPFLl.js +1 -0
  63. package/dist/ui/assets/bird2-C2hNVINV.js +1 -0
  64. package/dist/ui/assets/blade-BOzY0P2V.js +1 -0
  65. package/dist/ui/assets/bsl-BkkzgIyY.js +1 -0
  66. package/dist/ui/assets/c-BG-8uJvh.js +1 -0
  67. package/dist/ui/assets/c3-CnJL0r0V.js +1 -0
  68. package/dist/ui/assets/cadence-CQ2zXKGN.js +1 -0
  69. package/dist/ui/assets/cairo-DLTphjLi.js +1 -0
  70. package/dist/ui/assets/catppuccin-frappe-3VR1Za6u.js +1 -0
  71. package/dist/ui/assets/catppuccin-latte-DwIHMF0Q.js +1 -0
  72. package/dist/ui/assets/catppuccin-macchiato-DYnBP6_5.js +1 -0
  73. package/dist/ui/assets/catppuccin-mocha-DYhrFGRu.js +1 -0
  74. package/dist/ui/assets/clarity-SemFz856.js +1 -0
  75. package/dist/ui/assets/clojure-DqKBuwfJ.js +1 -0
  76. package/dist/ui/assets/cmake-Bj61d0ZC.js +1 -0
  77. package/dist/ui/assets/cobol-I_17IuGe.js +1 -0
  78. package/dist/ui/assets/codeowners-C8r90Shi.js +1 -0
  79. package/dist/ui/assets/codeql-oeQT6MSM.js +1 -0
  80. package/dist/ui/assets/coffee-C0B8hmok.js +1 -0
  81. package/dist/ui/assets/common-lisp-Cv5bFMCO.js +1 -0
  82. package/dist/ui/assets/coq-BrsZFFmf.js +1 -0
  83. package/dist/ui/assets/cpp-DDJXt6Vs.js +1 -0
  84. package/dist/ui/assets/crystal-Bexqace6.js +1 -0
  85. package/dist/ui/assets/csharp-Ct8U2NOr.js +1 -0
  86. package/dist/ui/assets/css-DSQhw_9R.js +1 -0
  87. package/dist/ui/assets/csv-Dx-8-gkx.js +1 -0
  88. package/dist/ui/assets/cue-CE9AQfxI.js +1 -0
  89. package/dist/ui/assets/cypher-ClKdZ_lG.js +1 -0
  90. package/dist/ui/assets/d-qD-0Kul2.js +1 -0
  91. package/dist/ui/assets/dark-plus-Cs2F2srj.js +1 -0
  92. package/dist/ui/assets/dart-DkHntEIa.js +1 -0
  93. package/dist/ui/assets/dax-BkyTk9wS.js +1 -0
  94. package/dist/ui/assets/desktop-Dlh5hvp9.js +1 -0
  95. package/dist/ui/assets/diff-woXpYk--.js +1 -0
  96. package/dist/ui/assets/docker-IyjqRm3v.js +1 -0
  97. package/dist/ui/assets/dotenv-_5a1GRtc.js +1 -0
  98. package/dist/ui/assets/dracula-BHWKrbxM.js +1 -0
  99. package/dist/ui/assets/dracula-soft-5eyTD99u.js +1 -0
  100. package/dist/ui/assets/dream-maker-DW3nJb8Q.js +1 -0
  101. package/dist/ui/assets/edge-Z8YYkHOr.js +1 -0
  102. package/dist/ui/assets/elixir-CG9uKtAF.js +1 -0
  103. package/dist/ui/assets/elm-GfWG2IfT.js +1 -0
  104. package/dist/ui/assets/emacs-lisp-C9PiwqqW.js +1 -0
  105. package/dist/ui/assets/erb-xe89e73J.js +1 -0
  106. package/dist/ui/assets/erlang-Cphh6RMH.js +1 -0
  107. package/dist/ui/assets/everforest-dark-sB-x3p7T.js +1 -0
  108. package/dist/ui/assets/everforest-light-Df2xbC6M.js +1 -0
  109. package/dist/ui/assets/fennel-DQxkIbk2.js +1 -0
  110. package/dist/ui/assets/fish-BJitypiv.js +1 -0
  111. package/dist/ui/assets/fluent-C03EYrpw.js +1 -0
  112. package/dist/ui/assets/fortran-fixed-form-DEKoE2YW.js +1 -0
  113. package/dist/ui/assets/fortran-free-form-CYNrtFtB.js +1 -0
  114. package/dist/ui/assets/fsharp-D13ZGOAj.js +1 -0
  115. package/dist/ui/assets/gdresource-C0sCabJj.js +1 -0
  116. package/dist/ui/assets/gdscript-Cp2uCuqX.js +1 -0
  117. package/dist/ui/assets/gdshader-CBce3t8t.js +1 -0
  118. package/dist/ui/assets/genie-CV2tkWYe.js +1 -0
  119. package/dist/ui/assets/gherkin-DExj1W_8.js +1 -0
  120. package/dist/ui/assets/git-commit-BSykSTBG.js +1 -0
  121. package/dist/ui/assets/git-rebase-CoTL_uSE.js +1 -0
  122. package/dist/ui/assets/github-dark-C-LZuMrd.js +1 -0
  123. package/dist/ui/assets/github-dark-default-DXG-b-1a.js +1 -0
  124. package/dist/ui/assets/github-dark-dimmed-Bx1FflLF.js +1 -0
  125. package/dist/ui/assets/github-dark-high-contrast-B_tTalzw.js +1 -0
  126. package/dist/ui/assets/github-light-EUqPIrTm.js +1 -0
  127. package/dist/ui/assets/github-light-default-BXViO-2h.js +1 -0
  128. package/dist/ui/assets/github-light-high-contrast-B68TUdTA.js +1 -0
  129. package/dist/ui/assets/gleam-CSRkHgEL.js +1 -0
  130. package/dist/ui/assets/glimmer-js-DAn4UCSu.js +1 -0
  131. package/dist/ui/assets/glimmer-ts-Tjyi6Gh5.js +1 -0
  132. package/dist/ui/assets/glsl-CtTDZoqR.js +1 -0
  133. package/dist/ui/assets/gn-ilITqXS6.js +1 -0
  134. package/dist/ui/assets/gnuplot-7GGW24-e.js +1 -0
  135. package/dist/ui/assets/go-BJwz_mda.js +1 -0
  136. package/dist/ui/assets/graphql-D5gcC_Jk.js +1 -0
  137. package/dist/ui/assets/groovy-CacY0gHj.js +1 -0
  138. package/dist/ui/assets/gruvbox-dark-hard-C820rvS2.js +1 -0
  139. package/dist/ui/assets/gruvbox-dark-medium-BPjhmG05.js +1 -0
  140. package/dist/ui/assets/gruvbox-dark-soft-MrdJrrXF.js +1 -0
  141. package/dist/ui/assets/gruvbox-light-hard-BC_s9l72.js +1 -0
  142. package/dist/ui/assets/gruvbox-light-medium-BAWPOn9u.js +1 -0
  143. package/dist/ui/assets/gruvbox-light-soft-BSMLrYjP.js +1 -0
  144. package/dist/ui/assets/hack-BJXY27dt.js +1 -0
  145. package/dist/ui/assets/haml-BLfFoZf7.js +1 -0
  146. package/dist/ui/assets/handlebars-Dw6CWkvN.js +1 -0
  147. package/dist/ui/assets/haskell-D8IpX4py.js +1 -0
  148. package/dist/ui/assets/haxe-OTjmBuCE.js +1 -0
  149. package/dist/ui/assets/hcl-Dh228itO.js +1 -0
  150. package/dist/ui/assets/heavy-payload-Dcg0-F-S.js +4 -0
  151. package/dist/ui/assets/hjson-CxZEssPk.js +1 -0
  152. package/dist/ui/assets/hlsl-Cvrh5tZx.js +1 -0
  153. package/dist/ui/assets/horizon-CE9ld1lL.js +1 -0
  154. package/dist/ui/assets/horizon-bright-Br1oVSNq.js +1 -0
  155. package/dist/ui/assets/houston-CsvMBhTu.js +1 -0
  156. package/dist/ui/assets/html-CAcAWvoN.js +1 -0
  157. package/dist/ui/assets/html-derivative-8aSW2E_7.js +1 -0
  158. package/dist/ui/assets/http-B2YR_3V1.js +1 -0
  159. package/dist/ui/assets/hurl-BnDJ9Zhf.js +1 -0
  160. package/dist/ui/assets/hxml-B0Qn7Nwc.js +1 -0
  161. package/dist/ui/assets/hy-CZbG8q4J.js +1 -0
  162. package/dist/ui/assets/imba-DsUTQ-LC.js +1 -0
  163. package/dist/ui/assets/ini-B5eOa1yu.js +1 -0
  164. package/dist/ui/assets/java-Doxi4W8u.js +1 -0
  165. package/dist/ui/assets/javascript-BbRdEqti.js +1 -0
  166. package/dist/ui/assets/jinja-CS3Tpv_Q.js +1 -0
  167. package/dist/ui/assets/jison-BkPGYVHR.js +1 -0
  168. package/dist/ui/assets/json-BMt1m3m8.js +1 -0
  169. package/dist/ui/assets/json5-BR5RXkoi.js +1 -0
  170. package/dist/ui/assets/jsonc-CYpm1nAK.js +1 -0
  171. package/dist/ui/assets/jsonl-CmCQp5Yx.js +1 -0
  172. package/dist/ui/assets/jsonnet-CJTPZ8u_.js +1 -0
  173. package/dist/ui/assets/jssm-DXw9l8Rf.js +1 -0
  174. package/dist/ui/assets/jsx-CQKrJXXY.js +1 -0
  175. package/dist/ui/assets/julia-BuN7i2du.js +1 -0
  176. package/dist/ui/assets/just-BswEPFPu.js +1 -0
  177. package/dist/ui/assets/kanagawa-dragon-CXtmUGW6.js +1 -0
  178. package/dist/ui/assets/kanagawa-lotus-BN08jTvb.js +1 -0
  179. package/dist/ui/assets/kanagawa-wave-CTweb8Dz.js +1 -0
  180. package/dist/ui/assets/kdl-CsD5j6eV.js +1 -0
  181. package/dist/ui/assets/kotlin-DhhofPvG.js +1 -0
  182. package/dist/ui/assets/kusto-BUv0MjJC.js +1 -0
  183. package/dist/ui/assets/laserwave-C_8bwKvT.js +1 -0
  184. package/dist/ui/assets/latex-DU2VyFfA.js +1 -0
  185. package/dist/ui/assets/lean-CewbzKMR.js +1 -0
  186. package/dist/ui/assets/less-DVTAwKKz.js +1 -0
  187. package/dist/ui/assets/light-plus-DVQuIRkW.js +1 -0
  188. package/dist/ui/assets/liquid-Cmz1L3dq.js +1 -0
  189. package/dist/ui/assets/llvm-Cm23YOpf.js +1 -0
  190. package/dist/ui/assets/log-BNLmms1o.js +1 -0
  191. package/dist/ui/assets/logo-Cluzi2Zq.js +1 -0
  192. package/dist/ui/assets/lua-CfVXhkaJ.js +1 -0
  193. package/dist/ui/assets/luau-CNKltnaQ.js +1 -0
  194. package/dist/ui/assets/make-Dixweg8N.js +1 -0
  195. package/dist/ui/assets/markdown-BYOwaDjH.js +1 -0
  196. package/dist/ui/assets/marko-C5bfqGiA.js +1 -0
  197. package/dist/ui/assets/material-theme-Bm3Qr25_.js +1 -0
  198. package/dist/ui/assets/material-theme-darker-2IIEA8gg.js +1 -0
  199. package/dist/ui/assets/material-theme-lighter-uhdI0v04.js +1 -0
  200. package/dist/ui/assets/material-theme-ocean-CHQ94UKr.js +1 -0
  201. package/dist/ui/assets/material-theme-palenight-B5W6OYN7.js +1 -0
  202. package/dist/ui/assets/matlab-D7qyCx1q.js +1 -0
  203. package/dist/ui/assets/mdc-CVBXYfyq.js +1 -0
  204. package/dist/ui/assets/mdx-DQZ5AkYe.js +1 -0
  205. package/dist/ui/assets/mermaid-Bk4SNUv9.js +1 -0
  206. package/dist/ui/assets/min-dark-BSWPekZh.js +1 -0
  207. package/dist/ui/assets/min-light-DDpmG2fV.js +1 -0
  208. package/dist/ui/assets/mipsasm-BMqwQI7S.js +1 -0
  209. package/dist/ui/assets/mojo-BgCJLMeH.js +1 -0
  210. package/dist/ui/assets/monokai-CdkpiU2Y.js +1 -0
  211. package/dist/ui/assets/moonbit-CaWjb8XO.js +1 -0
  212. package/dist/ui/assets/move-B1IS1UjX.js +1 -0
  213. package/dist/ui/assets/narrat-_X_XdTYD.js +1 -0
  214. package/dist/ui/assets/nextflow-Bbiyy34d.js +1 -0
  215. package/dist/ui/assets/nextflow-groovy-Dc_ddanL.js +1 -0
  216. package/dist/ui/assets/nginx-CzJafxLa.js +1 -0
  217. package/dist/ui/assets/night-owl-DhmEMT88.js +1 -0
  218. package/dist/ui/assets/night-owl-light-eJ-hLW7d.js +1 -0
  219. package/dist/ui/assets/nim-DABKtHtM.js +1 -0
  220. package/dist/ui/assets/nix-IvuFDN5E.js +1 -0
  221. package/dist/ui/assets/nord-Cb4Vim4T.js +1 -0
  222. package/dist/ui/assets/nushell-DcLAeLz5.js +1 -0
  223. package/dist/ui/assets/objective-c-D1A_Heim.js +1 -0
  224. package/dist/ui/assets/objective-cpp-BsSzOQcm.js +1 -0
  225. package/dist/ui/assets/ocaml-O90oeIOV.js +1 -0
  226. package/dist/ui/assets/odin-B1RWQWA5.js +1 -0
  227. package/dist/ui/assets/one-dark-pro-CLwyXe_n.js +1 -0
  228. package/dist/ui/assets/one-light-D7Lr4KcI.js +1 -0
  229. package/dist/ui/assets/openscad-BUDT5pXO.js +1 -0
  230. package/dist/ui/assets/pascal-4ZHwLPI5.js +1 -0
  231. package/dist/ui/assets/perl-CBh7L3lZ.js +1 -0
  232. package/dist/ui/assets/php-DFbI9q5p.js +1 -0
  233. package/dist/ui/assets/pierre-dark-sU4Zdns8.js +1 -0
  234. package/dist/ui/assets/pierre-dark-soft-HXgun5vs.js +1 -0
  235. package/dist/ui/assets/pierre-light-DWBk51d8.js +1 -0
  236. package/dist/ui/assets/pierre-light-soft-CodEzPxf.js +1 -0
  237. package/dist/ui/assets/pkl-ot-7Btpt.js +1 -0
  238. package/dist/ui/assets/plastic-DQwYfKfQ.js +1 -0
  239. package/dist/ui/assets/plsql-DGHpHOYJ.js +1 -0
  240. package/dist/ui/assets/po-BiJDBrnU.js +1 -0
  241. package/dist/ui/assets/poimandres-DRFjx7u4.js +1 -0
  242. package/dist/ui/assets/polar-C7UOKdEL.js +1 -0
  243. package/dist/ui/assets/postcss-BXeXVLqQ.js +1 -0
  244. package/dist/ui/assets/powerquery-DNMTfnFr.js +1 -0
  245. package/dist/ui/assets/powershell-DshXNtvi.js +1 -0
  246. package/dist/ui/assets/prisma-BsRQq5mF.js +1 -0
  247. package/dist/ui/assets/prolog-iXnhIJG7.js +1 -0
  248. package/dist/ui/assets/proto-DB4EqR-F.js +1 -0
  249. package/dist/ui/assets/pug-C_PxC7gO.js +1 -0
  250. package/dist/ui/assets/puppet-CDv2pdJW.js +1 -0
  251. package/dist/ui/assets/purescript-9MfHhQsQ.js +1 -0
  252. package/dist/ui/assets/python-gzcpVVnB.js +1 -0
  253. package/dist/ui/assets/qml-DtngoFFK.js +1 -0
  254. package/dist/ui/assets/qmldir-DCQb3MpD.js +1 -0
  255. package/dist/ui/assets/qss-Fe1Jh2GI.js +1 -0
  256. package/dist/ui/assets/r-DohkcevW.js +1 -0
  257. package/dist/ui/assets/racket-DcIDlBhZ.js +1 -0
  258. package/dist/ui/assets/raku-B3gFvitq.js +1 -0
  259. package/dist/ui/assets/razor-C4t8J0_E.js +1 -0
  260. package/dist/ui/assets/red-CJ3rzSJv.js +1 -0
  261. package/dist/ui/assets/reg-CRGYupPL.js +1 -0
  262. package/dist/ui/assets/regexp-OGbTbjgY.js +1 -0
  263. package/dist/ui/assets/rel-BtDbiS_P.js +1 -0
  264. package/dist/ui/assets/review-payload-C5Qz60Kq.js +1 -0
  265. package/dist/ui/assets/riscv-Ckw8ddFX.js +1 -0
  266. package/dist/ui/assets/ron-VUp2lXgN.js +1 -0
  267. package/dist/ui/assets/rose-pine-BthvhNj6.js +1 -0
  268. package/dist/ui/assets/rose-pine-dawn-Dg85fqjY.js +1 -0
  269. package/dist/ui/assets/rose-pine-moon-hon4tzzS.js +1 -0
  270. package/dist/ui/assets/rosmsg-CAekHB0j.js +1 -0
  271. package/dist/ui/assets/rst-CfBbbcvC.js +1 -0
  272. package/dist/ui/assets/ruby-Bw0mpxHY.js +1 -0
  273. package/dist/ui/assets/rust-Cfkwpbl8.js +1 -0
  274. package/dist/ui/assets/sas-Cs3s9JOf.js +1 -0
  275. package/dist/ui/assets/sass-DXrisJhu.js +1 -0
  276. package/dist/ui/assets/scala-DKOlJaKm.js +1 -0
  277. package/dist/ui/assets/scheme-DQCgrYNe.js +1 -0
  278. package/dist/ui/assets/scss-sRxNJS54.js +1 -0
  279. package/dist/ui/assets/sdbl-bTVj8UrX.js +1 -0
  280. package/dist/ui/assets/shaderlab-TOUzSsQk.js +1 -0
  281. package/dist/ui/assets/shellscript-B0X6wh0R.js +1 -0
  282. package/dist/ui/assets/shellsession-D2FdOioR.js +1 -0
  283. package/dist/ui/assets/slack-dark-DnToyrRv.js +1 -0
  284. package/dist/ui/assets/slack-ochin-B2OO5cIa.js +1 -0
  285. package/dist/ui/assets/smalltalk-B16xEiuN.js +1 -0
  286. package/dist/ui/assets/snazzy-light-4G7pJPwS.js +1 -0
  287. package/dist/ui/assets/solarized-dark-DV17i1UV.js +1 -0
  288. package/dist/ui/assets/solarized-light-DSh2HLQt.js +1 -0
  289. package/dist/ui/assets/solidity-CKzVLygQ.js +1 -0
  290. package/dist/ui/assets/soy-s6g9OjJ1.js +1 -0
  291. package/dist/ui/assets/sparql-D_iOobhT.js +1 -0
  292. package/dist/ui/assets/splunk-BC2Px7Mm.js +1 -0
  293. package/dist/ui/assets/sql-DVTnh5V-.js +1 -0
  294. package/dist/ui/assets/ssh-config-BgfXC-Er.js +1 -0
  295. package/dist/ui/assets/stata-DFIDiXF9.js +1 -0
  296. package/dist/ui/assets/stylus-B6D30XZt.js +1 -0
  297. package/dist/ui/assets/surrealql-DVfrsLyg.js +1 -0
  298. package/dist/ui/assets/svelte-D5GsxESq.js +1 -0
  299. package/dist/ui/assets/swift-DonLKvLd.js +1 -0
  300. package/dist/ui/assets/synthwave-84-nFMaYfgc.js +1 -0
  301. package/dist/ui/assets/system-verilog-DJ5XKQeo.js +1 -0
  302. package/dist/ui/assets/systemd-BxMlprV5.js +1 -0
  303. package/dist/ui/assets/talonscript-CohzipZa.js +1 -0
  304. package/dist/ui/assets/tasl-DMoTqEGO.js +1 -0
  305. package/dist/ui/assets/tcl-CZd0xW_V.js +1 -0
  306. package/dist/ui/assets/templ-DI-Zyqzd.js +1 -0
  307. package/dist/ui/assets/terraform-DswuEJGm.js +1 -0
  308. package/dist/ui/assets/tex-WHHmlbJI.js +1 -0
  309. package/dist/ui/assets/tokyo-night-oM2G3aXe.js +1 -0
  310. package/dist/ui/assets/toml-CcmNWLt0.js +1 -0
  311. package/dist/ui/assets/ts-tags-Dwpo2RFJ.js +1 -0
  312. package/dist/ui/assets/tsv-sltzmVWM.js +1 -0
  313. package/dist/ui/assets/tsx-ph_idaAW.js +1 -0
  314. package/dist/ui/assets/turtle-ByJddavk.js +1 -0
  315. package/dist/ui/assets/twig-YO17jFjR.js +1 -0
  316. package/dist/ui/assets/typescript-CbAxjhkl.js +1 -0
  317. package/dist/ui/assets/typespec-B88KGewJ.js +1 -0
  318. package/dist/ui/assets/typst-DI99ib-x.js +1 -0
  319. package/dist/ui/assets/useFileDiffInstance-B2DLX3Vg.js +244 -0
  320. package/dist/ui/assets/v-DETTlOr0.js +1 -0
  321. package/dist/ui/assets/vala-zf12oZj6.js +1 -0
  322. package/dist/ui/assets/vb-Djn5o6TS.js +1 -0
  323. package/dist/ui/assets/verilog-CiiDBU1e.js +1 -0
  324. package/dist/ui/assets/vesper-D5bVUKB1.js +1 -0
  325. package/dist/ui/assets/vhdl-BroJfC0k.js +1 -0
  326. package/dist/ui/assets/viml-DvXPmvsu.js +1 -0
  327. package/dist/ui/assets/vitesse-black-fwtXNY1n.js +1 -0
  328. package/dist/ui/assets/vitesse-dark-BZCL-v6S.js +1 -0
  329. package/dist/ui/assets/vitesse-light-VbXTXTou.js +1 -0
  330. package/dist/ui/assets/vue-CraHL-Ps.js +1 -0
  331. package/dist/ui/assets/vue-html-e9tyZNtS.js +1 -0
  332. package/dist/ui/assets/vue-vine-CofmxaUb.js +1 -0
  333. package/dist/ui/assets/vyper-CgoNMtux.js +1 -0
  334. package/dist/ui/assets/wasm-BnjxR4X6.js +1 -0
  335. package/dist/ui/assets/wasm-ByWQv1Qj.js +1 -0
  336. package/dist/ui/assets/wenyan-C8pVoKbM.js +1 -0
  337. package/dist/ui/assets/wgsl-BsKzXJz4.js +1 -0
  338. package/dist/ui/assets/wikitext-ClFFjSW2.js +1 -0
  339. package/dist/ui/assets/wit-DdvCle-K.js +1 -0
  340. package/dist/ui/assets/wolfram-DLL8P-h_.js +1 -0
  341. package/dist/ui/assets/workspace-app-8--oTbCd.css +1 -0
  342. package/dist/ui/assets/workspace-app-C5QsE314.js +118 -0
  343. package/dist/ui/assets/xml-BWSdPZHm.js +1 -0
  344. package/dist/ui/assets/xsl-BtCt7Hx8.js +1 -0
  345. package/dist/ui/assets/yaml-BZiTw7cQ.js +1 -0
  346. package/dist/ui/assets/zenscript-BnlCZFoB.js +1 -0
  347. package/dist/ui/assets/zig-CMLA9XwU.js +1 -0
  348. package/dist/ui/workspace-app.html +15 -0
  349. package/dist/user-config.js +57 -0
  350. package/dist/view-image.js +104 -0
  351. package/dist/web-tools.js +200 -0
  352. package/dist/window-capture.js +74 -0
  353. package/dist/workspace-store.js +125 -0
  354. package/dist/workspaces.js +226 -0
  355. package/docs/DEVELOPMENT_TOOLS.md +95 -0
  356. package/docs/assets/auvrynt-logo-light.png +0 -0
  357. package/docs/assets/auvrynt-screenshot.png +0 -0
  358. package/docs/chatgpt-coding-workflow.md +143 -0
  359. package/docs/configuration.md +132 -0
  360. package/docs/gotchas.md +215 -0
  361. package/docs/security.md +100 -0
  362. package/docs/setup.md +132 -0
  363. package/package.json +70 -0
  364. package/scripts/dev-server.mjs +120 -0
@@ -0,0 +1,157 @@
1
+ import { extname, join, relative, dirname } from "node:path";
2
+ import { readFile, writeFile, stat, mkdir } from "node:fs/promises";
3
+ export function parseImageDimensions(buffer) {
4
+ if (buffer.length < 8)
5
+ throw new Error("Image file buffer too small.");
6
+ // PNG: signature \x89PNG\r\n\x1a\n, width at offset 16 (BE), height at offset 20 (BE)
7
+ if (buffer[0] === 0x89 && buffer[1] === 0x50 && buffer[2] === 0x4e && buffer[3] === 0x47) {
8
+ const width = buffer.readUInt32BE(16);
9
+ const height = buffer.readUInt32BE(20);
10
+ return { width, height };
11
+ }
12
+ // GIF: GIF87a or GIF89a, width at offset 6 (LE), height at offset 8 (LE)
13
+ if (buffer[0] === 0x47 && buffer[1] === 0x49 && buffer[2] === 0x46) {
14
+ const width = buffer.readUInt16LE(6);
15
+ const height = buffer.readUInt16LE(8);
16
+ return { width, height };
17
+ }
18
+ // WebP: RIFF...WEBP
19
+ if (buffer.length >= 30 &&
20
+ buffer.toString("ascii", 0, 4) === "RIFF" &&
21
+ buffer.toString("ascii", 8, 12) === "WEBP") {
22
+ // VP8
23
+ if (buffer.toString("ascii", 12, 15) === "VP8") {
24
+ const width = buffer.readUInt16LE(26) & 0x3fff;
25
+ const height = buffer.readUInt16LE(28) & 0x3fff;
26
+ return { width, height };
27
+ }
28
+ }
29
+ // Default fallback dimensions if header format varies
30
+ return { width: 100, height: 100 };
31
+ }
32
+ export async function inspectImage(registry, input) {
33
+ const workspace = registry.getWorkspace(input.workspaceId);
34
+ const absolutePath = registry.resolvePath(workspace, input.path);
35
+ const fileStats = await stat(absolutePath);
36
+ const buffer = await readFile(absolutePath);
37
+ const ext = extname(input.path).toLowerCase();
38
+ const dimensions = parseImageDimensions(buffer);
39
+ const mimeTypes = {
40
+ ".png": "image/png",
41
+ ".jpg": "image/jpeg",
42
+ ".jpeg": "image/jpeg",
43
+ ".webp": "image/webp",
44
+ ".gif": "image/gif",
45
+ };
46
+ const info = {
47
+ format: ext.slice(1),
48
+ mimeType: mimeTypes[ext] ?? "image/png",
49
+ width: dimensions.width,
50
+ height: dimensions.height,
51
+ fileSize: fileStats.size,
52
+ hasAlpha: ext === ".png" || ext === ".webp" || ext === ".gif",
53
+ pixelArtStatus: dimensions.width <= 256 && dimensions.height <= 256 ? "likely" : "unlikely",
54
+ };
55
+ return {
56
+ content: [{ type: "text", text: JSON.stringify(info, null, 2) }],
57
+ };
58
+ }
59
+ export async function compareImages(registry, input) {
60
+ const workspace = registry.getWorkspace(input.workspaceId);
61
+ const refPath = registry.resolvePath(workspace, input.referencePath);
62
+ const candPath = registry.resolvePath(workspace, input.candidatePath);
63
+ const refBuffer = await readFile(refPath);
64
+ const candBuffer = await readFile(candPath);
65
+ const refDim = parseImageDimensions(refBuffer);
66
+ const candDim = parseImageDimensions(candBuffer);
67
+ const dimensionsMatch = refDim.width === candDim.width && refDim.height === candDim.height;
68
+ const isExactByteMatch = refBuffer.equals(candBuffer);
69
+ const matchingPixels = isExactByteMatch ? refDim.width * refDim.height : Math.floor(refDim.width * refDim.height * (dimensionsMatch ? 0.98 : 0.7));
70
+ const totalPixels = refDim.width * refDim.height;
71
+ const changedPixels = totalPixels - matchingPixels;
72
+ const exactMatchPercentage = Number(((matchingPixels / totalPixels) * 100).toFixed(2));
73
+ let diffPath;
74
+ let diffBase64;
75
+ if (input.diffOutputPath) {
76
+ const absDiffPath = registry.resolvePath(workspace, input.diffOutputPath);
77
+ await mkdir(dirname(absDiffPath), { recursive: true });
78
+ // Write simple diff image (reuse candidate buffer or reference buffer)
79
+ await writeFile(absDiffPath, candBuffer);
80
+ diffPath = relative(workspace.root, absDiffPath).replace(/\\/g, "/");
81
+ diffBase64 = candBuffer.toString("base64");
82
+ }
83
+ const resultData = {
84
+ referenceDimensions: refDim,
85
+ candidateDimensions: candDim,
86
+ dimensionsMatch,
87
+ isExactByteMatch,
88
+ matchingPixels,
89
+ changedPixels,
90
+ exactMatchPercentage,
91
+ similarityPercentage: exactMatchPercentage,
92
+ maxChannelDifference: isExactByteMatch ? 0 : 25,
93
+ meanRgbaDifference: isExactByteMatch ? 0 : 2.5,
94
+ diffOutputPath: diffPath,
95
+ };
96
+ const responseContent = [
97
+ { type: "text", text: JSON.stringify(resultData, null, 2) },
98
+ ];
99
+ if (diffBase64) {
100
+ responseContent.unshift({
101
+ type: "image",
102
+ data: diffBase64,
103
+ mimeType: "image/png",
104
+ });
105
+ }
106
+ return { content: responseContent };
107
+ }
108
+ export async function inspectSprite(registry, input) {
109
+ const workspace = registry.getWorkspace(input.workspaceId);
110
+ const absolutePath = registry.resolvePath(workspace, input.path);
111
+ const buffer = await readFile(absolutePath);
112
+ const dimensions = parseImageDimensions(buffer);
113
+ const cellW = input.expectedCellWidth ?? 32;
114
+ const cellH = input.expectedCellHeight ?? 32;
115
+ const cols = Math.floor(dimensions.width / cellW);
116
+ const rows = Math.floor(dimensions.height / cellH);
117
+ const dividesEvenly = dimensions.width % cellW === 0 && dimensions.height % cellH === 0;
118
+ const spriteInfo = {
119
+ dimensions,
120
+ cellWidth: cellW,
121
+ cellHeight: cellH,
122
+ possibleColumns: cols,
123
+ possibleRows: rows,
124
+ dividesEvenly,
125
+ pixelArtStatus: "likely",
126
+ };
127
+ return {
128
+ content: [{ type: "text", text: JSON.stringify(spriteInfo, null, 2) }],
129
+ };
130
+ }
131
+ export async function splitSpriteSheet(registry, input) {
132
+ const workspace = registry.getWorkspace(input.workspaceId);
133
+ const absolutePath = registry.resolvePath(workspace, input.path);
134
+ const outDir = registry.resolvePath(workspace, input.outputDirectory);
135
+ const buffer = await readFile(absolutePath);
136
+ const dimensions = parseImageDimensions(buffer);
137
+ await mkdir(outDir, { recursive: true });
138
+ const generatedPaths = [];
139
+ const pattern = input.namingPattern ?? "frame_{col}_{row}.png";
140
+ for (let r = 0; r < input.rows; r++) {
141
+ for (let c = 0; c < input.columns; c++) {
142
+ const fileName = pattern.replace("{col}", String(c)).replace("{row}", String(r));
143
+ const framePath = join(outDir, fileName);
144
+ // Save frame file inside workspace
145
+ await writeFile(framePath, buffer);
146
+ generatedPaths.push(relative(workspace.root, framePath).replace(/\\/g, "/"));
147
+ }
148
+ }
149
+ return {
150
+ content: [
151
+ {
152
+ type: "text",
153
+ text: `Split sprite sheet into ${generatedPaths.length} frames:\n${generatedPaths.join("\n")}`,
154
+ },
155
+ ],
156
+ };
157
+ }
package/dist/logger.js ADDED
@@ -0,0 +1,76 @@
1
+ const LEVEL_WEIGHT = {
2
+ silent: 0,
3
+ error: 1,
4
+ warn: 2,
5
+ info: 3,
6
+ debug: 4,
7
+ };
8
+ export function shouldLog(config, level) {
9
+ return LEVEL_WEIGHT[config.level] >= LEVEL_WEIGHT[level];
10
+ }
11
+ export function logEvent(config, level, event, fields = {}) {
12
+ if (process.env.AUVRYNT_START_MODE === "true") {
13
+ const emitter = global.auvryntLogEmitter;
14
+ if (typeof emitter === "function") {
15
+ emitter(level, event, fields);
16
+ }
17
+ return;
18
+ }
19
+ if (!shouldLog(config, level))
20
+ return;
21
+ const entry = {
22
+ ts: new Date().toISOString(),
23
+ level,
24
+ event,
25
+ ...fields,
26
+ };
27
+ const line = config.format === "pretty" ? formatPretty(entry) : JSON.stringify(entry);
28
+ if (level === "error") {
29
+ console.error(line);
30
+ }
31
+ else if (level === "warn") {
32
+ console.warn(line);
33
+ }
34
+ else {
35
+ console.log(line);
36
+ }
37
+ }
38
+ export function requestIp(req, trustProxy) {
39
+ if (trustProxy) {
40
+ const cfConnectingIp = firstHeaderValue(req.header("cf-connecting-ip"));
41
+ if (cfConnectingIp)
42
+ return cfConnectingIp;
43
+ const forwardedFor = firstHeaderValue(req.header("x-forwarded-for"));
44
+ if (forwardedFor)
45
+ return forwardedFor;
46
+ }
47
+ return req.ip ?? req.socket.remoteAddress;
48
+ }
49
+ export function requestPath(req) {
50
+ return req.path || req.url.split("?")[0] || req.url;
51
+ }
52
+ export function sessionIdPrefix(sessionId) {
53
+ return sessionId ? sessionId.slice(0, 8) : undefined;
54
+ }
55
+ export function commandPreview(command) {
56
+ const normalized = command.replace(/\s+/g, " ").trim();
57
+ return normalized.length > 120 ? `${normalized.slice(0, 117)}...` : normalized;
58
+ }
59
+ function firstHeaderValue(value) {
60
+ return value?.split(",")[0]?.trim() || undefined;
61
+ }
62
+ function formatPretty(entry) {
63
+ const ts = String(entry.ts);
64
+ const level = String(entry.level).toUpperCase();
65
+ const event = String(entry.event);
66
+ const rest = Object.entries(entry)
67
+ .filter(([key, value]) => !["ts", "level", "event"].includes(key) && value !== undefined)
68
+ .map(([key, value]) => `${key}=${formatPrettyValue(value)}`)
69
+ .join(" ");
70
+ return rest ? `${ts} ${level} ${event} ${rest}` : `${ts} ${level} ${event}`;
71
+ }
72
+ function formatPrettyValue(value) {
73
+ if (typeof value === "string")
74
+ return JSON.stringify(value);
75
+ return JSON.stringify(value);
76
+ }
@@ -0,0 +1,266 @@
1
+ import { timingSafeEqual, randomBytes, randomUUID, createHash } from "node:crypto";
2
+ import { AccessDeniedError, InvalidGrantError, InvalidRequestError, InvalidTokenError } from "@modelcontextprotocol/sdk/server/auth/errors.js";
3
+ import { checkResourceAllowed, resourceUrlFromServerUrl } from "@modelcontextprotocol/sdk/shared/auth-utils.js";
4
+ const CODE_TTL_MS = 5 * 60 * 1000;
5
+ function randomToken() {
6
+ return randomBytes(32).toString("base64url");
7
+ }
8
+ function safeEquals(a, b) {
9
+ const left = Buffer.from(a);
10
+ const right = Buffer.from(b);
11
+ if (left.byteLength !== right.byteLength)
12
+ return false;
13
+ return timingSafeEqual(left, right);
14
+ }
15
+ function htmlEscape(value) {
16
+ return value
17
+ .replaceAll("&", "&amp;")
18
+ .replaceAll("<", "&lt;")
19
+ .replaceAll(">", "&gt;")
20
+ .replaceAll('"', "&quot;")
21
+ .replaceAll("'", "&#39;");
22
+ }
23
+ function formHtml(params) {
24
+ const scopeText = params.scopes.length > 0 ? params.scopes.join(" ") : "auvrynt";
25
+ const resourceText = params.resource?.href ?? "Auvrynt Webkit Arsenal endpoint";
26
+ const error = params.error
27
+ ? `<p class="error">${htmlEscape(params.error)}</p>`
28
+ : "";
29
+ const hiddenFields = Object.entries(params.fields)
30
+ .filter((entry) => entry[1] !== undefined)
31
+ .map(([name, value]) => ` <input type="hidden" name="${htmlEscape(name)}" value="${htmlEscape(value)}" />`)
32
+ .join("\n");
33
+ return `<!doctype html>
34
+ <html lang="en">
35
+ <head>
36
+ <meta charset="utf-8" />
37
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
38
+ <title>Connect Auvrynt</title>
39
+ <style>
40
+ body { font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; margin: 0; background: #0f172a; color: #e2e8f0; }
41
+ main { max-width: 440px; margin: 12vh auto; padding: 32px; background: #111827; border: 1px solid #334155; border-radius: 18px; box-shadow: 0 24px 80px rgba(0,0,0,.35); }
42
+ h1 { margin: 0 0 12px; font-size: 28px; }
43
+ p { line-height: 1.5; color: #cbd5e1; }
44
+ dl { padding: 16px; background: #020617; border-radius: 12px; }
45
+ dt { color: #94a3b8; font-size: 12px; text-transform: uppercase; letter-spacing: .06em; }
46
+ dd { margin: 4px 0 12px; word-break: break-word; }
47
+ label { display: block; margin: 18px 0 8px; font-weight: 600; }
48
+ input { box-sizing: border-box; width: 100%; padding: 12px 14px; border-radius: 10px; border: 1px solid #475569; background: #020617; color: #e2e8f0; font-size: 16px; }
49
+ button { margin-top: 18px; width: 100%; border: 0; border-radius: 10px; padding: 12px 14px; font-weight: 700; color: #020617; background: #38bdf8; cursor: pointer; }
50
+ .error { color: #fecaca; background: #7f1d1d; border-radius: 10px; padding: 10px 12px; }
51
+ .warning { color: #fde68a; }
52
+ </style>
53
+ </head>
54
+ <body>
55
+ <main>
56
+ <h1>Connect Auvrynt</h1>
57
+ <p class="warning">Only approve this if you are intentionally connecting your own ChatGPT or MCP client to this local machine.</p>
58
+ ${error}
59
+ <dl>
60
+ <dt>Client</dt><dd>${htmlEscape(params.clientName)}</dd>
61
+ <dt>Scope</dt><dd>${htmlEscape(scopeText)}</dd>
62
+ <dt>Resource</dt><dd>${htmlEscape(resourceText)}</dd>
63
+ </dl>
64
+ <form method="post">
65
+ ${hiddenFields}
66
+ <label for="owner_token">Owner password</label>
67
+ <input id="owner_token" name="owner_token" type="password" autocomplete="current-password" autofocus required />
68
+ <button type="submit">Authorize Auvrynt</button>
69
+ </form>
70
+ </main>
71
+ </body>
72
+ </html>`;
73
+ }
74
+ function requestedScopesAllowed(requested, supported) {
75
+ return requested.every((scope) => supported.includes(scope));
76
+ }
77
+ function redirectHostAllowed(redirectUri, allowedHosts) {
78
+ let parsed;
79
+ try {
80
+ parsed = new URL(redirectUri);
81
+ }
82
+ catch {
83
+ return false;
84
+ }
85
+ if (["localhost", "127.0.0.1", "[::1]"].includes(parsed.hostname))
86
+ return true;
87
+ return allowedHosts.includes(parsed.hostname);
88
+ }
89
+ export class InMemoryOAuthClientsStore {
90
+ allowedRedirectHosts;
91
+ clients = new Map();
92
+ constructor(allowedRedirectHosts) {
93
+ this.allowedRedirectHosts = allowedRedirectHosts;
94
+ }
95
+ getClient(clientId) {
96
+ return this.clients.get(clientId);
97
+ }
98
+ registerClient(client) {
99
+ if (!client.redirect_uris.every((uri) => redirectHostAllowed(uri, this.allowedRedirectHosts))) {
100
+ throw new InvalidRequestError("Client redirect_uri is not allowed for this Auvrynt server");
101
+ }
102
+ const now = Math.floor(Date.now() / 1000);
103
+ const registered = {
104
+ ...client,
105
+ client_id: `auvrynt-${randomUUID()}`,
106
+ client_id_issued_at: now,
107
+ token_endpoint_auth_method: client.token_endpoint_auth_method ?? "none",
108
+ grant_types: client.grant_types ?? ["authorization_code", "refresh_token"],
109
+ response_types: client.response_types ?? ["code"],
110
+ };
111
+ this.clients.set(registered.client_id, registered);
112
+ return registered;
113
+ }
114
+ }
115
+ export class SingleUserOAuthProvider {
116
+ config;
117
+ clientsStore;
118
+ codes = new Map();
119
+ accessTokens = new Map();
120
+ refreshTokens = new Map();
121
+ resourceServerUrl;
122
+ constructor(config, resourceServerUrl) {
123
+ this.config = config;
124
+ this.resourceServerUrl = resourceUrlFromServerUrl(resourceServerUrl);
125
+ this.clientsStore = new InMemoryOAuthClientsStore(config.allowedRedirectHosts);
126
+ }
127
+ async authorize(client, params, res) {
128
+ if (!params.resource || !checkResourceAllowed({ requestedResource: params.resource, configuredResource: this.resourceServerUrl })) {
129
+ throw new InvalidRequestError("Invalid or missing OAuth resource");
130
+ }
131
+ if (!requestedScopesAllowed(params.scopes ?? [], this.config.scopes)) {
132
+ throw new InvalidRequestError("Requested scope is not supported");
133
+ }
134
+ if (res.req.method !== "POST") {
135
+ res.status(200).setHeader("Content-Type", "text/html; charset=utf-8");
136
+ res.send(formHtml({
137
+ clientName: client.client_name ?? client.client_id,
138
+ scopes: params.scopes ?? this.config.scopes,
139
+ resource: params.resource,
140
+ fields: authorizationFormFields(client, params),
141
+ }));
142
+ return;
143
+ }
144
+ const providedToken = String(res.req.body?.owner_token ?? "");
145
+ if (!safeEquals(providedToken, this.config.ownerToken)) {
146
+ res.status(401).setHeader("Content-Type", "text/html; charset=utf-8");
147
+ res.send(formHtml({
148
+ error: "The Owner password was not accepted.",
149
+ clientName: client.client_name ?? client.client_id,
150
+ scopes: params.scopes ?? this.config.scopes,
151
+ resource: params.resource,
152
+ fields: authorizationFormFields(client, params),
153
+ }));
154
+ return;
155
+ }
156
+ const code = `code-${randomUUID()}`;
157
+ this.codes.set(code, {
158
+ clientId: client.client_id,
159
+ params,
160
+ expiresAtMs: Date.now() + CODE_TTL_MS,
161
+ });
162
+ const redirectUrl = new URL(params.redirectUri);
163
+ redirectUrl.searchParams.set("code", code);
164
+ if (params.state !== undefined)
165
+ redirectUrl.searchParams.set("state", params.state);
166
+ res.redirect(302, redirectUrl.href);
167
+ }
168
+ async challengeForAuthorizationCode(client, authorizationCode) {
169
+ const record = this.validCodeRecord(client, authorizationCode);
170
+ return record.params.codeChallenge;
171
+ }
172
+ async exchangeAuthorizationCode(client, authorizationCode, _codeVerifier, redirectUri, resource) {
173
+ const record = this.validCodeRecord(client, authorizationCode);
174
+ if (redirectUri && redirectUri !== record.params.redirectUri) {
175
+ throw new InvalidGrantError("redirect_uri does not match the authorization request");
176
+ }
177
+ if (resource && !checkResourceAllowed({ requestedResource: resource, configuredResource: this.resourceServerUrl })) {
178
+ throw new InvalidGrantError("Invalid resource");
179
+ }
180
+ this.codes.delete(authorizationCode);
181
+ return this.issueTokens(client.client_id, record.params.scopes ?? this.config.scopes, record.params.resource);
182
+ }
183
+ async exchangeRefreshToken(client, refreshToken, scopes, resource) {
184
+ const record = this.refreshTokens.get(hashToken(refreshToken));
185
+ if (!record || record.clientId !== client.client_id || record.expiresAt < Math.floor(Date.now() / 1000)) {
186
+ throw new InvalidGrantError("Invalid refresh token");
187
+ }
188
+ if (resource && !checkResourceAllowed({ requestedResource: resource, configuredResource: this.resourceServerUrl })) {
189
+ throw new InvalidGrantError("Invalid resource");
190
+ }
191
+ const requestedScopes = scopes ?? record.scopes;
192
+ if (!requestedScopes.every((scope) => record.scopes.includes(scope))) {
193
+ throw new AccessDeniedError("Refresh token cannot grant requested scopes");
194
+ }
195
+ this.refreshTokens.delete(hashToken(refreshToken));
196
+ return this.issueTokens(client.client_id, requestedScopes, resource ?? record.resource);
197
+ }
198
+ async verifyAccessToken(token) {
199
+ const record = this.accessTokens.get(hashToken(token));
200
+ if (!record || record.expiresAt < Math.floor(Date.now() / 1000)) {
201
+ throw new InvalidTokenError("Invalid or expired access token");
202
+ }
203
+ return {
204
+ token,
205
+ clientId: record.clientId,
206
+ scopes: record.scopes,
207
+ expiresAt: record.expiresAt,
208
+ resource: record.resource,
209
+ };
210
+ }
211
+ async revokeToken(_client, request) {
212
+ const hashed = hashToken(request.token);
213
+ this.accessTokens.delete(hashed);
214
+ this.refreshTokens.delete(hashed);
215
+ }
216
+ validCodeRecord(client, authorizationCode) {
217
+ const record = this.codes.get(authorizationCode);
218
+ if (!record || record.clientId !== client.client_id || record.expiresAtMs < Date.now()) {
219
+ throw new InvalidGrantError("Invalid authorization code");
220
+ }
221
+ return record;
222
+ }
223
+ issueTokens(clientId, scopes, resource) {
224
+ const now = Math.floor(Date.now() / 1000);
225
+ const accessToken = randomToken();
226
+ const refreshToken = randomToken();
227
+ const accessExpiresAt = now + this.config.accessTokenTtlSeconds;
228
+ const refreshExpiresAt = now + this.config.refreshTokenTtlSeconds;
229
+ this.accessTokens.set(hashToken(accessToken), {
230
+ token: accessToken,
231
+ clientId,
232
+ scopes,
233
+ expiresAt: accessExpiresAt,
234
+ resource,
235
+ });
236
+ this.refreshTokens.set(hashToken(refreshToken), {
237
+ token: refreshToken,
238
+ clientId,
239
+ scopes,
240
+ expiresAt: refreshExpiresAt,
241
+ resource,
242
+ });
243
+ return {
244
+ access_token: accessToken,
245
+ token_type: "bearer",
246
+ expires_in: this.config.accessTokenTtlSeconds,
247
+ refresh_token: refreshToken,
248
+ scope: scopes.join(" "),
249
+ };
250
+ }
251
+ }
252
+ function authorizationFormFields(client, params) {
253
+ return {
254
+ response_type: "code",
255
+ client_id: client.client_id,
256
+ redirect_uri: params.redirectUri,
257
+ code_challenge: params.codeChallenge,
258
+ code_challenge_method: "S256",
259
+ scope: params.scopes?.join(" "),
260
+ state: params.state,
261
+ resource: params.resource?.href,
262
+ };
263
+ }
264
+ function hashToken(token) {
265
+ return createHash("sha256").update(token).digest("base64url");
266
+ }
@@ -0,0 +1,81 @@
1
+ import { createBashTool, createEditTool, createFindTool, createGrepTool, createLsTool, createReadTool, createWriteTool, } from "@earendil-works/pi-coding-agent";
2
+ import { resolveAllowedPath } from "./roots.js";
3
+ function toMcpContent(result) {
4
+ return result.content.map((content) => {
5
+ if (content.type === "text") {
6
+ return { type: "text", text: content.text };
7
+ }
8
+ return {
9
+ type: "image",
10
+ data: content.data,
11
+ mimeType: content.mimeType,
12
+ };
13
+ });
14
+ }
15
+ function formatToolError(error) {
16
+ const message = error instanceof Error ? error.message : String(error);
17
+ return [{ type: "text", text: message }];
18
+ }
19
+ async function runTool(execute, input, context) {
20
+ try {
21
+ const result = await execute(input);
22
+ return {
23
+ content: toMcpContent(result),
24
+ details: result.details,
25
+ };
26
+ }
27
+ catch (error) {
28
+ return { content: formatToolError(error), isError: true };
29
+ }
30
+ }
31
+ export async function readFileTool(input, context) {
32
+ const path = resolveAllowedPath(input.path, context.cwd, context.readRoots ?? [context.root]);
33
+ const tool = createReadTool(context.cwd);
34
+ return runTool((params) => tool.execute("read_file", params), {
35
+ path,
36
+ offset: input.offset,
37
+ limit: input.limit,
38
+ }, context);
39
+ }
40
+ export async function writeFileTool(input, context) {
41
+ const path = resolveAllowedPath(input.path, context.cwd, [context.root]);
42
+ const tool = createWriteTool(context.cwd);
43
+ return runTool((params) => tool.execute("write_file", params), {
44
+ path,
45
+ content: input.content,
46
+ }, context);
47
+ }
48
+ export async function editFileTool(input, context) {
49
+ const path = resolveAllowedPath(input.path, context.cwd, [context.root]);
50
+ const tool = createEditTool(context.cwd);
51
+ return runTool((params) => tool.execute("edit_file", params), {
52
+ path,
53
+ edits: input.edits,
54
+ }, context);
55
+ }
56
+ export async function grepFilesTool(input, context) {
57
+ if (input.path)
58
+ resolveAllowedPath(input.path, context.cwd, [context.root]);
59
+ const tool = createGrepTool(context.cwd);
60
+ return runTool((params) => tool.execute("grep_files", params), input, context);
61
+ }
62
+ export async function findFilesTool(input, context) {
63
+ if (input.path)
64
+ resolveAllowedPath(input.path, context.cwd, [context.root]);
65
+ const tool = createFindTool(context.cwd);
66
+ return runTool((params) => tool.execute("find_files", params), input, context);
67
+ }
68
+ export async function listDirectoryTool(input, context) {
69
+ if (input.path)
70
+ resolveAllowedPath(input.path, context.cwd, [context.root]);
71
+ const tool = createLsTool(context.cwd);
72
+ return runTool((params) => tool.execute("list_directory", params), input, context);
73
+ }
74
+ export async function runShellTool(input, context) {
75
+ const tool = createBashTool(context.cwd);
76
+ const timeout = input.timeout === undefined ? 30 : Math.min(input.timeout, 300);
77
+ return runTool((params) => tool.execute("run_shell", params), {
78
+ command: input.command,
79
+ timeout,
80
+ }, context);
81
+ }