@hienlh/ppm 0.23.21 → 0.23.23

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 (497) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/CLAUDE.md +6 -3
  3. package/README.md +1 -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 +2 -1
  7. package/dist/web/assets/{accounts-settings-section-DD88DRdx.js → accounts-settings-section-Cg-LncY6.js} +1 -1
  8. package/dist/web/assets/accounts-settings-section-Cg-LncY6.js.br +0 -0
  9. package/dist/web/assets/accounts-settings-section-Cg-LncY6.js.gz +0 -0
  10. package/dist/web/assets/{agent-session-sheet-C0PhhLKR.js → agent-session-sheet-DMdV8GOu.js} +2 -2
  11. package/dist/web/assets/agent-session-sheet-DMdV8GOu.js.br +0 -0
  12. package/dist/web/assets/agent-session-sheet-DMdV8GOu.js.gz +0 -0
  13. package/dist/web/assets/{agent-session-window-content-D0XZgh4U.js → agent-session-window-content-CYg58J-V.js} +1 -1
  14. package/dist/web/assets/agent-session-window-content-CYg58J-V.js.br +0 -0
  15. package/dist/web/assets/agent-session-window-content-CYg58J-V.js.gz +0 -0
  16. package/dist/web/assets/{ai-resource-editor-CpfQB6A7.js → ai-resource-editor-BvEnn0Z_.js} +1 -1
  17. package/dist/web/assets/ai-resource-editor-BvEnn0Z_.js.br +0 -0
  18. package/dist/web/assets/ai-resource-editor-BvEnn0Z_.js.gz +0 -0
  19. package/dist/web/assets/{ai-settings-section-DqE67XNC.js → ai-settings-section-Bo-nf2rY.js} +1 -1
  20. package/dist/web/assets/ai-settings-section-DAqiu_11.js +1 -0
  21. package/dist/web/assets/ai-settings-section-DAqiu_11.js.br +0 -0
  22. package/dist/web/assets/ai-settings-section-DAqiu_11.js.gz +0 -0
  23. package/dist/web/assets/{android-tab-4Z4AgHz1.js → android-tab-C-wmlFc0.js} +1 -1
  24. package/dist/web/assets/android-tab-C-wmlFc0.js.br +0 -0
  25. package/dist/web/assets/android-tab-C-wmlFc0.js.gz +0 -0
  26. package/dist/web/assets/{appearance-settings-section-DjQjiJF7.js → appearance-settings-section-CYqX6BGh.js} +1 -1
  27. package/dist/web/assets/appearance-settings-section-CYqX6BGh.js.br +0 -0
  28. package/dist/web/assets/appearance-settings-section-CYqX6BGh.js.gz +0 -0
  29. package/dist/web/assets/{apps-panel-_lxY9xbc.js → apps-panel-D1VTBxgC.js} +1 -1
  30. package/dist/web/assets/apps-panel-D1VTBxgC.js.br +0 -0
  31. package/dist/web/assets/apps-panel-D1VTBxgC.js.gz +0 -0
  32. package/dist/web/assets/{branch-review-tab-BzrhnFSs.js → branch-review-tab-BG6vxSsC.js} +1 -1
  33. package/dist/web/assets/branch-review-tab-BG6vxSsC.js.br +0 -0
  34. package/dist/web/assets/branch-review-tab-BG6vxSsC.js.gz +0 -0
  35. package/dist/web/assets/chat-tab-BAwGLGyR.js +19 -0
  36. package/dist/web/assets/chat-tab-BAwGLGyR.js.br +0 -0
  37. package/dist/web/assets/chat-tab-BAwGLGyR.js.gz +0 -0
  38. package/dist/web/assets/{chat-tab-BKHepkYi.js → chat-tab-BJ0Mi2sd.js} +1 -1
  39. package/dist/web/assets/chat-tab-BJ0Mi2sd.js.br +0 -0
  40. package/dist/web/assets/chat-tab-BJ0Mi2sd.js.gz +0 -0
  41. package/dist/web/assets/{code-editor-COWmNXO4.js → code-editor-DuwbwTpM.js} +4 -4
  42. package/dist/web/assets/code-editor-DuwbwTpM.js.br +0 -0
  43. package/dist/web/assets/code-editor-DuwbwTpM.js.gz +0 -0
  44. package/dist/web/assets/{codex-reset-credit-button-BHt4yJet.js → codex-reset-credit-button-tIwfnf2G.js} +1 -1
  45. package/dist/web/assets/codex-reset-credit-button-tIwfnf2G.js.br +0 -0
  46. package/dist/web/assets/codex-reset-credit-button-tIwfnf2G.js.gz +0 -0
  47. package/dist/web/assets/{conflict-editor-tj-1gzKr.js → conflict-editor-D2n-hQqs.js} +1 -1
  48. package/dist/web/assets/conflict-editor-D2n-hQqs.js.br +0 -0
  49. package/dist/web/assets/conflict-editor-D2n-hQqs.js.gz +0 -0
  50. package/dist/web/assets/{connection-form-tab-BV2QX8Cf.js → connection-form-tab-DYqPNq_-.js} +1 -1
  51. package/dist/web/assets/connection-form-tab-DYqPNq_-.js.br +0 -0
  52. package/dist/web/assets/connection-form-tab-DYqPNq_-.js.gz +0 -0
  53. package/dist/web/assets/{csv-preview-xhE2esgz.js → csv-preview-Xh3Z6BS5.js} +1 -1
  54. package/dist/web/assets/csv-preview-Xh3Z6BS5.js.br +0 -0
  55. package/dist/web/assets/csv-preview-Xh3Z6BS5.js.gz +0 -0
  56. package/dist/web/assets/{db-tab-parts-C3MsjOID.js → db-tab-parts-Dqnb3GCP.js} +1 -1
  57. package/dist/web/assets/db-tab-parts-Dqnb3GCP.js.br +0 -0
  58. package/dist/web/assets/db-tab-parts-Dqnb3GCP.js.gz +0 -0
  59. package/dist/web/assets/{design-settings-section-C3LxYhIw.js → design-settings-section-DNNWgxF9.js} +1 -1
  60. package/dist/web/assets/design-settings-section-DNNWgxF9.js.br +0 -0
  61. package/dist/web/assets/design-settings-section-DNNWgxF9.js.gz +0 -0
  62. package/dist/web/assets/{design-tab-DYcvjdfb.js → design-tab-BoAdSpZZ.js} +1 -1
  63. package/dist/web/assets/design-tab-BoAdSpZZ.js.br +0 -0
  64. package/dist/web/assets/design-tab-BoAdSpZZ.js.gz +0 -0
  65. package/dist/web/assets/{designs-sidebar-panel-Dpr4PPFT.js → designs-sidebar-panel-BKw7HFAz.js} +1 -1
  66. package/dist/web/assets/designs-sidebar-panel-BKw7HFAz.js.br +0 -0
  67. package/dist/web/assets/designs-sidebar-panel-BKw7HFAz.js.gz +0 -0
  68. package/dist/web/assets/{diff-viewer-Fl_4jqr6.js → diff-viewer-CRmfCAZX.js} +1 -1
  69. package/dist/web/assets/diff-viewer-CRmfCAZX.js.br +0 -0
  70. package/dist/web/assets/diff-viewer-CRmfCAZX.js.gz +0 -0
  71. package/dist/web/assets/{docx-preview-bVE9shPX.js → docx-preview-zIrtL09u.js} +1 -1
  72. package/dist/web/assets/docx-preview-zIrtL09u.js.br +0 -0
  73. package/dist/web/assets/docx-preview-zIrtL09u.js.gz +0 -0
  74. package/dist/web/assets/{editor-dialog-eEOYWdbr.js → editor-dialog-jMYvXVla.js} +1 -1
  75. package/dist/web/assets/editor-dialog-jMYvXVla.js.br +0 -0
  76. package/dist/web/assets/editor-dialog-jMYvXVla.js.gz +0 -0
  77. package/dist/web/assets/{editor-language-service-D1_Ggq4s.js → editor-language-service-Yb-61Bro.js} +1 -1
  78. package/dist/web/assets/editor-language-service-Yb-61Bro.js.br +0 -0
  79. package/dist/web/assets/editor-language-service-Yb-61Bro.js.gz +0 -0
  80. package/dist/web/assets/{explorer-body-C0UOcBPJ.js → explorer-body-C6qKehmd.js} +1 -1
  81. package/dist/web/assets/explorer-body-C6qKehmd.js.br +0 -0
  82. package/dist/web/assets/explorer-body-C6qKehmd.js.gz +0 -0
  83. package/dist/web/assets/{explorer-window-content-Dxee7SuJ.js → explorer-window-content-B9P8grrY.js} +1 -1
  84. package/dist/web/assets/explorer-window-content-B9P8grrY.js.br +0 -0
  85. package/dist/web/assets/explorer-window-content-B9P8grrY.js.gz +0 -0
  86. package/dist/web/assets/{extension-manager-section-D8krnoj8.js → extension-manager-section-C45v1QtG.js} +1 -1
  87. package/dist/web/assets/extension-manager-section-C45v1QtG.js.br +0 -0
  88. package/dist/web/assets/extension-manager-section-C45v1QtG.js.gz +0 -0
  89. package/dist/web/assets/{extension-webview-CtIdV69T.js → extension-webview-DIxM-xkH.js} +1 -1
  90. package/dist/web/assets/extension-webview-DIxM-xkH.js.br +0 -0
  91. package/dist/web/assets/extension-webview-DIxM-xkH.js.gz +0 -0
  92. package/dist/web/assets/{files-settings-section-C8vtarR8.js → files-settings-section-DeVlzKXd.js} +1 -1
  93. package/dist/web/assets/files-settings-section-DeVlzKXd.js.br +0 -0
  94. package/dist/web/assets/files-settings-section-DeVlzKXd.js.gz +0 -0
  95. package/dist/web/assets/format-date-CkyHzZLA.js +1 -0
  96. package/dist/web/assets/{general-settings-section-Chu8Ut8h.js → general-settings-section-CLVDIEym.js} +1 -1
  97. package/dist/web/assets/general-settings-section-CLVDIEym.js.br +0 -0
  98. package/dist/web/assets/general-settings-section-CLVDIEym.js.gz +0 -0
  99. package/dist/web/assets/{git-log-panel-DG09p6k5.js → git-log-panel-D3Q9NRll.js} +1 -1
  100. package/dist/web/assets/git-log-panel-D3Q9NRll.js.br +0 -0
  101. package/dist/web/assets/git-log-panel-D3Q9NRll.js.gz +0 -0
  102. package/dist/web/assets/{git-review-tab-CSy8DjSC.js → git-review-tab-ORgiYbva.js} +1 -1
  103. package/dist/web/assets/git-review-tab-ORgiYbva.js.br +0 -0
  104. package/dist/web/assets/git-review-tab-ORgiYbva.js.gz +0 -0
  105. package/dist/web/assets/{glide-data-grid-BN1y4BT0.js → glide-data-grid-CtWl1BTk.js} +1 -1
  106. package/dist/web/assets/glide-data-grid-CtWl1BTk.js.br +0 -0
  107. package/dist/web/assets/glide-data-grid-CtWl1BTk.js.gz +0 -0
  108. package/dist/web/assets/{grid-save-dialog-CfSuWw2t.js → grid-save-dialog-eV25Mqpg.js} +1 -1
  109. package/dist/web/assets/grid-save-dialog-eV25Mqpg.js.br +0 -0
  110. package/dist/web/assets/grid-save-dialog-eV25Mqpg.js.gz +0 -0
  111. package/dist/web/assets/{group-chat-tab-B04QMp7A.js → group-chat-tab-CYmbYXN2.js} +1 -1
  112. package/dist/web/assets/group-chat-tab-CYmbYXN2.js.br +0 -0
  113. package/dist/web/assets/group-chat-tab-CYmbYXN2.js.gz +0 -0
  114. package/dist/web/assets/{impexp-tab-BRNouquR.js → impexp-tab-D2OKxpFq.js} +1 -1
  115. package/dist/web/assets/impexp-tab-D2OKxpFq.js.br +0 -0
  116. package/dist/web/assets/impexp-tab-D2OKxpFq.js.gz +0 -0
  117. package/dist/web/assets/{index-BpgSIM5B.js → index-D8QDpdgs.js} +7 -7
  118. package/dist/web/assets/index-D8QDpdgs.js.br +0 -0
  119. package/dist/web/assets/index-D8QDpdgs.js.gz +0 -0
  120. package/dist/web/assets/{jira-watcher-section-CJeS5r6D.js → jira-watcher-section-B3OaMlim.js} +1 -1
  121. package/dist/web/assets/{keybindings-store-Dvxq-vZD.js → keybindings-store-C_aRhBu4.js} +1 -1
  122. package/dist/web/assets/{keyboard-shortcuts-section-BKDyZHhK.js → keyboard-shortcuts-section-DXRyKrSy.js} +1 -1
  123. package/dist/web/assets/keyboard-shortcuts-section-DXRyKrSy.js.br +0 -0
  124. package/dist/web/assets/keyboard-shortcuts-section-DXRyKrSy.js.gz +0 -0
  125. package/dist/web/assets/{language-servers-section-CbbkezhA.js → language-servers-section-BTs9iuZc.js} +2 -2
  126. package/dist/web/assets/language-servers-section-BTs9iuZc.js.br +0 -0
  127. package/dist/web/assets/language-servers-section-BTs9iuZc.js.gz +0 -0
  128. package/dist/web/assets/{logs-app-Blr1-v4q.js → logs-app-BlhVTOYN.js} +1 -1
  129. package/dist/web/assets/logs-app-BlhVTOYN.js.br +0 -0
  130. package/dist/web/assets/logs-app-BlhVTOYN.js.gz +0 -0
  131. package/dist/web/assets/{logs-tab-CGPtn2tU.js → logs-tab-kqNARbz0.js} +1 -1
  132. package/dist/web/assets/{logs-window-content-DAczcNmh.js → logs-window-content-UUCJJCqG.js} +1 -1
  133. package/dist/web/assets/{lsp-client-Ds3U2O52.js → lsp-client-BTlK_8lb.js} +1 -1
  134. package/dist/web/assets/lsp-client-BTlK_8lb.js.br +0 -0
  135. package/dist/web/assets/lsp-client-BTlK_8lb.js.gz +0 -0
  136. package/dist/web/assets/{markdown-renderer-DbJVwfUH.js → markdown-renderer-ClGxDien.js} +1 -1
  137. package/dist/web/assets/{markdown-renderer-DzCPadpB.js → markdown-renderer-DpsToFFB.js} +1 -1
  138. package/dist/web/assets/markdown-renderer-DpsToFFB.js.br +0 -0
  139. package/dist/web/assets/markdown-renderer-DpsToFFB.js.gz +0 -0
  140. package/dist/web/assets/{mobile-explorer-sheet-BClCMXb8.js → mobile-explorer-sheet-CybJbScN.js} +1 -1
  141. package/dist/web/assets/mobile-explorer-sheet-CybJbScN.js.br +0 -0
  142. package/dist/web/assets/mobile-explorer-sheet-CybJbScN.js.gz +0 -0
  143. package/dist/web/assets/{new-design-dialog-HRP9H11v.js → new-design-dialog-9WTgcJoj.js} +1 -1
  144. package/dist/web/assets/new-design-dialog-9WTgcJoj.js.br +0 -0
  145. package/dist/web/assets/new-design-dialog-9WTgcJoj.js.gz +0 -0
  146. package/dist/web/assets/{notification-store-BomzYNQj.js → notification-store-CPVq5ec5.js} +1 -1
  147. package/dist/web/assets/notifications-settings-section-xrYII-pL.js +1 -0
  148. package/dist/web/assets/notifications-settings-section-xrYII-pL.js.br +0 -0
  149. package/dist/web/assets/notifications-settings-section-xrYII-pL.js.gz +0 -0
  150. package/dist/web/assets/{ppmbot-settings-section-BRowIIqc.js → ppmbot-settings-section-Bc46iDP9.js} +1 -1
  151. package/dist/web/assets/ppmbot-settings-section-Bc46iDP9.js.br +0 -0
  152. package/dist/web/assets/ppmbot-settings-section-Bc46iDP9.js.gz +0 -0
  153. package/dist/web/assets/{problems-panel-DdB10Ybd.js → problems-panel-D49-Xkzd.js} +1 -1
  154. package/dist/web/assets/problems-panel-D49-Xkzd.js.br +0 -0
  155. package/dist/web/assets/problems-panel-D49-Xkzd.js.gz +0 -0
  156. package/dist/web/assets/{process-table-CzLaWPe0.js → process-table-NxYTZ0n9.js} +1 -1
  157. package/dist/web/assets/process-table-NxYTZ0n9.js.br +0 -0
  158. package/dist/web/assets/process-table-NxYTZ0n9.js.gz +0 -0
  159. package/dist/web/assets/{proxy-settings-section-BCq7R5DA.js → proxy-settings-section-Exx7cQc4.js} +1 -1
  160. package/dist/web/assets/proxy-settings-section-Exx7cQc4.js.br +0 -0
  161. package/dist/web/assets/proxy-settings-section-Exx7cQc4.js.gz +0 -0
  162. package/dist/web/assets/{query-tab-DGvj_h6l.js → query-tab-BWtJPuxw.js} +1 -1
  163. package/dist/web/assets/query-tab-BWtJPuxw.js.br +0 -0
  164. package/dist/web/assets/{query-tab-DGvj_h6l.js.gz → query-tab-BWtJPuxw.js.gz} +0 -0
  165. package/dist/web/assets/{remote-access-settings-section-BrqOoOyk.js → remote-access-settings-section-C4K__DNW.js} +1 -1
  166. package/dist/web/assets/remote-access-settings-section-C4K__DNW.js.br +0 -0
  167. package/dist/web/assets/remote-access-settings-section-C4K__DNW.js.gz +0 -0
  168. package/dist/web/assets/{remote-desktop-clipboard-notice-5r6UbdlN.js → remote-desktop-clipboard-notice-DQyysBwL.js} +1 -1
  169. package/dist/web/assets/remote-desktop-clipboard-notice-DQyysBwL.js.br +0 -0
  170. package/dist/web/assets/remote-desktop-clipboard-notice-DQyysBwL.js.gz +0 -0
  171. package/dist/web/assets/{remote-desktop-mobile-sheet-B9Q4auqe.js → remote-desktop-mobile-sheet-DZtEFmgf.js} +2 -2
  172. package/dist/web/assets/remote-desktop-mobile-sheet-DZtEFmgf.js.br +0 -0
  173. package/dist/web/assets/remote-desktop-mobile-sheet-DZtEFmgf.js.gz +0 -0
  174. package/dist/web/assets/{remote-desktop-mobile-view-CL-jrkA8.js → remote-desktop-mobile-view-VW7HdPUX.js} +1 -1
  175. package/dist/web/assets/remote-desktop-mobile-view-VW7HdPUX.js.br +0 -0
  176. package/dist/web/assets/remote-desktop-mobile-view-VW7HdPUX.js.gz +0 -0
  177. package/dist/web/assets/{remote-desktop-readiness-gate-DXEf2Jnz.js → remote-desktop-readiness-gate-B3tuP9Kt.js} +1 -1
  178. package/dist/web/assets/remote-desktop-readiness-gate-B3tuP9Kt.js.br +0 -0
  179. package/dist/web/assets/remote-desktop-readiness-gate-B3tuP9Kt.js.gz +0 -0
  180. package/dist/web/assets/{remote-desktop-window-content-20P6-gKB.js → remote-desktop-window-content-n0NoDCaE.js} +1 -1
  181. package/dist/web/assets/remote-desktop-window-content-n0NoDCaE.js.br +0 -0
  182. package/dist/web/assets/remote-desktop-window-content-n0NoDCaE.js.gz +0 -0
  183. package/dist/web/assets/{rename-object-dialog-Bs7pUsUP.js → rename-object-dialog-rLTW4A55.js} +1 -1
  184. package/dist/web/assets/rename-object-dialog-rLTW4A55.js.br +0 -0
  185. package/dist/web/assets/rename-object-dialog-rLTW4A55.js.gz +0 -0
  186. package/dist/web/assets/{review-code-Bjo4sHN9.js → review-code-DNfsaNO1.js} +1 -1
  187. package/dist/web/assets/review-code-DNfsaNO1.js.br +0 -0
  188. package/dist/web/assets/review-code-DNfsaNO1.js.gz +0 -0
  189. package/dist/web/assets/{save-as-dialog-BHx0Wp2B.js → save-as-dialog-BSz8WrNZ.js} +1 -1
  190. package/dist/web/assets/save-as-dialog-BSz8WrNZ.js.br +0 -0
  191. package/dist/web/assets/save-as-dialog-BSz8WrNZ.js.gz +0 -0
  192. package/dist/web/assets/{schedules-settings-section-C6ATYDPK.js → schedules-settings-section-DqUZ-H2K.js} +1 -1
  193. package/dist/web/assets/schedules-settings-section-DqUZ-H2K.js.br +0 -0
  194. package/dist/web/assets/schedules-settings-section-DqUZ-H2K.js.gz +0 -0
  195. package/dist/web/assets/{session-review-tab-BPMUyNTx.js → session-review-tab-DKtrFb9y.js} +1 -1
  196. package/dist/web/assets/session-review-tab-DKtrFb9y.js.br +0 -0
  197. package/dist/web/assets/session-review-tab-DKtrFb9y.js.gz +0 -0
  198. package/dist/web/assets/{settings-body-Dy5D6Vu7.js → settings-body-C42xA9Dw.js} +1 -1
  199. package/dist/web/assets/settings-body-C42xA9Dw.js.br +0 -0
  200. package/dist/web/assets/settings-body-C42xA9Dw.js.gz +0 -0
  201. package/dist/web/assets/{settings-rows-BRoYE2To.js → settings-rows-C7ZatT9O.js} +1 -1
  202. package/dist/web/assets/settings-rows-C7ZatT9O.js.br +0 -0
  203. package/dist/web/assets/settings-rows-C7ZatT9O.js.gz +0 -0
  204. package/dist/web/assets/{settings-section-content-essUViKu.js → settings-section-content-B_iXJpcK.js} +2 -2
  205. package/dist/web/assets/settings-section-content-B_iXJpcK.js.br +0 -0
  206. package/dist/web/assets/settings-section-content-B_iXJpcK.js.gz +0 -0
  207. package/dist/web/assets/settings-section-content-rxfQEQ66.js +1 -0
  208. package/dist/web/assets/{settings-tab-Di1DUP1j.js → settings-tab-PRw6OpEb.js} +1 -1
  209. package/dist/web/assets/{settings-window-content-DYvYFPWy.js → settings-window-content-WITQsGfW.js} +1 -1
  210. package/dist/web/assets/{slash-command-picker-8da30mYP.js → slash-command-picker-DmDs8nOj.js} +1 -1
  211. package/dist/web/assets/slash-command-picker-DmDs8nOj.js.br +0 -0
  212. package/dist/web/assets/slash-command-picker-DmDs8nOj.js.gz +0 -0
  213. package/dist/web/assets/{sql-object-tab-DRIHVXuR.js → sql-object-tab-D6P4hzkb.js} +1 -1
  214. package/dist/web/assets/sql-object-tab-D6P4hzkb.js.br +0 -0
  215. package/dist/web/assets/sql-object-tab-D6P4hzkb.js.gz +0 -0
  216. package/dist/web/assets/{sqlite-viewer-G-Jl2yEr.js → sqlite-viewer-mUitnzHB.js} +1 -1
  217. package/dist/web/assets/sqlite-viewer-mUitnzHB.js.br +0 -0
  218. package/dist/web/assets/sqlite-viewer-mUitnzHB.js.gz +0 -0
  219. package/dist/web/assets/{structure-save-dialog-Cwikz0we.js → structure-save-dialog-CmbNlmBY.js} +1 -1
  220. package/dist/web/assets/structure-save-dialog-CmbNlmBY.js.br +0 -0
  221. package/dist/web/assets/structure-save-dialog-CmbNlmBY.js.gz +0 -0
  222. package/dist/web/assets/{structure-tab-CWEgdZPm.js → structure-tab-DCPNuFTe.js} +1 -1
  223. package/dist/web/assets/structure-tab-DCPNuFTe.js.br +0 -0
  224. package/dist/web/assets/structure-tab-DCPNuFTe.js.gz +0 -0
  225. package/dist/web/assets/{system-monitor-body-BDQm9-wb.js → system-monitor-body-BhxyqSqu.js} +2 -2
  226. package/dist/web/assets/system-monitor-body-BhxyqSqu.js.br +0 -0
  227. package/dist/web/assets/system-monitor-body-BhxyqSqu.js.gz +0 -0
  228. package/dist/web/assets/{system-monitor-tab-BouN21Yh.js → system-monitor-tab-B_miogQI.js} +1 -1
  229. package/dist/web/assets/{system-monitor-window-content-BRyWBSOb.js → system-monitor-window-content-8IogR6tR.js} +1 -1
  230. package/dist/web/assets/{tab-host-window-content-CZ55-bTz.js → tab-host-window-content-BWHQjgWZ.js} +1 -1
  231. package/dist/web/assets/tab-host-window-content-BWHQjgWZ.js.br +0 -0
  232. package/dist/web/assets/tab-host-window-content-BWHQjgWZ.js.gz +0 -0
  233. package/dist/web/assets/{table-tab-Bmn4UdBV.js → table-tab-E3YMueu_.js} +1 -1
  234. package/dist/web/assets/table-tab-E3YMueu_.js.br +0 -0
  235. package/dist/web/assets/table-tab-E3YMueu_.js.gz +0 -0
  236. package/dist/web/assets/{telegram-bot-token-field-fdHwRf39.js → telegram-bot-token-field-CwW24m62.js} +1 -1
  237. package/dist/web/assets/telegram-bot-token-field-CwW24m62.js.br +0 -0
  238. package/dist/web/assets/telegram-bot-token-field-CwW24m62.js.gz +0 -0
  239. package/dist/web/assets/{terminal-tab-D-qlZXLK.js → terminal-tab-BAe5cWEL.js} +1 -1
  240. package/dist/web/assets/terminal-tab-BAe5cWEL.js.br +0 -0
  241. package/dist/web/assets/terminal-tab-BAe5cWEL.js.gz +0 -0
  242. package/dist/web/assets/{tool-cards-BdXbQ9Fv.js → tool-cards-DrCiSH2r.js} +2 -2
  243. package/dist/web/assets/tool-cards-DrCiSH2r.js.br +0 -0
  244. package/dist/web/assets/tool-cards-DrCiSH2r.js.gz +0 -0
  245. package/dist/web/assets/{tools-settings-section-CcPaspbR.js → tools-settings-section-S-vBr2af.js} +1 -1
  246. package/dist/web/assets/tools-settings-section-S-vBr2af.js.br +0 -0
  247. package/dist/web/assets/tools-settings-section-S-vBr2af.js.gz +0 -0
  248. package/dist/web/assets/{use-inline-blame-Ck5XoSS3.js → use-inline-blame-BzVaaCCt.js} +1 -1
  249. package/dist/web/assets/use-inline-blame-BzVaaCCt.js.br +0 -0
  250. package/dist/web/assets/{use-inline-blame-Ck5XoSS3.js.gz → use-inline-blame-BzVaaCCt.js.gz} +0 -0
  251. package/dist/web/assets/{use-lsp-CGSqfFBk.js → use-lsp-BwDL9Fqk.js} +1 -1
  252. package/dist/web/assets/use-lsp-BwDL9Fqk.js.br +0 -0
  253. package/dist/web/assets/use-lsp-BwDL9Fqk.js.gz +0 -0
  254. package/dist/web/assets/{use-monaco-theme-BW05eZS4.js → use-monaco-theme-DljSc3Xo.js} +1 -1
  255. package/dist/web/assets/{use-process-kill-DJ_f7rCO.js → use-process-kill-YDcDqDtG.js} +1 -1
  256. package/dist/web/assets/use-process-kill-YDcDqDtG.js.br +0 -0
  257. package/dist/web/assets/use-process-kill-YDcDqDtG.js.gz +0 -0
  258. package/dist/web/assets/{use-sql-schema-info-wt320fVR.js → use-sql-schema-info-cAI0vn7d.js} +1 -1
  259. package/dist/web/assets/use-sql-schema-info-cAI0vn7d.js.br +0 -0
  260. package/dist/web/assets/use-sql-schema-info-cAI0vn7d.js.gz +0 -0
  261. package/dist/web/assets/{use-websocket-CTwe74Cb.js → use-websocket-Djo_ruX_.js} +1 -1
  262. package/dist/web/assets/{web-preview-tab-D4XayUEK.js → web-preview-tab-DXy0hRef.js} +1 -1
  263. package/dist/web/assets/web-preview-tab-DXy0hRef.js.br +0 -0
  264. package/dist/web/assets/web-preview-tab-DXy0hRef.js.gz +0 -0
  265. package/dist/web/index.html +2 -2
  266. package/dist/web/index.html.br +0 -0
  267. package/dist/web/index.html.gz +0 -0
  268. package/dist/web/sw.js +1 -1
  269. package/dist/web/sw.js.br +0 -0
  270. package/dist/web/sw.js.gz +0 -0
  271. package/docs/architecture/ai-chat-and-providers.md +29 -0
  272. package/docs/deployment-guide.md +39 -0
  273. package/docs/lessons-learned.md +14 -4
  274. package/package.json +1 -1
  275. package/scripts/mem-diag-report.ts +31 -0
  276. package/src/providers/claude-agent-sdk-query-options.ts +13 -2
  277. package/src/providers/claude-agent-sdk.ts +58 -18
  278. package/src/providers/claude-approval-queue.ts +75 -0
  279. package/src/providers/claude-effort-status.ts +211 -0
  280. package/src/providers/registry.ts +10 -1
  281. package/src/server/index.ts +7 -6
  282. package/src/server/middleware/access-log.ts +3 -0
  283. package/src/server/middleware/cors-headers.ts +44 -0
  284. package/src/server/routes/chat.ts +21 -1
  285. package/src/server/routes/database-impexp.ts +1 -1
  286. package/src/server/routes/design-preview.ts +2 -2
  287. package/src/server/routes/settings.ts +16 -0
  288. package/src/server/ws/chat-effort-status.ts +73 -0
  289. package/src/server/ws/chat.ts +33 -3
  290. package/src/services/compact-segment.ts +14 -19
  291. package/src/services/database/grid-export-tickets.ts +6 -2
  292. package/src/services/database/impexp/readers/file-text.ts +6 -3
  293. package/src/services/edge-forwarder.ts +12 -0
  294. package/src/services/file-chunks.ts +39 -0
  295. package/src/services/file-lines.ts +10 -17
  296. package/src/services/lsp/lsp-manager.ts +3 -0
  297. package/src/services/memory-diagnostics-native.ts +110 -0
  298. package/src/services/memory-diagnostics-report.ts +200 -0
  299. package/src/services/memory-diagnostics-requests.ts +95 -0
  300. package/src/services/memory-diagnostics-spawns.ts +242 -0
  301. package/src/services/memory-diagnostics.ts +121 -23
  302. package/src/services/memory-watchdog.ts +185 -0
  303. package/src/services/nested-subagent-spy.ts +3 -0
  304. package/src/services/process-thread-snapshot.ts +12 -2
  305. package/src/services/process-tree-memory.ts +161 -0
  306. package/src/services/read-lines.ts +16 -27
  307. package/src/services/supervisor.ts +1 -0
  308. package/src/services/terminal.service.ts +8 -0
  309. package/src/services/transcript-images-file.ts +7 -11
  310. package/src/shared/effort-status.ts +128 -0
  311. package/src/types/api.ts +3 -1
  312. package/src/types/chat.ts +8 -0
  313. package/src/web/components/chat/chat-scroll-nav.tsx +12 -8
  314. package/src/web/components/chat/chat-tab.tsx +15 -11
  315. package/src/web/components/chat/message-action-bar.tsx +19 -4
  316. package/src/web/components/chat/message-input.tsx +6 -0
  317. package/src/web/components/chat/message-list.tsx +55 -21
  318. package/src/web/components/chat/message-user-bubble.tsx +2 -2
  319. package/src/web/components/chat/model-thinking-selector-helpers.ts +79 -0
  320. package/src/web/components/chat/model-thinking-selector.tsx +36 -10
  321. package/src/web/components/chat/session-changes-context.tsx +29 -1
  322. package/src/web/components/layout/reparenting-tab.tsx +53 -14
  323. package/src/web/components/settings/ai-settings-section.tsx +32 -0
  324. package/src/web/components/settings/notifications-settings-section.tsx +14 -1
  325. package/src/web/hooks/use-chat.ts +16 -0
  326. package/src/web/hooks/use-effort-status.ts +46 -0
  327. package/src/web/hooks/use-relative-time-tick.ts +35 -0
  328. package/src/web/hooks/use-session-file-changes.ts +5 -1
  329. package/src/web/hooks/use-tab-overflow.ts +26 -13
  330. package/src/web/lib/format-date.ts +6 -1
  331. package/src/web/lib/web-push-client.ts +35 -5
  332. package/src/web/lib/web-push-support.ts +57 -4
  333. package/dist/web/assets/accounts-settings-section-DD88DRdx.js.br +0 -0
  334. package/dist/web/assets/accounts-settings-section-DD88DRdx.js.gz +0 -0
  335. package/dist/web/assets/agent-session-sheet-C0PhhLKR.js.br +0 -0
  336. package/dist/web/assets/agent-session-sheet-C0PhhLKR.js.gz +0 -0
  337. package/dist/web/assets/agent-session-window-content-D0XZgh4U.js.br +0 -0
  338. package/dist/web/assets/agent-session-window-content-D0XZgh4U.js.gz +0 -0
  339. package/dist/web/assets/ai-resource-editor-CpfQB6A7.js.br +0 -0
  340. package/dist/web/assets/ai-resource-editor-CpfQB6A7.js.gz +0 -0
  341. package/dist/web/assets/ai-settings-section-CQWBwWcM.js +0 -1
  342. package/dist/web/assets/ai-settings-section-CQWBwWcM.js.br +0 -0
  343. package/dist/web/assets/ai-settings-section-CQWBwWcM.js.gz +0 -0
  344. package/dist/web/assets/android-tab-4Z4AgHz1.js.br +0 -0
  345. package/dist/web/assets/android-tab-4Z4AgHz1.js.gz +0 -0
  346. package/dist/web/assets/appearance-settings-section-DjQjiJF7.js.br +0 -0
  347. package/dist/web/assets/appearance-settings-section-DjQjiJF7.js.gz +0 -0
  348. package/dist/web/assets/apps-panel-_lxY9xbc.js.br +0 -0
  349. package/dist/web/assets/apps-panel-_lxY9xbc.js.gz +0 -0
  350. package/dist/web/assets/branch-review-tab-BzrhnFSs.js.br +0 -0
  351. package/dist/web/assets/branch-review-tab-BzrhnFSs.js.gz +0 -0
  352. package/dist/web/assets/chat-tab-BKHepkYi.js.br +0 -0
  353. package/dist/web/assets/chat-tab-BKHepkYi.js.gz +0 -0
  354. package/dist/web/assets/chat-tab-Cv8gYzcA.js +0 -19
  355. package/dist/web/assets/chat-tab-Cv8gYzcA.js.br +0 -0
  356. package/dist/web/assets/chat-tab-Cv8gYzcA.js.gz +0 -0
  357. package/dist/web/assets/code-editor-COWmNXO4.js.br +0 -0
  358. package/dist/web/assets/code-editor-COWmNXO4.js.gz +0 -0
  359. package/dist/web/assets/codex-reset-credit-button-BHt4yJet.js.br +0 -0
  360. package/dist/web/assets/codex-reset-credit-button-BHt4yJet.js.gz +0 -0
  361. package/dist/web/assets/conflict-editor-tj-1gzKr.js.br +0 -0
  362. package/dist/web/assets/conflict-editor-tj-1gzKr.js.gz +0 -0
  363. package/dist/web/assets/connection-form-tab-BV2QX8Cf.js.br +0 -0
  364. package/dist/web/assets/connection-form-tab-BV2QX8Cf.js.gz +0 -0
  365. package/dist/web/assets/csv-preview-xhE2esgz.js.br +0 -0
  366. package/dist/web/assets/csv-preview-xhE2esgz.js.gz +0 -0
  367. package/dist/web/assets/db-tab-parts-C3MsjOID.js.br +0 -0
  368. package/dist/web/assets/db-tab-parts-C3MsjOID.js.gz +0 -0
  369. package/dist/web/assets/design-settings-section-C3LxYhIw.js.br +0 -0
  370. package/dist/web/assets/design-settings-section-C3LxYhIw.js.gz +0 -0
  371. package/dist/web/assets/design-tab-DYcvjdfb.js.br +0 -0
  372. package/dist/web/assets/design-tab-DYcvjdfb.js.gz +0 -0
  373. package/dist/web/assets/designs-sidebar-panel-Dpr4PPFT.js.br +0 -0
  374. package/dist/web/assets/designs-sidebar-panel-Dpr4PPFT.js.gz +0 -0
  375. package/dist/web/assets/diff-viewer-Fl_4jqr6.js.br +0 -0
  376. package/dist/web/assets/diff-viewer-Fl_4jqr6.js.gz +0 -0
  377. package/dist/web/assets/docx-preview-bVE9shPX.js.br +0 -0
  378. package/dist/web/assets/docx-preview-bVE9shPX.js.gz +0 -0
  379. package/dist/web/assets/editor-dialog-eEOYWdbr.js.br +0 -0
  380. package/dist/web/assets/editor-dialog-eEOYWdbr.js.gz +0 -0
  381. package/dist/web/assets/editor-language-service-D1_Ggq4s.js.br +0 -0
  382. package/dist/web/assets/editor-language-service-D1_Ggq4s.js.gz +0 -0
  383. package/dist/web/assets/explorer-body-C0UOcBPJ.js.br +0 -0
  384. package/dist/web/assets/explorer-body-C0UOcBPJ.js.gz +0 -0
  385. package/dist/web/assets/explorer-window-content-Dxee7SuJ.js.br +0 -0
  386. package/dist/web/assets/explorer-window-content-Dxee7SuJ.js.gz +0 -0
  387. package/dist/web/assets/extension-manager-section-D8krnoj8.js.br +0 -0
  388. package/dist/web/assets/extension-manager-section-D8krnoj8.js.gz +0 -0
  389. package/dist/web/assets/extension-webview-CtIdV69T.js.br +0 -0
  390. package/dist/web/assets/extension-webview-CtIdV69T.js.gz +0 -0
  391. package/dist/web/assets/files-settings-section-C8vtarR8.js.br +0 -0
  392. package/dist/web/assets/files-settings-section-C8vtarR8.js.gz +0 -0
  393. package/dist/web/assets/format-date-CSHaU2wN.js +0 -1
  394. package/dist/web/assets/general-settings-section-Chu8Ut8h.js.br +0 -0
  395. package/dist/web/assets/general-settings-section-Chu8Ut8h.js.gz +0 -0
  396. package/dist/web/assets/git-log-panel-DG09p6k5.js.br +0 -0
  397. package/dist/web/assets/git-log-panel-DG09p6k5.js.gz +0 -0
  398. package/dist/web/assets/git-review-tab-CSy8DjSC.js.br +0 -0
  399. package/dist/web/assets/git-review-tab-CSy8DjSC.js.gz +0 -0
  400. package/dist/web/assets/glide-data-grid-BN1y4BT0.js.br +0 -0
  401. package/dist/web/assets/glide-data-grid-BN1y4BT0.js.gz +0 -0
  402. package/dist/web/assets/grid-save-dialog-CfSuWw2t.js.br +0 -0
  403. package/dist/web/assets/grid-save-dialog-CfSuWw2t.js.gz +0 -0
  404. package/dist/web/assets/group-chat-tab-B04QMp7A.js.br +0 -0
  405. package/dist/web/assets/group-chat-tab-B04QMp7A.js.gz +0 -0
  406. package/dist/web/assets/impexp-tab-BRNouquR.js.br +0 -0
  407. package/dist/web/assets/impexp-tab-BRNouquR.js.gz +0 -0
  408. package/dist/web/assets/index-BpgSIM5B.js.br +0 -0
  409. package/dist/web/assets/index-BpgSIM5B.js.gz +0 -0
  410. package/dist/web/assets/keyboard-shortcuts-section-BKDyZHhK.js.br +0 -0
  411. package/dist/web/assets/keyboard-shortcuts-section-BKDyZHhK.js.gz +0 -0
  412. package/dist/web/assets/language-servers-section-CbbkezhA.js.br +0 -0
  413. package/dist/web/assets/language-servers-section-CbbkezhA.js.gz +0 -0
  414. package/dist/web/assets/logs-app-Blr1-v4q.js.br +0 -0
  415. package/dist/web/assets/logs-app-Blr1-v4q.js.gz +0 -0
  416. package/dist/web/assets/lsp-client-Ds3U2O52.js.br +0 -0
  417. package/dist/web/assets/lsp-client-Ds3U2O52.js.gz +0 -0
  418. package/dist/web/assets/markdown-renderer-DzCPadpB.js.br +0 -0
  419. package/dist/web/assets/markdown-renderer-DzCPadpB.js.gz +0 -0
  420. package/dist/web/assets/mobile-explorer-sheet-BClCMXb8.js.br +0 -0
  421. package/dist/web/assets/mobile-explorer-sheet-BClCMXb8.js.gz +0 -0
  422. package/dist/web/assets/new-design-dialog-HRP9H11v.js.br +0 -0
  423. package/dist/web/assets/new-design-dialog-HRP9H11v.js.gz +0 -0
  424. package/dist/web/assets/notifications-settings-section-CYTTQaNr.js +0 -1
  425. package/dist/web/assets/notifications-settings-section-CYTTQaNr.js.br +0 -0
  426. package/dist/web/assets/notifications-settings-section-CYTTQaNr.js.gz +0 -0
  427. package/dist/web/assets/ppmbot-settings-section-BRowIIqc.js.br +0 -0
  428. package/dist/web/assets/ppmbot-settings-section-BRowIIqc.js.gz +0 -0
  429. package/dist/web/assets/problems-panel-DdB10Ybd.js.br +0 -0
  430. package/dist/web/assets/problems-panel-DdB10Ybd.js.gz +0 -0
  431. package/dist/web/assets/process-table-CzLaWPe0.js.br +0 -0
  432. package/dist/web/assets/process-table-CzLaWPe0.js.gz +0 -0
  433. package/dist/web/assets/proxy-settings-section-BCq7R5DA.js.br +0 -0
  434. package/dist/web/assets/proxy-settings-section-BCq7R5DA.js.gz +0 -0
  435. package/dist/web/assets/query-tab-DGvj_h6l.js.br +0 -0
  436. package/dist/web/assets/remote-access-settings-section-BrqOoOyk.js.br +0 -0
  437. package/dist/web/assets/remote-access-settings-section-BrqOoOyk.js.gz +0 -0
  438. package/dist/web/assets/remote-desktop-clipboard-notice-5r6UbdlN.js.br +0 -0
  439. package/dist/web/assets/remote-desktop-clipboard-notice-5r6UbdlN.js.gz +0 -0
  440. package/dist/web/assets/remote-desktop-mobile-sheet-B9Q4auqe.js.br +0 -0
  441. package/dist/web/assets/remote-desktop-mobile-sheet-B9Q4auqe.js.gz +0 -0
  442. package/dist/web/assets/remote-desktop-mobile-view-CL-jrkA8.js.br +0 -0
  443. package/dist/web/assets/remote-desktop-mobile-view-CL-jrkA8.js.gz +0 -0
  444. package/dist/web/assets/remote-desktop-readiness-gate-DXEf2Jnz.js.br +0 -0
  445. package/dist/web/assets/remote-desktop-readiness-gate-DXEf2Jnz.js.gz +0 -0
  446. package/dist/web/assets/remote-desktop-window-content-20P6-gKB.js.br +0 -0
  447. package/dist/web/assets/remote-desktop-window-content-20P6-gKB.js.gz +0 -0
  448. package/dist/web/assets/rename-object-dialog-Bs7pUsUP.js.br +0 -0
  449. package/dist/web/assets/rename-object-dialog-Bs7pUsUP.js.gz +0 -0
  450. package/dist/web/assets/review-code-Bjo4sHN9.js.br +0 -0
  451. package/dist/web/assets/review-code-Bjo4sHN9.js.gz +0 -0
  452. package/dist/web/assets/save-as-dialog-BHx0Wp2B.js.br +0 -0
  453. package/dist/web/assets/save-as-dialog-BHx0Wp2B.js.gz +0 -0
  454. package/dist/web/assets/schedules-settings-section-C6ATYDPK.js.br +0 -0
  455. package/dist/web/assets/schedules-settings-section-C6ATYDPK.js.gz +0 -0
  456. package/dist/web/assets/session-review-tab-BPMUyNTx.js.br +0 -0
  457. package/dist/web/assets/session-review-tab-BPMUyNTx.js.gz +0 -0
  458. package/dist/web/assets/settings-body-Dy5D6Vu7.js.br +0 -0
  459. package/dist/web/assets/settings-body-Dy5D6Vu7.js.gz +0 -0
  460. package/dist/web/assets/settings-rows-BRoYE2To.js.br +0 -0
  461. package/dist/web/assets/settings-rows-BRoYE2To.js.gz +0 -0
  462. package/dist/web/assets/settings-section-content-C4DX7TYv.js +0 -1
  463. package/dist/web/assets/settings-section-content-essUViKu.js.br +0 -0
  464. package/dist/web/assets/settings-section-content-essUViKu.js.gz +0 -0
  465. package/dist/web/assets/slash-command-picker-8da30mYP.js.br +0 -0
  466. package/dist/web/assets/slash-command-picker-8da30mYP.js.gz +0 -0
  467. package/dist/web/assets/sql-object-tab-DRIHVXuR.js.br +0 -0
  468. package/dist/web/assets/sql-object-tab-DRIHVXuR.js.gz +0 -0
  469. package/dist/web/assets/sqlite-viewer-G-Jl2yEr.js.br +0 -0
  470. package/dist/web/assets/sqlite-viewer-G-Jl2yEr.js.gz +0 -0
  471. package/dist/web/assets/structure-save-dialog-Cwikz0we.js.br +0 -0
  472. package/dist/web/assets/structure-save-dialog-Cwikz0we.js.gz +0 -0
  473. package/dist/web/assets/structure-tab-CWEgdZPm.js.br +0 -0
  474. package/dist/web/assets/structure-tab-CWEgdZPm.js.gz +0 -0
  475. package/dist/web/assets/system-monitor-body-BDQm9-wb.js.br +0 -0
  476. package/dist/web/assets/system-monitor-body-BDQm9-wb.js.gz +0 -0
  477. package/dist/web/assets/tab-host-window-content-CZ55-bTz.js.br +0 -0
  478. package/dist/web/assets/tab-host-window-content-CZ55-bTz.js.gz +0 -0
  479. package/dist/web/assets/table-tab-Bmn4UdBV.js.br +0 -0
  480. package/dist/web/assets/table-tab-Bmn4UdBV.js.gz +0 -0
  481. package/dist/web/assets/telegram-bot-token-field-fdHwRf39.js.br +0 -0
  482. package/dist/web/assets/telegram-bot-token-field-fdHwRf39.js.gz +0 -0
  483. package/dist/web/assets/terminal-tab-D-qlZXLK.js.br +0 -0
  484. package/dist/web/assets/terminal-tab-D-qlZXLK.js.gz +0 -0
  485. package/dist/web/assets/tool-cards-BdXbQ9Fv.js.br +0 -0
  486. package/dist/web/assets/tool-cards-BdXbQ9Fv.js.gz +0 -0
  487. package/dist/web/assets/tools-settings-section-CcPaspbR.js.br +0 -0
  488. package/dist/web/assets/tools-settings-section-CcPaspbR.js.gz +0 -0
  489. package/dist/web/assets/use-inline-blame-Ck5XoSS3.js.br +0 -0
  490. package/dist/web/assets/use-lsp-CGSqfFBk.js.br +0 -0
  491. package/dist/web/assets/use-lsp-CGSqfFBk.js.gz +0 -0
  492. package/dist/web/assets/use-process-kill-DJ_f7rCO.js.br +0 -0
  493. package/dist/web/assets/use-process-kill-DJ_f7rCO.js.gz +0 -0
  494. package/dist/web/assets/use-sql-schema-info-wt320fVR.js.br +0 -0
  495. package/dist/web/assets/use-sql-schema-info-wt320fVR.js.gz +0 -0
  496. package/dist/web/assets/web-preview-tab-D4XayUEK.js.br +0 -0
  497. package/dist/web/assets/web-preview-tab-D4XayUEK.js.gz +0 -0
@@ -15,29 +15,35 @@ export function useTabOverflow(scrollRef: RefObject<HTMLDivElement | null>): Tab
15
15
  const [canScrollLeft, setCanScrollLeft] = useState(false);
16
16
  const [canScrollRight, setCanScrollRight] = useState(false);
17
17
 
18
- const updateScroll = useCallback(() => {
19
- const el = scrollRef.current;
20
- if (!el) return;
21
- setCanScrollLeft(el.scrollLeft > 1);
22
- setCanScrollRight(el.scrollLeft + el.clientWidth < el.scrollWidth - 1);
23
- }, [scrollRef]);
24
-
25
18
  useEffect(() => {
26
19
  const el = scrollRef.current;
27
20
  if (!el) return;
28
- updateScroll();
29
- el.addEventListener("scroll", updateScroll, { passive: true });
30
- const ro = new ResizeObserver(updateScroll);
21
+ // Measured once a frame, whatever asked. The mutation observer fires straight after a
22
+ // commit, where reading a width lays out the whole page — on a project switch that is
23
+ // every transcript just put back on screen, and once per commit rather than once.
24
+ let frame = 0;
25
+ const update = () => {
26
+ frame = 0;
27
+ setCanScrollLeft(el.scrollLeft > 1);
28
+ setCanScrollRight(el.scrollLeft + el.clientWidth < el.scrollWidth - 1);
29
+ };
30
+ const schedule = () => {
31
+ if (!frame) frame = requestAnimationFrame(update);
32
+ };
33
+ schedule();
34
+ el.addEventListener("scroll", schedule, { passive: true });
35
+ const ro = new ResizeObserver(schedule);
31
36
  ro.observe(el);
32
37
  // Also observe children changes (tabs added/removed)
33
- const mo = new MutationObserver(updateScroll);
38
+ const mo = new MutationObserver(schedule);
34
39
  mo.observe(el, { childList: true, subtree: true });
35
40
  return () => {
36
- el.removeEventListener("scroll", updateScroll);
41
+ cancelAnimationFrame(frame);
42
+ el.removeEventListener("scroll", schedule);
37
43
  ro.disconnect();
38
44
  mo.disconnect();
39
45
  };
40
- }, [scrollRef, updateScroll]);
46
+ }, [scrollRef]);
41
47
 
42
48
  const scrollLeft = useCallback(() => {
43
49
  scrollRef.current?.scrollBy({ left: -150, behavior: "smooth" });
@@ -64,6 +70,13 @@ export function getHiddenUnreadDirection(
64
70
  notifications: Map<string, { count: number; type: string }>,
65
71
  ): { left: string | null; right: string | null } {
66
72
  if (!scrollEl) return { left: null, right: null };
73
+ // Called while the tab bar renders, where any geometry read is a forced layout: none at all
74
+ // unless some chat tab here has something unread.
75
+ const unread = tabs.some((tab) => {
76
+ const sessionId = tab.type === "chat" ? tab.metadata?.sessionId as string | undefined : undefined;
77
+ return !!sessionId && (notifications.get(sessionId)?.count ?? 0) > 0;
78
+ });
79
+ if (!unread) return { left: null, right: null };
67
80
  const viewLeft = scrollEl.scrollLeft;
68
81
  const viewRight = viewLeft + scrollEl.clientWidth;
69
82
  let leftType: string | null = null;
@@ -1,3 +1,7 @@
1
+ // Given options, `toLocaleDateString` builds a new formatter on every call — the hottest line
2
+ // when a long chat redraws its timestamps.
3
+ let shortDate: Intl.DateTimeFormat | undefined;
4
+
1
5
  /**
2
6
  * Format an ISO timestamp as a short English relative time string.
3
7
  * Examples: "just now", "5m ago", "3h ago", "2d ago", "Apr 21".
@@ -14,7 +18,8 @@ export function formatRelativeDate(iso: string): string {
14
18
  if (diffHr < 24) return `${diffHr}h ago`;
15
19
  const diffDay = Math.floor(diffHr / 24);
16
20
  if (diffDay < 7) return `${diffDay}d ago`;
17
- return date.toLocaleDateString(undefined, { month: "short", day: "numeric" });
21
+ shortDate ??= new Intl.DateTimeFormat(undefined, { month: "short", day: "numeric" });
22
+ return shortDate.format(date);
18
23
  } catch {
19
24
  return "";
20
25
  }
@@ -6,11 +6,15 @@ import { api } from "@/lib/api-client";
6
6
  import type { PushDeviceInfo } from "../../shared/notification-settings";
7
7
  import {
8
8
  PUSH_BLOCKED_MESSAGE,
9
+ PUSH_SUBSCRIBE_DEADLINE_MS,
9
10
  base64UrlToBytes,
11
+ browserNameFrom,
10
12
  bytesToBase64Url,
11
13
  deviceLabelFrom,
12
14
  isIosDevice,
15
+ pushServiceFailureMessage,
13
16
  pushSupportFrom,
17
+ withinDeadline,
14
18
  type PushSupport,
15
19
  } from "./web-push-support";
16
20
 
@@ -18,6 +22,20 @@ function ipadOs(): boolean {
18
22
  return navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1;
19
23
  }
20
24
 
25
+ /**
26
+ * The browser a push failure names. Brave says "Chrome" in its user agent; Vivaldi and Chromium
27
+ * do too, but list no Chrome brand, so they get "This browser" rather than a guess.
28
+ * `userAgentData` exists only in a secure context, and so does every use of this answer:
29
+ * `pushSupportFrom` stops at plain HTTP before it reads the browser.
30
+ */
31
+ function thisBrowser(): string {
32
+ if ("brave" in navigator) return "Brave";
33
+ const name = browserNameFrom(navigator.userAgent);
34
+ const brands = (navigator as Navigator & { userAgentData?: { brands: { brand: string }[] } }).userAgentData?.brands;
35
+ if (name === "Chrome" && brands && !brands.some((b) => b.brand === "Google Chrome")) return "Browser";
36
+ return name;
37
+ }
38
+
21
39
  export function pushSupport(): PushSupport {
22
40
  return pushSupportFrom({
23
41
  secure: window.isSecureContext,
@@ -28,11 +46,17 @@ export function pushSupport(): PushSupport {
28
46
  standalone: window.matchMedia?.("(display-mode: standalone)").matches
29
47
  || (navigator as Navigator & { standalone?: boolean }).standalone === true,
30
48
  permission: "Notification" in window ? Notification.permission : null,
49
+ browser: thisBrowser(),
31
50
  });
32
51
  }
33
52
 
53
+ /**
54
+ * Not `thisBrowser()`: a device list wants a name the user recognises, so a Chromium build with
55
+ * no Chrome brand (Vivaldi, Chromium) stays "Chrome" here. A push failure names the browser's
56
+ * push service, and there a wrong guess sends the user after the wrong one.
57
+ */
34
58
  export function thisDeviceLabel(): string {
35
- return deviceLabelFrom(navigator.userAgent, ipadOs());
59
+ return deviceLabelFrom(navigator.userAgent, ipadOs(), "brave" in navigator ? "Brave" : undefined);
36
60
  }
37
61
 
38
62
  /** This browser's subscription, if it has one. Never prompts. */
@@ -68,10 +92,16 @@ export async function enablePush(publicKey: string): Promise<PushDeviceInfo> {
68
92
  await subscription.unsubscribe();
69
93
  subscription = null;
70
94
  }
71
- subscription ??= await registration.pushManager.subscribe({
72
- userVisibleOnly: true,
73
- applicationServerKey: base64UrlToBytes(publicKey),
74
- });
95
+ try {
96
+ subscription ??= await withinDeadline(registration.pushManager.subscribe({
97
+ userVisibleOnly: true,
98
+ applicationServerKey: base64UrlToBytes(publicKey),
99
+ }), PUSH_SUBSCRIBE_DEADLINE_MS);
100
+ } catch (e) {
101
+ const hint = pushServiceFailureMessage(thisBrowser(), e);
102
+ if (hint) throw new Error(hint);
103
+ throw e;
104
+ }
75
105
  return api.post<PushDeviceInfo>("/api/notifications/push/subscribe", {
76
106
  subscription: subscription.toJSON(),
77
107
  label: thisDeviceLabel(),
@@ -14,6 +14,8 @@ export interface PushEnvironment {
14
14
  /** Opened from the Home Screen rather than in a browser tab. */
15
15
  standalone: boolean;
16
16
  permission: NotificationPermission | null;
17
+ /** `browserNameFrom`, or "Brave". */
18
+ browser?: string;
17
19
  }
18
20
 
19
21
  export type PushSupport =
@@ -40,27 +42,78 @@ export function pushSupportFrom(env: PushEnvironment): PushSupport {
40
42
  };
41
43
  }
42
44
  if (!env.serviceWorker || !env.pushManager || !env.notification) {
45
+ // Firefox hides PushManager, and nothing else, when `dom.push.enabled` is false.
46
+ if (env.browser === "Firefox" && env.serviceWorker && env.notification) {
47
+ return {
48
+ state: "unavailable",
49
+ message: "Push is turned off in this browser. Open about:config, set dom.push.enabled to true, then restart the browser.",
50
+ };
51
+ }
43
52
  return { state: "unavailable", message: "This browser cannot receive push notifications." };
44
53
  }
45
54
  if (env.permission === "denied") return { state: "blocked", message: PUSH_BLOCKED_MESSAGE };
46
55
  return { state: "available" };
47
56
  }
48
57
 
58
+ /**
59
+ * The first subscribe after a browser starts took ~30 s in Chrome and Brave (3 s once
60
+ * running). A push service the network blocks may never answer: with Google's hosts
61
+ * unresolvable, Chrome kept retrying for minutes and never rejected.
62
+ */
63
+ export const PUSH_SUBSCRIBE_DEADLINE_MS = 60_000;
64
+
65
+ export function withinDeadline<T>(promise: Promise<T>, ms: number): Promise<T> {
66
+ let timer: ReturnType<typeof setTimeout> | undefined;
67
+ const deadline = new Promise<never>((_, reject) => {
68
+ timer = setTimeout(() => reject(new DOMException("The push service did not answer.", "TimeoutError")), ms);
69
+ });
70
+ return Promise.race([promise, deadline]).finally(() => clearTimeout(timer));
71
+ }
72
+
73
+ /** Whose push service each browser registers with, where that is the same on every platform. */
74
+ const PUSH_SERVICE_OWNER: Record<string, string> = { Brave: "Google", Chrome: "Google", Firefox: "Mozilla", Safari: "Apple" };
75
+
76
+ /**
77
+ * What to do when `pushManager.subscribe` fails because of the push service, or null for
78
+ * any other failure. A browser reports a service it cannot use as an AbortError.
79
+ */
80
+ export function pushServiceFailureMessage(browser: string, error: unknown): string | null {
81
+ const { name, message } = (error ?? {}) as { name?: unknown; message?: unknown };
82
+ if (name !== "AbortError" && name !== "TimeoutError") return null;
83
+ // Brave turns Google's push service off by default and rejects at once.
84
+ if (browser === "Brave" && name === "AbortError") {
85
+ return "Brave keeps push off until you allow it: open brave://settings/privacy, turn on “Use Google services for push messaging”, restart Brave, then turn this on again.";
86
+ }
87
+ const owner = PUSH_SERVICE_OWNER[browser];
88
+ const service = owner ? `${owner}'s push service` : "its push service";
89
+ const failed = name === "TimeoutError" ? `got no answer from ${service} within a minute` : `could not register with ${service}`;
90
+ const said = name === "AbortError" && typeof message === "string" && message ? ` (${message})` : "";
91
+ return `${browser === "Browser" ? "This browser" : browser} ${failed}${said}. `
92
+ + `A firewall, VPN, DNS filter or ad blocker may be blocking it${owner ? "" : ", or push is turned off in this browser"}. `
93
+ + "Telegram and ntfy below work without it.";
94
+ }
95
+
49
96
  /** iPadOS reports itself as a Mac; a Mac has no touch screen. */
50
97
  export function isIosDevice(userAgent: string, platform: string, maxTouchPoints: number): boolean {
51
98
  return /iPhone|iPad|iPod/.test(userAgent) || (platform === "MacIntel" && maxTouchPoints > 1);
52
99
  }
53
100
 
54
- /** "Chrome on Android" — enough to tell a phone from a laptop in the list. */
55
- export function deviceLabelFrom(userAgent: string, ipadOs = false): string {
56
- const browser =
57
- /Edg(A|iOS)?\//.test(userAgent) ? "Edge"
101
+ /** Brave and most other Chromium builds say "Chrome"; the user agent cannot tell them apart. */
102
+ export function browserNameFrom(userAgent: string): string {
103
+ return /Edg(A|iOS)?\//.test(userAgent) ? "Edge"
58
104
  : /OPR\//.test(userAgent) ? "Opera"
59
105
  : /SamsungBrowser\//.test(userAgent) ? "Samsung Internet"
60
106
  : /Firefox\/|FxiOS\//.test(userAgent) ? "Firefox"
61
107
  : /Chrome\/|CriOS\//.test(userAgent) ? "Chrome"
62
108
  : /Safari\//.test(userAgent) ? "Safari"
63
109
  : "Browser";
110
+ }
111
+
112
+ /**
113
+ * "Chrome on Android" — enough to tell a phone from a laptop in the list. `browser` is for
114
+ * what the user agent cannot say: Brave's is Chrome's.
115
+ */
116
+ export function deviceLabelFrom(userAgent: string, ipadOs = false, browser = browserNameFrom(userAgent)): string {
64
117
  const os =
65
118
  /Android/.test(userAgent) ? "Android"
66
119
  : /iPhone|iPod/.test(userAgent) ? "iPhone"
@@ -1 +0,0 @@
1
- import{s as e}from"./rolldown-runtime-C5c2KzVm.js";import{D as t,E as n}from"./vendor-markdown-C-P1aR4p.js";import{Kr as r,gt as i,hr as a,r as o}from"./icons-BwyIKaTT.js";import{r as s}from"./api-client-xQDlhUTu.js";import{t as c}from"./open-settings-EXR4zoZG.js";import{t as l}from"./button-C9ZXWb3b.js";import{t as u}from"./input-C3oVNCMq.js";import{Ai as d,Er as f,Gn as p,Hn as m,Kn as h,Pn as g,Un as _,Vn as v,Wn as y}from"./index-BpgSIM5B.js";import{a as b,b as x}from"./api-settings-vmIRFNwZ.js";var S=e(t(),1),C=n(),w=[128e3,272e3,4e5,512e3,872e3,1e6],T=[1e5,2e5,23e4,35e4,45e4,75e4,9e5];function E({id:e,label:t,value:n,presets:r,disabled:i,compact:a,onChange:o}){let[s,c]=(0,S.useState)(!!n&&!r.includes(Number(n))),l=a?`text-[11px]`:`text-sm`;return(0,C.jsxs)(`div`,{className:`space-y-1`,children:[(0,C.jsx)(f,{htmlFor:e,className:l,children:t}),(0,C.jsxs)(`select`,{id:e,value:s?`custom`:n||`default`,disabled:i,"aria-describedby":`codex-context-help`,className:`w-full min-h-11 sm:min-h-0 rounded-md border border-input bg-background px-3 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50 ${a?`h-7`:`h-9`} ${l}`,onChange:e=>{let t=e.target.value;c(t===`custom`),t!==`custom`&&o(t===`default`?``:t)},children:[(0,C.jsx)(`option`,{value:`default`,children:`Codex default`}),r.map(e=>(0,C.jsxs)(`option`,{value:String(e),children:[e===1e6?`1M`:`${e/1e3}K`,` tokens`]},e)),(0,C.jsx)(`option`,{value:`custom`,children:`Custom...`})]}),s&&(0,C.jsx)(u,{id:`${e}-custom`,"aria-label":`Custom ${t.toLowerCase()}`,type:`number`,min:1,step:1,required:!0,value:n,disabled:i,placeholder:`Enter tokens`,"aria-describedby":`codex-context-help`,className:`min-h-11 sm:min-h-0 ${a?`h-7 text-[11px]`:``}`,onChange:e=>o(e.target.value)})]})}function D({config:e,compact:t,saving:n,onSave:r}){let[i,a]=(0,S.useState)(String(e?.model_context_window??``)),[o,s]=(0,S.useState)(String(e?.model_auto_compact_token_limit??``)),[c,l]=(0,S.useState)(null),u=t?`text-[11px]`:`text-sm`,d=t?`text-[9px]`:`text-[11px]`;async function f(e){e.preventDefault();let t=i.trim()?Number(i):null,n=o.trim()?Number(o):null;if([t,n].some(e=>e!==null&&(!Number.isSafeInteger(e)||e<=0))){l(`Enter positive whole numbers of tokens, or leave blank for Codex defaults.`);return}if(t!==null&&n!==null&&n>t){l(`Auto-compact threshold must not exceed the context window.`);return}l(null),await r({model_context_window:t,model_auto_compact_token_limit:n})}return(0,C.jsxs)(`form`,{onSubmit:f,className:`space-y-2 rounded-md border border-border p-3`,children:[(0,C.jsxs)(`div`,{className:`grid grid-cols-1 gap-3 sm:grid-cols-2`,children:[(0,C.jsx)(E,{id:`codex-context-window`,label:`Context window (tokens)`,value:i,presets:w,disabled:n,compact:t,onChange:e=>{a(e),l(null)}}),(0,C.jsx)(E,{id:`codex-compact-threshold`,label:`Auto-compact threshold (tokens)`,value:o,presets:T,disabled:n,compact:t,onChange:e=>{s(e),l(null)}})]}),(0,C.jsx)(`p`,{id:`codex-context-help`,className:`${d} text-muted-foreground`,children:`Choose Codex default to use Codex configuration and model defaults, or Custom to enter a value. Presets are shortcuts, not a list of limits supported by your model; increasing these values does not unlock a larger context window. Applies to new sessions and sessions resumed after a PPM restart.`}),c&&(0,C.jsx)(`p`,{role:`alert`,className:`${u} text-error`,children:c}),(0,C.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,C.jsx)(`a`,{href:`https://learn.chatgpt.com/docs/config-file/config-reference`,target:`_blank`,rel:`noreferrer`,className:`${d} text-primary underline`,children:`Codex context documentation`}),(0,C.jsx)(`button`,{type:`submit`,disabled:n,className:`min-h-11 sm:min-h-0 rounded-md border border-border px-3 py-1.5 hover:bg-surface-elevated disabled:opacity-50 ${u}`,children:n?`Saving...`:`Save context settings`})]})]})}var O=[{value:`low`,label:`Low`},{value:`medium`,label:`Medium`},{value:`high`,label:`High`},{value:`xhigh`,label:`Extra`},{value:`max`,label:`Max`}],k=[{value:`bypassPermissions`,label:`Bypass permissions (default)`},{value:`default`,label:`Ask before edits`},{value:`acceptEdits`,label:`Edit automatically`},{value:`plan`,label:`Plan mode`}],A={claude:`Claude`,cursor:`Cursor`,codex:`Codex`,gemini:`Gemini`};function j({compact:e}={}){let[t,n]=(0,S.useState)(null),[r,w]=(0,S.useState)(``),[T,E]=(0,S.useState)([]),[j,M]=(0,S.useState)(!1),[N,P]=(0,S.useState)(!1),[F,I]=(0,S.useState)(null),[L,R]=(0,S.useState)(0),[z,B]=(0,S.useState)([]),[V,H]=(0,S.useState)(!1);(0,S.useEffect)(()=>{b().then(e=>{n(e),w(e.default_provider??`claude`)}).catch(e=>I(e.message))},[]),(0,S.useEffect)(()=>{r&&s.get(`/api/settings/ai/providers/status`).then(B).catch(()=>B([]))},[r]);let U=z.find(e=>e.id===r&&!e.registered);(0,S.useEffect)(()=>{r&&(M(!0),s.get(`/api/settings/ai/providers/${r}/models`).then(E).catch(()=>E([])).finally(()=>M(!1)))},[r,!U]);let W=async()=>{H(!0);try{let e=await s.post(`/api/settings/ai/providers/${r}/probe`);B(t=>t.map(t=>t.id===e.id?e:t))}catch(e){I(e.message)}finally{H(!1)}},G=t?Object.keys(t.providers).filter(e=>e!==`mock`).map(e=>({id:e,name:A[e]??e})):[],K=t?.providers[r],q=K?.type===`agent-sdk`||!K?.type&&r===`claude`,J=async e=>{if(!t)return!1;P(!0),I(null);try{return n(await x(e)),R(e=>e+1),!0}catch(e){return I(e.message),!1}finally{P(!1)}},Y=(e,t)=>J({providers:{[r]:{[e]:t}}}),X=e?`text-[11px]`:`text-sm`,Z=e?`text-xs`:`text-sm`,te=e?`space-y-2`:`space-y-4`,Q=e?`space-y-1.5`:`space-y-3`,$=e?`space-y-1`:`space-y-1.5`;if(!t)return(0,C.jsxs)(`div`,{className:Q,children:[(0,C.jsx)(`h3`,{className:`${Z} font-medium text-text-secondary`,children:`AI Settings`}),(0,C.jsx)(`p`,{className:`${X} text-text-subtle`,children:F?`Error: ${F}`:`Loading...`})]});let ne=q?T:[{value:`__default__`,label:`Auto (default)`},...T];return(0,C.jsxs)(`div`,{className:te,children:[(0,C.jsx)(`h3`,{className:`${Z} font-medium text-text-secondary`,children:`AI Settings`}),(0,C.jsxs)(`div`,{className:$,children:[(0,C.jsx)(f,{htmlFor:`ai-new-chat-provider`,className:e?X:void 0,children:`New chat provider`}),(0,C.jsxs)(v,{value:t.new_chat_provider_mode??`default`,disabled:N,onValueChange:e=>J({new_chat_provider_mode:e}),children:[(0,C.jsx)(y,{id:`ai-new-chat-provider`,className:`w-full ${e?`h-7 text-[11px]`:``}`,children:(0,C.jsx)(p,{})}),(0,C.jsxs)(m,{children:[(0,C.jsx)(_,{value:`follow-focus`,children:`Follow last focused chat`}),(0,C.jsx)(_,{value:`default`,children:`Always use default provider`})]})]}),(0,C.jsx)(`p`,{className:`${e?`text-[9px]`:`text-[11px]`} text-muted-foreground`,children:t.new_chat_provider_mode===`follow-focus`?`New tabs follow the last chat you focused in this project, across panels. Existing tabs keep their provider.`:`New tabs always use the default provider. Existing tabs keep their provider.`})]}),(0,C.jsxs)(`div`,{className:$,children:[(0,C.jsx)(f,{htmlFor:`ai-default-provider`,className:e?X:void 0,children:`Default provider`}),(0,C.jsxs)(v,{value:t.default_provider,disabled:N,onValueChange:e=>J({default_provider:e}),children:[(0,C.jsx)(y,{id:`ai-default-provider`,className:`w-full ${e?`h-7 text-[11px]`:``}`,children:(0,C.jsx)(p,{})}),(0,C.jsx)(m,{children:G.map(e=>(0,C.jsx)(_,{value:e.id,children:e.name},e.id))})]}),t.new_chat_provider_mode===`follow-focus`&&(0,C.jsx)(`p`,{className:`${e?`text-[9px]`:`text-[11px]`} text-muted-foreground`,children:`Used when no chat has been focused in this project yet.`})]}),(0,C.jsxs)(`div`,{className:`flex items-start justify-between gap-3 rounded-md border border-border p-3`,children:[(0,C.jsxs)(`div`,{className:$,children:[(0,C.jsx)(f,{htmlFor:`ai-share-provider-context`,className:e?X:void 0,children:`Share rules and memory between providers`}),(0,C.jsx)(`p`,{id:`ai-share-provider-context-description`,className:`${e?`text-[9px]`:`text-[11px]`} text-muted-foreground`,children:`Share project rules and memory, plus global instruction files, across providers. Applies from the next project-chat message. Turning off keeps context already sent.`})]}),(0,C.jsx)(h,{id:`ai-share-provider-context`,"aria-describedby":`ai-share-provider-context-description`,checked:t.share_provider_context??!0,disabled:N,onCheckedChange:e=>J({share_provider_context:e})})]}),G.length>1&&(0,C.jsx)(`div`,{className:`flex gap-0.5 border-b border-border/50 -mx-1 px-1`,children:G.map(e=>(0,C.jsxs)(`button`,{onClick:()=>w(e.id),className:`flex items-center gap-1 px-2 py-1 text-[11px] rounded-t transition-colors ${r===e.id?`text-primary border-b-2 border-primary font-medium`:`text-text-subtle hover:text-text-secondary`}`,children:[(0,C.jsx)(d,{providerId:e.id}),(0,C.jsx)(`span`,{className:`capitalize`,children:e.name})]},e.id))}),(0,C.jsxs)(`div`,{className:Q,children:[U&&(0,C.jsxs)(`div`,{className:`flex items-start gap-2 rounded-md border border-warning/30 bg-warning/5 px-2.5 py-2`,children:[(0,C.jsx)(o,{className:`size-3.5 text-warning shrink-0 mt-0.5`}),(0,C.jsxs)(`div`,{className:`min-w-0 flex-1 space-y-1.5`,children:[(0,C.jsxs)(`p`,{className:`${X} text-text-secondary`,children:[A[r]??r,` is not available in chat — PPM could not start it.`]}),(0,C.jsx)(`p`,{className:`text-[11px] text-muted-foreground break-words`,children:U.reason}),U.nextProbeAt&&(0,C.jsxs)(`p`,{className:`text-[11px] text-text-subtle`,children:[`Checking again at `,new Date(U.nextProbeAt).toLocaleTimeString()]}),(0,C.jsxs)(l,{variant:`outline`,size:`sm`,onClick:W,disabled:V,className:`gap-1.5 cursor-pointer min-h-11 md:min-h-8`,children:[(0,C.jsx)(a,{className:`size-3.5 ${V?`animate-spin`:``}`}),V?`Checking...`:`Check again`]})]})]}),r===`codex`&&(0,C.jsxs)(`button`,{type:`button`,onClick:()=>c(`accounts`),className:`w-full flex items-center justify-between gap-2 rounded-md border border-border px-2.5 py-2 text-left cursor-pointer hover:bg-surface-elevated transition-colors`,children:[(0,C.jsx)(`span`,{className:`${X} text-text-secondary`,children:`Codex accounts & login`}),(0,C.jsx)(i,{className:`size-3.5 text-text-subtle shrink-0`})]}),T.length>0&&(0,C.jsxs)(`div`,{className:$,children:[(0,C.jsx)(f,{htmlFor:`ai-model`,className:e?X:void 0,children:`Model`}),(0,C.jsxs)(v,{value:q?K?.model??T[0]?.value:K?.model||`__default__`,onValueChange:e=>Y(`model`,e===`__default__`?void 0:e),disabled:j,children:[(0,C.jsx)(y,{id:`ai-model`,className:`w-full ${e?`h-7 text-[11px]`:``}`,children:(0,C.jsx)(p,{placeholder:j?`Loading models...`:`Select model`})}),(0,C.jsx)(m,{className:`max-h-[300px]`,children:ne.map(e=>(0,C.jsx)(_,{value:e.value,children:e.label},e.value))})]})]}),r===`codex`&&(0,C.jsx)(D,{config:K,compact:e,saving:N,onSave:e=>J({providers:{codex:e}})},JSON.stringify([K?.model_context_window,K?.model_auto_compact_token_limit])),q&&(0,C.jsxs)(C.Fragment,{children:[(0,C.jsxs)(`div`,{className:$,children:[(0,C.jsx)(f,{htmlFor:`ai-base-url`,className:e?X:void 0,children:`Base URL`}),(0,C.jsx)(u,{id:`ai-base-url`,type:`url`,defaultValue:K?.base_url??``,placeholder:`https://api.anthropic.com (default)`,className:e?`h-7 text-[11px]`:void 0,onBlur:e=>{Y(`base_url`,e.target.value.trim()||void 0)}},`baseurl-${r}-${L}`)]}),(0,C.jsxs)(`div`,{className:$,children:[(0,C.jsx)(f,{htmlFor:`ai-api-key`,className:e?X:void 0,children:`API Key / Token`}),(0,C.jsx)(u,{id:`ai-api-key`,type:`password`,defaultValue:K?.api_key??``,placeholder:`sk-ant-... (optional, overrides accounts)`,className:e?`h-7 text-[11px] font-mono`:`font-mono`,onBlur:e=>{let t=e.target.value.trim();t.startsWith(`••••`)||Y(`api_key`,t||void 0)}},`apikey-${r}-${L}`),(0,C.jsx)(`p`,{className:`${e?`text-[9px]`:`text-[11px]`} text-muted-foreground`,children:`Direct API key or OAuth token. Leave empty to use connected accounts.`})]}),(0,C.jsxs)(`div`,{className:$,children:[(0,C.jsx)(f,{htmlFor:`ai-effort`,className:e?X:void 0,children:`Effort`}),(0,C.jsxs)(v,{value:K?.effort??`high`,onValueChange:e=>Y(`effort`,e),children:[(0,C.jsx)(y,{id:`ai-effort`,className:`w-full ${e?`h-7 text-[11px]`:``}`,children:(0,C.jsx)(p,{})}),(0,C.jsx)(m,{children:O.map(e=>(0,C.jsx)(_,{value:e.value,children:e.label},e.value))})]})]}),(0,C.jsxs)(`div`,{className:$,children:[(0,C.jsx)(f,{htmlFor:`ai-max-turns`,className:e?X:void 0,children:`Max Turns (1-500)`}),(0,C.jsx)(u,{id:`ai-max-turns`,type:`number`,min:1,max:500,defaultValue:K?.max_turns??100,className:e?`h-7 text-[11px]`:void 0,onBlur:e=>{let t=parseInt(e.target.value);isNaN(t)||Y(`max_turns`,t)}},`turns-${r}-${L}`)]}),(0,C.jsxs)(`div`,{className:$,children:[(0,C.jsx)(f,{htmlFor:`ai-budget`,className:e?X:void 0,children:`Max Budget (USD)`}),(0,C.jsx)(u,{id:`ai-budget`,type:`number`,step:.1,min:.01,max:50,defaultValue:K?.max_budget_usd??``,placeholder:`No limit`,className:e?`h-7 text-[11px]`:void 0,onBlur:e=>{let t=parseFloat(e.target.value);Y(`max_budget_usd`,isNaN(t)?void 0:t)}},`budget-${r}-${L}`)]}),(0,C.jsxs)(`div`,{className:$,children:[(0,C.jsx)(f,{htmlFor:`ai-thinking`,className:e?X:void 0,children:`Thinking Budget (tokens)`}),(0,C.jsx)(u,{id:`ai-thinking`,type:`number`,min:0,defaultValue:K?.thinking_budget_tokens??``,placeholder:`Adaptive (model decides)`,className:e?`h-7 text-[11px]`:void 0,onBlur:e=>{let t=parseInt(e.target.value);Y(`thinking_budget_tokens`,isNaN(t)?void 0:t)}},`thinking-${r}-${L}`)]}),(0,C.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(f,{htmlFor:`ai-agent-teams`,className:e?X:void 0,children:`Agent Teams`}),(0,C.jsx)(`p`,{className:`${e?`text-[9px]`:`text-[11px]`} text-muted-foreground`,children:`Experimental. Enables multi-agent collaboration with shared tasks and messaging. Uses ~7x more tokens.`})]}),(0,C.jsx)(h,{id:`ai-agent-teams`,checked:K?.agent_teams??!1,onCheckedChange:e=>Y(`agent_teams`,e)})]}),K?.agent_teams&&(0,C.jsx)(ee,{compact:e}),(0,C.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(f,{htmlFor:`ai-context-1m`,className:e?X:void 0,children:`1M Context Window`}),(0,C.jsx)(`p`,{className:`${e?`text-[9px]`:`text-[11px]`} text-muted-foreground`,children:`Requires an entitled account (Max/Team/Enterprise) and an Opus 4 / Sonnet 4 model. Other accounts will error.`})]}),(0,C.jsx)(h,{id:`ai-context-1m`,checked:K?.context_1m??!1,onCheckedChange:e=>Y(`context_1m`,e)})]}),(0,C.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,C.jsxs)(`div`,{children:[(0,C.jsx)(f,{htmlFor:`ai-inherit-mcp`,className:e?X:void 0,children:`Inherit Claude Code MCP`}),(0,C.jsx)(`p`,{className:`${e?`text-[9px]`:`text-[11px]`} text-muted-foreground`,children:`Auto-load MCP servers from Claude Code's ~/.claude.json (global + per-project). Your own MCP servers override inherited ones.`})]}),(0,C.jsx)(h,{id:`ai-inherit-mcp`,checked:K?.inherit_claude_mcp??!0,onCheckedChange:e=>Y(`inherit_claude_mcp`,e)})]}),(0,C.jsxs)(`div`,{className:$,children:[(0,C.jsx)(f,{className:e?X:void 0,children:`MCP sign-in`}),(0,C.jsx)(`p`,{className:`${e?`text-[9px]`:`text-[11px]`} text-muted-foreground`,children:`Servers that use OAuth stay unavailable to Claude until someone signs in. Project-scoped servers are listed in the project's AI Resources panel.`}),(0,C.jsx)(`div`,{className:`-mx-2`,children:(0,C.jsx)(g,{showWhenEmpty:!0})})]})]}),(0,C.jsxs)(`div`,{className:$,children:[(0,C.jsx)(f,{htmlFor:`ai-permission-mode`,className:e?X:void 0,children:`Default Permission Mode`}),(0,C.jsxs)(v,{value:K?.permission_mode??`bypassPermissions`,onValueChange:e=>Y(`permission_mode`,e),children:[(0,C.jsx)(y,{id:`ai-permission-mode`,className:`w-full ${e?`h-7 text-[11px]`:``}`,children:(0,C.jsx)(p,{})}),(0,C.jsx)(m,{children:k.map(e=>(0,C.jsx)(_,{value:e.value,children:e.label},e.value))})]})]}),(0,C.jsxs)(`div`,{className:$,children:[(0,C.jsx)(f,{htmlFor:`ai-system-prompt`,className:e?X:void 0,children:`Additional Instructions`}),(0,C.jsx)(`textarea`,{id:`ai-system-prompt`,rows:e?3:4,defaultValue:K?.system_prompt??``,placeholder:`Enter additional instructions for ${r}...`,className:`w-full rounded-md border border-input bg-background px-3 py-2 ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ${e?`text-[11px]`:`text-sm`}`,onBlur:e=>{Y(`system_prompt`,e.target.value.trim()||void 0)}},`sysprompt-${r}-${L}`)]})]}),N&&(0,C.jsx)(`p`,{className:`text-xs text-text-subtle`,children:`Saving...`}),F&&(0,C.jsx)(`p`,{className:`text-xs text-error`,children:F})]})}function ee({compact:e}){let[t,n]=(0,S.useState)([]),[i,o]=(0,S.useState)(!1),[c,l]=(0,S.useState)(null),u=(0,S.useCallback)(async()=>{o(!0);try{n(await s.get(`/api/teams`)??[])}catch{}o(!1)},[]);(0,S.useEffect)(()=>{u()},[u]);let d=async e=>{try{await s.del(`/api/teams/${encodeURIComponent(e)}`),n(t=>t.filter(t=>t.name!==e)),l(null)}catch{}};return t.length===0&&!i?null:(0,C.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,C.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,C.jsxs)(f,{className:e?`text-[11px]`:void 0,children:[`Teams (`,t.length,`)`]}),(0,C.jsx)(`button`,{onClick:u,className:`text-text-subtle hover:text-foreground p-1`,"aria-label":`Refresh teams`,children:(0,C.jsx)(a,{className:`size-3 ${i?`animate-spin`:``}`})})]}),t.map(e=>(0,C.jsxs)(`div`,{className:`flex items-center justify-between p-2 rounded bg-surface-elevated text-xs`,children:[(0,C.jsxs)(`div`,{className:`min-w-0`,children:[(0,C.jsx)(`div`,{className:`font-medium truncate`,children:e.name}),e.description&&(0,C.jsx)(`div`,{className:`text-text-subtle truncate`,children:e.description}),(0,C.jsxs)(`div`,{className:`text-text-subtle`,children:[e.members?.length??e.memberCount??0,` members`,e.createdAt?` · ${new Date(e.createdAt).toLocaleDateString()}`:``]})]}),c===e.name?(0,C.jsxs)(`div`,{className:`flex gap-1 shrink-0 ml-2`,children:[(0,C.jsx)(`button`,{onClick:()=>d(e.name),className:`px-2 py-1 bg-error text-white rounded text-[10px]`,children:`Delete`}),(0,C.jsx)(`button`,{onClick:()=>l(null),className:`px-2 py-1 bg-panel-2 text-text rounded text-[10px]`,children:`Cancel`})]}):(0,C.jsx)(`button`,{onClick:()=>l(e.name),className:`shrink-0 text-text-subtle hover:text-error p-1 ml-2`,"aria-label":`Delete team ${e.name}`,children:(0,C.jsx)(r,{className:`size-3.5`})})]},e.name))]})}export{j as t};