@danneillouven/remote-workspace 0.0.0-stage → 0.1.0

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 (1469) hide show
  1. package/.env.example +32 -0
  2. package/README.md +196 -2
  3. package/bin/remote-workspace.mjs +29 -0
  4. package/dist/assets/add-project-screen-IOzaLXTc.js +1 -0
  5. package/dist/assets/apl-gfMMiTNf.js +1 -0
  6. package/dist/assets/arrow-left-B5CLiIbq.js +1 -0
  7. package/dist/assets/asciiarmor-C_eisQCp.js +1 -0
  8. package/dist/assets/asn1-DCl_8MCW.js +1 -0
  9. package/dist/assets/asterisk-BEn0Cwpx.js +1 -0
  10. package/dist/assets/brainfuck-D5EjA2JK.js +1 -0
  11. package/dist/assets/client-BaUFYZ28.js +63 -0
  12. package/dist/assets/clike-xvONpD0Z.js +1 -0
  13. package/dist/assets/clojure-BflJGmDX.js +1 -0
  14. package/dist/assets/cmake-84nbDH0I.js +1 -0
  15. package/dist/assets/cobol-DHLQUbN7.js +1 -0
  16. package/dist/assets/codemirror-DRp8cs-R.js +14 -0
  17. package/dist/assets/coffeescript-De_zI4J0.js +1 -0
  18. package/dist/assets/commonlisp-DgAKBe0r.js +1 -0
  19. package/dist/assets/copy-button-DlOU9KRy.js +1 -0
  20. package/dist/assets/corner-down-left-B7l-mMrb.js +1 -0
  21. package/dist/assets/crystal-Bsdphhtm.js +1 -0
  22. package/dist/assets/css-CnaYoQib.js +1 -0
  23. package/dist/assets/cypher-p9eYesGn.js +1 -0
  24. package/dist/assets/d-DWkQyNnU.js +1 -0
  25. package/dist/assets/diff-ChtP43wD.js +1 -0
  26. package/dist/assets/dist-3tAAASIu.js +1 -0
  27. package/dist/assets/dist-AXYnLL_F.js +9 -0
  28. package/dist/assets/dist-BGyMVrYk.js +11 -0
  29. package/dist/assets/dist-BN1wE2xy.js +1 -0
  30. package/dist/assets/dist-CDAjPDtI.js +1 -0
  31. package/dist/assets/dist-CJBq646Z.js +1 -0
  32. package/dist/assets/dist-CL_zGtiO.js +1 -0
  33. package/dist/assets/dist-CM8yt5f_.js +1 -0
  34. package/dist/assets/dist-CYNLiE2B.js +1 -0
  35. package/dist/assets/dist-CyOGylYO.js +1 -0
  36. package/dist/assets/dist-D-bo6lHS.js +1 -0
  37. package/dist/assets/dist-D7xXmJTH.js +1 -0
  38. package/dist/assets/dist-DGmHtnYo.js +6 -0
  39. package/dist/assets/dist-DOcORAD_.js +1 -0
  40. package/dist/assets/dist-DdeR5kYT.js +2 -0
  41. package/dist/assets/dist-DyYo49jM.js +1 -0
  42. package/dist/assets/dist-FOmLcFeD.js +1 -0
  43. package/dist/assets/dist-FUrprsRT.js +1 -0
  44. package/dist/assets/dist-JuM3aKGD.js +1 -0
  45. package/dist/assets/dist-S0tn--lj.js +1 -0
  46. package/dist/assets/dist-aVl135DR.js +23 -0
  47. package/dist/assets/dist-y7gdVNBt.js +1 -0
  48. package/dist/assets/dockerfile-DJkHQgkl.js +1 -0
  49. package/dist/assets/dtd-DTF72YNO.js +1 -0
  50. package/dist/assets/dylan-S7ucR4pR.js +1 -0
  51. package/dist/assets/ebnf-D4c0_ac3.js +1 -0
  52. package/dist/assets/ecl-BVIeWmwY.js +1 -0
  53. package/dist/assets/eiffel-BEjRio4Q.js +1 -0
  54. package/dist/assets/elm-Cshzl8qu.js +1 -0
  55. package/dist/assets/empty-state-CkET1cGs.js +1 -0
  56. package/dist/assets/erlang-BV0c4Hdn.js +1 -0
  57. package/dist/assets/eye-2RNiMHO-.js +1 -0
  58. package/dist/assets/factor-LKH5gN8L.js +1 -0
  59. package/dist/assets/fcl-ClOhbFR7.js +1 -0
  60. package/dist/assets/field-CYhxBv9B.js +1 -0
  61. package/dist/assets/forth-D6RzAl64.js +1 -0
  62. package/dist/assets/fortran-Bt6PBEDR.js +1 -0
  63. package/dist/assets/gas-BHEdbvp9.js +1 -0
  64. package/dist/assets/gherkin-oBAE_ms0.js +1 -0
  65. package/dist/assets/groovy-CUpZ7dEl.js +1 -0
  66. package/dist/assets/haskell-BRsoo5mP.js +1 -0
  67. package/dist/assets/haxe-DjVOVvNP.js +1 -0
  68. package/dist/assets/host-wizard-screen-Bs7pSgJk.js +1 -0
  69. package/dist/assets/http-CLVgA2GD.js +1 -0
  70. package/dist/assets/idl-BUZw3wgd.js +1 -0
  71. package/dist/assets/index-B5KQ4hDp.css +2 -0
  72. package/dist/assets/index-Cz0KzQeb.js +11 -0
  73. package/dist/assets/javascript-Bu8mWwtz.js +1 -0
  74. package/dist/assets/julia-CQfgDRfP.js +1 -0
  75. package/dist/assets/key-round-Cl7KguqM.js +1 -0
  76. package/dist/assets/layout.store-b9Rb2T9G.js +1 -0
  77. package/dist/assets/livescript-BXxG0Yva.js +1 -0
  78. package/dist/assets/login-screen-Co0lYHk4.js +1 -0
  79. package/dist/assets/lua-DPCEkfD_.js +1 -0
  80. package/dist/assets/manifest-CxKlFp1I.js +1 -0
  81. package/dist/assets/markdown-view-BQbaAkAk.js +29 -0
  82. package/dist/assets/markdown-view-aK-tdIwk.css +1 -0
  83. package/dist/assets/material-icon-RrSZDDw2.js +1 -0
  84. package/dist/assets/mathematica-u8YMmbU0.js +1 -0
  85. package/dist/assets/mbox-BEMVcqjs.js +1 -0
  86. package/dist/assets/middleware-C1xnEbcF.js +1 -0
  87. package/dist/assets/mirc-C9zpzAZU.js +1 -0
  88. package/dist/assets/mllike-B45xgp2S.js +1 -0
  89. package/dist/assets/modelica-CqHI_q-D.js +1 -0
  90. package/dist/assets/mscgen-qgSLujhx.js +1 -0
  91. package/dist/assets/mumps-BSzj6Xyz.js +1 -0
  92. package/dist/assets/nginx-8H7HVH4w.js +1 -0
  93. package/dist/assets/nsis-viPvXFiq.js +1 -0
  94. package/dist/assets/ntriples-CzMBulkp.js +1 -0
  95. package/dist/assets/octave-D2Q8cUp1.js +1 -0
  96. package/dist/assets/oz-BwTct_5T.js +1 -0
  97. package/dist/assets/page-shell-BSEpDNSs.js +1 -0
  98. package/dist/assets/pascal-Dp_KdFgX.js +1 -0
  99. package/dist/assets/password-input-CSjwFwJE.js +1 -0
  100. package/dist/assets/perl-BkSkiI9m.js +1 -0
  101. package/dist/assets/pig-AF4Hwhju.js +1 -0
  102. package/dist/assets/port-links-8g2kBRfp.js +1 -0
  103. package/dist/assets/powershell-D8WpQPaX.js +1 -0
  104. package/dist/assets/projects-screen-C3yWG8mw.js +1 -0
  105. package/dist/assets/properties-C357ku5U.js +1 -0
  106. package/dist/assets/protobuf-D1ij_kNL.js +1 -0
  107. package/dist/assets/pug-Dwd_FmgJ.js +1 -0
  108. package/dist/assets/puppet-BZyAS7I4.js +1 -0
  109. package/dist/assets/python-B_1Jd8HM.js +1 -0
  110. package/dist/assets/q-B9NhS7L_.js +1 -0
  111. package/dist/assets/query-D1fTvh27.js +1 -0
  112. package/dist/assets/r-CxDmU1I4.js +1 -0
  113. package/dist/assets/rpm-gpDK5sbt.js +1 -0
  114. package/dist/assets/ruby-ChfNwlCY.js +1 -0
  115. package/dist/assets/sas-C2OyD2Y6.js +1 -0
  116. package/dist/assets/scheme-D9qYN0V5.js +1 -0
  117. package/dist/assets/settings-screen-BM1Y4v3n.js +1 -0
  118. package/dist/assets/setup-screen--Rk5RNBd.js +1 -0
  119. package/dist/assets/shell-DwuoZtxw.js +1 -0
  120. package/dist/assets/sieve-tLWDfEkZ.js +1 -0
  121. package/dist/assets/simple-mode-DXiLM1-G.js +1 -0
  122. package/dist/assets/smalltalk-BLp5-jwC.js +1 -0
  123. package/dist/assets/solr-B78wSQJQ.js +1 -0
  124. package/dist/assets/sparkles-rMOjCpPO.js +1 -0
  125. package/dist/assets/sparql-Dz-mlCAC.js +1 -0
  126. package/dist/assets/spinner-Dhw2p8cg.js +1 -0
  127. package/dist/assets/spreadsheet-CTIncYxj.js +1 -0
  128. package/dist/assets/sql-DuQMFDvy.js +1 -0
  129. package/dist/assets/square-terminal-DL7ubCPR.js +1 -0
  130. package/dist/assets/stex-DNzd62Q_.js +1 -0
  131. package/dist/assets/stylus-BOVgKnng.js +1 -0
  132. package/dist/assets/swift-DKB6_1j6.js +1 -0
  133. package/dist/assets/tcl-BGfruO1u.js +1 -0
  134. package/dist/assets/textile-C4jVoHG1.js +1 -0
  135. package/dist/assets/tiddlywiki-VlUiK86J.js +1 -0
  136. package/dist/assets/tiki-DTszW0OQ.js +1 -0
  137. package/dist/assets/toml-BPTmHmyx.js +1 -0
  138. package/dist/assets/triangle-alert-CKXjnNZK.js +1 -0
  139. package/dist/assets/troff-C2dAgh7P.js +1 -0
  140. package/dist/assets/ttcn-PPSTk1ow.js +1 -0
  141. package/dist/assets/ttcn-cfg-2b4Gb5sE.js +1 -0
  142. package/dist/assets/turtle-Cx3rYX2g.js +1 -0
  143. package/dist/assets/use-visual-viewport-CHPXxqd5.js +1 -0
  144. package/dist/assets/useQuery-CTJ-5_ol.js +1 -0
  145. package/dist/assets/vb-BthdM_4N.js +1 -0
  146. package/dist/assets/vbscript-D9f6rSsU.js +1 -0
  147. package/dist/assets/velocity-CqftRsjg.js +1 -0
  148. package/dist/assets/verilog-CjI9Y6RI.js +1 -0
  149. package/dist/assets/vhdl-kS471soi.js +1 -0
  150. package/dist/assets/webidl-D5jiJvOU.js +1 -0
  151. package/dist/assets/workspace-screen-FWzP6Hvt.js +8 -0
  152. package/dist/assets/xquery-BKJx4mf9.js +1 -0
  153. package/dist/assets/xterm-BrP-ENHg.css +1 -0
  154. package/dist/assets/xterm-OPnvFLvt.js +22 -0
  155. package/dist/assets/yacas-CXXgtw0p.js +1 -0
  156. package/dist/assets/z80-Co3PbHdE.js +1 -0
  157. package/dist/favicon.svg +1 -0
  158. package/dist/index.html +29 -0
  159. package/dist/ios-viewport.js +9 -0
  160. package/dist/material-icons/3d.svg +1 -0
  161. package/dist/material-icons/abap.svg +1 -0
  162. package/dist/material-icons/abc.svg +1 -0
  163. package/dist/material-icons/actionscript.svg +1 -0
  164. package/dist/material-icons/ada.svg +1 -0
  165. package/dist/material-icons/adobe-illustrator.svg +1 -0
  166. package/dist/material-icons/adobe-illustrator_light.svg +1 -0
  167. package/dist/material-icons/adobe-photoshop.svg +1 -0
  168. package/dist/material-icons/adobe-photoshop_light.svg +1 -0
  169. package/dist/material-icons/adobe-swc.svg +1 -0
  170. package/dist/material-icons/adonis.svg +1 -0
  171. package/dist/material-icons/advpl-include.clone.svg +1 -0
  172. package/dist/material-icons/advpl-ptm.clone.svg +1 -0
  173. package/dist/material-icons/advpl-tlpp.clone.svg +1 -0
  174. package/dist/material-icons/advpl.svg +1 -0
  175. package/dist/material-icons/agent.svg +1 -0
  176. package/dist/material-icons/ahk2.clone.svg +1 -0
  177. package/dist/material-icons/amplify.svg +1 -0
  178. package/dist/material-icons/android.svg +1 -0
  179. package/dist/material-icons/angular-component.clone.svg +1 -0
  180. package/dist/material-icons/angular-directive.clone.svg +1 -0
  181. package/dist/material-icons/angular-guard.clone.svg +1 -0
  182. package/dist/material-icons/angular-interceptor.clone.svg +1 -0
  183. package/dist/material-icons/angular-pipe.clone.svg +1 -0
  184. package/dist/material-icons/angular-resolver.clone.svg +1 -0
  185. package/dist/material-icons/angular-service.clone.svg +1 -0
  186. package/dist/material-icons/angular.svg +1 -0
  187. package/dist/material-icons/antlr.svg +1 -0
  188. package/dist/material-icons/apiblueprint.svg +1 -0
  189. package/dist/material-icons/apollo.svg +1 -0
  190. package/dist/material-icons/applescript.svg +1 -0
  191. package/dist/material-icons/apps-script.svg +1 -0
  192. package/dist/material-icons/appveyor.svg +1 -0
  193. package/dist/material-icons/appwrite.svg +1 -0
  194. package/dist/material-icons/architecture.svg +1 -0
  195. package/dist/material-icons/arduino.svg +1 -0
  196. package/dist/material-icons/asciidoc.svg +1 -0
  197. package/dist/material-icons/assembly.svg +1 -0
  198. package/dist/material-icons/astro-config.svg +1 -0
  199. package/dist/material-icons/astro.svg +1 -0
  200. package/dist/material-icons/astyle.svg +1 -0
  201. package/dist/material-icons/audio.svg +1 -0
  202. package/dist/material-icons/aurelia.svg +1 -0
  203. package/dist/material-icons/authors.svg +1 -0
  204. package/dist/material-icons/auto.svg +1 -0
  205. package/dist/material-icons/auto_light.svg +1 -0
  206. package/dist/material-icons/autohotkey.svg +1 -0
  207. package/dist/material-icons/autoit.svg +1 -0
  208. package/dist/material-icons/azure-pipelines.svg +1 -0
  209. package/dist/material-icons/azure.svg +1 -0
  210. package/dist/material-icons/babel.svg +1 -0
  211. package/dist/material-icons/ballerina.svg +1 -0
  212. package/dist/material-icons/bashly-hook.svg +1 -0
  213. package/dist/material-icons/bashly-settings.clone.svg +1 -0
  214. package/dist/material-icons/bashly-settings_light.clone.svg +1 -0
  215. package/dist/material-icons/bashly-strings.clone.svg +1 -0
  216. package/dist/material-icons/bashly-strings_light.clone.svg +1 -0
  217. package/dist/material-icons/bashly.svg +1 -0
  218. package/dist/material-icons/bazel.svg +1 -0
  219. package/dist/material-icons/bbx.svg +1 -0
  220. package/dist/material-icons/beancount.svg +1 -0
  221. package/dist/material-icons/bench-js.svg +1 -0
  222. package/dist/material-icons/bench-jsx.svg +1 -0
  223. package/dist/material-icons/bench-ts.svg +1 -0
  224. package/dist/material-icons/bibliography.svg +1 -0
  225. package/dist/material-icons/bibtex-style.svg +1 -0
  226. package/dist/material-icons/bicep.svg +1 -0
  227. package/dist/material-icons/biome.svg +1 -0
  228. package/dist/material-icons/bitbucket.svg +1 -0
  229. package/dist/material-icons/bithound.svg +1 -0
  230. package/dist/material-icons/blender.svg +1 -0
  231. package/dist/material-icons/blink.svg +1 -0
  232. package/dist/material-icons/blink_light.svg +1 -0
  233. package/dist/material-icons/blitz.svg +1 -0
  234. package/dist/material-icons/bower.svg +1 -0
  235. package/dist/material-icons/brainfuck.svg +1 -0
  236. package/dist/material-icons/browserlist.svg +1 -0
  237. package/dist/material-icons/browserlist_light.svg +1 -0
  238. package/dist/material-icons/bruno.svg +1 -0
  239. package/dist/material-icons/buck.svg +1 -0
  240. package/dist/material-icons/bucklescript.svg +1 -0
  241. package/dist/material-icons/buildkite.svg +1 -0
  242. package/dist/material-icons/bun.svg +1 -0
  243. package/dist/material-icons/bun_light.svg +1 -0
  244. package/dist/material-icons/c.svg +1 -0
  245. package/dist/material-icons/c3.svg +1 -0
  246. package/dist/material-icons/cabal.svg +1 -0
  247. package/dist/material-icons/caddy.svg +1 -0
  248. package/dist/material-icons/cadence.svg +1 -0
  249. package/dist/material-icons/cairo.svg +1 -0
  250. package/dist/material-icons/cake.svg +1 -0
  251. package/dist/material-icons/capacitor.svg +1 -0
  252. package/dist/material-icons/capnp.svg +1 -0
  253. package/dist/material-icons/cbx.svg +1 -0
  254. package/dist/material-icons/cds.svg +1 -0
  255. package/dist/material-icons/certificate.svg +1 -0
  256. package/dist/material-icons/changelog.svg +1 -0
  257. package/dist/material-icons/chess.svg +1 -0
  258. package/dist/material-icons/chess_light.svg +1 -0
  259. package/dist/material-icons/chromatic.svg +1 -0
  260. package/dist/material-icons/chrome.svg +1 -0
  261. package/dist/material-icons/circleci.svg +1 -0
  262. package/dist/material-icons/circleci_light.svg +1 -0
  263. package/dist/material-icons/citation.svg +1 -0
  264. package/dist/material-icons/clangd.svg +1 -0
  265. package/dist/material-icons/claude.svg +1 -0
  266. package/dist/material-icons/cline.svg +1 -0
  267. package/dist/material-icons/clojure.svg +1 -0
  268. package/dist/material-icons/cloudfoundry.svg +1 -0
  269. package/dist/material-icons/cmake.svg +1 -0
  270. package/dist/material-icons/coala.svg +1 -0
  271. package/dist/material-icons/cobol.svg +1 -0
  272. package/dist/material-icons/coconut.svg +1 -0
  273. package/dist/material-icons/code-climate.svg +1 -0
  274. package/dist/material-icons/code-climate_light.svg +1 -0
  275. package/dist/material-icons/codecov.svg +1 -0
  276. package/dist/material-icons/codeowners.svg +1 -0
  277. package/dist/material-icons/coderabbit-ai.svg +1 -0
  278. package/dist/material-icons/coffee.svg +1 -0
  279. package/dist/material-icons/coldfusion.svg +1 -0
  280. package/dist/material-icons/coloredpetrinets.svg +1 -0
  281. package/dist/material-icons/command.svg +1 -0
  282. package/dist/material-icons/commitizen.svg +1 -0
  283. package/dist/material-icons/commitlint.svg +1 -0
  284. package/dist/material-icons/concourse.svg +1 -0
  285. package/dist/material-icons/conduct.svg +1 -0
  286. package/dist/material-icons/console.svg +1 -0
  287. package/dist/material-icons/container.clone.svg +1 -0
  288. package/dist/material-icons/contentlayer.svg +1 -0
  289. package/dist/material-icons/context.svg +1 -0
  290. package/dist/material-icons/contributing.svg +1 -0
  291. package/dist/material-icons/controller.svg +1 -0
  292. package/dist/material-icons/copilot.svg +1 -0
  293. package/dist/material-icons/copilot_light.svg +1 -0
  294. package/dist/material-icons/cpp.svg +1 -0
  295. package/dist/material-icons/craco.svg +1 -0
  296. package/dist/material-icons/credits.svg +1 -0
  297. package/dist/material-icons/crystal.svg +1 -0
  298. package/dist/material-icons/crystal_light.svg +1 -0
  299. package/dist/material-icons/csharp.svg +1 -0
  300. package/dist/material-icons/css-map.svg +1 -0
  301. package/dist/material-icons/css.svg +1 -0
  302. package/dist/material-icons/cucumber.svg +1 -0
  303. package/dist/material-icons/cuda.svg +1 -0
  304. package/dist/material-icons/cue.svg +1 -0
  305. package/dist/material-icons/cursor.svg +1 -0
  306. package/dist/material-icons/cursor_light.svg +1 -0
  307. package/dist/material-icons/cypress.svg +1 -0
  308. package/dist/material-icons/d.svg +1 -0
  309. package/dist/material-icons/dart.svg +1 -0
  310. package/dist/material-icons/dart_generated.svg +1 -0
  311. package/dist/material-icons/database.svg +1 -0
  312. package/dist/material-icons/deepsource.svg +1 -0
  313. package/dist/material-icons/denizenscript.svg +1 -0
  314. package/dist/material-icons/deno.svg +1 -0
  315. package/dist/material-icons/deno_light.svg +1 -0
  316. package/dist/material-icons/dependabot.svg +1 -0
  317. package/dist/material-icons/dependencies-update.svg +1 -0
  318. package/dist/material-icons/dhall.svg +1 -0
  319. package/dist/material-icons/diff.svg +1 -0
  320. package/dist/material-icons/dinophp.svg +1 -0
  321. package/dist/material-icons/disc.svg +1 -0
  322. package/dist/material-icons/django.svg +1 -0
  323. package/dist/material-icons/dll.svg +1 -0
  324. package/dist/material-icons/docker.svg +1 -0
  325. package/dist/material-icons/doctex-installer.svg +1 -0
  326. package/dist/material-icons/doctex.clone.svg +1 -0
  327. package/dist/material-icons/document.svg +1 -0
  328. package/dist/material-icons/dotjs.svg +1 -0
  329. package/dist/material-icons/drawio.svg +1 -0
  330. package/dist/material-icons/drizzle.svg +1 -0
  331. package/dist/material-icons/drone.svg +1 -0
  332. package/dist/material-icons/drone_light.svg +1 -0
  333. package/dist/material-icons/dtx.clone.svg +1 -0
  334. package/dist/material-icons/duc.svg +1 -0
  335. package/dist/material-icons/dune.svg +1 -0
  336. package/dist/material-icons/edge.svg +1 -0
  337. package/dist/material-icons/editorconfig.svg +1 -0
  338. package/dist/material-icons/ejs.svg +1 -0
  339. package/dist/material-icons/elixir.svg +1 -0
  340. package/dist/material-icons/elm.svg +1 -0
  341. package/dist/material-icons/email.svg +1 -0
  342. package/dist/material-icons/ember.svg +1 -0
  343. package/dist/material-icons/epub.svg +1 -0
  344. package/dist/material-icons/erlang.svg +1 -0
  345. package/dist/material-icons/esbuild.svg +1 -0
  346. package/dist/material-icons/eslint.svg +1 -0
  347. package/dist/material-icons/excalidraw.svg +1 -0
  348. package/dist/material-icons/exe.svg +1 -0
  349. package/dist/material-icons/expo.svg +1 -0
  350. package/dist/material-icons/expo_light.svg +1 -0
  351. package/dist/material-icons/fastlane.svg +1 -0
  352. package/dist/material-icons/favicon.svg +1 -0
  353. package/dist/material-icons/figma.svg +1 -0
  354. package/dist/material-icons/file.svg +1 -0
  355. package/dist/material-icons/firebase.svg +1 -0
  356. package/dist/material-icons/flash.svg +1 -0
  357. package/dist/material-icons/flow.svg +1 -0
  358. package/dist/material-icons/folder-admin-open.svg +1 -0
  359. package/dist/material-icons/folder-admin.svg +1 -0
  360. package/dist/material-icons/folder-android-open.svg +1 -0
  361. package/dist/material-icons/folder-android.svg +1 -0
  362. package/dist/material-icons/folder-angular-open.svg +1 -0
  363. package/dist/material-icons/folder-angular.svg +1 -0
  364. package/dist/material-icons/folder-animation-open.svg +1 -0
  365. package/dist/material-icons/folder-animation.svg +1 -0
  366. package/dist/material-icons/folder-ansible-open.svg +1 -0
  367. package/dist/material-icons/folder-ansible.svg +1 -0
  368. package/dist/material-icons/folder-api-open.svg +1 -0
  369. package/dist/material-icons/folder-api.svg +1 -0
  370. package/dist/material-icons/folder-apollo-open.svg +1 -0
  371. package/dist/material-icons/folder-apollo.svg +1 -0
  372. package/dist/material-icons/folder-app-open.svg +1 -0
  373. package/dist/material-icons/folder-app.svg +1 -0
  374. package/dist/material-icons/folder-appwrite-open.svg +1 -0
  375. package/dist/material-icons/folder-appwrite.svg +1 -0
  376. package/dist/material-icons/folder-archive-open.svg +1 -0
  377. package/dist/material-icons/folder-archive.svg +1 -0
  378. package/dist/material-icons/folder-assembly-open.svg +1 -0
  379. package/dist/material-icons/folder-assembly.svg +1 -0
  380. package/dist/material-icons/folder-astro-open.svg +1 -0
  381. package/dist/material-icons/folder-astro.svg +1 -0
  382. package/dist/material-icons/folder-atom-open.svg +1 -0
  383. package/dist/material-icons/folder-atom.svg +1 -0
  384. package/dist/material-icons/folder-attachment-open.svg +1 -0
  385. package/dist/material-icons/folder-attachment.svg +1 -0
  386. package/dist/material-icons/folder-audio-open.svg +1 -0
  387. package/dist/material-icons/folder-audio.svg +1 -0
  388. package/dist/material-icons/folder-aurelia-open.svg +1 -0
  389. package/dist/material-icons/folder-aurelia.svg +1 -0
  390. package/dist/material-icons/folder-aws-open.svg +1 -0
  391. package/dist/material-icons/folder-aws.svg +1 -0
  392. package/dist/material-icons/folder-azure-pipelines-open.svg +1 -0
  393. package/dist/material-icons/folder-azure-pipelines.svg +1 -0
  394. package/dist/material-icons/folder-backup-open.svg +1 -0
  395. package/dist/material-icons/folder-backup.svg +1 -0
  396. package/dist/material-icons/folder-base-open.svg +1 -0
  397. package/dist/material-icons/folder-base.svg +1 -0
  398. package/dist/material-icons/folder-batch-open.svg +1 -0
  399. package/dist/material-icons/folder-batch.svg +1 -0
  400. package/dist/material-icons/folder-benchmark-open.svg +1 -0
  401. package/dist/material-icons/folder-benchmark.svg +1 -0
  402. package/dist/material-icons/folder-bibliography-open.svg +1 -0
  403. package/dist/material-icons/folder-bibliography.svg +1 -0
  404. package/dist/material-icons/folder-bicep-open.svg +1 -0
  405. package/dist/material-icons/folder-bicep.svg +1 -0
  406. package/dist/material-icons/folder-blender-open.svg +1 -0
  407. package/dist/material-icons/folder-blender.svg +1 -0
  408. package/dist/material-icons/folder-bloc-open.svg +1 -0
  409. package/dist/material-icons/folder-bloc.svg +1 -0
  410. package/dist/material-icons/folder-bower-open.svg +1 -0
  411. package/dist/material-icons/folder-bower.svg +1 -0
  412. package/dist/material-icons/folder-buildkite-open.svg +1 -0
  413. package/dist/material-icons/folder-buildkite.svg +1 -0
  414. package/dist/material-icons/folder-cart-open.svg +1 -0
  415. package/dist/material-icons/folder-cart.svg +1 -0
  416. package/dist/material-icons/folder-changesets-open.svg +1 -0
  417. package/dist/material-icons/folder-changesets.svg +1 -0
  418. package/dist/material-icons/folder-ci-open.svg +1 -0
  419. package/dist/material-icons/folder-ci.svg +1 -0
  420. package/dist/material-icons/folder-circleci-open.svg +1 -0
  421. package/dist/material-icons/folder-circleci.svg +1 -0
  422. package/dist/material-icons/folder-class-open.svg +1 -0
  423. package/dist/material-icons/folder-class.svg +1 -0
  424. package/dist/material-icons/folder-claude-open.svg +1 -0
  425. package/dist/material-icons/folder-claude.svg +1 -0
  426. package/dist/material-icons/folder-client-open.svg +1 -0
  427. package/dist/material-icons/folder-client.svg +1 -0
  428. package/dist/material-icons/folder-cline-open.svg +1 -0
  429. package/dist/material-icons/folder-cline.svg +1 -0
  430. package/dist/material-icons/folder-cloud-functions-open.svg +1 -0
  431. package/dist/material-icons/folder-cloud-functions.svg +1 -0
  432. package/dist/material-icons/folder-cloudflare-open.svg +1 -0
  433. package/dist/material-icons/folder-cloudflare.svg +1 -0
  434. package/dist/material-icons/folder-cluster-open.svg +1 -0
  435. package/dist/material-icons/folder-cluster.svg +1 -0
  436. package/dist/material-icons/folder-cobol-open.svg +1 -0
  437. package/dist/material-icons/folder-cobol.svg +1 -0
  438. package/dist/material-icons/folder-command-open.svg +1 -0
  439. package/dist/material-icons/folder-command.svg +1 -0
  440. package/dist/material-icons/folder-components-open.svg +1 -0
  441. package/dist/material-icons/folder-components.svg +1 -0
  442. package/dist/material-icons/folder-config-open.svg +1 -0
  443. package/dist/material-icons/folder-config.svg +1 -0
  444. package/dist/material-icons/folder-connection-open.svg +1 -0
  445. package/dist/material-icons/folder-connection.svg +1 -0
  446. package/dist/material-icons/folder-console-open.svg +1 -0
  447. package/dist/material-icons/folder-console.svg +1 -0
  448. package/dist/material-icons/folder-constant-open.svg +1 -0
  449. package/dist/material-icons/folder-constant.svg +1 -0
  450. package/dist/material-icons/folder-container-open.svg +1 -0
  451. package/dist/material-icons/folder-container.svg +1 -0
  452. package/dist/material-icons/folder-content-open.svg +1 -0
  453. package/dist/material-icons/folder-content.svg +1 -0
  454. package/dist/material-icons/folder-context-open.svg +1 -0
  455. package/dist/material-icons/folder-context.svg +1 -0
  456. package/dist/material-icons/folder-contract-open.svg +1 -0
  457. package/dist/material-icons/folder-contract.svg +1 -0
  458. package/dist/material-icons/folder-controller-open.svg +1 -0
  459. package/dist/material-icons/folder-controller.svg +1 -0
  460. package/dist/material-icons/folder-core-open.svg +1 -0
  461. package/dist/material-icons/folder-core.svg +1 -0
  462. package/dist/material-icons/folder-coverage-open.svg +1 -0
  463. package/dist/material-icons/folder-coverage.svg +1 -0
  464. package/dist/material-icons/folder-css-open.svg +1 -0
  465. package/dist/material-icons/folder-css.svg +1 -0
  466. package/dist/material-icons/folder-cue-open.svg +1 -0
  467. package/dist/material-icons/folder-cue.svg +1 -0
  468. package/dist/material-icons/folder-cursor-open.svg +1 -0
  469. package/dist/material-icons/folder-cursor-open_light.svg +1 -0
  470. package/dist/material-icons/folder-cursor.svg +1 -0
  471. package/dist/material-icons/folder-cursor_light.svg +1 -0
  472. package/dist/material-icons/folder-custom-open.svg +1 -0
  473. package/dist/material-icons/folder-custom.svg +1 -0
  474. package/dist/material-icons/folder-cypress-open.svg +1 -0
  475. package/dist/material-icons/folder-cypress.svg +1 -0
  476. package/dist/material-icons/folder-dal-open.svg +1 -0
  477. package/dist/material-icons/folder-dal.svg +1 -0
  478. package/dist/material-icons/folder-dart-open.svg +1 -0
  479. package/dist/material-icons/folder-dart.svg +1 -0
  480. package/dist/material-icons/folder-database-open.svg +1 -0
  481. package/dist/material-icons/folder-database.svg +1 -0
  482. package/dist/material-icons/folder-debug-open.svg +1 -0
  483. package/dist/material-icons/folder-debug.svg +1 -0
  484. package/dist/material-icons/folder-decorators-open.svg +1 -0
  485. package/dist/material-icons/folder-decorators.svg +1 -0
  486. package/dist/material-icons/folder-delta-open.svg +1 -0
  487. package/dist/material-icons/folder-delta.svg +1 -0
  488. package/dist/material-icons/folder-deprecated-open.clone.svg +1 -0
  489. package/dist/material-icons/folder-deprecated.clone.svg +1 -0
  490. package/dist/material-icons/folder-desktop-open.svg +1 -0
  491. package/dist/material-icons/folder-desktop.svg +1 -0
  492. package/dist/material-icons/folder-development-open.clone.svg +1 -0
  493. package/dist/material-icons/folder-development.clone.svg +1 -0
  494. package/dist/material-icons/folder-directive-open.svg +1 -0
  495. package/dist/material-icons/folder-directive.svg +1 -0
  496. package/dist/material-icons/folder-dist-open.svg +1 -0
  497. package/dist/material-icons/folder-dist.svg +1 -0
  498. package/dist/material-icons/folder-docker-open.svg +1 -0
  499. package/dist/material-icons/folder-docker.svg +1 -0
  500. package/dist/material-icons/folder-docs-open.svg +1 -0
  501. package/dist/material-icons/folder-docs.svg +1 -0
  502. package/dist/material-icons/folder-download-open.svg +1 -0
  503. package/dist/material-icons/folder-download.svg +1 -0
  504. package/dist/material-icons/folder-drizzle-open.svg +1 -0
  505. package/dist/material-icons/folder-drizzle.svg +1 -0
  506. package/dist/material-icons/folder-dump-open.svg +1 -0
  507. package/dist/material-icons/folder-dump.svg +1 -0
  508. package/dist/material-icons/folder-eas-open.clone.svg +1 -0
  509. package/dist/material-icons/folder-eas.clone.svg +1 -0
  510. package/dist/material-icons/folder-element-open.svg +1 -0
  511. package/dist/material-icons/folder-element.svg +1 -0
  512. package/dist/material-icons/folder-enum-open.svg +1 -0
  513. package/dist/material-icons/folder-enum.svg +1 -0
  514. package/dist/material-icons/folder-environment-open.svg +1 -0
  515. package/dist/material-icons/folder-environment.svg +1 -0
  516. package/dist/material-icons/folder-error-open.svg +1 -0
  517. package/dist/material-icons/folder-error.svg +1 -0
  518. package/dist/material-icons/folder-eslint-open.svg +1 -0
  519. package/dist/material-icons/folder-eslint.svg +1 -0
  520. package/dist/material-icons/folder-event-open.svg +1 -0
  521. package/dist/material-icons/folder-event.svg +1 -0
  522. package/dist/material-icons/folder-examples-open.svg +1 -0
  523. package/dist/material-icons/folder-examples.svg +1 -0
  524. package/dist/material-icons/folder-expo-open.svg +1 -0
  525. package/dist/material-icons/folder-expo.svg +1 -0
  526. package/dist/material-icons/folder-export-open.svg +1 -0
  527. package/dist/material-icons/folder-export.svg +1 -0
  528. package/dist/material-icons/folder-fastlane-open.svg +1 -0
  529. package/dist/material-icons/folder-fastlane.svg +1 -0
  530. package/dist/material-icons/folder-favicon-open.svg +1 -0
  531. package/dist/material-icons/folder-favicon.svg +1 -0
  532. package/dist/material-icons/folder-features-open.svg +1 -0
  533. package/dist/material-icons/folder-features.svg +1 -0
  534. package/dist/material-icons/folder-filter-open.svg +1 -0
  535. package/dist/material-icons/folder-filter.svg +1 -0
  536. package/dist/material-icons/folder-firebase-open.svg +1 -0
  537. package/dist/material-icons/folder-firebase.svg +1 -0
  538. package/dist/material-icons/folder-firestore-open.svg +1 -0
  539. package/dist/material-icons/folder-firestore.svg +1 -0
  540. package/dist/material-icons/folder-flow-open.svg +1 -0
  541. package/dist/material-icons/folder-flow.svg +1 -0
  542. package/dist/material-icons/folder-flutter-open.svg +1 -0
  543. package/dist/material-icons/folder-flutter.svg +1 -0
  544. package/dist/material-icons/folder-font-open.svg +1 -0
  545. package/dist/material-icons/folder-font.svg +1 -0
  546. package/dist/material-icons/folder-forgejo-open.svg +1 -0
  547. package/dist/material-icons/folder-forgejo.svg +1 -0
  548. package/dist/material-icons/folder-form-open.svg +1 -0
  549. package/dist/material-icons/folder-form.svg +1 -0
  550. package/dist/material-icons/folder-functions-open.svg +1 -0
  551. package/dist/material-icons/folder-functions.svg +1 -0
  552. package/dist/material-icons/folder-gamemaker-open.svg +1 -0
  553. package/dist/material-icons/folder-gamemaker.svg +1 -0
  554. package/dist/material-icons/folder-gemini-ai-open.svg +1 -0
  555. package/dist/material-icons/folder-gemini-ai.svg +1 -0
  556. package/dist/material-icons/folder-generator-open.svg +1 -0
  557. package/dist/material-icons/folder-generator.svg +1 -0
  558. package/dist/material-icons/folder-gh-workflows-open.svg +1 -0
  559. package/dist/material-icons/folder-gh-workflows.svg +1 -0
  560. package/dist/material-icons/folder-git-open.svg +1 -0
  561. package/dist/material-icons/folder-git.svg +1 -0
  562. package/dist/material-icons/folder-gitea-open.svg +1 -0
  563. package/dist/material-icons/folder-gitea-workflows-open.clone.svg +1 -0
  564. package/dist/material-icons/folder-gitea-workflows.clone.svg +1 -0
  565. package/dist/material-icons/folder-gitea.svg +1 -0
  566. package/dist/material-icons/folder-github-open.svg +1 -0
  567. package/dist/material-icons/folder-github.svg +1 -0
  568. package/dist/material-icons/folder-gitlab-open.svg +1 -0
  569. package/dist/material-icons/folder-gitlab.svg +1 -0
  570. package/dist/material-icons/folder-global-open.svg +1 -0
  571. package/dist/material-icons/folder-global.svg +1 -0
  572. package/dist/material-icons/folder-go-open.svg +1 -0
  573. package/dist/material-icons/folder-go.svg +1 -0
  574. package/dist/material-icons/folder-godot-open.svg +1 -0
  575. package/dist/material-icons/folder-godot.svg +1 -0
  576. package/dist/material-icons/folder-gradle-open.svg +1 -0
  577. package/dist/material-icons/folder-gradle.svg +1 -0
  578. package/dist/material-icons/folder-graphql-open.svg +1 -0
  579. package/dist/material-icons/folder-graphql.svg +1 -0
  580. package/dist/material-icons/folder-guard-open.svg +1 -0
  581. package/dist/material-icons/folder-guard.svg +1 -0
  582. package/dist/material-icons/folder-gulp-open.svg +1 -0
  583. package/dist/material-icons/folder-gulp.svg +1 -0
  584. package/dist/material-icons/folder-helm-open.svg +1 -0
  585. package/dist/material-icons/folder-helm.svg +1 -0
  586. package/dist/material-icons/folder-helper-open.svg +1 -0
  587. package/dist/material-icons/folder-helper.svg +1 -0
  588. package/dist/material-icons/folder-home-open.svg +1 -0
  589. package/dist/material-icons/folder-home.svg +1 -0
  590. package/dist/material-icons/folder-hook-open.svg +1 -0
  591. package/dist/material-icons/folder-hook.svg +1 -0
  592. package/dist/material-icons/folder-husky-open.svg +1 -0
  593. package/dist/material-icons/folder-husky.svg +1 -0
  594. package/dist/material-icons/folder-i18n-open.svg +1 -0
  595. package/dist/material-icons/folder-i18n.svg +1 -0
  596. package/dist/material-icons/folder-images-open.svg +1 -0
  597. package/dist/material-icons/folder-images.svg +1 -0
  598. package/dist/material-icons/folder-import-open.svg +1 -0
  599. package/dist/material-icons/folder-import.svg +1 -0
  600. package/dist/material-icons/folder-include-open.svg +1 -0
  601. package/dist/material-icons/folder-include.svg +1 -0
  602. package/dist/material-icons/folder-input-open.svg +1 -0
  603. package/dist/material-icons/folder-input.svg +1 -0
  604. package/dist/material-icons/folder-instructions-open.clone.svg +1 -0
  605. package/dist/material-icons/folder-instructions.clone.svg +1 -0
  606. package/dist/material-icons/folder-intellij-open.svg +1 -0
  607. package/dist/material-icons/folder-intellij-open_light.svg +1 -0
  608. package/dist/material-icons/folder-intellij.svg +1 -0
  609. package/dist/material-icons/folder-intellij_light.svg +1 -0
  610. package/dist/material-icons/folder-interceptor-open.svg +1 -0
  611. package/dist/material-icons/folder-interceptor.svg +1 -0
  612. package/dist/material-icons/folder-interface-open.svg +1 -0
  613. package/dist/material-icons/folder-interface.svg +1 -0
  614. package/dist/material-icons/folder-ios-open.svg +1 -0
  615. package/dist/material-icons/folder-ios.svg +1 -0
  616. package/dist/material-icons/folder-java-open.svg +1 -0
  617. package/dist/material-icons/folder-java.svg +1 -0
  618. package/dist/material-icons/folder-javascript-open.svg +1 -0
  619. package/dist/material-icons/folder-javascript.svg +1 -0
  620. package/dist/material-icons/folder-jinja-open.svg +1 -0
  621. package/dist/material-icons/folder-jinja-open_light.svg +1 -0
  622. package/dist/material-icons/folder-jinja.svg +1 -0
  623. package/dist/material-icons/folder-jinja_light.svg +1 -0
  624. package/dist/material-icons/folder-job-open.svg +1 -0
  625. package/dist/material-icons/folder-job.svg +1 -0
  626. package/dist/material-icons/folder-json-open.svg +1 -0
  627. package/dist/material-icons/folder-json.svg +1 -0
  628. package/dist/material-icons/folder-jupyter-open.svg +1 -0
  629. package/dist/material-icons/folder-jupyter.svg +1 -0
  630. package/dist/material-icons/folder-keys-open.svg +1 -0
  631. package/dist/material-icons/folder-keys.svg +1 -0
  632. package/dist/material-icons/folder-kotlin-open.svg +1 -0
  633. package/dist/material-icons/folder-kotlin.svg +1 -0
  634. package/dist/material-icons/folder-kubernetes-open.svg +1 -0
  635. package/dist/material-icons/folder-kubernetes.svg +1 -0
  636. package/dist/material-icons/folder-kusto-open.svg +1 -0
  637. package/dist/material-icons/folder-kusto.svg +1 -0
  638. package/dist/material-icons/folder-layout-open.svg +1 -0
  639. package/dist/material-icons/folder-layout.svg +1 -0
  640. package/dist/material-icons/folder-lefthook-open.svg +1 -0
  641. package/dist/material-icons/folder-lefthook.svg +1 -0
  642. package/dist/material-icons/folder-less-open.svg +1 -0
  643. package/dist/material-icons/folder-less.svg +1 -0
  644. package/dist/material-icons/folder-lib-open.svg +1 -0
  645. package/dist/material-icons/folder-lib.svg +1 -0
  646. package/dist/material-icons/folder-license-open.svg +1 -0
  647. package/dist/material-icons/folder-license.svg +1 -0
  648. package/dist/material-icons/folder-link-open.svg +1 -0
  649. package/dist/material-icons/folder-link.svg +1 -0
  650. package/dist/material-icons/folder-linux-open.svg +1 -0
  651. package/dist/material-icons/folder-linux.svg +1 -0
  652. package/dist/material-icons/folder-liquibase-open.svg +1 -0
  653. package/dist/material-icons/folder-liquibase.svg +1 -0
  654. package/dist/material-icons/folder-log-open.svg +1 -0
  655. package/dist/material-icons/folder-log.svg +1 -0
  656. package/dist/material-icons/folder-lottie-open.svg +1 -0
  657. package/dist/material-icons/folder-lottie.svg +1 -0
  658. package/dist/material-icons/folder-lua-open.svg +1 -0
  659. package/dist/material-icons/folder-lua.svg +1 -0
  660. package/dist/material-icons/folder-luau-open.svg +1 -0
  661. package/dist/material-icons/folder-luau.svg +1 -0
  662. package/dist/material-icons/folder-macos-open.svg +1 -0
  663. package/dist/material-icons/folder-macos.svg +1 -0
  664. package/dist/material-icons/folder-mail-open.svg +1 -0
  665. package/dist/material-icons/folder-mail.svg +1 -0
  666. package/dist/material-icons/folder-mappings-open.svg +1 -0
  667. package/dist/material-icons/folder-mappings.svg +1 -0
  668. package/dist/material-icons/folder-markdown-open.svg +1 -0
  669. package/dist/material-icons/folder-markdown.svg +1 -0
  670. package/dist/material-icons/folder-mercurial-open.svg +1 -0
  671. package/dist/material-icons/folder-mercurial.svg +1 -0
  672. package/dist/material-icons/folder-messages-open.svg +1 -0
  673. package/dist/material-icons/folder-messages.svg +1 -0
  674. package/dist/material-icons/folder-meta-open.svg +1 -0
  675. package/dist/material-icons/folder-meta.svg +1 -0
  676. package/dist/material-icons/folder-metro-open.svg +1 -0
  677. package/dist/material-icons/folder-metro.svg +1 -0
  678. package/dist/material-icons/folder-middleware-open.svg +1 -0
  679. package/dist/material-icons/folder-middleware.svg +1 -0
  680. package/dist/material-icons/folder-migrations-open.svg +1 -0
  681. package/dist/material-icons/folder-migrations.svg +1 -0
  682. package/dist/material-icons/folder-mjml-open.svg +1 -0
  683. package/dist/material-icons/folder-mjml.svg +1 -0
  684. package/dist/material-icons/folder-mobile-open.svg +1 -0
  685. package/dist/material-icons/folder-mobile.svg +1 -0
  686. package/dist/material-icons/folder-mock-open.svg +1 -0
  687. package/dist/material-icons/folder-mock.svg +1 -0
  688. package/dist/material-icons/folder-mojo-open.svg +1 -0
  689. package/dist/material-icons/folder-mojo.svg +1 -0
  690. package/dist/material-icons/folder-molecule-open.svg +1 -0
  691. package/dist/material-icons/folder-molecule.svg +1 -0
  692. package/dist/material-icons/folder-moon-open.svg +1 -0
  693. package/dist/material-icons/folder-moon.svg +1 -0
  694. package/dist/material-icons/folder-netlify-open.svg +1 -0
  695. package/dist/material-icons/folder-netlify.svg +1 -0
  696. package/dist/material-icons/folder-next-open.svg +1 -0
  697. package/dist/material-icons/folder-next.svg +1 -0
  698. package/dist/material-icons/folder-nginx-open.svg +1 -0
  699. package/dist/material-icons/folder-nginx.svg +1 -0
  700. package/dist/material-icons/folder-ngrx-actions-open.clone.svg +1 -0
  701. package/dist/material-icons/folder-ngrx-actions.clone.svg +1 -0
  702. package/dist/material-icons/folder-ngrx-effects-open.clone.svg +1 -0
  703. package/dist/material-icons/folder-ngrx-effects.clone.svg +1 -0
  704. package/dist/material-icons/folder-ngrx-entities-open.clone.svg +1 -0
  705. package/dist/material-icons/folder-ngrx-entities.clone.svg +1 -0
  706. package/dist/material-icons/folder-ngrx-reducer-open.clone.svg +1 -0
  707. package/dist/material-icons/folder-ngrx-reducer.clone.svg +1 -0
  708. package/dist/material-icons/folder-ngrx-selectors-open.clone.svg +1 -0
  709. package/dist/material-icons/folder-ngrx-selectors.clone.svg +1 -0
  710. package/dist/material-icons/folder-ngrx-state-open.clone.svg +1 -0
  711. package/dist/material-icons/folder-ngrx-state.clone.svg +1 -0
  712. package/dist/material-icons/folder-ngrx-store-open.svg +1 -0
  713. package/dist/material-icons/folder-ngrx-store.svg +1 -0
  714. package/dist/material-icons/folder-node-open.svg +1 -0
  715. package/dist/material-icons/folder-node.svg +1 -0
  716. package/dist/material-icons/folder-nuxt-open.svg +1 -0
  717. package/dist/material-icons/folder-nuxt.svg +1 -0
  718. package/dist/material-icons/folder-obsidian-open.svg +1 -0
  719. package/dist/material-icons/folder-obsidian.svg +1 -0
  720. package/dist/material-icons/folder-open.svg +1 -0
  721. package/dist/material-icons/folder-opencode-open.svg +1 -0
  722. package/dist/material-icons/folder-opencode.svg +1 -0
  723. package/dist/material-icons/folder-organism-open.svg +1 -0
  724. package/dist/material-icons/folder-organism.svg +1 -0
  725. package/dist/material-icons/folder-other-open.svg +1 -0
  726. package/dist/material-icons/folder-other.svg +1 -0
  727. package/dist/material-icons/folder-packages-open.svg +1 -0
  728. package/dist/material-icons/folder-packages.svg +1 -0
  729. package/dist/material-icons/folder-pdf-open.svg +1 -0
  730. package/dist/material-icons/folder-pdf.svg +1 -0
  731. package/dist/material-icons/folder-pdm-open.svg +1 -0
  732. package/dist/material-icons/folder-pdm.svg +1 -0
  733. package/dist/material-icons/folder-php-open.svg +1 -0
  734. package/dist/material-icons/folder-php.svg +1 -0
  735. package/dist/material-icons/folder-phpmailer-open.svg +1 -0
  736. package/dist/material-icons/folder-phpmailer.svg +1 -0
  737. package/dist/material-icons/folder-pipe-open.svg +1 -0
  738. package/dist/material-icons/folder-pipe.svg +1 -0
  739. package/dist/material-icons/folder-plastic-open.svg +1 -0
  740. package/dist/material-icons/folder-plastic.svg +1 -0
  741. package/dist/material-icons/folder-plugin-open.svg +1 -0
  742. package/dist/material-icons/folder-plugin.svg +1 -0
  743. package/dist/material-icons/folder-policy-open.svg +1 -0
  744. package/dist/material-icons/folder-policy.svg +1 -0
  745. package/dist/material-icons/folder-postman-open.svg +1 -0
  746. package/dist/material-icons/folder-postman.svg +1 -0
  747. package/dist/material-icons/folder-powershell-open.svg +1 -0
  748. package/dist/material-icons/folder-powershell.svg +1 -0
  749. package/dist/material-icons/folder-prisma-open.svg +1 -0
  750. package/dist/material-icons/folder-prisma.svg +1 -0
  751. package/dist/material-icons/folder-private-open.svg +1 -0
  752. package/dist/material-icons/folder-private.svg +1 -0
  753. package/dist/material-icons/folder-project-open.svg +1 -0
  754. package/dist/material-icons/folder-project.svg +1 -0
  755. package/dist/material-icons/folder-prompts-open.svg +1 -0
  756. package/dist/material-icons/folder-prompts.svg +1 -0
  757. package/dist/material-icons/folder-proto-open.svg +1 -0
  758. package/dist/material-icons/folder-proto.svg +1 -0
  759. package/dist/material-icons/folder-public-open.svg +1 -0
  760. package/dist/material-icons/folder-public.svg +1 -0
  761. package/dist/material-icons/folder-python-open.svg +1 -0
  762. package/dist/material-icons/folder-python.svg +1 -0
  763. package/dist/material-icons/folder-pytorch-open.svg +1 -0
  764. package/dist/material-icons/folder-pytorch.svg +1 -0
  765. package/dist/material-icons/folder-quasar-open.svg +1 -0
  766. package/dist/material-icons/folder-quasar.svg +1 -0
  767. package/dist/material-icons/folder-queue-open.svg +1 -0
  768. package/dist/material-icons/folder-queue.svg +1 -0
  769. package/dist/material-icons/folder-r-open.svg +1 -0
  770. package/dist/material-icons/folder-r.svg +1 -0
  771. package/dist/material-icons/folder-react-components-open.svg +1 -0
  772. package/dist/material-icons/folder-react-components.svg +1 -0
  773. package/dist/material-icons/folder-redis-open.clone.svg +1 -0
  774. package/dist/material-icons/folder-redis.clone.svg +1 -0
  775. package/dist/material-icons/folder-redux-actions-open.clone.svg +1 -0
  776. package/dist/material-icons/folder-redux-actions.clone.svg +1 -0
  777. package/dist/material-icons/folder-redux-reducer-open.svg +1 -0
  778. package/dist/material-icons/folder-redux-reducer.svg +1 -0
  779. package/dist/material-icons/folder-redux-selector-open.clone.svg +1 -0
  780. package/dist/material-icons/folder-redux-selector.clone.svg +1 -0
  781. package/dist/material-icons/folder-redux-store-open.clone.svg +1 -0
  782. package/dist/material-icons/folder-redux-store.clone.svg +1 -0
  783. package/dist/material-icons/folder-redux-toolkit-open.clone.svg +1 -0
  784. package/dist/material-icons/folder-redux-toolkit.clone.svg +1 -0
  785. package/dist/material-icons/folder-repository-open.svg +1 -0
  786. package/dist/material-icons/folder-repository.svg +1 -0
  787. package/dist/material-icons/folder-resolver-open.svg +1 -0
  788. package/dist/material-icons/folder-resolver.svg +1 -0
  789. package/dist/material-icons/folder-resource-open.svg +1 -0
  790. package/dist/material-icons/folder-resource.svg +1 -0
  791. package/dist/material-icons/folder-review-open.svg +1 -0
  792. package/dist/material-icons/folder-review.svg +1 -0
  793. package/dist/material-icons/folder-robot-open.svg +1 -0
  794. package/dist/material-icons/folder-robot.svg +1 -0
  795. package/dist/material-icons/folder-root-open.svg +1 -0
  796. package/dist/material-icons/folder-root.svg +1 -0
  797. package/dist/material-icons/folder-routes-open.svg +1 -0
  798. package/dist/material-icons/folder-routes.svg +1 -0
  799. package/dist/material-icons/folder-rules-open.svg +1 -0
  800. package/dist/material-icons/folder-rules.svg +1 -0
  801. package/dist/material-icons/folder-rust-open.svg +1 -0
  802. package/dist/material-icons/folder-rust.svg +1 -0
  803. package/dist/material-icons/folder-salt-open.svg +1 -0
  804. package/dist/material-icons/folder-salt.svg +1 -0
  805. package/dist/material-icons/folder-sandbox-open.svg +1 -0
  806. package/dist/material-icons/folder-sandbox.svg +1 -0
  807. package/dist/material-icons/folder-sass-open.svg +1 -0
  808. package/dist/material-icons/folder-sass.svg +1 -0
  809. package/dist/material-icons/folder-scala-open.svg +1 -0
  810. package/dist/material-icons/folder-scala.svg +1 -0
  811. package/dist/material-icons/folder-scons-open.svg +1 -0
  812. package/dist/material-icons/folder-scons.svg +1 -0
  813. package/dist/material-icons/folder-scrap-open.clone.svg +1 -0
  814. package/dist/material-icons/folder-scrap.clone.svg +1 -0
  815. package/dist/material-icons/folder-scripts-open.svg +1 -0
  816. package/dist/material-icons/folder-scripts.svg +1 -0
  817. package/dist/material-icons/folder-secure-open.svg +1 -0
  818. package/dist/material-icons/folder-secure.svg +1 -0
  819. package/dist/material-icons/folder-seeders-open.svg +1 -0
  820. package/dist/material-icons/folder-seeders.svg +1 -0
  821. package/dist/material-icons/folder-server-open.svg +1 -0
  822. package/dist/material-icons/folder-server.svg +1 -0
  823. package/dist/material-icons/folder-serverless-open.svg +1 -0
  824. package/dist/material-icons/folder-serverless.svg +1 -0
  825. package/dist/material-icons/folder-shader-open.svg +1 -0
  826. package/dist/material-icons/folder-shader.svg +1 -0
  827. package/dist/material-icons/folder-shared-open.svg +1 -0
  828. package/dist/material-icons/folder-shared.svg +1 -0
  829. package/dist/material-icons/folder-simulations-open.svg +1 -0
  830. package/dist/material-icons/folder-simulations.svg +1 -0
  831. package/dist/material-icons/folder-skills-open.svg +1 -0
  832. package/dist/material-icons/folder-skills.svg +1 -0
  833. package/dist/material-icons/folder-snapcraft-open.svg +1 -0
  834. package/dist/material-icons/folder-snapcraft.svg +1 -0
  835. package/dist/material-icons/folder-snippet-open.svg +1 -0
  836. package/dist/material-icons/folder-snippet.svg +1 -0
  837. package/dist/material-icons/folder-src-open.svg +1 -0
  838. package/dist/material-icons/folder-src-tauri-open.svg +1 -0
  839. package/dist/material-icons/folder-src-tauri.svg +1 -0
  840. package/dist/material-icons/folder-src.svg +1 -0
  841. package/dist/material-icons/folder-stack-open.svg +1 -0
  842. package/dist/material-icons/folder-stack.svg +1 -0
  843. package/dist/material-icons/folder-stencil-open.svg +1 -0
  844. package/dist/material-icons/folder-stencil.svg +1 -0
  845. package/dist/material-icons/folder-store-open.svg +1 -0
  846. package/dist/material-icons/folder-store.svg +1 -0
  847. package/dist/material-icons/folder-storybook-open.svg +1 -0
  848. package/dist/material-icons/folder-storybook.svg +1 -0
  849. package/dist/material-icons/folder-stylus-open.svg +1 -0
  850. package/dist/material-icons/folder-stylus.svg +1 -0
  851. package/dist/material-icons/folder-sublime-open.svg +1 -0
  852. package/dist/material-icons/folder-sublime.svg +1 -0
  853. package/dist/material-icons/folder-supabase-open.svg +1 -0
  854. package/dist/material-icons/folder-supabase.svg +1 -0
  855. package/dist/material-icons/folder-svelte-open.svg +1 -0
  856. package/dist/material-icons/folder-svelte.svg +1 -0
  857. package/dist/material-icons/folder-svg-open.svg +1 -0
  858. package/dist/material-icons/folder-svg.svg +1 -0
  859. package/dist/material-icons/folder-syntax-open.svg +1 -0
  860. package/dist/material-icons/folder-syntax.svg +1 -0
  861. package/dist/material-icons/folder-target-open.svg +1 -0
  862. package/dist/material-icons/folder-target.svg +1 -0
  863. package/dist/material-icons/folder-taskfile-open.svg +1 -0
  864. package/dist/material-icons/folder-taskfile.svg +1 -0
  865. package/dist/material-icons/folder-tasks-open.svg +1 -0
  866. package/dist/material-icons/folder-tasks.svg +1 -0
  867. package/dist/material-icons/folder-television-open.svg +1 -0
  868. package/dist/material-icons/folder-television.svg +1 -0
  869. package/dist/material-icons/folder-temp-open.svg +1 -0
  870. package/dist/material-icons/folder-temp.svg +1 -0
  871. package/dist/material-icons/folder-template-open.svg +1 -0
  872. package/dist/material-icons/folder-template.svg +1 -0
  873. package/dist/material-icons/folder-terraform-open.svg +1 -0
  874. package/dist/material-icons/folder-terraform.svg +1 -0
  875. package/dist/material-icons/folder-test-open.svg +1 -0
  876. package/dist/material-icons/folder-test.svg +1 -0
  877. package/dist/material-icons/folder-theme-open.svg +1 -0
  878. package/dist/material-icons/folder-theme.svg +1 -0
  879. package/dist/material-icons/folder-toc-open.svg +1 -0
  880. package/dist/material-icons/folder-toc.svg +1 -0
  881. package/dist/material-icons/folder-tools-open.svg +1 -0
  882. package/dist/material-icons/folder-tools.svg +1 -0
  883. package/dist/material-icons/folder-trash-open.svg +1 -0
  884. package/dist/material-icons/folder-trash.svg +1 -0
  885. package/dist/material-icons/folder-trigger-open.svg +1 -0
  886. package/dist/material-icons/folder-trigger.svg +1 -0
  887. package/dist/material-icons/folder-turborepo-open.svg +1 -0
  888. package/dist/material-icons/folder-turborepo.svg +1 -0
  889. package/dist/material-icons/folder-typescript-open.svg +1 -0
  890. package/dist/material-icons/folder-typescript.svg +1 -0
  891. package/dist/material-icons/folder-ui-open.svg +1 -0
  892. package/dist/material-icons/folder-ui.svg +1 -0
  893. package/dist/material-icons/folder-unity-open.svg +1 -0
  894. package/dist/material-icons/folder-unity.svg +1 -0
  895. package/dist/material-icons/folder-update-open.svg +1 -0
  896. package/dist/material-icons/folder-update.svg +1 -0
  897. package/dist/material-icons/folder-upload-open.svg +1 -0
  898. package/dist/material-icons/folder-upload.svg +1 -0
  899. package/dist/material-icons/folder-utils-open.svg +1 -0
  900. package/dist/material-icons/folder-utils.svg +1 -0
  901. package/dist/material-icons/folder-vercel-open.svg +1 -0
  902. package/dist/material-icons/folder-vercel.svg +1 -0
  903. package/dist/material-icons/folder-verdaccio-open.svg +1 -0
  904. package/dist/material-icons/folder-verdaccio.svg +1 -0
  905. package/dist/material-icons/folder-video-open.svg +1 -0
  906. package/dist/material-icons/folder-video.svg +1 -0
  907. package/dist/material-icons/folder-views-open.svg +1 -0
  908. package/dist/material-icons/folder-views.svg +1 -0
  909. package/dist/material-icons/folder-vm-open.svg +1 -0
  910. package/dist/material-icons/folder-vm.svg +1 -0
  911. package/dist/material-icons/folder-vscode-open.svg +1 -0
  912. package/dist/material-icons/folder-vscode.svg +1 -0
  913. package/dist/material-icons/folder-vue-directives-open.svg +1 -0
  914. package/dist/material-icons/folder-vue-directives.svg +1 -0
  915. package/dist/material-icons/folder-vue-open.svg +1 -0
  916. package/dist/material-icons/folder-vue.svg +1 -0
  917. package/dist/material-icons/folder-vuepress-open.svg +1 -0
  918. package/dist/material-icons/folder-vuepress.svg +1 -0
  919. package/dist/material-icons/folder-vuex-store-open.svg +1 -0
  920. package/dist/material-icons/folder-vuex-store.svg +1 -0
  921. package/dist/material-icons/folder-wakatime-open.svg +1 -0
  922. package/dist/material-icons/folder-wakatime.svg +1 -0
  923. package/dist/material-icons/folder-webpack-open.svg +1 -0
  924. package/dist/material-icons/folder-webpack.svg +1 -0
  925. package/dist/material-icons/folder-windows-open.svg +1 -0
  926. package/dist/material-icons/folder-windows.svg +1 -0
  927. package/dist/material-icons/folder-wordpress-open.svg +1 -0
  928. package/dist/material-icons/folder-wordpress.svg +1 -0
  929. package/dist/material-icons/folder-yarn-open.svg +1 -0
  930. package/dist/material-icons/folder-yarn.svg +1 -0
  931. package/dist/material-icons/folder-zeabur-open.svg +1 -0
  932. package/dist/material-icons/folder-zeabur.svg +1 -0
  933. package/dist/material-icons/folder-zed-open.svg +1 -0
  934. package/dist/material-icons/folder-zed.svg +1 -0
  935. package/dist/material-icons/folder.svg +1 -0
  936. package/dist/material-icons/font.svg +1 -0
  937. package/dist/material-icons/forth.svg +1 -0
  938. package/dist/material-icons/fortran.svg +1 -0
  939. package/dist/material-icons/foxpro.svg +1 -0
  940. package/dist/material-icons/freemarker.svg +1 -0
  941. package/dist/material-icons/fsharp.svg +1 -0
  942. package/dist/material-icons/fusebox.svg +1 -0
  943. package/dist/material-icons/gamemaker.svg +1 -0
  944. package/dist/material-icons/garden.svg +1 -0
  945. package/dist/material-icons/gatsby.svg +1 -0
  946. package/dist/material-icons/gcp.svg +1 -0
  947. package/dist/material-icons/gemfile.svg +1 -0
  948. package/dist/material-icons/gemini-ai.svg +1 -0
  949. package/dist/material-icons/gemini.svg +1 -0
  950. package/dist/material-icons/git.svg +1 -0
  951. package/dist/material-icons/github-actions-workflow.svg +1 -0
  952. package/dist/material-icons/github-sponsors.svg +1 -0
  953. package/dist/material-icons/gitlab.svg +1 -0
  954. package/dist/material-icons/gitpod.svg +1 -0
  955. package/dist/material-icons/gleam.svg +1 -0
  956. package/dist/material-icons/gnuplot.svg +1 -0
  957. package/dist/material-icons/go-mod.svg +1 -0
  958. package/dist/material-icons/go.svg +1 -0
  959. package/dist/material-icons/go_gopher.svg +1 -0
  960. package/dist/material-icons/godot-assets.svg +1 -0
  961. package/dist/material-icons/godot.svg +1 -0
  962. package/dist/material-icons/google.svg +1 -0
  963. package/dist/material-icons/gradle.svg +1 -0
  964. package/dist/material-icons/grafana-alloy.svg +1 -0
  965. package/dist/material-icons/grain.svg +1 -0
  966. package/dist/material-icons/graphcool.svg +1 -0
  967. package/dist/material-icons/graphql.svg +1 -0
  968. package/dist/material-icons/gridsome.svg +1 -0
  969. package/dist/material-icons/groovy.svg +1 -0
  970. package/dist/material-icons/grunt.svg +1 -0
  971. package/dist/material-icons/gulp.svg +1 -0
  972. package/dist/material-icons/h.svg +1 -0
  973. package/dist/material-icons/hack.svg +1 -0
  974. package/dist/material-icons/hadolint.svg +1 -0
  975. package/dist/material-icons/haml.svg +1 -0
  976. package/dist/material-icons/handlebars.svg +1 -0
  977. package/dist/material-icons/happo.svg +1 -0
  978. package/dist/material-icons/hardhat.svg +1 -0
  979. package/dist/material-icons/harmonix.svg +1 -0
  980. package/dist/material-icons/haskell.svg +1 -0
  981. package/dist/material-icons/haxe.svg +1 -0
  982. package/dist/material-icons/hcl.svg +1 -0
  983. package/dist/material-icons/hcl_light.svg +1 -0
  984. package/dist/material-icons/helm.svg +1 -0
  985. package/dist/material-icons/heroku.svg +1 -0
  986. package/dist/material-icons/hex.svg +1 -0
  987. package/dist/material-icons/hip.svg +1 -0
  988. package/dist/material-icons/histoire.svg +1 -0
  989. package/dist/material-icons/hjson.svg +1 -0
  990. package/dist/material-icons/horusec.svg +1 -0
  991. package/dist/material-icons/hosts.svg +1 -0
  992. package/dist/material-icons/hosts_light.svg +1 -0
  993. package/dist/material-icons/hpp.svg +1 -0
  994. package/dist/material-icons/html.svg +1 -0
  995. package/dist/material-icons/http.svg +1 -0
  996. package/dist/material-icons/huff.svg +1 -0
  997. package/dist/material-icons/huff_light.svg +1 -0
  998. package/dist/material-icons/hurl.svg +1 -0
  999. package/dist/material-icons/husky.svg +1 -0
  1000. package/dist/material-icons/i18n.svg +1 -0
  1001. package/dist/material-icons/idris.svg +1 -0
  1002. package/dist/material-icons/ifanr-cloud.svg +1 -0
  1003. package/dist/material-icons/image.svg +1 -0
  1004. package/dist/material-icons/imba.svg +1 -0
  1005. package/dist/material-icons/installation.svg +1 -0
  1006. package/dist/material-icons/instructions.clone.svg +1 -0
  1007. package/dist/material-icons/ionic.svg +1 -0
  1008. package/dist/material-icons/istanbul.svg +1 -0
  1009. package/dist/material-icons/jar.svg +1 -0
  1010. package/dist/material-icons/java.svg +1 -0
  1011. package/dist/material-icons/javaclass.svg +1 -0
  1012. package/dist/material-icons/javascript-map.svg +1 -0
  1013. package/dist/material-icons/javascript.svg +1 -0
  1014. package/dist/material-icons/jenkins.svg +1 -0
  1015. package/dist/material-icons/jest.svg +1 -0
  1016. package/dist/material-icons/jinja.svg +1 -0
  1017. package/dist/material-icons/jinja_light.svg +1 -0
  1018. package/dist/material-icons/jsconfig.svg +1 -0
  1019. package/dist/material-icons/json.svg +1 -0
  1020. package/dist/material-icons/json_schema.svg +1 -0
  1021. package/dist/material-icons/jsr.svg +1 -0
  1022. package/dist/material-icons/jsr_light.svg +1 -0
  1023. package/dist/material-icons/julia.svg +1 -0
  1024. package/dist/material-icons/jupyter.svg +1 -0
  1025. package/dist/material-icons/just.svg +1 -0
  1026. package/dist/material-icons/karma.svg +1 -0
  1027. package/dist/material-icons/kcl.svg +1 -0
  1028. package/dist/material-icons/key.svg +1 -0
  1029. package/dist/material-icons/keystatic.svg +1 -0
  1030. package/dist/material-icons/kivy.svg +1 -0
  1031. package/dist/material-icons/kl.svg +1 -0
  1032. package/dist/material-icons/knip.svg +1 -0
  1033. package/dist/material-icons/kotlin.svg +1 -0
  1034. package/dist/material-icons/kubernetes.svg +1 -0
  1035. package/dist/material-icons/kusto.svg +1 -0
  1036. package/dist/material-icons/label.svg +1 -0
  1037. package/dist/material-icons/laravel.svg +1 -0
  1038. package/dist/material-icons/latex-class.clone.svg +1 -0
  1039. package/dist/material-icons/latex-package.clone.svg +1 -0
  1040. package/dist/material-icons/latex.clone.svg +1 -0
  1041. package/dist/material-icons/latexmk.svg +1 -0
  1042. package/dist/material-icons/lbx.svg +1 -0
  1043. package/dist/material-icons/lean.svg +1 -0
  1044. package/dist/material-icons/lefthook.svg +1 -0
  1045. package/dist/material-icons/lerna.svg +1 -0
  1046. package/dist/material-icons/less.svg +1 -0
  1047. package/dist/material-icons/liara.svg +1 -0
  1048. package/dist/material-icons/lib.svg +1 -0
  1049. package/dist/material-icons/license.svg +1 -0
  1050. package/dist/material-icons/lighthouse.svg +1 -0
  1051. package/dist/material-icons/lilypond.svg +1 -0
  1052. package/dist/material-icons/lintstaged.svg +1 -0
  1053. package/dist/material-icons/liquid.svg +1 -0
  1054. package/dist/material-icons/lisp.svg +1 -0
  1055. package/dist/material-icons/livescript.svg +1 -0
  1056. package/dist/material-icons/lock.svg +1 -0
  1057. package/dist/material-icons/log.svg +1 -0
  1058. package/dist/material-icons/lolcode.svg +1 -0
  1059. package/dist/material-icons/lottie.svg +1 -0
  1060. package/dist/material-icons/lua.svg +1 -0
  1061. package/dist/material-icons/luau.svg +1 -0
  1062. package/dist/material-icons/lynx.svg +1 -0
  1063. package/dist/material-icons/lyric.svg +1 -0
  1064. package/dist/material-icons/macaulay2.svg +1 -0
  1065. package/dist/material-icons/makefile.svg +1 -0
  1066. package/dist/material-icons/markdoc-config.svg +1 -0
  1067. package/dist/material-icons/markdoc.svg +1 -0
  1068. package/dist/material-icons/markdown.svg +1 -0
  1069. package/dist/material-icons/markdownlint.svg +1 -0
  1070. package/dist/material-icons/markojs.svg +1 -0
  1071. package/dist/material-icons/mathematica.svg +1 -0
  1072. package/dist/material-icons/matlab.svg +1 -0
  1073. package/dist/material-icons/maven.svg +1 -0
  1074. package/dist/material-icons/mdsvex.svg +1 -0
  1075. package/dist/material-icons/mdx.svg +1 -0
  1076. package/dist/material-icons/mercurial.svg +1 -0
  1077. package/dist/material-icons/merlin.svg +1 -0
  1078. package/dist/material-icons/mermaid.svg +1 -0
  1079. package/dist/material-icons/meson.svg +1 -0
  1080. package/dist/material-icons/metro.svg +1 -0
  1081. package/dist/material-icons/minecraft-fabric.svg +1 -0
  1082. package/dist/material-icons/minecraft.svg +1 -0
  1083. package/dist/material-icons/mint.svg +1 -0
  1084. package/dist/material-icons/mist.clone.svg +1 -0
  1085. package/dist/material-icons/mjml.svg +1 -0
  1086. package/dist/material-icons/mocha.svg +1 -0
  1087. package/dist/material-icons/modernizr.svg +1 -0
  1088. package/dist/material-icons/mojo.svg +1 -0
  1089. package/dist/material-icons/moon.svg +1 -0
  1090. package/dist/material-icons/moonscript.svg +1 -0
  1091. package/dist/material-icons/mrpack.svg +1 -0
  1092. package/dist/material-icons/mxml.svg +1 -0
  1093. package/dist/material-icons/nano-staged.svg +1 -0
  1094. package/dist/material-icons/nano-staged_light.svg +1 -0
  1095. package/dist/material-icons/ndst.svg +1 -0
  1096. package/dist/material-icons/nest-controller.clone.svg +1 -0
  1097. package/dist/material-icons/nest-decorator.clone.svg +1 -0
  1098. package/dist/material-icons/nest-filter.clone.svg +1 -0
  1099. package/dist/material-icons/nest-gateway.clone.svg +1 -0
  1100. package/dist/material-icons/nest-guard.clone.svg +1 -0
  1101. package/dist/material-icons/nest-interceptor.clone.svg +1 -0
  1102. package/dist/material-icons/nest-middleware.clone.svg +1 -0
  1103. package/dist/material-icons/nest-module.clone.svg +1 -0
  1104. package/dist/material-icons/nest-pipe.clone.svg +1 -0
  1105. package/dist/material-icons/nest-resolver.clone.svg +1 -0
  1106. package/dist/material-icons/nest-service.clone.svg +1 -0
  1107. package/dist/material-icons/nest.svg +1 -0
  1108. package/dist/material-icons/netlify.svg +1 -0
  1109. package/dist/material-icons/netlify_light.svg +1 -0
  1110. package/dist/material-icons/next.svg +1 -0
  1111. package/dist/material-icons/next_light.svg +1 -0
  1112. package/dist/material-icons/nginx.svg +1 -0
  1113. package/dist/material-icons/ngrx-actions.svg +1 -0
  1114. package/dist/material-icons/ngrx-effects.svg +1 -0
  1115. package/dist/material-icons/ngrx-entity.svg +1 -0
  1116. package/dist/material-icons/ngrx-reducer.svg +1 -0
  1117. package/dist/material-icons/ngrx-selectors.svg +1 -0
  1118. package/dist/material-icons/ngrx-state.svg +1 -0
  1119. package/dist/material-icons/nim.svg +1 -0
  1120. package/dist/material-icons/nix.svg +1 -0
  1121. package/dist/material-icons/nodejs.svg +1 -0
  1122. package/dist/material-icons/nodejs_alt.svg +1 -0
  1123. package/dist/material-icons/nodemon.svg +1 -0
  1124. package/dist/material-icons/npm.svg +1 -0
  1125. package/dist/material-icons/nuget.svg +1 -0
  1126. package/dist/material-icons/nunjucks.svg +1 -0
  1127. package/dist/material-icons/nuxt.svg +1 -0
  1128. package/dist/material-icons/nx.svg +1 -0
  1129. package/dist/material-icons/objective-c.svg +1 -0
  1130. package/dist/material-icons/objective-cpp.svg +1 -0
  1131. package/dist/material-icons/ocaml.svg +1 -0
  1132. package/dist/material-icons/odin.svg +1 -0
  1133. package/dist/material-icons/onnx.svg +1 -0
  1134. package/dist/material-icons/opa.svg +1 -0
  1135. package/dist/material-icons/opam.svg +1 -0
  1136. package/dist/material-icons/openapi.svg +1 -0
  1137. package/dist/material-icons/openapi_light.svg +1 -0
  1138. package/dist/material-icons/opencode.svg +1 -0
  1139. package/dist/material-icons/opencode_light.svg +1 -0
  1140. package/dist/material-icons/opentofu.svg +1 -0
  1141. package/dist/material-icons/opentofu_light.svg +1 -0
  1142. package/dist/material-icons/otne.svg +1 -0
  1143. package/dist/material-icons/oxc.svg +1 -0
  1144. package/dist/material-icons/packship.svg +1 -0
  1145. package/dist/material-icons/palette.svg +1 -0
  1146. package/dist/material-icons/panda.svg +1 -0
  1147. package/dist/material-icons/parcel.svg +1 -0
  1148. package/dist/material-icons/pascal.svg +1 -0
  1149. package/dist/material-icons/pawn.svg +1 -0
  1150. package/dist/material-icons/payload.svg +1 -0
  1151. package/dist/material-icons/payload_light.svg +1 -0
  1152. package/dist/material-icons/pdf.svg +1 -0
  1153. package/dist/material-icons/pdm.svg +1 -0
  1154. package/dist/material-icons/percy.svg +1 -0
  1155. package/dist/material-icons/perl.svg +1 -0
  1156. package/dist/material-icons/php-cs-fixer.svg +1 -0
  1157. package/dist/material-icons/php.svg +1 -0
  1158. package/dist/material-icons/php_elephant.svg +1 -0
  1159. package/dist/material-icons/php_elephant_pink.svg +1 -0
  1160. package/dist/material-icons/phpstan.svg +1 -0
  1161. package/dist/material-icons/phpunit.svg +1 -0
  1162. package/dist/material-icons/pinejs.svg +1 -0
  1163. package/dist/material-icons/pipeline.svg +1 -0
  1164. package/dist/material-icons/pkl.svg +1 -0
  1165. package/dist/material-icons/plastic.svg +1 -0
  1166. package/dist/material-icons/playwright.svg +1 -0
  1167. package/dist/material-icons/plop.svg +1 -0
  1168. package/dist/material-icons/pm2-ecosystem.svg +1 -0
  1169. package/dist/material-icons/pnpm.svg +1 -0
  1170. package/dist/material-icons/pnpm_light.svg +1 -0
  1171. package/dist/material-icons/poetry.svg +1 -0
  1172. package/dist/material-icons/postcss.svg +1 -0
  1173. package/dist/material-icons/posthtml.svg +1 -0
  1174. package/dist/material-icons/powerpoint.svg +1 -0
  1175. package/dist/material-icons/powershell.svg +1 -0
  1176. package/dist/material-icons/pre-commit.svg +1 -0
  1177. package/dist/material-icons/prettier.svg +1 -0
  1178. package/dist/material-icons/prisma.svg +1 -0
  1179. package/dist/material-icons/processing.svg +1 -0
  1180. package/dist/material-icons/prolog.svg +1 -0
  1181. package/dist/material-icons/prompt.svg +1 -0
  1182. package/dist/material-icons/proto.svg +1 -0
  1183. package/dist/material-icons/protractor.svg +1 -0
  1184. package/dist/material-icons/pug.svg +1 -0
  1185. package/dist/material-icons/puppet.svg +1 -0
  1186. package/dist/material-icons/puppeteer.svg +1 -0
  1187. package/dist/material-icons/purescript.svg +1 -0
  1188. package/dist/material-icons/python-misc.svg +1 -0
  1189. package/dist/material-icons/python.svg +1 -0
  1190. package/dist/material-icons/pytorch.svg +1 -0
  1191. package/dist/material-icons/qsharp.svg +1 -0
  1192. package/dist/material-icons/quarto.svg +1 -0
  1193. package/dist/material-icons/quasar.svg +1 -0
  1194. package/dist/material-icons/quokka.svg +1 -0
  1195. package/dist/material-icons/qwik.svg +1 -0
  1196. package/dist/material-icons/r.svg +1 -0
  1197. package/dist/material-icons/racket.svg +1 -0
  1198. package/dist/material-icons/raml.svg +1 -0
  1199. package/dist/material-icons/razor.svg +1 -0
  1200. package/dist/material-icons/rbxmk.svg +1 -0
  1201. package/dist/material-icons/rc.svg +1 -0
  1202. package/dist/material-icons/react.svg +1 -0
  1203. package/dist/material-icons/react_ts.svg +1 -0
  1204. package/dist/material-icons/readme.svg +1 -0
  1205. package/dist/material-icons/reason.svg +1 -0
  1206. package/dist/material-icons/red.svg +1 -0
  1207. package/dist/material-icons/redux-action.svg +1 -0
  1208. package/dist/material-icons/redux-reducer.svg +1 -0
  1209. package/dist/material-icons/redux-selector.svg +1 -0
  1210. package/dist/material-icons/redux-store.svg +1 -0
  1211. package/dist/material-icons/regedit.svg +1 -0
  1212. package/dist/material-icons/remark.svg +1 -0
  1213. package/dist/material-icons/remix.svg +1 -0
  1214. package/dist/material-icons/remix_light.svg +1 -0
  1215. package/dist/material-icons/renovate.svg +1 -0
  1216. package/dist/material-icons/replit.svg +1 -0
  1217. package/dist/material-icons/rescript-interface.svg +1 -0
  1218. package/dist/material-icons/rescript.svg +1 -0
  1219. package/dist/material-icons/restql.svg +1 -0
  1220. package/dist/material-icons/riot.svg +1 -0
  1221. package/dist/material-icons/roadmap.svg +1 -0
  1222. package/dist/material-icons/roblox.svg +1 -0
  1223. package/dist/material-icons/robot.svg +1 -0
  1224. package/dist/material-icons/robots.svg +1 -0
  1225. package/dist/material-icons/rocket.svg +1 -0
  1226. package/dist/material-icons/rojo.svg +1 -0
  1227. package/dist/material-icons/rolldown.svg +1 -0
  1228. package/dist/material-icons/rollup.svg +1 -0
  1229. package/dist/material-icons/rome.svg +1 -0
  1230. package/dist/material-icons/routing.svg +1 -0
  1231. package/dist/material-icons/rspec.svg +1 -0
  1232. package/dist/material-icons/rstack.svg +1 -0
  1233. package/dist/material-icons/rubocop.svg +1 -0
  1234. package/dist/material-icons/rubocop_light.svg +1 -0
  1235. package/dist/material-icons/ruby.svg +1 -0
  1236. package/dist/material-icons/ruff.svg +1 -0
  1237. package/dist/material-icons/rust.svg +1 -0
  1238. package/dist/material-icons/salesforce.svg +1 -0
  1239. package/dist/material-icons/salt.svg +1 -0
  1240. package/dist/material-icons/san.svg +1 -0
  1241. package/dist/material-icons/sas.svg +1 -0
  1242. package/dist/material-icons/sass.svg +1 -0
  1243. package/dist/material-icons/sbt.svg +1 -0
  1244. package/dist/material-icons/scala.svg +1 -0
  1245. package/dist/material-icons/scheme.svg +1 -0
  1246. package/dist/material-icons/scons.svg +1 -0
  1247. package/dist/material-icons/scons_light.svg +1 -0
  1248. package/dist/material-icons/screwdriver.svg +1 -0
  1249. package/dist/material-icons/search.svg +1 -0
  1250. package/dist/material-icons/semantic-release.svg +1 -0
  1251. package/dist/material-icons/semantic-release_light.svg +1 -0
  1252. package/dist/material-icons/semgrep.svg +1 -0
  1253. package/dist/material-icons/sentry.svg +1 -0
  1254. package/dist/material-icons/sequelize.svg +1 -0
  1255. package/dist/material-icons/serverless.svg +1 -0
  1256. package/dist/material-icons/settings.svg +1 -0
  1257. package/dist/material-icons/shader.svg +1 -0
  1258. package/dist/material-icons/shellcheck.svg +1 -0
  1259. package/dist/material-icons/shellcheck_light.svg +1 -0
  1260. package/dist/material-icons/silverstripe.svg +1 -0
  1261. package/dist/material-icons/simulink.svg +1 -0
  1262. package/dist/material-icons/siyuan.svg +1 -0
  1263. package/dist/material-icons/sketch.svg +1 -0
  1264. package/dist/material-icons/skill.svg +1 -0
  1265. package/dist/material-icons/slim.svg +1 -0
  1266. package/dist/material-icons/slint.svg +1 -0
  1267. package/dist/material-icons/slug.svg +1 -0
  1268. package/dist/material-icons/smarty.svg +1 -0
  1269. package/dist/material-icons/sml.svg +1 -0
  1270. package/dist/material-icons/snakemake.svg +1 -0
  1271. package/dist/material-icons/snapcraft.svg +1 -0
  1272. package/dist/material-icons/snowpack.svg +1 -0
  1273. package/dist/material-icons/snowpack_light.svg +1 -0
  1274. package/dist/material-icons/snyk.svg +1 -0
  1275. package/dist/material-icons/solidity.svg +1 -0
  1276. package/dist/material-icons/sonarcloud.svg +1 -0
  1277. package/dist/material-icons/spwn.svg +1 -0
  1278. package/dist/material-icons/stackblitz.svg +1 -0
  1279. package/dist/material-icons/stan.svg +1 -0
  1280. package/dist/material-icons/steadybit.svg +1 -0
  1281. package/dist/material-icons/stencil.svg +1 -0
  1282. package/dist/material-icons/stitches.svg +1 -0
  1283. package/dist/material-icons/stitches_light.svg +1 -0
  1284. package/dist/material-icons/storybook.svg +1 -0
  1285. package/dist/material-icons/stryker.svg +1 -0
  1286. package/dist/material-icons/sty.clone.svg +1 -0
  1287. package/dist/material-icons/stylable.svg +1 -0
  1288. package/dist/material-icons/stylelint.svg +1 -0
  1289. package/dist/material-icons/stylelint_light.svg +1 -0
  1290. package/dist/material-icons/stylus.svg +1 -0
  1291. package/dist/material-icons/sublime.svg +1 -0
  1292. package/dist/material-icons/subtitles.svg +1 -0
  1293. package/dist/material-icons/supabase.svg +1 -0
  1294. package/dist/material-icons/svelte.svg +1 -0
  1295. package/dist/material-icons/svelte_js.clone.svg +1 -0
  1296. package/dist/material-icons/svelte_ts.clone.svg +1 -0
  1297. package/dist/material-icons/svg.svg +1 -0
  1298. package/dist/material-icons/svgo.svg +1 -0
  1299. package/dist/material-icons/svgr.svg +1 -0
  1300. package/dist/material-icons/swagger.svg +1 -0
  1301. package/dist/material-icons/sway.svg +1 -0
  1302. package/dist/material-icons/swc.svg +1 -0
  1303. package/dist/material-icons/swift.svg +1 -0
  1304. package/dist/material-icons/syncpack.svg +1 -0
  1305. package/dist/material-icons/systemd.svg +1 -0
  1306. package/dist/material-icons/systemd_light.svg +1 -0
  1307. package/dist/material-icons/table.svg +1 -0
  1308. package/dist/material-icons/tailwindcss.svg +1 -0
  1309. package/dist/material-icons/tape.clone.svg +1 -0
  1310. package/dist/material-icons/taskfile.svg +1 -0
  1311. package/dist/material-icons/tauri.svg +1 -0
  1312. package/dist/material-icons/taze.svg +1 -0
  1313. package/dist/material-icons/tcl.svg +1 -0
  1314. package/dist/material-icons/teal.svg +1 -0
  1315. package/dist/material-icons/templ.svg +1 -0
  1316. package/dist/material-icons/template.svg +1 -0
  1317. package/dist/material-icons/terraform.svg +1 -0
  1318. package/dist/material-icons/test-js.svg +1 -0
  1319. package/dist/material-icons/test-jsx.svg +1 -0
  1320. package/dist/material-icons/test-ts.svg +1 -0
  1321. package/dist/material-icons/tex.svg +1 -0
  1322. package/dist/material-icons/textlint.svg +1 -0
  1323. package/dist/material-icons/tilt.svg +1 -0
  1324. package/dist/material-icons/tldraw.svg +1 -0
  1325. package/dist/material-icons/tldraw_light.svg +1 -0
  1326. package/dist/material-icons/tobi.svg +1 -0
  1327. package/dist/material-icons/tobimake.svg +1 -0
  1328. package/dist/material-icons/toc.svg +1 -0
  1329. package/dist/material-icons/todo.svg +1 -0
  1330. package/dist/material-icons/toml.svg +1 -0
  1331. package/dist/material-icons/toml_light.svg +1 -0
  1332. package/dist/material-icons/toon.svg +1 -0
  1333. package/dist/material-icons/travis.svg +1 -0
  1334. package/dist/material-icons/tree.svg +1 -0
  1335. package/dist/material-icons/trigger.svg +1 -0
  1336. package/dist/material-icons/tsconfig.svg +1 -0
  1337. package/dist/material-icons/tsdoc.svg +1 -0
  1338. package/dist/material-icons/tsdown.svg +1 -0
  1339. package/dist/material-icons/tsil.svg +1 -0
  1340. package/dist/material-icons/tune.svg +1 -0
  1341. package/dist/material-icons/turborepo.svg +1 -0
  1342. package/dist/material-icons/turborepo_light.svg +1 -0
  1343. package/dist/material-icons/twig.svg +1 -0
  1344. package/dist/material-icons/twine.svg +1 -0
  1345. package/dist/material-icons/typedoc.svg +1 -0
  1346. package/dist/material-icons/typescript-def.svg +1 -0
  1347. package/dist/material-icons/typescript.svg +1 -0
  1348. package/dist/material-icons/typst.svg +1 -0
  1349. package/dist/material-icons/uiua.svg +1 -0
  1350. package/dist/material-icons/umi.svg +1 -0
  1351. package/dist/material-icons/uml.svg +1 -0
  1352. package/dist/material-icons/uml_light.svg +1 -0
  1353. package/dist/material-icons/unity.svg +1 -0
  1354. package/dist/material-icons/unlicense.svg +1 -0
  1355. package/dist/material-icons/unocss.svg +1 -0
  1356. package/dist/material-icons/url.svg +1 -0
  1357. package/dist/material-icons/uv.svg +1 -0
  1358. package/dist/material-icons/vagrant.svg +1 -0
  1359. package/dist/material-icons/vala.svg +1 -0
  1360. package/dist/material-icons/vanilla-extract.svg +1 -0
  1361. package/dist/material-icons/varnish.svg +1 -0
  1362. package/dist/material-icons/vedic.svg +1 -0
  1363. package/dist/material-icons/velite.svg +1 -0
  1364. package/dist/material-icons/velocity.svg +1 -0
  1365. package/dist/material-icons/vercel.svg +1 -0
  1366. package/dist/material-icons/vercel_light.svg +1 -0
  1367. package/dist/material-icons/verdaccio.svg +1 -0
  1368. package/dist/material-icons/verified.svg +1 -0
  1369. package/dist/material-icons/verilog.svg +1 -0
  1370. package/dist/material-icons/verse.svg +1 -0
  1371. package/dist/material-icons/verse_light.svg +1 -0
  1372. package/dist/material-icons/vfl.svg +1 -0
  1373. package/dist/material-icons/video.svg +1 -0
  1374. package/dist/material-icons/vim.svg +1 -0
  1375. package/dist/material-icons/virtual.svg +1 -0
  1376. package/dist/material-icons/visualstudio.svg +1 -0
  1377. package/dist/material-icons/vite.svg +1 -0
  1378. package/dist/material-icons/vitest.svg +1 -0
  1379. package/dist/material-icons/vlang.svg +1 -0
  1380. package/dist/material-icons/vscode.svg +1 -0
  1381. package/dist/material-icons/vue-config.svg +1 -0
  1382. package/dist/material-icons/vue.svg +1 -0
  1383. package/dist/material-icons/vuex-store.svg +1 -0
  1384. package/dist/material-icons/wakatime.svg +1 -0
  1385. package/dist/material-icons/wakatime_light.svg +1 -0
  1386. package/dist/material-icons/wallaby.svg +1 -0
  1387. package/dist/material-icons/wally.svg +1 -0
  1388. package/dist/material-icons/warp.svg +1 -0
  1389. package/dist/material-icons/warp_light.svg +1 -0
  1390. package/dist/material-icons/watchman.svg +1 -0
  1391. package/dist/material-icons/webassembly.svg +1 -0
  1392. package/dist/material-icons/webhint.svg +1 -0
  1393. package/dist/material-icons/webpack.svg +1 -0
  1394. package/dist/material-icons/wepy.svg +1 -0
  1395. package/dist/material-icons/werf.svg +1 -0
  1396. package/dist/material-icons/windicss.svg +1 -0
  1397. package/dist/material-icons/wolframlanguage.svg +1 -0
  1398. package/dist/material-icons/word.svg +1 -0
  1399. package/dist/material-icons/wrangler.svg +1 -0
  1400. package/dist/material-icons/wxt.svg +1 -0
  1401. package/dist/material-icons/xaml.svg +1 -0
  1402. package/dist/material-icons/xmake.svg +1 -0
  1403. package/dist/material-icons/xml.svg +1 -0
  1404. package/dist/material-icons/yaml.svg +1 -0
  1405. package/dist/material-icons/yang.svg +1 -0
  1406. package/dist/material-icons/yarn.svg +1 -0
  1407. package/dist/material-icons/zeabur.svg +1 -0
  1408. package/dist/material-icons/zeabur_light.svg +1 -0
  1409. package/dist/material-icons/zig.svg +1 -0
  1410. package/dist/material-icons/zip.svg +1 -0
  1411. package/dist/theme-init.js +10 -0
  1412. package/docs/architecture.md +311 -0
  1413. package/docs/configuration.md +141 -0
  1414. package/docs/deployment.md +117 -0
  1415. package/docs/security-upgrade.md +35 -0
  1416. package/package.json +81 -4
  1417. package/runtime/server/src/app.js +71 -0
  1418. package/runtime/server/src/config/config.js +173 -0
  1419. package/runtime/server/src/lib/concurrency.js +44 -0
  1420. package/runtime/server/src/lib/errors.js +39 -0
  1421. package/runtime/server/src/lib/http-range.js +27 -0
  1422. package/runtime/server/src/lib/shell-quote.js +14 -0
  1423. package/runtime/server/src/lib/validation.js +11 -0
  1424. package/runtime/server/src/main.js +70 -0
  1425. package/runtime/server/src/modules/auth/auth-security.js +104 -0
  1426. package/runtime/server/src/modules/auth/auth-service.js +96 -0
  1427. package/runtime/server/src/modules/auth/auth.routes.js +108 -0
  1428. package/runtime/server/src/modules/auth/login-limiter.js +40 -0
  1429. package/runtime/server/src/modules/auth/password.js +29 -0
  1430. package/runtime/server/src/modules/auth/session-tokens.js +90 -0
  1431. package/runtime/server/src/modules/commit-message/commit-message-generator.js +203 -0
  1432. package/runtime/server/src/modules/commit-message/occ-config.js +53 -0
  1433. package/runtime/server/src/modules/exec/command-runner.js +91 -0
  1434. package/runtime/server/src/modules/filesystem/file-system-driver.js +1 -0
  1435. package/runtime/server/src/modules/filesystem/local-driver.js +95 -0
  1436. package/runtime/server/src/modules/filesystem/restricted-driver.js +114 -0
  1437. package/runtime/server/src/modules/filesystem/sftp-driver.js +105 -0
  1438. package/runtime/server/src/modules/filesystem/workspace-file-service.js +328 -0
  1439. package/runtime/server/src/modules/filesystem/workspace-path.js +31 -0
  1440. package/runtime/server/src/modules/git/git-parsers.js +229 -0
  1441. package/runtime/server/src/modules/git/git-service.js +597 -0
  1442. package/runtime/server/src/modules/git/git.routes.js +68 -0
  1443. package/runtime/server/src/modules/hosts/directory-browser.js +36 -0
  1444. package/runtime/server/src/modules/hosts/host-service.js +260 -0
  1445. package/runtime/server/src/modules/hosts/host.routes.js +31 -0
  1446. package/runtime/server/src/modules/hosts/key-installer.js +58 -0
  1447. package/runtime/server/src/modules/ssh/host-key-probe.js +64 -0
  1448. package/runtime/server/src/modules/ssh/host-key-verifier.js +153 -0
  1449. package/runtime/server/src/modules/ssh/ssh-config.js +1 -0
  1450. package/runtime/server/src/modules/ssh/ssh-connection-manager.js +190 -0
  1451. package/runtime/server/src/modules/ssh/ssh-connection.js +93 -0
  1452. package/runtime/server/src/modules/store/app-store.js +138 -0
  1453. package/runtime/server/src/modules/terminal/output-buffer.js +54 -0
  1454. package/runtime/server/src/modules/terminal/pty.js +1 -0
  1455. package/runtime/server/src/modules/terminal/ssh-pty-provider.js +91 -0
  1456. package/runtime/server/src/modules/terminal/terminal-manager.js +70 -0
  1457. package/runtime/server/src/modules/terminal/terminal-session.js +124 -0
  1458. package/runtime/server/src/modules/terminal/terminal-socket.js +170 -0
  1459. package/runtime/server/src/modules/terminal/terminal.routes.js +19 -0
  1460. package/runtime/server/src/modules/workspace/workspace-registry.js +231 -0
  1461. package/runtime/server/src/modules/workspace/workspace.routes.js +97 -0
  1462. package/runtime/server/src/scripts/reset-password.js +21 -0
  1463. package/runtime/server/src/services.js +35 -0
  1464. package/runtime/src/schema/api.js +30 -0
  1465. package/runtime/src/schema/auth.js +20 -0
  1466. package/runtime/src/schema/git.js +233 -0
  1467. package/runtime/src/schema/hosts.js +115 -0
  1468. package/runtime/src/schema/terminal.js +48 -0
  1469. package/runtime/src/schema/workspace.js +151 -0
@@ -0,0 +1,311 @@
1
+ # Architecture
2
+
3
+ ## Overview
4
+
5
+ ```text
6
+ Desktop / mobile browser
7
+ React 19 · TanStack Router/Query · Zustand · CodeMirror 6 · xterm.js
8
+ │ HTTPS (REST, cookie session) WebSocket /ws/terminal (one per terminal)
9
+ ▼
10
+ Fastify backend (Node 24, TypeScript run natively)
11
+ auth guards ─ routes ─ services ─ adapters
12
+ │ SSH control connection (SFTP + exec) one SSH connection per terminal (PTY)
13
+ ▼
14
+ Development machines (any number): project folders · git · login shell · claude · codex
15
+ ```
16
+
17
+ A single npm package holds both halves. The frontend keeps the boilerplate's layout (`src/app`, `src/features`,
18
+ `src/schema`, `src/store`, ...). The backend lives in `server/src` and imports the same Zod schemas from `src/schema`,
19
+ so HTTP and WebSocket contracts are defined once and validated on both sides.
20
+
21
+ ## Backend
22
+
23
+ Route handlers are thin: they validate input with Zod (`parseInput`) and call a service. Services hold the logic and
24
+ depend on small interfaces, wired in `server/src/services.ts`:
25
+
26
+ | Interface | Implementations | Used by |
27
+ | ------------------ | ------------------------------------------------- | ----------------------- |
28
+ | `FileSystemDriver` | `SftpFileSystemDriver`, `LocalFileSystemDriver` | `WorkspaceFileService` |
29
+ | `CommandRunner` | `SshCommandRunner`, `LocalCommandRunner` | SSH Git / local AI CLI |
30
+ | `PtyProvider` | `SshPtyProvider` (tests: `FakePtyProvider`) | `TerminalManager` |
31
+
32
+ ### Hosts, projects, and persistent state
33
+
34
+ Hosts and project records live in the store; administrator workspace-root policy lives in the environment. `AppStore` (`modules/store`) persists everything
35
+ in `DATA_DIR` with atomic, owner-only writes: `state.json` (password hash, hosts, projects, hashed session records)
36
+ and `keys/<hostId>` (private keys generated or imported in the UI; never in `state.json`
37
+ and never returned by the API).
38
+
39
+ - `HostService` (`modules/hosts`) manages SSH hosts: validates and stores credentials (generated ed25519 key, imported
40
+ unencrypted key, key file on the server, or ssh-agent), the user-trusted host key, and one `SshConnectionManager`
41
+ per host. Editing or removing a host drops its connection.
42
+ - `WorkspaceRegistry` (`modules/workspace`) manages projects (a folder on a host, or on the server machine for files
43
+ only). Each project lazily gets its own `WorkspaceFileService` and `GitService`, sharing its host's control
44
+ connection; terminals get a `PtyProvider` that starts the login shell in the project folder. Removing a project
45
+ terminates its terminals; removing a host removes its projects.
46
+ - `TerminalManager` is global (the session cap applies across projects) and tags every session with its project.
47
+
48
+ ### First-run setup
49
+
50
+ While no password exists, `AuthService` generates a random setup token, prints a `/setup#token=…` link on stdout and
51
+ writes it to `DATA_DIR/setup-token` (0600). `POST /api/auth/setup` requires that token (constant-time compare,
52
+ rate-limited), stores the scrypt hash, deletes the token, and signs the user in. Afterwards setup returns 409. The
53
+ token travels in the URL fragment, so it never appears in request logs or `Referer` headers.
54
+
55
+ ### Adding a host
56
+
57
+ 1. `POST /api/hosts/probe` opens a handshake and captures the host key inside the host-key callback, which then
58
+ rejects the connection: no credentials are ever offered to an unverified server. The response contains the key,
59
+ its SHA256 fingerprint, and what the server's `known_hosts` says (`trusted` / `unknown` / `mismatch` / `revoked`).
60
+ 2. The UI shows the fingerprint (and how to check it on the machine). `mismatch`/`revoked` cannot be trusted.
61
+ 3. `POST /api/hosts` stores the explicitly trusted key with the credentials. From then on every connection uses a
62
+ **pinned verifier** that accepts exactly that key (and only offers its algorithm). A changed key fails closed;
63
+ re-trusting goes through the same probe/review flow.
64
+ With `auth: {type: 'password'}`, the server first signs in once with the password (pinned host key, so it is never
65
+ offered to an unverified server), installs a freshly generated key in `authorized_keys`
66
+ (`hosts/key-installer.ts`, ssh-copy-id style), and stores only that key. The password exists only for that call.
67
+ 4. `POST /api/hosts/:id/test` opens a fresh control connection and reports authentication problems.
68
+
69
+ ### SSH connections
70
+
71
+ - `SshConnectionManager` owns one lazily opened **control connection** shared by SFTP (one channel) and short-lived
72
+ exec channels for Git (at most 4 concurrently, below OpenSSH's default `MaxSessions` of 10). It reconnects on the
73
+ next request after a drop, with exponential backoff (1 s → 30 s) after failures so a down host is not hammered.
74
+ - Each **terminal gets its own SSH connection**, so a hung shell or a dropped terminal never affects file or Git access
75
+ or other terminals.
76
+ - Every connection verifies the host key (`host-key-verifier.ts`) against the key the user trusted for that host.
77
+ Mismatched keys fail closed with an explicit message; trust is only ever granted by an explicit user decision after
78
+ seeing the fingerprint, and there is no opt-out.
79
+ - Transport errors are mapped to safe, actionable messages (authentication failed, host unreachable, timeout, ...).
80
+
81
+ ### Filesystem
82
+
83
+ `WorkspaceFileService` enforces the workspace boundary for every request:
84
+
85
+ 1. normalize the client path (`normalizeWorkspacePath`): relative POSIX path, no NUL, no `..` escape;
86
+ 2. resolve it to a **canonical path with symlinks resolved** (`realpath`, done by sftp-server over SSH);
87
+ 3. check containment with `path.relative` against the canonical root (not a string prefix — `/srv/app-old` is not
88
+ inside `/srv/app`).
89
+
90
+ Symlinks inside the workspace work; symlinks pointing outside are listed but refuse to open. Directories are listed
91
+ lazily (one level per request) and sorted directories-first with natural ordering. Files larger than `MAX_FILE_BYTES`
92
+ are not read; files with NUL bytes in the first 8000 bytes are reported as binary; invalid UTF-8 is decoded with
93
+ replacement characters and flagged; FIFOs and devices are refused (reading a FIFO would block).
94
+
95
+ ### Git
96
+
97
+ `GitService` runs the native Git CLI with argv vectors only:
98
+
99
+ - `git rev-parse --show-toplevel --show-prefix` finds the repository and maps repo paths to workspace paths (the
100
+ workspace may be a subdirectory of the repository).
101
+ - `git status --porcelain=v2 --branch -z --untracked-files=all` provides branch, upstream, ahead/behind, and every
102
+ change in one machine-readable call. (Porcelain v2 is used instead of v1 because it carries branch metadata and
103
+ rename sources in the same output.) `git diff [--cached] --numstat -z` adds line counts.
104
+ - **Nested repositories** (clones inside the project, submodules, worktrees): `find . -maxdepth 7 ( -name node_modules
105
+ -o … ) -prune -o -name .git -print0 -prune` lists `.git` entries below the project folder (symlinks are never
106
+ followed; dependency/build folders are skipped; at most 30 repositories; cached for 15 s). Each candidate must pass
107
+ `git rev-parse --show-toplevel` == that exact directory — Git silently falls back to a parent repository when a
108
+ `.git` is invalid — and then gets its own status. The UI shows one section per repository; the parent's untracked
109
+ entry for a nested clone is dropped. A repository that cannot be read reports its error without hiding the others.
110
+ Diff requests carry the repository path (`repo`) and are verified the same way before Git runs there.
111
+ - Diffs: `git diff` (unstaged), `git diff --cached -M` (staged, with the rename source), `git diff --no-index -- /dev/null
112
+ <file>` (untracked).
113
+ - Global flags: `--literal-pathspecs` (names are never globs), `--no-ext-diff --no-textconv` (never run
114
+ repository-configured programs), `--no-pager`, `GIT_OPTIONAL_LOCKS=0` (status never contends with Git running in a
115
+ terminal). Paths always follow `--`.
116
+ - Over SSH the argv is single-quoted for the remote login shell (`quoteShellArg`, tested by round-tripping hostile
117
+ strings through `/bin/sh`).
118
+
119
+ - **History graph**: `git log -z --topo-order --decorate=full --format=…` for `HEAD` and its upstream (or
120
+ `--branches --remotes --tags HEAD` with "all"), paged 50 at a time. Commit ids from the browser must be hex and are
121
+ resolved with `git rev-list --parents -n 1 <id>^{commit}` before use; commit details come from `git diff-tree -M
122
+ --name-status/--numstat` against the first parent (`--root` for root commits), file diffs from `git diff <parent>
123
+ <commit>` (or `git show` for root commits).
124
+ - The graph itself (`src/features/git/utils/history-graph.ts`) is a port of VS Code's
125
+ `scmHistory.ts`: the same swimlane assignment (`toISCMHistoryItemViewModelArray`), SVG geometry (22 px rows, 11 px
126
+ lanes, 5 px curves), node shapes (HEAD ring, merge double circle), lane palette (`scmGraph.foreground1-5`), and ref
127
+ colours (current branch blue, its upstream purple, other refs follow their lane). Ref pills follow VS Code's default
128
+ `scm.graph.badges: "filter"`. Clicking a commit opens a tab with every changed file and its diff (VS Code's
129
+ multi-diff editor).
130
+
131
+ Output is bounded (`MAX_DIFF_BYTES`, 16 MiB for status) and truncation is reported to the UI.
132
+
133
+ ### Terminals
134
+
135
+ ```text
136
+ TerminalManager ── TerminalSession ── PtyProcess (SSH exec + PTY, own connection)
137
+ │ OutputBuffer (bounded replay)
138
+ └── TerminalClient (the currently attached WebSocket, or none)
139
+ ```
140
+
141
+ - A session's lifetime is independent of any WebSocket. Sockets **attach** and **detach**; only an explicit
142
+ `terminate` (closing the tab), the orphan timeout, process exit + cleanup, or server shutdown ends it.
143
+ - Output is appended to a bounded `OutputBuffer` (`TERMINAL_REPLAY_BUFFER_BYTES`). On re-attach the buffer is replayed
144
+ starting at a line boundary.
145
+ - **Backpressure**: while more than 1 MiB is queued on the WebSocket, the PTY channel is paused (the remote program
146
+ blocks on write) and resumed below 256 KiB. While detached, output keeps draining into the bounded buffer.
147
+ - **Orphans**: a session with no attached socket for `TERMINAL_ORPHAN_TIMEOUT_MINUTES` is terminated (`0`, the default,
148
+ keeps running shells until their tab is closed; an exited shell without a client is reaped after 10 minutes). Any
149
+ browser that opens the app adopts live sessions it has no tab for, so shells resume on other devices too. A server-side
150
+ ping every 30 s detects half-open mobile connections; the same heartbeat re-verifies the login cookie and closes
151
+ sockets whose session was revoked or expired. Push revocation closes sockets immediately, every message checks authorization, and an expiry timer enforces the idle/absolute deadline.
152
+ - One client per session: a second attach takes over and the first socket receives `detached`.
153
+ - Shells start as `cd -- '<root>'; exec "$SHELL" -l` with a PTY, i.e. a normal interactive login shell in the
154
+ workspace.
155
+
156
+ #### WebSocket protocol (`src/schema/terminal.ts`)
157
+
158
+ Client → server (JSON text frames):
159
+
160
+ | Message | Meaning |
161
+ | ----------------------------------------- | ------------------------------------------------------ |
162
+ | `{type:"create", cols, rows}` | Start a new shell (must be the first message) |
163
+ | `{type:"attach", sessionId, cols, rows}` | Re-attach to an existing session (first message) |
164
+ | `{type:"input", data}` | Keystrokes / paste (≤ 64 KiB per message) |
165
+ | `{type:"resize", cols, rows}` | PTY window change |
166
+ | `{type:"terminate"}` | Kill the shell (tab closed) |
167
+
168
+ Server → client: raw **binary frames** for terminal output, plus JSON `ready {sessionId, replay}`, `exit {exitCode,
169
+ signal}`, `error {code, message}`, `detached`. Application close codes: 4000 protocol error, 4004 unknown session,
170
+ 4009 replaced, 4010 terminated, 4401 login expired. Upgrades without a valid session cookie or with a disallowed
171
+ `Origin` are refused with HTTP 401/403 before any session exists.
172
+
173
+ ### HTTP API
174
+
175
+ | Method & path | Purpose |
176
+ | ------------------------------ | ------------------------------------------- |
177
+ | `GET /api/health` | Liveness (public) |
178
+ | `GET /api/auth/session` | `{authenticated, setupRequired}` (public) |
179
+ | `POST /api/auth/setup` | First password, with the setup token (public, one-time) |
180
+ | `POST /api/auth/login` | Password login → `HttpOnly` session cookie |
181
+ | `POST /api/auth/logout` | Revoke the session |
182
+ | `POST /api/auth/activity` | Record explicit browser interaction; polling does not count |
183
+ | `POST /api/auth/logout-all` | Password-confirmed session revocation and terminal termination |
184
+ | `POST /api/auth/password` | Change password; signs out other sessions |
185
+ | `GET /api/hosts` | Hosts (public keys and fingerprints only) |
186
+ | `POST /api/hosts/probe` | Fetch a server's host key for review |
187
+ | `POST /api/hosts`, `PATCH/DELETE /api/hosts/:id` | Manage hosts |
188
+ | `POST /api/hosts/:id/test` | Fresh connection test |
189
+ | `GET /api/browse?host=&path=` | Directories on a host (folder picker) |
190
+ | `GET/POST /api/workspaces`, `PATCH/DELETE /api/workspaces/:id` | Manage projects |
191
+ | `GET /api/workspaces/:id` | Name, root, host, connection status |
192
+ | `POST /api/workspaces/:id/reconnect` | Force a new SSH control connection |
193
+ | `GET /api/workspaces/:id/tree?path=` | One directory level |
194
+ | `GET /api/workspaces/:id/file?path=` | File content (text / binary / too-large) |
195
+ | `PUT /api/workspaces/:id/file` | Save a text file (mtime precondition) |
196
+ | `GET /api/workspaces/:id/file/raw?path=&download=` | Media bytes for the viewer (byte ranges), or any file as a download |
197
+ | `POST /api/workspaces/:id/entries[/copy\|/move\|/rename\|/delete]` | Explorer file operations |
198
+ | `GET /api/workspaces/:id/git/status` | Branch and changes |
199
+ | `GET /api/workspaces/:id/git/diff?path=&area=&origPath=` | Diff for one change |
200
+ | `GET /api/workspaces/:id/git/refs?repo=` | Branches, remotes (URLs without credentials), tags, stashes |
201
+ | `POST /api/workspaces/:id/git/operation` | One "..." menu action (`op`: pull, push, sync, publish, fetch, checkout, branch, merge, rebase, stash, tag, remote, ...); fixed argv per `op`, names validated by Zod and Git |
202
+ | `GET /api/terminals` | Live sessions |
203
+ | `DELETE /api/terminals/:id` | Terminate a session |
204
+ | `WS /ws/terminal` | Terminal protocol above |
205
+
206
+ Errors always have the shape `{"error": {"code": "...", "message": "..."}}`. Only `AppError` messages reach the
207
+ browser; anything else becomes a generic `INTERNAL` error and is logged server-side.
208
+
209
+ ## Frontend
210
+
211
+ - **Routing**: `/setup` (only while setup is pending), `/login`, `/projects`, `/hosts/new` and `/hosts/:id` (the
212
+ connect-a-machine wizard), `/hosts/:id/add-project` (folder picker), `/settings`, and `/w/:workspaceId` (the
213
+ workspace). `/` reopens the last project. Guards redirect to setup or login as needed; any 401 sends the user to login.
214
+ - **Projects**: query keys are scoped by project (`['workspace', id, ...]`). The tabs store keeps one tab strip per
215
+ project (`tabs` for the open one, `saved` for the others) and switches before the workspace renders. Terminal tabs
216
+ carry their project id; the terminal registry keeps controllers of background projects connected, and only
217
+ terminates a shell when its tab disappears from every project.
218
+ - **Server state** lives in TanStack Query (`src/api/queries.ts`): directory listings (30 s stale time, cancellable),
219
+ file contents (refetched on focus, so files edited by an agent refresh), Git status and diffs (invalidated by the
220
+ refresh button and ~1.5 s after a command is submitted in any terminal).
221
+ - **Client state** lives in small Zustand stores: `tabs` (persisted: open tabs, order, active tab, terminal session
222
+ ids), `layout` (persisted: sidebar visibility/widths, word wrap; drawer state is not persisted), `explorer`
223
+ (expanded folders, hidden files), `git` panel selection.
224
+ - **Terminals** never go through React state. `TerminalController` owns the xterm.js instance, its DOM element, and its
225
+ WebSocket; `terminal-registry` creates one per tab and terminates it exactly when the tab disappears from the tab
226
+ store. React only mounts the controller's element into the active tab, so switching tabs, resizing across the
227
+ desktop/mobile breakpoint, or re-rendering never touches the connection. Scrollback is bounded (5000 lines).
228
+ Controllers reconnect with backoff, re-attach after reloads, and suppress xterm's automatic replies to terminal
229
+ queries contained in replayed history (otherwise those replies would be typed into the live shell).
230
+ - **Viewer**: one `CodeViewer` (CodeMirror 6, read-only) for files and diffs. Languages load on demand via
231
+ `@codemirror/language-data`. Scroll positions survive unmounting via `scrollSnapshot()`. On touch devices the
232
+ content is non-editable so tapping code never raises the keyboard; search is a toolbar button.
233
+ - **Diffs** are parsed into lines with old/new numbers; prefixes are stripped so the code is highlighted as its own
234
+ language, with line backgrounds and a dual line-number gutter as CodeMirror decorations (virtualized, so large diffs
235
+ stay fast).
236
+ - **Layout**: ≥ 1024 px shows resizable, collapsible sidebars; below that, explorer and Git become independent
237
+ slide-over drawers (swipe, backdrop tap, or Esc to close) that never reset the center tab. The app frame follows
238
+ `visualViewport`, so the terminal shrinks above the on-screen keyboard and the PTY is resized when the cell grid
239
+ changes. Safe-area insets are respected.
240
+
241
+ ## Security model
242
+
243
+ Single trusted user, defence in depth:
244
+
245
+ | Concern | Measure |
246
+ | -------------------------- | --------------------------------------------------------------------------------------------- |
247
+ | Exposure | Binds to 127.0.0.1; published via `tailscale serve` (HTTPS, tailnet only); Funnel not used. |
248
+ | Setup takeover | First password requires a one-time token printed on the server console. |
249
+ | Authentication | scrypt (N=32768, r=8, p=3); persistent opaque hashed sessions; `HttpOnly`, `SameSite=Strict`, `Secure` (over HTTPS) cookie. |
250
+ | Brute force | Per-IP exponential lockout after 5 failures plus a global cap. |
251
+ | CSRF / socket hijacking | State-changing requests and WebSocket upgrades must be same-origin on a loopback, IP, or `*.ts.net` host (DNS-rebinding names fail), or listed in `ALLOWED_ORIGINS`; `Sec-Fetch-Site: cross-site` rejected. |
252
+ | Revocation | Logout revokes the token; open terminal sockets are closed on the next heartbeat. |
253
+ | Credentials | Private keys stay in `DATA_DIR/keys` (0600); responses carry public keys only; never logged. |
254
+ | MITM | Host key reviewed and explicitly trusted once (known_hosts consulted), then pinned; probes send no credentials. |
255
+ | Path traversal / symlinks | Normalization + canonical-path containment. |
256
+ | Command injection | Argv only; single-quoted for the remote shell; `--` before paths; literal pathspecs; no ext diff/textconv. |
257
+ | Workspace access | Administrator-configured local/SSH roots; protected backend paths; local Git execution disabled. |
258
+ | Resource exhaustion | Size limits for files, diffs, listings, status; bounded replay buffers; session cap; backpressure; orphan reaping. |
259
+ | Browser hardening | CSP (`script-src 'self'`), `X-Frame-Options: DENY`, `nosniff`, `no-referrer`, `no-store` on API responses. |
260
+ | Logging | Structured pino logs; cookies redacted; terminal input and file contents never logged. |
261
+
262
+ Not covered: multi-user isolation (everyone who knows the password is the same user, with that user's shell),
263
+ TOCTOU between the containment check and the read (a process on the dev machine racing symlink swaps), and the remote
264
+ user's own permissions (the terminal is a full shell by design).
265
+
266
+ ## Extensions (future)
267
+
268
+ A VS Code extension host is out of scope: CodeMirror cannot run VS Code extensions, and supporting them would mean
269
+ embedding a VS Code workbench (e.g. openvscode-server) — a separate architectural decision.
270
+
271
+ The codebase is shaped for small internal integrations instead:
272
+
273
+ - **Git actions** (e.g. an AI-generated commit message): add a `GitService` method + route (it already has a safe
274
+ argv runner and repository detection), a schema in `src/schema/git.ts`, and a button in `GitPanel`. A commit-message
275
+ helper could call a CLI already installed on the remote (`claude -p`, `codex exec`) through `CommandRunner`, keeping
276
+ API keys out of this application.
277
+ - **Workspace commands**: a server-side registry of named argv templates executed via `CommandRunner`, exposed as a
278
+ command palette.
279
+ - **Sidebar panels / viewer actions**: panels are plain feature components composed by `WorkspaceScreen`; viewer
280
+ actions are extra buttons in `ViewHeader` or CodeMirror extensions passed through `CodeViewer`.
281
+ - **Language services**: would require a per-language LSP process on the remote and a CodeMirror LSP client; not
282
+ planned.
283
+
284
+ No plugin loader was built: with one user and a handful of planned helpers, direct composition is simpler and safer
285
+ than a dynamic plugin API.
286
+
287
+ ## Limitations
288
+
289
+ - Viewer is read-only (editing/saving is a planned follow-up; the API and tab model leave room for it).
290
+ - Single user: one password; everyone who knows it is the same user on every connected host.
291
+ - Private keys at rest are protected by file permissions, not encrypted (like `~/.ssh`). Passphrase-protected keys
292
+ cannot be imported; use ssh-agent for those.
293
+ - Terminal sessions live in the server process: a backend restart ends them (use `tmux` on the remote for
294
+ restart-proof sessions).
295
+ - Replayed terminal history is re-rendered at the current width, so a re-attached terminal may show wrapped lines or
296
+ zsh's `%` end-of-line markers from output produced at a different width. Full-screen programs redraw normally.
297
+ - Remote exec commands assume a POSIX-compatible login shell (bash, zsh, dash, ksh); fish as login shell may break
298
+ Git commands with unusual file names.
299
+ - SSH certificate host keys (`@cert-authority`) are not supported. SSH passwords are only used once, to install a
300
+ key; hosts that refuse public-key logins entirely cannot be used.
301
+ - No local PTY: projects on "this server" support file operations only. Git and terminals require SSH under a separate workspace account.
302
+ - File names that are not valid UTF-8 are displayed with replacement characters and cannot be opened.
303
+ - Directory listings beyond `MAX_DIR_ENTRIES` are truncated; there is no file search across the tree yet.
304
+
305
+ ## Security upgrade behavior
306
+
307
+ See [security-upgrade.md](security-upgrade.md) for deployment migration and manual checks. Sessions use random opaque tokens with only SHA-256 token hashes persisted in state. Logout remains effective across restart. Old signed cookies are rejected. Idle/absolute limits default to 30 minutes/eight hours; activity persistence is coalesced to 15 seconds. Password changes and sign-out-all stop app-managed terminals.
308
+
309
+ Filesystem primitives are wrapped in administrator policy checks, so creation, legacy project access, browsing, reads, downloads, and mutations enforce canonical permitted roots. Backend state, the deployment directory, `.ssh` and configured local key-file paths are excluded. Git and terminals are SSH-only to avoid running repository programs as the backend account. Shell permissions still require OS account isolation; workspace roots are not a shell sandbox.
310
+
311
+ AI commit generation is off by default. Enabling it permits text-only Claude with tools, MCP servers, hooks/discovery, and persistence disabled. Prompts go through stdin, never process arguments. Unrestricted fallbacks are unsupported; raw CLI errors are neither logged nor returned.
@@ -0,0 +1,141 @@
1
+ # Configuration
2
+
3
+ The app can start without settings, but administrator-configured roots are required before opening projects. Machines, keys, projects, and the password are set up in the
4
+ browser and stored in `DATA_DIR`. Environment variables (an optional `.env` next to `package.json`, loaded with Node's
5
+ `--env-file-if-exists`) define process-level defaults and workspace access policy. Nothing is exposed to the browser bundle — there are no
6
+ `VITE_` variables. Invalid values stop the server with a list of every problem.
7
+
8
+ Start from [`.env.example`](../.env.example) if you need overrides.
9
+
10
+ ## First run
11
+
12
+ `npm start` (or `npm run dev`) prints a one-time link such as:
13
+
14
+ ```text
15
+ First-time setup — open this one-time link to create your password:
16
+ ➜ http://localhost:4280/setup#token=…
17
+ ```
18
+
19
+ The token is also written to `DATA_DIR/setup-token`, which is useful when the server runs as a service
20
+ (`cat data/setup-token`). It stops working once the password exists. Opening `/setup` without the link asks for the
21
+ token.
22
+
23
+ Forgot the password? Stop the server, run `npm run reset-password`, and start it again. A new setup link is printed;
24
+ machines and projects are kept, and every session is signed out.
25
+
26
+ ## Data directory
27
+
28
+ | Path | Contents |
29
+ | ---------------------- | ------------------------------------------------------------ |
30
+ | `state.json` | Password hash (scrypt), hosts, projects, hashed login sessions |
31
+ | `keys/<hostId>` | Private keys generated or imported in the UI |
32
+ | `setup-token` | Only until setup is complete |
33
+
34
+ The directory is created `0700` and files `0600`; looser permissions on an existing directory are tightened at
35
+ start. It is gitignored. Back it up like you would `~/.ssh`. Changing the password revokes prior sessions; the initiating browser gets a fresh cookie. Legacy `session-secret` files are ignored.
36
+
37
+ ## Environment variables
38
+
39
+ ### HTTP server
40
+
41
+ | Variable | Default | Notes |
42
+ | ----------------- | ----------- | ------------------------------------------------------------------------------------------------------- |
43
+ | `HOST` | `127.0.0.1` | Only `127.0.0.1` or `::1`; publish through `tailscale serve`. |
44
+ | `PORT` | `4280` | Also used by the Vite dev proxy. |
45
+ | `LOG_LEVEL` | `info` | `fatal` … `trace`, or `silent`. Logs are structured JSON (pino). |
46
+ | `TRUST_PROXY` | `true` | Trusts `X-Forwarded-*` **from loopback only** (`tailscale serve`), for the real host, scheme, and client IP. |
47
+ | `ALLOWED_ORIGINS` | — | Extra origins for state-changing requests and WebSockets, comma-separated. Not needed for `localhost`, IP addresses, or `*.ts.net` names (same-origin requests there are accepted automatically). Only localhost and `*.ts.net` origins are accepted. |
48
+ | `PUBLIC_URL` | — | Public `https://` address behind a Cloudflare Tunnel. Always an allowed origin; the setup link is also printed with it. |
49
+ | `CLOUDFLARE_TUNNEL_TOKEN` | — | Used only by `npm run start:tunnel` (passed to `cloudflared`, never to the app server). See [deployment.md](deployment.md#cloudflare-tunnel). |
50
+ | `STATIC_DIR` | `dist` if built | Directory with the built frontend. |
51
+ | `DATA_DIR` | `./data` | See above. `~` expands. |
52
+
53
+ ### Sessions
54
+
55
+ | Variable | Default | Notes |
56
+ | ------------------- | ------- | ------------------------------------------------------------------------------ |
57
+ | `SESSION_TTL_HOURS` | `8` | Absolute session lifetime; maximum 24 hours. |
58
+ | `SESSION_IDLE_MINUTES` | `30` | Inactivity timeout; maximum 120 minutes. Polls, output and ping/pong do not extend it. |
59
+ | `COOKIE_SECURE` | `auto` | `auto` = `Secure` over HTTPS; `false` is rejected in production. |
60
+
61
+ ### Workspace policy and AI
62
+
63
+ | Variable | Default | Notes |
64
+ | --- | --- | --- |
65
+ | `LOCAL_WORKSPACE_ROOTS` | `[]` | JSON array of absolute local paths. Local workspaces support files only. |
66
+ | `SSH_WORKSPACE_ROOTS` | `[]` | JSON array of absolute paths on SSH hosts; applies across all configured hosts. |
67
+ | `AI_COMMIT_ENABLED` | `false` | Opt in to sending diffs to an AI CLI for commit messages: the first of `codex` or `claude` in OpenCodeCommit's `backend-order` (`~/.config/opencodecommit/config.toml`). Codex runs `exec` with a read-only sandbox and no user config; Claude runs text-only with tools disabled. Each uses the server user's own CLI login. |
68
+
69
+ Example: `SSH_WORKSPACE_ROOTS='["/home/dev/projects"]'`. Browser requests cannot change this policy. The picker starts at these roots. Backend state, deployment files, standard credential directories, configured key-file paths, and OS pseudo-filesystems are protected locally. Project roots are not shell sandboxes; use separate OS accounts and permissions. See [deployment](deployment.md).
70
+
71
+ ### SSH
72
+
73
+ | Variable | Default | Notes |
74
+ | --------------------------- | -------------------- | ----------------------------------------------------------------------- |
75
+ | `SSH_KNOWN_HOSTS_PATH` | `~/.ssh/known_hosts` | Consulted when adding a host: matching keys are recognized as trusted, conflicting ones are refused. |
76
+ | `SSH_READY_TIMEOUT_MS` | `20000` | Handshake timeout. |
77
+ | `SSH_KEEPALIVE_INTERVAL_MS` | `15000` | SSH keepalives; 3 missed keepalives drop the connection. |
78
+ | `SSH_AUTH_SOCK` | (inherited) | Enables "Use ssh-agent" in the UI. |
79
+
80
+ ### Terminals and limits
81
+
82
+ | Variable | Default | Notes |
83
+ | --------------------------------- | ---------------- | ----------------------------------------------------------- |
84
+ | `TERMINAL_TERM` | `xterm-256color` | `$TERM` for remote shells. |
85
+ | `TERMINAL_MAX_SESSIONS` | `10` | Concurrent shells across all projects (one SSH connection each). |
86
+ | `TERMINAL_REPLAY_BUFFER_BYTES` | `524288` | Recent output kept per session for re-attaching browsers. |
87
+ | `TERMINAL_ORPHAN_TIMEOUT_MINUTES` | `0` | A session with no connected browser for this long is terminated. `0` keeps running shells until their tab is closed (exited ones are still cleaned up after 10 minutes). |
88
+ | `MAX_FILE_BYTES` | `2097152` | Larger files are not loaded into the editor (also the save limit). |
89
+ | `MAX_IMAGE_BYTES` | `20971520` | Larger images are not shown in the image viewer (downloads and video are not limited). |
90
+ | `MAX_DIFF_BYTES` | `4194304` | Diffs are truncated beyond this (and flagged in the UI). |
91
+ | `MAX_DIR_ENTRIES` | `5000` | Directory listings are truncated beyond this. |
92
+
93
+ Variables from earlier versions (`AUTH_PASSWORD_HASH`, `SESSION_SECRET`, `WORKSPACE_*`, `SSH_HOST`, `SSH_USERNAME`,
94
+ `SSH_PRIVATE_KEY_PATH`, …) are ignored; set those things up in the UI.
95
+
96
+ ## Connecting a machine
97
+
98
+ **Projects → Connect a machine** walks through four steps:
99
+
100
+ 1. **Machine** — host name, MagicDNS name, or IP; SSH port; username.
101
+ 2. **Verify** — the server fetches the host key (without sending any credentials) and shows its SHA256 fingerprint.
102
+ If `known_hosts` on the server already trusts it, that is shown. Otherwise compare it on the machine itself:
103
+ ```sh
104
+ ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
105
+ ```
106
+ A key that conflicts with `known_hosts` cannot be trusted. Once trusted, the key is pinned: a different key later
107
+ is refused until you re-verify it under the host's settings.
108
+ 3. **Sign in**:
109
+ - *Password* (default): type your SSH password once. Over the already-verified connection, Remote Workspace signs
110
+ in (password or keyboard-interactive, as macOS uses), generates a dedicated ed25519 key, appends its public half
111
+ to `~/.ssh/authorized_keys` (creating `~/.ssh` 0700 / the file 0600 if needed, never duplicating it), and from
112
+ then on connects with that key. The password is used only for that one connection: it is never stored, logged,
113
+ or sent back to the browser. The host must allow public-key logins (OpenSSH does by default).
114
+
115
+ Under "Use an SSH key instead":
116
+ - *Generate a key, add it myself*: a dedicated ed25519 key; the next step shows the one-line command that adds
117
+ the public key to `~/.ssh/authorized_keys`. For hosts that do not accept passwords.
118
+ - *Paste an existing private key*: stored in `DATA_DIR/keys`, never shown again. Passphrase-protected keys are not
119
+ supported.
120
+ - *Key file on the server*: e.g. `~/.ssh/id_ed25519` of the user running Remote Workspace (read at connect time).
121
+ - *ssh-agent*: the agent available to the server process.
122
+ 4. **Connect** — tests a real connection and reports authentication or network problems.
123
+
124
+ Then pick a project folder. Add more projects on the same machine with **Add project** on its card.
125
+
126
+ Tip: restrict a generated key on the machine by prefixing its `authorized_keys` line with
127
+ `from="<server's Tailscale IP>"`.
128
+
129
+ ### What runs on the remote machine
130
+
131
+ - **Files**: the SFTP subsystem (enabled by default in OpenSSH).
132
+ - **Git**: `git` must be on the `PATH` of non-interactive SSH commands. Commands run through your login shell as
133
+ `cd -- '<root>' && exec env GIT_OPTIONAL_LOCKS=0 git ...` with every argument single-quoted, which assumes a
134
+ POSIX-compatible login shell (bash, zsh, dash, ksh).
135
+ - **Terminals**: each terminal is its own SSH connection running `cd -- '<root>'; exec "$SHELL" -l` with a PTY
136
+ (`TERMINAL_TERM`), i.e. a normal interactive login shell started in the project folder. Tools such as `claude` and
137
+ `codex` use whatever is installed and configured for that user.
138
+
139
+ ### Projects on the server itself
140
+
141
+ "Open a folder on this server" supports file operations inside `LOCAL_WORKSPACE_ROOTS`. For Git and terminals, add an SSH host using a separate OS account that cannot access backend secrets. Repository programs must never run under the backend service account.
@@ -0,0 +1,117 @@
1
+ # Deployment
2
+
3
+ Remote Workspace is a single-user remote shell application. Deploy it privately through Tailscale Serve:
4
+
5
+ ```text
6
+ phone/laptop → Tailscale access policy → Serve HTTPS → 127.0.0.1:4280 → SSH as a workspace user
7
+ ```
8
+
9
+ Tailscale checks who can reach the application. The app password checks who can operate it. File APIs check administrator-configured project roots. The SSH account's OS permissions control the shell; project roots are not a shell sandbox.
10
+
11
+ ## Account and directory separation
12
+
13
+ Run the backend under a dedicated account, such as `rw`, with no sudo privileges. SSH hosts must use a different workspace account, such as `dev`, which cannot read the backend's `DATA_DIR`, deployment configuration, or credentials. Use this separation even when SSH targets the same physical machine. Do not SSH back into the backend's service account.
14
+
15
+ Keep application code/configuration outside project roots, owned by the deployment administrator and not writable by workspace users. Use managed, dedicated SSH keys. Do not attach a general-purpose personal SSH agent to the service. Restrict the backend's tailnet access to the SSH hosts it needs.
16
+
17
+ Local projects support files only. Git and terminals require SSH: repository hooks, filters, and helpers must not execute with the backend's identity. OS isolation also protects against filesystem races and hard links, which path checks alone cannot make into a complete sandbox against a hostile local process.
18
+
19
+ ## Configure and build
20
+
21
+ Requirements: Node.js 24+, npm, Tailscale on the server and clients, HTTPS enabled for the tailnet, and SSH/SFTP/Git on workspace hosts.
22
+
23
+ Create a private `.env` beside `package.json`:
24
+
25
+ ```dotenv
26
+ HOST=127.0.0.1
27
+ PORT=4280
28
+ DATA_DIR=/var/lib/remote-workspace
29
+ SSH_WORKSPACE_ROOTS='["/home/dev/projects"]'
30
+ LOCAL_WORKSPACE_ROOTS='[]'
31
+ SESSION_TTL_HOURS=8
32
+ SESSION_IDLE_MINUTES=30
33
+ ```
34
+
35
+ The root arrays are administrator policy, not browser-editable settings. Paths in `SSH_WORKSPACE_ROOTS` apply on every SSH host. Choose dedicated project directories; no roots are allowed by default. `DATA_DIR`, the application deployment directory, `.ssh` directories, and configured backend key-file paths cannot be opened through local file APIs.
36
+
37
+ ```sh
38
+ npm ci
39
+ npm run build
40
+ npm run serve
41
+ ```
42
+
43
+ Open the one-time setup link printed on the server to set the app password. The setup token is also saved at `DATA_DIR/setup-token`; do not share it. Connect a host, verify its key fingerprint, and choose a permitted folder.
44
+
45
+ ## Run as a service on Linux
46
+
47
+ Create the service account and directories through your system administration process. The `rw` account needs read access to the deployment and write access to its private state directory.
48
+
49
+ Example `/etc/systemd/system/remote-workspace.service`:
50
+
51
+ ```ini
52
+ [Unit]
53
+ Description=Remote Workspace
54
+ After=network-online.target tailscaled.service
55
+ Wants=network-online.target
56
+
57
+ [Service]
58
+ Type=simple
59
+ User=rw
60
+ WorkingDirectory=/opt/remote-workspace
61
+ Environment=NODE_ENV=production
62
+ Environment=DATA_DIR=/var/lib/remote-workspace
63
+ StateDirectory=remote-workspace
64
+ StateDirectoryMode=0700
65
+ ExecStart=/usr/bin/node --env-file-if-exists=/opt/remote-workspace/.env server/src/main.ts
66
+ Restart=on-failure
67
+ RestartSec=3
68
+ NoNewPrivileges=true
69
+ PrivateTmp=true
70
+ ProtectSystem=strict
71
+ ProtectHome=true
72
+ ReadOnlyPaths=/opt/remote-workspace
73
+ UMask=0077
74
+
75
+ [Install]
76
+ WantedBy=multi-user.target
77
+ ```
78
+
79
+ `StateDirectory` remains writable. This example uses SSH projects; explicitly grant narrowly scoped filesystem access if enabling local projects. Keep the SSH workspace account separate from `rw`. On macOS use a service/LaunchDaemon with a dedicated service identity; a LaunchAgent under your everyday account does not provide account isolation.
80
+
81
+ ## Publish privately
82
+
83
+ ```sh
84
+ tailscale serve --bg 4280
85
+ tailscale serve status
86
+ ```
87
+
88
+ Restrict access to this machine's HTTPS port to your identity/devices in the tailnet policy. Open the private `https://<machine>.<tailnet>.ts.net` URL from a permitted Tailscale device. Serve supports WebSockets.
89
+
90
+ Do not enable Funnel or port forwarding. `HOST` rejects wildcard/external binds, so the only ways in are Tailscale Serve and the optional Cloudflare Tunnel below.
91
+
92
+ ## Cloudflare Tunnel
93
+
94
+ To also reach the app from devices outside the tailnet, publish it through a Cloudflare Tunnel. In Cloudflare Zero Trust, create a tunnel whose public hostname maps to `http://localhost:4280`, then add to `.env`:
95
+
96
+ ```dotenv
97
+ PUBLIC_URL=https://remote.example.com
98
+ CLOUDFLARE_TUNNEL_TOKEN=...
99
+ ```
100
+
101
+ `npm run start:tunnel` builds, starts the server, waits until it is healthy, then runs `cloudflared` (the token is never passed to the app server or put on a command line). Tailscale Serve keeps working alongside it.
102
+
103
+ The tunnel hostname is on the public internet, so the app password would be its only gate. Put a **Cloudflare Access** application with an allow policy for your identity (email OTP or SSO) in front of the hostname, so requests are rejected at Cloudflare's edge before they reach the app.
104
+
105
+ A `*.ts.net` Host header is not proof of Tailscale identity. The network boundary comes from the deployed Serve configuration and access policy, not header matching.
106
+
107
+ ## Sessions and shutdown
108
+
109
+ Run a single backend process per `DATA_DIR`; do not share the JSON store between replicas.
110
+
111
+ Sessions expire after eight hours or 30 minutes of inactivity by default. Pointer/keyboard activity, authenticated mutations and terminal input extend inactivity; background polling, output and ping/pong do not. Session activity writes are coalesced to 15 seconds, so a restart can shorten the idle window by up to 15 seconds.
112
+
113
+ Logout disconnects that login's sockets immediately. Detached shells remain available for the configured reconnect window (30 minutes by default). Password changes and **Sign out all devices** revoke sessions and terminate app-managed terminals. Detached or independently launched processes may continue and require OS-level management.
114
+
115
+ A backend restart ends terminal sessions. Valid login sessions persist; revoked sessions remain revoked. Stop the server before `npm run reset-password`; the command clears all login sessions and keeps hosts/projects.
116
+
117
+ For migration and verification, see [Security upgrade](security-upgrade.md).
@@ -0,0 +1,35 @@
1
+ # Security upgrade
2
+
3
+ ## Before restarting an existing installation
4
+
5
+ 1. Back up `DATA_DIR` securely. Stop the old backend and any public tunnel. Remove its Cloudflare public route, Tailscale Funnel exposure, and port forwarding if present. The application cannot remove external hosting configuration for you.
6
+ 2. Run the backend under a dedicated OS account. Move its state/configuration outside workspace directories and ensure SSH users cannot read or write them. SSH back to the same machine only using a different, unprivileged workspace account. Do not give workspace users sudo access to backend secrets.
7
+ 3. Remove `PUBLIC_URL` and tunnel tokens from the service environment. Set `HOST=127.0.0.1`, `SESSION_TTL_HOURS=8`, and `SESSION_IDLE_MINUTES=30`. Custom public origins and non-loopback binds are rejected. Remove old `SESSION_TTL_HOURS=168` overrides.
8
+ 4. Set `SSH_WORKSPACE_ROOTS` and/or `LOCAL_WORKSPACE_ROOTS` to JSON arrays of absolute project directories. Empty arrays deny access. SSH roots apply across configured hosts. Local projects are now file-only; add an SSH connection under the workspace account for Git and terminals.
9
+ 5. Build/restart, configure Tailscale Serve, and restrict its access policy to your identity/devices. Verify outside-tailnet access fails. Existing hosts/projects remain stored, but projects outside current policy cannot be used. The picker now starts at permitted roots.
10
+ 6. Existing signed cookies are rejected on upgrade; sign in again. Successful login upgrades legacy scrypt hashes automatically. The obsolete `session-secret` file is ignored and may be removed after migration. Never restore an old state backup over a running deployment: backups can contain previously valid session records. After restoring state, reset the password to clear sessions before exposing the service.
11
+ 7. AI generation is disabled by default. If required, enable `AI_COMMIT_ENABLED=true` and install/authenticate a Claude CLI supporting the shipped restrictive flags. Enabling it is the consent: the sparkle button then sends the diff without a further prompt. Codex/OpenCode fallbacks are disabled; unsupported Claude versions fail closed. Provider configuration and the CLI binary are trusted deployment components.
12
+
13
+ If compromise is suspected, revoke/replace the SSH keys on every destination host, not just in the UI. Deleting a host in the UI does not remove its authorized key from that host. Also rotate other credentials readable by the old backend/SSH accounts. A password change cannot recover an already stolen SSH key.
14
+
15
+ ## Automated checks
16
+
17
+ ```sh
18
+ npm run build
19
+ npm test
20
+ ```
21
+
22
+ Regression coverage includes local credential retrieval, protected symlinks across file operations, legacy project roots, revoked-cookie replay after restart, idle/absolute session expiry, push WebSocket revocation, post-revocation input, concurrent authentication limits, legacy hash upgrades, and restricted AI invocation without prompts in process arguments.
23
+
24
+ Real SSH adapter tests remain opt-in using `scripts/test-sshd.sh`; see the README.
25
+
26
+ ## Manual checks
27
+
28
+ - From a permitted Tailscale device, sign in, connect an SSH host, and open a project inside its configured root. Read/edit files and use Git/terminals. With local projects, confirm Source Control explains that SSH is required.
29
+ - Open the folder picker: only permitted roots are shown. Enter an unapproved path, the deployment directory, DATA_DIR, or an alias to one of them; access must fail. Attempts to change an existing project to a protected root must also fail.
30
+ - Sign in on two browsers. Log out on one; its open terminal sockets must disconnect immediately while the other login remains valid. Restart the backend and confirm the logged-out browser remains signed out.
31
+ - In Settings, submit an incorrect password to **Sign out all devices**; nothing should be revoked. Submit the correct password; both browsers must lose access, and app-managed terminals must stop.
32
+ - Change the password while another browser is connected. The other browser loses access and existing app-managed terminals stop. The initiating browser receives a fresh session cookie.
33
+ - For timeout checks in a temporary installation, set `SESSION_IDLE_MINUTES=1` and a short fractional `SESSION_TTL_HOURS`. Background polls and continuous terminal output must not keep a login alive. Real user input should extend idle time, but cannot extend the absolute deadline.
34
+ - If AI is enabled, verify Generate sends only the selected repository's diff. Inspect the restricted invocation using a test/stub CLI rather than sending private code during testing. Failed CLI output must not reveal prompts or secrets in HTTP errors or logs.
35
+ - Disconnect Tailscale on a separate client and try the remote URL. Verify access fails. This deployment check cannot be replaced by unit tests.