@hienlh/ppm 0.23.22 → 0.23.24

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 (463) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/CLAUDE.md +3 -1
  3. package/README.md +1 -1
  4. package/assets/skills/ppm/SKILL.md +1 -1
  5. package/assets/skills/ppm/references/http-api.md +2 -1
  6. package/dist/web/assets/{accounts-settings-section-CiNmIj02.js → accounts-settings-section-Cg-LncY6.js} +1 -1
  7. package/dist/web/assets/accounts-settings-section-Cg-LncY6.js.br +0 -0
  8. package/dist/web/assets/accounts-settings-section-Cg-LncY6.js.gz +0 -0
  9. package/dist/web/assets/{agent-session-sheet-DRR36PDA.js → agent-session-sheet-DMdV8GOu.js} +2 -2
  10. package/dist/web/assets/agent-session-sheet-DMdV8GOu.js.br +0 -0
  11. package/dist/web/assets/agent-session-sheet-DMdV8GOu.js.gz +0 -0
  12. package/dist/web/assets/{agent-session-window-content-DMhy16BM.js → agent-session-window-content-CYg58J-V.js} +1 -1
  13. package/dist/web/assets/agent-session-window-content-CYg58J-V.js.br +0 -0
  14. package/dist/web/assets/agent-session-window-content-CYg58J-V.js.gz +0 -0
  15. package/dist/web/assets/{ai-resource-editor-BG8boPw7.js → ai-resource-editor-BvEnn0Z_.js} +1 -1
  16. package/dist/web/assets/ai-resource-editor-BvEnn0Z_.js.br +0 -0
  17. package/dist/web/assets/ai-resource-editor-BvEnn0Z_.js.gz +0 -0
  18. package/dist/web/assets/{ai-settings-section-De5dYWlC.js → ai-settings-section-Bo-nf2rY.js} +1 -1
  19. package/dist/web/assets/ai-settings-section-DAqiu_11.js +1 -0
  20. package/dist/web/assets/ai-settings-section-DAqiu_11.js.br +0 -0
  21. package/dist/web/assets/ai-settings-section-DAqiu_11.js.gz +0 -0
  22. package/dist/web/assets/{android-tab-lHDxD93G.js → android-tab-C-wmlFc0.js} +1 -1
  23. package/dist/web/assets/android-tab-C-wmlFc0.js.br +0 -0
  24. package/dist/web/assets/android-tab-C-wmlFc0.js.gz +0 -0
  25. package/dist/web/assets/{appearance-settings-section-DO-ZyoMj.js → appearance-settings-section-CYqX6BGh.js} +1 -1
  26. package/dist/web/assets/appearance-settings-section-CYqX6BGh.js.br +0 -0
  27. package/dist/web/assets/appearance-settings-section-CYqX6BGh.js.gz +0 -0
  28. package/dist/web/assets/{apps-panel-CH-0CHYY.js → apps-panel-D1VTBxgC.js} +1 -1
  29. package/dist/web/assets/apps-panel-D1VTBxgC.js.br +0 -0
  30. package/dist/web/assets/apps-panel-D1VTBxgC.js.gz +0 -0
  31. package/dist/web/assets/{branch-review-tab-CdGtvekz.js → branch-review-tab-BG6vxSsC.js} +1 -1
  32. package/dist/web/assets/branch-review-tab-BG6vxSsC.js.br +0 -0
  33. package/dist/web/assets/branch-review-tab-BG6vxSsC.js.gz +0 -0
  34. package/dist/web/assets/chat-tab-BAwGLGyR.js +19 -0
  35. package/dist/web/assets/chat-tab-BAwGLGyR.js.br +0 -0
  36. package/dist/web/assets/chat-tab-BAwGLGyR.js.gz +0 -0
  37. package/dist/web/assets/{chat-tab-DMqWnFIo.js → chat-tab-BJ0Mi2sd.js} +1 -1
  38. package/dist/web/assets/chat-tab-BJ0Mi2sd.js.br +0 -0
  39. package/dist/web/assets/chat-tab-BJ0Mi2sd.js.gz +0 -0
  40. package/dist/web/assets/{code-editor-BCv8ONNS.js → code-editor-DuwbwTpM.js} +4 -4
  41. package/dist/web/assets/code-editor-DuwbwTpM.js.br +0 -0
  42. package/dist/web/assets/code-editor-DuwbwTpM.js.gz +0 -0
  43. package/dist/web/assets/{codex-reset-credit-button-CGMbIHak.js → codex-reset-credit-button-tIwfnf2G.js} +1 -1
  44. package/dist/web/assets/codex-reset-credit-button-tIwfnf2G.js.br +0 -0
  45. package/dist/web/assets/{codex-reset-credit-button-CGMbIHak.js.gz → codex-reset-credit-button-tIwfnf2G.js.gz} +0 -0
  46. package/dist/web/assets/{conflict-editor-3WmzqBlW.js → conflict-editor-D2n-hQqs.js} +1 -1
  47. package/dist/web/assets/conflict-editor-D2n-hQqs.js.br +0 -0
  48. package/dist/web/assets/conflict-editor-D2n-hQqs.js.gz +0 -0
  49. package/dist/web/assets/{connection-form-tab-BoWucvAe.js → connection-form-tab-DYqPNq_-.js} +1 -1
  50. package/dist/web/assets/connection-form-tab-DYqPNq_-.js.br +0 -0
  51. package/dist/web/assets/connection-form-tab-DYqPNq_-.js.gz +0 -0
  52. package/dist/web/assets/{csv-preview-BCgGsy7F.js → csv-preview-Xh3Z6BS5.js} +1 -1
  53. package/dist/web/assets/csv-preview-Xh3Z6BS5.js.br +0 -0
  54. package/dist/web/assets/csv-preview-Xh3Z6BS5.js.gz +0 -0
  55. package/dist/web/assets/{db-tab-parts-o6QMHBbA.js → db-tab-parts-Dqnb3GCP.js} +1 -1
  56. package/dist/web/assets/db-tab-parts-Dqnb3GCP.js.br +0 -0
  57. package/dist/web/assets/db-tab-parts-Dqnb3GCP.js.gz +0 -0
  58. package/dist/web/assets/{design-settings-section-seo6SdSk.js → design-settings-section-DNNWgxF9.js} +1 -1
  59. package/dist/web/assets/design-settings-section-DNNWgxF9.js.br +0 -0
  60. package/dist/web/assets/design-settings-section-DNNWgxF9.js.gz +0 -0
  61. package/dist/web/assets/{design-tab-B-f_b2LM.js → design-tab-BoAdSpZZ.js} +1 -1
  62. package/dist/web/assets/design-tab-BoAdSpZZ.js.br +0 -0
  63. package/dist/web/assets/design-tab-BoAdSpZZ.js.gz +0 -0
  64. package/dist/web/assets/{designs-sidebar-panel-CVT_TQP7.js → designs-sidebar-panel-BKw7HFAz.js} +1 -1
  65. package/dist/web/assets/designs-sidebar-panel-BKw7HFAz.js.br +0 -0
  66. package/dist/web/assets/designs-sidebar-panel-BKw7HFAz.js.gz +0 -0
  67. package/dist/web/assets/{diff-viewer-y9uBp_8u.js → diff-viewer-CRmfCAZX.js} +1 -1
  68. package/dist/web/assets/diff-viewer-CRmfCAZX.js.br +0 -0
  69. package/dist/web/assets/diff-viewer-CRmfCAZX.js.gz +0 -0
  70. package/dist/web/assets/{docx-preview-Dn_x3Inm.js → docx-preview-zIrtL09u.js} +1 -1
  71. package/dist/web/assets/docx-preview-zIrtL09u.js.br +0 -0
  72. package/dist/web/assets/docx-preview-zIrtL09u.js.gz +0 -0
  73. package/dist/web/assets/{editor-dialog-BwNXSajD.js → editor-dialog-jMYvXVla.js} +1 -1
  74. package/dist/web/assets/editor-dialog-jMYvXVla.js.br +0 -0
  75. package/dist/web/assets/editor-dialog-jMYvXVla.js.gz +0 -0
  76. package/dist/web/assets/{editor-language-service-XA_TnPLN.js → editor-language-service-Yb-61Bro.js} +1 -1
  77. package/dist/web/assets/editor-language-service-Yb-61Bro.js.br +0 -0
  78. package/dist/web/assets/editor-language-service-Yb-61Bro.js.gz +0 -0
  79. package/dist/web/assets/{explorer-body-DukR7zM9.js → explorer-body-C6qKehmd.js} +1 -1
  80. package/dist/web/assets/explorer-body-C6qKehmd.js.br +0 -0
  81. package/dist/web/assets/explorer-body-C6qKehmd.js.gz +0 -0
  82. package/dist/web/assets/{explorer-window-content-BjTZ44S3.js → explorer-window-content-B9P8grrY.js} +1 -1
  83. package/dist/web/assets/explorer-window-content-B9P8grrY.js.br +0 -0
  84. package/dist/web/assets/explorer-window-content-B9P8grrY.js.gz +0 -0
  85. package/dist/web/assets/{extension-manager-section-C4WD1BPQ.js → extension-manager-section-C45v1QtG.js} +1 -1
  86. package/dist/web/assets/extension-manager-section-C45v1QtG.js.br +0 -0
  87. package/dist/web/assets/extension-manager-section-C45v1QtG.js.gz +0 -0
  88. package/dist/web/assets/{extension-webview-CV2ujflc.js → extension-webview-DIxM-xkH.js} +1 -1
  89. package/dist/web/assets/extension-webview-DIxM-xkH.js.br +0 -0
  90. package/dist/web/assets/extension-webview-DIxM-xkH.js.gz +0 -0
  91. package/dist/web/assets/{files-settings-section-hS5ixQ8o.js → files-settings-section-DeVlzKXd.js} +1 -1
  92. package/dist/web/assets/files-settings-section-DeVlzKXd.js.br +0 -0
  93. package/dist/web/assets/files-settings-section-DeVlzKXd.js.gz +0 -0
  94. package/dist/web/assets/format-date-CkyHzZLA.js +1 -0
  95. package/dist/web/assets/{general-settings-section-BnKYY0AA.js → general-settings-section-CLVDIEym.js} +1 -1
  96. package/dist/web/assets/general-settings-section-CLVDIEym.js.br +0 -0
  97. package/dist/web/assets/general-settings-section-CLVDIEym.js.gz +0 -0
  98. package/dist/web/assets/{git-log-panel-JiWfR5xv.js → git-log-panel-D3Q9NRll.js} +1 -1
  99. package/dist/web/assets/git-log-panel-D3Q9NRll.js.br +0 -0
  100. package/dist/web/assets/git-log-panel-D3Q9NRll.js.gz +0 -0
  101. package/dist/web/assets/{git-review-tab-DgvcY__Q.js → git-review-tab-ORgiYbva.js} +1 -1
  102. package/dist/web/assets/git-review-tab-ORgiYbva.js.br +0 -0
  103. package/dist/web/assets/git-review-tab-ORgiYbva.js.gz +0 -0
  104. package/dist/web/assets/{glide-data-grid-r1MKxDjz.js → glide-data-grid-CtWl1BTk.js} +1 -1
  105. package/dist/web/assets/glide-data-grid-CtWl1BTk.js.br +0 -0
  106. package/dist/web/assets/glide-data-grid-CtWl1BTk.js.gz +0 -0
  107. package/dist/web/assets/{grid-save-dialog-Fa0yA-Ep.js → grid-save-dialog-eV25Mqpg.js} +1 -1
  108. package/dist/web/assets/grid-save-dialog-eV25Mqpg.js.br +0 -0
  109. package/dist/web/assets/grid-save-dialog-eV25Mqpg.js.gz +0 -0
  110. package/dist/web/assets/{group-chat-tab-B2Q8yqSX.js → group-chat-tab-CYmbYXN2.js} +1 -1
  111. package/dist/web/assets/group-chat-tab-CYmbYXN2.js.br +0 -0
  112. package/dist/web/assets/group-chat-tab-CYmbYXN2.js.gz +0 -0
  113. package/dist/web/assets/{impexp-tab-B8Ht4l32.js → impexp-tab-D2OKxpFq.js} +1 -1
  114. package/dist/web/assets/impexp-tab-D2OKxpFq.js.br +0 -0
  115. package/dist/web/assets/impexp-tab-D2OKxpFq.js.gz +0 -0
  116. package/dist/web/assets/{index-BtAn_krv.js → index-D8QDpdgs.js} +7 -7
  117. package/dist/web/assets/index-D8QDpdgs.js.br +0 -0
  118. package/dist/web/assets/index-D8QDpdgs.js.gz +0 -0
  119. package/dist/web/assets/{jira-watcher-section--ibKZfBs.js → jira-watcher-section-B3OaMlim.js} +1 -1
  120. package/dist/web/assets/{keybindings-store-Cwxl4tHv.js → keybindings-store-C_aRhBu4.js} +1 -1
  121. package/dist/web/assets/{keyboard-shortcuts-section-aoiLpWwf.js → keyboard-shortcuts-section-DXRyKrSy.js} +1 -1
  122. package/dist/web/assets/keyboard-shortcuts-section-DXRyKrSy.js.br +0 -0
  123. package/dist/web/assets/keyboard-shortcuts-section-DXRyKrSy.js.gz +0 -0
  124. package/dist/web/assets/{language-servers-section-BkGAezo6.js → language-servers-section-BTs9iuZc.js} +2 -2
  125. package/dist/web/assets/language-servers-section-BTs9iuZc.js.br +0 -0
  126. package/dist/web/assets/language-servers-section-BTs9iuZc.js.gz +0 -0
  127. package/dist/web/assets/{logs-app-DYgPtmjm.js → logs-app-BlhVTOYN.js} +1 -1
  128. package/dist/web/assets/logs-app-BlhVTOYN.js.br +0 -0
  129. package/dist/web/assets/logs-app-BlhVTOYN.js.gz +0 -0
  130. package/dist/web/assets/{logs-tab-BbDosK63.js → logs-tab-kqNARbz0.js} +1 -1
  131. package/dist/web/assets/{logs-window-content-CEXAyv-f.js → logs-window-content-UUCJJCqG.js} +1 -1
  132. package/dist/web/assets/{lsp-client-CIcphNmU.js → lsp-client-BTlK_8lb.js} +1 -1
  133. package/dist/web/assets/lsp-client-BTlK_8lb.js.br +0 -0
  134. package/dist/web/assets/lsp-client-BTlK_8lb.js.gz +0 -0
  135. package/dist/web/assets/{markdown-renderer-BNzQeoAO.js → markdown-renderer-ClGxDien.js} +1 -1
  136. package/dist/web/assets/{markdown-renderer-dk1w3goH.js → markdown-renderer-DpsToFFB.js} +1 -1
  137. package/dist/web/assets/markdown-renderer-DpsToFFB.js.br +0 -0
  138. package/dist/web/assets/markdown-renderer-DpsToFFB.js.gz +0 -0
  139. package/dist/web/assets/{mobile-explorer-sheet-D4lPZQZc.js → mobile-explorer-sheet-CybJbScN.js} +1 -1
  140. package/dist/web/assets/mobile-explorer-sheet-CybJbScN.js.br +0 -0
  141. package/dist/web/assets/mobile-explorer-sheet-CybJbScN.js.gz +0 -0
  142. package/dist/web/assets/{new-design-dialog-CIq7xspW.js → new-design-dialog-9WTgcJoj.js} +1 -1
  143. package/dist/web/assets/new-design-dialog-9WTgcJoj.js.br +0 -0
  144. package/dist/web/assets/new-design-dialog-9WTgcJoj.js.gz +0 -0
  145. package/dist/web/assets/{notification-store-Rv36noYX.js → notification-store-CPVq5ec5.js} +1 -1
  146. package/dist/web/assets/{notifications-settings-section-CoWMtXCC.js → notifications-settings-section-xrYII-pL.js} +1 -1
  147. package/dist/web/assets/notifications-settings-section-xrYII-pL.js.br +0 -0
  148. package/dist/web/assets/notifications-settings-section-xrYII-pL.js.gz +0 -0
  149. package/dist/web/assets/{ppmbot-settings-section-Ct0UwA6T.js → ppmbot-settings-section-Bc46iDP9.js} +1 -1
  150. package/dist/web/assets/ppmbot-settings-section-Bc46iDP9.js.br +0 -0
  151. package/dist/web/assets/ppmbot-settings-section-Bc46iDP9.js.gz +0 -0
  152. package/dist/web/assets/{problems-panel-D-HT-0PE.js → problems-panel-D49-Xkzd.js} +1 -1
  153. package/dist/web/assets/problems-panel-D49-Xkzd.js.br +0 -0
  154. package/dist/web/assets/problems-panel-D49-Xkzd.js.gz +0 -0
  155. package/dist/web/assets/{process-table-CXN0s4Pq.js → process-table-NxYTZ0n9.js} +1 -1
  156. package/dist/web/assets/process-table-NxYTZ0n9.js.br +0 -0
  157. package/dist/web/assets/process-table-NxYTZ0n9.js.gz +0 -0
  158. package/dist/web/assets/{proxy-settings-section-e6WWzP8n.js → proxy-settings-section-Exx7cQc4.js} +1 -1
  159. package/dist/web/assets/proxy-settings-section-Exx7cQc4.js.br +0 -0
  160. package/dist/web/assets/proxy-settings-section-Exx7cQc4.js.gz +0 -0
  161. package/dist/web/assets/{query-tab-C7C67t8F.js → query-tab-BWtJPuxw.js} +1 -1
  162. package/dist/web/assets/query-tab-BWtJPuxw.js.br +0 -0
  163. package/dist/web/assets/query-tab-BWtJPuxw.js.gz +0 -0
  164. package/dist/web/assets/{remote-access-settings-section-gGoATCF9.js → remote-access-settings-section-C4K__DNW.js} +1 -1
  165. package/dist/web/assets/remote-access-settings-section-C4K__DNW.js.br +0 -0
  166. package/dist/web/assets/remote-access-settings-section-C4K__DNW.js.gz +0 -0
  167. package/dist/web/assets/{remote-desktop-clipboard-notice-D5KjvMZx.js → remote-desktop-clipboard-notice-DQyysBwL.js} +1 -1
  168. package/dist/web/assets/remote-desktop-clipboard-notice-DQyysBwL.js.br +0 -0
  169. package/dist/web/assets/remote-desktop-clipboard-notice-DQyysBwL.js.gz +0 -0
  170. package/dist/web/assets/{remote-desktop-mobile-sheet-CY_DsGXZ.js → remote-desktop-mobile-sheet-DZtEFmgf.js} +2 -2
  171. package/dist/web/assets/remote-desktop-mobile-sheet-DZtEFmgf.js.br +0 -0
  172. package/dist/web/assets/remote-desktop-mobile-sheet-DZtEFmgf.js.gz +0 -0
  173. package/dist/web/assets/{remote-desktop-mobile-view-DdpI-RF8.js → remote-desktop-mobile-view-VW7HdPUX.js} +1 -1
  174. package/dist/web/assets/remote-desktop-mobile-view-VW7HdPUX.js.br +0 -0
  175. package/dist/web/assets/{remote-desktop-mobile-view-DdpI-RF8.js.gz → remote-desktop-mobile-view-VW7HdPUX.js.gz} +0 -0
  176. package/dist/web/assets/{remote-desktop-readiness-gate-WIyCCAv5.js → remote-desktop-readiness-gate-B3tuP9Kt.js} +1 -1
  177. package/dist/web/assets/remote-desktop-readiness-gate-B3tuP9Kt.js.br +0 -0
  178. package/dist/web/assets/remote-desktop-readiness-gate-B3tuP9Kt.js.gz +0 -0
  179. package/dist/web/assets/{remote-desktop-window-content-BMORZLZt.js → remote-desktop-window-content-n0NoDCaE.js} +1 -1
  180. package/dist/web/assets/remote-desktop-window-content-n0NoDCaE.js.br +0 -0
  181. package/dist/web/assets/remote-desktop-window-content-n0NoDCaE.js.gz +0 -0
  182. package/dist/web/assets/{rename-object-dialog-pIgWe_AL.js → rename-object-dialog-rLTW4A55.js} +1 -1
  183. package/dist/web/assets/rename-object-dialog-rLTW4A55.js.br +0 -0
  184. package/dist/web/assets/rename-object-dialog-rLTW4A55.js.gz +0 -0
  185. package/dist/web/assets/{review-code-oTNcTYlI.js → review-code-DNfsaNO1.js} +1 -1
  186. package/dist/web/assets/review-code-DNfsaNO1.js.br +0 -0
  187. package/dist/web/assets/review-code-DNfsaNO1.js.gz +0 -0
  188. package/dist/web/assets/{save-as-dialog-CnPLGTaL.js → save-as-dialog-BSz8WrNZ.js} +1 -1
  189. package/dist/web/assets/save-as-dialog-BSz8WrNZ.js.br +0 -0
  190. package/dist/web/assets/save-as-dialog-BSz8WrNZ.js.gz +0 -0
  191. package/dist/web/assets/{schedules-settings-section-CREqHG_i.js → schedules-settings-section-DqUZ-H2K.js} +1 -1
  192. package/dist/web/assets/schedules-settings-section-DqUZ-H2K.js.br +0 -0
  193. package/dist/web/assets/schedules-settings-section-DqUZ-H2K.js.gz +0 -0
  194. package/dist/web/assets/{session-review-tab-nFVJYYJH.js → session-review-tab-DKtrFb9y.js} +1 -1
  195. package/dist/web/assets/session-review-tab-DKtrFb9y.js.br +0 -0
  196. package/dist/web/assets/session-review-tab-DKtrFb9y.js.gz +0 -0
  197. package/dist/web/assets/{settings-body-DNzH0wOQ.js → settings-body-C42xA9Dw.js} +1 -1
  198. package/dist/web/assets/settings-body-C42xA9Dw.js.br +0 -0
  199. package/dist/web/assets/settings-body-C42xA9Dw.js.gz +0 -0
  200. package/dist/web/assets/{settings-rows-D02_4sDY.js → settings-rows-C7ZatT9O.js} +1 -1
  201. package/dist/web/assets/settings-rows-C7ZatT9O.js.br +0 -0
  202. package/dist/web/assets/settings-rows-C7ZatT9O.js.gz +0 -0
  203. package/dist/web/assets/{settings-section-content-DWopMfmq.js → settings-section-content-B_iXJpcK.js} +2 -2
  204. package/dist/web/assets/settings-section-content-B_iXJpcK.js.br +0 -0
  205. package/dist/web/assets/settings-section-content-B_iXJpcK.js.gz +0 -0
  206. package/dist/web/assets/settings-section-content-rxfQEQ66.js +1 -0
  207. package/dist/web/assets/{settings-tab-Cg0v5kO7.js → settings-tab-PRw6OpEb.js} +1 -1
  208. package/dist/web/assets/{settings-window-content-CqhwxJJn.js → settings-window-content-WITQsGfW.js} +1 -1
  209. package/dist/web/assets/{slash-command-picker-Bcizxvbh.js → slash-command-picker-DmDs8nOj.js} +1 -1
  210. package/dist/web/assets/slash-command-picker-DmDs8nOj.js.br +0 -0
  211. package/dist/web/assets/slash-command-picker-DmDs8nOj.js.gz +0 -0
  212. package/dist/web/assets/{sql-object-tab-b1Z2zVBm.js → sql-object-tab-D6P4hzkb.js} +1 -1
  213. package/dist/web/assets/sql-object-tab-D6P4hzkb.js.br +0 -0
  214. package/dist/web/assets/sql-object-tab-D6P4hzkb.js.gz +0 -0
  215. package/dist/web/assets/{sqlite-viewer-DhPv28tq.js → sqlite-viewer-mUitnzHB.js} +1 -1
  216. package/dist/web/assets/sqlite-viewer-mUitnzHB.js.br +0 -0
  217. package/dist/web/assets/sqlite-viewer-mUitnzHB.js.gz +0 -0
  218. package/dist/web/assets/{structure-save-dialog-sGUpqs8D.js → structure-save-dialog-CmbNlmBY.js} +1 -1
  219. package/dist/web/assets/structure-save-dialog-CmbNlmBY.js.br +0 -0
  220. package/dist/web/assets/structure-save-dialog-CmbNlmBY.js.gz +0 -0
  221. package/dist/web/assets/{structure-tab-Bo2OmDOc.js → structure-tab-DCPNuFTe.js} +1 -1
  222. package/dist/web/assets/structure-tab-DCPNuFTe.js.br +0 -0
  223. package/dist/web/assets/structure-tab-DCPNuFTe.js.gz +0 -0
  224. package/dist/web/assets/{system-monitor-body-C475Et9u.js → system-monitor-body-BhxyqSqu.js} +2 -2
  225. package/dist/web/assets/system-monitor-body-BhxyqSqu.js.br +0 -0
  226. package/dist/web/assets/system-monitor-body-BhxyqSqu.js.gz +0 -0
  227. package/dist/web/assets/{system-monitor-tab-Cm52yoW8.js → system-monitor-tab-B_miogQI.js} +1 -1
  228. package/dist/web/assets/{system-monitor-window-content-YYsGHxZF.js → system-monitor-window-content-8IogR6tR.js} +1 -1
  229. package/dist/web/assets/{tab-host-window-content-BKI6QoDa.js → tab-host-window-content-BWHQjgWZ.js} +1 -1
  230. package/dist/web/assets/tab-host-window-content-BWHQjgWZ.js.br +0 -0
  231. package/dist/web/assets/tab-host-window-content-BWHQjgWZ.js.gz +0 -0
  232. package/dist/web/assets/{table-tab-D-nKWMJR.js → table-tab-E3YMueu_.js} +1 -1
  233. package/dist/web/assets/table-tab-E3YMueu_.js.br +0 -0
  234. package/dist/web/assets/{table-tab-D-nKWMJR.js.gz → table-tab-E3YMueu_.js.gz} +0 -0
  235. package/dist/web/assets/{telegram-bot-token-field-BeNS2X2k.js → telegram-bot-token-field-CwW24m62.js} +1 -1
  236. package/dist/web/assets/telegram-bot-token-field-CwW24m62.js.br +0 -0
  237. package/dist/web/assets/telegram-bot-token-field-CwW24m62.js.gz +0 -0
  238. package/dist/web/assets/{terminal-tab-BbP753Ab.js → terminal-tab-BAe5cWEL.js} +1 -1
  239. package/dist/web/assets/terminal-tab-BAe5cWEL.js.br +0 -0
  240. package/dist/web/assets/terminal-tab-BAe5cWEL.js.gz +0 -0
  241. package/dist/web/assets/{tool-cards-Dh8Ekn2W.js → tool-cards-DrCiSH2r.js} +2 -2
  242. package/dist/web/assets/tool-cards-DrCiSH2r.js.br +0 -0
  243. package/dist/web/assets/tool-cards-DrCiSH2r.js.gz +0 -0
  244. package/dist/web/assets/{tools-settings-section-DGZRIULE.js → tools-settings-section-S-vBr2af.js} +1 -1
  245. package/dist/web/assets/tools-settings-section-S-vBr2af.js.br +0 -0
  246. package/dist/web/assets/tools-settings-section-S-vBr2af.js.gz +0 -0
  247. package/dist/web/assets/{use-inline-blame-BxwM-Wkj.js → use-inline-blame-BzVaaCCt.js} +1 -1
  248. package/dist/web/assets/use-inline-blame-BzVaaCCt.js.br +0 -0
  249. package/dist/web/assets/use-inline-blame-BzVaaCCt.js.gz +0 -0
  250. package/dist/web/assets/{use-lsp-BqvwRKmM.js → use-lsp-BwDL9Fqk.js} +1 -1
  251. package/dist/web/assets/use-lsp-BwDL9Fqk.js.br +0 -0
  252. package/dist/web/assets/use-lsp-BwDL9Fqk.js.gz +0 -0
  253. package/dist/web/assets/{use-monaco-theme-DU0EpDHH.js → use-monaco-theme-DljSc3Xo.js} +1 -1
  254. package/dist/web/assets/{use-process-kill-CVN_c4KF.js → use-process-kill-YDcDqDtG.js} +1 -1
  255. package/dist/web/assets/use-process-kill-YDcDqDtG.js.br +0 -0
  256. package/dist/web/assets/use-process-kill-YDcDqDtG.js.gz +0 -0
  257. package/dist/web/assets/{use-sql-schema-info-C0wBmR6-.js → use-sql-schema-info-cAI0vn7d.js} +1 -1
  258. package/dist/web/assets/use-sql-schema-info-cAI0vn7d.js.br +0 -0
  259. package/dist/web/assets/use-sql-schema-info-cAI0vn7d.js.gz +0 -0
  260. package/dist/web/assets/{use-websocket-K0OUXbbY.js → use-websocket-Djo_ruX_.js} +1 -1
  261. package/dist/web/assets/{web-preview-tab-DOgLv8Gt.js → web-preview-tab-DXy0hRef.js} +1 -1
  262. package/dist/web/assets/web-preview-tab-DXy0hRef.js.br +0 -0
  263. package/dist/web/assets/web-preview-tab-DXy0hRef.js.gz +0 -0
  264. package/dist/web/index.html +2 -2
  265. package/dist/web/index.html.br +0 -0
  266. package/dist/web/index.html.gz +0 -0
  267. package/dist/web/sw.js +1 -1
  268. package/dist/web/sw.js.br +0 -0
  269. package/dist/web/sw.js.gz +0 -0
  270. package/docs/architecture/ai-chat-and-providers.md +29 -0
  271. package/docs/lessons-learned.md +14 -4
  272. package/package.json +1 -1
  273. package/src/providers/claude-agent-sdk-query-options.ts +13 -2
  274. package/src/providers/claude-agent-sdk.ts +112 -30
  275. package/src/providers/claude-approval-queue.ts +75 -0
  276. package/src/providers/claude-effort-status.ts +211 -0
  277. package/src/server/routes/chat.ts +17 -0
  278. package/src/server/routes/settings.ts +16 -0
  279. package/src/server/ws/chat-effort-status.ts +73 -0
  280. package/src/server/ws/chat.ts +30 -3
  281. package/src/shared/effort-status.ts +128 -0
  282. package/src/types/api.ts +3 -1
  283. package/src/types/chat.ts +8 -0
  284. package/src/web/components/chat/chat-scroll-nav.tsx +12 -8
  285. package/src/web/components/chat/chat-tab.tsx +15 -11
  286. package/src/web/components/chat/message-action-bar.tsx +19 -4
  287. package/src/web/components/chat/message-input.tsx +6 -0
  288. package/src/web/components/chat/message-list.tsx +55 -21
  289. package/src/web/components/chat/message-user-bubble.tsx +2 -2
  290. package/src/web/components/chat/model-thinking-selector-helpers.ts +79 -0
  291. package/src/web/components/chat/model-thinking-selector.tsx +36 -10
  292. package/src/web/components/chat/session-changes-context.tsx +29 -1
  293. package/src/web/components/layout/reparenting-tab.tsx +53 -14
  294. package/src/web/components/settings/ai-settings-section.tsx +32 -0
  295. package/src/web/hooks/use-chat.ts +16 -0
  296. package/src/web/hooks/use-effort-status.ts +46 -0
  297. package/src/web/hooks/use-relative-time-tick.ts +35 -0
  298. package/src/web/hooks/use-session-file-changes.ts +5 -1
  299. package/src/web/hooks/use-tab-overflow.ts +26 -13
  300. package/src/web/lib/format-date.ts +6 -1
  301. package/dist/web/assets/accounts-settings-section-CiNmIj02.js.br +0 -0
  302. package/dist/web/assets/accounts-settings-section-CiNmIj02.js.gz +0 -0
  303. package/dist/web/assets/agent-session-sheet-DRR36PDA.js.br +0 -0
  304. package/dist/web/assets/agent-session-sheet-DRR36PDA.js.gz +0 -0
  305. package/dist/web/assets/agent-session-window-content-DMhy16BM.js.br +0 -0
  306. package/dist/web/assets/agent-session-window-content-DMhy16BM.js.gz +0 -0
  307. package/dist/web/assets/ai-resource-editor-BG8boPw7.js.br +0 -0
  308. package/dist/web/assets/ai-resource-editor-BG8boPw7.js.gz +0 -0
  309. package/dist/web/assets/ai-settings-section-DMGM1hYx.js +0 -1
  310. package/dist/web/assets/ai-settings-section-DMGM1hYx.js.br +0 -0
  311. package/dist/web/assets/ai-settings-section-DMGM1hYx.js.gz +0 -0
  312. package/dist/web/assets/android-tab-lHDxD93G.js.br +0 -0
  313. package/dist/web/assets/android-tab-lHDxD93G.js.gz +0 -0
  314. package/dist/web/assets/appearance-settings-section-DO-ZyoMj.js.br +0 -0
  315. package/dist/web/assets/appearance-settings-section-DO-ZyoMj.js.gz +0 -0
  316. package/dist/web/assets/apps-panel-CH-0CHYY.js.br +0 -0
  317. package/dist/web/assets/apps-panel-CH-0CHYY.js.gz +0 -0
  318. package/dist/web/assets/branch-review-tab-CdGtvekz.js.br +0 -0
  319. package/dist/web/assets/branch-review-tab-CdGtvekz.js.gz +0 -0
  320. package/dist/web/assets/chat-tab-DMqWnFIo.js.br +0 -0
  321. package/dist/web/assets/chat-tab-DMqWnFIo.js.gz +0 -0
  322. package/dist/web/assets/chat-tab-DzWpwPFb.js +0 -19
  323. package/dist/web/assets/chat-tab-DzWpwPFb.js.br +0 -0
  324. package/dist/web/assets/chat-tab-DzWpwPFb.js.gz +0 -0
  325. package/dist/web/assets/code-editor-BCv8ONNS.js.br +0 -0
  326. package/dist/web/assets/code-editor-BCv8ONNS.js.gz +0 -0
  327. package/dist/web/assets/codex-reset-credit-button-CGMbIHak.js.br +0 -0
  328. package/dist/web/assets/conflict-editor-3WmzqBlW.js.br +0 -0
  329. package/dist/web/assets/conflict-editor-3WmzqBlW.js.gz +0 -0
  330. package/dist/web/assets/connection-form-tab-BoWucvAe.js.br +0 -0
  331. package/dist/web/assets/connection-form-tab-BoWucvAe.js.gz +0 -0
  332. package/dist/web/assets/csv-preview-BCgGsy7F.js.br +0 -0
  333. package/dist/web/assets/csv-preview-BCgGsy7F.js.gz +0 -0
  334. package/dist/web/assets/db-tab-parts-o6QMHBbA.js.br +0 -0
  335. package/dist/web/assets/db-tab-parts-o6QMHBbA.js.gz +0 -0
  336. package/dist/web/assets/design-settings-section-seo6SdSk.js.br +0 -0
  337. package/dist/web/assets/design-settings-section-seo6SdSk.js.gz +0 -0
  338. package/dist/web/assets/design-tab-B-f_b2LM.js.br +0 -0
  339. package/dist/web/assets/design-tab-B-f_b2LM.js.gz +0 -0
  340. package/dist/web/assets/designs-sidebar-panel-CVT_TQP7.js.br +0 -0
  341. package/dist/web/assets/designs-sidebar-panel-CVT_TQP7.js.gz +0 -0
  342. package/dist/web/assets/diff-viewer-y9uBp_8u.js.br +0 -0
  343. package/dist/web/assets/diff-viewer-y9uBp_8u.js.gz +0 -0
  344. package/dist/web/assets/docx-preview-Dn_x3Inm.js.br +0 -0
  345. package/dist/web/assets/docx-preview-Dn_x3Inm.js.gz +0 -0
  346. package/dist/web/assets/editor-dialog-BwNXSajD.js.br +0 -0
  347. package/dist/web/assets/editor-dialog-BwNXSajD.js.gz +0 -0
  348. package/dist/web/assets/editor-language-service-XA_TnPLN.js.br +0 -0
  349. package/dist/web/assets/editor-language-service-XA_TnPLN.js.gz +0 -0
  350. package/dist/web/assets/explorer-body-DukR7zM9.js.br +0 -0
  351. package/dist/web/assets/explorer-body-DukR7zM9.js.gz +0 -0
  352. package/dist/web/assets/explorer-window-content-BjTZ44S3.js.br +0 -0
  353. package/dist/web/assets/explorer-window-content-BjTZ44S3.js.gz +0 -0
  354. package/dist/web/assets/extension-manager-section-C4WD1BPQ.js.br +0 -0
  355. package/dist/web/assets/extension-manager-section-C4WD1BPQ.js.gz +0 -0
  356. package/dist/web/assets/extension-webview-CV2ujflc.js.br +0 -0
  357. package/dist/web/assets/extension-webview-CV2ujflc.js.gz +0 -0
  358. package/dist/web/assets/files-settings-section-hS5ixQ8o.js.br +0 -0
  359. package/dist/web/assets/files-settings-section-hS5ixQ8o.js.gz +0 -0
  360. package/dist/web/assets/format-date-CSHaU2wN.js +0 -1
  361. package/dist/web/assets/general-settings-section-BnKYY0AA.js.br +0 -0
  362. package/dist/web/assets/general-settings-section-BnKYY0AA.js.gz +0 -0
  363. package/dist/web/assets/git-log-panel-JiWfR5xv.js.br +0 -0
  364. package/dist/web/assets/git-log-panel-JiWfR5xv.js.gz +0 -0
  365. package/dist/web/assets/git-review-tab-DgvcY__Q.js.br +0 -0
  366. package/dist/web/assets/git-review-tab-DgvcY__Q.js.gz +0 -0
  367. package/dist/web/assets/glide-data-grid-r1MKxDjz.js.br +0 -0
  368. package/dist/web/assets/glide-data-grid-r1MKxDjz.js.gz +0 -0
  369. package/dist/web/assets/grid-save-dialog-Fa0yA-Ep.js.br +0 -0
  370. package/dist/web/assets/grid-save-dialog-Fa0yA-Ep.js.gz +0 -0
  371. package/dist/web/assets/group-chat-tab-B2Q8yqSX.js.br +0 -0
  372. package/dist/web/assets/group-chat-tab-B2Q8yqSX.js.gz +0 -0
  373. package/dist/web/assets/impexp-tab-B8Ht4l32.js.br +0 -0
  374. package/dist/web/assets/impexp-tab-B8Ht4l32.js.gz +0 -0
  375. package/dist/web/assets/index-BtAn_krv.js.br +0 -0
  376. package/dist/web/assets/index-BtAn_krv.js.gz +0 -0
  377. package/dist/web/assets/keyboard-shortcuts-section-aoiLpWwf.js.br +0 -0
  378. package/dist/web/assets/keyboard-shortcuts-section-aoiLpWwf.js.gz +0 -0
  379. package/dist/web/assets/language-servers-section-BkGAezo6.js.br +0 -0
  380. package/dist/web/assets/language-servers-section-BkGAezo6.js.gz +0 -0
  381. package/dist/web/assets/logs-app-DYgPtmjm.js.br +0 -0
  382. package/dist/web/assets/logs-app-DYgPtmjm.js.gz +0 -0
  383. package/dist/web/assets/lsp-client-CIcphNmU.js.br +0 -0
  384. package/dist/web/assets/lsp-client-CIcphNmU.js.gz +0 -0
  385. package/dist/web/assets/markdown-renderer-dk1w3goH.js.br +0 -0
  386. package/dist/web/assets/markdown-renderer-dk1w3goH.js.gz +0 -0
  387. package/dist/web/assets/mobile-explorer-sheet-D4lPZQZc.js.br +0 -0
  388. package/dist/web/assets/mobile-explorer-sheet-D4lPZQZc.js.gz +0 -0
  389. package/dist/web/assets/new-design-dialog-CIq7xspW.js.br +0 -0
  390. package/dist/web/assets/new-design-dialog-CIq7xspW.js.gz +0 -0
  391. package/dist/web/assets/notifications-settings-section-CoWMtXCC.js.br +0 -0
  392. package/dist/web/assets/notifications-settings-section-CoWMtXCC.js.gz +0 -0
  393. package/dist/web/assets/ppmbot-settings-section-Ct0UwA6T.js.br +0 -0
  394. package/dist/web/assets/ppmbot-settings-section-Ct0UwA6T.js.gz +0 -0
  395. package/dist/web/assets/problems-panel-D-HT-0PE.js.br +0 -0
  396. package/dist/web/assets/problems-panel-D-HT-0PE.js.gz +0 -0
  397. package/dist/web/assets/process-table-CXN0s4Pq.js.br +0 -0
  398. package/dist/web/assets/process-table-CXN0s4Pq.js.gz +0 -0
  399. package/dist/web/assets/proxy-settings-section-e6WWzP8n.js.br +0 -0
  400. package/dist/web/assets/proxy-settings-section-e6WWzP8n.js.gz +0 -0
  401. package/dist/web/assets/query-tab-C7C67t8F.js.br +0 -0
  402. package/dist/web/assets/query-tab-C7C67t8F.js.gz +0 -0
  403. package/dist/web/assets/remote-access-settings-section-gGoATCF9.js.br +0 -0
  404. package/dist/web/assets/remote-access-settings-section-gGoATCF9.js.gz +0 -0
  405. package/dist/web/assets/remote-desktop-clipboard-notice-D5KjvMZx.js.br +0 -0
  406. package/dist/web/assets/remote-desktop-clipboard-notice-D5KjvMZx.js.gz +0 -0
  407. package/dist/web/assets/remote-desktop-mobile-sheet-CY_DsGXZ.js.br +0 -0
  408. package/dist/web/assets/remote-desktop-mobile-sheet-CY_DsGXZ.js.gz +0 -0
  409. package/dist/web/assets/remote-desktop-mobile-view-DdpI-RF8.js.br +0 -0
  410. package/dist/web/assets/remote-desktop-readiness-gate-WIyCCAv5.js.br +0 -0
  411. package/dist/web/assets/remote-desktop-readiness-gate-WIyCCAv5.js.gz +0 -0
  412. package/dist/web/assets/remote-desktop-window-content-BMORZLZt.js.br +0 -0
  413. package/dist/web/assets/remote-desktop-window-content-BMORZLZt.js.gz +0 -0
  414. package/dist/web/assets/rename-object-dialog-pIgWe_AL.js.br +0 -0
  415. package/dist/web/assets/rename-object-dialog-pIgWe_AL.js.gz +0 -0
  416. package/dist/web/assets/review-code-oTNcTYlI.js.br +0 -0
  417. package/dist/web/assets/review-code-oTNcTYlI.js.gz +0 -0
  418. package/dist/web/assets/save-as-dialog-CnPLGTaL.js.br +0 -0
  419. package/dist/web/assets/save-as-dialog-CnPLGTaL.js.gz +0 -0
  420. package/dist/web/assets/schedules-settings-section-CREqHG_i.js.br +0 -0
  421. package/dist/web/assets/schedules-settings-section-CREqHG_i.js.gz +0 -0
  422. package/dist/web/assets/session-review-tab-nFVJYYJH.js.br +0 -0
  423. package/dist/web/assets/session-review-tab-nFVJYYJH.js.gz +0 -0
  424. package/dist/web/assets/settings-body-DNzH0wOQ.js.br +0 -0
  425. package/dist/web/assets/settings-body-DNzH0wOQ.js.gz +0 -0
  426. package/dist/web/assets/settings-rows-D02_4sDY.js.br +0 -0
  427. package/dist/web/assets/settings-rows-D02_4sDY.js.gz +0 -0
  428. package/dist/web/assets/settings-section-content-BYW_9mHv.js +0 -1
  429. package/dist/web/assets/settings-section-content-DWopMfmq.js.br +0 -0
  430. package/dist/web/assets/settings-section-content-DWopMfmq.js.gz +0 -0
  431. package/dist/web/assets/slash-command-picker-Bcizxvbh.js.br +0 -0
  432. package/dist/web/assets/slash-command-picker-Bcizxvbh.js.gz +0 -0
  433. package/dist/web/assets/sql-object-tab-b1Z2zVBm.js.br +0 -0
  434. package/dist/web/assets/sql-object-tab-b1Z2zVBm.js.gz +0 -0
  435. package/dist/web/assets/sqlite-viewer-DhPv28tq.js.br +0 -0
  436. package/dist/web/assets/sqlite-viewer-DhPv28tq.js.gz +0 -0
  437. package/dist/web/assets/structure-save-dialog-sGUpqs8D.js.br +0 -0
  438. package/dist/web/assets/structure-save-dialog-sGUpqs8D.js.gz +0 -0
  439. package/dist/web/assets/structure-tab-Bo2OmDOc.js.br +0 -0
  440. package/dist/web/assets/structure-tab-Bo2OmDOc.js.gz +0 -0
  441. package/dist/web/assets/system-monitor-body-C475Et9u.js.br +0 -0
  442. package/dist/web/assets/system-monitor-body-C475Et9u.js.gz +0 -0
  443. package/dist/web/assets/tab-host-window-content-BKI6QoDa.js.br +0 -0
  444. package/dist/web/assets/tab-host-window-content-BKI6QoDa.js.gz +0 -0
  445. package/dist/web/assets/table-tab-D-nKWMJR.js.br +0 -0
  446. package/dist/web/assets/telegram-bot-token-field-BeNS2X2k.js.br +0 -0
  447. package/dist/web/assets/telegram-bot-token-field-BeNS2X2k.js.gz +0 -0
  448. package/dist/web/assets/terminal-tab-BbP753Ab.js.br +0 -0
  449. package/dist/web/assets/terminal-tab-BbP753Ab.js.gz +0 -0
  450. package/dist/web/assets/tool-cards-Dh8Ekn2W.js.br +0 -0
  451. package/dist/web/assets/tool-cards-Dh8Ekn2W.js.gz +0 -0
  452. package/dist/web/assets/tools-settings-section-DGZRIULE.js.br +0 -0
  453. package/dist/web/assets/tools-settings-section-DGZRIULE.js.gz +0 -0
  454. package/dist/web/assets/use-inline-blame-BxwM-Wkj.js.br +0 -0
  455. package/dist/web/assets/use-inline-blame-BxwM-Wkj.js.gz +0 -0
  456. package/dist/web/assets/use-lsp-BqvwRKmM.js.br +0 -0
  457. package/dist/web/assets/use-lsp-BqvwRKmM.js.gz +0 -0
  458. package/dist/web/assets/use-process-kill-CVN_c4KF.js.br +0 -0
  459. package/dist/web/assets/use-process-kill-CVN_c4KF.js.gz +0 -0
  460. package/dist/web/assets/use-sql-schema-info-C0wBmR6-.js.br +0 -0
  461. package/dist/web/assets/use-sql-schema-info-C0wBmR6-.js.gz +0 -0
  462. package/dist/web/assets/web-preview-tab-DOgLv8Gt.js.br +0 -0
  463. package/dist/web/assets/web-preview-tab-DOgLv8Gt.js.gz +0 -0
@@ -0,0 +1,46 @@
1
+ import { useEffect, useState } from "react";
2
+ import { api, projectUrl } from "@/lib/api-client";
3
+ import type { EffortStatus } from "../../shared/effort-status";
4
+
5
+ /** Short-lived: it is read from settings files the user may be editing right now. */
6
+ const CACHE_MS = 30_000;
7
+ const cache = new Map<string, { status: EffortStatus | null; at: number }>();
8
+
9
+ /**
10
+ * What overrides the effort pick outside PPM. A session's own status comes over its socket once
11
+ * the server has sent it; a chat with no session yet — the new-chat composer — asks what the
12
+ * project's settings files say, so the chip is right before the first message too.
13
+ */
14
+ export function useEffortStatus(p: {
15
+ projectName?: string;
16
+ providerId?: string;
17
+ model?: string | null;
18
+ sessionStatus: EffortStatus | null | undefined;
19
+ }): EffortStatus | null {
20
+ const { projectName, providerId, model, sessionStatus } = p;
21
+ const key = JSON.stringify([projectName ?? null, providerId ?? null, model ?? null]);
22
+ const wanted = sessionStatus === undefined && !!projectName && !!providerId;
23
+ const [fetched, setFetched] = useState<{ key: string; status: EffortStatus | null } | null>(null);
24
+
25
+ useEffect(() => {
26
+ if (!wanted) return;
27
+ const hit = cache.get(key);
28
+ if (hit && Date.now() - hit.at < CACHE_MS) {
29
+ setFetched({ key, status: hit.status });
30
+ return;
31
+ }
32
+ let active = true;
33
+ const query = model ? `?model=${encodeURIComponent(model)}` : "";
34
+ api.get<{ status: EffortStatus | null }>(`${projectUrl(projectName!)}/chat/providers/${providerId}/effort-status${query}`)
35
+ .then(({ status }) => {
36
+ cache.set(key, { status, at: Date.now() });
37
+ if (active) setFetched({ key, status });
38
+ })
39
+ // Nothing to say then; the chip shows the pick as it always did.
40
+ .catch(() => {});
41
+ return () => { active = false; };
42
+ }, [wanted, key, projectName, providerId, model]);
43
+
44
+ if (sessionStatus !== undefined) return sessionStatus;
45
+ return fetched?.key === key ? fetched.status : cache.get(key)?.status ?? null;
46
+ }
@@ -0,0 +1,35 @@
1
+ import { useSyncExternalStore } from "react";
2
+
3
+ /**
4
+ * Re-renders the caller every half minute, for labels such as "5m ago".
5
+ *
6
+ * The chat's labels used to stay current only because the whole transcript was redrawn on
7
+ * every render of the chat; now that it is not, they ask for the time themselves. One timer for
8
+ * the page, running only while a label is mounted.
9
+ */
10
+ export const RELATIVE_TIME_TICK_MS = 30_000;
11
+
12
+ let tick = 0;
13
+ let timer: ReturnType<typeof setInterval> | undefined;
14
+ const listeners = new Set<() => void>();
15
+
16
+ function subscribe(listener: () => void): () => void {
17
+ listeners.add(listener);
18
+ timer ??= setInterval(() => {
19
+ tick++;
20
+ for (const notify of listeners) notify();
21
+ }, RELATIVE_TIME_TICK_MS);
22
+ return () => {
23
+ listeners.delete(listener);
24
+ if (listeners.size === 0 && timer !== undefined) {
25
+ clearInterval(timer);
26
+ timer = undefined;
27
+ }
28
+ };
29
+ }
30
+
31
+ const snapshot = () => tick;
32
+
33
+ export function useRelativeTimeTick(): number {
34
+ return useSyncExternalStore(subscribe, snapshot, snapshot);
35
+ }
@@ -35,6 +35,10 @@ import {
35
35
  import type { ChatMessage } from "../../types/chat";
36
36
  import { SESSION_FILE_CHANGES_PUSH, type SessionFileChange, type SessionFileChangesPushEvent } from "../../shared/session-file-changes";
37
37
 
38
+ // One array for "not asked yet", which is most chats: a fresh `[]` per render reached every
39
+ // turn's action bar through the context and redrew them all on each render of the chat.
40
+ const NO_FILES: SessionFileChange[] = [];
41
+
38
42
  export function useSessionFileChanges({ projectName, sessionId, messages, isStreaming }: {
39
43
  projectName: string;
40
44
  sessionId: string | null;
@@ -173,5 +177,5 @@ export function useSessionFileChanges({ projectName, sessionId, messages, isStre
173
177
 
174
178
  // A list fetched for the previous session is never shown under this one.
175
179
  const unloadedCount = Math.max(paths.length, count.key === key ? count.n : 0);
176
- return { files: loaded ? state.files : [], paths, unloadedCount, loaded, loading: loadingKey === key && key !== "", refresh, setReviewed };
180
+ return { files: loaded ? state.files : NO_FILES, paths, unloadedCount, loaded, loading: loadingKey === key && key !== "", refresh, setReviewed };
177
181
  }
@@ -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
  }
@@ -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-BtAn_krv.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};