@hienlh/ppm 0.18.12 → 0.18.14

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 (548) hide show
  1. package/AGENTS.md +17 -5
  2. package/CHANGELOG.md +27 -0
  3. package/CLAUDE.md +3 -0
  4. package/README.md +6 -6
  5. package/assets/skills/ppm/SKILL.md +1 -1
  6. package/assets/skills/ppm/references/cli-reference.md +4 -4
  7. package/assets/skills/ppm/references/http-api.md +19 -1
  8. package/dist/web/assets/{adaptive-context-menu-DGCKKeTy.js → adaptive-context-menu-DCZtgOL7.js} +1 -1
  9. package/dist/web/assets/{ai-resource-editor-BOHHTTe7.js → ai-resource-editor-D5CPBg06.js} +1 -1
  10. package/dist/web/assets/{ai-settings-section-BigC_nZR.js → ai-settings-section-DY-t1bK8.js} +1 -1
  11. package/dist/web/assets/{angular-html-BYPaydvh.js → angular-html-CTvM4ulF.js} +1 -1
  12. package/dist/web/assets/{angular-ts-Bb4AMKlk.js → angular-ts-B_vSkjco.js} +1 -1
  13. package/dist/web/assets/api-client-BogqsFna.js +1 -0
  14. package/dist/web/assets/{api-settings-Bd3M4YpI.js → api-settings-B2iNXQ0c.js} +1 -1
  15. package/dist/web/assets/api-settings-DRF9oYkn.js +1 -0
  16. package/dist/web/assets/{api-themes-Cpx419SL.js → api-themes-DrWnJbhs.js} +1 -1
  17. package/dist/web/assets/{apl-DB2VjFCS.js → apl-DywzTry0.js} +1 -1
  18. package/dist/web/assets/architecture-PBZL5I3N-nw5-j_I_.js +1 -0
  19. package/dist/web/assets/{astro-BeoJdVpk.js → astro-1JaRgaSb.js} +1 -1
  20. package/dist/web/assets/{audio-preview-BgFuTn-0.js → audio-preview-DAuGvOiK.js} +1 -1
  21. package/dist/web/assets/{blade-Cf2q1sPf.js → blade-CDeeJWBb.js} +1 -1
  22. package/dist/web/assets/{bsl-W1kOaNpu.js → bsl-BfgoPVYR.js} +1 -1
  23. package/dist/web/assets/{button-5zTrkEoN.js → button-tNy0ba3y.js} +1 -1
  24. package/dist/web/assets/{cairo-BoAZFcje.js → cairo-C26gNwWW.js} +1 -1
  25. package/dist/web/assets/chat-tab-IcnU3nqQ.js +15 -0
  26. package/dist/web/assets/{cobol-B0Nm7RXj.js → cobol-D92nBnON.js} +1 -1
  27. package/dist/web/assets/code-editor-Dno5Srkm.js +10 -0
  28. package/dist/web/assets/{coffee-BakMn3on.js → coffee-CIWH40R1.js} +1 -1
  29. package/dist/web/assets/{conflict-editor-BUs5k9q_.js → conflict-editor-CDp0I3mD.js} +1 -1
  30. package/dist/web/assets/{context-menu-Bq92km4s.js → context-menu-BO1c9jKy.js} +1 -1
  31. package/dist/web/assets/{cpp-BRAJQHK2.js → cpp-DOrBqXCn.js} +1 -1
  32. package/dist/web/assets/{crystal-kqqO3zkK.js → crystal-BNKqmHux.js} +1 -1
  33. package/dist/web/assets/{csv-preview-ByoDgLAZ.js → csv-preview-D4svNDAq.js} +1 -1
  34. package/dist/web/assets/{data-grid-overlay-editor-Brkf9z41.js → data-grid-overlay-editor-BqV0AxZg.js} +1 -1
  35. package/dist/web/assets/{database-viewer-Btc3h8Yu.js → database-viewer-BCvv_Bwf.js} +1 -1
  36. package/dist/web/assets/{dialog-DwtGlowE.js → dialog-DcLGDwaX.js} +1 -1
  37. package/dist/web/assets/diff-viewer-D41fCFAi.js +4 -0
  38. package/dist/web/assets/{docx-preview-DAD_vg59.js → docx-preview-DfaQn9v7.js} +1 -1
  39. package/dist/web/assets/{edge-Cq1ZKZuE.js → edge-Dbjp42Pt.js} +1 -1
  40. package/dist/web/assets/{edit-diff-preview-B_VE7ppQ.js → edit-diff-preview-BqcUuFCc.js} +1 -1
  41. package/dist/web/assets/{elixir-BM_JoJRk.js → elixir-na3b1pYy.js} +1 -1
  42. package/dist/web/assets/{elm-Dw7oO08Y.js → elm-_Nalil1R.js} +1 -1
  43. package/dist/web/assets/{erb-CfKOGAfk.js → erb-CW_7dubf.js} +1 -1
  44. package/dist/web/assets/{erlang-DlDmGVeE.js → erlang-DmZ7Zzb0.js} +1 -1
  45. package/dist/web/assets/{esm-DGAP0GFh.js → esm-CwyBetO1.js} +1 -1
  46. package/dist/web/assets/explorer-body-DB1L30pa.js +2 -0
  47. package/dist/web/assets/explorer-window-content-Cwlt3C3I.js +1 -0
  48. package/dist/web/assets/{extension-store-Cpfh2vMm.js → extension-store-DUaZINyC.js} +1 -1
  49. package/dist/web/assets/{extension-webview-B2OnjuCu.js → extension-webview-BW_mccb3.js} +1 -1
  50. package/dist/web/assets/{file-store-aOERIEo-.js → file-store-yReVbR8q.js} +1 -1
  51. package/dist/web/assets/{fortran-fixed-form-XnAhQWxS.js → fortran-fixed-form-DB2A8L4-.js} +1 -1
  52. package/dist/web/assets/{fsharp-CdNvy0PG.js → fsharp-BYHrti7z.js} +1 -1
  53. package/dist/web/assets/{gdresource-DxuG5i8i.js → gdresource-D5GBin40.js} +1 -1
  54. package/dist/web/assets/{git-commit-3lMonsur.js → git-commit-CUiOBoIL.js} +1 -1
  55. package/dist/web/assets/{git-log-panel-Co0PBPHC.js → git-log-panel-C1QDkmgl.js} +1 -1
  56. package/dist/web/assets/{git-rebase-N8Z9kIMf.js → git-rebase-DOxGnpdw.js} +1 -1
  57. package/dist/web/assets/gitGraph-HDMCJU4V-C1xf87gN.js +1 -0
  58. package/dist/web/assets/glide-data-grid-Dz8lx6n2.js +138 -0
  59. package/dist/web/assets/{glimmer-js-Dp9OXiib.js → glimmer-js-Begy4UT7.js} +1 -1
  60. package/dist/web/assets/{glimmer-ts-CDVKBcDj.js → glimmer-ts-rPApRY8N.js} +1 -1
  61. package/dist/web/assets/{glsl-DPJxI4us.js → glsl-wrbPvrBL.js} +1 -1
  62. package/dist/web/assets/{graphql-BrFhaQQl.js → graphql-Cu4-NR__.js} +1 -1
  63. package/dist/web/assets/group-chat-tab-DFwr-pig.js +1 -0
  64. package/dist/web/assets/{hack-BzXbDMlA.js → hack-Ddo93XKD.js} +1 -1
  65. package/dist/web/assets/{haml-CPpkX0s5.js → haml-BFX_1i8j.js} +1 -1
  66. package/dist/web/assets/{handlebars-BqrApy52.js → handlebars-5gFKA4H5.js} +1 -1
  67. package/dist/web/assets/{html-DmjUl-OA.js → html-C06I-zeO.js} +1 -1
  68. package/dist/web/assets/{html-derivative-Cnd6XFR5.js → html-derivative-e5JLAFZF.js} +1 -1
  69. package/dist/web/assets/{http-DMLWYun2.js → http-CrAAhSU7.js} +1 -1
  70. package/dist/web/assets/{hurl-CKkCVxbj.js → hurl-T1V3SX9T.js} +1 -1
  71. package/dist/web/assets/{hxml-CAx19TtQ.js → hxml-B056LLKN.js} +1 -1
  72. package/dist/web/assets/{image-preview-DHUoylQ1.js → image-preview-DWyuCYT3.js} +1 -1
  73. package/dist/web/assets/index-DWpNR3nB.css +2 -0
  74. package/dist/web/assets/index-oUKV5nIA.js +52 -0
  75. package/dist/web/assets/info-3K5VOQVL-C2z7FTDe.js +1 -0
  76. package/dist/web/assets/{input-DcEk7mA3.js → input-DouJ9Zvt.js} +1 -1
  77. package/dist/web/assets/{jinja-BmB9YN9l.js → jinja-DGdtRh43.js} +1 -1
  78. package/dist/web/assets/{jison-BaVsKKpw.js → jison-Ah6QobPS.js} +1 -1
  79. package/dist/web/assets/{julia-BgVBLveX.js → julia-BJeGOK0K.js} +1 -1
  80. package/dist/web/assets/{just-C2ENIbl9.js → just-iw9oRs7j.js} +1 -1
  81. package/dist/web/assets/{keybindings-store-BGIyqXHI.js → keybindings-store-0Wqfa7Qp.js} +1 -1
  82. package/dist/web/assets/keybindings-store-d54pv2NK.js +1 -0
  83. package/dist/web/assets/{latex-BiDIWxKL.js → latex-DHjj5hyN.js} +1 -1
  84. package/dist/web/assets/{liquid-NxpapreE.js → liquid-B-FFecDc.js} +1 -1
  85. package/dist/web/assets/{lua-DVepQvwH.js → lua-DDianJp_.js} +1 -1
  86. package/dist/web/assets/{markdown-renderer-DlcDhgrF.js → markdown-renderer-BHiUhQN8.js} +3 -3
  87. package/dist/web/assets/markdown-renderer-CnE36_gd.js +1 -0
  88. package/dist/web/assets/{marko-CJ2606Xl.js → marko-BW5SBVng.js} +1 -1
  89. package/dist/web/assets/{mdc-D2bjqclE.js → mdc-B9gL9bjl.js} +1 -1
  90. package/dist/web/assets/{media-url-H17XJF-I.js → media-url-DUK-k0bB.js} +1 -1
  91. package/dist/web/assets/{mobile-bottom-sheet-g-r2hCFa.js → mobile-bottom-sheet-CJ7ApOkI.js} +1 -1
  92. package/dist/web/assets/mobile-explorer-sheet-BzjlS1Xn.js +1 -0
  93. package/dist/web/assets/{nextflow-BtJwUbfF.js → nextflow-dTluY6qy.js} +1 -1
  94. package/dist/web/assets/{nginx-j4gyIhHE.js → nginx-DlwghGI-.js} +1 -1
  95. package/dist/web/assets/{nim-ClH_gjP5.js → nim-N9jddb5D.js} +1 -1
  96. package/dist/web/assets/notification-store-C7UBqxYP.js +1 -0
  97. package/dist/web/assets/{number-overlay-editor-C1EqJnWq.js → number-overlay-editor-BVXM7aAs.js} +1 -1
  98. package/dist/web/assets/{overview-panel-vTeeJYVZ.js → overview-panel-DCCDmtCQ.js} +1 -1
  99. package/dist/web/assets/packet-RMMSAZCW-DQUxN0wU.js +1 -0
  100. package/dist/web/assets/{panel-store-BSnkjgHt.js → panel-store-B4rijFKN.js} +1 -1
  101. package/dist/web/assets/{pdf-preview-CqFGRY0Z.js → pdf-preview-D7yLmAZW.js} +1 -1
  102. package/dist/web/assets/{perl-C9H7X7CT.js → perl-CkmpYKa_.js} +1 -1
  103. package/dist/web/assets/{php-Bx2U-cQ_.js → php-BwZ3KDPo.js} +1 -1
  104. package/dist/web/assets/pie-UPGHQEXC-BOr9ek4Q.js +1 -0
  105. package/dist/web/assets/{postgres-viewer-DHwcQucn.js → postgres-viewer--CRN1fvO.js} +3 -3
  106. package/dist/web/assets/{process-table-BGRJNlpn.js → process-table-CXC10GSy.js} +1 -1
  107. package/dist/web/assets/{project-store--nvQiy75.js → project-store-BuY7rxn_.js} +1 -1
  108. package/dist/web/assets/{pug-Cw74sKsE.js → pug-B3rBPqQo.js} +1 -1
  109. package/dist/web/assets/{qml-BXD94Eqz.js → qml-BfDbWFmg.js} +1 -1
  110. package/dist/web/assets/radar-KQ55EAFF-DSErxZFb.js +1 -0
  111. package/dist/web/assets/{razor-DZ0-Ge0S.js → razor-B1ww1r38.js} +1 -1
  112. package/dist/web/assets/{rst-Dtdh0QUj.js → rst-C0MSq6m-.js} +1 -1
  113. package/dist/web/assets/{ruby-BC51BW2Q.js → ruby-ClIZ1wb3.js} +1 -1
  114. package/dist/web/assets/{run-in-terminal-Sd3KyjN4.js → run-in-terminal-4efbW2Xv.js} +1 -1
  115. package/dist/web/assets/{sas-BN8i4qOU.js → sas-DR0j3o4_.js} +1 -1
  116. package/dist/web/assets/{scroll-area-0gljZ6lF.js → scroll-area-ZP8wcwTI.js} +1 -1
  117. package/dist/web/assets/{scss-H-QtA7Rz.js → scss-Vh3JLayR.js} +1 -1
  118. package/dist/web/assets/{send-to-chat-u6m8l-rH.js → send-to-chat-BNrEpAyC.js} +1 -1
  119. package/dist/web/assets/{settings-store-CHY6Kzin.js → settings-store-OLJE7dPH.js} +2 -2
  120. package/dist/web/assets/{settings-tab-IY6K1MiZ.js → settings-tab-B1rvHFc6.js} +1 -1
  121. package/dist/web/assets/settings-tab-BUlmPJ2w.js +1 -0
  122. package/dist/web/assets/{shaderlab-CalNsj_x.js → shaderlab-0rHRnQ18.js} +1 -1
  123. package/dist/web/assets/{shellsession-BFrcoR8x.js → shellsession-Dxdw6D8c.js} +1 -1
  124. package/dist/web/assets/{soy-CNbku7vP.js → soy-BHlSNj1y.js} +1 -1
  125. package/dist/web/assets/{sparql-BN_orcVp.js → sparql-B2QaPpni.js} +1 -1
  126. package/dist/web/assets/{sql-query-editor-C6pC3I8l.js → sql-query-editor-R_iKjPP9.js} +1 -1
  127. package/dist/web/assets/{sqlite-viewer-DTr5PzUb.js → sqlite-viewer-b2onA0SP.js} +1 -1
  128. package/dist/web/assets/{stata-C6a5Ijzq.js → stata-CwIxjsEJ.js} +1 -1
  129. package/dist/web/assets/{surrealql-ClplI_HY.js → surrealql-C6vo-rp-.js} +1 -1
  130. package/dist/web/assets/{svelte-DNm-UNXB.js → svelte-LLdJ6rlH.js} +1 -1
  131. package/dist/web/assets/{switch-DKvKya9y.js → switch-DV-BDjyk.js} +1 -1
  132. package/dist/web/assets/system-monitor-body-DPYQlBEt.js +2 -0
  133. package/dist/web/assets/system-monitor-tab-CPQdWv27.js +1 -0
  134. package/dist/web/assets/{system-monitor-window-content-BUqRsPK2.js → system-monitor-window-content-BPif0azo.js} +1 -1
  135. package/dist/web/assets/tab-host-window-content-BnAN6m4K.js +1 -0
  136. package/dist/web/assets/{tab-store-CJuJRapl.js → tab-store-tFnyPmm4.js} +1 -1
  137. package/dist/web/assets/team-member-sheet-Bu2wG1sm.js +2 -0
  138. package/dist/web/assets/{team-member-window-content-T4Q5JI-G.js → team-member-window-content-BSyU-5Uc.js} +1 -1
  139. package/dist/web/assets/{templ-CSdqVobu.js → templ-CJGvhEP5.js} +1 -1
  140. package/dist/web/assets/{terminal-tab-Bb2rZegQ.js → terminal-tab-Ncor0Rfu.js} +3 -3
  141. package/dist/web/assets/{tex-DzSJ4kcZ.js → tex-psXWhc4t.js} +1 -1
  142. package/dist/web/assets/{tool-cards-lhqhrDTT.js → tool-cards-DdVP1wrD.js} +4 -4
  143. package/dist/web/assets/treemap-KZPCXAKY-C17p0LQw.js +1 -0
  144. package/dist/web/assets/{ts-tags-C28w3bTg.js → ts-tags-D5Ar_ZCO.js} +1 -1
  145. package/dist/web/assets/{twig-i5jY3QXB.js → twig-vJgGC-qY.js} +1 -1
  146. package/dist/web/assets/{use-blob-url-Dsq9OjTh.js → use-blob-url-BOVGWg9F.js} +1 -1
  147. package/dist/web/assets/use-coarse-long-press-BmI_GVW5.js +1 -0
  148. package/dist/web/assets/use-monaco-theme-BshnLXoY.js +1 -0
  149. package/dist/web/assets/{use-open-team-member-DkiEjFYE.js → use-open-team-member-CY3wOdWL.js} +1 -1
  150. package/dist/web/assets/{use-websocket-B8R50f7f.js → use-websocket-B7xjNsyD.js} +1 -1
  151. package/dist/web/assets/{vendor-mermaid-By4AVvJY.js → vendor-mermaid-999ksD45.js} +1 -1
  152. package/dist/web/assets/video-preview-7F72sRwf.js +1 -0
  153. package/dist/web/assets/{vue-Ceyet_lv.js → vue-BWngFyav.js} +1 -1
  154. package/dist/web/assets/{vue-html-GuU7g_hg.js → vue-html-BN5ZLu-H.js} +1 -1
  155. package/dist/web/assets/{vue-vine-CxXoaJr2.js → vue-vine-BZHnO8yV.js} +1 -1
  156. package/dist/web/assets/window-pip-registry-BnYU83LE.js +1 -0
  157. package/dist/web/assets/{window-store-CsEW6jiE.js → window-store-CQ1lghvv.js} +1 -1
  158. package/dist/web/assets/{xml-CbqOVhkP.js → xml-DS2beZHp.js} +1 -1
  159. package/dist/web/assets/{xsl-KfAmCauy.js → xsl-Ciiku1Bq.js} +1 -1
  160. package/dist/web/index.html +47 -45
  161. package/dist/web/sw.js +1 -1
  162. package/docs/architecture/ai-chat-and-providers.md +309 -0
  163. package/docs/architecture/data-and-storage.md +356 -0
  164. package/docs/architecture/extensions.md +496 -0
  165. package/docs/architecture/integrations.md +214 -0
  166. package/docs/architecture/workspace-and-ui.md +399 -0
  167. package/docs/claude-agent-sdk-reference.md +1 -1
  168. package/docs/code-patterns.md +361 -0
  169. package/docs/code-standards.md +8 -358
  170. package/docs/codebase-subsystems.md +364 -0
  171. package/docs/codebase-summary.md +34 -379
  172. package/docs/deployment-guide.md +280 -490
  173. package/docs/design-guidelines.md +4 -3
  174. package/docs/lessons-learned.md +27 -10
  175. package/docs/project-changelog.md +18 -806
  176. package/docs/project-overview-pdr.md +117 -111
  177. package/docs/project-roadmap.md +89 -133
  178. package/docs/system-architecture.md +77 -1826
  179. package/package.json +2 -2
  180. package/src/cli/commands/autostart.ts +2 -2
  181. package/src/cli/commands/config-cmd.ts +12 -3
  182. package/src/cli/commands/status.ts +3 -2
  183. package/src/cli/commands/stop.ts +32 -4
  184. package/src/server/index.ts +17 -3
  185. package/src/server/routes/chat-unread.ts +36 -0
  186. package/src/server/routes/named-tunnel.ts +132 -0
  187. package/src/server/routes/tunnel.ts +13 -0
  188. package/src/server/ws/chat.ts +5 -2
  189. package/src/services/autostart-register.ts +47 -29
  190. package/src/services/cloud.service.ts +26 -1
  191. package/src/services/config-secret-keys.ts +48 -0
  192. package/src/services/config.service.ts +1 -1
  193. package/src/services/db.service.ts +62 -12
  194. package/src/services/edge-forwarder.ts +191 -191
  195. package/src/services/extension-rpc-handlers.ts +9 -1
  196. package/src/services/file-watcher/watch-tree.ts +67 -33
  197. package/src/services/file-watcher.service.ts +28 -10
  198. package/src/services/fs-credential-path-guard.ts +103 -0
  199. package/src/services/fs-path-guard.service.ts +14 -66
  200. package/src/services/named-tunnel/cloudflare-dns-api.ts +40 -0
  201. package/src/services/named-tunnel/cloudflare-zone-api.ts +28 -0
  202. package/src/services/named-tunnel/cloudflared-cert.ts +95 -0
  203. package/src/services/named-tunnel/cloudflared-exec.ts +50 -0
  204. package/src/services/named-tunnel/cloudflared-login-helpers.ts +98 -0
  205. package/src/services/named-tunnel/cloudflared-login.service.ts +182 -0
  206. package/src/services/named-tunnel/hostname-rules.ts +58 -0
  207. package/src/services/named-tunnel/login-output-parser.ts +36 -0
  208. package/src/services/named-tunnel/named-tunnel-args.ts +110 -0
  209. package/src/services/named-tunnel/named-tunnel-config.ts +67 -0
  210. package/src/services/named-tunnel/named-tunnel-probe-state.ts +95 -0
  211. package/src/services/named-tunnel/named-tunnel-readiness.ts +59 -0
  212. package/src/services/named-tunnel/named-tunnel-runtime.ts +42 -0
  213. package/src/services/named-tunnel/named-tunnel-setup-confirm.ts +98 -0
  214. package/src/services/named-tunnel/named-tunnel-setup.service.ts +191 -0
  215. package/src/services/supervisor-state.ts +67 -2
  216. package/src/services/supervisor.ts +454 -157
  217. package/src/services/tunnel-registry-parse.ts +27 -0
  218. package/src/services/tunnel-registry.service.ts +2 -15
  219. package/src/services/tunnel.service.ts +12 -3
  220. package/src/services/windows-process-tree.ts +351 -351
  221. package/src/types/config.ts +31 -0
  222. package/src/web/app.tsx +5 -0
  223. package/src/web/components/chat/chat-history-bar.tsx +95 -98
  224. package/src/web/components/chat/chat-toolbar-overflow-menu.tsx +57 -0
  225. package/src/web/components/chat/session-debug-dialog.tsx +35 -27
  226. package/src/web/components/floating-window/floating-window.tsx +8 -1
  227. package/src/web/components/floating-window/open-tab-in-pip.ts +78 -0
  228. package/src/web/components/floating-window/window-pip-registry.ts +46 -0
  229. package/src/web/components/layout/cloud-share-named-tunnel-row.tsx +111 -0
  230. package/src/web/components/layout/cloud-share-popover.tsx +56 -14
  231. package/src/web/components/layout/tab-pop-out-menu-item.tsx +25 -2
  232. package/src/web/components/shared/connection-lost-overlay.tsx +44 -5
  233. package/src/web/components/tunnels/named-tunnel/hostname-validation.ts +14 -0
  234. package/src/web/components/tunnels/named-tunnel/named-tunnel-copy.ts +96 -0
  235. package/src/web/components/tunnels/named-tunnel/named-tunnel-hostname-field.tsx +51 -0
  236. package/src/web/components/tunnels/named-tunnel/named-tunnel-login-step.tsx +105 -0
  237. package/src/web/components/tunnels/named-tunnel/named-tunnel-section.tsx +159 -0
  238. package/src/web/components/tunnels/named-tunnel/named-tunnel-setup-content.tsx +197 -0
  239. package/src/web/components/tunnels/named-tunnel/named-tunnel-setup-popup.tsx +57 -0
  240. package/src/web/components/tunnels/named-tunnel/named-tunnel-step-reducer.ts +191 -0
  241. package/src/web/components/tunnels/named-tunnel/use-named-tunnel-setup.ts +212 -0
  242. package/src/web/components/tunnels/tunnel-manager-tab.tsx +4 -0
  243. package/src/web/hooks/use-global-events.ts +3 -1
  244. package/src/web/lib/api-named-tunnel.ts +54 -0
  245. package/src/web/lib/last-known-local-url.ts +23 -0
  246. package/src/web/stores/notification-store.ts +20 -1
  247. package/dist/web/assets/api-client-DTZEgjBQ.js +0 -1
  248. package/dist/web/assets/api-settings-kd1j4iR8.js +0 -1
  249. package/dist/web/assets/architecture-PBZL5I3N-8dCMT9r7.js +0 -1
  250. package/dist/web/assets/chat-tab-E3bf_V8X.js +0 -15
  251. package/dist/web/assets/code-editor-BUlM2gXk.js +0 -10
  252. package/dist/web/assets/diff-viewer-CZaDnR4w.js +0 -4
  253. package/dist/web/assets/explorer-body-9aBmyVpZ.js +0 -2
  254. package/dist/web/assets/explorer-window-content-DRtqoSPA.js +0 -1
  255. package/dist/web/assets/gitGraph-HDMCJU4V-2e_8dfbs.js +0 -1
  256. package/dist/web/assets/glide-data-grid-C4_zIneN.js +0 -138
  257. package/dist/web/assets/group-chat-tab-rOd8J8GC.js +0 -1
  258. package/dist/web/assets/index-BImUaigO.js +0 -52
  259. package/dist/web/assets/index-CSfi6DSU.css +0 -2
  260. package/dist/web/assets/info-3K5VOQVL-BZi1Gha1.js +0 -1
  261. package/dist/web/assets/keybindings-store-CzV2sPls.js +0 -1
  262. package/dist/web/assets/markdown-renderer-CcbR33VG.js +0 -1
  263. package/dist/web/assets/mobile-explorer-sheet-SIwQXlwA.js +0 -1
  264. package/dist/web/assets/notification-store-DV5QtUTg.js +0 -1
  265. package/dist/web/assets/packet-RMMSAZCW-o5htEcin.js +0 -1
  266. package/dist/web/assets/pie-UPGHQEXC-BXAIFSAD.js +0 -1
  267. package/dist/web/assets/radar-KQ55EAFF-Dbt2Aebl.js +0 -1
  268. package/dist/web/assets/settings-tab-Dic6TKkU.js +0 -1
  269. package/dist/web/assets/system-monitor-body-iwGiCns9.js +0 -2
  270. package/dist/web/assets/system-monitor-tab-DdXQhEel.js +0 -1
  271. package/dist/web/assets/tab-host-window-content-BnqGPu8a.js +0 -1
  272. package/dist/web/assets/team-member-sheet-LkAFSCvb.js +0 -2
  273. package/dist/web/assets/treemap-KZPCXAKY-DUbnl9dz.js +0 -1
  274. package/dist/web/assets/use-monaco-theme-BZvlsoBv.js +0 -1
  275. package/dist/web/assets/video-preview-m0-3p7QZ.js +0 -1
  276. package/packages/vscode-compat/node_modules/.bin/tsc.bunx +0 -0
  277. package/packages/vscode-compat/node_modules/.bin/tsc.exe +0 -0
  278. package/packages/vscode-compat/node_modules/.bin/tsserver.bunx +0 -0
  279. package/packages/vscode-compat/node_modules/.bin/tsserver.exe +0 -0
  280. /package/dist/web/assets/{abap-C6nB04tn.js → abap-CjzrhAS2.js} +0 -0
  281. /package/dist/web/assets/{actionscript-3-Vx4rw2sC.js → actionscript-3-B59Kbl-9.js} +0 -0
  282. /package/dist/web/assets/{ada-Ccd8vM20.js → ada-B7gItKAE.js} +0 -0
  283. /package/dist/web/assets/{andromeeda-DnBX5xMg.js → andromeeda-Dy5zcy0Q.js} +0 -0
  284. /package/dist/web/assets/{apache-B-9_sx0g.js → apache-B6T9jrc0.js} +0 -0
  285. /package/dist/web/assets/{apex-_wPVBYoL.js → apex-CTsIxDQw.js} +0 -0
  286. /package/dist/web/assets/{api-client-aQb5hHE5.js → api-client-oY1tC3tM.js} +0 -0
  287. /package/dist/web/assets/{applescript-CcvD-qr0.js → applescript-DuycKmmb.js} +0 -0
  288. /package/dist/web/assets/{apply-theme-BeLRfsSu.js → apply-theme-r8tKDrCR.js} +0 -0
  289. /package/dist/web/assets/{ara-C40Ztoms.js → ara-CISL3599.js} +0 -0
  290. /package/dist/web/assets/{asciidoc-CybYkJV4.js → asciidoc-BXyE2Lpr.js} +0 -0
  291. /package/dist/web/assets/{asm-9eOKwzR0.js → asm-y258phtP.js} +0 -0
  292. /package/dist/web/assets/{aurora-x-B5ZH4t7t.js → aurora-x-Dq3Jc78M.js} +0 -0
  293. /package/dist/web/assets/{awk-Dqilob-2.js → awk-DxL6XSJv.js} +0 -0
  294. /package/dist/web/assets/{ayu-dark-CPgRhf5r.js → ayu-dark-DjoK6Evo.js} +0 -0
  295. /package/dist/web/assets/{ayu-light-Do06Q52f.js → ayu-light-CKKXBLMI.js} +0 -0
  296. /package/dist/web/assets/{ayu-mirage-_BhxcrxY.js → ayu-mirage-DGXSrrXB.js} +0 -0
  297. /package/dist/web/assets/{ballerina-DDwK54QW.js → ballerina-DZSXFmUf.js} +0 -0
  298. /package/dist/web/assets/{bat-BGyGlzGk.js → bat-BNsZk6nY.js} +0 -0
  299. /package/dist/web/assets/{beancount-CRWBdapI.js → beancount-cPl4gJct.js} +0 -0
  300. /package/dist/web/assets/{berry-DbSFn2gO.js → berry-DGAodERk.js} +0 -0
  301. /package/dist/web/assets/{bibtex-QpsV9gm9.js → bibtex-DftVoRif.js} +0 -0
  302. /package/dist/web/assets/{bicep-CxS8CUve.js → bicep-Suioyyzh.js} +0 -0
  303. /package/dist/web/assets/{bird2-CuZhQzYR.js → bird2-DjU24I2P.js} +0 -0
  304. /package/dist/web/assets/{c-9bnDqE3g.js → c-DFi8Y_nN.js} +0 -0
  305. /package/dist/web/assets/{c3-JMZTrOhA.js → c3-1eSHnH5V.js} +0 -0
  306. /package/dist/web/assets/{cadence-DsDNayJS.js → cadence-DLLsFwQP.js} +0 -0
  307. /package/dist/web/assets/{can-open-in-ppm-BJfpynya.js → can-open-in-ppm-in727eFQ.js} +0 -0
  308. /package/dist/web/assets/{catppuccin-frappe-DYIKXXBe.js → catppuccin-frappe-DDj0JEiY.js} +0 -0
  309. /package/dist/web/assets/{catppuccin-latte-IYYOnUJ8.js → catppuccin-latte-DPyANHyR.js} +0 -0
  310. /package/dist/web/assets/{catppuccin-macchiato-BrJ_7mfS.js → catppuccin-macchiato-CO-h8VTT.js} +0 -0
  311. /package/dist/web/assets/{catppuccin-mocha-gzSu7v7-.js → catppuccin-mocha-BCmbN2IZ.js} +0 -0
  312. /package/dist/web/assets/{clarity-DLzsC0Hb.js → clarity-C0pYsZjs.js} +0 -0
  313. /package/dist/web/assets/{clipboard-7fw0Shic.js → clipboard-DBLGKMrH.js} +0 -0
  314. /package/dist/web/assets/{clojure-DS1BvoTt.js → clojure-JFr6s8iZ.js} +0 -0
  315. /package/dist/web/assets/{cmake-CDvsJwYp.js → cmake-EEcLEgVy.js} +0 -0
  316. /package/dist/web/assets/{codeowners-BjsYiflJ.js → codeowners-Deh3Lx0u.js} +0 -0
  317. /package/dist/web/assets/{codeql-CG-7ARat.js → codeql-C317igT5.js} +0 -0
  318. /package/dist/web/assets/{common-lisp-DSO1Lbh9.js → common-lisp-DepbATZs.js} +0 -0
  319. /package/dist/web/assets/{coq-DYdh3oP_.js → coq-MxgxU5ya.js} +0 -0
  320. /package/dist/web/assets/{csharp-DxEBz5s0.js → csharp-eEFXdsAq.js} +0 -0
  321. /package/dist/web/assets/{css-dal3Q-8C.js → css-Db-syWW9.js} +0 -0
  322. /package/dist/web/assets/{csv-CpqjMGiA.js → csv-DHeYcbaq.js} +0 -0
  323. /package/dist/web/assets/{csv-parser-3umBA4NY.js → csv-parser-_JWMLGl3.js} +0 -0
  324. /package/dist/web/assets/{cue-DinoJ_5k.js → cue-BmUNowrt.js} +0 -0
  325. /package/dist/web/assets/{cypher-DzxqmkUW.js → cypher-XjXHgCNS.js} +0 -0
  326. /package/dist/web/assets/{d-BxNwJuEC.js → d-BWJnZtig.js} +0 -0
  327. /package/dist/web/assets/{dark-plus-Clmv3V-0.js → dark-plus-Db7umas1.js} +0 -0
  328. /package/dist/web/assets/{dart-BWVtXD35.js → dart-DSI4HYh1.js} +0 -0
  329. /package/dist/web/assets/{data-grid-types-B4n51Fck.js → data-grid-types-CfVHh9gv.js} +0 -0
  330. /package/dist/web/assets/{dax-DsImuWgJ.js → dax-yw1JsAni.js} +0 -0
  331. /package/dist/web/assets/{desktop-B0jJuG2r.js → desktop-C2QO4RvD.js} +0 -0
  332. /package/dist/web/assets/{diff-CWqAAxoE.js → diff-Drt8aEyp.js} +0 -0
  333. /package/dist/web/assets/{dist-B-EXdSYE.js → dist-DNRvhVdz.js} +0 -0
  334. /package/dist/web/assets/{dist-C0eNNfbt.js → dist-VBxOHLmN.js} +0 -0
  335. /package/dist/web/assets/{docker-CYFCJdIL.js → docker-ByDKbmLl.js} +0 -0
  336. /package/dist/web/assets/{dotenv-CKDUjURg.js → dotenv-BkfOLytR.js} +0 -0
  337. /package/dist/web/assets/{dracula-CSoPspHE.js → dracula-DAmrm-Un.js} +0 -0
  338. /package/dist/web/assets/{dracula-soft-BuFjw5L1.js → dracula-soft-BUOEnKqR.js} +0 -0
  339. /package/dist/web/assets/{dream-maker-B6PdDRZu.js → dream-maker-DQBIfSiO.js} +0 -0
  340. /package/dist/web/assets/{emacs-lisp-CMcXvD0G.js → emacs-lisp-Blh5kBD3.js} +0 -0
  341. /package/dist/web/assets/{everforest-dark-cU8-wYzi.js → everforest-dark-CEzhDxHq.js} +0 -0
  342. /package/dist/web/assets/{everforest-light-KhorllqK.js → everforest-light-CPk_5Khm.js} +0 -0
  343. /package/dist/web/assets/{external-link-B8BynhvY.js → external-link-B6Hl0U4X.js} +0 -0
  344. /package/dist/web/assets/{fennel-BCELZK87.js → fennel-B1MT_EBZ.js} +0 -0
  345. /package/dist/web/assets/{file-exclamation-point-CZ4DiR75.js → file-exclamation-point-JzhTU2TX.js} +0 -0
  346. /package/dist/web/assets/{fish-BQc0y_jy.js → fish-C_HGcewt.js} +0 -0
  347. /package/dist/web/assets/{fluent-BTINnwF6.js → fluent-Dp1Iclmx.js} +0 -0
  348. /package/dist/web/assets/{folder-symlink-B8XrtvQK.js → folder-symlink-Dx1hOk8X.js} +0 -0
  349. /package/dist/web/assets/{format-bytes-WVcFxJuT.js → format-bytes-53WBtyi2.js} +0 -0
  350. /package/dist/web/assets/{fortran-free-form-BQim9wDz.js → fortran-free-form-B_-UA4XC.js} +0 -0
  351. /package/dist/web/assets/{gdscript-03w5u8un.js → gdscript-Bm_JpjS_.js} +0 -0
  352. /package/dist/web/assets/{gdshader-Dp2daNzU.js → gdshader-C_PNmfYU.js} +0 -0
  353. /package/dist/web/assets/{genie-CoNcjPiD.js → genie-B5rmR2TF.js} +0 -0
  354. /package/dist/web/assets/{gherkin-NrPOSPQL.js → gherkin-BTJ34TJ9.js} +0 -0
  355. /package/dist/web/assets/{github-dark-z4RE9ZqA.js → github-dark-DOkNVj9H.js} +0 -0
  356. /package/dist/web/assets/{github-dark-default-DOKw-1cI.js → github-dark-default-DTsmiyVo.js} +0 -0
  357. /package/dist/web/assets/{github-dark-dimmed-DJRNMkEA.js → github-dark-dimmed-CjbxAe9s.js} +0 -0
  358. /package/dist/web/assets/{github-dark-high-contrast-Bj7jJ_Gs.js → github-dark-high-contrast-r_M8F_k7.js} +0 -0
  359. /package/dist/web/assets/{github-light-B4k_yMFu.js → github-light-BzfxyMyb.js} +0 -0
  360. /package/dist/web/assets/{github-light-default-BHc-Uzhs.js → github-light-default-BOqiBIy5.js} +0 -0
  361. /package/dist/web/assets/{github-light-high-contrast-CHisIywL.js → github-light-high-contrast-DQzBrDM4.js} +0 -0
  362. /package/dist/web/assets/{gleam-CfbypZ4q.js → gleam-BWmuAtD8.js} +0 -0
  363. /package/dist/web/assets/{gn-YoAjyhJa.js → gn-CNQPjiZW.js} +0 -0
  364. /package/dist/web/assets/{gnuplot-xVkc1f1c.js → gnuplot-BlHjcPMe.js} +0 -0
  365. /package/dist/web/assets/{go-GPCwP3Gu.js → go-Bn8Ba9uz.js} +0 -0
  366. /package/dist/web/assets/{groovy-Crh4Yww9.js → groovy-C1Y1_F4V.js} +0 -0
  367. /package/dist/web/assets/{gruvbox-dark-hard-BluUFuDS.js → gruvbox-dark-hard-DueOsHav.js} +0 -0
  368. /package/dist/web/assets/{gruvbox-dark-medium-Cxk1FWQp.js → gruvbox-dark-medium-DaQjD538.js} +0 -0
  369. /package/dist/web/assets/{gruvbox-dark-soft-CHXMiFmj.js → gruvbox-dark-soft-CbbX2WOm.js} +0 -0
  370. /package/dist/web/assets/{gruvbox-light-hard-B6eKPjAD.js → gruvbox-light-hard-E2M70ljZ.js} +0 -0
  371. /package/dist/web/assets/{gruvbox-light-medium-pDwMm1ut.js → gruvbox-light-medium-B_DDLY6h.js} +0 -0
  372. /package/dist/web/assets/{gruvbox-light-soft-Cxu6kHqK.js → gruvbox-light-soft-2SZmyC1F.js} +0 -0
  373. /package/dist/web/assets/{haskell-C6JKHjbK.js → haskell-D8DeoXtG.js} +0 -0
  374. /package/dist/web/assets/{haxe-BuBNdF0a.js → haxe-BmZm7B0W.js} +0 -0
  375. /package/dist/web/assets/{hcl-DZpDdGj2.js → hcl-CKnBM3ng.js} +0 -0
  376. /package/dist/web/assets/{hjson-CBkhYRuo.js → hjson-Ct9t4-ci.js} +0 -0
  377. /package/dist/web/assets/{hlsl-C5nMxnp9.js → hlsl-BZSASBqS.js} +0 -0
  378. /package/dist/web/assets/{horizon-VAFvA6R6.js → horizon-CzX1AZ08.js} +0 -0
  379. /package/dist/web/assets/{horizon-bright-BC0xn7T3.js → horizon-bright-CCVNeRIP.js} +0 -0
  380. /package/dist/web/assets/{houston-BxrUivmz.js → houston-DBlJN7xc.js} +0 -0
  381. /package/dist/web/assets/{hy-DLtOXoaH.js → hy-Dyc6h6Xb.js} +0 -0
  382. /package/dist/web/assets/{image-gallery-Gnf7TdCR.js → image-gallery-DujlrjOC.js} +0 -0
  383. /package/dist/web/assets/{imba-BdpFXM2W.js → imba-Bauru7s2.js} +0 -0
  384. /package/dist/web/assets/{ini-BInJO_T0.js → ini-SjdwtaTp.js} +0 -0
  385. /package/dist/web/assets/{java-Dxuddnkb.js → java-D2r0ocpf.js} +0 -0
  386. /package/dist/web/assets/{javascript-CVamJfLY.js → javascript-y-lof7iP.js} +0 -0
  387. /package/dist/web/assets/{json-BLZ0ozYk.js → json-DO4LSx5A.js} +0 -0
  388. /package/dist/web/assets/{json5-BnXzmMKs.js → json5-BEwWf-W3.js} +0 -0
  389. /package/dist/web/assets/{jsonc-CSgkSga7.js → jsonc-OBEFv7gP.js} +0 -0
  390. /package/dist/web/assets/{jsonl-CY5W2nF2.js → jsonl-DOyW4Mg3.js} +0 -0
  391. /package/dist/web/assets/{jsonnet-CEJYH3sF.js → jsonnet-BL5R2CpP.js} +0 -0
  392. /package/dist/web/assets/{jssm-CsJc7Uhk.js → jssm-ksPusAyg.js} +0 -0
  393. /package/dist/web/assets/{jsx-jCiRaHU7.js → jsx-B6XEu6O-.js} +0 -0
  394. /package/dist/web/assets/{kanagawa-dragon-DfoA_GxX.js → kanagawa-dragon-JBVe_ji_.js} +0 -0
  395. /package/dist/web/assets/{kanagawa-lotus-BOLYJpWd.js → kanagawa-lotus-ChprO68_.js} +0 -0
  396. /package/dist/web/assets/{kanagawa-wave-DfKlbT1G.js → kanagawa-wave-D_uB_R0Q.js} +0 -0
  397. /package/dist/web/assets/{kdl-CmssIFTi.js → kdl-pf5B8N_m.js} +0 -0
  398. /package/dist/web/assets/{kotlin-BRsNgp6x.js → kotlin-BdF0METC.js} +0 -0
  399. /package/dist/web/assets/{kusto-T8X9jUab.js → kusto-BneVP-OU.js} +0 -0
  400. /package/dist/web/assets/{laserwave-DkJMVJ8Z.js → laserwave-C4-UPIyG.js} +0 -0
  401. /package/dist/web/assets/{lean-C65KGVPq.js → lean-BN6Jdymq.js} +0 -0
  402. /package/dist/web/assets/{less-exIPdDlf.js → less-Cx-fdlDC.js} +0 -0
  403. /package/dist/web/assets/{lib-mC1NZfuw.js → lib-CMuBa85c.js} +0 -0
  404. /package/dist/web/assets/{libesm-DSutUtl1.js → libesm-BB74PRsH.js} +0 -0
  405. /package/dist/web/assets/{light-plus-DiHUXAZt.js → light-plus-DFnnn_iL.js} +0 -0
  406. /package/dist/web/assets/{llvm-CJBnEzFM.js → llvm-BGxtW0Nw.js} +0 -0
  407. /package/dist/web/assets/{loader-circle-gSPVxfvH.js → loader-circle-Dpqcv0eS.js} +0 -0
  408. /package/dist/web/assets/{lock-Did-87UV.js → lock-DldbT31x.js} +0 -0
  409. /package/dist/web/assets/{log-DxMyUMuP.js → log-kQb4eJnj.js} +0 -0
  410. /package/dist/web/assets/{logo-CC9NKzca.js → logo-DqAzaq7s.js} +0 -0
  411. /package/dist/web/assets/{luau-Bw10I6zf.js → luau-Dc2cp-zS.js} +0 -0
  412. /package/dist/web/assets/{make-C_6M90m6.js → make-DYg9dwaJ.js} +0 -0
  413. /package/dist/web/assets/{markdown-bR9_R-LF.js → markdown-O4EPpS3K.js} +0 -0
  414. /package/dist/web/assets/{material-theme-BUx2Qujn.js → material-theme-ClP8yfQ2.js} +0 -0
  415. /package/dist/web/assets/{material-theme-darker-CRJrPgKm.js → material-theme-darker-LOK55hGu.js} +0 -0
  416. /package/dist/web/assets/{material-theme-lighter-CUAYppPa.js → material-theme-lighter-j72tzZqi.js} +0 -0
  417. /package/dist/web/assets/{material-theme-ocean-DuINF1fg.js → material-theme-ocean-C19LKClA.js} +0 -0
  418. /package/dist/web/assets/{material-theme-palenight-W6_icGCj.js → material-theme-palenight-DJ5tN2ax.js} +0 -0
  419. /package/dist/web/assets/{matlab-rfqn_b3z.js → matlab-DQNZ_NU8.js} +0 -0
  420. /package/dist/web/assets/{mdx-Bh1B_YOJ.js → mdx-CJayB7XK.js} +0 -0
  421. /package/dist/web/assets/{mermaid-Dxf6Ya2k.js → mermaid-Cb0TRX92.js} +0 -0
  422. /package/dist/web/assets/{min-dark-CivZ2L0h.js → min-dark-CWM8Bo-m.js} +0 -0
  423. /package/dist/web/assets/{min-light-B1Ykqtma.js → min-light-BBR1sjS2.js} +0 -0
  424. /package/dist/web/assets/{mipsasm-DynHaM0d.js → mipsasm-Jc7u7YSS.js} +0 -0
  425. /package/dist/web/assets/{mojo-Clw5PbGH.js → mojo-CTB0cutd.js} +0 -0
  426. /package/dist/web/assets/{monitor-Dv8vn_6O.js → monitor-4vWfqzuN.js} +0 -0
  427. /package/dist/web/assets/{monokai-DFIooFZT.js → monokai-CvM_YNKx.js} +0 -0
  428. /package/dist/web/assets/{moonbit-DnBSZWGM.js → moonbit-CbFEfYYM.js} +0 -0
  429. /package/dist/web/assets/{move-CCcL2PfL.js → move-BT38p0kT.js} +0 -0
  430. /package/dist/web/assets/{narrat-BDarg5Lk.js → narrat-55QZ_kOG.js} +0 -0
  431. /package/dist/web/assets/{nextflow-groovy-DrZOeCNW.js → nextflow-groovy-Bg8peyqg.js} +0 -0
  432. /package/dist/web/assets/{night-owl-BnZZCK7v.js → night-owl-DzS77iPK.js} +0 -0
  433. /package/dist/web/assets/{night-owl-light-CEwBsVHS.js → night-owl-light-DER7fGnx.js} +0 -0
  434. /package/dist/web/assets/{nix-amCzOPMR.js → nix-BSI8YesN.js} +0 -0
  435. /package/dist/web/assets/{nord-BIs2BC6q.js → nord-9bn7iNWo.js} +0 -0
  436. /package/dist/web/assets/{nushell-Y02fo4yw.js → nushell-qDVZn_lw.js} +0 -0
  437. /package/dist/web/assets/{objective-c-7xOZtWW1.js → objective-c-Blf-ATos.js} +0 -0
  438. /package/dist/web/assets/{objective-cpp-eVtjUvVB.js → objective-cpp-Bz8bAq47.js} +0 -0
  439. /package/dist/web/assets/{ocaml-Bi6ZwqG4.js → ocaml-B9heAsc3.js} +0 -0
  440. /package/dist/web/assets/{odin-8xf1Y0S9.js → odin-BaFYnOwO.js} +0 -0
  441. /package/dist/web/assets/{one-dark-pro-hVv-_y_b.js → one-dark-pro-D6B_hSe-.js} +0 -0
  442. /package/dist/web/assets/{one-light-CJJ3MtHt.js → one-light-Ba-f0wyk.js} +0 -0
  443. /package/dist/web/assets/{openscad-B2HcywLk.js → openscad-UvYyL2MK.js} +0 -0
  444. /package/dist/web/assets/{pascal-C7fllV_7.js → pascal-B4-qvEoG.js} +0 -0
  445. /package/dist/web/assets/{pkl-qvLC1IWP.js → pkl-B146nqGx.js} +0 -0
  446. /package/dist/web/assets/{plastic-BT1wHZv2.js → plastic-L38t-Id3.js} +0 -0
  447. /package/dist/web/assets/{play-4MZi1Axp.js → play-CpCAoQRZ.js} +0 -0
  448. /package/dist/web/assets/{plsql-1MsmdmJD.js → plsql-ItOG5Cca.js} +0 -0
  449. /package/dist/web/assets/{plus-BhMZqFsN.js → plus-BR0qewJI.js} +0 -0
  450. /package/dist/web/assets/{po-BigskytD.js → po-imiCTaNX.js} +0 -0
  451. /package/dist/web/assets/{poimandres-DuklniF7.js → poimandres-Bu6sIba9.js} +0 -0
  452. /package/dist/web/assets/{polar-e2pjN_sp.js → polar-CTeGoFxV.js} +0 -0
  453. /package/dist/web/assets/{portal-container-context-Cm5HipFr.js → portal-container-context-a399Hd9F.js} +0 -0
  454. /package/dist/web/assets/{postcss-DtAeYjWw.js → postcss-jvFe6GNE.js} +0 -0
  455. /package/dist/web/assets/{powerquery-Cr2PtehI.js → powerquery-D9Dw1hJp.js} +0 -0
  456. /package/dist/web/assets/{powershell-BxFTGLJ4.js → powershell-CZqvYQtg.js} +0 -0
  457. /package/dist/web/assets/{prisma-COWJiwdZ.js → prisma-B4D2nO_7.js} +0 -0
  458. /package/dist/web/assets/{prolog-DFvGKRx6.js → prolog-CQbyUcCF.js} +0 -0
  459. /package/dist/web/assets/{proto-CcK80lFt.js → proto-Cwpo0cW1.js} +0 -0
  460. /package/dist/web/assets/{puppet-BF60bZ4F.js → puppet-CKxCwBod.js} +0 -0
  461. /package/dist/web/assets/{purescript-zL_69MzU.js → purescript-B-MyXMMp.js} +0 -0
  462. /package/dist/web/assets/{python-CIwKhfb_.js → python-D6QbSR2S.js} +0 -0
  463. /package/dist/web/assets/{qmldir-CXNe04Lo.js → qmldir-BpTSVcw_.js} +0 -0
  464. /package/dist/web/assets/{qss-C8lAWe6G.js → qss-DBc4gbpe.js} +0 -0
  465. /package/dist/web/assets/{r-CL5ZVL3_.js → r-i9jMMi0s.js} +0 -0
  466. /package/dist/web/assets/{racket-BBfh0uh0.js → racket-BWNaxU7C.js} +0 -0
  467. /package/dist/web/assets/{raku-o6E8R5Q3.js → raku-fqTZLn7L.js} +0 -0
  468. /package/dist/web/assets/{react-CBTnT4sY.js → react-X4jUntEf.js} +0 -0
  469. /package/dist/web/assets/{red-GomRF2Xp.js → red-D-JEcuzA.js} +0 -0
  470. /package/dist/web/assets/{refresh-cw-B06yaBrW.js → refresh-cw-B9iv7csb.js} +0 -0
  471. /package/dist/web/assets/{reg-_ffDIvx9.js → reg-BbirlU1S.js} +0 -0
  472. /package/dist/web/assets/{regexp-Bl5sF65W.js → regexp-D8VTFrtg.js} +0 -0
  473. /package/dist/web/assets/{rel-DgMdqDuj.js → rel-ByQGKiNM.js} +0 -0
  474. /package/dist/web/assets/{resolve-theme-CRt_7wpd.js → resolve-theme-Cqb9zWYc.js} +0 -0
  475. /package/dist/web/assets/{riscv-8b3-Ye4X.js → riscv-B5nqCfLE.js} +0 -0
  476. /package/dist/web/assets/{ron-DrmU1KHP.js → ron-DOVh_iZR.js} +0 -0
  477. /package/dist/web/assets/{rose-pine-dawn-DEfhNlFH.js → rose-pine-dawn-B7hkmmWy.js} +0 -0
  478. /package/dist/web/assets/{rose-pine-C_-E2tF1.js → rose-pine-jp51ZUzi.js} +0 -0
  479. /package/dist/web/assets/{rose-pine-moon-BdvX3gdn.js → rose-pine-moon-Ff063yLj.js} +0 -0
  480. /package/dist/web/assets/{rosmsg-B6GhGpd5.js → rosmsg-Cyk7Il8z.js} +0 -0
  481. /package/dist/web/assets/{rotate-ccw-COXu_9oj.js → rotate-ccw-DnuPzJRE.js} +0 -0
  482. /package/dist/web/assets/{rust-DmC97M1-.js → rust-DRNM5epF.js} +0 -0
  483. /package/dist/web/assets/{sass-B0tJOHLM.js → sass-D_cB0-M1.js} +0 -0
  484. /package/dist/web/assets/{save-CtIGOjmx.js → save-DxonD4y1.js} +0 -0
  485. /package/dist/web/assets/{scala-n8zaFOXv.js → scala-Crl-1kKS.js} +0 -0
  486. /package/dist/web/assets/{scheme-BKD9ztBU.js → scheme-DCaWyEJ0.js} +0 -0
  487. /package/dist/web/assets/{sdbl-D8gB5-rS.js → sdbl-BbXNqwtX.js} +0 -0
  488. /package/dist/web/assets/{send-BlyNJAzy.js → send-B-t5Mz26.js} +0 -0
  489. /package/dist/web/assets/{shallow-DYo6goJ4.js → shallow-4zAfs2KW.js} +0 -0
  490. /package/dist/web/assets/{shellscript-BfXlf_Ao.js → shellscript-BAgksBhW.js} +0 -0
  491. /package/dist/web/assets/{shield-check-B0iGUiOK.js → shield-check-CdTiK1j2.js} +0 -0
  492. /package/dist/web/assets/{shield-off-BNLWBhcq.js → shield-off-DuetkXKM.js} +0 -0
  493. /package/dist/web/assets/{slack-dark-CylEddse.js → slack-dark-GB-ElUW_.js} +0 -0
  494. /package/dist/web/assets/{slack-ochin-w8wg8vuC.js → slack-ochin-tU6CFD3S.js} +0 -0
  495. /package/dist/web/assets/{smalltalk-hiAXA64u.js → smalltalk-DSVGUbtL.js} +0 -0
  496. /package/dist/web/assets/{snazzy-light-BwlV3Xty.js → snazzy-light-DZhi3PoS.js} +0 -0
  497. /package/dist/web/assets/{solarized-dark-vmNGdykz.js → solarized-dark-D6AMCco7.js} +0 -0
  498. /package/dist/web/assets/{solarized-light-DGv_0JXq.js → solarized-light-DepuTWSE.js} +0 -0
  499. /package/dist/web/assets/{solidity-Y7QSH0B1.js → solidity-CsxN618l.js} +0 -0
  500. /package/dist/web/assets/{splunk-BtgpLjHi.js → splunk-CF1m0Kkv.js} +0 -0
  501. /package/dist/web/assets/{sql-CRHYhOia.js → sql-DvyMDgrB.js} +0 -0
  502. /package/dist/web/assets/{ssh-config-DOqSs3au.js → ssh-config-a8sDo-Q8.js} +0 -0
  503. /package/dist/web/assets/{stylus-crCAEaBT.js → stylus-DCJ-6AjT.js} +0 -0
  504. /package/dist/web/assets/{swift-eE3rT7TC.js → swift-c-ZFxyPP.js} +0 -0
  505. /package/dist/web/assets/{synthwave-84-BWy14LBX.js → synthwave-84-9NPgBcuv.js} +0 -0
  506. /package/dist/web/assets/{system-verilog-DC0-DZM4.js → system-verilog-DPD02IOo.js} +0 -0
  507. /package/dist/web/assets/{systemd-to5p6N8I.js → systemd-BUr5HRtU.js} +0 -0
  508. /package/dist/web/assets/{table-Bbc783ko.js → table-FLU8ei8b.js} +0 -0
  509. /package/dist/web/assets/{talonscript-DoTcU8wm.js → talonscript-BNBQV5YJ.js} +0 -0
  510. /package/dist/web/assets/{tasl-cNZvUs95.js → tasl-BETjpSyu.js} +0 -0
  511. /package/dist/web/assets/{tcl-mZE8sZH8.js → tcl-Clp_AZiC.js} +0 -0
  512. /package/dist/web/assets/{terraform-CqHPpIfu.js → terraform-B0kZ0lim.js} +0 -0
  513. /package/dist/web/assets/{text-wrap-CBT4Gxtg.js → text-wrap-B05VGRa-.js} +0 -0
  514. /package/dist/web/assets/{tokyo-night-Tp2rTIZd.js → tokyo-night-oOJ0a7Dk.js} +0 -0
  515. /package/dist/web/assets/{toml-CU_vscgn.js → toml-DOPCSumy.js} +0 -0
  516. /package/dist/web/assets/{trash-2-Bk4yYlck.js → trash-2-CTXlTflF.js} +0 -0
  517. /package/dist/web/assets/{triangle-alert-B8EYecpe.js → triangle-alert-BRq0VAfd.js} +0 -0
  518. /package/dist/web/assets/{tsv-ik7iFB9D.js → tsv-D6qUGf84.js} +0 -0
  519. /package/dist/web/assets/{tsx-BMvvMKiv.js → tsx-B6qYhT6O.js} +0 -0
  520. /package/dist/web/assets/{turtle-DBqKCq9o.js → turtle-C0Rjzw73.js} +0 -0
  521. /package/dist/web/assets/{typescript-DXJDmMZZ.js → typescript-BiydShEu.js} +0 -0
  522. /package/dist/web/assets/{typespec-CBseCMtZ.js → typespec-DjmF6Aww.js} +0 -0
  523. /package/dist/web/assets/{typst-4oY25U9y.js → typst-CPuscfcL.js} +0 -0
  524. /package/dist/web/assets/{use-is-mobile-D1weanbj.js → use-is-mobile-b94q8RvF.js} +0 -0
  525. /package/dist/web/assets/{utils-BNRH507E.js → utils-C9OjCrou.js} +0 -0
  526. /package/dist/web/assets/{v-BXaZ_1oy.js → v-DE4vpLLQ.js} +0 -0
  527. /package/dist/web/assets/{vala-BImWJE7z.js → vala-CmUF2pS5.js} +0 -0
  528. /package/dist/web/assets/{vb-CLfj2_sy.js → vb-BvcRoX4b.js} +0 -0
  529. /package/dist/web/assets/{vendor-xterm-_yyu5n32.js → vendor-xterm-K8kpLxdb.js} +0 -0
  530. /package/dist/web/assets/{verilog-BWa8Ed2b.js → verilog-BGIzyH3R.js} +0 -0
  531. /package/dist/web/assets/{vesper-BGj1cg6m.js → vesper-CG7IrHQQ.js} +0 -0
  532. /package/dist/web/assets/{vhdl-mByK7mlx.js → vhdl-DMSumomw.js} +0 -0
  533. /package/dist/web/assets/{viml-CugmlW5g.js → viml-Drt7AEmU.js} +0 -0
  534. /package/dist/web/assets/{vitesse-black-vPdpy9TL.js → vitesse-black-DmsjfN0b.js} +0 -0
  535. /package/dist/web/assets/{vitesse-dark-BuQK3dUh.js → vitesse-dark-Dl55_WeJ.js} +0 -0
  536. /package/dist/web/assets/{vitesse-light-B3nz1XL9.js → vitesse-light-Crbv9aGg.js} +0 -0
  537. /package/dist/web/assets/{vyper-DH_GTIHG.js → vyper-CB7psEJj.js} +0 -0
  538. /package/dist/web/assets/{wasm-DfVbVJlW.js → wasm-BY1tuM5m.js} +0 -0
  539. /package/dist/web/assets/{wasm-C-LF9GjX.js → wasm-Dck8KPgP.js} +0 -0
  540. /package/dist/web/assets/{wenyan-CzQkHyHx.js → wenyan-DhewQ68b.js} +0 -0
  541. /package/dist/web/assets/{wgsl-Du_M1DW9.js → wgsl-DlmiP456.js} +0 -0
  542. /package/dist/web/assets/{wikitext-BWN_w5S7.js → wikitext-cQCnqNgE.js} +0 -0
  543. /package/dist/web/assets/{wit-BR13v5HD.js → wit-S5MaCngB.js} +0 -0
  544. /package/dist/web/assets/{wolfram-BoXxp_Xl.js → wolfram-Bh8n_9zr.js} +0 -0
  545. /package/dist/web/assets/{x-nhriOX9o.js → x-YDu4m2Iq.js} +0 -0
  546. /package/dist/web/assets/{yaml-DpR_EF-d.js → yaml-BoK_17l9.js} +0 -0
  547. /package/dist/web/assets/{zenscript-C-EdUtUd.js → zenscript-DB3ZFwNJ.js} +0 -0
  548. /package/dist/web/assets/{zig-BD4eA5nU.js → zig-Bv1BWmfT.js} +0 -0
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Permanent Tunnel Manager entry point for the named tunnel: status display
3
+ * plus the actions that survive after the first-run popup is gone or was
4
+ * closed early. Uses its own `useNamedTunnelSetup()` instance — see that
5
+ * hook's docstring for why two instances stay in sync without a shared store.
6
+ */
7
+ import { useState } from "react";
8
+ import { ExternalLink, Copy, Check, ShieldAlert, AlertTriangle } from "lucide-react";
9
+ import { toast } from "sonner";
10
+ import { namedTunnelApi } from "@/lib/api-named-tunnel";
11
+ import { copyToClipboard } from "@/lib/clipboard";
12
+ import { useNamedTunnelSetup } from "./use-named-tunnel-setup";
13
+ import { NamedTunnelSetupContent } from "./named-tunnel-setup-content";
14
+ import { namedTunnelCopy } from "./named-tunnel-copy";
15
+
16
+ export function NamedTunnelSection() {
17
+ const t = useNamedTunnelSetup();
18
+ const [confirmDisable, setConfirmDisable] = useState(false);
19
+ const [disabling, setDisabling] = useState(false);
20
+ const [copied, setCopied] = useState(false);
21
+ const c = namedTunnelCopy.section;
22
+ const status = t.status;
23
+
24
+ if (!status) return null; // still loading — avoid flashing empty controls
25
+
26
+ // Disabling the domain kills the connector that is serving this page, so the
27
+ // temporary URL that replaces it can never reach whoever pressed the button.
28
+ const servedByOwnHostname =
29
+ !!status.hostname && typeof window !== "undefined" && window.location.hostname === status.hostname;
30
+
31
+ // "ask-domain" is the popup's own opening question; the section skips it and
32
+ // shows a plain "Set up" button instead, since clicking that button already
33
+ // means "yes".
34
+ const inFlow = t.step.k !== "hidden" && t.step.k !== "ask-domain";
35
+ // Optional until the server route lands it — default to "on" so this never
36
+ // hides real functionality on a build that predates the field, but never
37
+ // reopens it for a genuine `false`.
38
+ const authEnabled = status.authEnabled ?? true;
39
+ // What is actually serving traffic, not just what was asked for — a failed
40
+ // named spawn falls back to quick while `mode` (the persisted request)
41
+ // still says "named".
42
+ const displayMode = status.liveMode ?? status.mode;
43
+ const certNeedsRelogin = status.certState === "invalid" || status.certState === "mismatch";
44
+
45
+ async function handleDisable() {
46
+ if (!confirmDisable) {
47
+ setConfirmDisable(true);
48
+ setTimeout(() => setConfirmDisable(false), 4000);
49
+ return;
50
+ }
51
+ setConfirmDisable(false);
52
+ setDisabling(true);
53
+ try {
54
+ await namedTunnelApi.disable();
55
+ toast.success("Đã chuyển về quick tunnel");
56
+ await t.refreshStatus();
57
+ } catch (e) {
58
+ toast.error(e instanceof Error ? e.message : "Không chuyển được về quick tunnel");
59
+ } finally {
60
+ setDisabling(false);
61
+ }
62
+ }
63
+
64
+ async function copyHostname(hostname: string) {
65
+ const ok = await copyToClipboard(`https://${hostname}`);
66
+ if (!ok) { toast.error("Failed to copy URL"); return; }
67
+ setCopied(true);
68
+ setTimeout(() => setCopied(false), 2000);
69
+ }
70
+
71
+ return (
72
+ <div className="p-3 border-b border-border bg-surface space-y-3">
73
+ <div className="flex items-center gap-2">
74
+ <span className="text-sm font-medium text-text-primary">{c.title}</span>
75
+ <span className={`px-1.5 py-0.5 rounded text-[10px] font-medium uppercase tracking-wide ${
76
+ displayMode === "named" ? "bg-success/10 text-success" : "bg-surface-elevated text-text-secondary"
77
+ }`}>
78
+ {displayMode === "named" ? c.modeNamed : c.modeQuick}
79
+ </span>
80
+ {status.mode !== displayMode && (
81
+ <span className="text-[10px] text-text-subtle">({c.configuredAs(status.mode)})</span>
82
+ )}
83
+ </div>
84
+
85
+ {status.mode === "named" && status.hostname && (
86
+ <div className="flex items-center gap-1 text-xs">
87
+ <a href={`https://${status.hostname}`} target="_blank" rel="noopener noreferrer" className="flex-1 min-w-0 truncate text-primary hover:underline">
88
+ {status.hostname}
89
+ </a>
90
+ <button
91
+ onClick={() => copyHostname(status.hostname!)}
92
+ aria-label="Copy URL"
93
+ className="shrink-0 size-11 flex items-center justify-center rounded-md hover:bg-surface-elevated transition-colors"
94
+ >
95
+ {copied ? <Check className="size-3.5 text-success" /> : <Copy className="size-3.5 text-text-secondary" />}
96
+ </button>
97
+ <a
98
+ href={`https://${status.hostname}`} target="_blank" rel="noopener noreferrer"
99
+ className="shrink-0 size-11 flex items-center justify-center rounded-md hover:bg-surface-elevated transition-colors"
100
+ >
101
+ <ExternalLink className="size-3.5 text-text-secondary" />
102
+ </a>
103
+ </div>
104
+ )}
105
+
106
+ {status.tokenMasked && (
107
+ <p className="text-[10px] font-mono text-text-subtle">{c.tokenLabel}: {status.tokenMasked}</p>
108
+ )}
109
+
110
+ {status.tunnelWarning && (
111
+ <div className="flex items-center gap-2 rounded-md border border-warning/30 bg-warning/10 px-2.5 py-2 text-xs text-foreground">
112
+ <AlertTriangle className="size-3.5 text-warning shrink-0" />
113
+ {status.tunnelWarning}
114
+ </div>
115
+ )}
116
+
117
+ {certNeedsRelogin && !inFlow && (
118
+ <div className="flex items-center gap-2 rounded-md border border-warning/30 bg-warning/10 px-2.5 py-2 text-xs text-foreground">
119
+ <ShieldAlert className="size-3.5 text-warning shrink-0" />
120
+ {status.certState === "mismatch" ? c.certMismatch : c.certInvalid}
121
+ </div>
122
+ )}
123
+
124
+ {inFlow ? (
125
+ <NamedTunnelSetupContent step={t.step} t={t} />
126
+ ) : !authEnabled ? (
127
+ <p className="text-xs text-text-secondary">{c.authDisabled}</p>
128
+ ) : (
129
+ <div className="flex flex-wrap gap-2">
130
+ {status.mode === "quick" && (
131
+ <button
132
+ onClick={t.answerYes}
133
+ className="min-h-11 px-3 py-2 rounded-md bg-primary text-primary-foreground text-xs font-medium hover:bg-primary/90 transition-colors"
134
+ >
135
+ {c.setup}
136
+ </button>
137
+ )}
138
+ {status.mode === "named" && (
139
+ <button
140
+ onClick={handleDisable}
141
+ disabled={disabling || servedByOwnHostname}
142
+ title={servedByOwnHostname ? c.disableSelfCut : undefined}
143
+ className={`min-h-11 px-3 py-2 rounded-md text-xs transition-colors disabled:opacity-50 ${
144
+ confirmDisable ? "bg-destructive/15 text-destructive" : "border border-border text-text-secondary hover:bg-surface-elevated"
145
+ }`}
146
+ >
147
+ {confirmDisable ? c.disableConfirm : c.disable}
148
+ </button>
149
+ )}
150
+ </div>
151
+ )}
152
+ {/* Turning the domain off kills the connector serving this very page, so
153
+ the replacement link would never reach the user who pressed it. */}
154
+ {status.mode === "named" && servedByOwnHostname && (
155
+ <p className="text-[11px] text-text-secondary leading-relaxed">{c.disableSelfCut}</p>
156
+ )}
157
+ </div>
158
+ );
159
+ }
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Step content switch — one card per step. Both the popup shell and the
3
+ * Tunnel Manager section render this, so it never assumes it is inside a
4
+ * dialog or a sheet (no close button of its own; the shell owns dismissal).
5
+ */
6
+ import { Loader2, AlertCircle } from "lucide-react";
7
+ import type { Step } from "./named-tunnel-step-reducer";
8
+ import type { UseNamedTunnelSetup } from "./use-named-tunnel-setup";
9
+ import { namedTunnelCopy } from "./named-tunnel-copy";
10
+ import { NamedTunnelLoginStep } from "./named-tunnel-login-step";
11
+ import { NamedTunnelHostnameField } from "./named-tunnel-hostname-field";
12
+
13
+ const primaryBtn = "w-full min-h-11 py-3 rounded-lg bg-primary text-primary-foreground text-sm font-medium hover:bg-primary/90 transition-colors disabled:opacity-50 disabled:pointer-events-none";
14
+ const secondaryBtn = "w-full min-h-11 py-3 rounded-lg border border-border text-sm text-text-secondary hover:bg-surface-elevated transition-colors";
15
+
16
+ interface Props {
17
+ step: Step;
18
+ t: UseNamedTunnelSetup;
19
+ }
20
+
21
+ export function NamedTunnelSetupContent({ step, t }: Props) {
22
+ switch (step.k) {
23
+ case "hidden":
24
+ return null;
25
+
26
+ case "ask-domain": {
27
+ const c = namedTunnelCopy.askDomain;
28
+ return (
29
+ <div className="space-y-4">
30
+ <div>
31
+ <h2 className="text-base font-semibold text-foreground">{c.title}</h2>
32
+ <p className="mt-1 text-sm text-text-secondary leading-relaxed">{c.body}</p>
33
+ </div>
34
+ <div className="flex gap-2">
35
+ <button type="button" onClick={t.answerNo} className={secondaryBtn}>{c.no}</button>
36
+ <button type="button" onClick={t.answerYes} className={primaryBtn}>{c.yes}</button>
37
+ </div>
38
+ </div>
39
+ );
40
+ }
41
+
42
+ case "no-domain": {
43
+ const c = namedTunnelCopy.noDomain;
44
+ return (
45
+ <div className="space-y-4">
46
+ <div>
47
+ <h2 className="text-base font-semibold text-foreground">{c.title}</h2>
48
+ <p className="mt-1 text-sm text-text-secondary leading-relaxed">{c.body}</p>
49
+ </div>
50
+ <button type="button" onClick={t.close} className={primaryBtn}>{c.close}</button>
51
+ </div>
52
+ );
53
+ }
54
+
55
+ case "login-wait":
56
+ return <NamedTunnelLoginStep url={step.url} slow={step.slow} onCancel={t.cancelLogin} />;
57
+
58
+ case "login-timeout": {
59
+ const c = namedTunnelCopy.timeout;
60
+ return (
61
+ <div className="space-y-4">
62
+ <div>
63
+ <h2 className="text-base font-semibold text-foreground">{c.title}</h2>
64
+ <p className="mt-1 text-sm text-text-secondary leading-relaxed">{c.body}</p>
65
+ </div>
66
+ <button type="button" onClick={t.retryLogin} className={primaryBtn}>{c.retry}</button>
67
+ </div>
68
+ );
69
+ }
70
+
71
+ case "login-cancelled": {
72
+ const c = namedTunnelCopy.cancelled;
73
+ return (
74
+ <div className="space-y-4">
75
+ <div>
76
+ <h2 className="text-base font-semibold text-foreground">{c.title}</h2>
77
+ <p className="mt-1 text-sm text-text-secondary leading-relaxed">{c.body}</p>
78
+ </div>
79
+ <button type="button" onClick={t.retryLogin} className={primaryBtn}>{c.retry}</button>
80
+ </div>
81
+ );
82
+ }
83
+
84
+ case "confirm-zone": {
85
+ const c = namedTunnelCopy.confirmZone;
86
+ return (
87
+ <div className="space-y-4">
88
+ <div>
89
+ <h2 className="text-base font-semibold text-foreground">{c.title}</h2>
90
+ <p className="mt-1 text-sm text-text-secondary leading-relaxed">{c.body(step.zone)}</p>
91
+ </div>
92
+ <div className="flex gap-2">
93
+ <button type="button" onClick={t.startOver} className={secondaryBtn}>{c.startOver}</button>
94
+ <button type="button" onClick={t.confirmZone} className={primaryBtn}>{c.confirm}</button>
95
+ </div>
96
+ </div>
97
+ );
98
+ }
99
+
100
+ case "needs-relogin": {
101
+ const c = namedTunnelCopy.needsRelogin;
102
+ return (
103
+ <div className="space-y-4">
104
+ <div>
105
+ <h2 className="text-base font-semibold text-foreground">{c.title}</h2>
106
+ <p className="mt-1 text-sm text-text-secondary leading-relaxed">{step.message}</p>
107
+ </div>
108
+ <button type="button" onClick={t.requestRelogin} className={primaryBtn}>{c.action}</button>
109
+ </div>
110
+ );
111
+ }
112
+
113
+ case "choose-hostname": {
114
+ const c = namedTunnelCopy.hostname;
115
+ return (
116
+ <div className="space-y-4">
117
+ <h2 className="text-base font-semibold text-foreground">{c.title}</h2>
118
+ <NamedTunnelHostnameField
119
+ zone={step.zone}
120
+ prefix={step.prefix}
121
+ error={step.error}
122
+ onChange={t.setHostnamePrefix}
123
+ />
124
+ <button
125
+ type="button"
126
+ onClick={t.submitHostname}
127
+ disabled={!step.prefix || !!step.error}
128
+ className={primaryBtn}
129
+ >
130
+ {c.submit}
131
+ </button>
132
+ </div>
133
+ );
134
+ }
135
+
136
+ case "applying":
137
+ return (
138
+ <div className="space-y-4 py-4">
139
+ <div className="flex items-center gap-2 text-sm text-foreground">
140
+ <Loader2 className="size-4 animate-spin text-primary" />
141
+ {step.message}
142
+ </div>
143
+ </div>
144
+ );
145
+
146
+ case "done": {
147
+ const c = namedTunnelCopy.done;
148
+ return (
149
+ <div className="space-y-4">
150
+ <div>
151
+ <h2 className="text-base font-semibold text-foreground">{c.title}</h2>
152
+ <p className="mt-1 text-sm text-text-secondary break-all">{c.body(step.hostname)}</p>
153
+ </div>
154
+ <button type="button" onClick={t.close} className={primaryBtn}>{c.close}</button>
155
+ </div>
156
+ );
157
+ }
158
+
159
+ case "pending": {
160
+ const c = namedTunnelCopy.pending;
161
+ return (
162
+ <div className="space-y-4">
163
+ <div>
164
+ <h2 className="text-base font-semibold text-foreground">{c.title}</h2>
165
+ <p className="mt-1 text-sm text-text-secondary leading-relaxed">{step.message}</p>
166
+ <p className="mt-2 text-xs font-mono text-text-subtle bg-surface-elevated rounded px-2 py-1.5 inline-block">
167
+ ppm restart
168
+ </p>
169
+ </div>
170
+ <button type="button" onClick={t.close} className={primaryBtn}>{c.close}</button>
171
+ </div>
172
+ );
173
+ }
174
+
175
+ case "error": {
176
+ const c = namedTunnelCopy.error;
177
+ return (
178
+ <div className="space-y-4">
179
+ <div className="flex items-start gap-2">
180
+ <AlertCircle className="size-4 text-destructive shrink-0 mt-0.5" />
181
+ <div>
182
+ <h2 className="text-base font-semibold text-foreground">{c.title}</h2>
183
+ <p className="mt-1 text-sm text-text-secondary leading-relaxed">{step.message}</p>
184
+ </div>
185
+ </div>
186
+ <div className="flex gap-2">
187
+ <button type="button" onClick={t.close} className={secondaryBtn}>{c.close}</button>
188
+ <button type="button" onClick={t.retryLogin} className={primaryBtn}>{c.retry}</button>
189
+ </div>
190
+ </div>
191
+ );
192
+ }
193
+
194
+ default:
195
+ return null;
196
+ }
197
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Mount point for the first-run named-tunnel flow: a centred dialog on
3
+ * desktop, a bottom sheet on mobile (`docs/design-guidelines.md` — dialogs
4
+ * must never be desktop-only). Closing (backdrop, swipe, X) only hides this
5
+ * popup instance — it does not call `dismiss()` and does not cancel an
6
+ * in-progress login; the Tunnel Manager section is the permanent re-entry
7
+ * point, so nothing is lost.
8
+ */
9
+ import { useState } from "react";
10
+ import { X } from "lucide-react";
11
+ import { useIsMobile } from "@/hooks/use-is-mobile";
12
+ import { BottomSheet } from "@/components/ui/mobile-bottom-sheet";
13
+ import { useNamedTunnelSetup } from "./use-named-tunnel-setup";
14
+ import { NamedTunnelSetupContent } from "./named-tunnel-setup-content";
15
+
16
+ export function NamedTunnelSetupPopup() {
17
+ const t = useNamedTunnelSetup();
18
+ const isMobile = useIsMobile();
19
+ const [closedByUser, setClosedByUser] = useState(false);
20
+
21
+ const visible = t.step.k !== "hidden" && !closedByUser;
22
+ if (!visible) return null;
23
+
24
+ const handleClose = () => setClosedByUser(true);
25
+
26
+ if (isMobile) {
27
+ return (
28
+ <BottomSheet open={visible} onClose={handleClose} zIndex={45}>
29
+ <div className="px-4 pb-4">
30
+ <NamedTunnelSetupContent step={t.step} t={t} />
31
+ </div>
32
+ </BottomSheet>
33
+ );
34
+ }
35
+
36
+ return (
37
+ <>
38
+ <div className="fixed inset-0 z-[45] bg-black/40" onClick={handleClose} />
39
+ <div
40
+ className="fixed z-[45] top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-full max-w-md max-h-[85vh] overflow-y-auto rounded-xl bg-popover text-popover-foreground border border-border shadow-2xl p-5"
41
+ onClick={(e) => e.stopPropagation()}
42
+ >
43
+ <button
44
+ type="button"
45
+ onClick={handleClose}
46
+ aria-label="Close"
47
+ className="absolute right-3 top-3 size-11 flex items-center justify-center rounded-md hover:bg-surface-elevated transition-colors"
48
+ >
49
+ <X className="size-4" />
50
+ </button>
51
+ <div className="pr-8">
52
+ <NamedTunnelSetupContent step={t.step} t={t} />
53
+ </div>
54
+ </div>
55
+ </>
56
+ );
57
+ }
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Pure step machine for the named-tunnel first-run flow. No side effects here
3
+ * (no fetch, no window events) — `use-named-tunnel-setup.ts` owns those and
4
+ * dispatches actions into `reduceStep`. Kept side-effect-free so the whole
5
+ * transition table is unit-testable without mocking the network or WS.
6
+ */
7
+ import type { LoginState, NamedTunnelStatus } from "@/lib/api-named-tunnel";
8
+ import { namedTunnelCopy } from "./named-tunnel-copy";
9
+ import { DEFAULT_HOSTNAME_PREFIX } from "./hostname-validation";
10
+
11
+ export type Step =
12
+ | { k: "hidden" }
13
+ | { k: "ask-domain" }
14
+ | { k: "no-domain" }
15
+ | { k: "login-wait"; url: string | null; slow: boolean }
16
+ | { k: "login-timeout" }
17
+ | { k: "login-cancelled" }
18
+ | { k: "confirm-zone"; zone: string }
19
+ | { k: "needs-relogin"; message: string }
20
+ | { k: "choose-hostname"; zone: string; prefix: string; error?: string }
21
+ | { k: "applying"; zone: string; prefix: string; message: string }
22
+ | { k: "done"; hostname: string }
23
+ | { k: "pending"; hostname: string; message: string }
24
+ | { k: "error"; message: string };
25
+
26
+ export type Action =
27
+ | { type: "status"; status: NamedTunnelStatus }
28
+ | { type: "answer-yes" }
29
+ | { type: "answer-no" }
30
+ | { type: "login-url"; url: string }
31
+ | { type: "login-state"; state: LoginState; message?: string | null }
32
+ | { type: "cancel" }
33
+ | { type: "retry" }
34
+ | { type: "zone-loaded"; zone: string }
35
+ | { type: "zone-error"; message: string }
36
+ | { type: "confirm-zone" }
37
+ | { type: "start-over" }
38
+ | { type: "hostname-prefix"; prefix: string; error?: string }
39
+ | { type: "submit" }
40
+ | { type: "setup-step"; message: string }
41
+ | { type: "setup-done"; hostname: string }
42
+ | { type: "setup-pending"; hostname: string; message: string }
43
+ | { type: "setup-error"; message: string }
44
+ | { type: "needs-relogin"; message: string }
45
+ | { type: "close" };
46
+
47
+ /** First step to render once `/status` has been read on mount. */
48
+ export function initialStepFromStatus(status: NamedTunnelStatus): Step {
49
+ // `authEnabled` is optional until the server route lands it — a missing
50
+ // value must not silently reopen the popup on an auth-disabled install, so
51
+ // default to "on" only for backward compatibility, never to hide a real
52
+ // `false`.
53
+ const authEnabled = status.authEnabled ?? true;
54
+ if (!authEnabled) {
55
+ return { k: "hidden" };
56
+ }
57
+ if (status.certState === "invalid" || status.certState === "mismatch") {
58
+ return {
59
+ k: "needs-relogin",
60
+ message: status.certState === "mismatch"
61
+ ? namedTunnelCopy.needsRelogin.certMismatch
62
+ : namedTunnelCopy.needsRelogin.certInvalid,
63
+ };
64
+ }
65
+ if (status.mode !== "quick" || status.dismissed) {
66
+ return { k: "hidden" };
67
+ }
68
+ return stepFromLoginState(status.login.state, status.login.url, status.login.message);
69
+ }
70
+
71
+ /**
72
+ * Steps a later `/status` refresh is allowed to recompute. Once the user has
73
+ * committed past login (confirm-zone, choose-hostname, applying) or reached a
74
+ * terminal card (done, pending, no-domain), a stale or lagging status
75
+ * snapshot must not silently reset that progress — only these "not yet
76
+ * committed" steps re-derive from a fresh fetch.
77
+ */
78
+ const STATUS_RESETTABLE: ReadonlySet<Step["k"]> = new Set([
79
+ "hidden", "ask-domain", "login-wait", "login-timeout", "login-cancelled", "needs-relogin", "error",
80
+ ]);
81
+
82
+ /**
83
+ * Steps that are actually waiting on a zone lookup. A login session's
84
+ * `state` stays "success" long after the moment it fired — it is not reset
85
+ * to "idle" — so a later, unrelated `/status` refresh (after setup-done, or
86
+ * on mount of an already-configured install) can still read "success" and
87
+ * ask for the zone again. Without this gate that stray `zone-loaded` would
88
+ * silently replace a "done" card with "confirm-zone", or reopen the hidden
89
+ * popup of a finished install straight into it. Exported so the hook can
90
+ * skip the redundant `/zone` call at the source instead of only discarding
91
+ * its result here.
92
+ */
93
+ export const ZONE_EXPECTING_STEPS: ReadonlySet<Step["k"]> = new Set(["login-wait", "needs-relogin"]);
94
+
95
+ function stepFromLoginState(state: LoginState, url: string | null, message: string | null): Step {
96
+ switch (state) {
97
+ case "waiting":
98
+ return { k: "login-wait", url, slow: false };
99
+ case "slow":
100
+ return { k: "login-wait", url, slow: true };
101
+ case "timeout":
102
+ return { k: "login-timeout" };
103
+ case "cancelled":
104
+ return { k: "login-cancelled" };
105
+ case "error":
106
+ return { k: "error", message: message ?? namedTunnelCopy.error.title };
107
+ case "success":
108
+ // Zone lookup is a hook-level side effect triggered right after this;
109
+ // the spinner stays on the login step until `zone-loaded` arrives.
110
+ return { k: "login-wait", url, slow: false };
111
+ case "idle":
112
+ default:
113
+ return { k: "ask-domain" };
114
+ }
115
+ }
116
+
117
+ export function reduceStep(step: Step, action: Action): Step {
118
+ switch (action.type) {
119
+ case "status":
120
+ return STATUS_RESETTABLE.has(step.k) ? initialStepFromStatus(action.status) : step;
121
+
122
+ case "answer-yes":
123
+ return { k: "login-wait", url: null, slow: false };
124
+
125
+ case "answer-no":
126
+ return { k: "no-domain" };
127
+
128
+ case "login-url":
129
+ return step.k === "login-wait"
130
+ ? { ...step, url: action.url }
131
+ : { k: "login-wait", url: action.url, slow: false };
132
+
133
+ case "login-state":
134
+ return stepFromLoginState(action.state, step.k === "login-wait" ? step.url : null, action.message ?? null);
135
+
136
+ case "cancel":
137
+ return { k: "login-cancelled" };
138
+
139
+ case "retry":
140
+ return { k: "login-wait", url: null, slow: false };
141
+
142
+ case "zone-loaded":
143
+ return ZONE_EXPECTING_STEPS.has(step.k) ? { k: "confirm-zone", zone: action.zone } : step;
144
+
145
+ case "zone-error":
146
+ return ZONE_EXPECTING_STEPS.has(step.k) ? { k: "error", message: action.message } : step;
147
+
148
+ case "confirm-zone":
149
+ return step.k === "confirm-zone"
150
+ ? { k: "choose-hostname", zone: step.zone, prefix: DEFAULT_HOSTNAME_PREFIX }
151
+ : step;
152
+
153
+ case "start-over":
154
+ return { k: "ask-domain" };
155
+
156
+ case "hostname-prefix":
157
+ return step.k === "choose-hostname"
158
+ ? { ...step, prefix: action.prefix, error: action.error }
159
+ : step;
160
+
161
+ case "submit":
162
+ return step.k === "choose-hostname"
163
+ ? { k: "applying", zone: step.zone, prefix: step.prefix, message: namedTunnelCopy.applying.title }
164
+ : step;
165
+
166
+ case "setup-step":
167
+ return step.k === "applying" ? { ...step, message: action.message } : step;
168
+
169
+ case "setup-done":
170
+ return { k: "done", hostname: action.hostname };
171
+
172
+ case "setup-pending":
173
+ return { k: "pending", hostname: action.hostname, message: action.message };
174
+
175
+ case "setup-error":
176
+ // Route back to the hostname field with the reason inline — losing the
177
+ // typed prefix here would make the user re-type it for a typo-sized fix.
178
+ return step.k === "applying"
179
+ ? { k: "choose-hostname", zone: step.zone, prefix: step.prefix, error: action.message }
180
+ : { k: "error", message: action.message };
181
+
182
+ case "needs-relogin":
183
+ return { k: "needs-relogin", message: action.message };
184
+
185
+ case "close":
186
+ return { k: "hidden" };
187
+
188
+ default:
189
+ return step;
190
+ }
191
+ }