@hienlh/ppm 0.23.6 → 0.23.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +84 -0
- package/CLAUDE.md +21 -1
- package/Dockerfile.test +8 -1
- package/assets/skills/ppm/SKILL.md +1 -1
- package/assets/skills/ppm/references/cli-reference.md +4 -4
- package/assets/skills/ppm/references/http-api.md +29 -1
- package/dist/web/assets/accounts-settings-section-BYWnY9hH.js +1 -0
- package/dist/web/assets/accounts-settings-section-BYWnY9hH.js.br +0 -0
- package/dist/web/assets/accounts-settings-section-BYWnY9hH.js.gz +0 -0
- package/dist/web/assets/{ai-resource-editor-Dn_wB-o5.js → ai-resource-editor-CY4n_Ccv.js} +1 -1
- package/dist/web/assets/ai-resource-editor-CY4n_Ccv.js.br +0 -0
- package/dist/web/assets/ai-resource-editor-CY4n_Ccv.js.gz +0 -0
- package/dist/web/assets/ai-settings-section-Bs3iUW4j.js +1 -0
- package/dist/web/assets/ai-settings-section-Bs3iUW4j.js.br +0 -0
- package/dist/web/assets/ai-settings-section-Bs3iUW4j.js.gz +0 -0
- package/dist/web/assets/ai-settings-section-DDs11XV4.js +1 -0
- package/dist/web/assets/api-client-CJPnCOG-.js +1 -0
- package/dist/web/assets/{api-client-c8YOpTlT.js → api-client-D-SMbdiH.js} +1 -1
- package/dist/web/assets/api-client-D-SMbdiH.js.br +0 -0
- package/dist/web/assets/api-client-D-SMbdiH.js.gz +0 -0
- package/dist/web/assets/api-settings-BDkkhFMq.js +1 -0
- package/dist/web/assets/{api-settings-BmvNoCbn.js → api-settings-Bv9mLCty.js} +1 -1
- package/dist/web/assets/api-settings-Bv9mLCty.js.br +0 -0
- package/dist/web/assets/api-settings-Bv9mLCty.js.gz +0 -0
- package/dist/web/assets/{api-themes-6fOQJgM9.js → api-themes-3wW-zLzU.js} +1 -1
- package/dist/web/assets/appearance-settings-section-C0BoIBmz.js +1 -0
- package/dist/web/assets/appearance-settings-section-C0BoIBmz.js.br +0 -0
- package/dist/web/assets/appearance-settings-section-C0BoIBmz.js.gz +0 -0
- package/dist/web/assets/apps-panel-DXAFsveZ.js +1 -0
- package/dist/web/assets/apps-panel-DXAFsveZ.js.br +0 -0
- package/dist/web/assets/apps-panel-DXAFsveZ.js.gz +0 -0
- package/dist/web/assets/{audio-preview-vaG2cB-k.js → audio-preview-BfES4Cx5.js} +1 -1
- package/dist/web/assets/audio-preview-BfES4Cx5.js.br +0 -0
- package/dist/web/assets/audio-preview-BfES4Cx5.js.gz +0 -0
- package/dist/web/assets/branch-review-tab-CA8hPSX9.js +1 -0
- package/dist/web/assets/branch-review-tab-CA8hPSX9.js.br +0 -0
- package/dist/web/assets/branch-review-tab-CA8hPSX9.js.gz +0 -0
- package/dist/web/assets/{button-Ci9EUgqd.js → button-DeAyLH9U.js} +1 -1
- package/dist/web/assets/button-DeAyLH9U.js.br +0 -0
- package/dist/web/assets/button-DeAyLH9U.js.gz +0 -0
- package/dist/web/assets/{chat-preparation-cache-BSIQGiWx.js → chat-preparation-cache-CcCd2g7A.js} +1 -1
- package/dist/web/assets/chat-preparation-cache-CcCd2g7A.js.br +0 -0
- package/dist/web/assets/chat-preparation-cache-CcCd2g7A.js.gz +0 -0
- package/dist/web/assets/chat-tab-BWi_bUzA.js +1 -0
- package/dist/web/assets/chat-tab-BWi_bUzA.js.br +0 -0
- package/dist/web/assets/chat-tab-BWi_bUzA.js.gz +0 -0
- package/dist/web/assets/chat-tab-BvJhIaVE.js +15 -0
- package/dist/web/assets/chat-tab-BvJhIaVE.js.br +0 -0
- package/dist/web/assets/chat-tab-BvJhIaVE.js.gz +0 -0
- package/dist/web/assets/code-editor-OJUdLVnn.js +7 -0
- package/dist/web/assets/code-editor-OJUdLVnn.js.br +0 -0
- package/dist/web/assets/code-editor-OJUdLVnn.js.gz +0 -0
- package/dist/web/assets/codex-reset-credit-button-Dgxy_VNp.js +1 -0
- package/dist/web/assets/codex-reset-credit-button-Dgxy_VNp.js.br +0 -0
- package/dist/web/assets/codex-reset-credit-button-Dgxy_VNp.js.gz +0 -0
- package/dist/web/assets/{conflict-editor-BA3y-qSH.js → conflict-editor-BpKW_vbL.js} +1 -1
- package/dist/web/assets/conflict-editor-BpKW_vbL.js.br +0 -0
- package/dist/web/assets/conflict-editor-BpKW_vbL.js.gz +0 -0
- package/dist/web/assets/context-menu-7OX80HDB.js +1 -0
- package/dist/web/assets/context-menu-7OX80HDB.js.br +0 -0
- package/dist/web/assets/context-menu-7OX80HDB.js.gz +0 -0
- package/dist/web/assets/{csv-preview-BioxkrQF.js → csv-preview-COYdTABa.js} +1 -1
- package/dist/web/assets/csv-preview-COYdTABa.js.br +0 -0
- package/dist/web/assets/csv-preview-COYdTABa.js.gz +0 -0
- package/dist/web/assets/{data-grid-overlay-editor-CQRVKr7y.js → data-grid-overlay-editor-CeZoduke.js} +1 -1
- package/dist/web/assets/data-grid-overlay-editor-CeZoduke.js.br +0 -0
- package/dist/web/assets/data-grid-overlay-editor-CeZoduke.js.gz +0 -0
- package/dist/web/assets/{database-viewer-BSoJ0E6p.js → database-viewer-BQcBqCKm.js} +1 -1
- package/dist/web/assets/database-viewer-BQcBqCKm.js.br +0 -0
- package/dist/web/assets/database-viewer-BQcBqCKm.js.gz +0 -0
- package/dist/web/assets/{design-export-client-ChMcMoqW.js → design-export-client-OrnGCSwu.js} +1 -1
- package/dist/web/assets/design-export-client-OrnGCSwu.js.br +0 -0
- package/dist/web/assets/design-export-client-OrnGCSwu.js.gz +0 -0
- package/dist/web/assets/{design-responsive-dialog-DNBhJJLf.js → design-responsive-dialog-vJjQrC4n.js} +1 -1
- package/dist/web/assets/design-responsive-dialog-vJjQrC4n.js.br +0 -0
- package/dist/web/assets/design-responsive-dialog-vJjQrC4n.js.gz +0 -0
- package/dist/web/assets/design-tab-BbmFk38H.js +33 -0
- package/dist/web/assets/design-tab-BbmFk38H.js.br +0 -0
- package/dist/web/assets/design-tab-BbmFk38H.js.gz +0 -0
- package/dist/web/assets/{designs-sidebar-panel-DHh5QsH9.js → designs-sidebar-panel-D2kXwB8B.js} +1 -1
- package/dist/web/assets/designs-sidebar-panel-D2kXwB8B.js.br +0 -0
- package/dist/web/assets/designs-sidebar-panel-D2kXwB8B.js.gz +0 -0
- package/dist/web/assets/dialog-Bocc0Fgb.js +1 -0
- package/dist/web/assets/dialog-Bocc0Fgb.js.br +0 -0
- package/dist/web/assets/dialog-Bocc0Fgb.js.gz +0 -0
- package/dist/web/assets/{diff-viewer-lctWoSmG.js → diff-viewer-Bj4DT6Mj.js} +1 -1
- package/dist/web/assets/diff-viewer-Bj4DT6Mj.js.br +0 -0
- package/dist/web/assets/diff-viewer-Bj4DT6Mj.js.gz +0 -0
- package/dist/web/assets/{docx-preview-C9XdKEj1.js → docx-preview-C2QqNGRE.js} +1 -1
- package/dist/web/assets/docx-preview-C2QqNGRE.js.br +0 -0
- package/dist/web/assets/docx-preview-C2QqNGRE.js.gz +0 -0
- package/dist/web/assets/editor-language-service-COqB2tuv.js +1 -0
- package/dist/web/assets/editor-language-service-COqB2tuv.js.br +3 -0
- package/dist/web/assets/editor-language-service-COqB2tuv.js.gz +0 -0
- package/dist/web/assets/explorer-body-DGrYajDN.js +2 -0
- package/dist/web/assets/explorer-body-DGrYajDN.js.br +0 -0
- package/dist/web/assets/explorer-body-DGrYajDN.js.gz +0 -0
- package/dist/web/assets/explorer-window-content-DLzkODTP.js +1 -0
- package/dist/web/assets/explorer-window-content-DLzkODTP.js.br +0 -0
- package/dist/web/assets/explorer-window-content-DLzkODTP.js.gz +0 -0
- package/dist/web/assets/{extension-manager-section-rbkXsZVR.js → extension-manager-section-Bu0qcB2i.js} +1 -1
- package/dist/web/assets/extension-manager-section-Bu0qcB2i.js.br +0 -0
- package/dist/web/assets/extension-manager-section-Bu0qcB2i.js.gz +0 -0
- package/dist/web/assets/{extension-webview-uPO0WgCq.js → extension-webview-G_WJ0N52.js} +1 -1
- package/dist/web/assets/extension-webview-G_WJ0N52.js.br +0 -0
- package/dist/web/assets/extension-webview-G_WJ0N52.js.gz +0 -0
- package/dist/web/assets/{file-icons-gx_FBOXY.js → file-icons-l7fNOmdS.js} +1 -1
- package/dist/web/assets/file-icons-l7fNOmdS.js.br +0 -0
- package/dist/web/assets/file-icons-l7fNOmdS.js.gz +0 -0
- package/dist/web/assets/{file-store-D9KE0kQC.js → file-store-B0e7sLag.js} +1 -1
- package/dist/web/assets/file-store-B0e7sLag.js.br +0 -0
- package/dist/web/assets/file-store-B0e7sLag.js.gz +0 -0
- package/dist/web/assets/{files-settings-section-CT7mDb0L.js → files-settings-section-ChZ_CynX.js} +1 -1
- package/dist/web/assets/files-settings-section-ChZ_CynX.js.br +0 -0
- package/dist/web/assets/files-settings-section-ChZ_CynX.js.gz +0 -0
- package/dist/web/assets/format-bytes-__396eCN.js +1 -0
- package/dist/web/assets/{format-file-meta-mQwA6SuY.js → format-file-meta-o1XBuoKS.js} +1 -1
- package/dist/web/assets/format-file-meta-o1XBuoKS.js.br +0 -0
- package/dist/web/assets/format-file-meta-o1XBuoKS.js.gz +0 -0
- package/dist/web/assets/{fs-api-DL36slbd.js → fs-api-CeHKwx95.js} +1 -1
- package/dist/web/assets/fs-api-CeHKwx95.js.br +0 -0
- package/dist/web/assets/fs-api-CeHKwx95.js.gz +0 -0
- package/dist/web/assets/{general-settings-section-DANPfMRN.js → general-settings-section-MSvDEbFa.js} +1 -1
- package/dist/web/assets/general-settings-section-MSvDEbFa.js.br +0 -0
- package/dist/web/assets/general-settings-section-MSvDEbFa.js.gz +0 -0
- package/dist/web/assets/{git-log-panel-BJPkLiEw.js → git-log-panel-gw5_a6j3.js} +1 -1
- package/dist/web/assets/git-log-panel-gw5_a6j3.js.br +0 -0
- package/dist/web/assets/git-log-panel-gw5_a6j3.js.gz +0 -0
- package/dist/web/assets/{git-repo-store-DSypNj19.js → git-repo-store-BpPnah5l.js} +1 -1
- package/dist/web/assets/git-repo-store-BpPnah5l.js.br +0 -0
- package/dist/web/assets/git-repo-store-BpPnah5l.js.gz +0 -0
- package/dist/web/assets/{glide-data-grid-R4PcAntf.js → glide-data-grid-Db2Cl26B.js} +5 -5
- package/dist/web/assets/glide-data-grid-Db2Cl26B.js.br +0 -0
- package/dist/web/assets/glide-data-grid-Db2Cl26B.js.gz +0 -0
- package/dist/web/assets/group-chat-tab-B4etmYTR.js +1 -0
- package/dist/web/assets/group-chat-tab-B4etmYTR.js.br +0 -0
- package/dist/web/assets/group-chat-tab-B4etmYTR.js.gz +0 -0
- package/dist/web/assets/{image-preview-CGdZrmLo.js → image-preview-CjNhpfWw.js} +1 -1
- package/dist/web/assets/index-CtAvmybi.js +52 -0
- package/dist/web/assets/index-CtAvmybi.js.br +0 -0
- package/dist/web/assets/index-CtAvmybi.js.gz +0 -0
- package/dist/web/assets/index-DeCJasyy.css +1 -0
- package/dist/web/assets/index-DeCJasyy.css.br +0 -0
- package/dist/web/assets/index-DeCJasyy.css.gz +0 -0
- package/dist/web/assets/{jira-watcher-section-DHRoyWcG.js → jira-watcher-section-CKSI1Alo.js} +1 -1
- package/dist/web/assets/keybindings-store-C4_yyU4u.js +1 -0
- package/dist/web/assets/{keyboard-shortcuts-section-BKej4mUf.js → keyboard-shortcuts-section-CEaVUc9a.js} +1 -1
- package/dist/web/assets/keyboard-shortcuts-section-CEaVUc9a.js.br +0 -0
- package/dist/web/assets/keyboard-shortcuts-section-CEaVUc9a.js.gz +0 -0
- package/dist/web/assets/language-servers-section-ePtEpnDc.js +2 -0
- package/dist/web/assets/language-servers-section-ePtEpnDc.js.br +0 -0
- package/dist/web/assets/language-servers-section-ePtEpnDc.js.gz +0 -0
- package/dist/web/assets/lsp-client-XzmR3Brr.js +1 -0
- package/dist/web/assets/lsp-client-XzmR3Brr.js.br +0 -0
- package/dist/web/assets/lsp-client-XzmR3Brr.js.gz +0 -0
- package/dist/web/assets/markdown-renderer-CTtDap-l.js +1 -0
- package/dist/web/assets/{markdown-renderer-BHtYqkYZ.js → markdown-renderer-D05fAr57.js} +2 -2
- package/dist/web/assets/markdown-renderer-D05fAr57.js.br +0 -0
- package/dist/web/assets/markdown-renderer-D05fAr57.js.gz +0 -0
- package/dist/web/assets/{media-url-CzUJrREv.js → media-url-C6NumuN5.js} +1 -1
- package/dist/web/assets/metric-chart-canvas-DHJe0VER.js +1 -0
- package/dist/web/assets/metric-chart-canvas-DHJe0VER.js.br +0 -0
- package/dist/web/assets/metric-chart-canvas-DHJe0VER.js.gz +0 -0
- package/dist/web/assets/{mobile-bottom-sheet-CuNi2FRv.js → mobile-bottom-sheet-D4UyOatB.js} +1 -1
- package/dist/web/assets/mobile-bottom-sheet-D4UyOatB.js.br +0 -0
- package/dist/web/assets/mobile-bottom-sheet-D4UyOatB.js.gz +0 -0
- package/dist/web/assets/mobile-explorer-sheet-CcfGdGL8.js +1 -0
- package/dist/web/assets/mobile-explorer-sheet-CcfGdGL8.js.br +0 -0
- package/dist/web/assets/mobile-explorer-sheet-CcfGdGL8.js.gz +0 -0
- package/dist/web/assets/{new-design-dialog-DS_XrpTG.js → new-design-dialog-BgmQopJM.js} +1 -1
- package/dist/web/assets/new-design-dialog-BgmQopJM.js.br +0 -0
- package/dist/web/assets/new-design-dialog-BgmQopJM.js.gz +0 -0
- package/dist/web/assets/notification-store-q5QBklKA.js +1 -0
- package/dist/web/assets/{notifications-settings-section-C05WYqcE.js → notifications-settings-section-BBJ0r9OS.js} +1 -1
- package/dist/web/assets/notifications-settings-section-BBJ0r9OS.js.br +0 -0
- package/dist/web/assets/notifications-settings-section-BBJ0r9OS.js.gz +0 -0
- package/dist/web/assets/{onboarding-entry-CmUqv1kl.js → onboarding-entry-BYOYswsi.js} +1 -1
- package/dist/web/assets/onboarding-entry-BYOYswsi.js.br +0 -0
- package/dist/web/assets/onboarding-entry-BYOYswsi.js.gz +0 -0
- package/dist/web/assets/{onboarding-quick-orientation-DIhWv1CN.js → onboarding-quick-orientation-DPHYFMbA.js} +1 -1
- package/dist/web/assets/onboarding-quick-orientation-DPHYFMbA.js.br +0 -0
- package/dist/web/assets/onboarding-quick-orientation-DPHYFMbA.js.gz +0 -0
- package/dist/web/assets/overview-panel-pkPs44Tv.js +1 -0
- package/dist/web/assets/overview-panel-pkPs44Tv.js.br +0 -0
- package/dist/web/assets/overview-panel-pkPs44Tv.js.gz +0 -0
- package/dist/web/assets/{pdf-preview-qdXmMkOR.js → pdf-preview-c-L_kDAs.js} +1 -1
- package/dist/web/assets/pdf-preview-c-L_kDAs.js.br +0 -0
- package/dist/web/assets/pdf-preview-c-L_kDAs.js.gz +0 -0
- package/dist/web/assets/performance-panel-yPrq0DJV.js +3 -0
- package/dist/web/assets/performance-panel-yPrq0DJV.js.br +0 -0
- package/dist/web/assets/performance-panel-yPrq0DJV.js.gz +0 -0
- package/dist/web/assets/{postgres-viewer-Xvlun_n5.js → postgres-viewer-CnwDCMNd.js} +1 -1
- package/dist/web/assets/postgres-viewer-CnwDCMNd.js.br +0 -0
- package/dist/web/assets/postgres-viewer-CnwDCMNd.js.gz +0 -0
- package/dist/web/assets/{ppmbot-settings-section-D8AES1BA.js → ppmbot-settings-section-BDXoSIDp.js} +1 -1
- package/dist/web/assets/ppmbot-settings-section-BDXoSIDp.js.br +0 -0
- package/dist/web/assets/ppmbot-settings-section-BDXoSIDp.js.gz +0 -0
- package/dist/web/assets/{pptx-export-CG6MRNok.js → pptx-export-D0RDY48h.js} +4 -4
- package/dist/web/assets/pptx-export-D0RDY48h.js.br +0 -0
- package/dist/web/assets/pptx-export-D0RDY48h.js.gz +0 -0
- package/dist/web/assets/{problems-panel-DTBG4beI.js → problems-panel-BgY8oyo9.js} +1 -1
- package/dist/web/assets/problems-panel-BgY8oyo9.js.br +0 -0
- package/dist/web/assets/problems-panel-BgY8oyo9.js.gz +0 -0
- package/dist/web/assets/process-row-format-CaaMcHzn.js +1 -0
- package/dist/web/assets/process-table-BOwDtXuG.js +1 -0
- package/dist/web/assets/process-table-BOwDtXuG.js.br +0 -0
- package/dist/web/assets/process-table-BOwDtXuG.js.gz +0 -0
- package/dist/web/assets/{project-framework-store-XxFXcUpb.js → project-framework-store-UDEMu28U.js} +1 -1
- package/dist/web/assets/{project-store-C5gJXkvb.js → project-store-DGa31y5B.js} +1 -1
- package/dist/web/assets/project-store-DGa31y5B.js.br +0 -0
- package/dist/web/assets/project-store-DGa31y5B.js.gz +0 -0
- package/dist/web/assets/{proxy-settings-section-CqtmbeRj.js → proxy-settings-section-Db6Kc6xG.js} +1 -1
- package/dist/web/assets/proxy-settings-section-Db6Kc6xG.js.br +0 -0
- package/dist/web/assets/proxy-settings-section-Db6Kc6xG.js.gz +0 -0
- package/dist/web/assets/{query-audit-section-UKG_smyt.js → query-audit-section-C0PAXhfT.js} +1 -1
- package/dist/web/assets/query-audit-section-C0PAXhfT.js.br +0 -0
- package/dist/web/assets/query-audit-section-C0PAXhfT.js.gz +0 -0
- package/dist/web/assets/{remote-desktop-clipboard-notice-Djt6cpNL.js → remote-desktop-clipboard-notice-DOVtobj_.js} +1 -1
- package/dist/web/assets/remote-desktop-clipboard-notice-DOVtobj_.js.br +0 -0
- package/dist/web/assets/remote-desktop-clipboard-notice-DOVtobj_.js.gz +0 -0
- package/dist/web/assets/remote-desktop-mobile-sheet-DXlU3msM.js +2 -0
- package/dist/web/assets/remote-desktop-mobile-sheet-DXlU3msM.js.br +0 -0
- package/dist/web/assets/remote-desktop-mobile-sheet-DXlU3msM.js.gz +0 -0
- package/dist/web/assets/remote-desktop-mobile-view-ClV4YTLU.js +1 -0
- package/dist/web/assets/remote-desktop-mobile-view-ClV4YTLU.js.br +0 -0
- package/dist/web/assets/remote-desktop-mobile-view-ClV4YTLU.js.gz +0 -0
- package/dist/web/assets/{remote-desktop-readiness-gate-DNJF8TcF.js → remote-desktop-readiness-gate-BsfoJzdc.js} +1 -1
- package/dist/web/assets/remote-desktop-readiness-gate-BsfoJzdc.js.br +0 -0
- package/dist/web/assets/remote-desktop-readiness-gate-BsfoJzdc.js.gz +0 -0
- package/dist/web/assets/remote-desktop-window-content-kDaXl1_Q.js +1 -0
- package/dist/web/assets/remote-desktop-window-content-kDaXl1_Q.js.br +0 -0
- package/dist/web/assets/remote-desktop-window-content-kDaXl1_Q.js.gz +0 -0
- package/dist/web/assets/{schedules-settings-section-BKoPovy2.js → schedules-settings-section-CvbjQM8z.js} +1 -1
- package/dist/web/assets/schedules-settings-section-CvbjQM8z.js.br +0 -0
- package/dist/web/assets/schedules-settings-section-CvbjQM8z.js.gz +0 -0
- package/dist/web/assets/{scroll-area-XonvWYn_.js → scroll-area-sjOeAfoD.js} +1 -1
- package/dist/web/assets/scroll-area-sjOeAfoD.js.br +0 -0
- package/dist/web/assets/scroll-area-sjOeAfoD.js.gz +0 -0
- package/dist/web/assets/{separator-sQj04Ari.js → separator-9A3PCG1t.js} +1 -1
- package/dist/web/assets/services-panel-CimW47P8.js +1 -0
- package/dist/web/assets/services-panel-CimW47P8.js.br +0 -0
- package/dist/web/assets/services-panel-CimW47P8.js.gz +0 -0
- package/dist/web/assets/settings-body-BTXNtpWL.js +2 -0
- package/dist/web/assets/settings-body-BTXNtpWL.js.br +0 -0
- package/dist/web/assets/settings-body-BTXNtpWL.js.gz +0 -0
- package/dist/web/assets/settings-store-DvftLqzy.js +2 -0
- package/dist/web/assets/settings-store-DvftLqzy.js.br +0 -0
- package/dist/web/assets/settings-store-DvftLqzy.js.gz +0 -0
- package/dist/web/assets/settings-tab-CGhaRXjs.js +1 -0
- package/dist/web/assets/settings-window-content--Uyg_Psr.js +1 -0
- package/dist/web/assets/sortable-header-DUW9T1Hz.js +1 -0
- package/dist/web/assets/sortable-header-DUW9T1Hz.js.br +0 -0
- package/dist/web/assets/sortable-header-DUW9T1Hz.js.gz +0 -0
- package/dist/web/assets/{sql-query-editor-BjIMi9Wk.js → sql-query-editor-Dn-cgDrW.js} +1 -1
- package/dist/web/assets/sql-query-editor-Dn-cgDrW.js.br +0 -0
- package/dist/web/assets/sql-query-editor-Dn-cgDrW.js.gz +0 -0
- package/dist/web/assets/{sqlite-viewer-BNcA6Irq.js → sqlite-viewer-B0NfaMjq.js} +1 -1
- package/dist/web/assets/sqlite-viewer-B0NfaMjq.js.br +0 -0
- package/dist/web/assets/sqlite-viewer-B0NfaMjq.js.gz +0 -0
- package/dist/web/assets/system-monitor-body-CxCfRQFb.js +2 -0
- package/dist/web/assets/system-monitor-body-CxCfRQFb.js.br +0 -0
- package/dist/web/assets/system-monitor-body-CxCfRQFb.js.gz +0 -0
- package/dist/web/assets/system-monitor-tab-Cb3EZUdp.js +1 -0
- package/dist/web/assets/system-monitor-window-content-51CA-2PH.js +1 -0
- package/dist/web/assets/{tab-host-window-content-CIRGNCvi.js → tab-host-window-content-CSrcmKNG.js} +1 -1
- package/dist/web/assets/tab-host-window-content-CSrcmKNG.js.br +0 -0
- package/dist/web/assets/tab-host-window-content-CSrcmKNG.js.gz +0 -0
- package/dist/web/assets/{team-member-sheet-CwXpLi3X.js → team-member-sheet-D4X6nh-x.js} +2 -2
- package/dist/web/assets/team-member-sheet-D4X6nh-x.js.br +0 -0
- package/dist/web/assets/team-member-sheet-D4X6nh-x.js.gz +0 -0
- package/dist/web/assets/{team-member-window-content-4swiiDz7.js → team-member-window-content-BxkbGVIL.js} +1 -1
- package/dist/web/assets/team-member-window-content-BxkbGVIL.js.br +0 -0
- package/dist/web/assets/team-member-window-content-BxkbGVIL.js.gz +0 -0
- package/dist/web/assets/{terminal-tab-BGcdtMMT.js → terminal-tab-BYo34IqU.js} +3 -3
- package/dist/web/assets/terminal-tab-BYo34IqU.js.br +0 -0
- package/dist/web/assets/terminal-tab-BYo34IqU.js.gz +0 -0
- package/dist/web/assets/{tool-cards-D0-krtA2.js → tool-cards-DvXjOped.js} +4 -4
- package/dist/web/assets/tool-cards-DvXjOped.js.br +0 -0
- package/dist/web/assets/tool-cards-DvXjOped.js.gz +0 -0
- package/dist/web/assets/{use-blob-url-CmavyEP8.js → use-blob-url-CISBWKG5.js} +1 -1
- package/dist/web/assets/use-inline-blame-Br6mheS4.js +16 -0
- package/dist/web/assets/use-inline-blame-Br6mheS4.js.br +0 -0
- package/dist/web/assets/use-inline-blame-Br6mheS4.js.gz +0 -0
- package/dist/web/assets/use-lsp-BpJmvQ0n.js +6 -0
- package/dist/web/assets/use-lsp-BpJmvQ0n.js.br +0 -0
- package/dist/web/assets/use-lsp-BpJmvQ0n.js.gz +0 -0
- package/dist/web/assets/{use-monaco-theme-C88KphGx.js → use-monaco-theme-UGOzyIhv.js} +1 -1
- package/dist/web/assets/use-process-kill-CyiiUD1E.js +1 -0
- package/dist/web/assets/use-process-kill-CyiiUD1E.js.br +0 -0
- package/dist/web/assets/use-process-kill-CyiiUD1E.js.gz +0 -0
- package/dist/web/assets/{use-websocket-Chk9guIU.js → use-websocket-Dpl21cHG.js} +1 -1
- package/dist/web/assets/{vendor-ui-BHh12_0v.js → vendor-ui-P9Ym7hCv.js} +1 -1
- package/dist/web/assets/vendor-ui-P9Ym7hCv.js.br +0 -0
- package/dist/web/assets/vendor-ui-P9Ym7hCv.js.gz +0 -0
- package/dist/web/assets/video-preview-D6Jw-IZK.js +1 -0
- package/dist/web/assets/video-preview-D6Jw-IZK.js.br +0 -0
- package/dist/web/assets/video-preview-D6Jw-IZK.js.gz +0 -0
- package/dist/web/assets/voice-settings-section-CcHQDYzN.js +1 -0
- package/dist/web/assets/voice-settings-section-CcHQDYzN.js.br +0 -0
- package/dist/web/assets/voice-settings-section-CcHQDYzN.js.gz +0 -0
- package/dist/web/assets/ws-auth-CqI8-aoA.js +1 -0
- package/dist/web/index.html +20 -20
- package/dist/web/index.html.br +0 -0
- package/dist/web/index.html.gz +0 -0
- package/dist/web/sw.js +1 -1
- package/dist/web/sw.js.br +0 -0
- package/dist/web/sw.js.gz +0 -0
- package/docs/deployment-guide.md +23 -0
- package/package.json +1 -1
- package/release-from-worktree.sh +224 -0
- package/src/cli/commands/config-cmd.ts +12 -0
- package/src/providers/claude-agent-sdk.ts +65 -2
- package/src/providers/codex-app-server/codex-jsonrpc-client.ts +16 -1
- package/src/providers/codex-app-server/codex-provider.ts +39 -7
- package/src/providers/provider-probe.ts +63 -0
- package/src/providers/registry.ts +109 -29
- package/src/server/index.ts +9 -0
- package/src/server/middleware/auth.ts +5 -1
- package/src/server/routes/cross-origin-guard.ts +20 -0
- package/src/server/routes/git.ts +40 -4
- package/src/server/routes/lsp.ts +97 -4
- package/src/server/routes/resources.ts +72 -9
- package/src/server/routes/settings.ts +19 -1
- package/src/server/routes/speech.ts +66 -0
- package/src/server/routes/system-services.ts +76 -0
- package/src/server/routes/tunnel.ts +33 -1
- package/src/server/ws/chat.ts +74 -3
- package/src/services/codex-account-login.ts +26 -2
- package/src/services/codex-reset-credit.service.ts +16 -3
- package/src/services/compaction-savings.ts +127 -0
- package/src/services/db.service.ts +123 -8
- package/src/services/fs-ops/fs-ops-trash.service.ts +22 -9
- package/src/services/git-refs/for-each-ref.ts +118 -0
- package/src/services/git.service.ts +25 -2
- package/src/services/host-info/spawn-runner.ts +48 -4
- package/src/services/jsonl-transcript-parser.ts +7 -42
- package/src/services/lsp/lsp-install.ts +289 -0
- package/src/services/lsp/lsp-manager.ts +160 -29
- package/src/services/lsp/server-registry.ts +120 -4
- package/src/services/named-tunnel/named-tunnel-config.ts +8 -2
- package/src/services/named-tunnel/named-tunnel-setup.service.ts +4 -0
- package/src/services/read-lines.ts +54 -0
- package/src/services/speech-to-text/whisper-catalog.ts +142 -0
- package/src/services/speech-to-text/whisper-download.ts +113 -0
- package/src/services/speech-to-text/whisper-hallucinations.ts +51 -0
- package/src/services/speech-to-text/whisper-install.service.ts +247 -0
- package/src/services/speech-to-text/whisper-paths.ts +62 -0
- package/src/services/speech-to-text/whisper-transcribe.service.ts +117 -0
- package/src/services/supervisor.ts +94 -11
- package/src/services/system-metrics/cpu-details-linux.ts +252 -0
- package/src/services/system-metrics/cpu-memory-collector.ts +140 -18
- package/src/services/system-metrics/device-collector-linux.ts +31 -0
- package/src/services/system-metrics/device-collector-types.ts +40 -0
- package/src/services/system-metrics/disk-devices-linux.ts +156 -0
- package/src/services/system-metrics/disk-inventory-linux.ts +150 -0
- package/src/services/system-metrics/fans-linux.ts +51 -0
- package/src/services/system-metrics/gpu-api-versions.ts +120 -0
- package/src/services/system-metrics/gpu-devices-linux.ts +370 -0
- package/src/services/system-metrics/gpu-fdinfo-linux.ts +253 -0
- package/src/services/system-metrics/hardware-inventory.ts +50 -0
- package/src/services/system-metrics/linux-fs.ts +43 -0
- package/src/services/system-metrics/memory-darwin.ts +91 -0
- package/src/services/system-metrics/memory-linux.ts +156 -0
- package/src/services/system-metrics/net-devices-linux.ts +114 -0
- package/src/services/system-metrics/net-inventory-linux.ts +100 -0
- package/src/services/system-metrics/partitions-linux.ts +158 -0
- package/src/services/system-metrics/process-collector-linux.ts +58 -6
- package/src/services/system-metrics/process-collector-types.ts +8 -1
- package/src/services/system-metrics/process-details-darwin.ts +166 -0
- package/src/services/system-metrics/process-details-linux.ts +150 -0
- package/src/services/system-metrics/process-grouping.ts +2 -1
- package/src/services/system-metrics/process-rows-builder.ts +2 -0
- package/src/services/system-metrics/process-swap-linux.ts +37 -0
- package/src/services/system-metrics/signal-executor.ts +84 -0
- package/src/services/system-metrics/signal-request-handler.ts +92 -0
- package/src/services/system-metrics/system-metrics-platform.ts +30 -4
- package/src/services/system-metrics/system-metrics-tick.ts +73 -4
- package/src/services/system-metrics/system-metrics.service.ts +87 -2
- package/src/services/system-metrics/udev-db.ts +40 -0
- package/src/services/system-services/app-cgroup-linux.ts +115 -0
- package/src/services/system-services/app-icon-service.ts +31 -0
- package/src/services/system-services/app-icons-linux.ts +124 -0
- package/src/services/system-services/apps-linux.ts +174 -0
- package/src/services/system-services/desktop-entry.ts +103 -0
- package/src/services/system-services/service-guard.ts +124 -0
- package/src/services/system-services/systemd-collector.ts +203 -0
- package/src/services/system-services/systemd-parse.ts +162 -0
- package/src/shared/prompt-cache-idle.ts +197 -0
- package/src/shared/turn-usage.ts +85 -1
- package/src/types/chat.ts +27 -0
- package/src/types/config.ts +14 -0
- package/src/types/git.ts +41 -0
- package/src/types/system-hardware.ts +137 -0
- package/src/types/system-metrics.ts +231 -2
- package/src/types/system-services.ts +73 -0
- package/src/web/components/branch-review/branch-review-tab.tsx +20 -20
- package/src/web/components/branch-review/branch-review-tree-row.tsx +1 -13
- package/src/web/components/chat/chat-tab.tsx +3 -0
- package/src/web/components/chat/compaction-divider.tsx +48 -0
- package/src/web/components/chat/idle-cache-notice.tsx +67 -0
- package/src/web/components/chat/message-input.tsx +48 -13
- package/src/web/components/chat/message-list.tsx +15 -0
- package/src/web/components/chat/prompt-cache-chip.tsx +74 -0
- package/src/web/components/editor/code-editor.tsx +1 -0
- package/src/web/components/editor/editor-language-service.tsx +11 -3
- package/src/web/components/editor/lsp-status.tsx +115 -13
- package/src/web/components/git/branch-picker.tsx +419 -0
- package/src/web/components/git/branch-select.tsx +34 -0
- package/src/web/components/git/create-worktree-dialog.tsx +17 -16
- package/src/web/components/git/git-repo-picker.tsx +28 -40
- package/src/web/components/layout/status-bar.tsx +42 -19
- package/src/web/components/settings/accounts/account-card.tsx +5 -1
- package/src/web/components/settings/ai-settings-section.tsx +67 -3
- package/src/web/components/settings/appearance-settings-section.tsx +2 -28
- package/src/web/components/settings/language-servers-section.tsx +362 -0
- package/src/web/components/settings/settings-categories.ts +8 -3
- package/src/web/components/settings/settings-section-content.tsx +2 -0
- package/src/web/components/settings/voice-settings-section.tsx +283 -0
- package/src/web/components/system/apps/app-row.tsx +110 -0
- package/src/web/components/system/apps/app-rows.ts +140 -0
- package/src/web/components/system/apps/apps-panel.tsx +129 -0
- package/src/web/components/system/metric-chart-canvas.tsx +79 -3
- package/src/web/components/system/overview-cards/card-shell.tsx +54 -0
- package/src/web/components/system/overview-cards/cpu-card.tsx +11 -6
- package/src/web/components/system/overview-cards/disk-card.tsx +11 -6
- package/src/web/components/system/overview-cards/gpu-card.tsx +16 -6
- package/src/web/components/system/overview-cards/mem-card.tsx +11 -6
- package/src/web/components/system/overview-cards/net-card.tsx +11 -6
- package/src/web/components/system/overview-device-target.ts +69 -0
- package/src/web/components/system/overview-panel.tsx +15 -1
- package/src/web/components/system/performance/cpu-core-grid.tsx +74 -0
- package/src/web/components/system/performance/cpu-detail.tsx +220 -0
- package/src/web/components/system/performance/detail-parts.tsx +149 -0
- package/src/web/components/system/performance/device-list.ts +139 -0
- package/src/web/components/system/performance/disk-detail.tsx +64 -0
- package/src/web/components/system/performance/fans-detail.tsx +35 -0
- package/src/web/components/system/performance/gpu-detail.tsx +116 -0
- package/src/web/components/system/performance/memory-detail.tsx +109 -0
- package/src/web/components/system/performance/nic-detail.tsx +55 -0
- package/src/web/components/system/performance/partition-list.tsx +79 -0
- package/src/web/components/system/performance/performance-panel.tsx +206 -0
- package/src/web/components/system/performance/use-hardware-inventory.ts +48 -0
- package/src/web/components/system/process-columns-grid.ts +5 -3
- package/src/web/components/system/process-details-dialog.tsx +116 -0
- package/src/web/components/system/process-group-row.tsx +6 -1
- package/src/web/components/system/process-row-format.ts +6 -0
- package/src/web/components/system/process-row-menu.tsx +72 -0
- package/src/web/components/system/process-row.tsx +7 -1
- package/src/web/components/system/process-table-model.ts +1 -1
- package/src/web/components/system/process-table-sort.ts +8 -4
- package/src/web/components/system/process-table-toolbar.tsx +10 -2
- package/src/web/components/system/process-table-totals.ts +3 -0
- package/src/web/components/system/process-table.tsx +25 -2
- package/src/web/components/system/services/service-action-confirm.tsx +100 -0
- package/src/web/components/system/services/service-columns.ts +103 -0
- package/src/web/components/system/services/service-details-sheet.tsx +97 -0
- package/src/web/components/system/services/service-resources.ts +105 -0
- package/src/web/components/system/services/service-row.tsx +146 -0
- package/src/web/components/system/services/service-rows.ts +92 -0
- package/src/web/components/system/services/service-sort.ts +90 -0
- package/src/web/components/system/services/services-header.tsx +51 -0
- package/src/web/components/system/services/services-panel.tsx +207 -0
- package/src/web/components/system/services/use-services.ts +92 -0
- package/src/web/components/system/sortable-header.tsx +13 -8
- package/src/web/components/system/sysmon-preferences.tsx +85 -0
- package/src/web/components/system/system-monitor-body.tsx +101 -43
- package/src/web/components/system/system-monitor-window-content.tsx +2 -3
- package/src/web/components/system/use-process-signal.ts +87 -0
- package/src/web/components/tunnels/public-tunnel-switch.tsx +82 -0
- package/src/web/components/tunnels/tunnel-manager-tab.tsx +4 -0
- package/src/web/components/ui/dialog.tsx +14 -1
- package/src/web/components/ui/search-select.tsx +279 -0
- package/src/web/components/ui/start-ellipsis.tsx +18 -0
- package/src/web/hooks/use-chat.ts +28 -0
- package/src/web/hooks/use-global-keybindings.ts +7 -5
- package/src/web/hooks/use-lsp.ts +23 -2
- package/src/web/hooks/use-minute-clock.ts +20 -0
- package/src/web/hooks/use-whisper-voice-input.ts +113 -0
- package/src/web/lib/api-tunnels.ts +19 -0
- package/src/web/lib/branch-select-items.ts +29 -0
- package/src/web/lib/cpu-graph-mode.ts +90 -0
- package/src/web/lib/format-bytes.ts +14 -0
- package/src/web/lib/git-ref-picker.ts +120 -0
- package/src/web/lib/lsp/lsp-client.ts +32 -0
- package/src/web/lib/search-select-rows.ts +55 -0
- package/src/web/lib/temperature.ts +27 -0
- package/src/web/lib/voice-wav.ts +69 -0
- package/src/web/stores/git-status-store.ts +31 -17
- package/src/web/stores/keybindings-store.ts +14 -1
- package/src/web/stores/settings-store.ts +65 -0
- package/src/web/styles/globals.css +11 -0
- package/dist/web/assets/accounts-settings-section-DUVO32SQ.js +0 -1
- package/dist/web/assets/accounts-settings-section-DUVO32SQ.js.br +0 -0
- package/dist/web/assets/accounts-settings-section-DUVO32SQ.js.gz +0 -0
- package/dist/web/assets/ai-resource-editor-Dn_wB-o5.js.br +0 -0
- package/dist/web/assets/ai-resource-editor-Dn_wB-o5.js.gz +0 -0
- package/dist/web/assets/ai-settings-section-CEbW8jRy.js +0 -1
- package/dist/web/assets/ai-settings-section-CEbW8jRy.js.br +0 -0
- package/dist/web/assets/ai-settings-section-CEbW8jRy.js.gz +0 -0
- package/dist/web/assets/ai-settings-section-D-mwEYFZ.js +0 -1
- package/dist/web/assets/api-client-BgedDTvo.js +0 -1
- package/dist/web/assets/api-client-c8YOpTlT.js.br +0 -0
- package/dist/web/assets/api-client-c8YOpTlT.js.gz +0 -0
- package/dist/web/assets/api-settings-BmvNoCbn.js.br +0 -0
- package/dist/web/assets/api-settings-BmvNoCbn.js.gz +0 -0
- package/dist/web/assets/api-settings-Bti1-Zn3.js +0 -1
- package/dist/web/assets/appearance-settings-section-tw6TpFb6.js +0 -1
- package/dist/web/assets/appearance-settings-section-tw6TpFb6.js.br +0 -0
- package/dist/web/assets/appearance-settings-section-tw6TpFb6.js.gz +0 -0
- package/dist/web/assets/audio-preview-vaG2cB-k.js.br +0 -0
- package/dist/web/assets/audio-preview-vaG2cB-k.js.gz +0 -0
- package/dist/web/assets/branch-review-tab-MBuMWp_i.js +0 -1
- package/dist/web/assets/branch-review-tab-MBuMWp_i.js.br +0 -0
- package/dist/web/assets/branch-review-tab-MBuMWp_i.js.gz +0 -0
- package/dist/web/assets/button-Ci9EUgqd.js.br +0 -0
- package/dist/web/assets/button-Ci9EUgqd.js.gz +0 -0
- package/dist/web/assets/chat-preparation-cache-BSIQGiWx.js.br +0 -0
- package/dist/web/assets/chat-preparation-cache-BSIQGiWx.js.gz +0 -0
- package/dist/web/assets/chat-tab-DVvnqhw6.js +0 -1
- package/dist/web/assets/chat-tab-DVvnqhw6.js.br +0 -0
- package/dist/web/assets/chat-tab-DVvnqhw6.js.gz +0 -0
- package/dist/web/assets/chat-tab-DaEHva22.js +0 -15
- package/dist/web/assets/chat-tab-DaEHva22.js.br +0 -0
- package/dist/web/assets/chat-tab-DaEHva22.js.gz +0 -0
- package/dist/web/assets/code-editor-Bu9lhTVp.js +0 -7
- package/dist/web/assets/code-editor-Bu9lhTVp.js.br +0 -0
- package/dist/web/assets/code-editor-Bu9lhTVp.js.gz +0 -0
- package/dist/web/assets/codex-reset-credit-button-CbmE5mRX.js +0 -1
- package/dist/web/assets/codex-reset-credit-button-CbmE5mRX.js.br +0 -0
- package/dist/web/assets/codex-reset-credit-button-CbmE5mRX.js.gz +0 -0
- package/dist/web/assets/conflict-editor-BA3y-qSH.js.br +0 -0
- package/dist/web/assets/conflict-editor-BA3y-qSH.js.gz +0 -0
- package/dist/web/assets/context-menu-CjYTq8DI.js +0 -1
- package/dist/web/assets/context-menu-CjYTq8DI.js.br +0 -0
- package/dist/web/assets/context-menu-CjYTq8DI.js.gz +0 -0
- package/dist/web/assets/csv-preview-BioxkrQF.js.br +0 -0
- package/dist/web/assets/csv-preview-BioxkrQF.js.gz +0 -0
- package/dist/web/assets/data-grid-overlay-editor-CQRVKr7y.js.br +0 -0
- package/dist/web/assets/data-grid-overlay-editor-CQRVKr7y.js.gz +0 -0
- package/dist/web/assets/database-viewer-BSoJ0E6p.js.br +0 -0
- package/dist/web/assets/database-viewer-BSoJ0E6p.js.gz +0 -0
- package/dist/web/assets/design-export-client-ChMcMoqW.js.br +0 -0
- package/dist/web/assets/design-export-client-ChMcMoqW.js.gz +0 -0
- package/dist/web/assets/design-responsive-dialog-DNBhJJLf.js.br +0 -0
- package/dist/web/assets/design-responsive-dialog-DNBhJJLf.js.gz +0 -0
- package/dist/web/assets/design-tab-iU2CviE3.js +0 -33
- package/dist/web/assets/design-tab-iU2CviE3.js.br +0 -0
- package/dist/web/assets/design-tab-iU2CviE3.js.gz +0 -0
- package/dist/web/assets/designs-sidebar-panel-DHh5QsH9.js.br +0 -0
- package/dist/web/assets/designs-sidebar-panel-DHh5QsH9.js.gz +0 -0
- package/dist/web/assets/dialog-B8clVkyi.js +0 -1
- package/dist/web/assets/dialog-B8clVkyi.js.br +0 -0
- package/dist/web/assets/dialog-B8clVkyi.js.gz +0 -0
- package/dist/web/assets/diff-viewer-lctWoSmG.js.br +0 -0
- package/dist/web/assets/diff-viewer-lctWoSmG.js.gz +0 -0
- package/dist/web/assets/docx-preview-C9XdKEj1.js.br +0 -0
- package/dist/web/assets/docx-preview-C9XdKEj1.js.gz +0 -0
- package/dist/web/assets/editor-language-service-fPG56hQO.js +0 -1
- package/dist/web/assets/editor-language-service-fPG56hQO.js.br +0 -0
- package/dist/web/assets/editor-language-service-fPG56hQO.js.gz +0 -0
- package/dist/web/assets/explorer-body-BgF7FsxI.js +0 -2
- package/dist/web/assets/explorer-body-BgF7FsxI.js.br +0 -0
- package/dist/web/assets/explorer-body-BgF7FsxI.js.gz +0 -0
- package/dist/web/assets/explorer-window-content-C21w_7lf.js +0 -1
- package/dist/web/assets/explorer-window-content-C21w_7lf.js.br +0 -0
- package/dist/web/assets/explorer-window-content-C21w_7lf.js.gz +0 -0
- package/dist/web/assets/extension-manager-section-rbkXsZVR.js.br +0 -0
- package/dist/web/assets/extension-manager-section-rbkXsZVR.js.gz +0 -0
- package/dist/web/assets/extension-webview-uPO0WgCq.js.br +0 -0
- package/dist/web/assets/extension-webview-uPO0WgCq.js.gz +0 -0
- package/dist/web/assets/file-icons-gx_FBOXY.js.br +0 -0
- package/dist/web/assets/file-icons-gx_FBOXY.js.gz +0 -0
- package/dist/web/assets/file-store-D9KE0kQC.js.br +0 -0
- package/dist/web/assets/file-store-D9KE0kQC.js.gz +0 -0
- package/dist/web/assets/files-settings-section-CT7mDb0L.js.br +0 -0
- package/dist/web/assets/files-settings-section-CT7mDb0L.js.gz +0 -0
- package/dist/web/assets/format-bytes-DmSHAKFe.js +0 -1
- package/dist/web/assets/format-file-meta-mQwA6SuY.js.br +0 -0
- package/dist/web/assets/format-file-meta-mQwA6SuY.js.gz +0 -0
- package/dist/web/assets/fs-api-DL36slbd.js.br +0 -0
- package/dist/web/assets/fs-api-DL36slbd.js.gz +0 -0
- package/dist/web/assets/general-settings-section-DANPfMRN.js.br +0 -0
- package/dist/web/assets/general-settings-section-DANPfMRN.js.gz +0 -0
- package/dist/web/assets/git-log-panel-BJPkLiEw.js.br +0 -0
- package/dist/web/assets/git-log-panel-BJPkLiEw.js.gz +0 -0
- package/dist/web/assets/git-repo-store-DSypNj19.js.br +0 -0
- package/dist/web/assets/git-repo-store-DSypNj19.js.gz +0 -0
- package/dist/web/assets/glide-data-grid-R4PcAntf.js.br +0 -0
- package/dist/web/assets/glide-data-grid-R4PcAntf.js.gz +0 -0
- package/dist/web/assets/group-chat-tab-BXMdo8w9.js +0 -1
- package/dist/web/assets/group-chat-tab-BXMdo8w9.js.br +0 -0
- package/dist/web/assets/group-chat-tab-BXMdo8w9.js.gz +0 -0
- package/dist/web/assets/index-C8nGqkKN.js +0 -52
- package/dist/web/assets/index-C8nGqkKN.js.br +0 -0
- package/dist/web/assets/index-C8nGqkKN.js.gz +0 -0
- package/dist/web/assets/index-DvClbTQx.css +0 -1
- package/dist/web/assets/index-DvClbTQx.css.br +0 -0
- package/dist/web/assets/index-DvClbTQx.css.gz +0 -0
- package/dist/web/assets/keybindings-store-BGKlQQAv.js +0 -1
- package/dist/web/assets/keyboard-shortcuts-section-BKej4mUf.js.br +0 -0
- package/dist/web/assets/keyboard-shortcuts-section-BKej4mUf.js.gz +0 -0
- package/dist/web/assets/markdown-renderer-BHtYqkYZ.js.br +0 -0
- package/dist/web/assets/markdown-renderer-BHtYqkYZ.js.gz +0 -0
- package/dist/web/assets/markdown-renderer-vDNuKjel.js +0 -1
- package/dist/web/assets/mobile-bottom-sheet-CuNi2FRv.js.br +0 -0
- package/dist/web/assets/mobile-bottom-sheet-CuNi2FRv.js.gz +0 -0
- package/dist/web/assets/mobile-explorer-sheet-DtvxS7-r.js +0 -1
- package/dist/web/assets/mobile-explorer-sheet-DtvxS7-r.js.br +0 -0
- package/dist/web/assets/mobile-explorer-sheet-DtvxS7-r.js.gz +0 -0
- package/dist/web/assets/new-design-dialog-DS_XrpTG.js.br +0 -0
- package/dist/web/assets/new-design-dialog-DS_XrpTG.js.gz +0 -0
- package/dist/web/assets/notification-store-Dnnj20Ky.js +0 -1
- package/dist/web/assets/notifications-settings-section-C05WYqcE.js.br +0 -0
- package/dist/web/assets/notifications-settings-section-C05WYqcE.js.gz +0 -0
- package/dist/web/assets/onboarding-entry-CmUqv1kl.js.br +0 -0
- package/dist/web/assets/onboarding-entry-CmUqv1kl.js.gz +0 -0
- package/dist/web/assets/onboarding-quick-orientation-DIhWv1CN.js.br +0 -0
- package/dist/web/assets/onboarding-quick-orientation-DIhWv1CN.js.gz +0 -0
- package/dist/web/assets/overview-panel-BZAW_nag.js +0 -1
- package/dist/web/assets/overview-panel-BZAW_nag.js.br +0 -0
- package/dist/web/assets/overview-panel-BZAW_nag.js.gz +0 -0
- package/dist/web/assets/pdf-preview-qdXmMkOR.js.br +0 -0
- package/dist/web/assets/pdf-preview-qdXmMkOR.js.gz +0 -0
- package/dist/web/assets/postgres-viewer-Xvlun_n5.js.br +0 -0
- package/dist/web/assets/postgres-viewer-Xvlun_n5.js.gz +0 -0
- package/dist/web/assets/ppmbot-settings-section-D8AES1BA.js.br +0 -0
- package/dist/web/assets/ppmbot-settings-section-D8AES1BA.js.gz +0 -0
- package/dist/web/assets/pptx-export-CG6MRNok.js.br +0 -0
- package/dist/web/assets/pptx-export-CG6MRNok.js.gz +0 -0
- package/dist/web/assets/problems-panel-DTBG4beI.js.br +0 -0
- package/dist/web/assets/problems-panel-DTBG4beI.js.gz +0 -0
- package/dist/web/assets/process-table-D_gR2XA6.js +0 -1
- package/dist/web/assets/process-table-D_gR2XA6.js.br +0 -0
- package/dist/web/assets/process-table-D_gR2XA6.js.gz +0 -0
- package/dist/web/assets/project-store-C5gJXkvb.js.br +0 -0
- package/dist/web/assets/project-store-C5gJXkvb.js.gz +0 -0
- package/dist/web/assets/proxy-settings-section-CqtmbeRj.js.br +0 -0
- package/dist/web/assets/proxy-settings-section-CqtmbeRj.js.gz +0 -0
- package/dist/web/assets/query-audit-section-UKG_smyt.js.br +0 -0
- package/dist/web/assets/query-audit-section-UKG_smyt.js.gz +0 -0
- package/dist/web/assets/remote-desktop-clipboard-notice-Djt6cpNL.js.br +0 -0
- package/dist/web/assets/remote-desktop-clipboard-notice-Djt6cpNL.js.gz +0 -0
- package/dist/web/assets/remote-desktop-mobile-sheet-BQxhJUkm.js +0 -2
- package/dist/web/assets/remote-desktop-mobile-sheet-BQxhJUkm.js.br +0 -0
- package/dist/web/assets/remote-desktop-mobile-sheet-BQxhJUkm.js.gz +0 -0
- package/dist/web/assets/remote-desktop-mobile-view-DGnT8RY7.js +0 -1
- package/dist/web/assets/remote-desktop-mobile-view-DGnT8RY7.js.br +0 -0
- package/dist/web/assets/remote-desktop-mobile-view-DGnT8RY7.js.gz +0 -0
- package/dist/web/assets/remote-desktop-readiness-gate-DNJF8TcF.js.br +0 -0
- package/dist/web/assets/remote-desktop-readiness-gate-DNJF8TcF.js.gz +0 -0
- package/dist/web/assets/remote-desktop-window-content-Ds0DKmM0.js +0 -1
- package/dist/web/assets/remote-desktop-window-content-Ds0DKmM0.js.br +0 -0
- package/dist/web/assets/remote-desktop-window-content-Ds0DKmM0.js.gz +0 -0
- package/dist/web/assets/schedules-settings-section-BKoPovy2.js.br +0 -0
- package/dist/web/assets/schedules-settings-section-BKoPovy2.js.gz +0 -0
- package/dist/web/assets/scroll-area-XonvWYn_.js.br +0 -0
- package/dist/web/assets/scroll-area-XonvWYn_.js.gz +0 -0
- package/dist/web/assets/settings-body-k2qPgRFe.js +0 -2
- package/dist/web/assets/settings-body-k2qPgRFe.js.br +0 -0
- package/dist/web/assets/settings-body-k2qPgRFe.js.gz +0 -0
- package/dist/web/assets/settings-store-Br5c1efC.js +0 -2
- package/dist/web/assets/settings-store-Br5c1efC.js.br +0 -0
- package/dist/web/assets/settings-store-Br5c1efC.js.gz +0 -0
- package/dist/web/assets/settings-tab-Bb23VdBu.js +0 -1
- package/dist/web/assets/settings-window-content-ClarWusz.js +0 -1
- package/dist/web/assets/sql-query-editor-BjIMi9Wk.js.br +0 -0
- package/dist/web/assets/sql-query-editor-BjIMi9Wk.js.gz +0 -0
- package/dist/web/assets/sqlite-viewer-BNcA6Irq.js.br +0 -0
- package/dist/web/assets/sqlite-viewer-BNcA6Irq.js.gz +0 -0
- package/dist/web/assets/system-monitor-body-D0T3ggt2.js +0 -2
- package/dist/web/assets/system-monitor-body-D0T3ggt2.js.br +0 -0
- package/dist/web/assets/system-monitor-body-D0T3ggt2.js.gz +0 -0
- package/dist/web/assets/system-monitor-tab-I1Igmoey.js +0 -1
- package/dist/web/assets/system-monitor-window-content-C5SeUv1H.js +0 -1
- package/dist/web/assets/tab-host-window-content-CIRGNCvi.js.br +0 -0
- package/dist/web/assets/tab-host-window-content-CIRGNCvi.js.gz +0 -0
- package/dist/web/assets/team-member-sheet-CwXpLi3X.js.br +0 -0
- package/dist/web/assets/team-member-sheet-CwXpLi3X.js.gz +0 -0
- package/dist/web/assets/team-member-window-content-4swiiDz7.js.br +0 -0
- package/dist/web/assets/team-member-window-content-4swiiDz7.js.gz +0 -0
- package/dist/web/assets/terminal-tab-BGcdtMMT.js.br +0 -0
- package/dist/web/assets/terminal-tab-BGcdtMMT.js.gz +0 -0
- package/dist/web/assets/tool-cards-D0-krtA2.js.br +0 -0
- package/dist/web/assets/tool-cards-D0-krtA2.js.gz +0 -0
- package/dist/web/assets/use-inline-blame-pKaXyGU-.js +0 -16
- package/dist/web/assets/use-inline-blame-pKaXyGU-.js.br +0 -0
- package/dist/web/assets/use-inline-blame-pKaXyGU-.js.gz +0 -0
- package/dist/web/assets/use-lsp-71azTXQz.js +0 -6
- package/dist/web/assets/use-lsp-71azTXQz.js.br +0 -0
- package/dist/web/assets/use-lsp-71azTXQz.js.gz +0 -0
- package/dist/web/assets/vendor-ui-BHh12_0v.js.br +0 -0
- package/dist/web/assets/vendor-ui-BHh12_0v.js.gz +0 -0
- package/dist/web/assets/video-preview-DxEX-uGo.js +0 -1
- package/dist/web/assets/video-preview-DxEX-uGo.js.br +0 -0
- package/dist/web/assets/video-preview-DxEX-uGo.js.gz +0 -0
- package/dist/web/assets/ws-auth-kXgsX2Js.js +0 -1
- /package/dist/web/assets/{__vite-browser-external-BpSQWxcq.js → __vite-browser-external-BILfYaAs.js} +0 -0
- /package/dist/web/assets/{run-in-terminal-HIdNgYim.js → run-in-terminal-2pSiup8e.js} +0 -0
- /package/dist/web/assets/{vendor-xterm-DLDtzLib.js → vendor-xterm-DF1JTfsy.js} +0 -0
- /package/dist/web/assets/{vendor-xterm-DLDtzLib.js.br → vendor-xterm-DF1JTfsy.js.br} +0 -0
- /package/dist/web/assets/{vendor-xterm-DLDtzLib.js.gz → vendor-xterm-DF1JTfsy.js.gz} +0 -0
|
@@ -9,9 +9,11 @@
|
|
|
9
9
|
* three things is true: it is working, it is starting, or it is not installed
|
|
10
10
|
* and here is the one command that fixes that.
|
|
11
11
|
*
|
|
12
|
-
* Nothing here installs anything
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* Nothing here installs anything on its own. An editor that reaches out to the
|
|
13
|
+
* network and installs a binary because a file was opened is doing something
|
|
14
|
+
* the user did not ask for — but a button that says Install is the user asking,
|
|
15
|
+
* so the missing server has one, and the command stays for anyone who would
|
|
16
|
+
* rather run it themselves or whose server is not one PPM can install.
|
|
15
17
|
*
|
|
16
18
|
* The same argument is why the *off* state has a chip. A language server is a
|
|
17
19
|
* real process on the host — one was 854 MB resident — so PPM keeps it off
|
|
@@ -21,12 +23,13 @@
|
|
|
21
23
|
* the on-state chip opens.
|
|
22
24
|
*/
|
|
23
25
|
import { useState } from "react";
|
|
24
|
-
import { AlertTriangle, Check, Copy, Loader2, Zap, ZapOff } from "@/lib/icons";
|
|
26
|
+
import { AlertTriangle, Check, Copy, Download, Loader2, Zap, ZapOff } from "@/lib/icons";
|
|
27
|
+
import { Button } from "@/components/ui/button";
|
|
25
28
|
import { Switch } from "@/components/ui/switch";
|
|
26
29
|
import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog";
|
|
27
30
|
import { BottomSheet } from "@/components/ui/mobile-bottom-sheet";
|
|
28
31
|
import { useIsMobile } from "@/hooks/use-is-mobile";
|
|
29
|
-
import type { LspDocumentStatus } from "@/lib/lsp/lsp-client";
|
|
32
|
+
import type { LspDocumentStatus, LspMissingServer } from "@/lib/lsp/lsp-client";
|
|
30
33
|
import type { LspDiagnostic } from "@/hooks/use-lsp";
|
|
31
34
|
|
|
32
35
|
interface LspStatusProps {
|
|
@@ -35,9 +38,16 @@ interface LspStatusProps {
|
|
|
35
38
|
onToggle: (enabled: boolean) => void;
|
|
36
39
|
status: LspDocumentStatus | null;
|
|
37
40
|
diagnostics: LspDiagnostic[];
|
|
41
|
+
/**
|
|
42
|
+
* Install the missing server, and reopen this file against it.
|
|
43
|
+
*
|
|
44
|
+
* Comes from the language service, which is behind a `lazy()` — this component is on the
|
|
45
|
+
* editor's static path, so it may not reach the LSP client itself.
|
|
46
|
+
*/
|
|
47
|
+
onInstall?: (serverId: string) => Promise<void>;
|
|
38
48
|
}
|
|
39
49
|
|
|
40
|
-
export function LspStatus({ enabled, onToggle, status, diagnostics }: LspStatusProps) {
|
|
50
|
+
export function LspStatus({ enabled, onToggle, status, diagnostics, onInstall }: LspStatusProps) {
|
|
41
51
|
const [open, setOpen] = useState(false);
|
|
42
52
|
const isMobile = useIsMobile();
|
|
43
53
|
|
|
@@ -106,6 +116,7 @@ export function LspStatus({ enabled, onToggle, status, diagnostics }: LspStatusP
|
|
|
106
116
|
warnings={warnings}
|
|
107
117
|
isMobile={isMobile}
|
|
108
118
|
onToggle={onToggle}
|
|
119
|
+
onInstall={onInstall}
|
|
109
120
|
onClose={() => setOpen(false)}
|
|
110
121
|
/>
|
|
111
122
|
)}
|
|
@@ -114,17 +125,25 @@ export function LspStatus({ enabled, onToggle, status, diagnostics }: LspStatusP
|
|
|
114
125
|
}
|
|
115
126
|
|
|
116
127
|
function LspStatusDetails({
|
|
117
|
-
status, errors, warnings, isMobile, onToggle, onClose,
|
|
128
|
+
status, errors, warnings, isMobile, onToggle, onInstall, onClose,
|
|
118
129
|
}: {
|
|
119
130
|
status: LspDocumentStatus;
|
|
120
131
|
errors: number;
|
|
121
132
|
warnings: number;
|
|
122
133
|
isMobile: boolean;
|
|
123
134
|
onToggle: (enabled: boolean) => void;
|
|
135
|
+
onInstall?: (serverId: string) => Promise<void>;
|
|
124
136
|
onClose: () => void;
|
|
125
137
|
}) {
|
|
126
138
|
const body = (
|
|
127
|
-
<LspStatusBody
|
|
139
|
+
<LspStatusBody
|
|
140
|
+
status={status}
|
|
141
|
+
errors={errors}
|
|
142
|
+
warnings={warnings}
|
|
143
|
+
isMobile={isMobile}
|
|
144
|
+
onToggle={onToggle}
|
|
145
|
+
onInstall={onInstall}
|
|
146
|
+
/>
|
|
128
147
|
);
|
|
129
148
|
|
|
130
149
|
if (isMobile) {
|
|
@@ -146,13 +165,14 @@ function LspStatusDetails({
|
|
|
146
165
|
}
|
|
147
166
|
|
|
148
167
|
function LspStatusBody({
|
|
149
|
-
status, errors, warnings, isMobile, onToggle,
|
|
168
|
+
status, errors, warnings, isMobile, onToggle, onInstall,
|
|
150
169
|
}: {
|
|
151
170
|
status: LspDocumentStatus;
|
|
152
171
|
errors: number;
|
|
153
172
|
warnings: number;
|
|
154
173
|
isMobile: boolean;
|
|
155
174
|
onToggle: (enabled: boolean) => void;
|
|
175
|
+
onInstall?: (serverId: string) => Promise<void>;
|
|
156
176
|
}) {
|
|
157
177
|
return (
|
|
158
178
|
<div className="p-4 space-y-4 overflow-y-auto text-sm leading-relaxed">
|
|
@@ -181,10 +201,15 @@ function LspStatusBody({
|
|
|
181
201
|
<p>{status.message}</p>
|
|
182
202
|
{status.server && (
|
|
183
203
|
<div className="space-y-2">
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
204
|
+
{status.reason === "not-installed" && status.server.installable && onInstall ? (
|
|
205
|
+
<>
|
|
206
|
+
<p className="text-xs text-muted-foreground">{installNote(status.server.installWith)}</p>
|
|
207
|
+
<InstallServerButton server={status.server} isMobile={isMobile} onInstall={onInstall} />
|
|
208
|
+
<p className="text-xs text-muted-foreground">Or run it yourself:</p>
|
|
209
|
+
</>
|
|
210
|
+
) : (
|
|
211
|
+
<p className="text-xs text-muted-foreground">{cannotInstallNote(status.server.installWith)}</p>
|
|
212
|
+
)}
|
|
188
213
|
<CopyableCommand command={status.server.installHint} isMobile={isMobile} />
|
|
189
214
|
</div>
|
|
190
215
|
)}
|
|
@@ -209,6 +234,83 @@ function LspStatusBody({
|
|
|
209
234
|
);
|
|
210
235
|
}
|
|
211
236
|
|
|
237
|
+
/**
|
|
238
|
+
* What pressing Install will actually do.
|
|
239
|
+
*
|
|
240
|
+
* Worth saying, because the three are not the same promise: two of them leave the machine's own
|
|
241
|
+
* tools untouched, and the rustup one deliberately does not — a rust-analyzer belongs to a
|
|
242
|
+
* toolchain, so PPM adds the component rather than keeping a copy that would be the wrong one
|
|
243
|
+
* for a project pinning another toolchain.
|
|
244
|
+
*/
|
|
245
|
+
function installNote(installWith: LspMissingServer["installWith"]): string {
|
|
246
|
+
switch (installWith) {
|
|
247
|
+
case "go":
|
|
248
|
+
return "PPM builds it with the Go on this machine and keeps the binary in its own folder,"
|
|
249
|
+
+ " leaving your GOBIN alone. A first build takes a minute or two.";
|
|
250
|
+
case "rustup":
|
|
251
|
+
return "PPM asks rustup to add the component to the toolchain this project uses — the same"
|
|
252
|
+
+ " as running the command below yourself.";
|
|
253
|
+
default:
|
|
254
|
+
return "PPM downloads it from npm into its own folder. Nothing you installed globally"
|
|
255
|
+
+ " changes, and this file picks it up without being reopened.";
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/** Why there is no button: either PPM has no toolchain to do it with, or it is a system package. */
|
|
260
|
+
function cannotInstallNote(installWith: LspMissingServer["installWith"]): string {
|
|
261
|
+
switch (installWith) {
|
|
262
|
+
case "go":
|
|
263
|
+
return "Install it, then reopen this file. PPM installs language servers but never toolchains,"
|
|
264
|
+
+ " and it cannot find a Go on this host.";
|
|
265
|
+
case "rustup":
|
|
266
|
+
return "Install it, then reopen this file. PPM installs language servers but never toolchains,"
|
|
267
|
+
+ " and it cannot find rustup on this host.";
|
|
268
|
+
default:
|
|
269
|
+
return "Install it, then reopen this file. This one comes from a system package manager,"
|
|
270
|
+
+ " which PPM will not run on your behalf.";
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* The Install button, and whatever the host said when it did not work.
|
|
276
|
+
*
|
|
277
|
+
* The progress is this component's own state rather than the caller's, so closing the dialog
|
|
278
|
+
* mid-install cancels nothing: the host finishes either way and the file's status is what
|
|
279
|
+
* reports it. Reopening during one shows an idle button, and pressing it again joins the
|
|
280
|
+
* install already running rather than starting a second over the same lockfile.
|
|
281
|
+
*/
|
|
282
|
+
function InstallServerButton({
|
|
283
|
+
server, isMobile, onInstall,
|
|
284
|
+
}: {
|
|
285
|
+
server: LspMissingServer;
|
|
286
|
+
isMobile: boolean;
|
|
287
|
+
onInstall: (serverId: string) => Promise<void>;
|
|
288
|
+
}) {
|
|
289
|
+
const [installing, setInstalling] = useState(false);
|
|
290
|
+
const [error, setError] = useState<string | null>(null);
|
|
291
|
+
|
|
292
|
+
return (
|
|
293
|
+
<>
|
|
294
|
+
<Button
|
|
295
|
+
type="button"
|
|
296
|
+
disabled={installing}
|
|
297
|
+
onClick={() => {
|
|
298
|
+
setInstalling(true);
|
|
299
|
+
setError(null);
|
|
300
|
+
onInstall(server.id)
|
|
301
|
+
.catch((e) => setError(e instanceof Error ? e.message : String(e)))
|
|
302
|
+
.finally(() => setInstalling(false));
|
|
303
|
+
}}
|
|
304
|
+
className={`w-full ${isMobile ? "min-h-11" : ""}`}
|
|
305
|
+
>
|
|
306
|
+
{installing ? <Loader2 className="size-4 animate-spin" /> : <Download className="size-4" />}
|
|
307
|
+
{installing ? `Installing ${server.displayName}…` : `Install ${server.displayName}`}
|
|
308
|
+
</Button>
|
|
309
|
+
{error && <p className="text-xs text-red-500 break-words">{error}</p>}
|
|
310
|
+
</>
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
|
|
212
314
|
function Row({ label, value, mono }: { label: string; value: string; mono?: boolean }) {
|
|
213
315
|
return (
|
|
214
316
|
<div className="flex gap-2 items-baseline">
|
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VS Code's "Select a branch or tag to checkout" quick pick, opened from the
|
|
3
|
+
* branch name in the status bar.
|
|
4
|
+
*
|
|
5
|
+
* Three things are worth knowing before editing this. The list is `GET /refs`,
|
|
6
|
+
* not `/branches`: the rows carry an author, a hash, a subject and an
|
|
7
|
+
* ahead/behind pair per ref, and tags, none of which `/branches` returns. What
|
|
8
|
+
* a picked row *runs* is `checkoutTarget`, not `git checkout <name>` — see the
|
|
9
|
+
* note there about remote refs detaching HEAD. And it is reachable on desktop
|
|
10
|
+
* only, because the status bar it opens from is `hidden md:flex`; the shell is
|
|
11
|
+
* still written to survive a narrow viewport rather than assume one.
|
|
12
|
+
*/
|
|
13
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
14
|
+
import { toast } from "sonner";
|
|
15
|
+
import {
|
|
16
|
+
ArrowDown,
|
|
17
|
+
ArrowUp,
|
|
18
|
+
Check,
|
|
19
|
+
Cloud,
|
|
20
|
+
GitBranch,
|
|
21
|
+
Link2Off,
|
|
22
|
+
Loader2,
|
|
23
|
+
Plus,
|
|
24
|
+
Search,
|
|
25
|
+
Tag,
|
|
26
|
+
} from "@/lib/icons";
|
|
27
|
+
import { api } from "@/lib/api-client";
|
|
28
|
+
import { cn } from "@/lib/utils";
|
|
29
|
+
import { useGitRepo } from "@/hooks/use-git-repo";
|
|
30
|
+
import { refreshGitStatus } from "@/stores/git-status-store";
|
|
31
|
+
import {
|
|
32
|
+
buildRows,
|
|
33
|
+
checkoutTarget,
|
|
34
|
+
firstSelectable,
|
|
35
|
+
localNameFor,
|
|
36
|
+
moveSelection,
|
|
37
|
+
refDetail,
|
|
38
|
+
type PickerAction,
|
|
39
|
+
type PickerRow,
|
|
40
|
+
} from "@/lib/git-ref-picker";
|
|
41
|
+
import { formatRelativeTime } from "../../../shared/blame";
|
|
42
|
+
import type { GitRef } from "../../../types/git";
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Which question the picker is currently asking.
|
|
46
|
+
*
|
|
47
|
+
* "Create new branch from..." is two questions in VS Code's order — the name
|
|
48
|
+
* first, then the ref — so the pending name rides along on the second stage.
|
|
49
|
+
*/
|
|
50
|
+
type Stage =
|
|
51
|
+
| { kind: "pick" }
|
|
52
|
+
| { kind: "name"; then: "create" | "from" }
|
|
53
|
+
| { kind: "pick-ref"; purpose: "from" | "detach"; name?: string };
|
|
54
|
+
|
|
55
|
+
const PLACEHOLDER: Record<Stage["kind"], string> = {
|
|
56
|
+
pick: "Select a branch or tag to checkout",
|
|
57
|
+
name: "Branch name",
|
|
58
|
+
"pick-ref": "Select a ref",
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
function placeholderFor(stage: Stage): string {
|
|
62
|
+
if (stage.kind === "pick-ref") {
|
|
63
|
+
return stage.purpose === "from"
|
|
64
|
+
? "Select a ref to create the branch from"
|
|
65
|
+
: "Select a branch or tag to checkout in detached mode";
|
|
66
|
+
}
|
|
67
|
+
return PLACEHOLDER[stage.kind];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* The selection tint, and why it is not `bg-accent/15` like the command palette
|
|
72
|
+
* and the extension quick pick beside it.
|
|
73
|
+
*
|
|
74
|
+
* shadcn's `accent` is deliberately a hover **surface** in this app — `globals.css`
|
|
75
|
+
* says so, and maps `--color-accent` to `--panel-2` while the brand blue lives in
|
|
76
|
+
* `--color-primary`. A surface at 15% over the panel it is nearly identical to
|
|
77
|
+
* changes almost nothing: measured in a real browser against the dialog's own
|
|
78
|
+
* background, `bg-accent/15` composites to a contrast ratio of **1.01** on a
|
|
79
|
+
* light panel (rgb(243,247,255) → rgb(245,248,255)) and **1.009** on a dark one,
|
|
80
|
+
* i.e. a keyboard selection nobody can see. `bg-primary/15` carries the brand
|
|
81
|
+
* hue and measures 1.21 on both.
|
|
82
|
+
*
|
|
83
|
+
* Same family as the `opacity`-is-not-dimming note in CLAUDE.md: the class reads
|
|
84
|
+
* perfectly well and paints nothing.
|
|
85
|
+
*/
|
|
86
|
+
const SELECTED_ROW = "bg-primary/15 text-text-primary";
|
|
87
|
+
const HOVER_ROW = "hover:bg-primary/10";
|
|
88
|
+
|
|
89
|
+
const REF_ICON: Record<GitRef["type"], typeof GitBranch> = {
|
|
90
|
+
branch: GitBranch,
|
|
91
|
+
remote: Cloud,
|
|
92
|
+
tag: Tag,
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const ACTION_ICON: Record<PickerAction, typeof GitBranch> = {
|
|
96
|
+
create: Plus,
|
|
97
|
+
"create-from": Plus,
|
|
98
|
+
detach: Link2Off,
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export function BranchPicker({
|
|
102
|
+
projectName,
|
|
103
|
+
onClose,
|
|
104
|
+
}: {
|
|
105
|
+
projectName: string;
|
|
106
|
+
onClose: () => void;
|
|
107
|
+
}) {
|
|
108
|
+
const { repo, gitUrl, rebaseStatus } = useGitRepo(projectName);
|
|
109
|
+
const [refs, setRefs] = useState<GitRef[] | null>(null);
|
|
110
|
+
const [loadError, setLoadError] = useState<string | null>(null);
|
|
111
|
+
const [stage, setStage] = useState<Stage>({ kind: "pick" });
|
|
112
|
+
const [query, setQuery] = useState("");
|
|
113
|
+
const [selected, setSelected] = useState(0);
|
|
114
|
+
const [busy, setBusy] = useState(false);
|
|
115
|
+
const inputRef = useRef<HTMLInputElement>(null);
|
|
116
|
+
const listRef = useRef<HTMLDivElement>(null);
|
|
117
|
+
|
|
118
|
+
useEffect(() => {
|
|
119
|
+
if (!repo) return;
|
|
120
|
+
let cancelled = false;
|
|
121
|
+
api
|
|
122
|
+
.get<GitRef[]>(gitUrl("/refs"))
|
|
123
|
+
.then((data) => !cancelled && setRefs(data))
|
|
124
|
+
.catch((e) => !cancelled && setLoadError(e instanceof Error ? e.message : "Could not list refs"));
|
|
125
|
+
return () => {
|
|
126
|
+
cancelled = true;
|
|
127
|
+
};
|
|
128
|
+
}, [repo, gitUrl]);
|
|
129
|
+
|
|
130
|
+
useEffect(() => {
|
|
131
|
+
requestAnimationFrame(() => inputRef.current?.focus());
|
|
132
|
+
}, []);
|
|
133
|
+
|
|
134
|
+
const rows = useMemo(
|
|
135
|
+
() => (stage.kind === "name" ? [] : buildRows(refs ?? [], query, { actions: stage.kind === "pick" })),
|
|
136
|
+
[refs, query, stage.kind],
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
// A new filter invalidates the old index outright: row 12 of the previous
|
|
140
|
+
// list is a different ref, so clamping it would move the highlight silently.
|
|
141
|
+
useEffect(() => {
|
|
142
|
+
setSelected(firstSelectable(rows));
|
|
143
|
+
}, [rows]);
|
|
144
|
+
|
|
145
|
+
useEffect(() => {
|
|
146
|
+
listRef.current?.children[selected]?.scrollIntoView({ block: "nearest" });
|
|
147
|
+
}, [selected]);
|
|
148
|
+
|
|
149
|
+
const commit = useCallback(
|
|
150
|
+
async (work: () => Promise<unknown>, done: string) => {
|
|
151
|
+
setBusy(true);
|
|
152
|
+
try {
|
|
153
|
+
await work();
|
|
154
|
+
} catch (e) {
|
|
155
|
+
setBusy(false);
|
|
156
|
+
toast.error(e instanceof Error ? e.message : "Git command failed");
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
onClose();
|
|
160
|
+
toast.success(done);
|
|
161
|
+
// The status bar still names the branch just left until this lands.
|
|
162
|
+
void refreshGitStatus(projectName, gitUrl, rebaseStatus);
|
|
163
|
+
},
|
|
164
|
+
[onClose, projectName, gitUrl, rebaseStatus],
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
const pickRef = useCallback(
|
|
168
|
+
(ref: GitRef) => {
|
|
169
|
+
if (busy) return;
|
|
170
|
+
if (stage.kind === "pick-ref" && stage.purpose === "detach") {
|
|
171
|
+
void commit(
|
|
172
|
+
() => api.post(gitUrl("/checkout"), { ref: ref.name, mode: "detach" }),
|
|
173
|
+
`Detached HEAD at ${ref.name}`,
|
|
174
|
+
);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
if (stage.kind === "pick-ref" && stage.name) {
|
|
178
|
+
const name = stage.name;
|
|
179
|
+
void commit(
|
|
180
|
+
() => api.post(gitUrl("/branch/create"), { name, from: ref.name }),
|
|
181
|
+
`Created ${name} from ${ref.name}`,
|
|
182
|
+
);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
if (ref.current) {
|
|
186
|
+
onClose();
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const target = checkoutTarget(ref, refs ?? []);
|
|
190
|
+
// `track` lands on the LOCAL branch `-t` creates, not on the remote ref
|
|
191
|
+
// that was picked — naming the remote here would report a branch the user
|
|
192
|
+
// is not on.
|
|
193
|
+
const landedOn = target.mode === "track" ? localNameFor(target.ref) : target.ref;
|
|
194
|
+
void commit(() => api.post(gitUrl("/checkout"), target), `Switched to ${landedOn}`);
|
|
195
|
+
},
|
|
196
|
+
[busy, stage, commit, gitUrl, refs, onClose],
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
const pickAction = useCallback((action: PickerAction) => {
|
|
200
|
+
setQuery("");
|
|
201
|
+
setStage(
|
|
202
|
+
action === "detach"
|
|
203
|
+
? { kind: "pick-ref", purpose: "detach" }
|
|
204
|
+
: { kind: "name", then: action === "create" ? "create" : "from" },
|
|
205
|
+
);
|
|
206
|
+
inputRef.current?.focus();
|
|
207
|
+
}, []);
|
|
208
|
+
|
|
209
|
+
const submitName = useCallback(() => {
|
|
210
|
+
const name = query.trim();
|
|
211
|
+
if (!name || stage.kind !== "name" || busy) return;
|
|
212
|
+
if (stage.then === "from") {
|
|
213
|
+
setStage({ kind: "pick-ref", purpose: "from", name });
|
|
214
|
+
setQuery("");
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
void commit(() => api.post(gitUrl("/branch/create"), { name }), `Created ${name}`);
|
|
218
|
+
}, [query, stage, busy, commit, gitUrl]);
|
|
219
|
+
|
|
220
|
+
function activate(row: PickerRow | undefined) {
|
|
221
|
+
if (!row) return;
|
|
222
|
+
if (row.kind === "action") pickAction(row.action);
|
|
223
|
+
else if (row.kind === "ref") pickRef(row.ref);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function handleKeyDown(e: React.KeyboardEvent) {
|
|
227
|
+
switch (e.key) {
|
|
228
|
+
case "ArrowDown":
|
|
229
|
+
e.preventDefault();
|
|
230
|
+
setSelected((i) => moveSelection(rows, i, 1));
|
|
231
|
+
break;
|
|
232
|
+
case "ArrowUp":
|
|
233
|
+
e.preventDefault();
|
|
234
|
+
setSelected((i) => moveSelection(rows, i, -1));
|
|
235
|
+
break;
|
|
236
|
+
case "Enter":
|
|
237
|
+
e.preventDefault();
|
|
238
|
+
if (stage.kind === "name") submitName();
|
|
239
|
+
else activate(rows[selected]);
|
|
240
|
+
break;
|
|
241
|
+
case "Escape":
|
|
242
|
+
e.preventDefault();
|
|
243
|
+
// Back out one question at a time, the way a multi-step quick pick does.
|
|
244
|
+
if (stage.kind === "pick") onClose();
|
|
245
|
+
else {
|
|
246
|
+
setStage({ kind: "pick" });
|
|
247
|
+
setQuery("");
|
|
248
|
+
}
|
|
249
|
+
break;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return (
|
|
254
|
+
/*
|
|
255
|
+
* The desktop panel is bounded by the shell's PADDING, not by a `vh` cap of
|
|
256
|
+
* its own. `pt-[20vh]` beside `max-h-[80vh]` adds up to exactly 100vh, so
|
|
257
|
+
* the panel's bottom edge landed on the viewport's — measured at 620px tall:
|
|
258
|
+
* top 124, bottom 620, gap 0 — and the last row of the list was sliced by
|
|
259
|
+
* the window edge rather than by a visible container, which reads as a
|
|
260
|
+
* dialog overflowing the screen instead of a list that scrolls.
|
|
261
|
+
*
|
|
262
|
+
* `max-h-full` resolves against the flex container's CONTENT box, so the
|
|
263
|
+
* padding below is subtracted for free and the gap survives any window
|
|
264
|
+
* height. Below `md` the panel is a bottom sheet and *should* sit flush on
|
|
265
|
+
* the bottom edge, so the padding is desktop-only.
|
|
266
|
+
*/
|
|
267
|
+
<div
|
|
268
|
+
className="fixed inset-0 z-50 flex items-end justify-center md:items-start md:px-4 md:pt-[12vh] md:pb-[10vh]"
|
|
269
|
+
onClick={onClose}
|
|
270
|
+
>
|
|
271
|
+
<div className="fixed inset-0 bg-black/50" />
|
|
272
|
+
<div
|
|
273
|
+
role="dialog"
|
|
274
|
+
aria-label="Checkout a branch or tag"
|
|
275
|
+
className="relative z-10 w-full max-w-xl rounded-t-xl md:rounded-xl border border-border bg-background shadow-2xl overflow-hidden max-h-[80vh] md:max-h-full flex flex-col"
|
|
276
|
+
onClick={(e) => e.stopPropagation()}
|
|
277
|
+
onKeyDown={handleKeyDown}
|
|
278
|
+
>
|
|
279
|
+
<div className="flex items-center gap-2 border-b border-border px-3 py-2.5 shrink-0">
|
|
280
|
+
{busy ? (
|
|
281
|
+
<Loader2 className="size-4 text-text-subtle shrink-0 animate-spin" />
|
|
282
|
+
) : (
|
|
283
|
+
<Search className="size-4 text-text-subtle shrink-0" />
|
|
284
|
+
)}
|
|
285
|
+
<input
|
|
286
|
+
ref={inputRef}
|
|
287
|
+
type="text"
|
|
288
|
+
value={query}
|
|
289
|
+
disabled={busy}
|
|
290
|
+
onChange={(e) => setQuery(e.target.value)}
|
|
291
|
+
placeholder={placeholderFor(stage)}
|
|
292
|
+
className="flex-1 bg-transparent text-sm text-text-primary outline-none placeholder:text-text-subtle disabled:opacity-60"
|
|
293
|
+
/>
|
|
294
|
+
<kbd className="hidden sm:inline-flex items-center rounded border border-border bg-surface px-1.5 py-0.5 text-[10px] text-text-subtle font-mono">
|
|
295
|
+
ESC
|
|
296
|
+
</kbd>
|
|
297
|
+
</div>
|
|
298
|
+
|
|
299
|
+
{stage.kind === "name" ? (
|
|
300
|
+
<p className="px-3 py-4 text-xs text-text-3">
|
|
301
|
+
{stage.then === "from"
|
|
302
|
+
? "Press Enter, then choose the ref to branch from."
|
|
303
|
+
: "Press Enter to create the branch from HEAD and switch to it."}
|
|
304
|
+
</p>
|
|
305
|
+
) : (
|
|
306
|
+
<div ref={listRef} className="overflow-y-auto py-1">
|
|
307
|
+
{loadError ? (
|
|
308
|
+
<p className="px-3 py-4 text-sm text-error text-center">{loadError}</p>
|
|
309
|
+
) : !refs ? (
|
|
310
|
+
<p className="px-3 py-4 text-sm text-text-subtle text-center">Loading refs…</p>
|
|
311
|
+
) : rows.length === 0 ? (
|
|
312
|
+
<p className="px-3 py-4 text-sm text-text-subtle text-center">No matching branches or tags</p>
|
|
313
|
+
) : (
|
|
314
|
+
rows.map((row, i) =>
|
|
315
|
+
row.kind === "separator" ? (
|
|
316
|
+
<div
|
|
317
|
+
key={`sep-${row.label}`}
|
|
318
|
+
className="px-3 pt-2 pb-1 text-[10px] uppercase tracking-wide text-text-3 border-t border-border-soft first:border-t-0 first:pt-1"
|
|
319
|
+
>
|
|
320
|
+
{row.label}
|
|
321
|
+
</div>
|
|
322
|
+
) : row.kind === "action" ? (
|
|
323
|
+
<Row
|
|
324
|
+
key={`act-${row.action}`}
|
|
325
|
+
icon={ACTION_ICON[row.action]}
|
|
326
|
+
active={i === selected}
|
|
327
|
+
onSelect={() => pickAction(row.action)}
|
|
328
|
+
label={row.label}
|
|
329
|
+
/>
|
|
330
|
+
) : (
|
|
331
|
+
<RefRow
|
|
332
|
+
key={row.ref.refName}
|
|
333
|
+
refItem={row.ref}
|
|
334
|
+
active={i === selected}
|
|
335
|
+
onSelect={() => pickRef(row.ref)}
|
|
336
|
+
/>
|
|
337
|
+
),
|
|
338
|
+
)
|
|
339
|
+
)}
|
|
340
|
+
</div>
|
|
341
|
+
)}
|
|
342
|
+
</div>
|
|
343
|
+
</div>
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
function Row({
|
|
348
|
+
icon: Icon,
|
|
349
|
+
label,
|
|
350
|
+
active,
|
|
351
|
+
onSelect,
|
|
352
|
+
}: {
|
|
353
|
+
icon: typeof GitBranch;
|
|
354
|
+
label: string;
|
|
355
|
+
active: boolean;
|
|
356
|
+
onSelect: () => void;
|
|
357
|
+
}) {
|
|
358
|
+
return (
|
|
359
|
+
<button
|
|
360
|
+
type="button"
|
|
361
|
+
onClick={onSelect}
|
|
362
|
+
className={cn(
|
|
363
|
+
"flex items-center gap-2.5 w-full px-3 py-2 text-sm text-left transition-colors",
|
|
364
|
+
active ? SELECTED_ROW : "text-text-secondary " + HOVER_ROW,
|
|
365
|
+
)}
|
|
366
|
+
>
|
|
367
|
+
<Icon className="size-4 shrink-0 text-text-3" />
|
|
368
|
+
<span className="truncate">{label}</span>
|
|
369
|
+
</button>
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
function RefRow({
|
|
374
|
+
refItem,
|
|
375
|
+
active,
|
|
376
|
+
onSelect,
|
|
377
|
+
}: {
|
|
378
|
+
refItem: GitRef;
|
|
379
|
+
active: boolean;
|
|
380
|
+
onSelect: () => void;
|
|
381
|
+
}) {
|
|
382
|
+
const Icon = refItem.current ? Check : REF_ICON[refItem.type];
|
|
383
|
+
return (
|
|
384
|
+
<button
|
|
385
|
+
type="button"
|
|
386
|
+
onClick={onSelect}
|
|
387
|
+
className={cn(
|
|
388
|
+
"flex items-start gap-2.5 w-full px-3 py-1.5 text-sm text-left transition-colors",
|
|
389
|
+
active ? SELECTED_ROW : "text-text-secondary " + HOVER_ROW,
|
|
390
|
+
)}
|
|
391
|
+
>
|
|
392
|
+
<Icon className={cn("size-4 shrink-0 mt-0.5", refItem.current ? "text-primary" : "text-text-3")} />
|
|
393
|
+
<span className="flex-1 min-w-0">
|
|
394
|
+
<span className="flex items-baseline gap-2">
|
|
395
|
+
<span className="truncate">{refItem.name}</span>
|
|
396
|
+
<span className="ml-auto shrink-0 flex items-center gap-1.5 text-xs text-text-3">
|
|
397
|
+
{refItem.behind > 0 && (
|
|
398
|
+
<span className="flex items-center gap-0.5">
|
|
399
|
+
<ArrowDown className="size-3" />
|
|
400
|
+
{refItem.behind}
|
|
401
|
+
</span>
|
|
402
|
+
)}
|
|
403
|
+
{refItem.ahead > 0 && (
|
|
404
|
+
<span className="flex items-center gap-0.5">
|
|
405
|
+
<ArrowUp className="size-3" />
|
|
406
|
+
{refItem.ahead}
|
|
407
|
+
</span>
|
|
408
|
+
)}
|
|
409
|
+
{refItem.gone && <span className="text-warning">gone</span>}
|
|
410
|
+
{/* Without the dot, `↑1 1 hour ago` reads as one number twice. */}
|
|
411
|
+
{(refItem.ahead > 0 || refItem.behind > 0 || refItem.gone) && <span aria-hidden>·</span>}
|
|
412
|
+
<span>{formatRelativeTime(Date.parse(refItem.date))}</span>
|
|
413
|
+
</span>
|
|
414
|
+
</span>
|
|
415
|
+
<span className="block truncate text-xs text-text-3">{refDetail(refItem)}</span>
|
|
416
|
+
</span>
|
|
417
|
+
</button>
|
|
418
|
+
);
|
|
419
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The branch picker — Branch Review's two, and Add Worktree's.
|
|
3
|
+
*
|
|
4
|
+
* These were native `<select>`s, on the argument that the OS picker scrolls well
|
|
5
|
+
* and is a good touch target. What that missed is the list: a working repository
|
|
6
|
+
* here has a few dozen local branches and several hundred remote-tracking ones,
|
|
7
|
+
* all named `fix/NX-1234-…`, and a native picker cannot be searched. So it is a
|
|
8
|
+
* `SearchSelect` over the repository's branches; what a branch row says and the
|
|
9
|
+
* order the groups come in are `branchItems`.
|
|
10
|
+
*/
|
|
11
|
+
import { useMemo } from "react";
|
|
12
|
+
import { GitBranch as GitBranchIcon } from "@/lib/icons";
|
|
13
|
+
import { SearchSelect, type SearchSelectProps } from "@/components/ui/search-select";
|
|
14
|
+
import { branchItems } from "@/lib/branch-select-items";
|
|
15
|
+
import type { GitBranch } from "../../../types/git";
|
|
16
|
+
|
|
17
|
+
type BranchSelectProps = Omit<
|
|
18
|
+
SearchSelectProps,
|
|
19
|
+
"items" | "icon" | "placeholder" | "searchPlaceholder" | "emptyText"
|
|
20
|
+
> & { branches: GitBranch[] };
|
|
21
|
+
|
|
22
|
+
export function BranchSelect({ branches, ...rest }: BranchSelectProps) {
|
|
23
|
+
const items = useMemo(() => branchItems(branches), [branches]);
|
|
24
|
+
return (
|
|
25
|
+
<SearchSelect
|
|
26
|
+
{...rest}
|
|
27
|
+
items={items}
|
|
28
|
+
icon={GitBranchIcon}
|
|
29
|
+
placeholder="Select a branch"
|
|
30
|
+
searchPlaceholder="Search branches"
|
|
31
|
+
emptyText="No matching branches"
|
|
32
|
+
/>
|
|
33
|
+
);
|
|
34
|
+
}
|