@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
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mission Center's CPU page, from `/sys/devices/system/cpu`, `/proc` and hwmon.
|
|
3
|
+
* Split in two: the static facts go in the hardware inventory (they cannot change
|
|
4
|
+
* while the kernel is up), the live ones ride the tick.
|
|
5
|
+
*
|
|
6
|
+
* Package power is RAPL's cumulative energy counter, so it needs two samples like
|
|
7
|
+
* any other rate — the caller keeps the previous one.
|
|
8
|
+
*/
|
|
9
|
+
import type { CpuInfo } from "../../types/system-hardware.ts";
|
|
10
|
+
import { readAttr, readNumber, realLinuxFs, type LinuxFs } from "./linux-fs.ts";
|
|
11
|
+
|
|
12
|
+
export const SYS_CPU = "/sys/devices/system/cpu";
|
|
13
|
+
const RAPL_DIR = "/sys/class/powercap";
|
|
14
|
+
const HWMON_DIR = "/sys/class/hwmon";
|
|
15
|
+
|
|
16
|
+
/** `/sys/class/hwmon/<h>/name` of the package sensor, in preference order. */
|
|
17
|
+
const PACKAGE_SENSORS = ["coretemp", "k10temp", "zenpower"];
|
|
18
|
+
|
|
19
|
+
// ---------------------------------------------------------------- static
|
|
20
|
+
|
|
21
|
+
export function readCpuInfo(fs: LinuxFs = realLinuxFs): CpuInfo | undefined {
|
|
22
|
+
const cpuinfo = fs.read("/proc/cpuinfo");
|
|
23
|
+
if (!cpuinfo) return undefined;
|
|
24
|
+
const topology = parseCpuinfoTopology(cpuinfo);
|
|
25
|
+
const caches = readCacheSizes(fs);
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
name: topology.model,
|
|
29
|
+
sockets: topology.sockets,
|
|
30
|
+
physicalCores: topology.physicalCores,
|
|
31
|
+
logicalCores: topology.logicalCores,
|
|
32
|
+
...defined("baseMHz", khzToMhz(readNumber(fs, `${SYS_CPU}/cpu0/cpufreq/base_frequency`))),
|
|
33
|
+
...defined("maxMHz", khzToMhz(readNumber(fs, `${SYS_CPU}/cpu0/cpufreq/cpuinfo_max_freq`))),
|
|
34
|
+
...defined("virtualization", virtualizationName(topology.flags)),
|
|
35
|
+
isVirtualMachine: topology.flags.has("hypervisor"),
|
|
36
|
+
...defined("l1CacheBytes", caches.l1),
|
|
37
|
+
...defined("l2CacheBytes", caches.l2),
|
|
38
|
+
...defined("l3CacheBytes", caches.l3),
|
|
39
|
+
...defined("freqDriver", readAttr(fs, `${SYS_CPU}/cpu0/cpufreq/scaling_driver`)),
|
|
40
|
+
...defined("freqGovernor", readAttr(fs, `${SYS_CPU}/cpu0/cpufreq/scaling_governor`)),
|
|
41
|
+
...defined("powerPreference", readAttr(fs, `${SYS_CPU}/cpu0/cpufreq/energy_performance_preference`)),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface CpuTopology {
|
|
46
|
+
model: string;
|
|
47
|
+
logicalCores: number;
|
|
48
|
+
physicalCores: number;
|
|
49
|
+
sockets: number;
|
|
50
|
+
flags: Set<string>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** `/proc/cpuinfo` is one block per logical CPU. Sockets are the distinct
|
|
54
|
+
* `physical id`s; physical cores are `cpu cores` summed once per socket, which
|
|
55
|
+
* is right for a hybrid part too — the kernel reports the real count there. */
|
|
56
|
+
export function parseCpuinfoTopology(text: string): CpuTopology {
|
|
57
|
+
let model = "";
|
|
58
|
+
const flags = new Set<string>();
|
|
59
|
+
const coresPerSocket = new Map<string, number>();
|
|
60
|
+
let logicalCores = 0;
|
|
61
|
+
let currentSocket = "0";
|
|
62
|
+
|
|
63
|
+
for (const line of text.split("\n")) {
|
|
64
|
+
const sep = line.indexOf(":");
|
|
65
|
+
if (sep < 0) continue;
|
|
66
|
+
const key = line.slice(0, sep).trim();
|
|
67
|
+
const value = line.slice(sep + 1).trim();
|
|
68
|
+
if (key === "processor") { logicalCores++; currentSocket = "0"; }
|
|
69
|
+
else if (key === "model name" && !model) model = value;
|
|
70
|
+
else if (key === "physical id") currentSocket = value;
|
|
71
|
+
else if (key === "cpu cores") coresPerSocket.set(currentSocket, Number(value) || 0);
|
|
72
|
+
else if (key === "flags" && flags.size === 0) for (const f of value.split(/\s+/)) flags.add(f);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const sockets = Math.max(coresPerSocket.size, 1);
|
|
76
|
+
let physicalCores = 0;
|
|
77
|
+
for (const n of coresPerSocket.values()) physicalCores += n;
|
|
78
|
+
return { model, logicalCores, physicalCores: physicalCores || logicalCores, sockets, flags };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Intel publishes `vmx`, AMD `svm`. Mission Center prints the marketing name. */
|
|
82
|
+
export function virtualizationName(flags: ReadonlySet<string>): string | undefined {
|
|
83
|
+
if (flags.has("vmx")) return "Intel VT-x";
|
|
84
|
+
if (flags.has("svm")) return "AMD-V";
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Cache sizes summed over DISTINCT caches: every CPU sharing one reports the
|
|
89
|
+
* same `shared_cpu_list`, so that string is the deduplication key. L1 combines
|
|
90
|
+
* data and instruction, which is what Mission Center shows as one figure. */
|
|
91
|
+
export function readCacheSizes(fs: Pick<LinuxFs, "list" | "read">): { l1?: number; l2?: number; l3?: number } {
|
|
92
|
+
const seen = new Set<string>();
|
|
93
|
+
const totals = new Map<number, number>();
|
|
94
|
+
|
|
95
|
+
for (const cpu of fs.list(SYS_CPU) ?? []) {
|
|
96
|
+
if (!/^cpu\d+$/.test(cpu)) continue;
|
|
97
|
+
const cacheDir = `${SYS_CPU}/${cpu}/cache`;
|
|
98
|
+
for (const index of fs.list(cacheDir) ?? []) {
|
|
99
|
+
if (!index.startsWith("index")) continue;
|
|
100
|
+
const dir = `${cacheDir}/${index}`;
|
|
101
|
+
const level = readNumber(fs, `${dir}/level`);
|
|
102
|
+
const size = parseCacheSize(readAttr(fs, `${dir}/size`));
|
|
103
|
+
const shared = readAttr(fs, `${dir}/shared_cpu_list`);
|
|
104
|
+
if (level === undefined || size === undefined) continue;
|
|
105
|
+
const key = `${level}:${readAttr(fs, `${dir}/type`) ?? ""}:${shared ?? `${cpu}/${index}`}`;
|
|
106
|
+
if (seen.has(key)) continue;
|
|
107
|
+
seen.add(key);
|
|
108
|
+
totals.set(level, (totals.get(level) ?? 0) + size);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
...defined("l1", totals.get(1)),
|
|
113
|
+
...defined("l2", totals.get(2)),
|
|
114
|
+
...defined("l3", totals.get(3)),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** sysfs writes cache sizes as "48K" / "30720K" / "16M". */
|
|
119
|
+
export function parseCacheSize(raw: string | undefined): number | undefined {
|
|
120
|
+
if (!raw) return undefined;
|
|
121
|
+
const m = /^(\d+)([KMG])?$/i.exec(raw.trim());
|
|
122
|
+
if (!m) return undefined;
|
|
123
|
+
const n = Number(m[1]);
|
|
124
|
+
const unit = (m[2] ?? "").toUpperCase();
|
|
125
|
+
const scale = unit === "G" ? 1024 ** 3 : unit === "M" ? 1024 ** 2 : unit === "K" ? 1024 : 1;
|
|
126
|
+
return n * scale;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ---------------------------------------------------------------- live
|
|
130
|
+
|
|
131
|
+
export interface RaplSample {
|
|
132
|
+
microjoules: number;
|
|
133
|
+
atSec: number;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export interface CpuLiveExtras {
|
|
137
|
+
currentMHz?: number;
|
|
138
|
+
tempC?: number;
|
|
139
|
+
powerW?: number;
|
|
140
|
+
threadCount?: number;
|
|
141
|
+
handleCount?: number;
|
|
142
|
+
uptimeSec?: number;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export interface CpuLiveResult {
|
|
146
|
+
extras: CpuLiveExtras;
|
|
147
|
+
/** RAPL baseline to hand back on the next tick; null when the host has none. */
|
|
148
|
+
rapl: RaplSample | null;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function collectCpuLive(
|
|
152
|
+
prevRapl: RaplSample | null,
|
|
153
|
+
fs: Pick<LinuxFs, "list" | "read"> = realLinuxFs,
|
|
154
|
+
now: () => number = Date.now,
|
|
155
|
+
): CpuLiveResult {
|
|
156
|
+
const atSec = now() / 1000;
|
|
157
|
+
const rapl = readRaplEnergy(fs, atSec);
|
|
158
|
+
const loadavg = fs.read("/proc/loadavg") ?? "";
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
rapl,
|
|
162
|
+
extras: {
|
|
163
|
+
...defined("currentMHz", meanCurrentMHz(fs)),
|
|
164
|
+
...defined("tempC", readPackageTempC(fs)),
|
|
165
|
+
...defined("powerW", raplWatts(prevRapl, rapl)),
|
|
166
|
+
...defined("threadCount", parseThreadCount(loadavg)),
|
|
167
|
+
...defined("handleCount", parseHandleCount(fs.read("/proc/sys/fs/file-nr"))),
|
|
168
|
+
...defined("uptimeSec", parseUptimeSec(fs.read("/proc/uptime"))),
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/** Mean of every online core's current clock. `scaling_cur_freq` is what the
|
|
174
|
+
* governor asked for; `cpuinfo_cur_freq` needs root on some drivers, so it is
|
|
175
|
+
* never read here. */
|
|
176
|
+
export function meanCurrentMHz(fs: Pick<LinuxFs, "list" | "read">): number | undefined {
|
|
177
|
+
let sum = 0;
|
|
178
|
+
let count = 0;
|
|
179
|
+
for (const cpu of fs.list(SYS_CPU) ?? []) {
|
|
180
|
+
if (!/^cpu\d+$/.test(cpu)) continue;
|
|
181
|
+
const khz = readNumber(fs, `${SYS_CPU}/${cpu}/cpufreq/scaling_cur_freq`);
|
|
182
|
+
if (khz === undefined) continue;
|
|
183
|
+
sum += khz;
|
|
184
|
+
count++;
|
|
185
|
+
}
|
|
186
|
+
return count > 0 ? Math.round(sum / count / 1000) : undefined;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/** The package sensor, in preference order; `temp1_input` is the package on
|
|
190
|
+
* coretemp ("Package id 0") and the die on k10temp. */
|
|
191
|
+
export function readPackageTempC(fs: Pick<LinuxFs, "list" | "read">): number | undefined {
|
|
192
|
+
const chips = fs.list(HWMON_DIR) ?? [];
|
|
193
|
+
for (const wanted of PACKAGE_SENSORS) {
|
|
194
|
+
for (const chip of chips) {
|
|
195
|
+
if (readAttr(fs, `${HWMON_DIR}/${chip}/name`) !== wanted) continue;
|
|
196
|
+
const milli = readNumber(fs, `${HWMON_DIR}/${chip}/temp1_input`);
|
|
197
|
+
if (milli !== undefined) return Math.round(milli / 100) / 10;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return undefined;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/** Sum of every RAPL package domain. Intel exposes `intel-rapl:N`, AMD the same
|
|
204
|
+
* interface; a host with neither (a VM, an ARM board) reports no power at all. */
|
|
205
|
+
export function readRaplEnergy(fs: Pick<LinuxFs, "list" | "read">, atSec: number): RaplSample | null {
|
|
206
|
+
let microjoules = 0;
|
|
207
|
+
let found = false;
|
|
208
|
+
for (const entry of fs.list(RAPL_DIR) ?? []) {
|
|
209
|
+
if (!/^intel-rapl:\d+$/.test(entry)) continue;
|
|
210
|
+
const name = readAttr(fs, `${RAPL_DIR}/${entry}/name`) ?? "";
|
|
211
|
+
if (!name.startsWith("package")) continue;
|
|
212
|
+
const uj = readNumber(fs, `${RAPL_DIR}/${entry}/energy_uj`);
|
|
213
|
+
if (uj === undefined) continue;
|
|
214
|
+
microjoules += uj;
|
|
215
|
+
found = true;
|
|
216
|
+
}
|
|
217
|
+
return found ? { microjoules, atSec } : null;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/** Watts over the interval. The counter wraps at `max_energy_range_uj`, which a
|
|
221
|
+
* negative delta reveals — one unmeasured tick is better than a false spike. */
|
|
222
|
+
export function raplWatts(prev: RaplSample | null, next: RaplSample | null): number | undefined {
|
|
223
|
+
if (!prev || !next) return undefined;
|
|
224
|
+
const dt = next.atSec - prev.atSec;
|
|
225
|
+
const dj = next.microjoules - prev.microjoules;
|
|
226
|
+
if (!(dt > 0) || dj < 0) return undefined;
|
|
227
|
+
return Math.round(dj / dt / 1000) / 1000;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/** `/proc/loadavg`'s fourth field is `running/total` kernel tasks. */
|
|
231
|
+
export function parseThreadCount(loadavg: string): number | undefined {
|
|
232
|
+
const m = /\s(\d+)\/(\d+)\s/.exec(` ${loadavg.trim()} `);
|
|
233
|
+
const n = m ? Number(m[2]) : NaN;
|
|
234
|
+
return Number.isFinite(n) ? n : undefined;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/** `/proc/sys/fs/file-nr`: allocated, free, max. The first is the live count. */
|
|
238
|
+
export function parseHandleCount(fileNr: string | null): number | undefined {
|
|
239
|
+
const n = Number(fileNr?.trim().split(/\s+/)[0]);
|
|
240
|
+
return Number.isFinite(n) ? n : undefined;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export function parseUptimeSec(uptime: string | null): number | undefined {
|
|
244
|
+
const n = Number(uptime?.trim().split(/\s+/)[0]);
|
|
245
|
+
return Number.isFinite(n) ? Math.round(n) : undefined;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const khzToMhz = (khz: number | undefined) => (khz === undefined ? undefined : Math.round(khz / 1000));
|
|
249
|
+
|
|
250
|
+
function defined<K extends string, V>(key: K, value: V | undefined): Partial<Record<K, V>> {
|
|
251
|
+
return value === undefined ? {} : ({ [key]: value } as Record<K, V>);
|
|
252
|
+
}
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Whole-machine CPU + memory
|
|
2
|
+
* Whole-machine CPU + memory. Runs in both tiers.
|
|
3
|
+
*
|
|
4
|
+
* Reads files on Linux and spawns nothing there. On darwin it spawns exactly one
|
|
5
|
+
* `sysctl` per tick for swap, which `node:os` does not carry — measured at
|
|
6
|
+
* 1.33 ms, see `memory-darwin.ts`.
|
|
3
7
|
*/
|
|
4
8
|
import os from "node:os";
|
|
5
9
|
import { readFileSync } from "node:fs";
|
|
6
10
|
import type { CpuMetrics, MemoryMetrics } from "../../types/system-metrics.ts";
|
|
11
|
+
import { enrichMemory, readZramTotals, type ZramTotals } from "./memory-linux.ts";
|
|
12
|
+
import { parseSwapUsage, readSwapUsage } from "./memory-darwin.ts";
|
|
7
13
|
|
|
8
14
|
export interface CoreTimes {
|
|
9
15
|
user: number;
|
|
@@ -11,8 +17,16 @@ export interface CoreTimes {
|
|
|
11
17
|
sys: number;
|
|
12
18
|
idle: number;
|
|
13
19
|
irq: number;
|
|
20
|
+
/** Blocked on I/O: neither busy nor idle. `os.cpus()` has no field for it and
|
|
21
|
+
* libuv reads the column into a throwaway, so these three are 0 on any host
|
|
22
|
+
* whose sample came from there — see `sampleCpuTimes`. */
|
|
23
|
+
iowait: number;
|
|
24
|
+
softirq: number;
|
|
25
|
+
steal: number;
|
|
14
26
|
}
|
|
15
27
|
|
|
28
|
+
const NO_EXTRA = { iowait: 0, softirq: 0, steal: 0 } as const;
|
|
29
|
+
|
|
16
30
|
export interface CpuTimesSample {
|
|
17
31
|
times: CoreTimes[];
|
|
18
32
|
/** Wall clock of the sample, epoch ms. */
|
|
@@ -20,38 +34,110 @@ export interface CpuTimesSample {
|
|
|
20
34
|
model: string;
|
|
21
35
|
}
|
|
22
36
|
|
|
37
|
+
/** Read `/proc/stat` on Linux, null elsewhere or on failure. Injectable for tests. */
|
|
38
|
+
export function readProcStat(): string | null {
|
|
39
|
+
if (process.platform !== "linux") return null;
|
|
40
|
+
try {
|
|
41
|
+
return readFileSync("/proc/stat", "utf-8");
|
|
42
|
+
} catch {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
23
47
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
48
|
+
* Per-core times from a `/proc/stat` dump, in the file's own jiffies. Null when
|
|
49
|
+
* no `cpuN` line is present, so the caller can fall back.
|
|
50
|
+
*
|
|
51
|
+
* `guest`/`guest_nice` are deliberately NOT read: the kernel already counts them
|
|
52
|
+
* inside `user`/`nice`, so adding them would inflate the total and under-report
|
|
53
|
+
* every busy percentage on a host running VMs.
|
|
28
54
|
*/
|
|
29
|
-
export function
|
|
55
|
+
export function parseProcStatCores(stat: string): CoreTimes[] | null {
|
|
56
|
+
const cores: CoreTimes[] = [];
|
|
57
|
+
for (const line of stat.split("\n")) {
|
|
58
|
+
const m = /^cpu(\d+)\s+(.*)$/.exec(line);
|
|
59
|
+
if (!m) continue;
|
|
60
|
+
const n = m[2]!.trim().split(/\s+/).map(Number);
|
|
61
|
+
if (n.length < 8 || n.some((v) => !Number.isFinite(v))) return null;
|
|
62
|
+
cores[Number(m[1])] = {
|
|
63
|
+
user: n[0]!, nice: n[1]!, sys: n[2]!, idle: n[3]!,
|
|
64
|
+
iowait: n[4]!, irq: n[5]!, softirq: n[6]!, steal: n[7]!,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
// A hole would mean a core index we never saw, which no kernel produces — but
|
|
68
|
+
// a sparse array here would crash the delta, so treat it as unusable.
|
|
69
|
+
if (cores.length === 0 || cores.some((c) => c === undefined)) return null;
|
|
70
|
+
return cores;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Prefer `/proc/stat`; fall back to `os.cpus()`.
|
|
75
|
+
*
|
|
76
|
+
* `os.cpus()` cannot express a core that is blocked on I/O. libuv's Linux
|
|
77
|
+
* `uv_cpu_info` reads the `iowait`, `softirq` and `steal` columns into a
|
|
78
|
+
* throwaway variable, so a core parked in iowait shows a *tiny* total delta with
|
|
79
|
+
* no idle in it — measured on this host, 6 jiffies of which 0 were idle while
|
|
80
|
+
* the kernel reported 195 of 201 in iowait, i.e. the Overview card drew one core
|
|
81
|
+
* pinned at a red **100%** while it was 3% busy and waiting on a disk write.
|
|
82
|
+
*
|
|
83
|
+
* The fallback still copies the numbers out immediately: Bun 1.3.10 on Windows
|
|
84
|
+
* returns the SAME `times` object on a later call while the previous array is
|
|
85
|
+
* still referenced, and the delta then reads 0 % forever with no error anywhere.
|
|
86
|
+
*/
|
|
87
|
+
export function sampleCpuTimes(
|
|
88
|
+
now: number = Date.now(),
|
|
89
|
+
stat: () => string | null = readProcStat,
|
|
90
|
+
): CpuTimesSample {
|
|
30
91
|
const cpus = os.cpus();
|
|
31
|
-
const
|
|
32
|
-
|
|
92
|
+
const model = cpus[0]?.model?.trim() ?? "";
|
|
93
|
+
const dump = stat();
|
|
94
|
+
const fromProc = dump ? parseProcStatCores(dump) : null;
|
|
95
|
+
if (fromProc && fromProc.length === cpus.length) return { times: fromProc, at: now, model };
|
|
96
|
+
return { times: cpus.map((c) => ({ ...c.times, ...NO_EXTRA })), at: now, model };
|
|
33
97
|
}
|
|
34
98
|
|
|
35
99
|
const round1 = (n: number): number => Math.round(n * 10) / 10;
|
|
36
100
|
|
|
37
|
-
/**
|
|
101
|
+
/**
|
|
102
|
+
* Busy % total + per core between two samples. Pure. First sample → all zeros.
|
|
103
|
+
*
|
|
104
|
+
* The kernel share is `sys + irq` over the same interval — Mission Center draws
|
|
105
|
+
* it as a second, darker line under the total, so it is a SUBSET of `total` and
|
|
106
|
+
* must never be added to it.
|
|
107
|
+
*/
|
|
38
108
|
export function computeCpuFromSamples(prev: CpuTimesSample | null, next: CpuTimesSample): CpuMetrics {
|
|
39
|
-
const zeros: CpuMetrics = {
|
|
109
|
+
const zeros: CpuMetrics = {
|
|
110
|
+
total: 0, cores: next.times.map(() => 0), model: next.model,
|
|
111
|
+
kernelPercent: 0, coreKernel: next.times.map(() => 0),
|
|
112
|
+
};
|
|
40
113
|
if (!prev || prev.times.length !== next.times.length) return zeros;
|
|
41
114
|
|
|
42
115
|
let busySum = 0;
|
|
116
|
+
let kernelSum = 0;
|
|
43
117
|
let totalSum = 0;
|
|
118
|
+
const coreKernel: number[] = [];
|
|
44
119
|
const cores = next.times.map((n, i) => {
|
|
45
120
|
const p = prev.times[i]!;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
121
|
+
// Waiting on I/O is not work. Folding it into `idle` is what `top` and
|
|
122
|
+
// Mission Center both do, and leaving it out of `total` altogether is the
|
|
123
|
+
// bug that drew an idle core at 100% — see `sampleCpuTimes`.
|
|
124
|
+
const notBusy = (n.idle - p.idle) + (n.iowait - p.iowait);
|
|
125
|
+
const kernel = (n.sys - p.sys) + (n.irq - p.irq) + (n.softirq - p.softirq);
|
|
126
|
+
const total = (n.user - p.user) + (n.nice - p.nice) + kernel
|
|
127
|
+
+ notBusy + (n.steal - p.steal);
|
|
128
|
+
if (!(total > 0)) {
|
|
129
|
+
coreKernel.push(0);
|
|
130
|
+
return 0;
|
|
131
|
+
}
|
|
132
|
+
busySum += total - notBusy;
|
|
133
|
+
kernelSum += kernel;
|
|
50
134
|
totalSum += total;
|
|
51
|
-
|
|
135
|
+
coreKernel.push(clampPercent(kernel / total * 100));
|
|
136
|
+
return clampPercent((total - notBusy) / total * 100);
|
|
52
137
|
});
|
|
53
138
|
const total = totalSum > 0 ? clampPercent(busySum / totalSum * 100) : 0;
|
|
54
|
-
|
|
139
|
+
const kernelPercent = totalSum > 0 ? clampPercent(kernelSum / totalSum * 100) : 0;
|
|
140
|
+
return { total, cores, model: next.model, kernelPercent, coreKernel };
|
|
55
141
|
}
|
|
56
142
|
|
|
57
143
|
function clampPercent(v: number): number {
|
|
@@ -59,6 +145,20 @@ function clampPercent(v: number): number {
|
|
|
59
145
|
return round1(Math.min(100, Math.max(0, v)));
|
|
60
146
|
}
|
|
61
147
|
|
|
148
|
+
/**
|
|
149
|
+
* Seconds since boot, on all three platforms — `os.uptime()` reads
|
|
150
|
+
* `/proc/uptime`, `kern.boottime` and `GetTickCount64` respectively.
|
|
151
|
+
*
|
|
152
|
+
* Linux has a finer figure of its own and `collectDevices` merges it OVER this
|
|
153
|
+
* one; the reason this exists is that the per-device collector is null off
|
|
154
|
+
* Linux, so "Up time" was an em dash — the claim that the host could not be
|
|
155
|
+
* asked how long it had been up — on macOS and Windows both.
|
|
156
|
+
*/
|
|
157
|
+
export function hostUptimeSec(): number | undefined {
|
|
158
|
+
const seconds = os.uptime();
|
|
159
|
+
return Number.isFinite(seconds) && seconds > 0 ? Math.round(seconds) : undefined;
|
|
160
|
+
}
|
|
161
|
+
|
|
62
162
|
/** Read `/proc/meminfo` on Linux, null elsewhere or on failure. Injectable for tests. */
|
|
63
163
|
export function readMeminfo(): string | null {
|
|
64
164
|
if (process.platform !== "linux") return null;
|
|
@@ -82,8 +182,19 @@ export function parseMemAvailableBytes(meminfo: string): number | null {
|
|
|
82
182
|
* and `os.freemem()` is within 0.2 GiB of CIM's `FreePhysicalMemory`. On Linux
|
|
83
183
|
* `freemem()` is `MemFree`, which makes a warm page cache look like a nearly
|
|
84
184
|
* full machine — `MemAvailable` is what `free` and Task-Manager-like tools show.
|
|
185
|
+
* On **darwin** `freemem()` is already right and must be left alone: it agrees
|
|
186
|
+
* with what `top` calls unused (75 MB against this figure's 124 MB on the same
|
|
187
|
+
* host, sampled seconds apart), which is the number Activity Monitor shows.
|
|
188
|
+
*
|
|
189
|
+
* Swap is the one field macOS publishes and `os` does not, so it is fetched
|
|
190
|
+
* separately — see `memory-darwin.ts` for why that costs a spawn and why the
|
|
191
|
+
* page counts from `vm_stat` are deliberately not used.
|
|
85
192
|
*/
|
|
86
|
-
export function collectMemory(
|
|
193
|
+
export function collectMemory(
|
|
194
|
+
meminfo: () => string | null = readMeminfo,
|
|
195
|
+
zram: () => ZramTotals | undefined = defaultZram,
|
|
196
|
+
swapusage: () => string | null = readSwapUsage,
|
|
197
|
+
): MemoryMetrics {
|
|
87
198
|
const totalBytes = os.totalmem();
|
|
88
199
|
let availableBytes = os.freemem();
|
|
89
200
|
const info = meminfo();
|
|
@@ -97,5 +208,16 @@ export function collectMemory(meminfo: () => string | null = readMeminfo): Memor
|
|
|
97
208
|
const availableMB = round1(availableBytes / MB);
|
|
98
209
|
const usedMB = round1(Math.max(totalMB - availableMB, 0));
|
|
99
210
|
const percent = totalMB > 0 ? round1(usedMB / totalMB * 100) : 0;
|
|
100
|
-
|
|
211
|
+
const base: MemoryMetrics = { totalMB, usedMB, availableMB, percent };
|
|
212
|
+
// `info` is null off Linux, so the composition fields simply stay absent there
|
|
213
|
+
// — but swap is not one of those: macOS answers for it, and leaving it absent
|
|
214
|
+
// rendered an em dash on a host with 8 GB of swap in use.
|
|
215
|
+
if (info) return enrichMemory(base, info, zram());
|
|
216
|
+
return { ...base, ...parseSwapUsage(swapusage()) };
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/** Two `/sys` reads on a host that has zram and one cheap directory listing on
|
|
220
|
+
* one that does not — small enough to run per tick, unlike the DIMM layout. */
|
|
221
|
+
function defaultZram(): ZramTotals | undefined {
|
|
222
|
+
return readZramTotals();
|
|
101
223
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** Every per-device Linux collector as one tick-shaped call. */
|
|
2
|
+
import { collectLinuxDiskDevices } from "./disk-devices-linux.ts";
|
|
3
|
+
import { collectLinuxNicDevices } from "./net-devices-linux.ts";
|
|
4
|
+
import { collectLinuxFans } from "./fans-linux.ts";
|
|
5
|
+
import { collectCpuLive } from "./cpu-details-linux.ts";
|
|
6
|
+
import { collectLinuxGpus } from "./gpu-devices-linux.ts";
|
|
7
|
+
import type { DrmGpuCollector } from "./gpu-fdinfo-linux.ts";
|
|
8
|
+
import { realLinuxFs, type LinuxFs } from "./linux-fs.ts";
|
|
9
|
+
import type { DeviceCollection, DeviceSampleState } from "./device-collector-types.ts";
|
|
10
|
+
|
|
11
|
+
export function collectLinuxDevices(
|
|
12
|
+
prev: DeviceSampleState,
|
|
13
|
+
drm: DrmGpuCollector,
|
|
14
|
+
fs: LinuxFs = realLinuxFs,
|
|
15
|
+
now: () => number = Date.now,
|
|
16
|
+
): DeviceCollection {
|
|
17
|
+
const disks = collectLinuxDiskDevices(prev.disks, fs, now);
|
|
18
|
+
const nics = collectLinuxNicDevices(prev.nics, fs, now);
|
|
19
|
+
const cpu = collectCpuLive(prev.rapl, fs, now);
|
|
20
|
+
// The same walk the process rows are built from: asking here first (or second)
|
|
21
|
+
// costs nothing, because the collector memoises one result per tick.
|
|
22
|
+
const gpus = collectLinuxGpus(prev.gpus, drm.usage(), fs, now);
|
|
23
|
+
return {
|
|
24
|
+
disks: disks.disks,
|
|
25
|
+
nics: nics.nics,
|
|
26
|
+
fans: collectLinuxFans(fs),
|
|
27
|
+
cpu: cpu.extras,
|
|
28
|
+
gpus: gpus.gpus,
|
|
29
|
+
next: { disks: disks.next, nics: nics.next, rapl: cpu.rapl, gpus: gpus.next },
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** Shape of the per-device (drive / interface) half of a tick, platform-neutral so
|
|
2
|
+
* the tick assembler does not import a Linux module to name its own state. */
|
|
3
|
+
import type { CpuMetrics, DiskMetrics, FanMetrics, GpuMetrics, NicMetrics } from "../../types/system-metrics.ts";
|
|
4
|
+
import type { DiskSampleState } from "./disk-devices-linux.ts";
|
|
5
|
+
import type { NicSampleState } from "./net-devices-linux.ts";
|
|
6
|
+
import type { RaplSample } from "./cpu-details-linux.ts";
|
|
7
|
+
import type { GpuSampleState } from "./gpu-devices-linux.ts";
|
|
8
|
+
|
|
9
|
+
/** Previous counters, per device id. Each device is measured against its own
|
|
10
|
+
* baseline, so one appearing mid-session costs one unavailable tick and never a
|
|
11
|
+
* spike measured from zero. */
|
|
12
|
+
export interface DeviceSampleState {
|
|
13
|
+
disks: DiskSampleState;
|
|
14
|
+
nics: NicSampleState;
|
|
15
|
+
/** Cumulative RAPL energy, the baseline package power is measured against. */
|
|
16
|
+
rapl: RaplSample | null;
|
|
17
|
+
/** Per-card rc6 / uncore counters. */
|
|
18
|
+
gpus: GpuSampleState;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const EMPTY_DEVICE_STATE: DeviceSampleState = {
|
|
22
|
+
disks: new Map(), nics: new Map(), rapl: null, gpus: new Map(),
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export interface DeviceCollection {
|
|
26
|
+
disks: DiskMetrics[];
|
|
27
|
+
nics: NicMetrics[];
|
|
28
|
+
/** Empty where the host has no fan tachometer. */
|
|
29
|
+
fans: FanMetrics[];
|
|
30
|
+
/** Merged over the cross-platform `CpuMetrics` by the tick, never replacing it. */
|
|
31
|
+
cpu: Partial<CpuMetrics>;
|
|
32
|
+
/** Cards this platform reads from sysfs. Appended to whatever the vendor-tool
|
|
33
|
+
* collector (nvidia-smi) found, which covers the drivers sysfs cannot. */
|
|
34
|
+
gpus: GpuMetrics[];
|
|
35
|
+
next: DeviceSampleState;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Synchronous by design: every source is a small sysfs read, so there is no
|
|
39
|
+
* subprocess to await and no reason for the tick to yield. */
|
|
40
|
+
export type DeviceCollector = (prev: DeviceSampleState) => DeviceCollection;
|