@hienlh/ppm 0.23.6 → 0.23.7

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 (701) hide show
  1. package/CHANGELOG.md +84 -0
  2. package/CLAUDE.md +21 -1
  3. package/Dockerfile.test +8 -1
  4. package/assets/skills/ppm/SKILL.md +1 -1
  5. package/assets/skills/ppm/references/cli-reference.md +4 -4
  6. package/assets/skills/ppm/references/http-api.md +29 -1
  7. package/dist/web/assets/accounts-settings-section-BYWnY9hH.js +1 -0
  8. package/dist/web/assets/accounts-settings-section-BYWnY9hH.js.br +0 -0
  9. package/dist/web/assets/accounts-settings-section-BYWnY9hH.js.gz +0 -0
  10. package/dist/web/assets/{ai-resource-editor-Dn_wB-o5.js → ai-resource-editor-CY4n_Ccv.js} +1 -1
  11. package/dist/web/assets/ai-resource-editor-CY4n_Ccv.js.br +0 -0
  12. package/dist/web/assets/ai-resource-editor-CY4n_Ccv.js.gz +0 -0
  13. package/dist/web/assets/ai-settings-section-Bs3iUW4j.js +1 -0
  14. package/dist/web/assets/ai-settings-section-Bs3iUW4j.js.br +0 -0
  15. package/dist/web/assets/ai-settings-section-Bs3iUW4j.js.gz +0 -0
  16. package/dist/web/assets/ai-settings-section-DDs11XV4.js +1 -0
  17. package/dist/web/assets/api-client-CJPnCOG-.js +1 -0
  18. package/dist/web/assets/{api-client-c8YOpTlT.js → api-client-D-SMbdiH.js} +1 -1
  19. package/dist/web/assets/api-client-D-SMbdiH.js.br +0 -0
  20. package/dist/web/assets/api-client-D-SMbdiH.js.gz +0 -0
  21. package/dist/web/assets/api-settings-BDkkhFMq.js +1 -0
  22. package/dist/web/assets/{api-settings-BmvNoCbn.js → api-settings-Bv9mLCty.js} +1 -1
  23. package/dist/web/assets/api-settings-Bv9mLCty.js.br +0 -0
  24. package/dist/web/assets/api-settings-Bv9mLCty.js.gz +0 -0
  25. package/dist/web/assets/{api-themes-6fOQJgM9.js → api-themes-3wW-zLzU.js} +1 -1
  26. package/dist/web/assets/appearance-settings-section-C0BoIBmz.js +1 -0
  27. package/dist/web/assets/appearance-settings-section-C0BoIBmz.js.br +0 -0
  28. package/dist/web/assets/appearance-settings-section-C0BoIBmz.js.gz +0 -0
  29. package/dist/web/assets/apps-panel-DXAFsveZ.js +1 -0
  30. package/dist/web/assets/apps-panel-DXAFsveZ.js.br +0 -0
  31. package/dist/web/assets/apps-panel-DXAFsveZ.js.gz +0 -0
  32. package/dist/web/assets/{audio-preview-vaG2cB-k.js → audio-preview-BfES4Cx5.js} +1 -1
  33. package/dist/web/assets/audio-preview-BfES4Cx5.js.br +0 -0
  34. package/dist/web/assets/audio-preview-BfES4Cx5.js.gz +0 -0
  35. package/dist/web/assets/branch-review-tab-CA8hPSX9.js +1 -0
  36. package/dist/web/assets/branch-review-tab-CA8hPSX9.js.br +0 -0
  37. package/dist/web/assets/branch-review-tab-CA8hPSX9.js.gz +0 -0
  38. package/dist/web/assets/{button-Ci9EUgqd.js → button-DeAyLH9U.js} +1 -1
  39. package/dist/web/assets/button-DeAyLH9U.js.br +0 -0
  40. package/dist/web/assets/button-DeAyLH9U.js.gz +0 -0
  41. package/dist/web/assets/{chat-preparation-cache-BSIQGiWx.js → chat-preparation-cache-CcCd2g7A.js} +1 -1
  42. package/dist/web/assets/chat-preparation-cache-CcCd2g7A.js.br +0 -0
  43. package/dist/web/assets/chat-preparation-cache-CcCd2g7A.js.gz +0 -0
  44. package/dist/web/assets/chat-tab-BWi_bUzA.js +1 -0
  45. package/dist/web/assets/chat-tab-BWi_bUzA.js.br +0 -0
  46. package/dist/web/assets/chat-tab-BWi_bUzA.js.gz +0 -0
  47. package/dist/web/assets/chat-tab-BvJhIaVE.js +15 -0
  48. package/dist/web/assets/chat-tab-BvJhIaVE.js.br +0 -0
  49. package/dist/web/assets/chat-tab-BvJhIaVE.js.gz +0 -0
  50. package/dist/web/assets/code-editor-OJUdLVnn.js +7 -0
  51. package/dist/web/assets/code-editor-OJUdLVnn.js.br +0 -0
  52. package/dist/web/assets/code-editor-OJUdLVnn.js.gz +0 -0
  53. package/dist/web/assets/codex-reset-credit-button-Dgxy_VNp.js +1 -0
  54. package/dist/web/assets/codex-reset-credit-button-Dgxy_VNp.js.br +0 -0
  55. package/dist/web/assets/codex-reset-credit-button-Dgxy_VNp.js.gz +0 -0
  56. package/dist/web/assets/{conflict-editor-BA3y-qSH.js → conflict-editor-BpKW_vbL.js} +1 -1
  57. package/dist/web/assets/conflict-editor-BpKW_vbL.js.br +0 -0
  58. package/dist/web/assets/conflict-editor-BpKW_vbL.js.gz +0 -0
  59. package/dist/web/assets/context-menu-7OX80HDB.js +1 -0
  60. package/dist/web/assets/context-menu-7OX80HDB.js.br +0 -0
  61. package/dist/web/assets/context-menu-7OX80HDB.js.gz +0 -0
  62. package/dist/web/assets/{csv-preview-BioxkrQF.js → csv-preview-COYdTABa.js} +1 -1
  63. package/dist/web/assets/csv-preview-COYdTABa.js.br +0 -0
  64. package/dist/web/assets/csv-preview-COYdTABa.js.gz +0 -0
  65. package/dist/web/assets/{data-grid-overlay-editor-CQRVKr7y.js → data-grid-overlay-editor-CeZoduke.js} +1 -1
  66. package/dist/web/assets/data-grid-overlay-editor-CeZoduke.js.br +0 -0
  67. package/dist/web/assets/data-grid-overlay-editor-CeZoduke.js.gz +0 -0
  68. package/dist/web/assets/{database-viewer-BSoJ0E6p.js → database-viewer-BQcBqCKm.js} +1 -1
  69. package/dist/web/assets/database-viewer-BQcBqCKm.js.br +0 -0
  70. package/dist/web/assets/database-viewer-BQcBqCKm.js.gz +0 -0
  71. package/dist/web/assets/{design-export-client-ChMcMoqW.js → design-export-client-OrnGCSwu.js} +1 -1
  72. package/dist/web/assets/design-export-client-OrnGCSwu.js.br +0 -0
  73. package/dist/web/assets/design-export-client-OrnGCSwu.js.gz +0 -0
  74. package/dist/web/assets/{design-responsive-dialog-DNBhJJLf.js → design-responsive-dialog-vJjQrC4n.js} +1 -1
  75. package/dist/web/assets/design-responsive-dialog-vJjQrC4n.js.br +0 -0
  76. package/dist/web/assets/design-responsive-dialog-vJjQrC4n.js.gz +0 -0
  77. package/dist/web/assets/design-tab-BbmFk38H.js +33 -0
  78. package/dist/web/assets/design-tab-BbmFk38H.js.br +0 -0
  79. package/dist/web/assets/design-tab-BbmFk38H.js.gz +0 -0
  80. package/dist/web/assets/{designs-sidebar-panel-DHh5QsH9.js → designs-sidebar-panel-D2kXwB8B.js} +1 -1
  81. package/dist/web/assets/designs-sidebar-panel-D2kXwB8B.js.br +0 -0
  82. package/dist/web/assets/designs-sidebar-panel-D2kXwB8B.js.gz +0 -0
  83. package/dist/web/assets/dialog-Bocc0Fgb.js +1 -0
  84. package/dist/web/assets/dialog-Bocc0Fgb.js.br +0 -0
  85. package/dist/web/assets/dialog-Bocc0Fgb.js.gz +0 -0
  86. package/dist/web/assets/{diff-viewer-lctWoSmG.js → diff-viewer-Bj4DT6Mj.js} +1 -1
  87. package/dist/web/assets/diff-viewer-Bj4DT6Mj.js.br +0 -0
  88. package/dist/web/assets/diff-viewer-Bj4DT6Mj.js.gz +0 -0
  89. package/dist/web/assets/{docx-preview-C9XdKEj1.js → docx-preview-C2QqNGRE.js} +1 -1
  90. package/dist/web/assets/docx-preview-C2QqNGRE.js.br +0 -0
  91. package/dist/web/assets/docx-preview-C2QqNGRE.js.gz +0 -0
  92. package/dist/web/assets/editor-language-service-COqB2tuv.js +1 -0
  93. package/dist/web/assets/editor-language-service-COqB2tuv.js.br +3 -0
  94. package/dist/web/assets/editor-language-service-COqB2tuv.js.gz +0 -0
  95. package/dist/web/assets/explorer-body-DGrYajDN.js +2 -0
  96. package/dist/web/assets/explorer-body-DGrYajDN.js.br +0 -0
  97. package/dist/web/assets/explorer-body-DGrYajDN.js.gz +0 -0
  98. package/dist/web/assets/explorer-window-content-DLzkODTP.js +1 -0
  99. package/dist/web/assets/explorer-window-content-DLzkODTP.js.br +0 -0
  100. package/dist/web/assets/explorer-window-content-DLzkODTP.js.gz +0 -0
  101. package/dist/web/assets/{extension-manager-section-rbkXsZVR.js → extension-manager-section-Bu0qcB2i.js} +1 -1
  102. package/dist/web/assets/extension-manager-section-Bu0qcB2i.js.br +0 -0
  103. package/dist/web/assets/extension-manager-section-Bu0qcB2i.js.gz +0 -0
  104. package/dist/web/assets/{extension-webview-uPO0WgCq.js → extension-webview-G_WJ0N52.js} +1 -1
  105. package/dist/web/assets/extension-webview-G_WJ0N52.js.br +0 -0
  106. package/dist/web/assets/extension-webview-G_WJ0N52.js.gz +0 -0
  107. package/dist/web/assets/{file-icons-gx_FBOXY.js → file-icons-l7fNOmdS.js} +1 -1
  108. package/dist/web/assets/file-icons-l7fNOmdS.js.br +0 -0
  109. package/dist/web/assets/file-icons-l7fNOmdS.js.gz +0 -0
  110. package/dist/web/assets/{file-store-D9KE0kQC.js → file-store-B0e7sLag.js} +1 -1
  111. package/dist/web/assets/file-store-B0e7sLag.js.br +0 -0
  112. package/dist/web/assets/file-store-B0e7sLag.js.gz +0 -0
  113. package/dist/web/assets/{files-settings-section-CT7mDb0L.js → files-settings-section-ChZ_CynX.js} +1 -1
  114. package/dist/web/assets/files-settings-section-ChZ_CynX.js.br +0 -0
  115. package/dist/web/assets/files-settings-section-ChZ_CynX.js.gz +0 -0
  116. package/dist/web/assets/format-bytes-__396eCN.js +1 -0
  117. package/dist/web/assets/{format-file-meta-mQwA6SuY.js → format-file-meta-o1XBuoKS.js} +1 -1
  118. package/dist/web/assets/format-file-meta-o1XBuoKS.js.br +0 -0
  119. package/dist/web/assets/format-file-meta-o1XBuoKS.js.gz +0 -0
  120. package/dist/web/assets/{fs-api-DL36slbd.js → fs-api-CeHKwx95.js} +1 -1
  121. package/dist/web/assets/fs-api-CeHKwx95.js.br +0 -0
  122. package/dist/web/assets/fs-api-CeHKwx95.js.gz +0 -0
  123. package/dist/web/assets/{general-settings-section-DANPfMRN.js → general-settings-section-MSvDEbFa.js} +1 -1
  124. package/dist/web/assets/general-settings-section-MSvDEbFa.js.br +0 -0
  125. package/dist/web/assets/general-settings-section-MSvDEbFa.js.gz +0 -0
  126. package/dist/web/assets/{git-log-panel-BJPkLiEw.js → git-log-panel-gw5_a6j3.js} +1 -1
  127. package/dist/web/assets/git-log-panel-gw5_a6j3.js.br +0 -0
  128. package/dist/web/assets/git-log-panel-gw5_a6j3.js.gz +0 -0
  129. package/dist/web/assets/{git-repo-store-DSypNj19.js → git-repo-store-BpPnah5l.js} +1 -1
  130. package/dist/web/assets/git-repo-store-BpPnah5l.js.br +0 -0
  131. package/dist/web/assets/git-repo-store-BpPnah5l.js.gz +0 -0
  132. package/dist/web/assets/{glide-data-grid-R4PcAntf.js → glide-data-grid-Db2Cl26B.js} +5 -5
  133. package/dist/web/assets/glide-data-grid-Db2Cl26B.js.br +0 -0
  134. package/dist/web/assets/glide-data-grid-Db2Cl26B.js.gz +0 -0
  135. package/dist/web/assets/group-chat-tab-B4etmYTR.js +1 -0
  136. package/dist/web/assets/group-chat-tab-B4etmYTR.js.br +0 -0
  137. package/dist/web/assets/group-chat-tab-B4etmYTR.js.gz +0 -0
  138. package/dist/web/assets/{image-preview-CGdZrmLo.js → image-preview-CjNhpfWw.js} +1 -1
  139. package/dist/web/assets/index-CtAvmybi.js +52 -0
  140. package/dist/web/assets/index-CtAvmybi.js.br +0 -0
  141. package/dist/web/assets/index-CtAvmybi.js.gz +0 -0
  142. package/dist/web/assets/index-DeCJasyy.css +1 -0
  143. package/dist/web/assets/index-DeCJasyy.css.br +0 -0
  144. package/dist/web/assets/index-DeCJasyy.css.gz +0 -0
  145. package/dist/web/assets/{jira-watcher-section-DHRoyWcG.js → jira-watcher-section-CKSI1Alo.js} +1 -1
  146. package/dist/web/assets/keybindings-store-C4_yyU4u.js +1 -0
  147. package/dist/web/assets/{keyboard-shortcuts-section-BKej4mUf.js → keyboard-shortcuts-section-CEaVUc9a.js} +1 -1
  148. package/dist/web/assets/keyboard-shortcuts-section-CEaVUc9a.js.br +0 -0
  149. package/dist/web/assets/keyboard-shortcuts-section-CEaVUc9a.js.gz +0 -0
  150. package/dist/web/assets/language-servers-section-ePtEpnDc.js +2 -0
  151. package/dist/web/assets/language-servers-section-ePtEpnDc.js.br +0 -0
  152. package/dist/web/assets/language-servers-section-ePtEpnDc.js.gz +0 -0
  153. package/dist/web/assets/lsp-client-XzmR3Brr.js +1 -0
  154. package/dist/web/assets/lsp-client-XzmR3Brr.js.br +0 -0
  155. package/dist/web/assets/lsp-client-XzmR3Brr.js.gz +0 -0
  156. package/dist/web/assets/markdown-renderer-CTtDap-l.js +1 -0
  157. package/dist/web/assets/{markdown-renderer-BHtYqkYZ.js → markdown-renderer-D05fAr57.js} +2 -2
  158. package/dist/web/assets/markdown-renderer-D05fAr57.js.br +0 -0
  159. package/dist/web/assets/markdown-renderer-D05fAr57.js.gz +0 -0
  160. package/dist/web/assets/{media-url-CzUJrREv.js → media-url-C6NumuN5.js} +1 -1
  161. package/dist/web/assets/metric-chart-canvas-DHJe0VER.js +1 -0
  162. package/dist/web/assets/metric-chart-canvas-DHJe0VER.js.br +0 -0
  163. package/dist/web/assets/metric-chart-canvas-DHJe0VER.js.gz +0 -0
  164. package/dist/web/assets/{mobile-bottom-sheet-CuNi2FRv.js → mobile-bottom-sheet-D4UyOatB.js} +1 -1
  165. package/dist/web/assets/mobile-bottom-sheet-D4UyOatB.js.br +0 -0
  166. package/dist/web/assets/mobile-bottom-sheet-D4UyOatB.js.gz +0 -0
  167. package/dist/web/assets/mobile-explorer-sheet-CcfGdGL8.js +1 -0
  168. package/dist/web/assets/mobile-explorer-sheet-CcfGdGL8.js.br +0 -0
  169. package/dist/web/assets/mobile-explorer-sheet-CcfGdGL8.js.gz +0 -0
  170. package/dist/web/assets/{new-design-dialog-DS_XrpTG.js → new-design-dialog-BgmQopJM.js} +1 -1
  171. package/dist/web/assets/new-design-dialog-BgmQopJM.js.br +0 -0
  172. package/dist/web/assets/new-design-dialog-BgmQopJM.js.gz +0 -0
  173. package/dist/web/assets/notification-store-q5QBklKA.js +1 -0
  174. package/dist/web/assets/{notifications-settings-section-C05WYqcE.js → notifications-settings-section-BBJ0r9OS.js} +1 -1
  175. package/dist/web/assets/notifications-settings-section-BBJ0r9OS.js.br +0 -0
  176. package/dist/web/assets/notifications-settings-section-BBJ0r9OS.js.gz +0 -0
  177. package/dist/web/assets/{onboarding-entry-CmUqv1kl.js → onboarding-entry-BYOYswsi.js} +1 -1
  178. package/dist/web/assets/onboarding-entry-BYOYswsi.js.br +0 -0
  179. package/dist/web/assets/onboarding-entry-BYOYswsi.js.gz +0 -0
  180. package/dist/web/assets/{onboarding-quick-orientation-DIhWv1CN.js → onboarding-quick-orientation-DPHYFMbA.js} +1 -1
  181. package/dist/web/assets/onboarding-quick-orientation-DPHYFMbA.js.br +0 -0
  182. package/dist/web/assets/onboarding-quick-orientation-DPHYFMbA.js.gz +0 -0
  183. package/dist/web/assets/overview-panel-pkPs44Tv.js +1 -0
  184. package/dist/web/assets/overview-panel-pkPs44Tv.js.br +0 -0
  185. package/dist/web/assets/overview-panel-pkPs44Tv.js.gz +0 -0
  186. package/dist/web/assets/{pdf-preview-qdXmMkOR.js → pdf-preview-c-L_kDAs.js} +1 -1
  187. package/dist/web/assets/pdf-preview-c-L_kDAs.js.br +0 -0
  188. package/dist/web/assets/pdf-preview-c-L_kDAs.js.gz +0 -0
  189. package/dist/web/assets/performance-panel-yPrq0DJV.js +3 -0
  190. package/dist/web/assets/performance-panel-yPrq0DJV.js.br +0 -0
  191. package/dist/web/assets/performance-panel-yPrq0DJV.js.gz +0 -0
  192. package/dist/web/assets/{postgres-viewer-Xvlun_n5.js → postgres-viewer-CnwDCMNd.js} +1 -1
  193. package/dist/web/assets/postgres-viewer-CnwDCMNd.js.br +0 -0
  194. package/dist/web/assets/postgres-viewer-CnwDCMNd.js.gz +0 -0
  195. package/dist/web/assets/{ppmbot-settings-section-D8AES1BA.js → ppmbot-settings-section-BDXoSIDp.js} +1 -1
  196. package/dist/web/assets/ppmbot-settings-section-BDXoSIDp.js.br +0 -0
  197. package/dist/web/assets/ppmbot-settings-section-BDXoSIDp.js.gz +0 -0
  198. package/dist/web/assets/{pptx-export-CG6MRNok.js → pptx-export-D0RDY48h.js} +4 -4
  199. package/dist/web/assets/pptx-export-D0RDY48h.js.br +0 -0
  200. package/dist/web/assets/pptx-export-D0RDY48h.js.gz +0 -0
  201. package/dist/web/assets/{problems-panel-DTBG4beI.js → problems-panel-BgY8oyo9.js} +1 -1
  202. package/dist/web/assets/problems-panel-BgY8oyo9.js.br +0 -0
  203. package/dist/web/assets/problems-panel-BgY8oyo9.js.gz +0 -0
  204. package/dist/web/assets/process-row-format-CaaMcHzn.js +1 -0
  205. package/dist/web/assets/process-table-BOwDtXuG.js +1 -0
  206. package/dist/web/assets/process-table-BOwDtXuG.js.br +0 -0
  207. package/dist/web/assets/process-table-BOwDtXuG.js.gz +0 -0
  208. package/dist/web/assets/{project-framework-store-XxFXcUpb.js → project-framework-store-UDEMu28U.js} +1 -1
  209. package/dist/web/assets/{project-store-C5gJXkvb.js → project-store-DGa31y5B.js} +1 -1
  210. package/dist/web/assets/project-store-DGa31y5B.js.br +0 -0
  211. package/dist/web/assets/project-store-DGa31y5B.js.gz +0 -0
  212. package/dist/web/assets/{proxy-settings-section-CqtmbeRj.js → proxy-settings-section-Db6Kc6xG.js} +1 -1
  213. package/dist/web/assets/proxy-settings-section-Db6Kc6xG.js.br +0 -0
  214. package/dist/web/assets/proxy-settings-section-Db6Kc6xG.js.gz +0 -0
  215. package/dist/web/assets/{query-audit-section-UKG_smyt.js → query-audit-section-C0PAXhfT.js} +1 -1
  216. package/dist/web/assets/query-audit-section-C0PAXhfT.js.br +0 -0
  217. package/dist/web/assets/query-audit-section-C0PAXhfT.js.gz +0 -0
  218. package/dist/web/assets/{remote-desktop-clipboard-notice-Djt6cpNL.js → remote-desktop-clipboard-notice-DOVtobj_.js} +1 -1
  219. package/dist/web/assets/remote-desktop-clipboard-notice-DOVtobj_.js.br +0 -0
  220. package/dist/web/assets/remote-desktop-clipboard-notice-DOVtobj_.js.gz +0 -0
  221. package/dist/web/assets/remote-desktop-mobile-sheet-DXlU3msM.js +2 -0
  222. package/dist/web/assets/remote-desktop-mobile-sheet-DXlU3msM.js.br +0 -0
  223. package/dist/web/assets/remote-desktop-mobile-sheet-DXlU3msM.js.gz +0 -0
  224. package/dist/web/assets/remote-desktop-mobile-view-ClV4YTLU.js +1 -0
  225. package/dist/web/assets/remote-desktop-mobile-view-ClV4YTLU.js.br +0 -0
  226. package/dist/web/assets/remote-desktop-mobile-view-ClV4YTLU.js.gz +0 -0
  227. package/dist/web/assets/{remote-desktop-readiness-gate-DNJF8TcF.js → remote-desktop-readiness-gate-BsfoJzdc.js} +1 -1
  228. package/dist/web/assets/remote-desktop-readiness-gate-BsfoJzdc.js.br +0 -0
  229. package/dist/web/assets/remote-desktop-readiness-gate-BsfoJzdc.js.gz +0 -0
  230. package/dist/web/assets/remote-desktop-window-content-kDaXl1_Q.js +1 -0
  231. package/dist/web/assets/remote-desktop-window-content-kDaXl1_Q.js.br +0 -0
  232. package/dist/web/assets/remote-desktop-window-content-kDaXl1_Q.js.gz +0 -0
  233. package/dist/web/assets/{schedules-settings-section-BKoPovy2.js → schedules-settings-section-CvbjQM8z.js} +1 -1
  234. package/dist/web/assets/schedules-settings-section-CvbjQM8z.js.br +0 -0
  235. package/dist/web/assets/schedules-settings-section-CvbjQM8z.js.gz +0 -0
  236. package/dist/web/assets/{scroll-area-XonvWYn_.js → scroll-area-sjOeAfoD.js} +1 -1
  237. package/dist/web/assets/scroll-area-sjOeAfoD.js.br +0 -0
  238. package/dist/web/assets/scroll-area-sjOeAfoD.js.gz +0 -0
  239. package/dist/web/assets/{separator-sQj04Ari.js → separator-9A3PCG1t.js} +1 -1
  240. package/dist/web/assets/services-panel-CimW47P8.js +1 -0
  241. package/dist/web/assets/services-panel-CimW47P8.js.br +0 -0
  242. package/dist/web/assets/services-panel-CimW47P8.js.gz +0 -0
  243. package/dist/web/assets/settings-body-BTXNtpWL.js +2 -0
  244. package/dist/web/assets/settings-body-BTXNtpWL.js.br +0 -0
  245. package/dist/web/assets/settings-body-BTXNtpWL.js.gz +0 -0
  246. package/dist/web/assets/settings-store-DvftLqzy.js +2 -0
  247. package/dist/web/assets/settings-store-DvftLqzy.js.br +0 -0
  248. package/dist/web/assets/settings-store-DvftLqzy.js.gz +0 -0
  249. package/dist/web/assets/settings-tab-CGhaRXjs.js +1 -0
  250. package/dist/web/assets/settings-window-content--Uyg_Psr.js +1 -0
  251. package/dist/web/assets/sortable-header-DUW9T1Hz.js +1 -0
  252. package/dist/web/assets/sortable-header-DUW9T1Hz.js.br +0 -0
  253. package/dist/web/assets/sortable-header-DUW9T1Hz.js.gz +0 -0
  254. package/dist/web/assets/{sql-query-editor-BjIMi9Wk.js → sql-query-editor-Dn-cgDrW.js} +1 -1
  255. package/dist/web/assets/sql-query-editor-Dn-cgDrW.js.br +0 -0
  256. package/dist/web/assets/sql-query-editor-Dn-cgDrW.js.gz +0 -0
  257. package/dist/web/assets/{sqlite-viewer-BNcA6Irq.js → sqlite-viewer-B0NfaMjq.js} +1 -1
  258. package/dist/web/assets/sqlite-viewer-B0NfaMjq.js.br +0 -0
  259. package/dist/web/assets/sqlite-viewer-B0NfaMjq.js.gz +0 -0
  260. package/dist/web/assets/system-monitor-body-CxCfRQFb.js +2 -0
  261. package/dist/web/assets/system-monitor-body-CxCfRQFb.js.br +0 -0
  262. package/dist/web/assets/system-monitor-body-CxCfRQFb.js.gz +0 -0
  263. package/dist/web/assets/system-monitor-tab-Cb3EZUdp.js +1 -0
  264. package/dist/web/assets/system-monitor-window-content-51CA-2PH.js +1 -0
  265. package/dist/web/assets/{tab-host-window-content-CIRGNCvi.js → tab-host-window-content-CSrcmKNG.js} +1 -1
  266. package/dist/web/assets/tab-host-window-content-CSrcmKNG.js.br +0 -0
  267. package/dist/web/assets/tab-host-window-content-CSrcmKNG.js.gz +0 -0
  268. package/dist/web/assets/{team-member-sheet-CwXpLi3X.js → team-member-sheet-D4X6nh-x.js} +2 -2
  269. package/dist/web/assets/team-member-sheet-D4X6nh-x.js.br +0 -0
  270. package/dist/web/assets/team-member-sheet-D4X6nh-x.js.gz +0 -0
  271. package/dist/web/assets/{team-member-window-content-4swiiDz7.js → team-member-window-content-BxkbGVIL.js} +1 -1
  272. package/dist/web/assets/team-member-window-content-BxkbGVIL.js.br +0 -0
  273. package/dist/web/assets/team-member-window-content-BxkbGVIL.js.gz +0 -0
  274. package/dist/web/assets/{terminal-tab-BGcdtMMT.js → terminal-tab-BYo34IqU.js} +3 -3
  275. package/dist/web/assets/terminal-tab-BYo34IqU.js.br +0 -0
  276. package/dist/web/assets/terminal-tab-BYo34IqU.js.gz +0 -0
  277. package/dist/web/assets/{tool-cards-D0-krtA2.js → tool-cards-DvXjOped.js} +4 -4
  278. package/dist/web/assets/tool-cards-DvXjOped.js.br +0 -0
  279. package/dist/web/assets/tool-cards-DvXjOped.js.gz +0 -0
  280. package/dist/web/assets/{use-blob-url-CmavyEP8.js → use-blob-url-CISBWKG5.js} +1 -1
  281. package/dist/web/assets/use-inline-blame-Br6mheS4.js +16 -0
  282. package/dist/web/assets/use-inline-blame-Br6mheS4.js.br +0 -0
  283. package/dist/web/assets/use-inline-blame-Br6mheS4.js.gz +0 -0
  284. package/dist/web/assets/use-lsp-BpJmvQ0n.js +6 -0
  285. package/dist/web/assets/use-lsp-BpJmvQ0n.js.br +0 -0
  286. package/dist/web/assets/use-lsp-BpJmvQ0n.js.gz +0 -0
  287. package/dist/web/assets/{use-monaco-theme-C88KphGx.js → use-monaco-theme-UGOzyIhv.js} +1 -1
  288. package/dist/web/assets/use-process-kill-CyiiUD1E.js +1 -0
  289. package/dist/web/assets/use-process-kill-CyiiUD1E.js.br +0 -0
  290. package/dist/web/assets/use-process-kill-CyiiUD1E.js.gz +0 -0
  291. package/dist/web/assets/{use-websocket-Chk9guIU.js → use-websocket-Dpl21cHG.js} +1 -1
  292. package/dist/web/assets/{vendor-ui-BHh12_0v.js → vendor-ui-P9Ym7hCv.js} +1 -1
  293. package/dist/web/assets/vendor-ui-P9Ym7hCv.js.br +0 -0
  294. package/dist/web/assets/vendor-ui-P9Ym7hCv.js.gz +0 -0
  295. package/dist/web/assets/video-preview-D6Jw-IZK.js +1 -0
  296. package/dist/web/assets/video-preview-D6Jw-IZK.js.br +0 -0
  297. package/dist/web/assets/video-preview-D6Jw-IZK.js.gz +0 -0
  298. package/dist/web/assets/voice-settings-section-CcHQDYzN.js +1 -0
  299. package/dist/web/assets/voice-settings-section-CcHQDYzN.js.br +0 -0
  300. package/dist/web/assets/voice-settings-section-CcHQDYzN.js.gz +0 -0
  301. package/dist/web/assets/ws-auth-CqI8-aoA.js +1 -0
  302. package/dist/web/index.html +20 -20
  303. package/dist/web/index.html.br +0 -0
  304. package/dist/web/index.html.gz +0 -0
  305. package/dist/web/sw.js +1 -1
  306. package/dist/web/sw.js.br +0 -0
  307. package/dist/web/sw.js.gz +0 -0
  308. package/docs/deployment-guide.md +23 -0
  309. package/package.json +1 -1
  310. package/release-from-worktree.sh +224 -0
  311. package/src/cli/commands/config-cmd.ts +12 -0
  312. package/src/providers/claude-agent-sdk.ts +65 -2
  313. package/src/providers/codex-app-server/codex-jsonrpc-client.ts +16 -1
  314. package/src/providers/codex-app-server/codex-provider.ts +39 -7
  315. package/src/providers/provider-probe.ts +63 -0
  316. package/src/providers/registry.ts +109 -29
  317. package/src/server/index.ts +9 -0
  318. package/src/server/middleware/auth.ts +5 -1
  319. package/src/server/routes/cross-origin-guard.ts +20 -0
  320. package/src/server/routes/git.ts +40 -4
  321. package/src/server/routes/lsp.ts +97 -4
  322. package/src/server/routes/resources.ts +72 -9
  323. package/src/server/routes/settings.ts +19 -1
  324. package/src/server/routes/speech.ts +66 -0
  325. package/src/server/routes/system-services.ts +76 -0
  326. package/src/server/routes/tunnel.ts +33 -1
  327. package/src/server/ws/chat.ts +74 -3
  328. package/src/services/codex-account-login.ts +26 -2
  329. package/src/services/codex-reset-credit.service.ts +16 -3
  330. package/src/services/compaction-savings.ts +127 -0
  331. package/src/services/db.service.ts +123 -8
  332. package/src/services/fs-ops/fs-ops-trash.service.ts +22 -9
  333. package/src/services/git-refs/for-each-ref.ts +118 -0
  334. package/src/services/git.service.ts +25 -2
  335. package/src/services/host-info/spawn-runner.ts +48 -4
  336. package/src/services/jsonl-transcript-parser.ts +7 -42
  337. package/src/services/lsp/lsp-install.ts +289 -0
  338. package/src/services/lsp/lsp-manager.ts +160 -29
  339. package/src/services/lsp/server-registry.ts +120 -4
  340. package/src/services/named-tunnel/named-tunnel-config.ts +8 -2
  341. package/src/services/named-tunnel/named-tunnel-setup.service.ts +4 -0
  342. package/src/services/read-lines.ts +54 -0
  343. package/src/services/speech-to-text/whisper-catalog.ts +142 -0
  344. package/src/services/speech-to-text/whisper-download.ts +113 -0
  345. package/src/services/speech-to-text/whisper-hallucinations.ts +51 -0
  346. package/src/services/speech-to-text/whisper-install.service.ts +247 -0
  347. package/src/services/speech-to-text/whisper-paths.ts +62 -0
  348. package/src/services/speech-to-text/whisper-transcribe.service.ts +117 -0
  349. package/src/services/supervisor.ts +94 -11
  350. package/src/services/system-metrics/cpu-details-linux.ts +252 -0
  351. package/src/services/system-metrics/cpu-memory-collector.ts +140 -18
  352. package/src/services/system-metrics/device-collector-linux.ts +31 -0
  353. package/src/services/system-metrics/device-collector-types.ts +40 -0
  354. package/src/services/system-metrics/disk-devices-linux.ts +156 -0
  355. package/src/services/system-metrics/disk-inventory-linux.ts +150 -0
  356. package/src/services/system-metrics/fans-linux.ts +51 -0
  357. package/src/services/system-metrics/gpu-api-versions.ts +120 -0
  358. package/src/services/system-metrics/gpu-devices-linux.ts +370 -0
  359. package/src/services/system-metrics/gpu-fdinfo-linux.ts +253 -0
  360. package/src/services/system-metrics/hardware-inventory.ts +50 -0
  361. package/src/services/system-metrics/linux-fs.ts +43 -0
  362. package/src/services/system-metrics/memory-darwin.ts +91 -0
  363. package/src/services/system-metrics/memory-linux.ts +156 -0
  364. package/src/services/system-metrics/net-devices-linux.ts +114 -0
  365. package/src/services/system-metrics/net-inventory-linux.ts +100 -0
  366. package/src/services/system-metrics/partitions-linux.ts +158 -0
  367. package/src/services/system-metrics/process-collector-linux.ts +58 -6
  368. package/src/services/system-metrics/process-collector-types.ts +8 -1
  369. package/src/services/system-metrics/process-details-darwin.ts +166 -0
  370. package/src/services/system-metrics/process-details-linux.ts +150 -0
  371. package/src/services/system-metrics/process-grouping.ts +2 -1
  372. package/src/services/system-metrics/process-rows-builder.ts +2 -0
  373. package/src/services/system-metrics/process-swap-linux.ts +37 -0
  374. package/src/services/system-metrics/signal-executor.ts +84 -0
  375. package/src/services/system-metrics/signal-request-handler.ts +92 -0
  376. package/src/services/system-metrics/system-metrics-platform.ts +30 -4
  377. package/src/services/system-metrics/system-metrics-tick.ts +73 -4
  378. package/src/services/system-metrics/system-metrics.service.ts +87 -2
  379. package/src/services/system-metrics/udev-db.ts +40 -0
  380. package/src/services/system-services/app-cgroup-linux.ts +115 -0
  381. package/src/services/system-services/app-icon-service.ts +31 -0
  382. package/src/services/system-services/app-icons-linux.ts +124 -0
  383. package/src/services/system-services/apps-linux.ts +174 -0
  384. package/src/services/system-services/desktop-entry.ts +103 -0
  385. package/src/services/system-services/service-guard.ts +124 -0
  386. package/src/services/system-services/systemd-collector.ts +203 -0
  387. package/src/services/system-services/systemd-parse.ts +162 -0
  388. package/src/shared/prompt-cache-idle.ts +197 -0
  389. package/src/shared/turn-usage.ts +85 -1
  390. package/src/types/chat.ts +27 -0
  391. package/src/types/config.ts +14 -0
  392. package/src/types/git.ts +41 -0
  393. package/src/types/system-hardware.ts +137 -0
  394. package/src/types/system-metrics.ts +231 -2
  395. package/src/types/system-services.ts +73 -0
  396. package/src/web/components/branch-review/branch-review-tab.tsx +20 -20
  397. package/src/web/components/branch-review/branch-review-tree-row.tsx +1 -13
  398. package/src/web/components/chat/chat-tab.tsx +3 -0
  399. package/src/web/components/chat/compaction-divider.tsx +48 -0
  400. package/src/web/components/chat/idle-cache-notice.tsx +67 -0
  401. package/src/web/components/chat/message-input.tsx +48 -13
  402. package/src/web/components/chat/message-list.tsx +15 -0
  403. package/src/web/components/chat/prompt-cache-chip.tsx +74 -0
  404. package/src/web/components/editor/code-editor.tsx +1 -0
  405. package/src/web/components/editor/editor-language-service.tsx +11 -3
  406. package/src/web/components/editor/lsp-status.tsx +115 -13
  407. package/src/web/components/git/branch-picker.tsx +419 -0
  408. package/src/web/components/git/branch-select.tsx +34 -0
  409. package/src/web/components/git/create-worktree-dialog.tsx +17 -16
  410. package/src/web/components/git/git-repo-picker.tsx +28 -40
  411. package/src/web/components/layout/status-bar.tsx +42 -19
  412. package/src/web/components/settings/accounts/account-card.tsx +5 -1
  413. package/src/web/components/settings/ai-settings-section.tsx +67 -3
  414. package/src/web/components/settings/appearance-settings-section.tsx +2 -28
  415. package/src/web/components/settings/language-servers-section.tsx +362 -0
  416. package/src/web/components/settings/settings-categories.ts +8 -3
  417. package/src/web/components/settings/settings-section-content.tsx +2 -0
  418. package/src/web/components/settings/voice-settings-section.tsx +283 -0
  419. package/src/web/components/system/apps/app-row.tsx +110 -0
  420. package/src/web/components/system/apps/app-rows.ts +140 -0
  421. package/src/web/components/system/apps/apps-panel.tsx +129 -0
  422. package/src/web/components/system/metric-chart-canvas.tsx +79 -3
  423. package/src/web/components/system/overview-cards/card-shell.tsx +54 -0
  424. package/src/web/components/system/overview-cards/cpu-card.tsx +11 -6
  425. package/src/web/components/system/overview-cards/disk-card.tsx +11 -6
  426. package/src/web/components/system/overview-cards/gpu-card.tsx +16 -6
  427. package/src/web/components/system/overview-cards/mem-card.tsx +11 -6
  428. package/src/web/components/system/overview-cards/net-card.tsx +11 -6
  429. package/src/web/components/system/overview-device-target.ts +69 -0
  430. package/src/web/components/system/overview-panel.tsx +15 -1
  431. package/src/web/components/system/performance/cpu-core-grid.tsx +74 -0
  432. package/src/web/components/system/performance/cpu-detail.tsx +220 -0
  433. package/src/web/components/system/performance/detail-parts.tsx +149 -0
  434. package/src/web/components/system/performance/device-list.ts +139 -0
  435. package/src/web/components/system/performance/disk-detail.tsx +64 -0
  436. package/src/web/components/system/performance/fans-detail.tsx +35 -0
  437. package/src/web/components/system/performance/gpu-detail.tsx +116 -0
  438. package/src/web/components/system/performance/memory-detail.tsx +109 -0
  439. package/src/web/components/system/performance/nic-detail.tsx +55 -0
  440. package/src/web/components/system/performance/partition-list.tsx +79 -0
  441. package/src/web/components/system/performance/performance-panel.tsx +206 -0
  442. package/src/web/components/system/performance/use-hardware-inventory.ts +48 -0
  443. package/src/web/components/system/process-columns-grid.ts +5 -3
  444. package/src/web/components/system/process-details-dialog.tsx +116 -0
  445. package/src/web/components/system/process-group-row.tsx +6 -1
  446. package/src/web/components/system/process-row-format.ts +6 -0
  447. package/src/web/components/system/process-row-menu.tsx +72 -0
  448. package/src/web/components/system/process-row.tsx +7 -1
  449. package/src/web/components/system/process-table-model.ts +1 -1
  450. package/src/web/components/system/process-table-sort.ts +8 -4
  451. package/src/web/components/system/process-table-toolbar.tsx +10 -2
  452. package/src/web/components/system/process-table-totals.ts +3 -0
  453. package/src/web/components/system/process-table.tsx +25 -2
  454. package/src/web/components/system/services/service-action-confirm.tsx +100 -0
  455. package/src/web/components/system/services/service-columns.ts +103 -0
  456. package/src/web/components/system/services/service-details-sheet.tsx +97 -0
  457. package/src/web/components/system/services/service-resources.ts +105 -0
  458. package/src/web/components/system/services/service-row.tsx +146 -0
  459. package/src/web/components/system/services/service-rows.ts +92 -0
  460. package/src/web/components/system/services/service-sort.ts +90 -0
  461. package/src/web/components/system/services/services-header.tsx +51 -0
  462. package/src/web/components/system/services/services-panel.tsx +207 -0
  463. package/src/web/components/system/services/use-services.ts +92 -0
  464. package/src/web/components/system/sortable-header.tsx +13 -8
  465. package/src/web/components/system/sysmon-preferences.tsx +85 -0
  466. package/src/web/components/system/system-monitor-body.tsx +101 -43
  467. package/src/web/components/system/system-monitor-window-content.tsx +2 -3
  468. package/src/web/components/system/use-process-signal.ts +87 -0
  469. package/src/web/components/tunnels/public-tunnel-switch.tsx +82 -0
  470. package/src/web/components/tunnels/tunnel-manager-tab.tsx +4 -0
  471. package/src/web/components/ui/dialog.tsx +14 -1
  472. package/src/web/components/ui/search-select.tsx +279 -0
  473. package/src/web/components/ui/start-ellipsis.tsx +18 -0
  474. package/src/web/hooks/use-chat.ts +28 -0
  475. package/src/web/hooks/use-global-keybindings.ts +7 -5
  476. package/src/web/hooks/use-lsp.ts +23 -2
  477. package/src/web/hooks/use-minute-clock.ts +20 -0
  478. package/src/web/hooks/use-whisper-voice-input.ts +113 -0
  479. package/src/web/lib/api-tunnels.ts +19 -0
  480. package/src/web/lib/branch-select-items.ts +29 -0
  481. package/src/web/lib/cpu-graph-mode.ts +90 -0
  482. package/src/web/lib/format-bytes.ts +14 -0
  483. package/src/web/lib/git-ref-picker.ts +120 -0
  484. package/src/web/lib/lsp/lsp-client.ts +32 -0
  485. package/src/web/lib/search-select-rows.ts +55 -0
  486. package/src/web/lib/temperature.ts +27 -0
  487. package/src/web/lib/voice-wav.ts +69 -0
  488. package/src/web/stores/git-status-store.ts +31 -17
  489. package/src/web/stores/keybindings-store.ts +14 -1
  490. package/src/web/stores/settings-store.ts +65 -0
  491. package/src/web/styles/globals.css +11 -0
  492. package/dist/web/assets/accounts-settings-section-DUVO32SQ.js +0 -1
  493. package/dist/web/assets/accounts-settings-section-DUVO32SQ.js.br +0 -0
  494. package/dist/web/assets/accounts-settings-section-DUVO32SQ.js.gz +0 -0
  495. package/dist/web/assets/ai-resource-editor-Dn_wB-o5.js.br +0 -0
  496. package/dist/web/assets/ai-resource-editor-Dn_wB-o5.js.gz +0 -0
  497. package/dist/web/assets/ai-settings-section-CEbW8jRy.js +0 -1
  498. package/dist/web/assets/ai-settings-section-CEbW8jRy.js.br +0 -0
  499. package/dist/web/assets/ai-settings-section-CEbW8jRy.js.gz +0 -0
  500. package/dist/web/assets/ai-settings-section-D-mwEYFZ.js +0 -1
  501. package/dist/web/assets/api-client-BgedDTvo.js +0 -1
  502. package/dist/web/assets/api-client-c8YOpTlT.js.br +0 -0
  503. package/dist/web/assets/api-client-c8YOpTlT.js.gz +0 -0
  504. package/dist/web/assets/api-settings-BmvNoCbn.js.br +0 -0
  505. package/dist/web/assets/api-settings-BmvNoCbn.js.gz +0 -0
  506. package/dist/web/assets/api-settings-Bti1-Zn3.js +0 -1
  507. package/dist/web/assets/appearance-settings-section-tw6TpFb6.js +0 -1
  508. package/dist/web/assets/appearance-settings-section-tw6TpFb6.js.br +0 -0
  509. package/dist/web/assets/appearance-settings-section-tw6TpFb6.js.gz +0 -0
  510. package/dist/web/assets/audio-preview-vaG2cB-k.js.br +0 -0
  511. package/dist/web/assets/audio-preview-vaG2cB-k.js.gz +0 -0
  512. package/dist/web/assets/branch-review-tab-MBuMWp_i.js +0 -1
  513. package/dist/web/assets/branch-review-tab-MBuMWp_i.js.br +0 -0
  514. package/dist/web/assets/branch-review-tab-MBuMWp_i.js.gz +0 -0
  515. package/dist/web/assets/button-Ci9EUgqd.js.br +0 -0
  516. package/dist/web/assets/button-Ci9EUgqd.js.gz +0 -0
  517. package/dist/web/assets/chat-preparation-cache-BSIQGiWx.js.br +0 -0
  518. package/dist/web/assets/chat-preparation-cache-BSIQGiWx.js.gz +0 -0
  519. package/dist/web/assets/chat-tab-DVvnqhw6.js +0 -1
  520. package/dist/web/assets/chat-tab-DVvnqhw6.js.br +0 -0
  521. package/dist/web/assets/chat-tab-DVvnqhw6.js.gz +0 -0
  522. package/dist/web/assets/chat-tab-DaEHva22.js +0 -15
  523. package/dist/web/assets/chat-tab-DaEHva22.js.br +0 -0
  524. package/dist/web/assets/chat-tab-DaEHva22.js.gz +0 -0
  525. package/dist/web/assets/code-editor-Bu9lhTVp.js +0 -7
  526. package/dist/web/assets/code-editor-Bu9lhTVp.js.br +0 -0
  527. package/dist/web/assets/code-editor-Bu9lhTVp.js.gz +0 -0
  528. package/dist/web/assets/codex-reset-credit-button-CbmE5mRX.js +0 -1
  529. package/dist/web/assets/codex-reset-credit-button-CbmE5mRX.js.br +0 -0
  530. package/dist/web/assets/codex-reset-credit-button-CbmE5mRX.js.gz +0 -0
  531. package/dist/web/assets/conflict-editor-BA3y-qSH.js.br +0 -0
  532. package/dist/web/assets/conflict-editor-BA3y-qSH.js.gz +0 -0
  533. package/dist/web/assets/context-menu-CjYTq8DI.js +0 -1
  534. package/dist/web/assets/context-menu-CjYTq8DI.js.br +0 -0
  535. package/dist/web/assets/context-menu-CjYTq8DI.js.gz +0 -0
  536. package/dist/web/assets/csv-preview-BioxkrQF.js.br +0 -0
  537. package/dist/web/assets/csv-preview-BioxkrQF.js.gz +0 -0
  538. package/dist/web/assets/data-grid-overlay-editor-CQRVKr7y.js.br +0 -0
  539. package/dist/web/assets/data-grid-overlay-editor-CQRVKr7y.js.gz +0 -0
  540. package/dist/web/assets/database-viewer-BSoJ0E6p.js.br +0 -0
  541. package/dist/web/assets/database-viewer-BSoJ0E6p.js.gz +0 -0
  542. package/dist/web/assets/design-export-client-ChMcMoqW.js.br +0 -0
  543. package/dist/web/assets/design-export-client-ChMcMoqW.js.gz +0 -0
  544. package/dist/web/assets/design-responsive-dialog-DNBhJJLf.js.br +0 -0
  545. package/dist/web/assets/design-responsive-dialog-DNBhJJLf.js.gz +0 -0
  546. package/dist/web/assets/design-tab-iU2CviE3.js +0 -33
  547. package/dist/web/assets/design-tab-iU2CviE3.js.br +0 -0
  548. package/dist/web/assets/design-tab-iU2CviE3.js.gz +0 -0
  549. package/dist/web/assets/designs-sidebar-panel-DHh5QsH9.js.br +0 -0
  550. package/dist/web/assets/designs-sidebar-panel-DHh5QsH9.js.gz +0 -0
  551. package/dist/web/assets/dialog-B8clVkyi.js +0 -1
  552. package/dist/web/assets/dialog-B8clVkyi.js.br +0 -0
  553. package/dist/web/assets/dialog-B8clVkyi.js.gz +0 -0
  554. package/dist/web/assets/diff-viewer-lctWoSmG.js.br +0 -0
  555. package/dist/web/assets/diff-viewer-lctWoSmG.js.gz +0 -0
  556. package/dist/web/assets/docx-preview-C9XdKEj1.js.br +0 -0
  557. package/dist/web/assets/docx-preview-C9XdKEj1.js.gz +0 -0
  558. package/dist/web/assets/editor-language-service-fPG56hQO.js +0 -1
  559. package/dist/web/assets/editor-language-service-fPG56hQO.js.br +0 -0
  560. package/dist/web/assets/editor-language-service-fPG56hQO.js.gz +0 -0
  561. package/dist/web/assets/explorer-body-BgF7FsxI.js +0 -2
  562. package/dist/web/assets/explorer-body-BgF7FsxI.js.br +0 -0
  563. package/dist/web/assets/explorer-body-BgF7FsxI.js.gz +0 -0
  564. package/dist/web/assets/explorer-window-content-C21w_7lf.js +0 -1
  565. package/dist/web/assets/explorer-window-content-C21w_7lf.js.br +0 -0
  566. package/dist/web/assets/explorer-window-content-C21w_7lf.js.gz +0 -0
  567. package/dist/web/assets/extension-manager-section-rbkXsZVR.js.br +0 -0
  568. package/dist/web/assets/extension-manager-section-rbkXsZVR.js.gz +0 -0
  569. package/dist/web/assets/extension-webview-uPO0WgCq.js.br +0 -0
  570. package/dist/web/assets/extension-webview-uPO0WgCq.js.gz +0 -0
  571. package/dist/web/assets/file-icons-gx_FBOXY.js.br +0 -0
  572. package/dist/web/assets/file-icons-gx_FBOXY.js.gz +0 -0
  573. package/dist/web/assets/file-store-D9KE0kQC.js.br +0 -0
  574. package/dist/web/assets/file-store-D9KE0kQC.js.gz +0 -0
  575. package/dist/web/assets/files-settings-section-CT7mDb0L.js.br +0 -0
  576. package/dist/web/assets/files-settings-section-CT7mDb0L.js.gz +0 -0
  577. package/dist/web/assets/format-bytes-DmSHAKFe.js +0 -1
  578. package/dist/web/assets/format-file-meta-mQwA6SuY.js.br +0 -0
  579. package/dist/web/assets/format-file-meta-mQwA6SuY.js.gz +0 -0
  580. package/dist/web/assets/fs-api-DL36slbd.js.br +0 -0
  581. package/dist/web/assets/fs-api-DL36slbd.js.gz +0 -0
  582. package/dist/web/assets/general-settings-section-DANPfMRN.js.br +0 -0
  583. package/dist/web/assets/general-settings-section-DANPfMRN.js.gz +0 -0
  584. package/dist/web/assets/git-log-panel-BJPkLiEw.js.br +0 -0
  585. package/dist/web/assets/git-log-panel-BJPkLiEw.js.gz +0 -0
  586. package/dist/web/assets/git-repo-store-DSypNj19.js.br +0 -0
  587. package/dist/web/assets/git-repo-store-DSypNj19.js.gz +0 -0
  588. package/dist/web/assets/glide-data-grid-R4PcAntf.js.br +0 -0
  589. package/dist/web/assets/glide-data-grid-R4PcAntf.js.gz +0 -0
  590. package/dist/web/assets/group-chat-tab-BXMdo8w9.js +0 -1
  591. package/dist/web/assets/group-chat-tab-BXMdo8w9.js.br +0 -0
  592. package/dist/web/assets/group-chat-tab-BXMdo8w9.js.gz +0 -0
  593. package/dist/web/assets/index-C8nGqkKN.js +0 -52
  594. package/dist/web/assets/index-C8nGqkKN.js.br +0 -0
  595. package/dist/web/assets/index-C8nGqkKN.js.gz +0 -0
  596. package/dist/web/assets/index-DvClbTQx.css +0 -1
  597. package/dist/web/assets/index-DvClbTQx.css.br +0 -0
  598. package/dist/web/assets/index-DvClbTQx.css.gz +0 -0
  599. package/dist/web/assets/keybindings-store-BGKlQQAv.js +0 -1
  600. package/dist/web/assets/keyboard-shortcuts-section-BKej4mUf.js.br +0 -0
  601. package/dist/web/assets/keyboard-shortcuts-section-BKej4mUf.js.gz +0 -0
  602. package/dist/web/assets/markdown-renderer-BHtYqkYZ.js.br +0 -0
  603. package/dist/web/assets/markdown-renderer-BHtYqkYZ.js.gz +0 -0
  604. package/dist/web/assets/markdown-renderer-vDNuKjel.js +0 -1
  605. package/dist/web/assets/mobile-bottom-sheet-CuNi2FRv.js.br +0 -0
  606. package/dist/web/assets/mobile-bottom-sheet-CuNi2FRv.js.gz +0 -0
  607. package/dist/web/assets/mobile-explorer-sheet-DtvxS7-r.js +0 -1
  608. package/dist/web/assets/mobile-explorer-sheet-DtvxS7-r.js.br +0 -0
  609. package/dist/web/assets/mobile-explorer-sheet-DtvxS7-r.js.gz +0 -0
  610. package/dist/web/assets/new-design-dialog-DS_XrpTG.js.br +0 -0
  611. package/dist/web/assets/new-design-dialog-DS_XrpTG.js.gz +0 -0
  612. package/dist/web/assets/notification-store-Dnnj20Ky.js +0 -1
  613. package/dist/web/assets/notifications-settings-section-C05WYqcE.js.br +0 -0
  614. package/dist/web/assets/notifications-settings-section-C05WYqcE.js.gz +0 -0
  615. package/dist/web/assets/onboarding-entry-CmUqv1kl.js.br +0 -0
  616. package/dist/web/assets/onboarding-entry-CmUqv1kl.js.gz +0 -0
  617. package/dist/web/assets/onboarding-quick-orientation-DIhWv1CN.js.br +0 -0
  618. package/dist/web/assets/onboarding-quick-orientation-DIhWv1CN.js.gz +0 -0
  619. package/dist/web/assets/overview-panel-BZAW_nag.js +0 -1
  620. package/dist/web/assets/overview-panel-BZAW_nag.js.br +0 -0
  621. package/dist/web/assets/overview-panel-BZAW_nag.js.gz +0 -0
  622. package/dist/web/assets/pdf-preview-qdXmMkOR.js.br +0 -0
  623. package/dist/web/assets/pdf-preview-qdXmMkOR.js.gz +0 -0
  624. package/dist/web/assets/postgres-viewer-Xvlun_n5.js.br +0 -0
  625. package/dist/web/assets/postgres-viewer-Xvlun_n5.js.gz +0 -0
  626. package/dist/web/assets/ppmbot-settings-section-D8AES1BA.js.br +0 -0
  627. package/dist/web/assets/ppmbot-settings-section-D8AES1BA.js.gz +0 -0
  628. package/dist/web/assets/pptx-export-CG6MRNok.js.br +0 -0
  629. package/dist/web/assets/pptx-export-CG6MRNok.js.gz +0 -0
  630. package/dist/web/assets/problems-panel-DTBG4beI.js.br +0 -0
  631. package/dist/web/assets/problems-panel-DTBG4beI.js.gz +0 -0
  632. package/dist/web/assets/process-table-D_gR2XA6.js +0 -1
  633. package/dist/web/assets/process-table-D_gR2XA6.js.br +0 -0
  634. package/dist/web/assets/process-table-D_gR2XA6.js.gz +0 -0
  635. package/dist/web/assets/project-store-C5gJXkvb.js.br +0 -0
  636. package/dist/web/assets/project-store-C5gJXkvb.js.gz +0 -0
  637. package/dist/web/assets/proxy-settings-section-CqtmbeRj.js.br +0 -0
  638. package/dist/web/assets/proxy-settings-section-CqtmbeRj.js.gz +0 -0
  639. package/dist/web/assets/query-audit-section-UKG_smyt.js.br +0 -0
  640. package/dist/web/assets/query-audit-section-UKG_smyt.js.gz +0 -0
  641. package/dist/web/assets/remote-desktop-clipboard-notice-Djt6cpNL.js.br +0 -0
  642. package/dist/web/assets/remote-desktop-clipboard-notice-Djt6cpNL.js.gz +0 -0
  643. package/dist/web/assets/remote-desktop-mobile-sheet-BQxhJUkm.js +0 -2
  644. package/dist/web/assets/remote-desktop-mobile-sheet-BQxhJUkm.js.br +0 -0
  645. package/dist/web/assets/remote-desktop-mobile-sheet-BQxhJUkm.js.gz +0 -0
  646. package/dist/web/assets/remote-desktop-mobile-view-DGnT8RY7.js +0 -1
  647. package/dist/web/assets/remote-desktop-mobile-view-DGnT8RY7.js.br +0 -0
  648. package/dist/web/assets/remote-desktop-mobile-view-DGnT8RY7.js.gz +0 -0
  649. package/dist/web/assets/remote-desktop-readiness-gate-DNJF8TcF.js.br +0 -0
  650. package/dist/web/assets/remote-desktop-readiness-gate-DNJF8TcF.js.gz +0 -0
  651. package/dist/web/assets/remote-desktop-window-content-Ds0DKmM0.js +0 -1
  652. package/dist/web/assets/remote-desktop-window-content-Ds0DKmM0.js.br +0 -0
  653. package/dist/web/assets/remote-desktop-window-content-Ds0DKmM0.js.gz +0 -0
  654. package/dist/web/assets/schedules-settings-section-BKoPovy2.js.br +0 -0
  655. package/dist/web/assets/schedules-settings-section-BKoPovy2.js.gz +0 -0
  656. package/dist/web/assets/scroll-area-XonvWYn_.js.br +0 -0
  657. package/dist/web/assets/scroll-area-XonvWYn_.js.gz +0 -0
  658. package/dist/web/assets/settings-body-k2qPgRFe.js +0 -2
  659. package/dist/web/assets/settings-body-k2qPgRFe.js.br +0 -0
  660. package/dist/web/assets/settings-body-k2qPgRFe.js.gz +0 -0
  661. package/dist/web/assets/settings-store-Br5c1efC.js +0 -2
  662. package/dist/web/assets/settings-store-Br5c1efC.js.br +0 -0
  663. package/dist/web/assets/settings-store-Br5c1efC.js.gz +0 -0
  664. package/dist/web/assets/settings-tab-Bb23VdBu.js +0 -1
  665. package/dist/web/assets/settings-window-content-ClarWusz.js +0 -1
  666. package/dist/web/assets/sql-query-editor-BjIMi9Wk.js.br +0 -0
  667. package/dist/web/assets/sql-query-editor-BjIMi9Wk.js.gz +0 -0
  668. package/dist/web/assets/sqlite-viewer-BNcA6Irq.js.br +0 -0
  669. package/dist/web/assets/sqlite-viewer-BNcA6Irq.js.gz +0 -0
  670. package/dist/web/assets/system-monitor-body-D0T3ggt2.js +0 -2
  671. package/dist/web/assets/system-monitor-body-D0T3ggt2.js.br +0 -0
  672. package/dist/web/assets/system-monitor-body-D0T3ggt2.js.gz +0 -0
  673. package/dist/web/assets/system-monitor-tab-I1Igmoey.js +0 -1
  674. package/dist/web/assets/system-monitor-window-content-C5SeUv1H.js +0 -1
  675. package/dist/web/assets/tab-host-window-content-CIRGNCvi.js.br +0 -0
  676. package/dist/web/assets/tab-host-window-content-CIRGNCvi.js.gz +0 -0
  677. package/dist/web/assets/team-member-sheet-CwXpLi3X.js.br +0 -0
  678. package/dist/web/assets/team-member-sheet-CwXpLi3X.js.gz +0 -0
  679. package/dist/web/assets/team-member-window-content-4swiiDz7.js.br +0 -0
  680. package/dist/web/assets/team-member-window-content-4swiiDz7.js.gz +0 -0
  681. package/dist/web/assets/terminal-tab-BGcdtMMT.js.br +0 -0
  682. package/dist/web/assets/terminal-tab-BGcdtMMT.js.gz +0 -0
  683. package/dist/web/assets/tool-cards-D0-krtA2.js.br +0 -0
  684. package/dist/web/assets/tool-cards-D0-krtA2.js.gz +0 -0
  685. package/dist/web/assets/use-inline-blame-pKaXyGU-.js +0 -16
  686. package/dist/web/assets/use-inline-blame-pKaXyGU-.js.br +0 -0
  687. package/dist/web/assets/use-inline-blame-pKaXyGU-.js.gz +0 -0
  688. package/dist/web/assets/use-lsp-71azTXQz.js +0 -6
  689. package/dist/web/assets/use-lsp-71azTXQz.js.br +0 -0
  690. package/dist/web/assets/use-lsp-71azTXQz.js.gz +0 -0
  691. package/dist/web/assets/vendor-ui-BHh12_0v.js.br +0 -0
  692. package/dist/web/assets/vendor-ui-BHh12_0v.js.gz +0 -0
  693. package/dist/web/assets/video-preview-DxEX-uGo.js +0 -1
  694. package/dist/web/assets/video-preview-DxEX-uGo.js.br +0 -0
  695. package/dist/web/assets/video-preview-DxEX-uGo.js.gz +0 -0
  696. package/dist/web/assets/ws-auth-kXgsX2Js.js +0 -1
  697. /package/dist/web/assets/{__vite-browser-external-BpSQWxcq.js → __vite-browser-external-BILfYaAs.js} +0 -0
  698. /package/dist/web/assets/{run-in-terminal-HIdNgYim.js → run-in-terminal-2pSiup8e.js} +0 -0
  699. /package/dist/web/assets/{vendor-xterm-DLDtzLib.js → vendor-xterm-DF1JTfsy.js} +0 -0
  700. /package/dist/web/assets/{vendor-xterm-DLDtzLib.js.br → vendor-xterm-DF1JTfsy.js.br} +0 -0
  701. /package/dist/web/assets/{vendor-xterm-DLDtzLib.js.gz → vendor-xterm-DF1JTfsy.js.gz} +0 -0
@@ -32,6 +32,14 @@ export interface LanguageServerDefinition {
32
32
  rootMarkers: string[];
33
33
  /** Shown verbatim when the command cannot be found. */
34
34
  installHint: string;
35
+ /**
36
+ * How the Install button installs this server, when PPM can install it at all.
37
+ *
38
+ * Unset for a server that needs a system package manager — `clangd`, `lua-language-server`
39
+ * and `solargraph` mean pacman, apt, brew or a gem, i.e. a password and a choice PPM has no
40
+ * business making. Those keep a command to copy and no button.
41
+ */
42
+ install?: LanguageServerInstall;
35
43
  /**
36
44
  * The npm package PPM depends on for this server, when it ships one.
37
45
  *
@@ -42,6 +50,25 @@ export interface LanguageServerDefinition {
42
50
  initializationOptions?: Record<string, unknown>;
43
51
  }
44
52
 
53
+ /**
54
+ * What the Install button runs.
55
+ *
56
+ * `bun` and `go` both put the server inside PPM's own directory, so nothing the user installed
57
+ * is touched and `rm -rf` is the uninstall. `rustup` is the exception and has to be: a
58
+ * rust-analyzer belongs to a toolchain, and a private copy would be the wrong one as soon as a
59
+ * project pins a different toolchain.
60
+ *
61
+ * PPM never installs the *toolchain*. `go` and `rustup` are offered only where the host
62
+ * already has them — see `canInstall` in `lsp-install.ts`.
63
+ */
64
+ export type LanguageServerInstall =
65
+ /** `bun add <packages>`; the first package provides `command`, the rest are what it needs. */
66
+ | { with: "bun"; packages: string[] }
67
+ /** `go install <module>` with `GOBIN` pointed at PPM's own bin directory. */
68
+ | { with: "go"; module: string }
69
+ /** `rustup component add <component>`, in whichever toolchain the project selects. */
70
+ | { with: "rustup"; component: string };
71
+
45
72
  /**
46
73
  * File extension to LSP language id.
47
74
  *
@@ -110,6 +137,7 @@ export const LANGUAGE_SERVERS: LanguageServerDefinition[] = [
110
137
  // start against it with "provides no tsserver" — which reads like a broken
111
138
  // install rather than the wrong major version.
112
139
  installHint: "bun add -g typescript-language-server typescript@5",
140
+ install: { with: "bun", packages: ["typescript-language-server", "typescript@5"] },
113
141
  // Shipped with PPM, so this one works on a fresh install with nothing else done. The
114
142
  // project's own copy still wins where there is one — a repository pinned to TypeScript 4
115
143
  // has to be analysed by its own server, not by whatever PPM happens to carry.
@@ -153,6 +181,7 @@ export const LANGUAGE_SERVERS: LanguageServerDefinition[] = [
153
181
  args: ["--stdio"],
154
182
  rootMarkers: ["pyproject.toml", "setup.py", "setup.cfg", "requirements.txt", "Pipfile"],
155
183
  installHint: "bun add -g pyright",
184
+ install: { with: "bun", packages: ["pyright"] },
156
185
  },
157
186
  {
158
187
  id: "gopls",
@@ -162,6 +191,9 @@ export const LANGUAGE_SERVERS: LanguageServerDefinition[] = [
162
191
  args: [],
163
192
  rootMarkers: ["go.work", "go.mod"],
164
193
  installHint: "go install golang.org/x/tools/gopls@latest",
194
+ // Built by the host's own Go, into PPM's directory: `GOBIN` is what decides where the
195
+ // binary lands, so `~/go/bin` is left exactly as the user arranged it. 10.6 s here.
196
+ install: { with: "go", module: "golang.org/x/tools/gopls@latest" },
165
197
  },
166
198
  {
167
199
  id: "rust-analyzer",
@@ -171,6 +203,11 @@ export const LANGUAGE_SERVERS: LanguageServerDefinition[] = [
171
203
  args: [],
172
204
  rootMarkers: ["Cargo.toml"],
173
205
  installHint: "rustup component add rust-analyzer",
206
+ // The one server PPM does not keep in its own directory: rust-analyzer belongs to a
207
+ // *toolchain*, and a copy of its own would be the wrong one the moment a project pins a
208
+ // different one. `rustup which` is then both the lookup and the installed-check — it exits
209
+ // non-zero with "unknown binary" when the component is absent, in 3 ms.
210
+ install: { with: "rustup", component: "rust-analyzer" },
174
211
  },
175
212
  {
176
213
  id: "clangd",
@@ -189,6 +226,7 @@ export const LANGUAGE_SERVERS: LanguageServerDefinition[] = [
189
226
  args: ["--stdio"],
190
227
  rootMarkers: ["package.json"],
191
228
  installHint: "bun add -g vscode-langservers-extracted",
229
+ install: { with: "bun", packages: ["vscode-langservers-extracted"] },
192
230
  },
193
231
  {
194
232
  id: "html",
@@ -198,6 +236,7 @@ export const LANGUAGE_SERVERS: LanguageServerDefinition[] = [
198
236
  args: ["--stdio"],
199
237
  rootMarkers: ["package.json"],
200
238
  installHint: "bun add -g vscode-langservers-extracted",
239
+ install: { with: "bun", packages: ["vscode-langservers-extracted"] },
201
240
  },
202
241
  {
203
242
  id: "css",
@@ -207,6 +246,7 @@ export const LANGUAGE_SERVERS: LanguageServerDefinition[] = [
207
246
  args: ["--stdio"],
208
247
  rootMarkers: ["package.json"],
209
248
  installHint: "bun add -g vscode-langservers-extracted",
249
+ install: { with: "bun", packages: ["vscode-langservers-extracted"] },
210
250
  },
211
251
  {
212
252
  id: "yaml",
@@ -216,6 +256,7 @@ export const LANGUAGE_SERVERS: LanguageServerDefinition[] = [
216
256
  args: ["--stdio"],
217
257
  rootMarkers: [],
218
258
  installHint: "bun add -g yaml-language-server",
259
+ install: { with: "bun", packages: ["yaml-language-server"] },
219
260
  },
220
261
  {
221
262
  id: "bash",
@@ -225,6 +266,7 @@ export const LANGUAGE_SERVERS: LanguageServerDefinition[] = [
225
266
  args: ["start"],
226
267
  rootMarkers: [],
227
268
  installHint: "bun add -g bash-language-server",
269
+ install: { with: "bun", packages: ["bash-language-server"] },
228
270
  },
229
271
  {
230
272
  id: "intelephense",
@@ -234,6 +276,7 @@ export const LANGUAGE_SERVERS: LanguageServerDefinition[] = [
234
276
  args: ["--stdio"],
235
277
  rootMarkers: ["composer.json"],
236
278
  installHint: "bun add -g intelephense",
279
+ install: { with: "bun", packages: ["intelephense"] },
237
280
  },
238
281
  {
239
282
  id: "solargraph",
@@ -261,6 +304,7 @@ export const LANGUAGE_SERVERS: LanguageServerDefinition[] = [
261
304
  args: ["--stdio"],
262
305
  rootMarkers: ["package.json"],
263
306
  installHint: "bun add -g @vue/language-server",
307
+ install: { with: "bun", packages: ["@vue/language-server"] },
264
308
  },
265
309
  {
266
310
  id: "svelte",
@@ -270,6 +314,7 @@ export const LANGUAGE_SERVERS: LanguageServerDefinition[] = [
270
314
  args: ["--stdio"],
271
315
  rootMarkers: ["package.json"],
272
316
  installHint: "bun add -g svelte-language-server",
317
+ install: { with: "bun", packages: ["svelte-language-server"] },
273
318
  },
274
319
  ];
275
320
 
@@ -282,6 +327,26 @@ export function serverById(id: string): LanguageServerDefinition | undefined {
282
327
  return LANGUAGE_SERVERS.find((s) => s.id === id);
283
328
  }
284
329
 
330
+ /**
331
+ * The other servers that an uninstall of this one would also take away.
332
+ *
333
+ * One npm package can provide several servers — `vscode-langservers-extracted` is JSON, HTML
334
+ * and CSS at once — so `bun remove` of it removes all three whichever row the button was on.
335
+ * That is not a thing to discover afterwards, so the Settings pane names them before asking.
336
+ * Nothing shares a `go` module or a rustup component, so those answer with nothing.
337
+ */
338
+ export function serversSharingInstall(definition: LanguageServerDefinition): LanguageServerDefinition[] {
339
+ const plan = definition.install;
340
+ if (plan?.with !== "bun") return [];
341
+ const pkg = packageName(plan.packages[0] ?? "");
342
+ return LANGUAGE_SERVERS.filter(
343
+ (s) =>
344
+ s.id !== definition.id &&
345
+ s.install?.with === "bun" &&
346
+ packageName(s.install.packages[0] ?? "") === pkg,
347
+ );
348
+ }
349
+
285
350
  /**
286
351
  * Directories to search, nearest first, from the file's own directory up to and
287
352
  * including the project root.
@@ -386,16 +451,67 @@ export function bundledServerEntry(
386
451
  ): string | null {
387
452
  const pkg = definition.bundledPackage;
388
453
  if (!pkg) return null;
389
- let manifestPath: string;
454
+ try {
455
+ return binEntry(resolve(`${pkg}/package.json`), definition.command);
456
+ } catch {
457
+ return null;
458
+ }
459
+ }
460
+
461
+ /**
462
+ * The entry script of an npm server the Install button put in PPM's own directory.
463
+ *
464
+ * Built as a path *under* `installDir` rather than resolved through `require`: Node resolution
465
+ * climbs out of the directory it starts in, so a stray `~/node_modules` would answer for a
466
+ * package PPM never installed — and whatever answers here is executed.
467
+ */
468
+ export function installedServerEntry(definition: LanguageServerDefinition, installDir: string): string | null {
469
+ if (definition.install?.with !== "bun") return null;
470
+ const spec = definition.install.packages[0];
471
+ if (!spec) return null;
472
+ const pkgDir = path.join(installDir, "node_modules", ...packageName(spec).split("/"));
473
+ return binEntry(path.join(pkgDir, "package.json"), definition.command);
474
+ }
475
+
476
+ /**
477
+ * Where a compiled server the Install button built would be — PPM's own `bin` directory.
478
+ *
479
+ * That is `GOBIN` for the install, so the binary is PPM's to find and to delete, and the
480
+ * user's `~/go/bin` is left as they arranged it. A plain path: whether it exists is the
481
+ * caller's `exists()`, the same as for every other candidate.
482
+ */
483
+ export function installedBinaryPath(
484
+ definition: LanguageServerDefinition,
485
+ installDir: string,
486
+ platform: NodeJS.Platform = process.platform,
487
+ ): string | null {
488
+ if (definition.install?.with !== "go") return null;
489
+ return path.join(installDir, "bin", platform === "win32" ? `${definition.command}.exe` : definition.command);
490
+ }
491
+
492
+ /** `typescript@5` → `typescript`, keeping a scoped package's own leading `@`. */
493
+ export function packageName(spec: string): string {
494
+ const at = spec.indexOf("@", 1);
495
+ return at === -1 ? spec : spec.slice(0, at);
496
+ }
497
+
498
+ /**
499
+ * `bin[command]` from a package manifest, as an absolute path.
500
+ *
501
+ * Both callers want the package's **entry script** and not npm's `.bin` shim: that shim starts
502
+ * `#!/usr/bin/env node`, and someone who installed PPM with bun may have no `node` on the
503
+ * machine at all — measured as exit **127** with `env: 'node': No such file or directory`,
504
+ * after the server had already been reported as installed. The manager runs the entry with bun.
505
+ */
506
+ function binEntry(manifestPath: string, command: string): string | null {
390
507
  let manifest: { bin?: string | Record<string, string> };
391
508
  try {
392
- manifestPath = resolve(`${pkg}/package.json`);
393
509
  manifest = JSON.parse(readFileSync(manifestPath, "utf8")) as typeof manifest;
394
510
  } catch {
395
- return null;
511
+ return null; // not installed, or a manifest we cannot read
396
512
  }
397
513
  // `bin` is either a bare string — the package's own name — or a map of command to path.
398
- const relative = typeof manifest.bin === "string" ? manifest.bin : manifest.bin?.[definition.command];
514
+ const relative = typeof manifest.bin === "string" ? manifest.bin : manifest.bin?.[command];
399
515
  if (!relative) return null;
400
516
  return path.resolve(path.dirname(manifestPath), relative);
401
517
  }
@@ -9,6 +9,8 @@
9
9
  export type TunnelMode = "quick" | "named";
10
10
 
11
11
  export interface ResolvedTunnelConfig {
12
+ /** Master switch — `false` means spawn no tunnel at all, whatever `mode` says. */
13
+ enabled: boolean;
12
14
  mode: TunnelMode;
13
15
  hostname: string | null;
14
16
  tunnelName: string | null;
@@ -18,7 +20,7 @@ export interface ResolvedTunnelConfig {
18
20
  dismissed: boolean;
19
21
  }
20
22
 
21
- const QUICK: Omit<ResolvedTunnelConfig, "dismissed"> = {
23
+ const QUICK: Omit<ResolvedTunnelConfig, "dismissed" | "enabled"> = {
22
24
  mode: "quick", hostname: null, tunnelName: null, token: null, zoneID: null, accountID: null,
23
25
  };
24
26
 
@@ -35,6 +37,9 @@ export function resolveTunnelConfig(raw: unknown): ResolvedTunnelConfig {
35
37
  }
36
38
 
37
39
  const dismissed = obj != null && typeof obj.dismissed === "boolean" ? obj.dismissed : false;
40
+ // Absent means a row older than the master switch, back when the tunnel was
41
+ // unconditional — absent is therefore on, never off.
42
+ const enabled = obj != null && typeof obj.enabled === "boolean" ? obj.enabled : true;
38
43
 
39
44
  // Named mode requires BOTH the stored mode flag AND all four identity fields —
40
45
  // checking fields alone would resurrect a tunnel the user explicitly disabled,
@@ -46,10 +51,11 @@ export function resolveTunnelConfig(raw: unknown): ResolvedTunnelConfig {
46
51
  nonEmptyString(obj.accountID);
47
52
 
48
53
  if (!named || obj == null) {
49
- return { ...QUICK, dismissed };
54
+ return { ...QUICK, enabled, dismissed };
50
55
  }
51
56
 
52
57
  return {
58
+ enabled,
53
59
  mode: "named",
54
60
  hostname: obj.namedTunnelHostname as string,
55
61
  tunnelName: nonEmptyString(obj.namedTunnelName) ? obj.namedTunnelName : null,
@@ -159,6 +159,10 @@ async function runSetupInner(hostname: string): Promise<SetupOutcome> {
159
159
 
160
160
  broadcastGlobalEvent({ type: "tunnel:setup_step", step: "apply", message: "applying configuration" });
161
161
  configService.set("tunnel", {
162
+ // Carry the master switch across rather than defaulting it: configuring a
163
+ // domain is not consent to start sharing, and this write would otherwise
164
+ // silently turn a deliberately-off tunnel back on.
165
+ enabled: configService.get("tunnel").enabled,
162
166
  mode: "named",
163
167
  namedTunnelName: tunnelName,
164
168
  namedTunnelHostname: hostname,
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Streaming line reader for the JSONL transcripts.
3
+ *
4
+ * Its own module because two readers need it — the full message parser and the
5
+ * compaction scan — and having the second import it from the first would make the
6
+ * two files a cycle.
7
+ */
8
+
9
+ /**
10
+ * Yield a file's lines without holding the file in memory.
11
+ *
12
+ * `Bun.file().text()` plus `split("\n")` costs the whole transcript twice over —
13
+ * 277MB resident for a 77MB file, which is what forced a cap low enough to
14
+ * reject real sessions. Peak here is one chunk plus one line.
15
+ *
16
+ * `fromByte` reads a tail window instead of the whole file, for the callers that
17
+ * have to bound what they parse. See `fullParseWindow` in
18
+ * `jsonl-transcript-parser.ts` for why a bound is a window rather than a refusal.
19
+ */
20
+ export async function* readLines(filePath: string, fromByte = 0): AsyncGenerator<string> {
21
+ const decoder = new TextDecoder();
22
+ // Explicit reader rather than `for await` over the stream: the DOM lib's
23
+ // ReadableStream is not typed as async-iterable, and the `finally` is what
24
+ // releases it when a caller breaks early on `beforeUuid`.
25
+ // One byte *before* the offset, so the first line the split produces is
26
+ // always the tail of the record the offset fell inside — the empty string
27
+ // when it fell exactly on a newline. That makes the drop below unconditional
28
+ // instead of a boundary case, and a boundary case here silently costs a whole
29
+ // record rather than a fragment.
30
+ const file = fromByte > 0 ? Bun.file(filePath).slice(fromByte - 1) : Bun.file(filePath);
31
+ const reader = file.stream().getReader();
32
+ // A fragment is not always unparseable — the tail of one record is sometimes
33
+ // a complete smaller document — so it has to go by position rather than be
34
+ // left for `JSON.parse` to reject, or it enters as an invented message.
35
+ let dropPartial = fromByte > 0;
36
+ let buffered = "";
37
+ try {
38
+ while (true) {
39
+ const { done, value } = await reader.read();
40
+ if (done) break;
41
+ buffered += decoder.decode(value, { stream: true });
42
+ const lines = buffered.split("\n");
43
+ buffered = lines.pop() ?? "";
44
+ for (const line of lines) {
45
+ if (dropPartial) { dropPartial = false; continue; }
46
+ yield line;
47
+ }
48
+ }
49
+ } finally {
50
+ reader.releaseLock();
51
+ }
52
+ buffered += decoder.decode();
53
+ if (buffered && !dropPartial) yield buffered;
54
+ }
@@ -0,0 +1,142 @@
1
+ /**
2
+ * What "install Whisper" downloads: one whisper.cpp build per platform, one
3
+ * speech model, and the VAD model that goes with every model.
4
+ *
5
+ * Pure and parameterised so the whole matrix is unit-testable without touching
6
+ * `process.*` or the network. Every entry is pinned by tag/revision AND by
7
+ * SHA-256, because this code downloads an executable onto the user's machine.
8
+ *
9
+ * The VAD model is not optional. Whisper invents speech out of silence, and in
10
+ * Vietnamese it invents the same YouTube outro every time — six seconds of
11
+ * digital silence transcribed as "Hãy subscribe cho kênh Ghiền Mì Gõ Để không
12
+ * bỏ lỡ những video hấp dẫn" on both `small` and `large-v3-turbo`, and pink
13
+ * noise as "Cảm ơn các bạn đã theo dõi và hẹn gặp lại." With Silero VAD in
14
+ * front, both come back empty (and in 0.3s instead of seconds).
15
+ */
16
+
17
+ /** whisper.cpp release that the prebuilt binaries come from. */
18
+ export const WHISPER_BUILD = "b5130";
19
+ /** Whisper version inside that build, for display only. */
20
+ export const WHISPER_VERSION = "1.9.4";
21
+
22
+ const RELEASE_BASE = `https://github.com/ggml-org/whisper.cpp/releases/download/${WHISPER_BUILD}`;
23
+
24
+ /** Pinned commits of the Hugging Face repos the models are fetched from. */
25
+ const MODEL_REPO_REV = "5359861c739e955e79d9a303bcbc70fb988958b1";
26
+ const VAD_REPO_REV = "9ffd54a1e1ee413ddf265af9913beaf518d1639b";
27
+
28
+ export interface WhisperAsset {
29
+ /** Archive file name as published in the release. */
30
+ file: string;
31
+ url: string;
32
+ sha256: string;
33
+ ext: "tar.gz" | "zip";
34
+ }
35
+
36
+ /**
37
+ * Prebuilt whisper.cpp per platform.
38
+ *
39
+ * macOS is deliberately absent: the release ships an xcframework (a library for
40
+ * Swift apps), never a `whisper-cli`, so there is nothing to download and
41
+ * unpack. A Mac uses Homebrew's `whisper.cpp` formula instead — see
42
+ * `MACOS_INSTALL_HINT` — and PPM then finds `whisper-cli` on PATH.
43
+ */
44
+ const ASSETS: Record<string, WhisperAsset> = {
45
+ "linux-x64": {
46
+ file: "whisper-bin-ubuntu-x64.tar.gz",
47
+ url: `${RELEASE_BASE}/whisper-bin-ubuntu-x64.tar.gz`,
48
+ sha256: "53e7fd8b5764edad916b8848dd0af6abb1ff1d3b86c899e79c78652412536c32",
49
+ ext: "tar.gz",
50
+ },
51
+ "linux-arm64": {
52
+ file: "whisper-bin-ubuntu-arm64.tar.gz",
53
+ url: `${RELEASE_BASE}/whisper-bin-ubuntu-arm64.tar.gz`,
54
+ sha256: "93532a0e3777f26f041ffa358ee77dd88b1a33a86847c1990745327ff335a5d6",
55
+ ext: "tar.gz",
56
+ },
57
+ "win32-x64": {
58
+ file: "whisper-bin-x64.zip",
59
+ url: `${RELEASE_BASE}/whisper-bin-x64.zip`,
60
+ sha256: "f9ec6c52a2e949b62ab51fa21d0d497958f9e41c3010c157c4e42932d5316f3c",
61
+ ext: "zip",
62
+ },
63
+ "win32-arm64": {
64
+ file: "whisper-bin-win-cpu-arm64.zip",
65
+ url: `${RELEASE_BASE}/whisper-bin-win-cpu-arm64.zip`,
66
+ sha256: "799543b926ab5b6c2d60cab269a2092e0ae8d27820e9e15429e59de3699546fc",
67
+ ext: "zip",
68
+ },
69
+ };
70
+
71
+ export const MACOS_INSTALL_HINT = "brew install whisper.cpp";
72
+
73
+ /** The published build for a platform/arch pair, or null when there is none. */
74
+ export function whisperAssetFor(platform: NodeJS.Platform, arch: string): WhisperAsset | null {
75
+ return ASSETS[`${platform}-${arch}`] ?? null;
76
+ }
77
+
78
+ export interface WhisperModel {
79
+ id: string;
80
+ /** File name in the Hugging Face repo, and on disk. */
81
+ file: string;
82
+ label: string;
83
+ /** One line under the label in Settings. */
84
+ note: string;
85
+ bytes: number;
86
+ sha256: string;
87
+ }
88
+
89
+ /**
90
+ * Three rungs, measured on a 10s Vietnamese clip (i9-12900K, 16 threads):
91
+ * `base` 0.9s but "sửa giúp" came back "sửa dụp"; `small` 2.2s and readable;
92
+ * `large-v3-turbo` 5.5s and the only one that kept English identifiers
93
+ * ("handle ... toggle ... message input") intact. Quantized weights, since a
94
+ * q5 file is a third of the size for no accuracy difference anyone dictating a
95
+ * chat message would notice.
96
+ */
97
+ export const WHISPER_MODELS: WhisperModel[] = [
98
+ {
99
+ id: "base-q5_1",
100
+ file: "ggml-base-q5_1.bin",
101
+ label: "Base",
102
+ note: "Fastest, weakest — usable for English, rough in Vietnamese",
103
+ bytes: 59_707_625,
104
+ sha256: "422f1ae452ade6f30a004d7e5c6a43195e4433bc370bf23fac9cc591f01a8898",
105
+ },
106
+ {
107
+ id: "small-q5_1",
108
+ file: "ggml-small-q5_1.bin",
109
+ label: "Small",
110
+ note: "Middle ground — readable Vietnamese, garbles English words",
111
+ bytes: 190_085_487,
112
+ sha256: "ae85e4a935d7a567bd102fe55afc16bb595bdb618e11b2fc7591bc08120411bb",
113
+ },
114
+ {
115
+ id: "large-v3-turbo-q5_0",
116
+ file: "ggml-large-v3-turbo-q5_0.bin",
117
+ label: "Large v3 Turbo",
118
+ note: "Best Vietnamese, keeps English terms — a few seconds per sentence",
119
+ bytes: 574_041_195,
120
+ sha256: "394221709cd5ad1f40c46e6031ca61bce88931e6e088c188294c6d5a55ffa7e2",
121
+ },
122
+ ];
123
+
124
+ export const DEFAULT_MODEL_ID = "large-v3-turbo-q5_0";
125
+
126
+ export const VAD_MODEL = {
127
+ file: "ggml-silero-v5.1.2.bin",
128
+ bytes: 885_098,
129
+ sha256: "29940d98d42b91fbd05ce489f3ecf7c72f0a42f027e4875919a28fb4c04ea2cf",
130
+ };
131
+
132
+ export function modelById(id: string): WhisperModel | null {
133
+ return WHISPER_MODELS.find((m) => m.id === id) ?? null;
134
+ }
135
+
136
+ export function modelUrl(model: WhisperModel): string {
137
+ return `https://huggingface.co/ggerganov/whisper.cpp/resolve/${MODEL_REPO_REV}/${model.file}`;
138
+ }
139
+
140
+ export function vadModelUrl(): string {
141
+ return `https://huggingface.co/ggml-org/whisper-vad/resolve/${VAD_REPO_REV}/${VAD_MODEL.file}`;
142
+ }
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Streaming download with a SHA-256 gate.
3
+ *
4
+ * A model is 574 MB, so it is hashed while it streams rather than read back
5
+ * afterwards, and it lands on a `.part` file that is only renamed once the hash
6
+ * matches: an interrupted or tampered download can never be mistaken for an
7
+ * installed one, and a retry starts clean.
8
+ */
9
+ import { createHash } from "node:crypto";
10
+ import { mkdirSync, renameSync, rmSync } from "node:fs";
11
+ import { dirname } from "node:path";
12
+
13
+ export type FetchFn = typeof fetch;
14
+
15
+ export interface DownloadOptions {
16
+ url: string;
17
+ dest: string;
18
+ /** Lowercase hex. The download is discarded when the bytes hash to anything else. */
19
+ sha256: string;
20
+ /** Called as bytes arrive; `total` is 0 when the server sends no Content-Length. */
21
+ onProgress?: (received: number, total: number) => void;
22
+ fetchFn?: FetchFn;
23
+ signal?: AbortSignal;
24
+ }
25
+
26
+ /**
27
+ * How long the transfer may produce no bytes at all before it is abandoned.
28
+ *
29
+ * Idle rather than wall-clock: the largest model here is 574 MB, and any total-time
30
+ * bound that a slow line can exceed would abort a download that was working. What is
31
+ * never legitimate is silence — a half-open socket after a dropped wifi link or a
32
+ * tunnel that went away never errors and never yields, so without this the `for await`
33
+ * below simply never returns and the install never settles.
34
+ */
35
+ const STALL_TIMEOUT_MS = 60_000;
36
+
37
+ export async function downloadVerified(opts: DownloadOptions): Promise<void> {
38
+ const { url, dest, sha256, onProgress, signal } = opts;
39
+ const fetchFn = opts.fetchFn ?? fetch;
40
+ const part = `${dest}.part`;
41
+
42
+ mkdirSync(dirname(dest), { recursive: true });
43
+ rmSync(part, { force: true });
44
+
45
+ // The caller's signal and the stall timer both have to reach the body stream, and
46
+ // `fetch` takes one signal — so an internal controller carries both.
47
+ const stall = new AbortController();
48
+ const forwardAbort = () => stall.abort(signal?.reason);
49
+ signal?.addEventListener("abort", forwardAbort, { once: true });
50
+ let timer: ReturnType<typeof setTimeout> | null = null;
51
+ const armStallTimer = (): void => {
52
+ if (timer) clearTimeout(timer);
53
+ timer = setTimeout(
54
+ () => stall.abort(new Error(`download stalled: no bytes for ${STALL_TIMEOUT_MS}ms (${url})`)),
55
+ STALL_TIMEOUT_MS,
56
+ );
57
+ timer.unref?.();
58
+ };
59
+ const disarm = (): void => {
60
+ if (timer) clearTimeout(timer);
61
+ timer = null;
62
+ signal?.removeEventListener("abort", forwardAbort);
63
+ };
64
+
65
+ let res: Response;
66
+ armStallTimer();
67
+ try {
68
+ res = await fetchFn(url, { redirect: "follow", signal: stall.signal });
69
+ } catch (e) {
70
+ disarm();
71
+ throw stall.signal.aborted && stall.signal.reason instanceof Error ? stall.signal.reason : e;
72
+ }
73
+ if (!res.ok) { disarm(); throw new Error(`download failed: HTTP ${res.status} (${url})`); }
74
+ if (!res.body) { disarm(); throw new Error(`download failed: empty body (${url})`); }
75
+
76
+ const total = Number(res.headers.get("content-length") ?? 0) || 0;
77
+ const hash = createHash("sha256");
78
+ const sink = Bun.file(part).writer();
79
+ let received = 0;
80
+
81
+ try {
82
+ for await (const chunk of res.body as unknown as AsyncIterable<Uint8Array>) {
83
+ armStallTimer();
84
+ hash.update(chunk);
85
+ sink.write(chunk);
86
+ received += chunk.byteLength;
87
+ onProgress?.(received, total);
88
+ }
89
+ await sink.end();
90
+ disarm();
91
+ } catch (e) {
92
+ disarm();
93
+ try {
94
+ await sink.end();
95
+ } catch {
96
+ // Sink already torn down by the failure itself.
97
+ }
98
+ rmSync(part, { force: true });
99
+ // An abort raised by the stall timer carries the reason worth reporting; the
100
+ // stream's own `AbortError` says only that somebody cancelled.
101
+ throw stall.signal.aborted && stall.signal.reason instanceof Error ? stall.signal.reason : e;
102
+ }
103
+
104
+ const actual = hash.digest("hex");
105
+ if (actual !== sha256.toLowerCase()) {
106
+ rmSync(part, { force: true });
107
+ throw new Error(`checksum mismatch for ${url}: expected ${sha256}, got ${actual}`);
108
+ }
109
+
110
+ // Windows refuses a rename onto an existing file, so clear the target first.
111
+ rmSync(dest, { force: true });
112
+ renameSync(part, dest);
113
+ }
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Sentences Whisper invents when it is handed audio with no speech in it.
3
+ *
4
+ * The model was trained on YouTube subtitles, so the likeliest continuation of
5
+ * "a Vietnamese clip with nothing being said" is that channel's sign-off — and
6
+ * it is not a rare edge case: with `--vad` off, *every* non-speech clip
7
+ * measured on large-v3-turbo (digital silence, white noise at four levels,
8
+ * 50 Hz hum, a 440 Hz tone, brown noise, keyboard clicks, a cough, a breath)
9
+ * came back as the same one sentence, byte for byte:
10
+ *
11
+ * silence/noise/hum/tone/typing/cough → "Hãy subscribe cho kênh Ghiền Mì
12
+ * Gõ Để không bỏ lỡ những video hấp dẫn"
13
+ * room tone → "Cảm ơn các bạn đã theo dõi và hẹn gặp lại."
14
+ *
15
+ * The VAD model is what normally stops this (those same clips come back empty
16
+ * with it on), so this list is the second line of defence for the audio VAD
17
+ * does let through — a fan, a distant TV, a word spoken too far from the mic.
18
+ * It is deliberately short and measured rather than guessed: add a sentence
19
+ * here only after seeing this model produce it from a clip with no speech.
20
+ */
21
+
22
+ /** Same shape as the list: lowercased, punctuation dropped, spaces collapsed. */
23
+ function normalize(line: string): string {
24
+ return line
25
+ .toLowerCase()
26
+ .replace(/[.,!?;:"'`*\-_()[\]…]/g, " ")
27
+ .replace(/\s+/g, " ")
28
+ .trim();
29
+ }
30
+
31
+ const INVENTED = [
32
+ "Hãy subscribe cho kênh Ghiền Mì Gõ Để không bỏ lỡ những video hấp dẫn",
33
+ "Cảm ơn các bạn đã theo dõi và hẹn gặp lại.",
34
+ ].map(normalize);
35
+
36
+ /**
37
+ * The channel name is the fingerprint: the sign-off comes back with small
38
+ * wording changes, and nobody dictating into a chat box says it at all.
39
+ */
40
+ const FINGERPRINT = normalize("Ghiền Mì Gõ");
41
+
42
+ /**
43
+ * True for a whole segment the model made up. Whole lines only — `-nt` prints
44
+ * one line per segment, so dropping a line drops exactly the invented
45
+ * sentence and leaves the real ones either side of it alone.
46
+ */
47
+ export function isInventedLine(line: string): boolean {
48
+ const normalized = normalize(line);
49
+ if (normalized.length === 0) return false;
50
+ return INVENTED.includes(normalized) || normalized.includes(FINGERPRINT);
51
+ }