@dyyz1993/codenomad 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (496) hide show
  1. package/README.md +173 -0
  2. package/dist/api-types.js +1 -0
  3. package/dist/auth/auth-store.js +134 -0
  4. package/dist/auth/http-auth.js +37 -0
  5. package/dist/auth/manager.js +140 -0
  6. package/dist/auth/password-hash.js +32 -0
  7. package/dist/auth/session-manager.js +17 -0
  8. package/dist/auth/token-manager.js +27 -0
  9. package/dist/background-processes/manager.js +576 -0
  10. package/dist/bin.js +24 -0
  11. package/dist/cli-upgrade.js +53 -0
  12. package/dist/cli-upgrade.test.js +31 -0
  13. package/dist/clients/connection-manager.js +93 -0
  14. package/dist/config/location.js +57 -0
  15. package/dist/config/schema.js +71 -0
  16. package/dist/events/bus.js +45 -0
  17. package/dist/filesystem/__tests__/browser.test.js +65 -0
  18. package/dist/filesystem/__tests__/search-cache.test.js +40 -0
  19. package/dist/filesystem/browser.js +306 -0
  20. package/dist/filesystem/search-cache.js +43 -0
  21. package/dist/filesystem/search.js +135 -0
  22. package/dist/index.js +477 -0
  23. package/dist/launcher.js +149 -0
  24. package/dist/loader.js +21 -0
  25. package/dist/logger.js +109 -0
  26. package/dist/opencode-config/README.md +32 -0
  27. package/dist/opencode-config/opencode.jsonc +3 -0
  28. package/dist/opencode-config/package-lock.json +380 -0
  29. package/dist/opencode-config/package.json +9 -0
  30. package/dist/opencode-config/plugin/codenomad.ts +62 -0
  31. package/dist/opencode-config/plugin/lib/background-process.ts +265 -0
  32. package/dist/opencode-config/plugin/lib/client.ts +133 -0
  33. package/dist/opencode-config/plugin/lib/request.ts +214 -0
  34. package/dist/opencode-config.js +26 -0
  35. package/dist/plugins/channel.js +40 -0
  36. package/dist/plugins/handlers.js +17 -0
  37. package/dist/plugins/voice-mode.js +78 -0
  38. package/dist/releases/dev-release-monitor.js +75 -0
  39. package/dist/releases/release-monitor.js +107 -0
  40. package/dist/server/__tests__/network-addresses.test.js +68 -0
  41. package/dist/server/__tests__/remote-proxy.test.js +204 -0
  42. package/dist/server/http-server.js +926 -0
  43. package/dist/server/network-addresses.js +114 -0
  44. package/dist/server/remote-proxy.js +466 -0
  45. package/dist/server/routes/auth-pages/login.html +135 -0
  46. package/dist/server/routes/auth-pages/token.html +93 -0
  47. package/dist/server/routes/auth.js +148 -0
  48. package/dist/server/routes/background-processes.js +78 -0
  49. package/dist/server/routes/events.js +66 -0
  50. package/dist/server/routes/filesystem.js +43 -0
  51. package/dist/server/routes/meta.js +44 -0
  52. package/dist/server/routes/plugin.js +70 -0
  53. package/dist/server/routes/remote-proxy.js +42 -0
  54. package/dist/server/routes/remote-servers.js +142 -0
  55. package/dist/server/routes/settings.js +69 -0
  56. package/dist/server/routes/sidecars.js +46 -0
  57. package/dist/server/routes/speech.js +63 -0
  58. package/dist/server/routes/storage.js +52 -0
  59. package/dist/server/routes/workspaces.js +221 -0
  60. package/dist/server/routes/worktrees.js +156 -0
  61. package/dist/server/tls.js +224 -0
  62. package/dist/settings/binaries.js +37 -0
  63. package/dist/settings/merge-patch.js +33 -0
  64. package/dist/settings/migrate.js +238 -0
  65. package/dist/settings/public-config.js +33 -0
  66. package/dist/settings/service.js +101 -0
  67. package/dist/settings/yaml-doc-store.js +96 -0
  68. package/dist/sidecars/manager.js +193 -0
  69. package/dist/speech/providers/openai-compatible.js +189 -0
  70. package/dist/speech/service.js +58 -0
  71. package/dist/storage/instance-store.js +56 -0
  72. package/dist/ui/__tests__/remote-ui.test.js +67 -0
  73. package/dist/ui/remote-ui.js +462 -0
  74. package/dist/workspaces/__tests__/git-worktrees.test.js +43 -0
  75. package/dist/workspaces/__tests__/spawn.test.js +140 -0
  76. package/dist/workspaces/git-mutations.js +98 -0
  77. package/dist/workspaces/git-status.js +323 -0
  78. package/dist/workspaces/git-worktrees.js +216 -0
  79. package/dist/workspaces/instance-events.js +180 -0
  80. package/dist/workspaces/manager.js +368 -0
  81. package/dist/workspaces/opencode-auth.js +34 -0
  82. package/dist/workspaces/opencode-auth.test.js +34 -0
  83. package/dist/workspaces/runtime.js +366 -0
  84. package/dist/workspaces/spawn.js +219 -0
  85. package/dist/workspaces/worktree-directory.js +74 -0
  86. package/dist/workspaces/worktree-map.js +116 -0
  87. package/package.json +50 -0
  88. package/public/apple-touch-icon-180x180.png +0 -0
  89. package/public/assets/ChangesTab-BRNmSjeC.js +2 -0
  90. package/public/assets/CodeNomad-Icon-bmTWNPXy.png +0 -0
  91. package/public/assets/DiffToolbar-DPPgfx42.js +1 -0
  92. package/public/assets/FilesTab-sEeGPOoz.js +2 -0
  93. package/public/assets/GitChangesTab-tJ-TCq0c.js +2 -0
  94. package/public/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  95. package/public/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  96. package/public/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  97. package/public/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  98. package/public/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  99. package/public/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  100. package/public/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  101. package/public/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  102. package/public/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  103. package/public/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  104. package/public/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  105. package/public/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  106. package/public/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  107. package/public/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  108. package/public/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  109. package/public/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  110. package/public/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  111. package/public/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  112. package/public/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  113. package/public/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  114. package/public/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  115. package/public/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  116. package/public/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  117. package/public/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  118. package/public/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  119. package/public/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  120. package/public/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  121. package/public/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  122. package/public/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  123. package/public/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  124. package/public/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  125. package/public/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  126. package/public/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  127. package/public/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  128. package/public/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  129. package/public/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  130. package/public/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  131. package/public/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  132. package/public/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  133. package/public/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  134. package/public/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  135. package/public/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  136. package/public/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  137. package/public/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  138. package/public/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  139. package/public/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  140. package/public/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  141. package/public/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  142. package/public/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  143. package/public/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  144. package/public/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  145. package/public/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  146. package/public/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  147. package/public/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  148. package/public/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  149. package/public/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  150. package/public/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  151. package/public/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  152. package/public/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  153. package/public/assets/SplitFilePanel-CHqNLZvU.js +1 -0
  154. package/public/assets/StatusTab-DMd0ByCA.js +1 -0
  155. package/public/assets/abap-BdImnpbu.js +1 -0
  156. package/public/assets/actionscript-3-CfeIJUat.js +1 -0
  157. package/public/assets/ada-bCR0ucgS.js +1 -0
  158. package/public/assets/align-justify-BWapkGTe.js +1 -0
  159. package/public/assets/andromeeda-C-Jbm3Hp.js +1 -0
  160. package/public/assets/angular-html-CU67Zn6k.js +1 -0
  161. package/public/assets/angular-ts-BwZT4LLn.js +1 -0
  162. package/public/assets/apache-Pmp26Uib.js +1 -0
  163. package/public/assets/apex-DhZLUxFE.js +1 -0
  164. package/public/assets/apl-dKokRX4l.js +1 -0
  165. package/public/assets/applescript-Co6uUVPk.js +1 -0
  166. package/public/assets/ara-BRHolxvo.js +1 -0
  167. package/public/assets/asciidoc-Dv7Oe6Be.js +1 -0
  168. package/public/assets/asm-D_Q5rh1f.js +1 -0
  169. package/public/assets/astro-CbQHKStN.js +1 -0
  170. package/public/assets/aurora-x-D-2ljcwZ.js +1 -0
  171. package/public/assets/awk-DMzUqQB5.js +1 -0
  172. package/public/assets/ayu-dark-Cv9koXgw.js +1 -0
  173. package/public/assets/ballerina-BFfxhgS-.js +1 -0
  174. package/public/assets/bat-BkioyH1T.js +1 -0
  175. package/public/assets/beancount-k_qm7-4y.js +1 -0
  176. package/public/assets/berry-D08WgyRC.js +1 -0
  177. package/public/assets/bibtex-CHM0blh-.js +1 -0
  178. package/public/assets/bicep-Bmn6On1c.js +1 -0
  179. package/public/assets/blade-DVc8C-J4.js +1 -0
  180. package/public/assets/bsl-BO_Y6i37.js +1 -0
  181. package/public/assets/bundle-full-CXlKQh5B.js +13 -0
  182. package/public/assets/c-BIGW1oBm.js +1 -0
  183. package/public/assets/cadence-Bv_4Rxtq.js +1 -0
  184. package/public/assets/cairo-KRGpt6FW.js +1 -0
  185. package/public/assets/catppuccin-frappe-DFWUc33u.js +1 -0
  186. package/public/assets/catppuccin-latte-C9dUb6Cb.js +1 -0
  187. package/public/assets/catppuccin-macchiato-DQyhUUbL.js +1 -0
  188. package/public/assets/catppuccin-mocha-D87Tk5Gz.js +1 -0
  189. package/public/assets/clarity-D53aC0YG.js +1 -0
  190. package/public/assets/clojure-P80f7IUj.js +1 -0
  191. package/public/assets/cmake-D1j8_8rp.js +1 -0
  192. package/public/assets/cobol-nwyudZeR.js +1 -0
  193. package/public/assets/codeowners-Bp6g37R7.js +1 -0
  194. package/public/assets/codeql-DsOJ9woJ.js +1 -0
  195. package/public/assets/coffee-Ch7k5sss.js +1 -0
  196. package/public/assets/common-lisp-Cg-RD9OK.js +1 -0
  197. package/public/assets/coq-DkFqJrB1.js +1 -0
  198. package/public/assets/cpp-CofmeUqb.js +1 -0
  199. package/public/assets/crystal-tKQVLTB8.js +1 -0
  200. package/public/assets/csharp-CX12Zw3r.js +1 -0
  201. package/public/assets/css-DPfMkruS.js +1 -0
  202. package/public/assets/csv-fuZLfV_i.js +1 -0
  203. package/public/assets/cue-D82EKSYY.js +1 -0
  204. package/public/assets/cypher-COkxafJQ.js +1 -0
  205. package/public/assets/d-85-TOEBH.js +1 -0
  206. package/public/assets/dark-plus-eOWES_5F.js +1 -0
  207. package/public/assets/dart-CF10PKvl.js +1 -0
  208. package/public/assets/dax-CEL-wOlO.js +1 -0
  209. package/public/assets/desktop-BmXAJ9_W.js +1 -0
  210. package/public/assets/diff-D97Zzqfu.js +1 -0
  211. package/public/assets/diff-viewer-BFtW5J8P.js +1 -0
  212. package/public/assets/docker-BcOcwvcX.js +1 -0
  213. package/public/assets/dotenv-Da5cRb03.js +1 -0
  214. package/public/assets/dracula-BzJJZx-M.js +1 -0
  215. package/public/assets/dracula-soft-BXkSAIEj.js +1 -0
  216. package/public/assets/dream-maker-BtqSS_iP.js +1 -0
  217. package/public/assets/edge-BkV0erSs.js +1 -0
  218. package/public/assets/elixir-CDX3lj18.js +1 -0
  219. package/public/assets/elm-DbKCFpqz.js +1 -0
  220. package/public/assets/emacs-lisp-C9XAeP06.js +1 -0
  221. package/public/assets/erb-BOJIQeun.js +1 -0
  222. package/public/assets/erlang-DsQrWhSR.js +1 -0
  223. package/public/assets/everforest-dark-BgDCqdQA.js +1 -0
  224. package/public/assets/everforest-light-C8M2exoo.js +1 -0
  225. package/public/assets/fast-diff-vendor-DgdwVvTQ.js +1 -0
  226. package/public/assets/fennel-BYunw83y.js +1 -0
  227. package/public/assets/fish-BvzEVeQv.js +1 -0
  228. package/public/assets/fluent-C4IJs8-o.js +1 -0
  229. package/public/assets/fortran-fixed-form-BZjJHVRy.js +1 -0
  230. package/public/assets/fortran-free-form-D22FLkUw.js +1 -0
  231. package/public/assets/fsharp-CXgrBDvD.js +1 -0
  232. package/public/assets/gdresource-B7Tvp0Sc.js +1 -0
  233. package/public/assets/gdscript-DTMYz4Jt.js +1 -0
  234. package/public/assets/gdshader-DkwncUOv.js +1 -0
  235. package/public/assets/genie-D0YGMca9.js +1 -0
  236. package/public/assets/gherkin-DyxjwDmM.js +1 -0
  237. package/public/assets/git-commit-F4YmCXRG.js +1 -0
  238. package/public/assets/git-diff-vendor-CSgooKT_.js +52 -0
  239. package/public/assets/git-diff-vendor-HAZkIolJ.css +19 -0
  240. package/public/assets/git-rebase-r7XF79zn.js +1 -0
  241. package/public/assets/github-dark-DHJKELXO.js +1 -0
  242. package/public/assets/github-dark-default-Cuk6v7N8.js +1 -0
  243. package/public/assets/github-dark-dimmed-DH5Ifo-i.js +1 -0
  244. package/public/assets/github-dark-high-contrast-E3gJ1_iC.js +1 -0
  245. package/public/assets/github-light-DAi9KRSo.js +1 -0
  246. package/public/assets/github-light-default-D7oLnXFd.js +1 -0
  247. package/public/assets/github-light-high-contrast-BfjtVDDH.js +1 -0
  248. package/public/assets/gleam-BspZqrRM.js +1 -0
  249. package/public/assets/glimmer-js-Rg0-pVw9.js +1 -0
  250. package/public/assets/glimmer-ts-U6CK756n.js +1 -0
  251. package/public/assets/glsl-DplSGwfg.js +1 -0
  252. package/public/assets/gnuplot-DdkO51Og.js +1 -0
  253. package/public/assets/go-Dn2_MT6a.js +1 -0
  254. package/public/assets/graphql-ChdNCCLP.js +1 -0
  255. package/public/assets/groovy-gcz8RCvz.js +1 -0
  256. package/public/assets/gruvbox-dark-hard-CFHQjOhq.js +1 -0
  257. package/public/assets/gruvbox-dark-medium-GsRaNv29.js +1 -0
  258. package/public/assets/gruvbox-dark-soft-CVdnzihN.js +1 -0
  259. package/public/assets/gruvbox-light-hard-CH1njM8p.js +1 -0
  260. package/public/assets/gruvbox-light-medium-DRw_LuNl.js +1 -0
  261. package/public/assets/gruvbox-light-soft-hJgmCMqR.js +1 -0
  262. package/public/assets/hack-CaT9iCJl.js +1 -0
  263. package/public/assets/haml-B8DHNrY2.js +1 -0
  264. package/public/assets/handlebars-BL8al0AC.js +1 -0
  265. package/public/assets/haskell-Df6bDoY_.js +1 -0
  266. package/public/assets/haxe-CzTSHFRz.js +1 -0
  267. package/public/assets/hcl-BWvSN4gD.js +1 -0
  268. package/public/assets/highlight-vendor-8FKMu9os.js +10 -0
  269. package/public/assets/hjson-D5-asLiD.js +1 -0
  270. package/public/assets/hlsl-D3lLCCz7.js +1 -0
  271. package/public/assets/houston-DnULxvSX.js +1 -0
  272. package/public/assets/html-GMplVEZG.js +1 -0
  273. package/public/assets/html-derivative-BFtXZ54Q.js +1 -0
  274. package/public/assets/http-jrhK8wxY.js +1 -0
  275. package/public/assets/hurl-irOxFIW8.js +1 -0
  276. package/public/assets/hxml-Bvhsp5Yf.js +1 -0
  277. package/public/assets/hy-DFXneXwc.js +1 -0
  278. package/public/assets/imba-DGztddWO.js +1 -0
  279. package/public/assets/index-Bdy3MTIn.js +1 -0
  280. package/public/assets/index-BvRe9GiS.js +1 -0
  281. package/public/assets/index-Ctq8RqRf.js +1 -0
  282. package/public/assets/index-D-NvysdX.js +1 -0
  283. package/public/assets/index-D6RMBXUk.js +2 -0
  284. package/public/assets/index-DXI9DoVB.css +1 -0
  285. package/public/assets/index-DYWkPhKo.js +1 -0
  286. package/public/assets/index-D_FDiI6a.js +1 -0
  287. package/public/assets/index-Dty5bSHf.js +1 -0
  288. package/public/assets/index-H16e4Rqc.js +1 -0
  289. package/public/assets/ini-BEwlwnbL.js +1 -0
  290. package/public/assets/java-CylS5w8V.js +1 -0
  291. package/public/assets/javascript-wDzz0qaB.js +1 -0
  292. package/public/assets/jinja-4LBKfQ-Z.js +1 -0
  293. package/public/assets/jison-wvAkD_A8.js +1 -0
  294. package/public/assets/json-Cp-IABpG.js +1 -0
  295. package/public/assets/json5-C9tS-k6U.js +1 -0
  296. package/public/assets/jsonc-Des-eS-w.js +1 -0
  297. package/public/assets/jsonl-DcaNXYhu.js +1 -0
  298. package/public/assets/jsonnet-DFQXde-d.js +1 -0
  299. package/public/assets/jssm-C2t-YnRu.js +1 -0
  300. package/public/assets/jsx-g9-lgVsj.js +1 -0
  301. package/public/assets/julia-C8NyazO9.js +1 -0
  302. package/public/assets/kanagawa-dragon-CkXjmgJE.js +1 -0
  303. package/public/assets/kanagawa-lotus-CfQXZHmo.js +1 -0
  304. package/public/assets/kanagawa-wave-DWedfzmr.js +1 -0
  305. package/public/assets/kdl-DV7GczEv.js +1 -0
  306. package/public/assets/kotlin-BdnUsdx6.js +1 -0
  307. package/public/assets/kusto-BvAqAH-y.js +1 -0
  308. package/public/assets/laserwave-DUszq2jm.js +1 -0
  309. package/public/assets/latex-BUKiar2Z.js +1 -0
  310. package/public/assets/lean-DP1Csr6i.js +1 -0
  311. package/public/assets/less-B1dDrJ26.js +1 -0
  312. package/public/assets/light-plus-B7mTdjB0.js +1 -0
  313. package/public/assets/liquid-DYVedYrR.js +1 -0
  314. package/public/assets/llvm-BtvRca6l.js +1 -0
  315. package/public/assets/loading-CmEVQgyj.css +1 -0
  316. package/public/assets/loading-W2Y_wR0P.js +1 -0
  317. package/public/assets/log-2UxHyX5q.js +1 -0
  318. package/public/assets/logo-BtOb2qkB.js +1 -0
  319. package/public/assets/lua-BbnMAYS6.js +1 -0
  320. package/public/assets/luau-CXu1NL6O.js +1 -0
  321. package/public/assets/main-Bala0YJ4.js +57 -0
  322. package/public/assets/make-CHLpvVh8.js +1 -0
  323. package/public/assets/markdown-Cvjx9yec.js +1 -0
  324. package/public/assets/markdown-Db8cvZ4Z.js +315 -0
  325. package/public/assets/marko-CPi9NSCl.js +1 -0
  326. package/public/assets/material-theme-D5KoaKCx.js +1 -0
  327. package/public/assets/material-theme-darker-BfHTSMKl.js +1 -0
  328. package/public/assets/material-theme-lighter-B0m2ddpp.js +1 -0
  329. package/public/assets/material-theme-ocean-CyktbL80.js +1 -0
  330. package/public/assets/material-theme-palenight-Csfq5Kiy.js +1 -0
  331. package/public/assets/matlab-D7o27uSR.js +1 -0
  332. package/public/assets/mdc-DUICxH0z.js +1 -0
  333. package/public/assets/mdx-Cmh6b_Ma.js +1 -0
  334. package/public/assets/mermaid-DKYwYmdq.js +1 -0
  335. package/public/assets/min-dark-CafNBF8u.js +1 -0
  336. package/public/assets/min-light-CTRr51gU.js +1 -0
  337. package/public/assets/mipsasm-CKIfxQSi.js +1 -0
  338. package/public/assets/mojo-1DNp92w6.js +1 -0
  339. package/public/assets/monaco-viewer-DWQqXKm3.js +26 -0
  340. package/public/assets/monokai-D4h5O-jR.js +1 -0
  341. package/public/assets/move-Bu9oaDYs.js +1 -0
  342. package/public/assets/narrat-DRg8JJMk.js +1 -0
  343. package/public/assets/nextflow-CUEJCptM.js +1 -0
  344. package/public/assets/nginx-DknmC5AR.js +1 -0
  345. package/public/assets/night-owl-C39BiMTA.js +1 -0
  346. package/public/assets/nim-CVrawwO9.js +1 -0
  347. package/public/assets/nix-BbRYJGeE.js +1 -0
  348. package/public/assets/nord-Ddv68eIx.js +1 -0
  349. package/public/assets/nushell-C-sUppwS.js +1 -0
  350. package/public/assets/objective-c-DXmwc3jG.js +1 -0
  351. package/public/assets/objective-cpp-CLxacb5B.js +1 -0
  352. package/public/assets/ocaml-C0hk2d4L.js +1 -0
  353. package/public/assets/one-dark-pro-DVMEJ2y_.js +1 -0
  354. package/public/assets/one-light-PoHY5YXO.js +1 -0
  355. package/public/assets/pascal-D93ZcfNL.js +1 -0
  356. package/public/assets/perl-C0TMdlhV.js +1 -0
  357. package/public/assets/php-CDn_0X-4.js +1 -0
  358. package/public/assets/pkl-u5AG7uiY.js +1 -0
  359. package/public/assets/plastic-3e1v2bzS.js +1 -0
  360. package/public/assets/plsql-ChMvpjG-.js +1 -0
  361. package/public/assets/po-BTJTHyun.js +1 -0
  362. package/public/assets/poimandres-CS3Unz2-.js +1 -0
  363. package/public/assets/polar-C0HS_06l.js +1 -0
  364. package/public/assets/postcss-CXtECtnM.js +1 -0
  365. package/public/assets/powerquery-CEu0bR-o.js +1 -0
  366. package/public/assets/powershell-Dpen1YoG.js +1 -0
  367. package/public/assets/prisma-Dd19v3D-.js +1 -0
  368. package/public/assets/prolog-CbFg5uaA.js +1 -0
  369. package/public/assets/proto-DyJlTyXw.js +1 -0
  370. package/public/assets/pug-CGlum2m_.js +1 -0
  371. package/public/assets/puppet-BMWR74SV.js +1 -0
  372. package/public/assets/purescript-CklMAg4u.js +1 -0
  373. package/public/assets/python-B6aJPvgy.js +1 -0
  374. package/public/assets/qml-3beO22l8.js +1 -0
  375. package/public/assets/qmldir-C8lEn-DE.js +1 -0
  376. package/public/assets/qss-IeuSbFQv.js +1 -0
  377. package/public/assets/r-DiinP2Uv.js +1 -0
  378. package/public/assets/racket-BqYA7rlc.js +1 -0
  379. package/public/assets/raku-DXvB9xmW.js +1 -0
  380. package/public/assets/razor-WgofotgN.js +1 -0
  381. package/public/assets/red-bN70gL4F.js +1 -0
  382. package/public/assets/reg-C-SQnVFl.js +1 -0
  383. package/public/assets/regexp-CDVJQ6XC.js +1 -0
  384. package/public/assets/rel-C3B-1QV4.js +1 -0
  385. package/public/assets/riscv-BM1_JUlF.js +1 -0
  386. package/public/assets/rose-pine-BHrmToEH.js +1 -0
  387. package/public/assets/rose-pine-dawn-CnK8MTSM.js +1 -0
  388. package/public/assets/rose-pine-moon-NleAzG8P.js +1 -0
  389. package/public/assets/rosmsg-BJDFO7_C.js +1 -0
  390. package/public/assets/rst-B0xPkSld.js +1 -0
  391. package/public/assets/ruby-BvKwtOVI.js +1 -0
  392. package/public/assets/rust-B1yitclQ.js +1 -0
  393. package/public/assets/sas-cz2c8ADy.js +1 -0
  394. package/public/assets/sass-Cj5Yp3dK.js +1 -0
  395. package/public/assets/scala-C151Ov-r.js +1 -0
  396. package/public/assets/scheme-C98Dy4si.js +1 -0
  397. package/public/assets/scss-OYdSNvt2.js +1 -0
  398. package/public/assets/sdbl-DVxCFoDh.js +1 -0
  399. package/public/assets/shaderlab-Dg9Lc6iA.js +1 -0
  400. package/public/assets/shellscript-Yzrsuije.js +1 -0
  401. package/public/assets/shellsession-BADoaaVG.js +1 -0
  402. package/public/assets/slack-dark-BthQWCQV.js +1 -0
  403. package/public/assets/slack-ochin-DqwNpetd.js +1 -0
  404. package/public/assets/smalltalk-BERRCDM3.js +1 -0
  405. package/public/assets/snazzy-light-Bw305WKR.js +1 -0
  406. package/public/assets/solarized-dark-DXbdFlpD.js +1 -0
  407. package/public/assets/solarized-light-L9t79GZl.js +1 -0
  408. package/public/assets/solidity-BbcW6ACK.js +1 -0
  409. package/public/assets/soy-Brmx7dQM.js +1 -0
  410. package/public/assets/sparql-rVzFXLq3.js +1 -0
  411. package/public/assets/splunk-BtCnVYZw.js +1 -0
  412. package/public/assets/sql-BLtJtn59.js +1 -0
  413. package/public/assets/ssh-config-_ykCGR6B.js +1 -0
  414. package/public/assets/stata-BH5u7GGu.js +1 -0
  415. package/public/assets/stylus-BEDo0Tqx.js +1 -0
  416. package/public/assets/svelte-3Dk4HxPD.js +1 -0
  417. package/public/assets/swift-Dg5xB15N.js +1 -0
  418. package/public/assets/synthwave-84-CbfX1IO0.js +1 -0
  419. package/public/assets/system-verilog-CnnmHF94.js +1 -0
  420. package/public/assets/systemd-4A_iFExJ.js +1 -0
  421. package/public/assets/talonscript-CkByrt1z.js +1 -0
  422. package/public/assets/tasl-QIJgUcNo.js +1 -0
  423. package/public/assets/tcl-dwOrl1Do.js +1 -0
  424. package/public/assets/templ-W15q3VgB.js +1 -0
  425. package/public/assets/terraform-BETggiCN.js +1 -0
  426. package/public/assets/tex-Cppo0RY3.js +1 -0
  427. package/public/assets/tokyo-night-hegEt444.js +1 -0
  428. package/public/assets/toml-vGWfd6FD.js +1 -0
  429. package/public/assets/tool-call-D0BYXlFe.js +59 -0
  430. package/public/assets/ts-tags-zn1MmPIZ.js +1 -0
  431. package/public/assets/tsv-B_m7g4N7.js +1 -0
  432. package/public/assets/tsx-COt5Ahok.js +1 -0
  433. package/public/assets/turtle-BsS91CYL.js +1 -0
  434. package/public/assets/twig-CO9l9SDP.js +1 -0
  435. package/public/assets/typescript-BPQ3VLAy.js +1 -0
  436. package/public/assets/typespec-Df68jz8_.js +1 -0
  437. package/public/assets/typst-DHCkPAjA.js +1 -0
  438. package/public/assets/unified-picker-QgONWj_1.js +1 -0
  439. package/public/assets/v-BcVCzyr7.js +1 -0
  440. package/public/assets/vala-CsfeWuGM.js +1 -0
  441. package/public/assets/vb-D17OF-Vu.js +1 -0
  442. package/public/assets/verilog-BQ8w6xss.js +1 -0
  443. package/public/assets/vesper-DU1UobuO.js +1 -0
  444. package/public/assets/vhdl-CeAyd5Ju.js +1 -0
  445. package/public/assets/viml-CJc9bBzg.js +1 -0
  446. package/public/assets/vitesse-black-Bkuqu6BP.js +1 -0
  447. package/public/assets/vitesse-dark-D0r3Knsf.js +1 -0
  448. package/public/assets/vitesse-light-CVO1_9PV.js +1 -0
  449. package/public/assets/vue-CCoi5OLL.js +1 -0
  450. package/public/assets/vue-html-DAAvJJDi.js +1 -0
  451. package/public/assets/vue-vine-_Ih-lPRR.js +1 -0
  452. package/public/assets/vyper-CDx5xZoG.js +1 -0
  453. package/public/assets/wasm-CG6Dc4jp.js +1 -0
  454. package/public/assets/wasm-MzD3tlZU.js +1 -0
  455. package/public/assets/wenyan-BV7otONQ.js +1 -0
  456. package/public/assets/wgsl-Dx-B1_4e.js +1 -0
  457. package/public/assets/wikitext-BhOHFoWU.js +1 -0
  458. package/public/assets/wit-5i3qLPDT.js +1 -0
  459. package/public/assets/wolfram-lXgVvXCa.js +1 -0
  460. package/public/assets/wrap-text-CEH9wOr_.js +1 -0
  461. package/public/assets/xml-sdJ4AIDG.js +1 -0
  462. package/public/assets/xsl-CtQFsRM5.js +1 -0
  463. package/public/assets/yaml-Buea-lGh.js +1 -0
  464. package/public/assets/zenscript-DVFEvuxE.js +1 -0
  465. package/public/assets/zig-VOosw3JB.js +1 -0
  466. package/public/favicon.ico +0 -0
  467. package/public/index.html +42 -0
  468. package/public/loading.html +33 -0
  469. package/public/logo.png +0 -0
  470. package/public/manifest.webmanifest +1 -0
  471. package/public/maskable-icon-512x512.png +0 -0
  472. package/public/monaco/vs/base/browser/ui/codicons/codicon/codicon.ttf +0 -0
  473. package/public/monaco/vs/base/worker/workerMain.js +31 -0
  474. package/public/monaco/vs/basic-languages/cpp/cpp.js +10 -0
  475. package/public/monaco/vs/basic-languages/kotlin/kotlin.js +10 -0
  476. package/public/monaco/vs/basic-languages/markdown/markdown.js +10 -0
  477. package/public/monaco/vs/basic-languages/python/python.js +10 -0
  478. package/public/monaco/vs/editor/editor.main.css +8 -0
  479. package/public/monaco/vs/editor/editor.main.js +798 -0
  480. package/public/monaco/vs/language/css/cssMode.js +13 -0
  481. package/public/monaco/vs/language/css/cssWorker.js +77 -0
  482. package/public/monaco/vs/language/html/htmlMode.js +13 -0
  483. package/public/monaco/vs/language/html/htmlWorker.js +454 -0
  484. package/public/monaco/vs/language/json/jsonMode.js +19 -0
  485. package/public/monaco/vs/language/json/jsonWorker.js +42 -0
  486. package/public/monaco/vs/language/typescript/tsMode.js +20 -0
  487. package/public/monaco/vs/language/typescript/tsWorker.js +51328 -0
  488. package/public/monaco/vs/loader.js +11 -0
  489. package/public/monaco.worker.js +7 -0
  490. package/public/pwa-192x192.png +0 -0
  491. package/public/pwa-512x512.png +0 -0
  492. package/public/pwa-64x64.png +0 -0
  493. package/public/registerSW.js +1 -0
  494. package/public/sw.js +1 -0
  495. package/public/ui-version.json +3 -0
  496. package/public/workbox-60d14903.js +1 -0
@@ -0,0 +1,114 @@
1
+ import os from "os";
2
+ export function resolveNetworkAddresses(args) {
3
+ const { host, protocol, port } = args;
4
+ const interfaces = os.networkInterfaces();
5
+ const seen = new Set();
6
+ const results = [];
7
+ const addAddress = (ip, scope) => {
8
+ if (!ip || ip === "0.0.0.0")
9
+ return;
10
+ const key = `ipv4-${ip}`;
11
+ if (seen.has(key))
12
+ return;
13
+ seen.add(key);
14
+ results.push({ ip, family: "ipv4", scope, remoteUrl: `${protocol}://${ip}:${port}` });
15
+ };
16
+ const normalizeFamily = (value) => {
17
+ if (typeof value === "string") {
18
+ const lowered = value.toLowerCase();
19
+ if (lowered === "ipv4") {
20
+ return "ipv4";
21
+ }
22
+ }
23
+ if (value === 4)
24
+ return "ipv4";
25
+ return null;
26
+ };
27
+ if (host === "0.0.0.0") {
28
+ // Enumerate system interfaces (IPv4 only)
29
+ for (const entries of Object.values(interfaces)) {
30
+ if (!entries)
31
+ continue;
32
+ for (const entry of entries) {
33
+ const family = normalizeFamily(entry.family);
34
+ if (!family)
35
+ continue;
36
+ if (!entry.address || entry.address === "0.0.0.0")
37
+ continue;
38
+ const scope = entry.internal ? "loopback" : "external";
39
+ addAddress(entry.address, scope);
40
+ }
41
+ }
42
+ }
43
+ // Always include loopback address
44
+ addAddress("127.0.0.1", "loopback");
45
+ // Include explicitly configured host if it was IPv4
46
+ if (isIPv4Address(host) && host !== "0.0.0.0") {
47
+ const isLoopback = host.startsWith("127.");
48
+ addAddress(host, isLoopback ? "loopback" : "external");
49
+ }
50
+ const scopeWeight = { external: 0, internal: 1, loopback: 2 };
51
+ return results.sort((a, b) => {
52
+ const scopeDelta = scopeWeight[a.scope] - scopeWeight[b.scope];
53
+ if (scopeDelta !== 0)
54
+ return scopeDelta;
55
+ return 0;
56
+ });
57
+ }
58
+ export function resolveRemoteAddresses(args) {
59
+ const all = resolveNetworkAddresses(args);
60
+ const userVisible = sortUserVisibleAddresses(all.filter((address) => address.scope === "external"));
61
+ return {
62
+ all,
63
+ userVisible,
64
+ primaryRemoteUrl: userVisible[0]?.remoteUrl,
65
+ };
66
+ }
67
+ function sortUserVisibleAddresses(addresses) {
68
+ return [...addresses].sort((left, right) => getUserVisiblePriority(left.ip) - getUserVisiblePriority(right.ip));
69
+ }
70
+ function getUserVisiblePriority(ip) {
71
+ if (isPrivateIPv4(ip))
72
+ return 0;
73
+ if (isLinkLocalIPv4(ip))
74
+ return 2;
75
+ return 1;
76
+ }
77
+ function isLinkLocalIPv4(ip) {
78
+ const octets = parseIPv4(ip);
79
+ if (!octets)
80
+ return false;
81
+ const [first, second] = octets;
82
+ return first === 169 && second === 254;
83
+ }
84
+ function isPrivateIPv4(ip) {
85
+ const octets = parseIPv4(ip);
86
+ if (!octets)
87
+ return false;
88
+ const [first, second] = octets;
89
+ if (first === 10)
90
+ return true;
91
+ if (first === 192 && second === 168)
92
+ return true;
93
+ return first === 172 && second >= 16 && second <= 31;
94
+ }
95
+ function parseIPv4(value) {
96
+ if (!isIPv4Address(value))
97
+ return null;
98
+ return value.split(".").map((part) => Number(part));
99
+ }
100
+ function isIPv4Address(value) {
101
+ if (!value)
102
+ return false;
103
+ const parts = value.split(".");
104
+ if (parts.length !== 4)
105
+ return false;
106
+ return parts.every((part) => {
107
+ if (part.length === 0 || part.length > 3)
108
+ return false;
109
+ if (!/^[0-9]+$/.test(part))
110
+ return false;
111
+ const num = Number(part);
112
+ return Number.isInteger(num) && num >= 0 && num <= 255;
113
+ });
114
+ }
@@ -0,0 +1,466 @@
1
+ import Fastify from "fastify";
2
+ import { randomBytes, randomUUID } from "crypto";
3
+ import { Readable } from "stream";
4
+ import { pipeline } from "stream/promises";
5
+ import { Agent, fetch } from "undici";
6
+ const LOOPBACK_HOST = "127.0.0.1";
7
+ const BOOTSTRAP_PAGE_PATH = "/__codenomad/auth/token";
8
+ const BOOTSTRAP_EXCHANGE_PATH = "/__codenomad/api/auth/token";
9
+ const SESSION_IDLE_TTL_MS = 30 * 60000;
10
+ export class RemoteProxySessionManager {
11
+ constructor(options) {
12
+ this.options = options;
13
+ this.sessions = new Map();
14
+ this.cleanupTimer = setInterval(() => {
15
+ void this.cleanupExpiredSessions();
16
+ }, 60000);
17
+ this.cleanupTimer.unref();
18
+ }
19
+ async createSession(baseUrl, skipTlsVerify) {
20
+ if (!this.options.httpsOptions) {
21
+ throw new Error("Local HTTPS is required for remote proxy sessions");
22
+ }
23
+ const targetBaseUrl = normalizeBaseUrl(baseUrl);
24
+ const sessionId = randomUUID();
25
+ const bootstrapToken = randomBytes(32).toString("base64url");
26
+ const dispatcher = skipTlsVerify ? new Agent({ connect: { rejectUnauthorized: false } }) : undefined;
27
+ const app = Fastify({ logger: false, https: this.options.httpsOptions });
28
+ let session = null;
29
+ app.removeAllContentTypeParsers();
30
+ // Preserve raw request bodies for proxying while still letting token JSON parse from Buffer.
31
+ app.addContentTypeParser("*", { parseAs: "buffer" }, (_req, body, done) => done(null, body));
32
+ app.get(BOOTSTRAP_PAGE_PATH, async (request, reply) => {
33
+ if (!this.options.authManager.isLoopbackRequest(request)) {
34
+ reply.code(404).send({ error: "Not found" });
35
+ return;
36
+ }
37
+ reply.header("Cache-Control", "no-store");
38
+ reply.header("Pragma", "no-cache");
39
+ reply.header("Expires", "0");
40
+ reply.type("text/html").send(buildBootstrapPageHtml());
41
+ });
42
+ app.post(BOOTSTRAP_EXCHANGE_PATH, async (request, reply) => {
43
+ if (!this.options.authManager.isLoopbackRequest(request)) {
44
+ reply.code(404).send({ error: "Not found" });
45
+ return;
46
+ }
47
+ if (!session) {
48
+ reply.code(503).send({ error: "Remote proxy session is unavailable" });
49
+ return;
50
+ }
51
+ const body = parseTokenBody(request.body);
52
+ if (body.token !== session.bootstrapToken) {
53
+ reply.code(401).send({ error: "Invalid token" });
54
+ return;
55
+ }
56
+ session.activated = true;
57
+ session.lastAccessAt = Date.now();
58
+ reply.send({ ok: true });
59
+ });
60
+ app.all("/*", async (request, reply) => {
61
+ if (!session) {
62
+ reply.code(503).send({ error: "Remote proxy session is unavailable" });
63
+ return;
64
+ }
65
+ if (!session.activated) {
66
+ reply.code(403).send({ error: "Remote proxy session is not activated" });
67
+ return;
68
+ }
69
+ session.lastAccessAt = Date.now();
70
+ await proxyRequest({ request, reply, session, logger: this.options.logger });
71
+ });
72
+ app.setNotFoundHandler(async (request, reply) => {
73
+ if (!session) {
74
+ reply.code(503).send({ error: "Remote proxy session is unavailable" });
75
+ return;
76
+ }
77
+ if (!session.activated) {
78
+ reply.code(403).send({ error: "Remote proxy session is not activated" });
79
+ return;
80
+ }
81
+ session.lastAccessAt = Date.now();
82
+ await proxyRequest({ request, reply, session, logger: this.options.logger });
83
+ });
84
+ const addressInfo = await app.listen({ host: LOOPBACK_HOST, port: 0 });
85
+ const address = new URL(addressInfo);
86
+ const localBaseUrl = new URL(`https://${LOOPBACK_HOST}:${address.port}`);
87
+ const entryUrl = new URL(targetBaseUrl.pathname || "/", localBaseUrl);
88
+ const returnTo = buildReturnToTarget(entryUrl);
89
+ session = {
90
+ id: sessionId,
91
+ bootstrapToken,
92
+ targetBaseUrl,
93
+ skipTlsVerify,
94
+ localBaseUrl,
95
+ entryUrl,
96
+ bootstrapUrl: `${localBaseUrl.origin}${BOOTSTRAP_PAGE_PATH}?returnTo=${encodeURIComponent(returnTo)}#${encodeURIComponent(bootstrapToken)}`,
97
+ activated: false,
98
+ cookiePrefix: `cnrp_${randomBytes(6).toString("hex")}_`,
99
+ app,
100
+ dispatcher,
101
+ createdAt: Date.now(),
102
+ lastAccessAt: Date.now(),
103
+ };
104
+ this.sessions.set(sessionId, session);
105
+ this.options.logger.info({ sessionId, targetBaseUrl: targetBaseUrl.toString(), localBaseUrl: localBaseUrl.toString() }, "Created remote proxy session");
106
+ return { sessionId, windowUrl: session.bootstrapUrl };
107
+ }
108
+ async deleteSession(sessionId) {
109
+ return this.disposeSession(sessionId);
110
+ }
111
+ async cleanupExpiredSessions() {
112
+ const now = Date.now();
113
+ for (const session of Array.from(this.sessions.values())) {
114
+ if (now - session.lastAccessAt <= SESSION_IDLE_TTL_MS) {
115
+ continue;
116
+ }
117
+ await this.disposeSession(session.id);
118
+ }
119
+ }
120
+ async disposeSession(sessionId) {
121
+ const session = this.sessions.get(sessionId);
122
+ if (!session) {
123
+ return false;
124
+ }
125
+ this.sessions.delete(sessionId);
126
+ session.dispatcher?.close().catch(() => { });
127
+ await session.app.close().catch(() => { });
128
+ this.options.logger.info({ sessionId }, "Disposed remote proxy session");
129
+ return true;
130
+ }
131
+ }
132
+ function normalizeBaseUrl(input) {
133
+ const parsed = new URL(input.trim());
134
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
135
+ throw new Error("Server URL must use http:// or https://");
136
+ }
137
+ parsed.hash = "";
138
+ parsed.search = "";
139
+ parsed.pathname = parsed.pathname === "/" ? "/" : parsed.pathname.replace(/\/+$/, "") || "/";
140
+ return parsed;
141
+ }
142
+ function buildReturnToTarget(entryUrl) {
143
+ const query = entryUrl.search ? entryUrl.search : "";
144
+ return `${entryUrl.pathname || "/"}${query}`;
145
+ }
146
+ function buildBootstrapPageHtml() {
147
+ return `<!doctype html>
148
+ <html lang="en">
149
+ <head>
150
+ <meta charset="utf-8" />
151
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
152
+ <title>CodeNomad</title>
153
+ <style>
154
+ body { font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial; background: #0b0b0f; color: #fff; display: flex; align-items: center; justify-content: center; height: 100vh; margin: 0; }
155
+ .card { width: 420px; max-width: calc(100vw - 32px); background: #14141c; border: 1px solid rgba(255,255,255,0.08); border-radius: 14px; padding: 24px; }
156
+ h1 { font-size: 18px; margin: 0 0 12px; }
157
+ p { margin: 0; color: rgba(255,255,255,0.7); font-size: 13px; line-height: 1.4; }
158
+ .error { margin-top: 12px; color: #ff6b6b; font-size: 13px; display: none; }
159
+ </style>
160
+ </head>
161
+ <body>
162
+ <div class="card">
163
+ <h1>Connecting...</h1>
164
+ <p>Finalizing local authentication.</p>
165
+ <div id="error" class="error"></div>
166
+ </div>
167
+ <script>
168
+ const token = decodeURIComponent((location.hash || "").replace(/^#/, "").trim())
169
+ const params = new URLSearchParams(location.search)
170
+ const returnTo = sanitizeReturnTo(params.get("returnTo"))
171
+ const errorEl = document.getElementById("error")
172
+
173
+ function sanitizeReturnTo(value) {
174
+ if (!value || typeof value !== "string") return "/"
175
+ if (!value.startsWith("/")) return "/"
176
+ if (value.startsWith("//")) return "/"
177
+ return value
178
+ }
179
+
180
+ function showError(message) {
181
+ errorEl.textContent = message
182
+ errorEl.style.display = "block"
183
+ }
184
+
185
+ async function run() {
186
+ if (!token) {
187
+ showError("Missing bootstrap token.")
188
+ return
189
+ }
190
+
191
+ try {
192
+ const res = await fetch("${BOOTSTRAP_EXCHANGE_PATH}", {
193
+ method: "POST",
194
+ headers: { "Content-Type": "application/json" },
195
+ body: JSON.stringify({ token }),
196
+ credentials: "include",
197
+ })
198
+
199
+ if (!res.ok) {
200
+ let message = ""
201
+ try {
202
+ const json = await res.json()
203
+ message = json && json.error ? String(json.error) : ""
204
+ } catch {
205
+ message = ""
206
+ }
207
+ showError(message || "Token exchange failed (" + res.status + ")")
208
+ return
209
+ }
210
+
211
+ window.location.replace(returnTo)
212
+ } catch (error) {
213
+ showError(error && error.message ? error.message : String(error))
214
+ }
215
+ }
216
+
217
+ run()
218
+ </script>
219
+ </body>
220
+ </html>`;
221
+ }
222
+ function parseTokenBody(body) {
223
+ const value = normalizeJsonBody(body);
224
+ const token = typeof value?.token === "string" ? value.token.trim() : "";
225
+ if (!token) {
226
+ throw new Error("Missing bootstrap token");
227
+ }
228
+ return { token };
229
+ }
230
+ function normalizeJsonBody(body) {
231
+ if (Buffer.isBuffer(body)) {
232
+ return JSON.parse(body.toString("utf-8"));
233
+ }
234
+ if (typeof body === "string") {
235
+ return JSON.parse(body);
236
+ }
237
+ return body;
238
+ }
239
+ function toRequestBody(body) {
240
+ if (body == null) {
241
+ return undefined;
242
+ }
243
+ if (Buffer.isBuffer(body) || typeof body === "string" || body instanceof Uint8Array) {
244
+ return body;
245
+ }
246
+ return JSON.stringify(body);
247
+ }
248
+ async function proxyRequest(args) {
249
+ const { request, reply, session, logger } = args;
250
+ const upstreamUrl = buildUpstreamUrl(session.targetBaseUrl, request.raw.url ?? request.url);
251
+ const headers = filterRequestHeaders(request.headers, session);
252
+ const init = {
253
+ method: request.method,
254
+ headers,
255
+ dispatcher: session.dispatcher,
256
+ redirect: "manual",
257
+ };
258
+ if (request.method !== "GET" && request.method !== "HEAD") {
259
+ const body = toRequestBody(request.body);
260
+ if (body !== undefined) {
261
+ init.body = body;
262
+ init.duplex = "half";
263
+ }
264
+ }
265
+ try {
266
+ const response = await fetch(upstreamUrl, init);
267
+ reply.code(response.status);
268
+ applyResponseHeaders(reply, response, session);
269
+ if (!response.body || request.method === "HEAD") {
270
+ reply.send();
271
+ return;
272
+ }
273
+ reply.hijack();
274
+ reply.raw.writeHead(reply.statusCode, toOutgoingHeaders(reply.getHeaders()));
275
+ await pipeline(Readable.fromWeb(response.body), reply.raw);
276
+ }
277
+ catch (error) {
278
+ logger.error({ err: error, upstreamUrl }, "Failed to proxy remote session request");
279
+ if (!reply.sent) {
280
+ reply.code(502).send({ error: "Remote proxy request failed" });
281
+ }
282
+ }
283
+ }
284
+ function buildUpstreamUrl(baseUrl, rawUrl) {
285
+ const parsed = new URL(rawUrl, "https://localhost");
286
+ const url = new URL(baseUrl.toString());
287
+ url.pathname = rewriteRequestPath(baseUrl, parsed.pathname);
288
+ url.search = stripInternalQuery(parsed.search);
289
+ url.hash = "";
290
+ return url.toString();
291
+ }
292
+ function rewriteRequestPath(baseUrl, requestPath) {
293
+ const basePath = normalizedBasePath(baseUrl);
294
+ if (basePath === "/") {
295
+ return requestPath;
296
+ }
297
+ if (requestPath === "/") {
298
+ return basePath;
299
+ }
300
+ if (pathHasBasePrefix(basePath, requestPath)) {
301
+ return requestPath;
302
+ }
303
+ return `${basePath}${requestPath}`;
304
+ }
305
+ function normalizedBasePath(baseUrl) {
306
+ return baseUrl.pathname || "/";
307
+ }
308
+ function pathHasBasePrefix(basePath, requestPath) {
309
+ return requestPath === basePath || requestPath.startsWith(`${basePath}/`);
310
+ }
311
+ function stripInternalQuery(search) {
312
+ if (!search || search === "?") {
313
+ return "";
314
+ }
315
+ return search;
316
+ }
317
+ function filterRequestHeaders(headers, session) {
318
+ const next = {};
319
+ for (const [key, value] of Object.entries(headers ?? {})) {
320
+ if (!value)
321
+ continue;
322
+ const lower = key.toLowerCase();
323
+ if (isHopByHopHeader(lower) ||
324
+ lower === "host" ||
325
+ lower === "content-length" ||
326
+ lower === "accept-encoding") {
327
+ continue;
328
+ }
329
+ if (lower === "origin") {
330
+ next[key] = session.targetBaseUrl.origin;
331
+ continue;
332
+ }
333
+ if (lower === "referer") {
334
+ const rewritten = rewriteRefererHeader(Array.isArray(value) ? value[0] : value, session.targetBaseUrl);
335
+ if (rewritten) {
336
+ next[key] = rewritten;
337
+ }
338
+ continue;
339
+ }
340
+ if (lower === "cookie") {
341
+ const rewritten = rewriteRequestCookieHeader(Array.isArray(value) ? value.join("; ") : value, session.cookiePrefix);
342
+ if (rewritten) {
343
+ next[key] = rewritten;
344
+ }
345
+ continue;
346
+ }
347
+ next[key] = Array.isArray(value) ? value.join(",") : value;
348
+ }
349
+ next.host = session.targetBaseUrl.port ? `${session.targetBaseUrl.hostname}:${session.targetBaseUrl.port}` : session.targetBaseUrl.hostname;
350
+ if (!next.origin) {
351
+ next.origin = session.targetBaseUrl.origin;
352
+ }
353
+ return next;
354
+ }
355
+ function rewriteRefererHeader(referer, targetBaseUrl) {
356
+ if (!referer) {
357
+ return null;
358
+ }
359
+ try {
360
+ const parsed = new URL(referer);
361
+ const rewritten = new URL(targetBaseUrl.toString());
362
+ rewritten.pathname = rewriteRequestPath(targetBaseUrl, parsed.pathname);
363
+ rewritten.search = parsed.search;
364
+ rewritten.hash = parsed.hash;
365
+ return rewritten.toString();
366
+ }
367
+ catch {
368
+ return null;
369
+ }
370
+ }
371
+ function applyResponseHeaders(reply, response, session) {
372
+ const setCookie = response.headers.getSetCookie?.();
373
+ if (Array.isArray(setCookie)) {
374
+ for (const cookie of setCookie) {
375
+ reply.header("set-cookie", rewriteSetCookie(cookie, session.cookiePrefix));
376
+ }
377
+ }
378
+ response.headers.forEach((value, key) => {
379
+ const lower = key.toLowerCase();
380
+ if (isHopByHopHeader(lower) ||
381
+ lower === "set-cookie" ||
382
+ lower === "content-length" ||
383
+ lower === "content-encoding") {
384
+ return;
385
+ }
386
+ if (lower === "location") {
387
+ reply.header(key, rewriteLocation(value, session.targetBaseUrl, session.localBaseUrl));
388
+ return;
389
+ }
390
+ reply.header(key, value);
391
+ });
392
+ }
393
+ function toOutgoingHeaders(headers) {
394
+ const next = {};
395
+ for (const [key, value] of Object.entries(headers)) {
396
+ if (value === undefined) {
397
+ continue;
398
+ }
399
+ next[key] = Array.isArray(value) ? value.map(String) : String(value);
400
+ }
401
+ return next;
402
+ }
403
+ function rewriteSetCookie(cookie, cookiePrefix) {
404
+ const parts = cookie.split(";").map((part) => part.trim());
405
+ const first = parts.shift() ?? "";
406
+ const separator = first.indexOf("=");
407
+ if (separator <= 0) {
408
+ return cookie;
409
+ }
410
+ const name = first.slice(0, separator).trim();
411
+ const value = first.slice(separator + 1);
412
+ const rewritten = [`${cookiePrefix}${name}=${value}`];
413
+ for (const part of parts) {
414
+ if (part.slice(0, 7).toLowerCase().startsWith("domain=")) {
415
+ continue;
416
+ }
417
+ rewritten.push(part);
418
+ }
419
+ return rewritten.join("; ");
420
+ }
421
+ function rewriteRequestCookieHeader(cookieHeader, cookiePrefix) {
422
+ const next = [];
423
+ for (const rawPart of cookieHeader.split(";")) {
424
+ const part = rawPart.trim();
425
+ if (!part)
426
+ continue;
427
+ const separator = part.indexOf("=");
428
+ if (separator <= 0)
429
+ continue;
430
+ const name = part.slice(0, separator).trim();
431
+ const value = part.slice(separator + 1);
432
+ if (!name.startsWith(cookiePrefix)) {
433
+ continue;
434
+ }
435
+ next.push(`${name.slice(cookiePrefix.length)}=${value}`);
436
+ }
437
+ return next.join("; ");
438
+ }
439
+ function rewriteLocation(location, targetBaseUrl, localBaseUrl) {
440
+ try {
441
+ const parsed = new URL(location, targetBaseUrl);
442
+ if (parsed.origin !== targetBaseUrl.origin) {
443
+ return location;
444
+ }
445
+ const rewritten = new URL(localBaseUrl.toString());
446
+ rewritten.pathname = parsed.pathname;
447
+ rewritten.search = parsed.search;
448
+ rewritten.hash = parsed.hash;
449
+ return rewritten.toString();
450
+ }
451
+ catch {
452
+ return location;
453
+ }
454
+ }
455
+ function isHopByHopHeader(name) {
456
+ return new Set([
457
+ "connection",
458
+ "keep-alive",
459
+ "proxy-authenticate",
460
+ "proxy-authorization",
461
+ "te",
462
+ "trailer",
463
+ "transfer-encoding",
464
+ "upgrade",
465
+ ]).has(name);
466
+ }