@zuzuucodes/cli 1.1.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (462) hide show
  1. package/README.md +7 -6
  2. package/bin/zuzuu-web.mjs +15 -0
  3. package/package.json +19 -8
  4. package/web-app/dist/browse.js +48 -0
  5. package/web-app/dist/config.js +52 -0
  6. package/web-app/dist/file-list.js +87 -0
  7. package/web-app/dist/frames.js +16 -0
  8. package/web-app/dist/fs-api.js +226 -0
  9. package/web-app/dist/git.js +73 -0
  10. package/web-app/dist/history.js +45 -0
  11. package/web-app/dist/index.js +160 -0
  12. package/web-app/dist/protocol/index.js +53 -0
  13. package/web-app/dist/protocol/zuzuu.js +2 -0
  14. package/web-app/dist/safe-path.js +60 -0
  15. package/web-app/dist/search.js +145 -0
  16. package/web-app/dist/server.js +407 -0
  17. package/web-app/dist/sessions.js +334 -0
  18. package/web-app/dist/shell-integration/inject.js +70 -0
  19. package/web-app/dist/shell-integration/webcode.bash +41 -0
  20. package/web-app/dist/shell-integration/webcode.fish +28 -0
  21. package/web-app/dist/shell-integration/webcode.zsh +35 -0
  22. package/web-app/dist/workflows.js +48 -0
  23. package/web-app/dist/ws-fs.js +69 -0
  24. package/web-app/dist/ws-term.js +42 -0
  25. package/web-app/dist/zuzuu-api.js +348 -0
  26. package/web-app/package.json +6 -0
  27. package/web-app/web-dist/assets/DiffTab-NYcg0Jn6.js +1 -0
  28. package/web-app/web-dist/assets/MonacoFile-C_nBCUL-.js +1 -0
  29. package/web-app/web-dist/assets/abap-08VXUWAP.js +1 -0
  30. package/web-app/web-dist/assets/abap-CLvhMVsD.js +1 -0
  31. package/web-app/web-dist/assets/actionscript-3--17pq3dv.js +1 -0
  32. package/web-app/web-dist/assets/ada-C5qYipkI.js +1 -0
  33. package/web-app/web-dist/assets/andromeeda-vGVdxbeo.js +1 -0
  34. package/web-app/web-dist/assets/angular-html-CmT26mqM.js +1 -0
  35. package/web-app/web-dist/assets/angular-ts-CD_OonCa.js +1 -0
  36. package/web-app/web-dist/assets/apache-U0d_L8uA.js +1 -0
  37. package/web-app/web-dist/assets/apex-BWPQTe0t.js +1 -0
  38. package/web-app/web-dist/assets/apex-VAyPSnFM.js +1 -0
  39. package/web-app/web-dist/assets/apl-uOGC3x4e.js +1 -0
  40. package/web-app/web-dist/assets/applescript-CCn79oCD.js +1 -0
  41. package/web-app/web-dist/assets/ara-4CJ0cIlV.js +1 -0
  42. package/web-app/web-dist/assets/asciidoc-DE70LPWp.js +1 -0
  43. package/web-app/web-dist/assets/asciinema-player-CZa1Uf8p.css +1 -0
  44. package/web-app/web-dist/assets/asm-Cmm7eHzH.js +1 -0
  45. package/web-app/web-dist/assets/astro-B6ybQmWG.js +1 -0
  46. package/web-app/web-dist/assets/aurora-x-CDeNXAV0.js +1 -0
  47. package/web-app/web-dist/assets/awk-BWXHIvNe.js +1 -0
  48. package/web-app/web-dist/assets/ayu-dark-DluEY0Gj.js +1 -0
  49. package/web-app/web-dist/assets/ayu-light-C3h-C4tm.js +1 -0
  50. package/web-app/web-dist/assets/ayu-mirage-Bqwy1Gya.js +1 -0
  51. package/web-app/web-dist/assets/azcli-Bc_sGQ0U.js +1 -0
  52. package/web-app/web-dist/assets/ballerina-B7ZEbQpA.js +1 -0
  53. package/web-app/web-dist/assets/bat-Bo4NYOV-.js +1 -0
  54. package/web-app/web-dist/assets/bat-i0X4ZdIN.js +1 -0
  55. package/web-app/web-dist/assets/beancount-D-usSTwE.js +1 -0
  56. package/web-app/web-dist/assets/berry-DKpUyyne.js +1 -0
  57. package/web-app/web-dist/assets/bibtex-Ci_nEsc7.js +1 -0
  58. package/web-app/web-dist/assets/bicep-B5-_aFwp.js +2 -0
  59. package/web-app/web-dist/assets/bicep-CUHmPFLl.js +1 -0
  60. package/web-app/web-dist/assets/bird2-C6vDhewU.js +1 -0
  61. package/web-app/web-dist/assets/blade-B1QGRlVx.js +1 -0
  62. package/web-app/web-dist/assets/bsl-BkkzgIyY.js +1 -0
  63. package/web-app/web-dist/assets/c-BvoqrSVH.js +1 -0
  64. package/web-app/web-dist/assets/c3-BFHwR3_K.js +1 -0
  65. package/web-app/web-dist/assets/cadence-CQ2zXKGN.js +1 -0
  66. package/web-app/web-dist/assets/cairo-DLTphjLi.js +1 -0
  67. package/web-app/web-dist/assets/cameligo-DMUM7wLl.js +1 -0
  68. package/web-app/web-dist/assets/catppuccin-frappe-3VR1Za6u.js +1 -0
  69. package/web-app/web-dist/assets/catppuccin-latte-DwIHMF0Q.js +1 -0
  70. package/web-app/web-dist/assets/catppuccin-macchiato-DYnBP6_5.js +1 -0
  71. package/web-app/web-dist/assets/catppuccin-mocha-DYhrFGRu.js +1 -0
  72. package/web-app/web-dist/assets/chunk-QTnfLwEv.js +1 -0
  73. package/web-app/web-dist/assets/clarity-SemFz856.js +1 -0
  74. package/web-app/web-dist/assets/clojure-Cm7r79vr.js +1 -0
  75. package/web-app/web-dist/assets/clojure-DqKBuwfJ.js +1 -0
  76. package/web-app/web-dist/assets/cmake-Bj61d0ZC.js +1 -0
  77. package/web-app/web-dist/assets/cobol-BgqgtYWn.js +1 -0
  78. package/web-app/web-dist/assets/codeowners-C8r90Shi.js +1 -0
  79. package/web-app/web-dist/assets/codeql-oeQT6MSM.js +1 -0
  80. package/web-app/web-dist/assets/codicon-ngg6Pgfi.ttf +0 -0
  81. package/web-app/web-dist/assets/coffee-0wIRKYlr.js +1 -0
  82. package/web-app/web-dist/assets/coffee-Ba7i2nA0.js +1 -0
  83. package/web-app/web-dist/assets/common-lisp-Cv5bFMCO.js +1 -0
  84. package/web-app/web-dist/assets/coq-BrsZFFmf.js +1 -0
  85. package/web-app/web-dist/assets/cpp-BXsk94m0.js +1 -0
  86. package/web-app/web-dist/assets/cpp-C7h46wYY.js +1 -0
  87. package/web-app/web-dist/assets/crystal-CyTK3qFN.js +1 -0
  88. package/web-app/web-dist/assets/csharp-BKxtCVv1.js +1 -0
  89. package/web-app/web-dist/assets/csharp-oqKa8noW.js +1 -0
  90. package/web-app/web-dist/assets/csp-bTuwJoIa.js +1 -0
  91. package/web-app/web-dist/assets/css-DIMkf-bt.js +3 -0
  92. package/web-app/web-dist/assets/css-Z8oOGxII.js +1 -0
  93. package/web-app/web-dist/assets/css.worker-CvXBzhp8.js +89 -0
  94. package/web-app/web-dist/assets/cssMode-BXZOx0fG.js +1 -0
  95. package/web-app/web-dist/assets/csv-Dx-8-gkx.js +1 -0
  96. package/web-app/web-dist/assets/cue-CE9AQfxI.js +1 -0
  97. package/web-app/web-dist/assets/cypher-CVaqCwHa.js +1 -0
  98. package/web-app/web-dist/assets/cypher-ClKdZ_lG.js +1 -0
  99. package/web-app/web-dist/assets/d-qD-0Kul2.js +1 -0
  100. package/web-app/web-dist/assets/dark-plus-Cs2F2srj.js +1 -0
  101. package/web-app/web-dist/assets/dart-CnvKMtbv.js +1 -0
  102. package/web-app/web-dist/assets/dart-onAF5SnQ.js +1 -0
  103. package/web-app/web-dist/assets/dax-BkyTk9wS.js +1 -0
  104. package/web-app/web-dist/assets/desktop-Dlh5hvp9.js +1 -0
  105. package/web-app/web-dist/assets/diff-woXpYk--.js +1 -0
  106. package/web-app/web-dist/assets/dist-Cj6v7Kj8.js +153 -0
  107. package/web-app/web-dist/assets/dist-DNelLewU.js +4 -0
  108. package/web-app/web-dist/assets/docker-IyjqRm3v.js +1 -0
  109. package/web-app/web-dist/assets/dockerfile-DZFCIeNp.js +1 -0
  110. package/web-app/web-dist/assets/dotenv-_5a1GRtc.js +1 -0
  111. package/web-app/web-dist/assets/dracula-BHWKrbxM.js +1 -0
  112. package/web-app/web-dist/assets/dracula-soft-5eyTD99u.js +1 -0
  113. package/web-app/web-dist/assets/dream-maker-DW3nJb8Q.js +1 -0
  114. package/web-app/web-dist/assets/ecl-D05T4iGw.js +1 -0
  115. package/web-app/web-dist/assets/edge-CvML9pwC.js +1 -0
  116. package/web-app/web-dist/assets/editor-Br_kD0ds.css +1 -0
  117. package/web-app/web-dist/assets/editor.api2-BmGoRSl4.js +872 -0
  118. package/web-app/web-dist/assets/editor.worker-Cn2oRESe.js +26 -0
  119. package/web-app/web-dist/assets/elixir-6RTg0lbw.js +1 -0
  120. package/web-app/web-dist/assets/elixir-CrjqTiSc.js +1 -0
  121. package/web-app/web-dist/assets/elm-C4JtJ0Au.js +1 -0
  122. package/web-app/web-dist/assets/emacs-lisp-B4R74twV.js +1 -0
  123. package/web-app/web-dist/assets/erb-Cmeb-29V.js +1 -0
  124. package/web-app/web-dist/assets/erlang-Cphh6RMH.js +1 -0
  125. package/web-app/web-dist/assets/everforest-dark-sB-x3p7T.js +1 -0
  126. package/web-app/web-dist/assets/everforest-light-Df2xbC6M.js +1 -0
  127. package/web-app/web-dist/assets/fennel-DQxkIbk2.js +1 -0
  128. package/web-app/web-dist/assets/fish-BJitypiv.js +1 -0
  129. package/web-app/web-dist/assets/flow9-C5_-GSwl.js +1 -0
  130. package/web-app/web-dist/assets/fluent-C03EYrpw.js +1 -0
  131. package/web-app/web-dist/assets/fortran-fixed-form-DEKoE2YW.js +1 -0
  132. package/web-app/web-dist/assets/fortran-free-form-CYNrtFtB.js +1 -0
  133. package/web-app/web-dist/assets/freemarker2-B5LAi19B.js +3 -0
  134. package/web-app/web-dist/assets/fsharp-C8Ef5oNN.js +1 -0
  135. package/web-app/web-dist/assets/fsharp-D13ZGOAj.js +1 -0
  136. package/web-app/web-dist/assets/gdresource-C0sCabJj.js +1 -0
  137. package/web-app/web-dist/assets/gdscript-Cp2uCuqX.js +1 -0
  138. package/web-app/web-dist/assets/gdshader-CBce3t8t.js +1 -0
  139. package/web-app/web-dist/assets/genie-CV2tkWYe.js +1 -0
  140. package/web-app/web-dist/assets/gherkin-DExj1W_8.js +1 -0
  141. package/web-app/web-dist/assets/git-commit-BSykSTBG.js +1 -0
  142. package/web-app/web-dist/assets/git-rebase-CXqdToiP.js +1 -0
  143. package/web-app/web-dist/assets/github-dark-C-LZuMrd.js +1 -0
  144. package/web-app/web-dist/assets/github-dark-default-DXG-b-1a.js +1 -0
  145. package/web-app/web-dist/assets/github-dark-dimmed-Bx1FflLF.js +1 -0
  146. package/web-app/web-dist/assets/github-dark-high-contrast-B_tTalzw.js +1 -0
  147. package/web-app/web-dist/assets/github-light-EUqPIrTm.js +1 -0
  148. package/web-app/web-dist/assets/github-light-default-BXViO-2h.js +1 -0
  149. package/web-app/web-dist/assets/github-light-high-contrast-B68TUdTA.js +1 -0
  150. package/web-app/web-dist/assets/gleam-CSRkHgEL.js +1 -0
  151. package/web-app/web-dist/assets/glimmer-js-Kq-kdTyV.js +1 -0
  152. package/web-app/web-dist/assets/glimmer-ts-D0RKLJNf.js +1 -0
  153. package/web-app/web-dist/assets/glsl-KwyfU2aa.js +1 -0
  154. package/web-app/web-dist/assets/gn-ilITqXS6.js +1 -0
  155. package/web-app/web-dist/assets/gnuplot-7GGW24-e.js +1 -0
  156. package/web-app/web-dist/assets/go-C-y9NEjX.js +1 -0
  157. package/web-app/web-dist/assets/go-rLFTqkRN.js +1 -0
  158. package/web-app/web-dist/assets/graphql-DSeOUAa2.js +1 -0
  159. package/web-app/web-dist/assets/graphql-fmXr3nnJ.js +1 -0
  160. package/web-app/web-dist/assets/groovy-CacY0gHj.js +1 -0
  161. package/web-app/web-dist/assets/gruvbox-dark-hard-C820rvS2.js +1 -0
  162. package/web-app/web-dist/assets/gruvbox-dark-medium-BPjhmG05.js +1 -0
  163. package/web-app/web-dist/assets/gruvbox-dark-soft-MrdJrrXF.js +1 -0
  164. package/web-app/web-dist/assets/gruvbox-light-hard-BC_s9l72.js +1 -0
  165. package/web-app/web-dist/assets/gruvbox-light-medium-BAWPOn9u.js +1 -0
  166. package/web-app/web-dist/assets/gruvbox-light-soft-BSMLrYjP.js +1 -0
  167. package/web-app/web-dist/assets/hack-trjVF3Po.js +1 -0
  168. package/web-app/web-dist/assets/haml-azVoxQRV.js +1 -0
  169. package/web-app/web-dist/assets/handlebars-B8_x7Zx7.js +1 -0
  170. package/web-app/web-dist/assets/handlebars-g7ZhGhI_.js +1 -0
  171. package/web-app/web-dist/assets/haskell-D8IpX4py.js +1 -0
  172. package/web-app/web-dist/assets/haxe-OTjmBuCE.js +1 -0
  173. package/web-app/web-dist/assets/hcl-CpzslTdj.js +1 -0
  174. package/web-app/web-dist/assets/hcl-Dh228itO.js +1 -0
  175. package/web-app/web-dist/assets/hjson-CxZEssPk.js +1 -0
  176. package/web-app/web-dist/assets/hlsl-Cvrh5tZx.js +1 -0
  177. package/web-app/web-dist/assets/horizon-CE9ld1lL.js +1 -0
  178. package/web-app/web-dist/assets/horizon-bright-DSNQnXHK.js +1 -0
  179. package/web-app/web-dist/assets/houston-CsvMBhTu.js +1 -0
  180. package/web-app/web-dist/assets/html-CfvRMgoC.js +1 -0
  181. package/web-app/web-dist/assets/html-D_7P5S4m.js +1 -0
  182. package/web-app/web-dist/assets/html-derivative-BYX_F_XH.js +1 -0
  183. package/web-app/web-dist/assets/html.worker-BO6WuOEO.js +502 -0
  184. package/web-app/web-dist/assets/htmlMode-CScDVtoR.js +1 -0
  185. package/web-app/web-dist/assets/http-BIVDpHT-.js +1 -0
  186. package/web-app/web-dist/assets/hurl-CFsshMju.js +1 -0
  187. package/web-app/web-dist/assets/hxml-B0Qn7Nwc.js +1 -0
  188. package/web-app/web-dist/assets/hy-CZbG8q4J.js +1 -0
  189. package/web-app/web-dist/assets/imba-DsUTQ-LC.js +1 -0
  190. package/web-app/web-dist/assets/index--lqPz7z2.css +2 -0
  191. package/web-app/web-dist/assets/index-BTchnWPZ.js +270 -0
  192. package/web-app/web-dist/assets/ini-B5eOa1yu.js +1 -0
  193. package/web-app/web-dist/assets/ini-sBoK_t0W.js +1 -0
  194. package/web-app/web-dist/assets/java-BEtHBSE6.js +1 -0
  195. package/web-app/web-dist/assets/java-D4RbCvBe.js +1 -0
  196. package/web-app/web-dist/assets/javascript-Bxx2wV4w.js +1 -0
  197. package/web-app/web-dist/assets/javascript-Cb010CKM.js +1 -0
  198. package/web-app/web-dist/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
  199. package/web-app/web-dist/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
  200. package/web-app/web-dist/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  201. package/web-app/web-dist/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  202. package/web-app/web-dist/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
  203. package/web-app/web-dist/assets/jinja-_ZS5zWwe.js +1 -0
  204. package/web-app/web-dist/assets/jison-D8mMEpcs.js +1 -0
  205. package/web-app/web-dist/assets/json-DWgqV4D1.js +1 -0
  206. package/web-app/web-dist/assets/json.worker-BkJRGcCJ.js +58 -0
  207. package/web-app/web-dist/assets/json5-BR5RXkoi.js +1 -0
  208. package/web-app/web-dist/assets/jsonMode-BMZXTtiq.js +7 -0
  209. package/web-app/web-dist/assets/jsonc-CYpm1nAK.js +1 -0
  210. package/web-app/web-dist/assets/jsonl-CmCQp5Yx.js +1 -0
  211. package/web-app/web-dist/assets/jsonnet-CJTPZ8u_.js +1 -0
  212. package/web-app/web-dist/assets/jssm-DXw9l8Rf.js +1 -0
  213. package/web-app/web-dist/assets/jsx-CZjSJa1f.js +1 -0
  214. package/web-app/web-dist/assets/julia-Bri6UV-V.js +1 -0
  215. package/web-app/web-dist/assets/julia-D4h2DZrs.js +1 -0
  216. package/web-app/web-dist/assets/just-bMqQi3xg.js +1 -0
  217. package/web-app/web-dist/assets/kanagawa-dragon-CXtmUGW6.js +1 -0
  218. package/web-app/web-dist/assets/kanagawa-lotus-BN08jTvb.js +1 -0
  219. package/web-app/web-dist/assets/kanagawa-wave-CTweb8Dz.js +1 -0
  220. package/web-app/web-dist/assets/kdl-CsD5j6eV.js +1 -0
  221. package/web-app/web-dist/assets/kotlin-BOotOW0E.js +1 -0
  222. package/web-app/web-dist/assets/kotlin-DhhofPvG.js +1 -0
  223. package/web-app/web-dist/assets/kusto-C7mF5XQf.js +1 -0
  224. package/web-app/web-dist/assets/laserwave-C_8bwKvT.js +1 -0
  225. package/web-app/web-dist/assets/latex-DThYi3CX.js +1 -0
  226. package/web-app/web-dist/assets/lean-CewbzKMR.js +1 -0
  227. package/web-app/web-dist/assets/less-B9JPFI3C.js +2 -0
  228. package/web-app/web-dist/assets/less-DVTAwKKz.js +1 -0
  229. package/web-app/web-dist/assets/lexon-CfSJPG6W.js +1 -0
  230. package/web-app/web-dist/assets/light-plus-DVQuIRkW.js +1 -0
  231. package/web-app/web-dist/assets/liquid-CUjzzP4r.js +1 -0
  232. package/web-app/web-dist/assets/liquid-CesB-zzl.js +1 -0
  233. package/web-app/web-dist/assets/llvm-Cm23YOpf.js +1 -0
  234. package/web-app/web-dist/assets/log-BNLmms1o.js +1 -0
  235. package/web-app/web-dist/assets/logo-Cluzi2Zq.js +1 -0
  236. package/web-app/web-dist/assets/lspLanguageFeatures-gTnJsses.js +4 -0
  237. package/web-app/web-dist/assets/lua-CsQS60Ue.js +1 -0
  238. package/web-app/web-dist/assets/lua-TGj_6NzO.js +1 -0
  239. package/web-app/web-dist/assets/luau-FMPmPwt6.js +1 -0
  240. package/web-app/web-dist/assets/m3-D-oSqn_W.js +1 -0
  241. package/web-app/web-dist/assets/make-Dixweg8N.js +1 -0
  242. package/web-app/web-dist/assets/markdown-BYOwaDjH.js +1 -0
  243. package/web-app/web-dist/assets/markdown-Cimd5fb3.js +1 -0
  244. package/web-app/web-dist/assets/marko-yoGoLK2m.js +1 -0
  245. package/web-app/web-dist/assets/material-theme-Bm3Qr25_.js +1 -0
  246. package/web-app/web-dist/assets/material-theme-darker-2IIEA8gg.js +1 -0
  247. package/web-app/web-dist/assets/material-theme-lighter-uhdI0v04.js +1 -0
  248. package/web-app/web-dist/assets/material-theme-ocean-CHQ94UKr.js +1 -0
  249. package/web-app/web-dist/assets/material-theme-palenight-B5W6OYN7.js +1 -0
  250. package/web-app/web-dist/assets/matlab-D7qyCx1q.js +1 -0
  251. package/web-app/web-dist/assets/mdc-BvtXU6eH.js +1 -0
  252. package/web-app/web-dist/assets/mdx-DQZ5AkYe.js +1 -0
  253. package/web-app/web-dist/assets/mdx-DrXGQbNB.js +1 -0
  254. package/web-app/web-dist/assets/mermaid-Bk4SNUv9.js +1 -0
  255. package/web-app/web-dist/assets/min-dark-BSWPekZh.js +1 -0
  256. package/web-app/web-dist/assets/min-light-DDpmG2fV.js +1 -0
  257. package/web-app/web-dist/assets/mips-CIPQ_RoX.js +1 -0
  258. package/web-app/web-dist/assets/mipsasm-BMqwQI7S.js +1 -0
  259. package/web-app/web-dist/assets/mojo-BgCJLMeH.js +1 -0
  260. package/web-app/web-dist/assets/monaco-setup-DAY1k6DB.js +16 -0
  261. package/web-app/web-dist/assets/monokai-CdkpiU2Y.js +1 -0
  262. package/web-app/web-dist/assets/moonbit-CaWjb8XO.js +1 -0
  263. package/web-app/web-dist/assets/move-B1IS1UjX.js +1 -0
  264. package/web-app/web-dist/assets/msdax-DauUninz.js +1 -0
  265. package/web-app/web-dist/assets/mysql-SOo6toE5.js +1 -0
  266. package/web-app/web-dist/assets/narrat-_X_XdTYD.js +1 -0
  267. package/web-app/web-dist/assets/nextflow-BJtWHP5T.js +1 -0
  268. package/web-app/web-dist/assets/nextflow-groovy-DJMQeKeT.js +1 -0
  269. package/web-app/web-dist/assets/nginx-DoUz032F.js +1 -0
  270. package/web-app/web-dist/assets/night-owl-DhmEMT88.js +1 -0
  271. package/web-app/web-dist/assets/night-owl-light-eJ-hLW7d.js +1 -0
  272. package/web-app/web-dist/assets/nim-B0Pl8B4R.js +1 -0
  273. package/web-app/web-dist/assets/nix-IvuFDN5E.js +1 -0
  274. package/web-app/web-dist/assets/nord-Cb4Vim4T.js +1 -0
  275. package/web-app/web-dist/assets/nushell-DcLAeLz5.js +1 -0
  276. package/web-app/web-dist/assets/objective-c-D1A_Heim.js +1 -0
  277. package/web-app/web-dist/assets/objective-c-FvmIjYaQ.js +1 -0
  278. package/web-app/web-dist/assets/objective-cpp-BsSzOQcm.js +1 -0
  279. package/web-app/web-dist/assets/ocaml-O90oeIOV.js +1 -0
  280. package/web-app/web-dist/assets/odin-B1RWQWA5.js +1 -0
  281. package/web-app/web-dist/assets/one-dark-pro-CLwyXe_n.js +1 -0
  282. package/web-app/web-dist/assets/one-light-D7Lr4KcI.js +1 -0
  283. package/web-app/web-dist/assets/openscad-BUDT5pXO.js +1 -0
  284. package/web-app/web-dist/assets/pascal-4ZHwLPI5.js +1 -0
  285. package/web-app/web-dist/assets/pascal-DrH0SRf2.js +1 -0
  286. package/web-app/web-dist/assets/pascaligo-D-ptJ9y-.js +1 -0
  287. package/web-app/web-dist/assets/perl-D2tfAALb.js +1 -0
  288. package/web-app/web-dist/assets/perl-oz_6vUea.js +1 -0
  289. package/web-app/web-dist/assets/pgsql-DTj74zXo.js +1 -0
  290. package/web-app/web-dist/assets/php-BImCcX5X.js +1 -0
  291. package/web-app/web-dist/assets/php-nr791fC2.js +1 -0
  292. package/web-app/web-dist/assets/pkl-ot-7Btpt.js +1 -0
  293. package/web-app/web-dist/assets/pla-CopQ2nXW.js +1 -0
  294. package/web-app/web-dist/assets/plastic-DQwYfKfQ.js +1 -0
  295. package/web-app/web-dist/assets/plsql-DGHpHOYJ.js +1 -0
  296. package/web-app/web-dist/assets/po-BiJDBrnU.js +1 -0
  297. package/web-app/web-dist/assets/poimandres-DRFjx7u4.js +1 -0
  298. package/web-app/web-dist/assets/polar-C7UOKdEL.js +1 -0
  299. package/web-app/web-dist/assets/postcss-BXeXVLqQ.js +1 -0
  300. package/web-app/web-dist/assets/postiats-43DmfD33.js +1 -0
  301. package/web-app/web-dist/assets/powerquery-D3hlyOfw.js +1 -0
  302. package/web-app/web-dist/assets/powerquery-DNMTfnFr.js +1 -0
  303. package/web-app/web-dist/assets/powershell-DmHpPYUd.js +1 -0
  304. package/web-app/web-dist/assets/powershell-DshXNtvi.js +1 -0
  305. package/web-app/web-dist/assets/prisma-BsRQq5mF.js +1 -0
  306. package/web-app/web-dist/assets/prolog-iXnhIJG7.js +1 -0
  307. package/web-app/web-dist/assets/proto-DB4EqR-F.js +1 -0
  308. package/web-app/web-dist/assets/protobuf-C531GsRP.js +2 -0
  309. package/web-app/web-dist/assets/pug-BcnpC8P_.js +1 -0
  310. package/web-app/web-dist/assets/pug-Z5eAx3Zn.js +1 -0
  311. package/web-app/web-dist/assets/puppet-CDv2pdJW.js +1 -0
  312. package/web-app/web-dist/assets/purescript-9MfHhQsQ.js +1 -0
  313. package/web-app/web-dist/assets/python-gzcpVVnB.js +1 -0
  314. package/web-app/web-dist/assets/python-ypRCBnvu.js +1 -0
  315. package/web-app/web-dist/assets/qml-DFDAunHY.js +1 -0
  316. package/web-app/web-dist/assets/qmldir-DCQb3MpD.js +1 -0
  317. package/web-app/web-dist/assets/qsharp-DkqhCAOL.js +1 -0
  318. package/web-app/web-dist/assets/qss-Fe1Jh2GI.js +1 -0
  319. package/web-app/web-dist/assets/r-BwWrilGY.js +1 -0
  320. package/web-app/web-dist/assets/r-fCpuAR7u.js +1 -0
  321. package/web-app/web-dist/assets/racket-DcIDlBhZ.js +1 -0
  322. package/web-app/web-dist/assets/raku-B3gFvitq.js +1 -0
  323. package/web-app/web-dist/assets/razor-1_376SZM.js +1 -0
  324. package/web-app/web-dist/assets/razor-aqrhpwqZ.js +1 -0
  325. package/web-app/web-dist/assets/red-CJ3rzSJv.js +1 -0
  326. package/web-app/web-dist/assets/redis-ClamHrr6.js +1 -0
  327. package/web-app/web-dist/assets/redshift-DT7zqm-g.js +1 -0
  328. package/web-app/web-dist/assets/reg-CRGYupPL.js +1 -0
  329. package/web-app/web-dist/assets/regexp-B4yxx-Ty.js +1 -0
  330. package/web-app/web-dist/assets/rel-BtDbiS_P.js +1 -0
  331. package/web-app/web-dist/assets/restructuredtext-BYgofb2h.js +1 -0
  332. package/web-app/web-dist/assets/riscv-Ckw8ddFX.js +1 -0
  333. package/web-app/web-dist/assets/ron-VUp2lXgN.js +1 -0
  334. package/web-app/web-dist/assets/rose-pine-BthvhNj6.js +1 -0
  335. package/web-app/web-dist/assets/rose-pine-dawn-Dg85fqjY.js +1 -0
  336. package/web-app/web-dist/assets/rose-pine-moon-hon4tzzS.js +1 -0
  337. package/web-app/web-dist/assets/rosmsg-CAekHB0j.js +1 -0
  338. package/web-app/web-dist/assets/rst-2vG6f11Y.js +1 -0
  339. package/web-app/web-dist/assets/ruby-DezsRK8O.js +1 -0
  340. package/web-app/web-dist/assets/ruby-Dj6bCFXR.js +1 -0
  341. package/web-app/web-dist/assets/rust-Cfkwpbl8.js +1 -0
  342. package/web-app/web-dist/assets/rust-DdL9SqIa.js +1 -0
  343. package/web-app/web-dist/assets/sas-BhVZ4qL2.js +1 -0
  344. package/web-app/web-dist/assets/sass-DXrisJhu.js +1 -0
  345. package/web-app/web-dist/assets/sb-CcwsVR0C.js +1 -0
  346. package/web-app/web-dist/assets/scala-DHpiXF5c.js +1 -0
  347. package/web-app/web-dist/assets/scala-DKOlJaKm.js +1 -0
  348. package/web-app/web-dist/assets/scheme-BeGwcela.js +1 -0
  349. package/web-app/web-dist/assets/scheme-DQCgrYNe.js +1 -0
  350. package/web-app/web-dist/assets/scss-QdjMO_xV.js +1 -0
  351. package/web-app/web-dist/assets/scss-gp-XZpBa.js +3 -0
  352. package/web-app/web-dist/assets/sdbl-bTVj8UrX.js +1 -0
  353. package/web-app/web-dist/assets/shaderlab-TOUzSsQk.js +1 -0
  354. package/web-app/web-dist/assets/shell-CC2rA5mh.js +1 -0
  355. package/web-app/web-dist/assets/shellscript-BnlgeVVx.js +1 -0
  356. package/web-app/web-dist/assets/shellsession-CyO2fnhB.js +1 -0
  357. package/web-app/web-dist/assets/slack-dark-DnToyrRv.js +1 -0
  358. package/web-app/web-dist/assets/slack-ochin-B2OO5cIa.js +1 -0
  359. package/web-app/web-dist/assets/smalltalk-B16xEiuN.js +1 -0
  360. package/web-app/web-dist/assets/snazzy-light-4G7pJPwS.js +1 -0
  361. package/web-app/web-dist/assets/solarized-dark-DV17i1UV.js +1 -0
  362. package/web-app/web-dist/assets/solarized-light-DSh2HLQt.js +1 -0
  363. package/web-app/web-dist/assets/solidity-BEEn4gHE.js +1 -0
  364. package/web-app/web-dist/assets/solidity-CKzVLygQ.js +1 -0
  365. package/web-app/web-dist/assets/sophia-CRfGWb83.js +1 -0
  366. package/web-app/web-dist/assets/soy-DIkw6E88.js +1 -0
  367. package/web-app/web-dist/assets/sparql-D_Lu-MrJ.js +1 -0
  368. package/web-app/web-dist/assets/sparql-D_iOobhT.js +1 -0
  369. package/web-app/web-dist/assets/splunk-BC2Px7Mm.js +1 -0
  370. package/web-app/web-dist/assets/sql-DGnQv6iD.js +1 -0
  371. package/web-app/web-dist/assets/sql-NEE52Syq.js +1 -0
  372. package/web-app/web-dist/assets/ssh-config-BgfXC-Er.js +1 -0
  373. package/web-app/web-dist/assets/st-DbInun42.js +1 -0
  374. package/web-app/web-dist/assets/stata-DvkM932O.js +1 -0
  375. package/web-app/web-dist/assets/stylus-B6D30XZt.js +1 -0
  376. package/web-app/web-dist/assets/surrealql-B4-Q8tqV.js +1 -0
  377. package/web-app/web-dist/assets/svelte-p6yBy-Ki.js +1 -0
  378. package/web-app/web-dist/assets/swift-Bxkupp3x.js +1 -0
  379. package/web-app/web-dist/assets/swift-DonLKvLd.js +1 -0
  380. package/web-app/web-dist/assets/synthwave-84-nFMaYfgc.js +1 -0
  381. package/web-app/web-dist/assets/system-verilog-DJ5XKQeo.js +1 -0
  382. package/web-app/web-dist/assets/systemd-BxMlprV5.js +1 -0
  383. package/web-app/web-dist/assets/systemverilog-Bz4Y3fRF.js +1 -0
  384. package/web-app/web-dist/assets/talonscript-CohzipZa.js +1 -0
  385. package/web-app/web-dist/assets/tasl-DMoTqEGO.js +1 -0
  386. package/web-app/web-dist/assets/tcl-CZd0xW_V.js +1 -0
  387. package/web-app/web-dist/assets/tcl-DISqw1ZD.js +1 -0
  388. package/web-app/web-dist/assets/templ-C7EkuiZr.js +1 -0
  389. package/web-app/web-dist/assets/terraform-DswuEJGm.js +1 -0
  390. package/web-app/web-dist/assets/tex-DkmD8uFC.js +1 -0
  391. package/web-app/web-dist/assets/tokyo-night-oM2G3aXe.js +1 -0
  392. package/web-app/web-dist/assets/toml-CcmNWLt0.js +1 -0
  393. package/web-app/web-dist/assets/ts-tags-U-hncHg4.js +1 -0
  394. package/web-app/web-dist/assets/ts.worker-B0J26iPs.js +67734 -0
  395. package/web-app/web-dist/assets/tsMode-D--bqr5b.js +11 -0
  396. package/web-app/web-dist/assets/tsv-sltzmVWM.js +1 -0
  397. package/web-app/web-dist/assets/tsx-MJ0-9sYG.js +1 -0
  398. package/web-app/web-dist/assets/turtle-ByJddavk.js +1 -0
  399. package/web-app/web-dist/assets/twig-CU0OP-IA.js +1 -0
  400. package/web-app/web-dist/assets/twig-De2hgUGE.js +1 -0
  401. package/web-app/web-dist/assets/typescript-C17ZkDe8.js +1 -0
  402. package/web-app/web-dist/assets/typescript-DnLjiKtn.js +1 -0
  403. package/web-app/web-dist/assets/typespec-B8J7ngcE.js +1 -0
  404. package/web-app/web-dist/assets/typespec-BRdr0IET.js +1 -0
  405. package/web-app/web-dist/assets/typst-DI99ib-x.js +1 -0
  406. package/web-app/web-dist/assets/v-DETTlOr0.js +1 -0
  407. package/web-app/web-dist/assets/vala-zf12oZj6.js +1 -0
  408. package/web-app/web-dist/assets/vb-DV3o63ZY.js +1 -0
  409. package/web-app/web-dist/assets/vb-Djn5o6TS.js +1 -0
  410. package/web-app/web-dist/assets/verilog-CiiDBU1e.js +1 -0
  411. package/web-app/web-dist/assets/vesper-DdrHHSXu.js +1 -0
  412. package/web-app/web-dist/assets/vhdl-BroJfC0k.js +1 -0
  413. package/web-app/web-dist/assets/viml-DvXPmvsu.js +1 -0
  414. package/web-app/web-dist/assets/vitesse-black-fwtXNY1n.js +1 -0
  415. package/web-app/web-dist/assets/vitesse-dark-BZCL-v6S.js +1 -0
  416. package/web-app/web-dist/assets/vitesse-light-VbXTXTou.js +1 -0
  417. package/web-app/web-dist/assets/vue-Db7nY3ba.js +1 -0
  418. package/web-app/web-dist/assets/vue-html-BvAbiAw1.js +1 -0
  419. package/web-app/web-dist/assets/vue-vine-BEaIQIlA.js +1 -0
  420. package/web-app/web-dist/assets/vyper-CgoNMtux.js +1 -0
  421. package/web-app/web-dist/assets/wasm-BnjxR4X6.js +1 -0
  422. package/web-app/web-dist/assets/wasm-ByWQv1Qj.js +1 -0
  423. package/web-app/web-dist/assets/wenyan-C8pVoKbM.js +1 -0
  424. package/web-app/web-dist/assets/wgsl-BsKzXJz4.js +1 -0
  425. package/web-app/web-dist/assets/wgsl-DpFanUEy.js +298 -0
  426. package/web-app/web-dist/assets/wikitext-ClFFjSW2.js +1 -0
  427. package/web-app/web-dist/assets/wit-DdvCle-K.js +1 -0
  428. package/web-app/web-dist/assets/wolfram-DLL8P-h_.js +1 -0
  429. package/web-app/web-dist/assets/xml-CA9lHFQV.js +1 -0
  430. package/web-app/web-dist/assets/xml-an4Nuuqq.js +1 -0
  431. package/web-app/web-dist/assets/xsl-D3NQgH22.js +1 -0
  432. package/web-app/web-dist/assets/yaml-CwRYMJka.js +1 -0
  433. package/web-app/web-dist/assets/yaml-Diiu6O9P.js +1 -0
  434. package/web-app/web-dist/assets/zenscript-BnlCZFoB.js +1 -0
  435. package/web-app/web-dist/assets/zig-CMLA9XwU.js +1 -0
  436. package/web-app/web-dist/index.html +16 -0
  437. package/zuzuu/capture/bin/capture.mjs +99 -0
  438. package/zuzuu/capture/bin/inspect-trace.mjs +13 -0
  439. package/zuzuu/capture-core.mjs +3 -3
  440. package/zuzuu/commands/capture.mjs +1 -1
  441. package/zuzuu/commands/doctor.mjs +1 -1
  442. package/zuzuu/commands/hook.mjs +1 -1
  443. package/zuzuu/commands/init.mjs +1 -1
  444. package/zuzuu/commands/status.mjs +1 -1
  445. package/zuzuu/commands/trace.mjs +1 -1
  446. package/zuzuu/commands/web.mjs +49 -45
  447. package/zuzuu/knowledge/distill.mjs +1 -1
  448. package/zuzuu/live/reconcile.mjs +1 -1
  449. package/zuzuu/store.mjs +1 -1
  450. /package/{experiments/experiment-1-trace-capture → zuzuu/capture}/adapters/claude-code.mjs +0 -0
  451. /package/{experiments/experiment-1-trace-capture → zuzuu/capture}/adapters/codex.mjs +0 -0
  452. /package/{experiments/experiment-1-trace-capture → zuzuu/capture}/adapters/gemini-cli.mjs +0 -0
  453. /package/{experiments/experiment-1-trace-capture → zuzuu/capture}/adapters/host-adapter.mjs +0 -0
  454. /package/{experiments/experiment-1-trace-capture → zuzuu/capture}/adapters/opencode.mjs +0 -0
  455. /package/{experiments/experiment-1-trace-capture → zuzuu/capture}/adapters/pi.mjs +0 -0
  456. /package/{experiments/experiment-1-trace-capture → zuzuu/capture}/adapters/registry.mjs +0 -0
  457. /package/{experiments/experiment-1-trace-capture → zuzuu/capture}/adapters/signals.mjs +0 -0
  458. /package/{experiments/experiment-1-trace-capture → zuzuu/capture}/core/event.mjs +0 -0
  459. /package/{experiments/experiment-1-trace-capture → zuzuu/capture}/core/ids.mjs +0 -0
  460. /package/{experiments/experiment-1-trace-capture → zuzuu/capture}/core/otlp.mjs +0 -0
  461. /package/{experiments/experiment-1-trace-capture → zuzuu/capture}/core/render.mjs +0 -0
  462. /package/{experiments/experiment-1-trace-capture → zuzuu/capture}/core/spans.mjs +0 -0
@@ -0,0 +1,334 @@
1
+ import os from "node:os";
2
+ import crypto from "node:crypto";
3
+ import { execFile } from "node:child_process";
4
+ import { promisify } from "node:util";
5
+ import pty from "@lydell/node-pty";
6
+ import xtermHeadless from "@xterm/headless";
7
+ import addonSerialize from "@xterm/addon-serialize";
8
+ // Both packages are CJS bundles without ESM named exports.
9
+ const { Terminal } = xtermHeadless;
10
+ const { SerializeAddon } = addonSerialize;
11
+ import { ServerOp, FLOW_HIGH_WATER, FLOW_LOW_WATER, } from "./protocol/index.js";
12
+ import { encodeFrame } from "./frames.js";
13
+ import { toRel } from "./safe-path.js";
14
+ import { buildInjection, cleanupInjection } from "./shell-integration/inject.js";
15
+ const execFileAsync = promisify(execFile);
16
+ const SCROLLBACK = 10_000;
17
+ const CWD_POLL_MS = 2_500;
18
+ /** asciicast ring buffer caps */
19
+ const REC_MAX_BYTES = 2 * 1024 * 1024;
20
+ const REC_MAX_EVENTS = 10_000;
21
+ /** Resolve the live working directory of a process, shell-agnostically. */
22
+ async function processCwd(pid) {
23
+ try {
24
+ if (process.platform === "linux") {
25
+ const { stdout } = await execFileAsync("readlink", [`/proc/${pid}/cwd`], { timeout: 1000 });
26
+ return stdout.trim() || null;
27
+ }
28
+ // darwin: -Fn prints "p<pid>" then "n<path>" lines
29
+ const { stdout } = await execFileAsync("lsof", ["-a", "-p", String(pid), "-d", "cwd", "-Fn"], { timeout: 2000 });
30
+ const line = stdout.split("\n").find((l) => l.startsWith("n"));
31
+ return line ? line.slice(1) : null;
32
+ }
33
+ catch {
34
+ return null;
35
+ }
36
+ }
37
+ /** Parse an OSC 7 payload `file://host/path` into a decoded absolute path. */
38
+ export function parseOsc7(payload) {
39
+ const m = /^file:\/\/[^/]*(\/.*)$/.exec(payload);
40
+ if (!m)
41
+ return null;
42
+ try {
43
+ return decodeURIComponent(m[1]);
44
+ }
45
+ catch {
46
+ return m[1];
47
+ }
48
+ }
49
+ function pickShell() {
50
+ if (process.platform === "win32")
51
+ return process.env.COMSPEC ?? "cmd.exe";
52
+ return process.env.SHELL ?? (process.platform === "darwin" ? "/bin/zsh" : "/bin/bash");
53
+ }
54
+ /**
55
+ * A PTY whose lifetime is decoupled from any WebSocket. A headless xterm
56
+ * mirrors all output so a (re)attaching client gets an accurate replay of
57
+ * screen + scrollback via the serialize addon, then streams live.
58
+ *
59
+ * Flow control: while a client is attached we count PTY output bytes in
60
+ * flight (sent but not yet acked by the client's `term.write` callbacks).
61
+ * Above the high-water mark the PTY is paused — backpressure propagates to
62
+ * the kernel pty buffer, so `yes` / giant `cat` never overruns the browser.
63
+ */
64
+ export class Session {
65
+ cwd;
66
+ root;
67
+ onUpdate;
68
+ id = crypto.randomBytes(8).toString("hex");
69
+ createdAt = Date.now();
70
+ title;
71
+ alive = true;
72
+ /** live working directory of the shell (absolute) */
73
+ cwdAbs;
74
+ pty;
75
+ mirror;
76
+ serializer = new SerializeAddon();
77
+ socket = null;
78
+ inflight = 0;
79
+ paused = false;
80
+ exitPayload = null;
81
+ cwdTimer = null;
82
+ cwdPolling = false;
83
+ /** true once OSC 7 has reported cwd — the poll fallback then stops */
84
+ oscCwd = false;
85
+ tempDir;
86
+ // asciicast v2 ring buffer ("o" + "r" only — input is never recorded)
87
+ castEvents = [];
88
+ castBytes = 0;
89
+ castTruncated = false;
90
+ constructor(cwd, root, cols = 80, rows = 24, onUpdate) {
91
+ this.cwd = cwd;
92
+ this.root = root;
93
+ this.onUpdate = onUpdate;
94
+ this.cwdAbs = cwd;
95
+ const shell = pickShell();
96
+ this.title = shell.split("/").pop() ?? shell;
97
+ this.mirror = new Terminal({ cols, rows, scrollback: SCROLLBACK, allowProposedApi: true });
98
+ this.mirror.loadAddon(this.serializer);
99
+ // OSC 7: the shell reports its real cwd instantly/exactly; this makes
100
+ // the poll loop a fallback for shells where the hook didn't load.
101
+ this.mirror.parser.registerOscHandler(7, (payload) => {
102
+ const dir = parseOsc7(payload);
103
+ if (dir) {
104
+ this.oscCwd = true;
105
+ this.stopCwdPolling();
106
+ if (dir !== this.cwdAbs) {
107
+ this.cwdAbs = dir;
108
+ this.send(encodeFrame(ServerOp.Cwd, JSON.stringify(this.cwdPayload())));
109
+ this.onUpdate();
110
+ }
111
+ }
112
+ return true;
113
+ });
114
+ const injection = process.platform === "win32" ? null : buildInjection(shell);
115
+ this.tempDir = injection?.tempDir;
116
+ const args = injection?.args ?? (process.platform === "win32" ? [] : ["-l"]);
117
+ this.pty = pty.spawn(shell, args, {
118
+ name: "xterm-256color",
119
+ cols,
120
+ rows,
121
+ cwd,
122
+ env: {
123
+ ...process.env,
124
+ ...injection?.env,
125
+ TERM: "xterm-256color",
126
+ COLORTERM: "truecolor",
127
+ WEBCODE: "1",
128
+ },
129
+ });
130
+ this.pty.onData((data) => {
131
+ this.mirror.write(data);
132
+ this.recordEvent("o", data);
133
+ const proc = this.pty.process;
134
+ if (proc && proc !== this.title) {
135
+ this.title = proc;
136
+ this.send(encodeFrame(ServerOp.Title, JSON.stringify({ title: this.title })));
137
+ this.onUpdate();
138
+ }
139
+ if (this.socket) {
140
+ const frame = encodeFrame(ServerOp.Output, Buffer.from(data, "utf8"));
141
+ this.inflight += frame.length - 1;
142
+ this.send(frame);
143
+ if (!this.paused && this.inflight > FLOW_HIGH_WATER) {
144
+ this.paused = true;
145
+ this.pty.pause();
146
+ }
147
+ }
148
+ });
149
+ this.pty.onExit(({ exitCode, signal }) => {
150
+ this.alive = false;
151
+ this.exitPayload = JSON.stringify({ exitCode, signal });
152
+ this.send(encodeFrame(ServerOp.Exit, this.exitPayload));
153
+ this.onUpdate();
154
+ });
155
+ }
156
+ /** Single-attachment model: a new client takes over the session. */
157
+ attach(ws) {
158
+ if (this.socket && this.socket !== ws) {
159
+ this.socket.close(4000, "session attached elsewhere");
160
+ }
161
+ this.socket = ws;
162
+ this.resetFlow();
163
+ const snapshot = this.serializer.serialize({ scrollback: SCROLLBACK });
164
+ ws.send(encodeFrame(ServerOp.Replay, snapshot));
165
+ ws.send(encodeFrame(ServerOp.Cwd, JSON.stringify(this.cwdPayload())));
166
+ if (!this.alive && this.exitPayload) {
167
+ ws.send(encodeFrame(ServerOp.Exit, this.exitPayload));
168
+ }
169
+ this.startCwdPolling();
170
+ }
171
+ detach(ws) {
172
+ if (this.socket === ws) {
173
+ this.socket = null;
174
+ this.resetFlow();
175
+ this.stopCwdPolling();
176
+ }
177
+ }
178
+ // ── cwd tracking ───────────────────────────────────────────────────
179
+ cwdPayload() {
180
+ const inside = this.cwdAbs === this.root || this.cwdAbs.startsWith(this.root + "/");
181
+ return inside
182
+ ? { cwd: toRel(this.root, this.cwdAbs) }
183
+ : { cwd: this.cwdAbs, outside: true };
184
+ }
185
+ startCwdPolling() {
186
+ if (this.cwdTimer || !this.alive || this.oscCwd)
187
+ return;
188
+ this.cwdTimer = setInterval(() => {
189
+ if (this.cwdPolling)
190
+ return;
191
+ this.cwdPolling = true;
192
+ void processCwd(this.pty.pid)
193
+ .then((dir) => {
194
+ if (dir && dir !== this.cwdAbs) {
195
+ this.cwdAbs = dir;
196
+ this.send(encodeFrame(ServerOp.Cwd, JSON.stringify(this.cwdPayload())));
197
+ this.onUpdate();
198
+ }
199
+ })
200
+ .finally(() => {
201
+ this.cwdPolling = false;
202
+ });
203
+ }, CWD_POLL_MS);
204
+ }
205
+ stopCwdPolling() {
206
+ if (this.cwdTimer) {
207
+ clearInterval(this.cwdTimer);
208
+ this.cwdTimer = null;
209
+ }
210
+ }
211
+ // ── asciicast recording ────────────────────────────────────────────
212
+ recordEvent(code, data) {
213
+ this.castEvents.push([(Date.now() - this.createdAt) / 1000, code, data]);
214
+ this.castBytes += data.length;
215
+ while (this.castEvents.length > REC_MAX_EVENTS ||
216
+ (this.castBytes > REC_MAX_BYTES && this.castEvents.length > 1)) {
217
+ const dropped = this.castEvents.shift();
218
+ this.castBytes -= dropped[2].length;
219
+ this.castTruncated = true;
220
+ }
221
+ }
222
+ /** Serialize the buffer as asciicast v2 (NDJSON). */
223
+ recording() {
224
+ const header = {
225
+ version: 2,
226
+ width: this.pty.cols,
227
+ height: this.pty.rows,
228
+ timestamp: Math.floor(this.createdAt / 1000),
229
+ title: `webcode — ${this.title}`,
230
+ env: { SHELL: process.env.SHELL ?? "", TERM: "xterm-256color" },
231
+ };
232
+ const lines = [JSON.stringify(header)];
233
+ for (const ev of this.castEvents) {
234
+ lines.push(JSON.stringify([Math.round(ev[0] * 1000) / 1000, ev[1], ev[2]]));
235
+ }
236
+ return lines.join("\n") + "\n";
237
+ }
238
+ write(data) {
239
+ if (this.alive)
240
+ this.pty.write(data);
241
+ }
242
+ resize(cols, rows) {
243
+ if (!Number.isInteger(cols) || !Number.isInteger(rows))
244
+ return;
245
+ if (cols < 2 || rows < 1 || cols > 1000 || rows > 1000)
246
+ return;
247
+ this.mirror.resize(cols, rows);
248
+ if (this.alive)
249
+ this.pty.resize(cols, rows);
250
+ this.recordEvent("r", `${cols}x${rows}`);
251
+ }
252
+ /** Client reports bytes it has finished rendering. */
253
+ ack(bytes) {
254
+ if (!Number.isFinite(bytes) || bytes < 0)
255
+ return;
256
+ this.inflight = Math.max(0, this.inflight - bytes);
257
+ if (this.paused && this.inflight < FLOW_LOW_WATER) {
258
+ this.paused = false;
259
+ if (this.alive)
260
+ this.pty.resume();
261
+ }
262
+ }
263
+ /** Nobody is listening: stop counting and let the PTY run free. */
264
+ resetFlow() {
265
+ this.inflight = 0;
266
+ if (this.paused) {
267
+ this.paused = false;
268
+ if (this.alive)
269
+ this.pty.resume();
270
+ }
271
+ }
272
+ send(frame) {
273
+ if (this.socket && this.socket.readyState === this.socket.OPEN) {
274
+ this.socket.send(frame);
275
+ }
276
+ }
277
+ kill() {
278
+ this.stopCwdPolling();
279
+ this.socket?.close(1000, "session closed");
280
+ this.socket = null;
281
+ if (this.alive) {
282
+ try {
283
+ this.pty.kill();
284
+ }
285
+ catch {
286
+ // already gone
287
+ }
288
+ }
289
+ this.mirror.dispose();
290
+ cleanupInjection(this.tempDir);
291
+ }
292
+ info() {
293
+ return {
294
+ id: this.id,
295
+ title: this.title,
296
+ cwd: this.cwdAbs,
297
+ alive: this.alive,
298
+ createdAt: this.createdAt,
299
+ };
300
+ }
301
+ }
302
+ export class SessionManager {
303
+ defaultCwd;
304
+ sessions = new Map();
305
+ constructor(defaultCwd = os.homedir()) {
306
+ this.defaultCwd = defaultCwd;
307
+ }
308
+ create(cwd, cols, rows) {
309
+ const session = new Session(cwd ?? this.defaultCwd, this.defaultCwd, cols, rows, () => { });
310
+ this.sessions.set(session.id, session);
311
+ return session;
312
+ }
313
+ get(id) {
314
+ return this.sessions.get(id);
315
+ }
316
+ list() {
317
+ return [...this.sessions.values()]
318
+ .sort((a, b) => a.createdAt - b.createdAt)
319
+ .map((s) => s.info());
320
+ }
321
+ close(id) {
322
+ const session = this.sessions.get(id);
323
+ if (!session)
324
+ return false;
325
+ session.kill();
326
+ this.sessions.delete(id);
327
+ return true;
328
+ }
329
+ shutdown() {
330
+ for (const session of this.sessions.values())
331
+ session.kill();
332
+ this.sessions.clear();
333
+ }
334
+ }
@@ -0,0 +1,70 @@
1
+ import fs from "node:fs";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import crypto from "node:crypto";
5
+ import { fileURLToPath } from "node:url";
6
+ const HERE = path.dirname(fileURLToPath(import.meta.url));
7
+ function readScript(name) {
8
+ // scripts sit beside this module in src; tsc copies them to dist via the
9
+ // build step (see package.json), so resolve relative to the compiled file.
10
+ return fs.readFileSync(path.join(HERE, name), "utf8");
11
+ }
12
+ /**
13
+ * Build the spawn args + env that load webcode's OSC 133 / OSC 7 shell
14
+ * integration after the user's own rc. Returns null for shells we don't
15
+ * integrate (caller spawns as before and falls back to cwd polling).
16
+ *
17
+ * Mirrors VS Code's approach: a temp ZDOTDIR for zsh, --rcfile for bash,
18
+ * a vendor conf.d for fish.
19
+ */
20
+ export function buildInjection(shell) {
21
+ const base = path.basename(shell);
22
+ if (base === "zsh") {
23
+ const dir = mkTemp();
24
+ const prevZdotdir = process.env.ZDOTDIR ?? os.homedir();
25
+ // Each entry point sources the user's original, and .zshrc then adds us.
26
+ const sourcePrev = (file) => `[ -f "${prevZdotdir}/${file}" ] && WEBCODE_IN_INIT=1 . "${prevZdotdir}/${file}"\n`;
27
+ write(dir, ".zshenv", sourcePrev(".zshenv"));
28
+ write(dir, ".zprofile", sourcePrev(".zprofile"));
29
+ write(dir, ".zlogin", sourcePrev(".zlogin"));
30
+ write(dir, ".zshrc", sourcePrev(".zshrc") + readScript("webcode.zsh"));
31
+ return {
32
+ args: ["-l"],
33
+ env: { ZDOTDIR: dir, WEBCODE_ZDOTDIR_PREV: prevZdotdir },
34
+ tempDir: dir,
35
+ };
36
+ }
37
+ if (base === "bash") {
38
+ const dir = mkTemp();
39
+ const rc = path.join(dir, "rc.bash");
40
+ fs.writeFileSync(rc, `[ -f ~/.bashrc ] && . ~/.bashrc\n` + readScript("webcode.bash"), "utf8");
41
+ // interactive (not login) so --rcfile is honored; the rc sources ~/.bashrc
42
+ return { args: ["--rcfile", rc, "-i"], env: {}, tempDir: dir };
43
+ }
44
+ if (base === "fish") {
45
+ const dir = mkTemp();
46
+ const confDir = path.join(dir, "fish", "vendor_conf.d");
47
+ fs.mkdirSync(confDir, { recursive: true });
48
+ fs.writeFileSync(path.join(confDir, "webcode.fish"), readScript("webcode.fish"), "utf8");
49
+ // fish reads conf.d from each XDG_DATA_DIRS/fish entry
50
+ const prev = process.env.XDG_DATA_DIRS ?? "/usr/local/share:/usr/share";
51
+ return {
52
+ args: ["-l"],
53
+ env: { XDG_DATA_DIRS: `${dir}:${prev}` },
54
+ tempDir: dir,
55
+ };
56
+ }
57
+ return null;
58
+ }
59
+ function mkTemp() {
60
+ const dir = path.join(os.tmpdir(), `webcode-si-${crypto.randomBytes(6).toString("hex")}`);
61
+ fs.mkdirSync(dir, { recursive: true });
62
+ return dir;
63
+ }
64
+ function write(dir, file, content) {
65
+ fs.writeFileSync(path.join(dir, file), content, "utf8");
66
+ }
67
+ export function cleanupInjection(tempDir) {
68
+ if (tempDir)
69
+ fs.rm(tempDir, { recursive: true, force: true }, () => { });
70
+ }
@@ -0,0 +1,41 @@
1
+ # webcode shell integration (bash) — OSC 133 semantic prompts + OSC 7 cwd.
2
+ # Sourced from a temp --rcfile after the user's ~/.bashrc has loaded.
3
+ # Uses the bash-preexec pattern (DEBUG trap + PROMPT_COMMAND) since bash has
4
+ # no native preexec/precmd hooks.
5
+ if [[ -n "$WEBCODE" && -z "$WEBCODE_SI_LOADED" ]]; then
6
+ WEBCODE_SI_LOADED=1
7
+
8
+ __webcode_osc7() {
9
+ printf '\033]7;file://%s%s\033\\' "${HOSTNAME:-localhost}" "$PWD"
10
+ }
11
+
12
+ # Fires before drawing each prompt: close previous command (D;exit), emit
13
+ # cwd (OSC 7) and prompt start (A). $? must be captured first.
14
+ __webcode_prompt() {
15
+ local exit=$?
16
+ printf '\033]133;D;%s\033\\' "$exit"
17
+ __webcode_osc7
18
+ printf '\033]133;A\033\\'
19
+ __webcode_preexec_armed=1
20
+ }
21
+
22
+ # DEBUG trap fires before each command runs → emit output start (C). Armed
23
+ # once per prompt so it doesn't fire for PROMPT_COMMAND's own subshells.
24
+ __webcode_preexec_armed=0
25
+ __webcode_debug() {
26
+ if [[ "$__webcode_preexec_armed" == 1 && "$BASH_COMMAND" != "__webcode_prompt" ]]; then
27
+ __webcode_preexec_armed=0
28
+ printf '\033]133;C\033\\'
29
+ fi
30
+ }
31
+
32
+ # mark prompt end (B = command start region)
33
+ PS1="$PS1"'\[\033]133;B\033\\\]'
34
+
35
+ case "$PROMPT_COMMAND" in
36
+ *__webcode_prompt*) ;;
37
+ "") PROMPT_COMMAND="__webcode_prompt" ;;
38
+ *) PROMPT_COMMAND="__webcode_prompt;$PROMPT_COMMAND" ;;
39
+ esac
40
+ trap '__webcode_debug' DEBUG
41
+ fi
@@ -0,0 +1,28 @@
1
+ # webcode shell integration (fish) — OSC 133 semantic prompts + OSC 7 cwd.
2
+ # Dropped into a temp vendor_conf.d so fish auto-loads it after user config.
3
+ if test -n "$WEBCODE"; and not set -q WEBCODE_SI_LOADED
4
+ set -g WEBCODE_SI_LOADED 1
5
+
6
+ function __webcode_osc7 --on-variable PWD
7
+ printf '\033]7;file://%s%s\033\\' (hostname) "$PWD"
8
+ end
9
+
10
+ # prompt start (A) + previous-command done (D;exit)
11
+ function __webcode_prompt_start --on-event fish_prompt
12
+ printf '\033]133;D;%s\033\\' $status
13
+ __webcode_osc7
14
+ printf '\033]133;A\033\\'
15
+ end
16
+
17
+ # command start (C)
18
+ function __webcode_preexec --on-event fish_preexec
19
+ printf '\033]133;C\033\\'
20
+ end
21
+
22
+ # mark prompt end (B) by wrapping fish_prompt
23
+ functions -q __webcode_orig_fish_prompt; or functions -c fish_prompt __webcode_orig_fish_prompt
24
+ function fish_prompt
25
+ __webcode_orig_fish_prompt
26
+ printf '\033]133;B\033\\'
27
+ end
28
+ end
@@ -0,0 +1,35 @@
1
+ # webcode shell integration (zsh) — emits OSC 133 semantic prompts + OSC 7 cwd.
2
+ # Sourced from a temp ZDOTDIR .zshrc after the user's own rc has loaded.
3
+ # Guarded so it only runs inside webcode and only once.
4
+ if [[ -n "$WEBCODE" && -z "$WEBCODE_SI_LOADED" ]]; then
5
+ WEBCODE_SI_LOADED=1
6
+
7
+ __webcode_osc7() {
8
+ printf '\033]7;file://%s%s\033\\' "$HOST" "$PWD"
9
+ }
10
+
11
+ # prompt start (A) + previous-command done (D;exit) live in precmd;
12
+ # command start (C) lives in preexec.
13
+ __webcode_precmd() {
14
+ local exit=$?
15
+ printf '\033]133;D;%s\033\\' "$exit"
16
+ __webcode_osc7
17
+ printf '\033]133;A\033\\'
18
+ }
19
+
20
+ __webcode_preexec() {
21
+ printf '\033]133;C\033\\'
22
+ }
23
+
24
+ # mark the end of the prompt (B = command start region) by appending to PS1
25
+ PS1="$PS1"$'%{\033]133;B\033\\%}'
26
+
27
+ autoload -Uz add-zsh-hook 2>/dev/null
28
+ if (( $+functions[add-zsh-hook] )); then
29
+ add-zsh-hook precmd __webcode_precmd
30
+ add-zsh-hook preexec __webcode_preexec
31
+ else
32
+ precmd_functions+=(__webcode_precmd)
33
+ preexec_functions+=(__webcode_preexec)
34
+ fi
35
+ fi
@@ -0,0 +1,48 @@
1
+ import fsp from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { resolveSafe } from "./safe-path.js";
4
+ const WORKFLOW_DIR = ".webcode/workflows";
5
+ /** List workflows stored under .webcode/workflows/*.json in the workspace. */
6
+ export async function listWorkflows(root) {
7
+ let dir;
8
+ try {
9
+ dir = await resolveSafe(root, WORKFLOW_DIR);
10
+ }
11
+ catch {
12
+ return [];
13
+ }
14
+ let names;
15
+ try {
16
+ names = await fsp.readdir(dir);
17
+ }
18
+ catch {
19
+ return []; // dir doesn't exist yet
20
+ }
21
+ const workflows = [];
22
+ for (const name of names) {
23
+ if (!name.endsWith(".json"))
24
+ continue;
25
+ try {
26
+ const raw = await fsp.readFile(path.join(dir, name), "utf8");
27
+ const wf = JSON.parse(raw);
28
+ if (wf.name && wf.command)
29
+ workflows.push(wf);
30
+ }
31
+ catch {
32
+ // skip malformed
33
+ }
34
+ }
35
+ return workflows.sort((a, b) => a.name.localeCompare(b.name));
36
+ }
37
+ /** Persist a workflow as .webcode/workflows/<slug>.json. */
38
+ export async function saveWorkflow(root, wf) {
39
+ const slug = wf.name
40
+ .toLowerCase()
41
+ .replace(/[^a-z0-9]+/g, "-")
42
+ .replace(/^-|-$/g, "") || "workflow";
43
+ const rel = `${WORKFLOW_DIR}/${slug}.json`;
44
+ const abs = await resolveSafe(root, rel);
45
+ await fsp.mkdir(path.dirname(abs), { recursive: true });
46
+ await fsp.writeFile(abs, JSON.stringify(wf, null, 2) + "\n", "utf8");
47
+ return rel;
48
+ }
@@ -0,0 +1,69 @@
1
+ import { watch } from "chokidar";
2
+ import { resolveSafe } from "./safe-path.js";
3
+ const DEBOUNCE_MS = 120;
4
+ const MAX_WATCHES = 200;
5
+ /**
6
+ * The explorer watches only the directories it currently has expanded —
7
+ * non-recursive, one watcher each — so fd usage stays bounded no matter how
8
+ * big the workspace is. Events are debounced per directory and the client
9
+ * just refetches that directory's listing.
10
+ */
11
+ export function handleFsSocket(ws, root) {
12
+ const watchers = new Map();
13
+ const pending = new Map();
14
+ const notify = (relPath) => {
15
+ clearTimeout(pending.get(relPath));
16
+ pending.set(relPath, setTimeout(() => {
17
+ pending.delete(relPath);
18
+ if (ws.readyState === ws.OPEN) {
19
+ const msg = { type: "changed", path: relPath };
20
+ ws.send(JSON.stringify(msg));
21
+ }
22
+ }, DEBOUNCE_MS));
23
+ };
24
+ ws.on("message", (raw) => {
25
+ void (async () => {
26
+ let msg;
27
+ try {
28
+ msg = JSON.parse(raw.toString());
29
+ }
30
+ catch {
31
+ return;
32
+ }
33
+ if (msg.type === "watch") {
34
+ if (watchers.has(msg.path) || watchers.size >= MAX_WATCHES)
35
+ return;
36
+ let abs;
37
+ try {
38
+ abs = await resolveSafe(root, msg.path);
39
+ }
40
+ catch {
41
+ return;
42
+ }
43
+ const watcher = watch(abs, {
44
+ depth: 0,
45
+ ignoreInitial: true,
46
+ followSymlinks: false,
47
+ });
48
+ watcher.on("all", () => notify(msg.path));
49
+ watcher.on("error", () => { });
50
+ watchers.set(msg.path, watcher);
51
+ }
52
+ else if (msg.type === "unwatch") {
53
+ const watcher = watchers.get(msg.path);
54
+ if (watcher) {
55
+ watchers.delete(msg.path);
56
+ void watcher.close();
57
+ }
58
+ }
59
+ })();
60
+ });
61
+ ws.on("close", () => {
62
+ for (const timer of pending.values())
63
+ clearTimeout(timer);
64
+ pending.clear();
65
+ for (const watcher of watchers.values())
66
+ void watcher.close();
67
+ watchers.clear();
68
+ });
69
+ }
@@ -0,0 +1,42 @@
1
+ import { ClientOp } from "./protocol/index.js";
2
+ import { decodeFrame } from "./frames.js";
3
+ export function handleTermSocket(ws, session) {
4
+ session.attach(ws);
5
+ ws.on("message", (raw, isBinary) => {
6
+ if (!isBinary && !Buffer.isBuffer(raw))
7
+ return;
8
+ let frame;
9
+ try {
10
+ frame = decodeFrame(Buffer.isBuffer(raw) ? raw : Buffer.from(raw));
11
+ }
12
+ catch {
13
+ return;
14
+ }
15
+ switch (frame.op) {
16
+ case ClientOp.Input:
17
+ session.write(frame.payload.toString("utf8"));
18
+ break;
19
+ case ClientOp.Resize: {
20
+ try {
21
+ const { cols, rows } = JSON.parse(frame.payload.toString("utf8"));
22
+ session.resize(cols, rows);
23
+ }
24
+ catch {
25
+ // ignore malformed resize
26
+ }
27
+ break;
28
+ }
29
+ case ClientOp.Ack: {
30
+ try {
31
+ const { bytes } = JSON.parse(frame.payload.toString("utf8"));
32
+ session.ack(bytes);
33
+ }
34
+ catch {
35
+ // ignore malformed ack
36
+ }
37
+ break;
38
+ }
39
+ }
40
+ });
41
+ ws.on("close", () => session.detach(ws));
42
+ }