offsite 0.0.17 → 0.0.19

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 (276) hide show
  1. package/apps/server/dist/main.mjs +289 -158
  2. package/apps/server/dist/main.mjs.map +1 -1
  3. package/apps/web/dist/assets/HugeiconsIcon-B46TDTdz.js +1 -0
  4. package/apps/web/dist/assets/angular-html-BswFT_28.js +1 -0
  5. package/apps/web/dist/assets/angular-html-DOLkzBtu.js +1 -0
  6. package/apps/web/dist/assets/angular-ts-DOMhGxLQ.js +1 -0
  7. package/apps/web/dist/assets/{apl-bz_iDiNf.js → apl-Dio8Ke0X.js} +1 -1
  8. package/apps/web/dist/assets/astro-CN6YWUG3.js +1 -0
  9. package/apps/web/dist/assets/bat-C7sJWglS.js +1 -0
  10. package/apps/web/dist/assets/{bat-qdxAdBWQ.js → bat-HFWzIrao.js} +1 -1
  11. package/apps/web/dist/assets/{bibtex-Ci_nEsc7.js → bibtex-Conh3HYz.js} +1 -1
  12. package/apps/web/dist/assets/bibtex-DUQXB5kJ.js +1 -0
  13. package/apps/web/dist/assets/blade-BrDpNfUX.js +1 -0
  14. package/apps/web/dist/assets/bsl-gRq8cI6V.js +1 -0
  15. package/apps/web/dist/assets/c-Cz4nF6n_.js +1 -0
  16. package/apps/web/dist/assets/c-SSSlmE39.js +1 -0
  17. package/apps/web/dist/assets/cairo-D66nqRlU.js +1 -0
  18. package/apps/web/dist/assets/{chapel-DUoqr6M4.js → chapel-C1sUNn9S.js} +1 -1
  19. package/apps/web/dist/assets/clojure-CAE6QLVB.js +1 -0
  20. package/apps/web/dist/assets/{clojure-DqKBuwfJ.js → clojure-zIjcJonk.js} +1 -1
  21. package/apps/web/dist/assets/cmake-Cpsd-0Y4.js +1 -0
  22. package/apps/web/dist/assets/{cmake-Bj61d0ZC.js → cmake-T_kMSWuN.js} +1 -1
  23. package/apps/web/dist/assets/{cobol-Cn0D9nVy.js → cobol-BvqUwMCV.js} +1 -1
  24. package/apps/web/dist/assets/{coffee-C1tCcS8h.js → coffee-BSYIIMkB.js} +1 -1
  25. package/apps/web/dist/assets/coffee-NEqv5HL5.js +1 -0
  26. package/apps/web/dist/assets/cpp-BDT6bThX.js +1 -0
  27. package/apps/web/dist/assets/cpp-vothkh01.js +1 -0
  28. package/apps/web/dist/assets/{crystal-DF-BMake.js → crystal-DEF7AEJQ.js} +1 -1
  29. package/apps/web/dist/assets/{csharp-dmMxLVLW.js → csharp-B3DbjJyj.js} +1 -1
  30. package/apps/web/dist/assets/csharp-CFKDkFDZ.js +1 -0
  31. package/apps/web/dist/assets/css-BGIxQoYs.js +1 -0
  32. package/apps/web/dist/assets/css-DgaLhXQH.js +1 -0
  33. package/apps/web/dist/assets/{csv-Dx-8-gkx.js → csv-B_R7vXwK.js} +1 -1
  34. package/apps/web/dist/assets/csv-k4CB9lhx.js +1 -0
  35. package/apps/web/dist/assets/dart-DjhkpiWP.js +1 -0
  36. package/apps/web/dist/assets/{dart-CHZY9Xhz.js → dart-_dH3dQdM.js} +1 -1
  37. package/apps/web/dist/assets/{diff-woXpYk--.js → diff-CR4ZX0DC.js} +1 -1
  38. package/apps/web/dist/assets/diff-eeGLjE2V.js +1 -0
  39. package/apps/web/dist/assets/dist-BJ6NAVkJ.js +153 -0
  40. package/apps/web/dist/assets/dist-BlYvnVje.js +1 -0
  41. package/apps/web/dist/assets/{docker-IyjqRm3v.js → docker-CAzcIhYn.js} +1 -1
  42. package/apps/web/dist/assets/docker-D0LTq72f.js +1 -0
  43. package/apps/web/dist/assets/edge-B_SBzXGF.js +1 -0
  44. package/apps/web/dist/assets/{elixir-K6buEKBc.js → elixir-BL8v4QDr.js} +1 -1
  45. package/apps/web/dist/assets/elixir-BN3BkYei.js +1 -0
  46. package/apps/web/dist/assets/{elm-B78wD7Un.js → elm-CC1TmzeR.js} +1 -1
  47. package/apps/web/dist/assets/{erb-DuhNLWPu.js → erb-BjlLGk-_.js} +1 -1
  48. package/apps/web/dist/assets/erlang-CCXss5H6.js +1 -0
  49. package/apps/web/dist/assets/erlang-ir39Pet8.js +1 -0
  50. package/apps/web/dist/assets/fortran-fixed-form-1cK5gXa1.js +1 -0
  51. package/apps/web/dist/assets/fortran-free-form-C5q_0aPq.js +1 -0
  52. package/apps/web/dist/assets/{fortran-free-form-CYNrtFtB.js → fortran-free-form-uHOymLAb.js} +1 -1
  53. package/apps/web/dist/assets/fsharp-C37UASp4.js +1 -0
  54. package/apps/web/dist/assets/fsharp-SO2Zcqp5.js +1 -0
  55. package/apps/web/dist/assets/gdresource-LxjHb83i.js +1 -0
  56. package/apps/web/dist/assets/gdscript-CJEqcM-5.js +1 -0
  57. package/apps/web/dist/assets/{gdscript-DYvRD3hg.js → gdscript-DJFPOtzS.js} +1 -1
  58. package/apps/web/dist/assets/gdshader-BNp4G147.js +1 -0
  59. package/apps/web/dist/assets/{gdshader-CBce3t8t.js → gdshader-kiBtQlv1.js} +1 -1
  60. package/apps/web/dist/assets/git-commit-BAuDFD-1.js +1 -0
  61. package/apps/web/dist/assets/git-commit-DaNUDv1O.js +1 -0
  62. package/apps/web/dist/assets/{git-rebase-C6n0imm6.js → git-rebase-Bh7mDoAc.js} +1 -1
  63. package/apps/web/dist/assets/git-rebase-qxk4jQ_Z.js +1 -0
  64. package/apps/web/dist/assets/{glimmer-js-B65Nng8o.js → glimmer-js-CIdbWayl.js} +1 -1
  65. package/apps/web/dist/assets/{glimmer-ts-Cme47tem.js → glimmer-ts-B16xCo2k.js} +1 -1
  66. package/apps/web/dist/assets/glsl-CaPTrB3a.js +1 -0
  67. package/apps/web/dist/assets/glsl-D01ELkOo.js +1 -0
  68. package/apps/web/dist/assets/go-CC6EVc1J.js +1 -0
  69. package/apps/web/dist/assets/{go-rLFTqkRN.js → go-CFMhVTkq.js} +1 -1
  70. package/apps/web/dist/assets/graphql-BZEhxNwM.js +1 -0
  71. package/apps/web/dist/assets/graphql-DEIChqxY.js +1 -0
  72. package/apps/web/dist/assets/{groovy-CacY0gHj.js → groovy-Dj7WCBJM.js} +1 -1
  73. package/apps/web/dist/assets/groovy-_MokPXAr.js +1 -0
  74. package/apps/web/dist/assets/{hack-W5aeWZGp.js → hack-C30D-q0p.js} +1 -1
  75. package/apps/web/dist/assets/haml-BU6KMePS.js +1 -0
  76. package/apps/web/dist/assets/haml-C1zHJAQt.js +1 -0
  77. package/apps/web/dist/assets/handlebars-WZCg7K7Q.js +1 -0
  78. package/apps/web/dist/assets/{handlebars-CYz9msjm.js → handlebars-g-3gLrXt.js} +1 -1
  79. package/apps/web/dist/assets/haxe-B0BMDyun.js +1 -0
  80. package/apps/web/dist/assets/{haxe-C8oCnwJJ.js → haxe-CD8O8Ul0.js} +1 -1
  81. package/apps/web/dist/assets/hlsl-DQJgUA8P.js +1 -0
  82. package/apps/web/dist/assets/{hlsl-Cvrh5tZx.js → hlsl-ajL2FB-w.js} +1 -1
  83. package/apps/web/dist/assets/html-BCy9P6D2.js +1 -0
  84. package/apps/web/dist/assets/html-DSw1lh5G.js +1 -0
  85. package/apps/web/dist/assets/{html-derivative-fPnJ7c-5.js → html-derivative-DyzJkWO6.js} +1 -1
  86. package/apps/web/dist/assets/html-derivative-ekTk9Unt.js +1 -0
  87. package/apps/web/dist/assets/{http-DIR9LW29.js → http-BjrBtiM6.js} +1 -1
  88. package/apps/web/dist/assets/{hurl-73h4sQYH.js → hurl-B4P9s9G3.js} +1 -1
  89. package/apps/web/dist/assets/hxml-DPF7XkXa.js +1 -0
  90. package/apps/web/dist/assets/image-viewer-DnE3hPpr.js +1 -0
  91. package/apps/web/dist/assets/index-L4LBYfU2.js +783 -0
  92. package/apps/web/dist/assets/index-V87-gz8B.css +2 -0
  93. package/apps/web/dist/assets/{ini-B5eOa1yu.js → ini-0B7NLFlx.js} +1 -1
  94. package/apps/web/dist/assets/ini-DiZ1IqbV.js +1 -0
  95. package/apps/web/dist/assets/java-BtIQNnN0.js +1 -0
  96. package/apps/web/dist/assets/java-_ATy9zCa.js +1 -0
  97. package/apps/web/dist/assets/javascript-BzbQS41l.js +1 -0
  98. package/apps/web/dist/assets/javascript-CpIGwZ_Y.js +1 -0
  99. package/apps/web/dist/assets/{jinja-wBZAPGc9.js → jinja-dRcm23Ea.js} +1 -1
  100. package/apps/web/dist/assets/{jison-bZuttet2.js → jison-D3aJooqo.js} +1 -1
  101. package/apps/web/dist/assets/json-B88Oqtu5.js +1 -0
  102. package/apps/web/dist/assets/json-C3WlssX3.js +1 -0
  103. package/apps/web/dist/assets/jsonc-BzJ54Uh_.js +1 -0
  104. package/apps/web/dist/assets/{jsonc-CYpm1nAK.js → jsonc-dcnCvL0G.js} +1 -1
  105. package/apps/web/dist/assets/jsx-C4yDKi0A.js +1 -0
  106. package/apps/web/dist/assets/jsx-D3KKoC5L.js +1 -0
  107. package/apps/web/dist/assets/jsx-runtime-D3jfb0Ew.js +1 -0
  108. package/apps/web/dist/assets/julia-C8a5hZkp.js +1 -0
  109. package/apps/web/dist/assets/julia-hqywDEUR.js +1 -0
  110. package/apps/web/dist/assets/just-CP_wDfXI.js +1 -0
  111. package/apps/web/dist/assets/{latex-DN5Fi2zg.js → latex-B_Ztlc7G.js} +1 -1
  112. package/apps/web/dist/assets/latex-Bn9nYtub.js +1 -0
  113. package/apps/web/dist/assets/{less-DVTAwKKz.js → less-B64L-FWb.js} +1 -1
  114. package/apps/web/dist/assets/less-CXhFgJ4v.js +1 -0
  115. package/apps/web/dist/assets/{liquid-DtPrOPBs.js → liquid-CQNtsgCr.js} +1 -1
  116. package/apps/web/dist/assets/log-Bu1ZtrH6.js +1 -0
  117. package/apps/web/dist/assets/{log-BNLmms1o.js → log-BvtJ4bSl.js} +1 -1
  118. package/apps/web/dist/assets/lua-DjuecEsk.js +1 -0
  119. package/apps/web/dist/assets/lua-fPRBWD-V.js +1 -0
  120. package/apps/web/dist/assets/make-B54cR2A1.js +1 -0
  121. package/apps/web/dist/assets/{make-Dixweg8N.js → make-URElk0GJ.js} +1 -1
  122. package/apps/web/dist/assets/{markdown-BYOwaDjH.js → markdown-CboqBxpY.js} +1 -1
  123. package/apps/web/dist/assets/markdown-CjQmuOi1.js +1 -0
  124. package/apps/web/dist/assets/marko-DPS0EkZ1.js +1 -0
  125. package/apps/web/dist/assets/mdc-C6srEd4p.js +1 -0
  126. package/apps/web/dist/assets/{nextflow-groovy-D7IRt6Pp.js → nextflow-groovy-C770ykRh.js} +1 -1
  127. package/apps/web/dist/assets/nextflow-groovy-D5vAge1Z.js +1 -0
  128. package/apps/web/dist/assets/nextflow-uA5IJerx.js +1 -0
  129. package/apps/web/dist/assets/{nginx-BlYeGp57.js → nginx-BxRBJ-Af.js} +1 -1
  130. package/apps/web/dist/assets/nim-DN3EGtL-.js +1 -0
  131. package/apps/web/dist/assets/nim-ZjzS1dcU.js +1 -0
  132. package/apps/web/dist/assets/objective-c-CsonrGpd.js +1 -0
  133. package/apps/web/dist/assets/{objective-c-D1A_Heim.js → objective-c-D_ECFp-D.js} +1 -1
  134. package/apps/web/dist/assets/ocaml-BuP2SoBQ.js +1 -0
  135. package/apps/web/dist/assets/{ocaml-O90oeIOV.js → ocaml-D6dNsUd0.js} +1 -1
  136. package/apps/web/dist/assets/org-BRAbLUOJ.js +1 -0
  137. package/apps/web/dist/assets/perl-Ciba4h2-.js +1 -0
  138. package/apps/web/dist/assets/{perl-BGPYGeVd.js → perl-sgZsTtaf.js} +1 -1
  139. package/apps/web/dist/assets/{php-kgT6t38x.js → php-D9QpVhjP.js} +1 -1
  140. package/apps/web/dist/assets/php-DBfnyu6d.js +1 -0
  141. package/apps/web/dist/assets/{postcss-BXeXVLqQ.js → postcss-D_Wz94rJ.js} +1 -1
  142. package/apps/web/dist/assets/postcss-DkKB82OS.js +1 -0
  143. package/apps/web/dist/assets/powershell-Blb2ISmZ.js +1 -0
  144. package/apps/web/dist/assets/{powershell-QtSnmXcu.js → powershell-CItYMEtV.js} +1 -1
  145. package/apps/web/dist/assets/preview-dialog-CApdSumg.js +273 -0
  146. package/apps/web/dist/assets/pug-C_nSP9Mg.js +1 -0
  147. package/apps/web/dist/assets/{pug-COTHnC13.js → pug-nGRwXpob.js} +1 -1
  148. package/apps/web/dist/assets/python-C5TF47hQ.js +1 -0
  149. package/apps/web/dist/assets/{python-gzcpVVnB.js → python-CzFU0dpx.js} +1 -1
  150. package/apps/web/dist/assets/{qml-DhqsM4c7.js → qml-BxleM7bJ.js} +1 -1
  151. package/apps/web/dist/assets/r-BXEss897.js +1 -0
  152. package/apps/web/dist/assets/r-DWzjseEo.js +1 -0
  153. package/apps/web/dist/assets/{raku-B3gFvitq.js → raku-BtFKomnU.js} +1 -1
  154. package/apps/web/dist/assets/raku-Cj6OV6qV.js +1 -0
  155. package/apps/web/dist/assets/{razor-BGH58TzE.js → razor-UAq-8THt.js} +1 -1
  156. package/apps/web/dist/assets/regexp-BWpGejPw.js +1 -0
  157. package/apps/web/dist/assets/regexp-wOX-4MEz.js +1 -0
  158. package/apps/web/dist/assets/rst-BCaXiUC4.js +1 -0
  159. package/apps/web/dist/assets/ruby-C4ARPOX3.js +1 -0
  160. package/apps/web/dist/assets/{ruby-DtfMo-6m.js → ruby-Dl3oLoVp.js} +1 -1
  161. package/apps/web/dist/assets/rust-Ch0zZBV0.js +1 -0
  162. package/apps/web/dist/assets/{rust-DpiIf5JO.js → rust-DBZE5Si3.js} +1 -1
  163. package/apps/web/dist/assets/{sas-DkQGY_o2.js → sas-BowjnAvi.js} +1 -1
  164. package/apps/web/dist/assets/scala-CTTBu_35.js +1 -0
  165. package/apps/web/dist/assets/{scala-BiFt_7mu.js → scala-o2NiCLJc.js} +1 -1
  166. package/apps/web/dist/assets/scss-CWs8DVSa.js +1 -0
  167. package/apps/web/dist/assets/scss-D3wBkj3d.js +1 -0
  168. package/apps/web/dist/assets/{sdbl-bTVj8UrX.js → sdbl-CpzYUp7e.js} +1 -1
  169. package/apps/web/dist/assets/sdbl-CyKdwm0B.js +1 -0
  170. package/apps/web/dist/assets/shaderlab-DY7g_Ava.js +1 -0
  171. package/apps/web/dist/assets/shellscript-CVTB3cr6.js +1 -0
  172. package/apps/web/dist/assets/shellscript-CqHdAlCp.js +1 -0
  173. package/apps/web/dist/assets/{shellsession-CT0a4IuI.js → shellsession-DDrivR0a.js} +1 -1
  174. package/apps/web/dist/assets/{soy-B3ufTOzS.js → soy-CUUUw2U6.js} +1 -1
  175. package/apps/web/dist/assets/sparql-Dy5Sx-zJ.js +1 -0
  176. package/apps/web/dist/assets/sql-CNu3Or2W.js +1 -0
  177. package/apps/web/dist/assets/sql-CfM2IJm3.js +1 -0
  178. package/apps/web/dist/assets/{stata-BYhfUPEu.js → stata-Dj4sbAEx.js} +1 -1
  179. package/apps/web/dist/assets/{stylus-B6D30XZt.js → stylus-LiTfbrWi.js} +1 -1
  180. package/apps/web/dist/assets/stylus-y-ZXgJGq.js +1 -0
  181. package/apps/web/dist/assets/{surrealql-UIZa84-V.js → surrealql-NoXzmj18.js} +1 -1
  182. package/apps/web/dist/assets/svelte-BaCIHHWd.js +1 -0
  183. package/apps/web/dist/assets/swift-CCLoYZtx.js +1 -0
  184. package/apps/web/dist/assets/{swift-CyEgAFGc.js → swift-DQ24oLw9.js} +1 -1
  185. package/apps/web/dist/assets/system-verilog-DFpyZzg3.js +1 -0
  186. package/apps/web/dist/assets/{system-verilog-Dh5ihWbf.js → system-verilog-Dp2k_mze.js} +1 -1
  187. package/apps/web/dist/assets/templ-BfgLc4ra.js +1 -0
  188. package/apps/web/dist/assets/tex-C9L8xJex.js +1 -0
  189. package/apps/web/dist/assets/tex-CNYz7bLJ.js +1 -0
  190. package/apps/web/dist/assets/tooltip-DZsSQhD8.js +1 -0
  191. package/apps/web/dist/assets/{ts-tags-Bk8_Hqg_.js → ts-tags-DLz2GTd3.js} +1 -1
  192. package/apps/web/dist/assets/tsx-BOvsFOI6.js +1 -0
  193. package/apps/web/dist/assets/tsx-CGosfAUg.js +1 -0
  194. package/apps/web/dist/assets/turtle-CQ9kcy0m.js +1 -0
  195. package/apps/web/dist/assets/{turtle-ByJddavk.js → turtle-CcN57yC0.js} +1 -1
  196. package/apps/web/dist/assets/twig-HaHkB3PH.js +1 -0
  197. package/apps/web/dist/assets/twig-lMQ09cjh.js +1 -0
  198. package/apps/web/dist/assets/typescript-Bb1J8qyy.js +1 -0
  199. package/apps/web/dist/assets/typescript-j_1H8WHN.js +1 -0
  200. package/apps/web/dist/assets/typst-DDNSzYFN.js +1 -0
  201. package/apps/web/dist/assets/{vb-DOwzaHZ0.js → vb-3nVziYZS.js} +1 -1
  202. package/apps/web/dist/assets/vb-CP6Ec8nh.js +1 -0
  203. package/apps/web/dist/assets/verilog-1j7BQk-h.js +1 -0
  204. package/apps/web/dist/assets/{verilog-B2gwz-sJ.js → verilog-kL8Dwv27.js} +1 -1
  205. package/apps/web/dist/assets/video-player-05lO0mz3.js +1416 -0
  206. package/apps/web/dist/assets/video-player-DGtpeSpK.js +1 -0
  207. package/apps/web/dist/assets/video-viewer-B404MUMw.js +1 -0
  208. package/apps/web/dist/assets/{vue-html-B42dVyQs.js → vue-html-CGMs_6qn.js} +1 -1
  209. package/apps/web/dist/assets/vue-qH43U_rv.js +1 -0
  210. package/apps/web/dist/assets/vue-vine-6XI2pIvQ.js +1 -0
  211. package/apps/web/dist/assets/xml-DuKfbPI6.js +1 -0
  212. package/apps/web/dist/assets/xml-WY0zc4PG.js +1 -0
  213. package/apps/web/dist/assets/xsl-CW58cerL.js +1 -0
  214. package/apps/web/dist/assets/{xsl-73EQy__K.js → xsl-Czhm44Ae.js} +1 -1
  215. package/apps/web/dist/assets/yaml-DDA_XMNu.js +1 -0
  216. package/apps/web/dist/assets/yaml-DijMHRDA.js +1 -0
  217. package/apps/web/dist/assets/{zig-CMLA9XwU.js → zig-B7sSDI6F.js} +1 -1
  218. package/apps/web/dist/assets/zig-cFafUZna.js +1 -0
  219. package/apps/web/dist/assets/zoomable-image-CjNpa0bY.js +41 -0
  220. package/apps/web/dist/assets/zoomable-image-CzRbnhdc.js +1 -0
  221. package/apps/web/dist/index.html +7 -2
  222. package/apps/web/dist/sw.js +1 -1
  223. package/package.json +1 -1
  224. package/apps/web/dist/assets/angular-html-DS1oV12F.js +0 -1
  225. package/apps/web/dist/assets/angular-ts-DGEt84_g.js +0 -1
  226. package/apps/web/dist/assets/astro-jXSlLJ7l.js +0 -1
  227. package/apps/web/dist/assets/blade-2sxYYh5A.js +0 -1
  228. package/apps/web/dist/assets/bsl-_VjlB9mv.js +0 -1
  229. package/apps/web/dist/assets/c-DapwzVu-.js +0 -1
  230. package/apps/web/dist/assets/cairo-DLTphjLi.js +0 -1
  231. package/apps/web/dist/assets/cpp-DxWN2Okg.js +0 -1
  232. package/apps/web/dist/assets/css-DO_8FP-m.js +0 -1
  233. package/apps/web/dist/assets/edge-D8r2HbS9.js +0 -1
  234. package/apps/web/dist/assets/erlang-Cphh6RMH.js +0 -1
  235. package/apps/web/dist/assets/fortran-fixed-form-DEKoE2YW.js +0 -1
  236. package/apps/web/dist/assets/fsharp-D13ZGOAj.js +0 -1
  237. package/apps/web/dist/assets/gdresource-xMC7jr7x.js +0 -1
  238. package/apps/web/dist/assets/git-commit-BSykSTBG.js +0 -1
  239. package/apps/web/dist/assets/glsl-DCAs0c4j.js +0 -1
  240. package/apps/web/dist/assets/graphql-CjoRmsAT.js +0 -1
  241. package/apps/web/dist/assets/haml-C_s1GJd7.js +0 -1
  242. package/apps/web/dist/assets/html-rJzVMoNs.js +0 -1
  243. package/apps/web/dist/assets/hxml-Dcm88srW.js +0 -1
  244. package/apps/web/dist/assets/index-CbDKWecy.js +0 -1206
  245. package/apps/web/dist/assets/index-aoUjY0qi.css +0 -2
  246. package/apps/web/dist/assets/java-CC9QxJEZ.js +0 -1
  247. package/apps/web/dist/assets/javascript-BhEdsWyv.js +0 -1
  248. package/apps/web/dist/assets/json-BwYVcFZr.js +0 -1
  249. package/apps/web/dist/assets/jsx-DZ0EGwxr.js +0 -1
  250. package/apps/web/dist/assets/julia-Bj20nWQB.js +0 -1
  251. package/apps/web/dist/assets/just-pKKGVoyp.js +0 -1
  252. package/apps/web/dist/assets/lua-C1ueigSQ.js +0 -1
  253. package/apps/web/dist/assets/marko-BAsjT454.js +0 -1
  254. package/apps/web/dist/assets/mdc-DwMa0Ya_.js +0 -1
  255. package/apps/web/dist/assets/nextflow-CSgcYZcx.js +0 -1
  256. package/apps/web/dist/assets/nim-DASYTjR5.js +0 -1
  257. package/apps/web/dist/assets/org-DSeAzk6D.js +0 -1
  258. package/apps/web/dist/assets/r-D-KnVREb.js +0 -1
  259. package/apps/web/dist/assets/regexp-BHxEHonG.js +0 -1
  260. package/apps/web/dist/assets/rst-UweowKJr.js +0 -1
  261. package/apps/web/dist/assets/scss-QYV6e_ks.js +0 -1
  262. package/apps/web/dist/assets/shaderlab-TOUzSsQk.js +0 -1
  263. package/apps/web/dist/assets/shellscript-CBTXJvxj.js +0 -1
  264. package/apps/web/dist/assets/sparql-D_iOobhT.js +0 -1
  265. package/apps/web/dist/assets/sql-BhGvXJN_.js +0 -1
  266. package/apps/web/dist/assets/svelte-SkphxuD6.js +0 -1
  267. package/apps/web/dist/assets/templ-C8T3Zgrx.js +0 -1
  268. package/apps/web/dist/assets/tex-Be-e7W9g.js +0 -1
  269. package/apps/web/dist/assets/tsx-B_hC-_lk.js +0 -1
  270. package/apps/web/dist/assets/twig-pKLKVHRj.js +0 -1
  271. package/apps/web/dist/assets/typescript-D8MumUKS.js +0 -1
  272. package/apps/web/dist/assets/typst-DCcUGqaw.js +0 -1
  273. package/apps/web/dist/assets/vue-B_0IsDtY.js +0 -1
  274. package/apps/web/dist/assets/vue-vine-CUms6qs_.js +0 -1
  275. package/apps/web/dist/assets/xml-Dh5mAVtG.js +0 -1
  276. package/apps/web/dist/assets/yaml-C5lWNsLB.js +0 -1
@@ -8,18 +8,19 @@ import os from "node:os";
8
8
  import { deleteSession, forkSession, getSessionMessages, getSubagentMessages, listSessions, query, renameSession } from "@anthropic-ai/claude-agent-sdk";
9
9
  import { execFile, spawn } from "node:child_process";
10
10
  import readline from "node:readline";
11
+ import { lstat, mkdir, open, readFile, readdir, readlink, stat, writeFile } from "node:fs/promises";
11
12
  import { z } from "zod";
12
13
  import { Command } from "@commander-js/extra-typings";
13
14
  import { setTimeout as setTimeout$1 } from "node:timers/promises";
14
15
  import { OpenCode } from "@opencode/client";
15
16
  import { ensure, headers } from "@opencode/client/service";
16
17
  import { and, eq, gt, inArray, lte, sql } from "drizzle-orm";
18
+ import { pathToFileURL } from "node:url";
17
19
  import { sumBy } from "es-toolkit";
18
20
  import { DatabaseSync } from "node:sqlite";
19
21
  import { drizzle } from "drizzle-orm/node-sqlite";
20
22
  import { migrate } from "drizzle-orm/node-sqlite/migrator";
21
23
  import { integer, snakeCase, text } from "drizzle-orm/sqlite-core";
22
- import { lstat, open, readFile, readdir, readlink, stat } from "node:fs/promises";
23
24
  import webPush from "web-push";
24
25
  import { promisify } from "node:util";
25
26
  import { spawn as spawn$1 } from "@lydell/node-pty";
@@ -376,17 +377,17 @@ function toUserInput(prompt, uuid, priority) {
376
377
  type: "user",
377
378
  message: {
378
379
  role: "user",
379
- content: [...prompt.images.map((image) => ({
380
+ content: [...prompt.text === "" ? [] : [{
381
+ type: "text",
382
+ text: prompt.text
383
+ }], ...prompt.images.map((image) => ({
380
384
  type: "image",
381
385
  source: {
382
386
  type: "base64",
383
387
  media_type: image.mediaType,
384
388
  data: image.data
385
389
  }
386
- })), ...prompt.text === "" ? [] : [{
387
- type: "text",
388
- text: prompt.text
389
- }]]
390
+ }))]
390
391
  },
391
392
  parent_tool_use_id: null,
392
393
  uuid,
@@ -398,13 +399,13 @@ function promptMessage(prompt, uuid) {
398
399
  type: "user",
399
400
  uuid,
400
401
  time: Date.now(),
401
- content: [...prompt.images.map((image) => ({
402
- type: "image",
403
- ...image
404
- })), ...prompt.text === "" ? [] : [{
402
+ content: [...prompt.text === "" ? [] : [{
405
403
  type: "text",
406
404
  text: prompt.text
407
- }]],
405
+ }], ...prompt.images.map((image) => ({
406
+ type: "image",
407
+ ...image
408
+ }))],
408
409
  parent: null
409
410
  };
410
411
  }
@@ -482,6 +483,23 @@ function isRecord(value) {
482
483
  return typeof value === "object" && value !== null && !Array.isArray(value);
483
484
  }
484
485
  //#endregion
486
+ //#region src/lib/images.ts
487
+ const extensions = {
488
+ "image/png": "png",
489
+ "image/jpeg": "jpg",
490
+ "image/gif": "gif",
491
+ "image/webp": "webp"
492
+ };
493
+ async function saveImage(sessionId, image) {
494
+ const extension = extensions[image.mediaType];
495
+ if (extension === void 0) throw new Error(`${image.mediaType} images are not supported`);
496
+ const directory = path.join(os.tmpdir(), "offsite", sessionId, "images");
497
+ await mkdir(directory, { recursive: true });
498
+ const file = path.join(directory, `${randomUUID()}.${extension}`);
499
+ await writeFile(file, Buffer.from(image.data, "base64"));
500
+ return file;
501
+ }
502
+ //#endregion
485
503
  //#region src/lib/codex/items.ts
486
504
  const statuses$1 = {
487
505
  inProgress: "running",
@@ -631,13 +649,24 @@ function toItems$1(turnId, item, parent, time) {
631
649
  }
632
650
  function userText$1(input) {
633
651
  switch (input.type) {
634
- case "text": return [input.text];
652
+ case "text": return [input.text.replaceAll(/\[Image: source: [^\]]+\]/g, "")];
635
653
  case "skill":
636
654
  case "mention": return [`$${input.name}`];
637
655
  case "image":
638
656
  case "localImage": return [];
639
657
  }
640
658
  }
659
+ async function imageInputs(sessionId, images) {
660
+ const files = await Promise.all(images.map((image) => saveImage(sessionId, image)));
661
+ return [...images.map((image) => ({
662
+ type: "image",
663
+ url: `data:${image.mediaType};base64,${image.data}`
664
+ })), ...files.map((file) => ({
665
+ type: "text",
666
+ text: `[Image: source: ${file}]`,
667
+ text_elements: []
668
+ }))];
669
+ }
641
670
  function userImages(input) {
642
671
  if (input.type !== "image") return [];
643
672
  const match = /^data:([^;,]+);base64,(.*)$/.exec(input.url);
@@ -823,11 +852,9 @@ const configSchema = z.strictObject({
823
852
  opencode: z.record(z.string(), modelSetting).default({})
824
853
  }).prefault({}),
825
854
  delivery: z.enum(["queue", "steer"]).default("steer"),
826
- autoResolve: z.strictObject({
827
- questions: z.number().positive().nullable().default(3),
828
- permissions: z.number().positive().nullable().default(1),
829
- permissionDecision: z.enum(["allow", "deny"]).default("allow")
830
- }).prefault({}),
855
+ autoSkipQuestionTimeout: z.number().positive().nullable().default(180),
856
+ autoPermissionMode: z.enum(["allow", "deny"]).default("allow"),
857
+ autoPermissionTimeout: z.number().positive().nullable().default(15),
831
858
  terminal: z.strictObject({
832
859
  shell: z.strictObject({
833
860
  macos: z.string().nullable().default(null),
@@ -914,20 +941,27 @@ function broadcastActivity() {
914
941
  });
915
942
  }
916
943
  function scheduleAutoResolve(sessionId, request) {
917
- if (request.kind === "plan") return;
918
- const settings = readConfig().autoResolve;
919
- const minutes = request.kind === "question" ? settings.questions : settings.permissions;
920
- if (minutes === null) return;
944
+ if (request.kind === "plan") return request;
945
+ const config = readConfig();
946
+ const seconds = request.kind === "question" ? config.autoSkipQuestionTimeout : config.autoPermissionTimeout;
947
+ if (seconds === null) return request;
948
+ const decision = request.kind === "question" ? "allow" : config.autoPermissionMode;
921
949
  setTimeout(async () => {
922
950
  const run = runs.get(sessionId);
923
951
  if (run === void 0) return;
924
952
  try {
925
- if (request.kind === "question") await run.respond(request.id, "allow", {});
926
- else await run.respond(request.id, readConfig().autoResolve.permissionDecision, null);
953
+ await run.respond(request.id, decision, request.kind === "question" ? {} : null);
927
954
  } catch (error) {
928
955
  console.warn(`could not auto-resolve ${request.id}: ${error}`);
929
956
  }
930
- }, minutes * 6e4);
957
+ }, seconds * 1e3);
958
+ return {
959
+ ...request,
960
+ autoResolve: {
961
+ at: Date.now() + seconds * 1e3,
962
+ decision
963
+ }
964
+ };
931
965
  }
932
966
  //#endregion
933
967
  //#region src/lib/codex/requests.ts
@@ -1257,11 +1291,12 @@ var CodexRun = class CodexRun {
1257
1291
  });
1258
1292
  return;
1259
1293
  }
1260
- const request = toRequest$1(String(id), method, params, this.items);
1261
- if (request === null) {
1294
+ const created = toRequest$1(String(id), method, params, this.items);
1295
+ if (created === null) {
1262
1296
  this.server.replyError(id, `offsite does not handle ${method}`);
1263
1297
  return;
1264
1298
  }
1299
+ const request = scheduleAutoResolve(this.sessionId, created);
1265
1300
  this.pending.set(request.id, {
1266
1301
  request,
1267
1302
  id,
@@ -1274,7 +1309,6 @@ var CodexRun = class CodexRun {
1274
1309
  request
1275
1310
  });
1276
1311
  broadcastActivity();
1277
- scheduleAutoResolve(this.sessionId, request);
1278
1312
  }
1279
1313
  async startTurn(prompt) {
1280
1314
  clearTimeout(this.idleTimer);
@@ -1331,10 +1365,7 @@ var CodexRun = class CodexRun {
1331
1365
  text,
1332
1366
  text_elements: []
1333
1367
  }],
1334
- ...prompt.images.map((image) => ({
1335
- type: "image",
1336
- url: `data:${image.mediaType};base64,${image.data}`
1337
- }))
1368
+ ...await imageInputs(this.sessionId, prompt.images)
1338
1369
  ];
1339
1370
  }
1340
1371
  finishTurn() {
@@ -1746,7 +1777,7 @@ function toolItems(base, tool) {
1746
1777
  case "skill": return [{
1747
1778
  ...base,
1748
1779
  kind: "skill",
1749
- skill: text$2(input.name),
1780
+ skill: text$2(input.id),
1750
1781
  output,
1751
1782
  status
1752
1783
  }];
@@ -2070,7 +2101,7 @@ var OpenCodeRun = class OpenCodeRun {
2070
2101
  await (await openCode()).session.prompt({
2071
2102
  sessionID: this.sessionId,
2072
2103
  text: prompt.text,
2073
- files: files(prompt),
2104
+ files: await files(this.sessionId, prompt),
2074
2105
  delivery: "steer"
2075
2106
  });
2076
2107
  return;
@@ -2240,7 +2271,7 @@ var OpenCodeRun = class OpenCodeRun {
2240
2271
  sessionID,
2241
2272
  name: match[1],
2242
2273
  text: match[2],
2243
- files: files(prompt)
2274
+ files: await files(sessionID, prompt)
2244
2275
  });
2245
2276
  return;
2246
2277
  }
@@ -2249,7 +2280,7 @@ var OpenCodeRun = class OpenCodeRun {
2249
2280
  await client.session.prompt({
2250
2281
  sessionID,
2251
2282
  text: match[2],
2252
- files: files(prompt),
2283
+ files: await files(sessionID, prompt),
2253
2284
  skills: [{ id: skill.id }]
2254
2285
  });
2255
2286
  return;
@@ -2258,7 +2289,7 @@ var OpenCodeRun = class OpenCodeRun {
2258
2289
  await client.session.prompt({
2259
2290
  sessionID,
2260
2291
  text: prompt.text,
2261
- files: files(prompt)
2292
+ files: await files(sessionID, prompt)
2262
2293
  });
2263
2294
  }
2264
2295
  async apply() {
@@ -2299,14 +2330,17 @@ var OpenCodeRun = class OpenCodeRun {
2299
2330
  });
2300
2331
  }
2301
2332
  addPending(pending) {
2302
- this.pending.set(pending.request.id, pending);
2333
+ const request = scheduleAutoResolve(this.sessionId, pending.request);
2334
+ this.pending.set(request.id, {
2335
+ ...pending,
2336
+ request
2337
+ });
2303
2338
  publish$2(this.sessionId, {
2304
2339
  type: "request",
2305
2340
  sessionId: this.sessionId,
2306
- request: pending.request
2341
+ request
2307
2342
  });
2308
2343
  broadcastActivity();
2309
- scheduleAutoResolve(this.sessionId, pending.request);
2310
2344
  }
2311
2345
  finishTurn() {
2312
2346
  this.partial = "";
@@ -2366,8 +2400,8 @@ var OpenCodeRun = class OpenCodeRun {
2366
2400
  });
2367
2401
  }
2368
2402
  };
2369
- function files(prompt) {
2370
- return prompt.images.map((image) => ({ uri: `data:${image.mediaType};base64,${image.data}` }));
2403
+ function files(sessionId, prompt) {
2404
+ return Promise.all(prompt.images.map(async (image) => ({ uri: pathToFileURL(await saveImage(sessionId, image)).href })));
2371
2405
  }
2372
2406
  //#endregion
2373
2407
  //#region src/storage/db.ts
@@ -2676,7 +2710,7 @@ async function find(provider, paths) {
2676
2710
  return [{
2677
2711
  id: thread.id,
2678
2712
  provider: "codex",
2679
- title: thread.name ?? thread.preview,
2713
+ title: thread.name ?? thread.preview.replaceAll(/\[Image: source: [^\]]+\]/g, ""),
2680
2714
  projectId,
2681
2715
  branch: thread.gitInfo?.branch ?? null,
2682
2716
  updatedAt: thread.updatedAt * 1e3
@@ -4319,13 +4353,13 @@ var Run = class {
4319
4353
  }, IDLE_LIMIT);
4320
4354
  }
4321
4355
  ask(options) {
4322
- const request = toRequest({
4356
+ const request = scheduleAutoResolve(this.sessionId, toRequest({
4323
4357
  id: randomUUID(),
4324
4358
  toolName: options.toolName,
4325
4359
  input: options.input,
4326
4360
  title: options.title,
4327
4361
  canAlwaysAllow: options.suggestions.length > 0
4328
- });
4362
+ }));
4329
4363
  return new Promise((resolve) => {
4330
4364
  this.pending.set(request.id, {
4331
4365
  request,
@@ -4339,7 +4373,6 @@ var Run = class {
4339
4373
  request
4340
4374
  });
4341
4375
  broadcastActivity();
4342
- scheduleAutoResolve(this.sessionId, request);
4343
4376
  options.signal.addEventListener("abort", () => this.settle(request.id, {
4344
4377
  behavior: "deny",
4345
4378
  message: "Cancelled"
@@ -4391,6 +4424,153 @@ var Run = class {
4391
4424
  }
4392
4425
  };
4393
4426
  //#endregion
4427
+ //#region ../core/src/media.ts
4428
+ const mediaTypes = /* @__PURE__ */ new Map([
4429
+ [".png", "image/png"],
4430
+ [".jpg", "image/jpeg"],
4431
+ [".jpeg", "image/jpeg"],
4432
+ [".gif", "image/gif"],
4433
+ [".webp", "image/webp"],
4434
+ [".svg", "image/svg+xml"],
4435
+ [".mp4", "video/mp4"],
4436
+ [".m4v", "video/mp4"],
4437
+ [".webm", "video/webm"],
4438
+ [".mov", "video/quicktime"],
4439
+ [".mp3", "audio/mpeg"],
4440
+ [".wav", "audio/wav"],
4441
+ [".ogg", "audio/ogg"],
4442
+ [".opus", "audio/ogg"],
4443
+ [".m4a", "audio/mp4"],
4444
+ [".aac", "audio/aac"],
4445
+ [".flac", "audio/flac"]
4446
+ ]);
4447
+ //#endregion
4448
+ //#region src/services/files.ts
4449
+ const FILE_LIMIT = 2e4;
4450
+ const OUTPUT_LIMIT$1 = 262144;
4451
+ const READ_LIMIT = 1048576;
4452
+ const MEDIA_LINK_LIFETIME = 36e5;
4453
+ const mediaLinks = /* @__PURE__ */ new Map();
4454
+ const skipped = /* @__PURE__ */ new Set([
4455
+ "node_modules",
4456
+ ".git",
4457
+ ".DS_Store",
4458
+ "dist",
4459
+ "target",
4460
+ ".next",
4461
+ "__pycache__",
4462
+ ".venv"
4463
+ ]);
4464
+ async function listFiles(cwd) {
4465
+ const files = [];
4466
+ const pending = [""];
4467
+ while (pending.length > 0 && files.length < FILE_LIMIT) {
4468
+ const dir = pending.pop() ?? "";
4469
+ let entries;
4470
+ try {
4471
+ entries = await readdir(path.join(cwd, dir), { withFileTypes: true });
4472
+ } catch {
4473
+ continue;
4474
+ }
4475
+ for (const entry of entries) {
4476
+ if (skipped.has(entry.name)) continue;
4477
+ const relative = dir === "" ? entry.name : `${dir}/${entry.name}`;
4478
+ if (entry.isDirectory()) pending.push(relative);
4479
+ if (entry.isFile()) files.push(relative);
4480
+ if (entry.isSymbolicLink()) {
4481
+ if ((await stat(path.join(cwd, relative)).catch(() => null))?.isFile() === true) files.push(relative);
4482
+ }
4483
+ }
4484
+ }
4485
+ return files.slice(0, FILE_LIMIT).sort();
4486
+ }
4487
+ function readProjectFile(cwd, file) {
4488
+ const full = resolveProjectFile(cwd, file);
4489
+ const stats = statSync(full);
4490
+ if (!stats.isFile()) throw new Error(`${file} is not a file`);
4491
+ if (stats.size > READ_LIMIT) return {
4492
+ kind: "large",
4493
+ size: stats.size,
4494
+ limit: READ_LIMIT
4495
+ };
4496
+ const data = readFileSync(full);
4497
+ const mediaType = mediaTypes.get(path.extname(full).toLowerCase());
4498
+ if (mediaType?.startsWith("image/") === true) return {
4499
+ kind: "image",
4500
+ size: stats.size,
4501
+ mediaType,
4502
+ data: data.toString("base64")
4503
+ };
4504
+ if (data.includes(0)) return {
4505
+ kind: "binary",
4506
+ size: stats.size
4507
+ };
4508
+ return {
4509
+ kind: "text",
4510
+ size: stats.size,
4511
+ content: data.toString("utf8")
4512
+ };
4513
+ }
4514
+ function linkProjectMedia(cwd, file) {
4515
+ const full = resolveProjectFile(cwd, file);
4516
+ const mediaType = mediaTypes.get(path.extname(full).toLowerCase());
4517
+ if (mediaType === void 0) throw new Error(`${file} is not an image, video or audio file`);
4518
+ for (const [token, link] of mediaLinks) if (link.expiresAt <= Date.now()) mediaLinks.delete(token);
4519
+ const token = randomBytes(32).toString("base64url");
4520
+ mediaLinks.set(token, {
4521
+ file: full,
4522
+ mediaType,
4523
+ expiresAt: Date.now() + MEDIA_LINK_LIFETIME
4524
+ });
4525
+ return token;
4526
+ }
4527
+ function findMediaLink(token) {
4528
+ if (token === null) return null;
4529
+ const link = mediaLinks.get(token);
4530
+ if (link === void 0 || link.expiresAt <= Date.now()) return null;
4531
+ return link;
4532
+ }
4533
+ function saveUpload(name, data) {
4534
+ const dir = path.join(home, "uploads", randomUUID());
4535
+ mkdirSync(dir, { recursive: true });
4536
+ const file = path.join(dir, path.basename(name));
4537
+ writeFileSync(file, data);
4538
+ return file;
4539
+ }
4540
+ async function taskOutput(sessionId, file) {
4541
+ const tasks = path.dirname(file);
4542
+ if (!/^[\w-]+$/.test(sessionId) || !path.isAbsolute(file) || path.normalize(file) !== file || !/^\w+\.output$/.test(path.basename(file)) || path.basename(tasks) !== "tasks" || path.basename(path.dirname(tasks)) !== sessionId) throw new Error("Not a background task output file of this thread");
4543
+ let stats;
4544
+ try {
4545
+ stats = await lstat(file);
4546
+ } catch (error) {
4547
+ if (hasCode(error, "ENOENT")) return null;
4548
+ throw error;
4549
+ }
4550
+ if (!stats.isFile()) throw new Error("Background task output is not a regular file");
4551
+ const start = Math.max(0, stats.size - OUTPUT_LIMIT$1);
4552
+ const handle = await open(file, "r");
4553
+ try {
4554
+ const buffer = Buffer.alloc(stats.size - start);
4555
+ const read = await handle.read(buffer, 0, buffer.length, start);
4556
+ return {
4557
+ text: buffer.subarray(0, read.bytesRead).toString("utf8"),
4558
+ truncated: start > 0
4559
+ };
4560
+ } finally {
4561
+ await handle.close();
4562
+ }
4563
+ }
4564
+ function resolveProjectFile(cwd, file) {
4565
+ const root = realpathSync(cwd);
4566
+ const resolved = path.resolve(root, file);
4567
+ if (!existsSync(resolved)) throw new Error(`${file} does not exist`);
4568
+ const full = realpathSync(resolved);
4569
+ const relative = path.relative(root, full);
4570
+ if (relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) throw new Error(`${file} is outside the project`);
4571
+ return full;
4572
+ }
4573
+ //#endregion
4394
4574
  //#region src/services/git.ts
4395
4575
  const DIFF_LIMIT = 8e4;
4396
4576
  const UNTRACKED_LIMIT = 100;
@@ -4649,6 +4829,7 @@ async function isRepo(cwd) {
4649
4829
  }
4650
4830
  async function repoDiff(repo, prefix) {
4651
4831
  const tracked = await git(repo, [
4832
+ "--no-optional-locks",
4652
4833
  "diff",
4653
4834
  await diffBase(repo),
4654
4835
  "--no-color",
@@ -4708,119 +4889,6 @@ function newFilePatch(cwd, file, prefix) {
4708
4889
  return `${header}@@ -0,0 +1,${lines.length} @@\n${lines.map((line) => `+${line}\n`).join("")}`;
4709
4890
  }
4710
4891
  //#endregion
4711
- //#region src/services/files.ts
4712
- const FILE_LIMIT = 2e4;
4713
- const OUTPUT_LIMIT$1 = 262144;
4714
- const READ_LIMIT = 1048576;
4715
- const images = /* @__PURE__ */ new Map([
4716
- [".png", "image/png"],
4717
- [".jpg", "image/jpeg"],
4718
- [".jpeg", "image/jpeg"],
4719
- [".gif", "image/gif"],
4720
- [".webp", "image/webp"],
4721
- [".svg", "image/svg+xml"]
4722
- ]);
4723
- const skipped = /* @__PURE__ */ new Set([
4724
- "node_modules",
4725
- ".git",
4726
- "dist",
4727
- "target",
4728
- ".next"
4729
- ]);
4730
- async function listFiles(cwd) {
4731
- try {
4732
- const { stdout } = await git(cwd, [
4733
- "ls-files",
4734
- "--cached",
4735
- "--others",
4736
- "--exclude-standard"
4737
- ]);
4738
- return stdout.split("\n").filter(Boolean).slice(0, FILE_LIMIT);
4739
- } catch {
4740
- return walk(cwd);
4741
- }
4742
- }
4743
- function readProjectFile(cwd, file) {
4744
- const root = realpathSync(cwd);
4745
- const full = realpathSync(path.resolve(root, file));
4746
- const relative = path.relative(root, full);
4747
- if (relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) throw new Error(`${file} is outside the project`);
4748
- const stats = statSync(full);
4749
- if (!stats.isFile()) throw new Error(`${file} is not a file`);
4750
- if (stats.size > READ_LIMIT) return {
4751
- kind: "large",
4752
- size: stats.size,
4753
- limit: READ_LIMIT
4754
- };
4755
- const data = readFileSync(full);
4756
- const mediaType = images.get(path.extname(full).toLowerCase());
4757
- if (mediaType !== void 0) return {
4758
- kind: "image",
4759
- size: stats.size,
4760
- mediaType,
4761
- data: data.toString("base64")
4762
- };
4763
- if (data.includes(0)) return {
4764
- kind: "binary",
4765
- size: stats.size
4766
- };
4767
- return {
4768
- kind: "text",
4769
- size: stats.size,
4770
- content: data.toString("utf8")
4771
- };
4772
- }
4773
- function saveUpload(name, data) {
4774
- const dir = path.join(home, "uploads", randomUUID());
4775
- mkdirSync(dir, { recursive: true });
4776
- const file = path.join(dir, path.basename(name));
4777
- writeFileSync(file, data);
4778
- return file;
4779
- }
4780
- async function taskOutput(sessionId, file) {
4781
- const tasks = path.dirname(file);
4782
- if (!/^[\w-]+$/.test(sessionId) || !path.isAbsolute(file) || path.normalize(file) !== file || !/^\w+\.output$/.test(path.basename(file)) || path.basename(tasks) !== "tasks" || path.basename(path.dirname(tasks)) !== sessionId) throw new Error("Not a background task output file of this thread");
4783
- let stats;
4784
- try {
4785
- stats = await lstat(file);
4786
- } catch (error) {
4787
- if (hasCode(error, "ENOENT")) return null;
4788
- throw error;
4789
- }
4790
- if (!stats.isFile()) throw new Error("Background task output is not a regular file");
4791
- const start = Math.max(0, stats.size - OUTPUT_LIMIT$1);
4792
- const handle = await open(file, "r");
4793
- try {
4794
- const buffer = Buffer.alloc(stats.size - start);
4795
- const read = await handle.read(buffer, 0, buffer.length, start);
4796
- return {
4797
- text: buffer.subarray(0, read.bytesRead).toString("utf8"),
4798
- truncated: start > 0
4799
- };
4800
- } finally {
4801
- await handle.close();
4802
- }
4803
- }
4804
- function walk(root) {
4805
- const files = [];
4806
- const pending = [""];
4807
- while (pending.length > 0 && files.length < FILE_LIMIT) {
4808
- const dir = pending.pop() ?? "";
4809
- let entries;
4810
- try {
4811
- entries = readdirSync(path.join(root, dir), { withFileTypes: true });
4812
- } catch {
4813
- continue;
4814
- }
4815
- for (const entry of entries) {
4816
- const relative = dir === "" ? entry.name : `${dir}/${entry.name}`;
4817
- if (entry.isDirectory() && !skipped.has(entry.name)) pending.push(relative);
4818
- if (entry.isFile()) files.push(relative);
4819
- }
4820
- }
4821
- return files;
4822
- }
4823
- //#endregion
4824
4892
  //#region src/services/runs.ts
4825
4893
  const locks = /* @__PURE__ */ new Map();
4826
4894
  function stopAll() {
@@ -6034,6 +6102,7 @@ const handlers = {
6034
6102
  capabilities: (params) => capabilities(params.provider, params.accountId, params.projectId === null ? os.homedir() : projectPath(params.projectId)),
6035
6103
  "files.list": (params) => listFiles(projectPath(params.projectId)),
6036
6104
  "files.read": (params) => readProjectFile(projectPath(params.projectId), params.path),
6105
+ "files.media": (params) => linkProjectMedia(projectPath(params.projectId), params.path),
6037
6106
  "files.upload": (params) => saveUpload(params.name, Buffer.from(params.data, "base64")),
6038
6107
  "tasks.output": (params) => taskOutput(params.sessionId, params.path),
6039
6108
  "git.status": (params) => gitRepos(projectPath(params.projectId)),
@@ -6212,6 +6281,10 @@ const code = args.auth && args.pair && !hasDevices() ? addCode(null) : null;
6212
6281
  const tickets = /* @__PURE__ */ new Map();
6213
6282
  const server = createServer((request, response) => {
6214
6283
  const url = new URL(request.url ?? "/", "http://localhost");
6284
+ if (url.pathname === "/api/media") {
6285
+ serveMedia(url.searchParams.get("token"), request, response);
6286
+ return;
6287
+ }
6215
6288
  if (url.pathname.startsWith("/api/")) {
6216
6289
  answerApi(url.pathname, request, response);
6217
6290
  return;
@@ -6308,6 +6381,64 @@ function answerApi(pathname, request, response) {
6308
6381
  response.statusCode = 404;
6309
6382
  response.end("not found");
6310
6383
  }
6384
+ function serveMedia(token, request, response) {
6385
+ if (request.method !== "GET") {
6386
+ response.statusCode = 405;
6387
+ response.end("use GET");
6388
+ return;
6389
+ }
6390
+ const link = findMediaLink(token);
6391
+ if (link === null) {
6392
+ response.statusCode = 404;
6393
+ response.end("This media link expired");
6394
+ return;
6395
+ }
6396
+ const stats = statSync(link.file, { throwIfNoEntry: false });
6397
+ if (stats === void 0 || !stats.isFile()) {
6398
+ response.statusCode = 404;
6399
+ response.end("not found");
6400
+ return;
6401
+ }
6402
+ response.setHeader("content-type", link.mediaType);
6403
+ response.setHeader("accept-ranges", "bytes");
6404
+ response.setHeader("cache-control", "private, max-age=3600");
6405
+ response.setHeader("content-security-policy", "sandbox");
6406
+ response.setHeader("x-content-type-options", "nosniff");
6407
+ if (request.headers.range === void 0) {
6408
+ response.setHeader("content-length", stats.size);
6409
+ createReadStream(link.file).on("error", () => response.destroy()).pipe(response);
6410
+ return;
6411
+ }
6412
+ const range = byteRange(request.headers.range, stats.size);
6413
+ if (range === null) {
6414
+ response.statusCode = 416;
6415
+ response.setHeader("content-range", `bytes */${stats.size}`);
6416
+ response.end();
6417
+ return;
6418
+ }
6419
+ response.statusCode = 206;
6420
+ response.setHeader("content-range", `bytes ${range.start}-${range.end}/${stats.size}`);
6421
+ response.setHeader("content-length", range.end - range.start + 1);
6422
+ createReadStream(link.file, range).on("error", () => response.destroy()).pipe(response);
6423
+ }
6424
+ function byteRange(header, size) {
6425
+ const match = /^bytes=(?:(\d+)-(\d*)|-(\d+))$/.exec(header);
6426
+ if (match === null) return null;
6427
+ if (match[3] !== void 0) {
6428
+ if (size === 0 || Number(match[3]) === 0) return null;
6429
+ return {
6430
+ start: Math.max(size - Number(match[3]), 0),
6431
+ end: size - 1
6432
+ };
6433
+ }
6434
+ const start = Number(match[1]);
6435
+ const end = match[2] === "" ? size - 1 : Math.min(Number(match[2]), size - 1);
6436
+ if (start > end) return null;
6437
+ return {
6438
+ start,
6439
+ end
6440
+ };
6441
+ }
6311
6442
  function answerJson(response, body) {
6312
6443
  response.setHeader("content-type", "application/json");
6313
6444
  response.end(JSON.stringify(body));