@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
@@ -35,6 +35,23 @@ export interface PpmConfig {
35
35
  clawbot?: PPMBotConfig;
36
36
  cloud_url?: string;
37
37
  query_audit: QueryAuditConfig;
38
+ tunnel: TunnelConfig;
39
+ }
40
+
41
+ /**
42
+ * Persisted named-tunnel state. `namedTunnelToken` is secret-by-contract —
43
+ * guarded by the config-key denylist and never returned unmasked by any route.
44
+ * `zoneID`/`accountID` are pinned at setup and re-checked on every reuse.
45
+ */
46
+ export interface TunnelConfig {
47
+ mode: "quick" | "named";
48
+ namedTunnelName?: string;
49
+ namedTunnelHostname?: string;
50
+ namedTunnelToken?: string;
51
+ zoneID?: string;
52
+ accountID?: string;
53
+ /** User answered "no domain" — popup must never nag again. */
54
+ dismissed?: boolean;
38
55
  }
39
56
 
40
57
  export interface QueryAuditConfig {
@@ -131,6 +148,9 @@ export const DEFAULT_CONFIG: PpmConfig = {
131
148
  permission_mode: "bypassPermissions",
132
149
  debounce_ms: 2000,
133
150
  },
151
+ tunnel: {
152
+ mode: "quick",
153
+ },
134
154
  };
135
155
 
136
156
  const VALID_TYPES = ["agent-sdk", "cli", "mock"] as const;
@@ -264,5 +284,16 @@ export function sanitizeConfig(config: PpmConfig): boolean {
264
284
  }
265
285
  }
266
286
 
287
+ // Only repair `tunnel` when storage itself is malformed (wrong type / bad enum).
288
+ // Never strip namedTunnel*/zoneID/accountID just because mode is "quick" or the
289
+ // combination looks "incomplete" — that degrade-to-quick judgment belongs to
290
+ // the runtime resolver (resolveTunnelConfig), or /disable's "keep the config so
291
+ // Retry works" contract silently breaks.
292
+ if (typeof config.tunnel !== "object" || config.tunnel === null ||
293
+ (config.tunnel.mode !== "quick" && config.tunnel.mode !== "named")) {
294
+ config.tunnel = structuredClone(DEFAULT_CONFIG.tunnel);
295
+ dirty = true;
296
+ }
297
+
267
298
  return dirty;
268
299
  }
package/src/web/app.tsx CHANGED
@@ -27,6 +27,7 @@ import { useServerReload } from "@/hooks/use-server-reload";
27
27
  import { CommandPalette } from "@/components/layout/command-palette";
28
28
  import { ComparePicker } from "@/components/editor/compare-picker";
29
29
  import { BugReportPopup } from "@/components/shared/bug-report-popup";
30
+ import { NamedTunnelSetupPopup } from "@/components/tunnels/named-tunnel/named-tunnel-setup-popup";
30
31
  import { ImageOverlay } from "@/components/shared/image-overlay";
31
32
  import { DiagramOverlay } from "@/components/shared/diagram-overlay";
32
33
  import { BackgroundOutputPanel } from "@/components/chat/background-output-panel";
@@ -359,6 +360,10 @@ export function App() {
359
360
  {/* Global bug report popup */}
360
361
  <BugReportPopup />
361
362
 
363
+ {/* Named-tunnel first-run setup popup — hidden unless auth is on, mode is
364
+ still quick and the user has not dismissed it (or a cert needs renewal) */}
365
+ <NamedTunnelSetupPopup />
366
+
362
367
  {/* Global image lightbox */}
363
368
  <ImageOverlay />
364
369
 
@@ -1,5 +1,5 @@
1
1
  import { useState, useEffect, useCallback, useRef, type MouseEvent } from "react";
2
- import { History, Settings2, Loader2, MessageSquare, RefreshCw, Search, Pencil, Check, X, BellOff, Circle, Pin, PinOff, Trash2, Users, Bot, Tags, CalendarX2 } from "lucide-react";
2
+ import { History, Settings2, Loader2, MessageSquare, RefreshCw, Search, Pencil, Check, X, Pin, PinOff, Trash2, Users, Bot, Tags, CalendarX2 } from "lucide-react";
3
3
  import { Activity } from "lucide-react";
4
4
  import { api, projectUrl } from "@/lib/api-client";
5
5
  import { useTabStore } from "@/stores/tab-store";
@@ -8,7 +8,8 @@ import { cn } from "@/lib/utils";
8
8
  import { AISettingsSection } from "@/components/settings/ai-settings-section";
9
9
  import { TagSettingsSection } from "@/components/settings/tag-settings-section";
10
10
  import { SessionContextMenu } from "./session-context-menu";
11
- import { SessionDebugButton } from "./session-debug-dialog";
11
+ import { SessionDebugDialog } from "./session-debug-dialog";
12
+ import { ChatToolbarOverflowMenu } from "./chat-toolbar-overflow-menu";
12
13
  import { UsageDetailPanel } from "./usage-badge";
13
14
  import { CodexUsagePanel } from "./codex-usage-panel";
14
15
  import { TeamActivityPanel } from "./team-activity-panel";
@@ -82,6 +83,7 @@ export function ChatHistoryBar({
82
83
  const [selectedTagId, setSelectedTagId] = useState<number | null>(null);
83
84
  const [tagCounts, setTagCounts] = useState<Record<number, number>>({});
84
85
  const [showTagSettings, setShowTagSettings] = useState(false);
86
+ const [debugOpen, setDebugOpen] = useState(false);
85
87
  const editInputRef = useRef<HTMLInputElement>(null);
86
88
  const openTab = useTabStore((s) => s.openTab);
87
89
  const PAGE_SIZE = 50;
@@ -273,112 +275,88 @@ export function ChatHistoryBar({
273
275
 
274
276
  return (
275
277
  <div className="border-b border-border/50">
276
- {/* Toolbar row — all buttons on one line */}
278
+ {/* Toolbar row — status chips scroll on the left, controls stay pinned right.
279
+ A narrow chat pane must never push the connection indicator out of view. */}
277
280
  <div className="flex items-center gap-1 px-2 py-1">
278
- {/* History */}
279
- <button
280
- onClick={() => togglePanel("history")}
281
- className={`flex items-center gap-1 px-1.5 py-0.5 rounded text-[11px] transition-colors ${
282
- activePanel === "history" ? "text-primary bg-primary/10" : "text-text-secondary hover:text-foreground hover:bg-surface-elevated"
283
- }`}
284
- >
285
- <History className="size-3" />
286
- <span>History</span>
287
- </button>
288
-
289
- {/* Active provider + AI Settings (combined) */}
290
- {sessionId && providerId && providerId !== "mock" ? (
281
+ <div className="flex min-w-0 flex-1 items-center gap-1 overflow-x-auto scrollbar-none">
282
+ {/* History */}
291
283
  <button
292
- onClick={() => togglePanel("config")}
293
- className={`flex items-center gap-1 px-1.5 py-0.5 rounded text-[11px] transition-colors ${
294
- activePanel === "config" ? "text-primary bg-primary/10" : "text-text-secondary hover:text-foreground hover:bg-surface-elevated"
284
+ onClick={() => togglePanel("history")}
285
+ className={`shrink-0 flex items-center gap-1 px-1.5 py-0.5 rounded text-[11px] transition-colors ${
286
+ activePanel === "history" ? "text-primary bg-primary/10" : "text-text-secondary hover:text-foreground hover:bg-surface-elevated"
295
287
  }`}
296
- title="AI Settings"
297
288
  >
298
- <ProviderBadge providerId={providerId} />
299
- <span className="capitalize">{providerId}</span>
289
+ <History className="size-3" />
290
+ <span>History</span>
300
291
  </button>
301
- ) : (
302
- <button
303
- onClick={() => togglePanel("config")}
304
- className={`p-1 rounded transition-colors ${
305
- activePanel === "config" ? "text-primary bg-primary/10" : "text-text-subtle hover:text-text-secondary hover:bg-surface-elevated"
306
- }`}
307
- title="AI Settings"
308
- >
309
- <Settings2 className="size-3" />
310
- </button>
311
- )}
312
-
313
- {/* Usage & Accounts — Claude and Codex both surface usage + account mgmt here */}
314
- {(isClaudeProvider || isCodexProvider) ? (
315
- <button
316
- onClick={() => togglePanel("usage")}
317
- className={`flex items-center gap-1 px-1.5 py-0.5 rounded text-[11px] font-medium tabular-nums transition-colors hover:bg-surface-elevated ${
318
- activePanel === "usage" ? "bg-primary/10" : ""
319
- } ${usageColor}`}
320
- title="Usage limits"
321
- >
322
- <Activity className="size-3" />
323
- {usageInfo.activeAccountLabel && (
324
- <span className="text-text-secondary font-normal truncate max-w-[60px]">[{usageInfo.activeAccountLabel}]</span>
325
- )}
326
- <span>5h:{fiveHourPct != null ? `${fiveHourPct}%` : "--%"}</span>
327
- <span className="text-text-subtle">·</span>
328
- <span>Wk:{sevenDayPct != null ? `${sevenDayPct}%` : "--%"}</span>
329
- </button>
330
- ) : null}
331
-
332
- {/* Team activity */}
333
- {teamActivity?.hasTeams && (
334
- <button
335
- onClick={() => {
336
- togglePanel("team");
337
- onTeamOpen?.();
338
- }}
339
- className={`relative flex items-center gap-1 px-1.5 py-0.5 rounded text-[11px] transition-colors ${
340
- activePanel === "team" ? "text-primary bg-primary/10" : "text-text-secondary hover:text-foreground hover:bg-surface-elevated"
341
- }`}
342
- title="Team activity"
343
- >
344
- <Users className="size-3" />
345
- <span>Team</span>
346
- {(teamActivity.unreadCount ?? 0) > 0 && (
347
- <span className="absolute -top-0.5 -right-0.5 size-2 bg-primary rounded-full animate-pulse" />
348
- )}
349
- </button>
350
- )}
351
292
 
352
- {/* Spacer */}
353
- <div className="flex-1" />
293
+ {/* Active provider + AI Settings (combined) */}
294
+ {sessionId && providerId && providerId !== "mock" ? (
295
+ <button
296
+ onClick={() => togglePanel("config")}
297
+ className={`shrink-0 flex items-center gap-1 px-1.5 py-0.5 rounded text-[11px] transition-colors ${
298
+ activePanel === "config" ? "text-primary bg-primary/10" : "text-text-secondary hover:text-foreground hover:bg-surface-elevated"
299
+ }`}
300
+ title="AI Settings"
301
+ >
302
+ <ProviderBadge providerId={providerId} />
303
+ <span className="capitalize">{providerId}</span>
304
+ </button>
305
+ ) : (
306
+ <button
307
+ onClick={() => togglePanel("config")}
308
+ className={`shrink-0 p-1 rounded transition-colors ${
309
+ activePanel === "config" ? "text-primary bg-primary/10" : "text-text-subtle hover:text-text-secondary hover:bg-surface-elevated"
310
+ }`}
311
+ title="AI Settings"
312
+ >
313
+ <Settings2 className="size-3" />
314
+ </button>
315
+ )}
354
316
 
355
- {/* Mark as read */}
356
- {hasUnread && sessionId && (
357
- <button
358
- onClick={() => clearForSession(sessionId)}
359
- className="p-1 rounded text-warning hover:text-warning/80 hover:bg-surface-elevated transition-colors"
360
- title="Mark as read"
361
- >
362
- <BellOff className="size-3" />
363
- </button>
364
- )}
317
+ {/* Usage & Accounts — Claude and Codex both surface usage + account mgmt here */}
318
+ {(isClaudeProvider || isCodexProvider) ? (
319
+ <button
320
+ onClick={() => togglePanel("usage")}
321
+ className={`shrink-0 flex items-center gap-1 px-1.5 py-0.5 rounded text-[11px] font-medium tabular-nums transition-colors hover:bg-surface-elevated ${
322
+ activePanel === "usage" ? "bg-primary/10" : ""
323
+ } ${usageColor}`}
324
+ title="Usage limits"
325
+ >
326
+ <Activity className="size-3" />
327
+ {usageInfo.activeAccountLabel && (
328
+ <span className="text-text-secondary font-normal truncate max-w-[60px]">[{usageInfo.activeAccountLabel}]</span>
329
+ )}
330
+ <span>5h:{fiveHourPct != null ? `${fiveHourPct}%` : "--%"}</span>
331
+ <span className="text-text-subtle">·</span>
332
+ <span>Wk:{sevenDayPct != null ? `${sevenDayPct}%` : "--%"}</span>
333
+ </button>
334
+ ) : null}
365
335
 
366
- {/* Mark as unread */}
367
- {!hasUnread && sessionId && (
368
- <button
369
- onClick={() => markUnread(sessionId, projectName)}
370
- className="p-1 rounded text-primary hover:text-primary/80 hover:bg-surface-elevated transition-colors"
371
- title="Mark as unread"
372
- >
373
- <Circle className="size-3 fill-current" />
374
- </button>
375
- )}
336
+ {/* Team activity */}
337
+ {teamActivity?.hasTeams && (
338
+ <button
339
+ onClick={() => {
340
+ togglePanel("team");
341
+ onTeamOpen?.();
342
+ }}
343
+ className={`shrink-0 relative flex items-center gap-1 px-1.5 py-0.5 rounded text-[11px] transition-colors ${
344
+ activePanel === "team" ? "text-primary bg-primary/10" : "text-text-secondary hover:text-foreground hover:bg-surface-elevated"
345
+ }`}
346
+ title="Team activity"
347
+ >
348
+ <Users className="size-3" />
349
+ <span>Team</span>
350
+ {(teamActivity.unreadCount ?? 0) > 0 && (
351
+ <span className="absolute -top-0.5 -right-0.5 size-2 bg-primary rounded-full animate-pulse" />
352
+ )}
353
+ </button>
354
+ )}
376
355
 
377
- {/* Debug info — copy session IDs + JSONL path */}
378
- {sessionId && (
379
- <SessionDebugButton sessionId={sessionId} projectName={projectName} />
380
- )}
356
+ </div>
381
357
 
358
+ {/* Pinned controls — always visible, never scrolled away */}
359
+ <div className="flex shrink-0 items-center gap-1 pl-1">
382
360
  {/* Reload messages + connection status */}
383
361
  {onReload && (
384
362
  <button
@@ -397,8 +375,27 @@ export function ChatHistoryBar({
397
375
  <span className={`absolute -top-0.5 -right-0.5 size-1.5 rounded-full ${isConnected ? "bg-success" : "bg-error animate-pulse"}`} />
398
376
  </button>
399
377
  )}
378
+
379
+ {/* Overflow menu — session actions, and the home for future toolbar actions */}
380
+ {sessionId && (
381
+ <ChatToolbarOverflowMenu
382
+ hasUnread={hasUnread}
383
+ onToggleUnread={() => hasUnread ? clearForSession(sessionId) : markUnread(sessionId, projectName)}
384
+ onOpenDebug={() => setDebugOpen(true)}
385
+ />
386
+ )}
387
+ </div>
400
388
  </div>
401
389
 
390
+ {sessionId && (
391
+ <SessionDebugDialog
392
+ sessionId={sessionId}
393
+ projectName={projectName}
394
+ open={debugOpen}
395
+ onOpenChange={setDebugOpen}
396
+ />
397
+ )}
398
+
402
399
  {/* Panels — only one visible at a time */}
403
400
 
404
401
  {/* History panel */}
@@ -0,0 +1,57 @@
1
+ import { BellOff, Bug, Circle, MoreHorizontal } from "lucide-react";
2
+ import {
3
+ DropdownMenu,
4
+ DropdownMenuContent,
5
+ DropdownMenuItem,
6
+ DropdownMenuTrigger,
7
+ } from "@/components/ui/dropdown-menu";
8
+
9
+ /**
10
+ * Session actions that do not earn permanent space in the chat toolbar.
11
+ *
12
+ * The toolbar's left zone scrolls once the chat panel gets narrow, so every
13
+ * control pinned on the right competes for the handful of pixels that stay
14
+ * visible. Only the connection indicator earns that spot; infrequent actions
15
+ * live behind this trigger, which is also where future toolbar actions belong.
16
+ */
17
+ export function ChatToolbarOverflowMenu({
18
+ hasUnread,
19
+ onToggleUnread,
20
+ onOpenDebug,
21
+ }: {
22
+ hasUnread: boolean;
23
+ onToggleUnread: () => void;
24
+ onOpenDebug: () => void;
25
+ }) {
26
+ return (
27
+ <DropdownMenu>
28
+ <DropdownMenuTrigger asChild>
29
+ <button
30
+ type="button"
31
+ className="flex items-center justify-center size-5 rounded text-text-subtle hover:text-text-secondary hover:bg-surface-elevated transition-colors"
32
+ title="More actions"
33
+ aria-label="More actions"
34
+ >
35
+ <MoreHorizontal className="size-3.5" />
36
+ </button>
37
+ </DropdownMenuTrigger>
38
+ {/* Anchored above: this toolbar sits at the bottom of the chat pane. */}
39
+ <DropdownMenuContent align="end" side="top" className="min-w-[190px]">
40
+ <DropdownMenuItem onClick={onToggleUnread} className="max-md:py-3">
41
+ {hasUnread ? (
42
+ <>
43
+ <BellOff className="size-3.5 text-warning" /> Mark as read
44
+ </>
45
+ ) : (
46
+ <>
47
+ <Circle className="size-3.5 fill-current text-primary" /> Mark as unread
48
+ </>
49
+ )}
50
+ </DropdownMenuItem>
51
+ <DropdownMenuItem onClick={onOpenDebug} className="max-md:py-3">
52
+ <Bug className="size-3.5" /> Session debug info
53
+ </DropdownMenuItem>
54
+ </DropdownMenuContent>
55
+ </DropdownMenu>
56
+ );
57
+ }
@@ -308,15 +308,30 @@ function TurnUsageHistory({ sessionId, projectName }: { sessionId: string; proje
308
308
  );
309
309
  }
310
310
 
311
- /** Toolbar button opening the session's debug facts and transcript maintenance. */
312
- export function SessionDebugButton({ sessionId, projectName }: { sessionId: string; projectName: string }) {
313
- const [open, setOpen] = useState(false);
311
+ /**
312
+ * Session debug facts and transcript maintenance.
313
+ *
314
+ * Controlled by the caller so the trigger can live anywhere — including inside a
315
+ * dropdown menu, which unmounts its own items on select and would take an
316
+ * internally-owned dialog down with them.
317
+ */
318
+ export function SessionDebugDialog({
319
+ sessionId,
320
+ projectName,
321
+ open,
322
+ onOpenChange,
323
+ }: {
324
+ sessionId: string;
325
+ projectName: string;
326
+ open: boolean;
327
+ onOpenChange: (open: boolean) => void;
328
+ }) {
314
329
  const [info, setInfo] = useState<string | null>(null);
315
330
  const [copied, setCopied] = useState(false);
316
331
  const isMobile = useIsMobile();
317
332
 
318
- const openPopup = () => {
319
- setOpen(true);
333
+ useEffect(() => {
334
+ if (!open) return;
320
335
  setCopied(false);
321
336
  setInfo(null);
322
337
  api.get<DebugInfo>(
@@ -333,7 +348,7 @@ export function SessionDebugButton({ sessionId, projectName }: { sessionId: stri
333
348
  ...gatherRenderStats(),
334
349
  ].filter(Boolean).join("\n"));
335
350
  }).catch(() => setInfo("Failed to load debug info"));
336
- };
351
+ }, [open, sessionId, projectName]);
337
352
 
338
353
  const copy = () => {
339
354
  if (!info) return;
@@ -365,27 +380,20 @@ export function SessionDebugButton({ sessionId, projectName }: { sessionId: stri
365
380
  </div>
366
381
  );
367
382
 
383
+ if (isMobile) {
384
+ return (
385
+ <BottomSheet open={open} onClose={() => onOpenChange(false)} className="popover-solid">
386
+ <div className="max-h-[85vh] overflow-y-auto px-4 pb-4 pt-1">{body}</div>
387
+ </BottomSheet>
388
+ );
389
+ }
390
+
368
391
  return (
369
- <>
370
- <button
371
- onClick={openPopup}
372
- className="p-1 rounded text-text-subtle hover:text-text-secondary hover:bg-surface-elevated transition-colors"
373
- title="Session debug info"
374
- >
375
- <Bug className="size-3" />
376
- </button>
377
- {isMobile ? (
378
- <BottomSheet open={open} onClose={() => setOpen(false)} className="popover-solid">
379
- <div className="max-h-[85vh] overflow-y-auto px-4 pb-4 pt-1">{body}</div>
380
- </BottomSheet>
381
- ) : (
382
- <Dialog open={open} onOpenChange={setOpen}>
383
- <DialogContent className="sm:max-w-lg">
384
- <DialogTitle className="sr-only">Session debug info</DialogTitle>
385
- {body}
386
- </DialogContent>
387
- </Dialog>
388
- )}
389
- </>
392
+ <Dialog open={open} onOpenChange={onOpenChange}>
393
+ <DialogContent className="sm:max-w-lg">
394
+ <DialogTitle className="sr-only">Session debug info</DialogTitle>
395
+ {body}
396
+ </DialogContent>
397
+ </Dialog>
390
398
  );
391
399
  }
@@ -19,6 +19,7 @@ import { PortalContainerProvider } from "@/components/ui/portal-container-contex
19
19
  import { TITLEBAR_HEIGHT } from "./window-chrome-contract";
20
20
  import { useWindowBodyElement } from "./use-window-body-element";
21
21
  import { WindowPipPlaceholder } from "./window-pip-placeholder";
22
+ import { isPipOnlyWindow } from "./window-pip-registry";
22
23
  import { WindowSkinChrome } from "./window-skin-chrome";
23
24
  import { windowZIndex, type Bounds, type Rect } from "./window-geometry";
24
25
  import { useWindowStore, type WindowRuntimeState } from "./window-store";
@@ -120,6 +121,8 @@ export function FloatingWindow({
120
121
  movable: !maximized,
121
122
  });
122
123
 
124
+ const hiddenHost = Boolean(pip) && isPipOnlyWindow(win.id);
125
+
123
126
  return (
124
127
  <div
125
128
  ref={rootRef}
@@ -135,6 +138,10 @@ export function FloatingWindow({
135
138
  focused ? "shadow-2xl shadow-black/40" : "shadow-lg shadow-black/20",
136
139
  // Transitions are for maximize/restore only; during a gesture they would lag the pointer.
137
140
  gesturing ? "transition-none" : "transition-[transform,width,height] duration-150 motion-reduce:transition-none",
141
+ // A window opened only to carry a tab into PiP is never shown: the user asked for a
142
+ // PiP, not a window. `hidden` and not an unmount — the body must stay connected, or
143
+ // the PiP host has nowhere to put the tab back.
144
+ hiddenHost && "hidden",
138
145
  )}
139
146
  >
140
147
  <WindowSkinChrome
@@ -158,7 +165,7 @@ export function FloatingWindow({
158
165
  onClose={close}
159
166
  />
160
167
 
161
- {pip && <WindowPipPlaceholder pip={pip} minimized={minimized} />}
168
+ {pip && !hiddenHost && <WindowPipPlaceholder pip={pip} minimized={minimized} />}
162
169
 
163
170
  {!maximized && !minimized && (
164
171
  <WindowResizeHandles bind={(handle) => bindResize(handle) as Record<string, unknown>} />
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Send a tab straight into picture-in-picture, without the user ever seeing a window.
3
+ *
4
+ * A PiP window can only adopt an element that is already in the page, and it needs somewhere
5
+ * to put it back. The floating window is that element and that home — so one still opens
6
+ * here, it is simply never shown: the frame keeps a pip-only window off screen, and closing
7
+ * PiP closes it, which re-docks the tab into the panel it came from.
8
+ */
9
+
10
+ import { usePanelStore } from "@/stores/panel-store";
11
+ import { focusPipDocument } from "./pip/pip-focus-target";
12
+ import { attachPipHost } from "./pip/pip-host";
13
+ import { TITLEBAR_HEIGHT } from "./window-chrome-contract";
14
+ import {
15
+ clearPipOnlyWindow,
16
+ markPipOnlyWindow,
17
+ setWindowPip,
18
+ whenWindowSlot,
19
+ } from "./window-pip-registry";
20
+ import { useWindowStore } from "./window-store";
21
+
22
+ export type OpenTabInPipResult = "opened" | "window-cap" | "cancelled";
23
+
24
+ /** Drop the host window; its own teardown hands the tab back to the panel it came from. */
25
+ function discard(windowId: string): void {
26
+ clearPipOnlyWindow(windowId);
27
+ useWindowStore.getState().close(windowId);
28
+ }
29
+
30
+ /**
31
+ * Detach a tab into a hidden window and adopt it into a PiP window.
32
+ *
33
+ * Rejects when the browser refuses the request (no support, or the click's activation was
34
+ * already spent); the caller reports that. Call it from a click handler with nothing awaited
35
+ * before it — the one await inside is a React commit, which leaves the activation valid.
36
+ */
37
+ export async function openTabInPip(tabId: string, panelId: string): Promise<OpenTabInPipResult> {
38
+ const windowId = usePanelStore.getState().popOutTab(tabId, panelId);
39
+ if (!windowId) return "window-cap";
40
+ markPipOnlyWindow(windowId);
41
+
42
+ // The window exists in the store, but its body is created by the frame's layout effect —
43
+ // one commit away.
44
+ const slot = await whenWindowSlot(windowId);
45
+ if (!slot) {
46
+ discard(windowId);
47
+ return "cancelled";
48
+ }
49
+
50
+ const rect = useWindowStore.getState().windows[windowId]?.rect;
51
+ let handle;
52
+ try {
53
+ handle = await attachPipHost(slot, {
54
+ // A zero falls through to the host's minimum size rather than a magic default.
55
+ width: rect?.w ?? 0,
56
+ height: rect ? rect.h - TITLEBAR_HEIGHT : 0,
57
+ onDetach: () => {
58
+ setWindowPip(windowId, null);
59
+ // Closing PiP means "done with this tab out here", not "give me a window instead":
60
+ // the tab goes back to its strip.
61
+ discard(windowId);
62
+ },
63
+ });
64
+ } catch (err) {
65
+ discard(windowId);
66
+ throw err;
67
+ }
68
+
69
+ // Null means the window went away while the request was in flight; the host already
70
+ // restored what it had and called onDetach.
71
+ if (!handle) return "cancelled";
72
+
73
+ setWindowPip(windowId, handle);
74
+ // A DOM move carries no focus with it: without this the tab is visible in PiP but swallows
75
+ // nothing until the user clicks it.
76
+ focusPipDocument(handle.pipWindow.document);
77
+ return "opened";
78
+ }
@@ -24,6 +24,52 @@ const listeners = new Set<() => void>();
24
24
  export function publishWindowSlot(windowId: string, el: HTMLElement | null): void {
25
25
  if (el) slots.set(windowId, el);
26
26
  else slots.delete(windowId);
27
+ for (const notify of listeners) notify();
28
+ }
29
+
30
+ /**
31
+ * Resolve once a window has published its body, or `null` if it never does.
32
+ *
33
+ * A window opened to host a picture-in-picture request exists in the store before React has
34
+ * mounted its frame, so the element the PiP host needs does not exist yet in the click
35
+ * handler that created it. Waiting is safe: transient activation survives a commit, it is
36
+ * consuming it twice that the browser refuses.
37
+ */
38
+ export function whenWindowSlot(windowId: string, timeoutMs = 2000): Promise<HTMLElement | null> {
39
+ const existing = windowSlot(windowId);
40
+ if (existing) return Promise.resolve(existing);
41
+ return new Promise((resolve) => {
42
+ const settle = (el: HTMLElement | null) => {
43
+ listeners.delete(check);
44
+ clearTimeout(timer);
45
+ resolve(el);
46
+ };
47
+ const check = () => {
48
+ const el = windowSlot(windowId);
49
+ if (el) settle(el);
50
+ };
51
+ const timer = setTimeout(() => settle(null), timeoutMs);
52
+ listeners.add(check);
53
+ });
54
+ }
55
+
56
+ /**
57
+ * Windows that exist only to carry a tab into picture-in-picture: the frame keeps them off
58
+ * screen while PiP is up, and closing PiP closes the window, so the tab goes straight back
59
+ * to its tab strip instead of stranding an empty window the user never asked for.
60
+ */
61
+ const pipOnly = new Set<string>();
62
+
63
+ export function markPipOnlyWindow(windowId: string): void {
64
+ pipOnly.add(windowId);
65
+ }
66
+
67
+ export function isPipOnlyWindow(windowId: string): boolean {
68
+ return pipOnly.has(windowId);
69
+ }
70
+
71
+ export function clearPipOnlyWindow(windowId: string): void {
72
+ pipOnly.delete(windowId);
27
73
  }
28
74
 
29
75
  /** The body element of a mounted window, or null. */