@hienlh/ppm 0.9.85 → 0.9.87
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/260415-0932-git-graph-stash-rebase-conflicts/reports/code-reviewer-260415-1020-stash-rebase-conflicts.md +288 -0
- package/260415-0932-git-graph-stash-rebase-conflicts/reports/tester-260415-1020-build-check.md +117 -0
- package/260415-1150-ext-silent-failure-debugging/reports/code-reviewer-260415-1159-ext-error-reporting-review.md +205 -0
- package/260415-1150-ext-silent-failure-debugging/reports/docs-manager-260415-1206-ext-error-reporting.md +99 -0
- package/260415-1150-ext-silent-failure-debugging/reports/tester-260415-1159-extension-error-reporting.md +174 -0
- package/CHANGELOG.md +24 -0
- package/dist/web/assets/{_basePickBy-D-bUmjma.js → _basePickBy-Bj0dI1ei.js} +1 -1
- package/dist/web/assets/{_baseUniq-BnXXIfRB.js → _baseUniq-CyzdZeQH.js} +1 -1
- package/dist/web/assets/ai-settings-section-Bo9lCaTd.js +1 -0
- package/dist/web/assets/{api-settings-Qi2xRiHa.js → api-settings-CUxg9RE5.js} +1 -1
- package/dist/web/assets/{arc-DB9vXGzd.js → arc-CxgHJ7Z4.js} +1 -1
- package/dist/web/assets/architecture-PBZL5I3N-DDFO_NKq.js +1 -0
- package/dist/web/assets/{architectureDiagram-2XIMDMQ5-BBV25747.js → architectureDiagram-2XIMDMQ5-D16OotsC.js} +1 -1
- package/dist/web/assets/arrow-up-I9-21gkR.js +1 -0
- package/dist/web/assets/{blockDiagram-WCTKOSBZ-BOTnY2Lq.js → blockDiagram-WCTKOSBZ-Ct57Wtfk.js} +1 -1
- package/dist/web/assets/{c4Diagram-IC4MRINW-D7QAUdHD.js → c4Diagram-IC4MRINW-BIymcNsg.js} +1 -1
- package/dist/web/assets/channel-wumTB1if.js +1 -0
- package/dist/web/assets/chat-tab-R4gKsnxD.js +10 -0
- package/dist/web/assets/chevron-right-DY_wImxB.js +1 -0
- package/dist/web/assets/{chunk-4BX2VUAB-BnOVw77D.js → chunk-4BX2VUAB-CENmY7Kw.js} +1 -1
- package/dist/web/assets/{chunk-55IACEB6-BftA8DxR.js → chunk-55IACEB6-DhZGI1l3.js} +1 -1
- package/dist/web/assets/{chunk-7E7YKBS2-B0vnP8v3.js → chunk-7E7YKBS2-DZcnC7Ow.js} +1 -1
- package/dist/web/assets/{chunk-7R4GIKGN-Czlaj26D.js → chunk-7R4GIKGN-y8bfHEy-.js} +2 -2
- package/dist/web/assets/{chunk-C72U2L5F-DpEbDtMo.js → chunk-C72U2L5F-BHPkfQj2.js} +1 -1
- package/dist/web/assets/{chunk-EGIJ26TM-BWXe6lkx.js → chunk-EGIJ26TM-nant2LXl.js} +1 -1
- package/dist/web/assets/{chunk-FMBD7UC4-DspqhPfk.js → chunk-FMBD7UC4-Bog4cpN-.js} +1 -1
- package/dist/web/assets/{chunk-GEFDOKGD-D6HHRbYk.js → chunk-GEFDOKGD-86LFbsAC.js} +1 -1
- package/dist/web/assets/chunk-GLR3WWYH-Re-5eSlQ.js +2 -0
- package/dist/web/assets/chunk-HHEYEP7N-C45i5G_3.js +1 -0
- package/dist/web/assets/{chunk-JSJVCQXG-BC8wnMwf.js → chunk-JSJVCQXG-23eG9mgt.js} +1 -1
- package/dist/web/assets/{chunk-KX2RTZJC-D3VDtyvX.js → chunk-KX2RTZJC-CHj8TnTB.js} +1 -1
- package/dist/web/assets/{chunk-KYZI473N-Z-NBw_HS.js → chunk-KYZI473N-gqRLpJ4w.js} +1 -1
- package/dist/web/assets/{chunk-L3YUKLVL--RGkEh__.js → chunk-L3YUKLVL-DnSMmNFC.js} +1 -1
- package/dist/web/assets/{chunk-MX3YWQON-2B76t_Kx.js → chunk-MX3YWQON-B6g1ZH9X.js} +1 -1
- package/dist/web/assets/{chunk-NQ4KR5QH-BekY3tEi.js → chunk-NQ4KR5QH-DX32345Y.js} +1 -1
- package/dist/web/assets/{chunk-O4XLMI2P-2CJLfx_1.js → chunk-O4XLMI2P-Vp_V4P-b.js} +1 -1
- package/dist/web/assets/{chunk-OZEHJAEY-sug_L09P.js → chunk-OZEHJAEY-lKq2SWjA.js} +1 -1
- package/dist/web/assets/{chunk-PQ6SQG4A-_fwPRLQy.js → chunk-PQ6SQG4A-Bik13fTV.js} +1 -1
- package/dist/web/assets/{chunk-PU5JKC2W-BUaTFJVQ.js → chunk-PU5JKC2W-DD95Rx35.js} +1 -1
- package/dist/web/assets/chunk-QZHKN3VN-N3VXx1VH.js +1 -0
- package/dist/web/assets/{chunk-R5LLSJPH-C37xW0vj.js → chunk-R5LLSJPH-dRhXRnrb.js} +1 -1
- package/dist/web/assets/{chunk-WL4C6EOR-CCkt_MT6.js → chunk-WL4C6EOR-B1iIvLOG.js} +1 -1
- package/dist/web/assets/{chunk-XIRO2GV7-Dz2LBq7Y.js → chunk-XIRO2GV7-DZBoNl1_.js} +1 -1
- package/dist/web/assets/{chunk-XPW4576I-DenTbBuj.js → chunk-XPW4576I-CgLyyW03.js} +1 -1
- package/dist/web/assets/{chunk-XZSTWKYB-Dbp1nUSQ.js → chunk-XZSTWKYB-DjV8xl5A.js} +1 -1
- package/dist/web/assets/{chunk-YBOYWFTD-3OTKowjE.js → chunk-YBOYWFTD-D_ILLe6_.js} +1 -1
- package/dist/web/assets/classDiagram-VBA2DB6C-mr-Cb1me.js +1 -0
- package/dist/web/assets/classDiagram-v2-RAHNMMFH-BKe8_uda.js +1 -0
- package/dist/web/assets/clone--z5KLAuR.js +1 -0
- package/dist/web/assets/code-editor-Br0vzTOy.js +8 -0
- package/dist/web/assets/columns-2-IeETSfON.js +1 -0
- package/dist/web/assets/conflict-editor-BPgCjnNz.js +19 -0
- package/dist/web/assets/{cose-bilkent-S5V4N54A-MbmGZnt0.js → cose-bilkent-S5V4N54A-BGNPFv3x.js} +1 -1
- package/dist/web/assets/{csv-preview-uZ_7b8I7.js → csv-preview-BZRICDP0.js} +2 -2
- package/dist/web/assets/{dagre-CPhI6v-K.js → dagre-CkhlMHnx.js} +1 -1
- package/dist/web/assets/{dagre-KLK3FWXG-CmSE-oNj.js → dagre-KLK3FWXG-Cnp996VG.js} +1 -1
- package/dist/web/assets/database-CgTomMxt.js +1 -0
- package/dist/web/assets/{database-viewer-5xljX0JI.js → database-viewer-DaUoQ-oR.js} +2 -2
- package/dist/web/assets/{diagram-E7M64L7V-B5XG3ZT7.js → diagram-E7M64L7V-BZF0tSOr.js} +1 -1
- package/dist/web/assets/{diagram-IFDJBPK2-BsP248aX.js → diagram-IFDJBPK2-nUcO8sN8.js} +1 -1
- package/dist/web/assets/{diagram-P4PSJMXO-Cna3408N.js → diagram-P4PSJMXO-CW0eCkwC.js} +1 -1
- package/dist/web/assets/diff-viewer-BzvK3gAE.js +4 -0
- package/dist/web/assets/dist-CM0oD8tQ.js +1 -0
- package/dist/web/assets/{erDiagram-INFDFZHY-B7SgktiR.js → erDiagram-INFDFZHY-DSkriYZ9.js} +1 -1
- package/dist/web/assets/extension-webview-CGepEw-b.js +3 -0
- package/dist/web/assets/{flowDiagram-PKNHOUZH-FOYZZ1OB.js → flowDiagram-PKNHOUZH-CFYAfZBx.js} +1 -1
- package/dist/web/assets/{ganttDiagram-A5KZAMGK-CnHVYh9v.js → ganttDiagram-A5KZAMGK-KSn4XAU4.js} +1 -1
- package/dist/web/assets/gitGraph-HDMCJU4V-OkvBPi6H.js +1 -0
- package/dist/web/assets/{gitGraphDiagram-K3NZZRJ6-0G9XxZay.js → gitGraphDiagram-K3NZZRJ6-BMgjjVys.js} +1 -1
- package/dist/web/assets/{graphlib-CNiBwlg_.js → graphlib-BWe1iK_s.js} +1 -1
- package/dist/web/assets/index-CKsEzQ4f.js +26 -0
- package/dist/web/assets/index-Chf0otez.css +2 -0
- package/dist/web/assets/info-3K5VOQVL-BDU2_bYD.js +1 -0
- package/dist/web/assets/infoDiagram-LFFYTUFH-Diq4Cyc3.js +2 -0
- package/dist/web/assets/input-BHj0veau.js +45 -0
- package/dist/web/assets/{isEmpty-CcCb5n2-.js → isEmpty-BfLnxq-B.js} +1 -1
- package/dist/web/assets/{ishikawaDiagram-PHBUUO56-D4QCzh5J.js → ishikawaDiagram-PHBUUO56-CiVEvp8o.js} +1 -1
- package/dist/web/assets/{journeyDiagram-4ABVD52K-CnHYNfKW.js → journeyDiagram-4ABVD52K-CG_v5Aho.js} +1 -1
- package/dist/web/assets/jsx-runtime-BRW_vwa9.js +1 -0
- package/dist/web/assets/{kanban-definition-K7BYSVSG-Bh_g3EVu.js → kanban-definition-K7BYSVSG-miB0-_Zq.js} +1 -1
- package/dist/web/assets/keybindings-store-D5zgHod8.js +1 -0
- package/dist/web/assets/{line-6d3eBADm.js → line-CSuSrJ9J.js} +1 -1
- package/dist/web/assets/{linear-cA_2lQy7.js → linear-DFN_MPsw.js} +1 -1
- package/dist/web/assets/{markdown-renderer-CZ07F7T6.js → markdown-renderer-DSYnGywb.js} +6 -6
- package/dist/web/assets/{mermaid-parser.core-C3kd7JXM.js → mermaid-parser.core-CFdP1Z5_.js} +2 -2
- package/dist/web/assets/{mindmap-definition-YRQLILUH-CYiUwhr_.js → mindmap-definition-YRQLILUH-pYPWwASE.js} +1 -1
- package/dist/web/assets/{ordinal-XHK5vIzZ.js → ordinal-DpFn432U.js} +1 -1
- package/dist/web/assets/packet-RMMSAZCW-BwpIpYB3.js +1 -0
- package/dist/web/assets/pie-UPGHQEXC-BPgAfmes.js +1 -0
- package/dist/web/assets/{pieDiagram-SKSYHLDU-D0S7jeZA.js → pieDiagram-SKSYHLDU-Dovdlvhu.js} +1 -1
- package/dist/web/assets/plus-DQGIb4mQ.js +1 -0
- package/dist/web/assets/port-forwarding-tab-vmqDKmk2.js +1 -0
- package/dist/web/assets/{postgres-viewer-RldlAO_m.js → postgres-viewer-0lIAosrr.js} +3 -3
- package/dist/web/assets/{quadrantDiagram-337W2JSQ-0hNP63hW.js → quadrantDiagram-337W2JSQ-TXe6cU_F.js} +1 -1
- package/dist/web/assets/radar-KQ55EAFF-TqxBkWx-.js +1 -0
- package/dist/web/assets/refresh-cw-Clk8fdUD.js +1 -0
- package/dist/web/assets/{requirementDiagram-Z7DCOOCP-BVnmqFbL.js → requirementDiagram-Z7DCOOCP-CuiiuGS9.js} +1 -1
- package/dist/web/assets/{sankeyDiagram-WA2Y5GQK-DVkYdCJb.js → sankeyDiagram-WA2Y5GQK-BbRmhv0t.js} +1 -1
- package/dist/web/assets/scroll-area-BpXCNme3.js +1 -0
- package/dist/web/assets/{sequenceDiagram-2WXFIKYE-B80s7sOg.js → sequenceDiagram-2WXFIKYE-B2D8IQDb.js} +1 -1
- package/dist/web/assets/settings-tab-CMnv1fce.js +1 -0
- package/dist/web/assets/{sql-query-editor-CjZ7Z6XL.js → sql-query-editor-Bc2hAwqT.js} +1 -1
- package/dist/web/assets/sqlite-viewer-B60MS2Dy.js +1 -0
- package/dist/web/assets/square-vBdqj0bF.js +1 -0
- package/dist/web/assets/{stateDiagram-RAJIS63D-BPLXgXRR.js → stateDiagram-RAJIS63D-ylr4HxPu.js} +1 -1
- package/dist/web/assets/stateDiagram-v2-FVOUBMTO-D6zvxf3M.js +1 -0
- package/dist/web/assets/table-Bi27fEaN.js +1 -0
- package/dist/web/assets/{terminal-tab-DjzD8GLn.js → terminal-tab-CCJoLstH.js} +2 -2
- package/dist/web/assets/text-wrap-D_OmSzhp.js +1 -0
- package/dist/web/assets/{timeline-definition-YZTLITO2-fa_51u1X.js → timeline-definition-YZTLITO2-pMv1grvM.js} +1 -1
- package/dist/web/assets/trash-2-CNuB-htI.js +1 -0
- package/dist/web/assets/treemap-KZPCXAKY-Kck06FKU.js +1 -0
- package/dist/web/assets/{use-monaco-theme-D9XFxQuU.js → use-monaco-theme-BJK48EmK.js} +1 -1
- package/dist/web/assets/{vennDiagram-LZ73GAT5-kX4jJn6W.js → vennDiagram-LZ73GAT5-C-rkIUbo.js} +1 -1
- package/dist/web/assets/x-Dw3TjeY_.js +1 -0
- package/dist/web/assets/{xychartDiagram-JWTSCODW-Bzm5lZBs.js → xychartDiagram-JWTSCODW-CtpjAakO.js} +1 -1
- package/dist/web/index.html +18 -22
- package/dist/web/sw.js +1 -1
- package/docs/codebase-summary.md +169 -13
- package/docs/extension-development-guide.md +98 -1
- package/docs/journals/260414-1400-ext-git-graph-port-complete.md +147 -0
- package/docs/journals/260414-1452-git-graph-faithful-port.md +144 -0
- package/docs/journals/260414-1810-git-graph-ui-improvements-complete.md +261 -0
- package/docs/journals/260414-2001-bundled-extensions.md +219 -0
- package/docs/project-changelog.md +123 -21
- package/docs/project-roadmap.md +4 -2
- package/docs/system-architecture.md +77 -6
- package/package.json +1 -1
- package/packages/ext-git-graph/package.json +30 -0
- package/packages/ext-git-graph/src/extension-integration.test.ts +230 -0
- package/packages/ext-git-graph/src/extension-parsers.test.ts +193 -0
- package/packages/ext-git-graph/src/extension.ts +921 -0
- package/packages/ext-git-graph/src/git-log-parser.test.ts +271 -0
- package/packages/ext-git-graph/src/git-log-parser.ts +38 -0
- package/packages/ext-git-graph/src/types.ts +192 -0
- package/packages/ext-git-graph/src/webview-html.test.ts +142 -0
- package/packages/ext-git-graph/src/webview-html.ts +2417 -0
- package/packages/vscode-compat/src/index.ts +4 -0
- package/packages/vscode-compat/src/process.ts +25 -0
- package/packages/vscode-compat/src/window.ts +10 -0
- package/src/cli/commands/ext-cmd.ts +3 -1
- package/src/server/ws/extensions.ts +34 -4
- package/src/services/contribution-registry.ts +14 -1
- package/src/services/extension-host-worker.ts +12 -3
- package/src/services/extension-manifest.ts +18 -1
- package/src/services/extension-rpc-handlers.ts +68 -2
- package/src/services/extension.service.ts +63 -9
- package/src/types/extension-messages.ts +3 -1
- package/src/types/extension.ts +8 -0
- package/src/web/components/editor/code-editor.tsx +16 -4
- package/src/web/components/editor/conflict-editor.tsx +368 -0
- package/src/web/components/extensions/extension-webview.tsx +153 -12
- package/src/web/components/layout/command-palette.tsx +41 -17
- package/src/web/components/layout/editor-panel.tsx +16 -4
- package/src/web/components/layout/mobile-nav.tsx +6 -5
- package/src/web/components/layout/tab-bar.tsx +3 -3
- package/src/web/components/layout/tab-content.tsx +17 -5
- package/src/web/components/settings/keyboard-shortcuts-section.tsx +46 -1
- package/src/web/hooks/use-extension-ws.ts +30 -4
- package/src/web/hooks/use-global-keybindings.ts +24 -2
- package/src/web/hooks/use-url-sync.ts +8 -3
- package/src/web/stores/extension-store.ts +8 -0
- package/src/web/stores/keybindings-store.ts +2 -3
- package/src/web/stores/panel-store.ts +2 -2
- package/src/web/stores/panel-utils.ts +6 -2
- package/src/web/stores/tab-store.ts +3 -2
- package/dist/web/assets/ai-settings-section-D6d-RmR6.js +0 -1
- package/dist/web/assets/architecture-PBZL5I3N-DpVzOETR.js +0 -1
- package/dist/web/assets/arrow-up-BigIMx-e.js +0 -1
- package/dist/web/assets/channel-Cgy1thYT.js +0 -1
- package/dist/web/assets/chat-tab-DXBb9Y3U.js +0 -10
- package/dist/web/assets/check-ePA3ZvK4.js +0 -1
- package/dist/web/assets/chevron-down-EQA06nR-.js +0 -1
- package/dist/web/assets/chevron-right-CXzzT44u.js +0 -1
- package/dist/web/assets/chunk-GLR3WWYH-CxUl1sdz.js +0 -2
- package/dist/web/assets/chunk-HHEYEP7N-DN7ebS2Y.js +0 -1
- package/dist/web/assets/chunk-QZHKN3VN-C4La7oLj.js +0 -1
- package/dist/web/assets/classDiagram-VBA2DB6C-C3IyfqG-.js +0 -1
- package/dist/web/assets/classDiagram-v2-RAHNMMFH-Dcvhz2pb.js +0 -1
- package/dist/web/assets/clone--C7Tby8z.js +0 -1
- package/dist/web/assets/code-editor-Cr7JrBKC.js +0 -8
- package/dist/web/assets/columns-2-BZ9uqssV.js +0 -1
- package/dist/web/assets/createLucideIcon-PuMiQgHl.js +0 -1
- package/dist/web/assets/database-D1ToEV9d.js +0 -1
- package/dist/web/assets/diff-viewer-BBr6e_gb.js +0 -4
- package/dist/web/assets/dist-KUoHa6tg.js +0 -1
- package/dist/web/assets/extension-webview-B0klBip8.js +0 -3
- package/dist/web/assets/eye-CNcBU6Tx.js +0 -1
- package/dist/web/assets/git-graph-CDiwGa0g.js +0 -1
- package/dist/web/assets/gitGraph-HDMCJU4V-DcPyMEIJ.js +0 -1
- package/dist/web/assets/index-CkaCzNgO.css +0 -2
- package/dist/web/assets/index-Ic5uTu20.js +0 -26
- package/dist/web/assets/info-3K5VOQVL-Dw4O15cw.js +0 -1
- package/dist/web/assets/infoDiagram-LFFYTUFH-DFhmsucr.js +0 -2
- package/dist/web/assets/input-CcbTF6ih.js +0 -45
- package/dist/web/assets/jsx-runtime-R_NjdZtX.js +0 -1
- package/dist/web/assets/keybindings-store-CxE6BlG2.js +0 -1
- package/dist/web/assets/packet-RMMSAZCW-o3LmdL8H.js +0 -1
- package/dist/web/assets/pie-UPGHQEXC-BjNP0M3B.js +0 -1
- package/dist/web/assets/plus-Iso5r9vD.js +0 -1
- package/dist/web/assets/port-forwarding-tab-BPuSc6pI.js +0 -1
- package/dist/web/assets/radar-KQ55EAFF-gDgOiaME.js +0 -1
- package/dist/web/assets/refresh-cw-BgQzFNaG.js +0 -1
- package/dist/web/assets/scroll-area-i4EZlOl_.js +0 -1
- package/dist/web/assets/settings-tab-BzSSN2BQ.js +0 -1
- package/dist/web/assets/sqlite-viewer-CoyZOM_Y.js +0 -1
- package/dist/web/assets/square-pfn_LYYy.js +0 -1
- package/dist/web/assets/stateDiagram-v2-FVOUBMTO-DksQJ7es.js +0 -1
- package/dist/web/assets/table-CHv2x_qg.js +0 -1
- package/dist/web/assets/tag-Bb_UFXt0.js +0 -1
- package/dist/web/assets/text-wrap-D8BbQYTx.js +0 -1
- package/dist/web/assets/trash-2-DYCa06CV.js +0 -1
- package/dist/web/assets/treemap-KZPCXAKY-DwFqAvnj.js +0 -1
- package/dist/web/assets/x-BXecj-16.js +0 -1
- package/src/web/components/git/git-graph-branch-label.tsx +0 -124
- package/src/web/components/git/git-graph-constants.ts +0 -185
- package/src/web/components/git/git-graph-detail.tsx +0 -107
- package/src/web/components/git/git-graph-dialog.tsx +0 -72
- package/src/web/components/git/git-graph-row.tsx +0 -167
- package/src/web/components/git/git-graph-settings-dialog.tsx +0 -104
- package/src/web/components/git/git-graph-svg.tsx +0 -54
- package/src/web/components/git/git-graph-toolbar.tsx +0 -195
- package/src/web/components/git/git-graph.tsx +0 -193
- package/src/web/components/git/use-column-resize.ts +0 -33
- package/src/web/components/git/use-git-graph.ts +0 -201
- /package/dist/web/assets/{api-client-wQbeUyeh.js → api-client-BvxmRZUi.js} +0 -0
- /package/dist/web/assets/{array-X0JlPOfd.js → array-BFDiaBgf.js} +0 -0
- /package/dist/web/assets/{csv-parser-CElqio6o.js → csv-parser-i7fjqP2H.js} +0 -0
- /package/dist/web/assets/{cytoscape.esm-BfIOPvwt.js → cytoscape.esm-C8i2jUzT.js} +0 -0
- /package/dist/web/assets/{defaultLocale-B6RGN4id.js → defaultLocale-ZeknFqNe.js} +0 -0
- /package/dist/web/assets/{dist-CK1enexV.js → dist-DZmJeHOA.js} +0 -0
- /package/dist/web/assets/{init-BmUWJJHz.js → init-0VJVrkRJ.js} +0 -0
- /package/dist/web/assets/{isArrayLikeObject-BrCM-iA1.js → isArrayLikeObject-ClzWCpcm.js} +0 -0
- /package/dist/web/assets/{katex-xQS_6bNb.js → katex-DR0kdMDv.js} +0 -0
- /package/dist/web/assets/{lib-CfWBrYll.js → lib-DSLzfeW0.js} +0 -0
- /package/dist/web/assets/{math-CpLFzrfV.js → math-CRc16Nj6.js} +0 -0
- /package/dist/web/assets/{path-CoPyR7c2.js → path-INs8XTPH.js} +0 -0
- /package/dist/web/assets/{preload-helper-CH6UZRzu.js → preload-helper-mr3rCizq.js} +0 -0
- /package/dist/web/assets/{react-j5zqhEum.js → react-0tkk-ztn.js} +0 -0
- /package/dist/web/assets/{rough.esm-D5NinLFK.js → rough.esm-eLccZ4OJ.js} +0 -0
- /package/dist/web/assets/{sql-completion-provider-D0xutVaK.js → sql-completion-provider-B8uUWWej.js} +0 -0
- /package/dist/web/assets/{src-j04igtQ5.js → src-CqyWLlNZ.js} +0 -0
- /package/dist/web/assets/{utils-CSCvNZxE.js → utils-DX8jb5qv.js} +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Suspense, lazy, useEffect, useState, useCallback } from "react";
|
|
2
|
-
import { ChevronDown, ChevronUp, Loader2, Terminal, MessageSquare,
|
|
2
|
+
import { ChevronDown, ChevronUp, Loader2, Terminal, MessageSquare, FilePlus, Pin, PinOff } from "lucide-react";
|
|
3
3
|
import { usePanelStore } from "@/stores/panel-store";
|
|
4
4
|
import { useProjectStore } from "@/stores/project-store";
|
|
5
|
-
import type
|
|
5
|
+
import { useTabStore, type TabType } from "@/stores/tab-store";
|
|
6
6
|
import { api, projectUrl } from "@/lib/api-client";
|
|
7
7
|
import type { SessionInfo } from "../../../types/chat";
|
|
8
8
|
import { TabBar } from "./tab-bar";
|
|
@@ -12,7 +12,7 @@ import { cn } from "@/lib/utils";
|
|
|
12
12
|
const QUICK_OPEN_TABS: { type: TabType; label: string; icon: React.ElementType }[] = [
|
|
13
13
|
{ type: "terminal", label: "Terminal", icon: Terminal },
|
|
14
14
|
{ type: "chat", label: "AI Chat", icon: MessageSquare },
|
|
15
|
-
{ type: "
|
|
15
|
+
{ type: "editor", label: "New File", icon: FilePlus },
|
|
16
16
|
];
|
|
17
17
|
|
|
18
18
|
const TAB_COMPONENTS: Record<TabType, React.LazyExoticComponent<React.ComponentType<{ metadata?: Record<string, unknown>; tabId?: string }>>> = {
|
|
@@ -22,11 +22,12 @@ const TAB_COMPONENTS: Record<TabType, React.LazyExoticComponent<React.ComponentT
|
|
|
22
22
|
database: lazy(() => import("@/components/database/database-viewer").then((m) => ({ default: m.DatabaseViewer }))),
|
|
23
23
|
sqlite: lazy(() => import("@/components/sqlite/sqlite-viewer").then((m) => ({ default: m.SqliteViewer }))),
|
|
24
24
|
postgres: lazy(() => import("@/components/postgres/postgres-viewer").then((m) => ({ default: m.PostgresViewer }))),
|
|
25
|
-
"git-graph": lazy(() => import("@/components/git/git-graph").then((m) => ({ default: m.GitGraph }))),
|
|
26
25
|
"git-diff": lazy(() => import("@/components/editor/diff-viewer").then((m) => ({ default: m.DiffViewer }))),
|
|
27
26
|
settings: lazy(() => import("@/components/settings/settings-tab").then((m) => ({ default: m.SettingsTab }))),
|
|
28
27
|
ports: lazy(() => import("@/components/ports/port-forwarding-tab").then((m) => ({ default: m.PortForwardingTab }))),
|
|
28
|
+
extension: lazy(() => import("@/components/extensions/extension-webview").then((m) => ({ default: m.ExtensionWebview }))),
|
|
29
29
|
"extension-webview": lazy(() => import("@/components/extensions/extension-webview").then((m) => ({ default: m.ExtensionWebview }))),
|
|
30
|
+
"conflict-editor": lazy(() => import("@/components/editor/conflict-editor").then((m) => ({ default: m.ConflictEditor }))),
|
|
30
31
|
};
|
|
31
32
|
|
|
32
33
|
interface EditorPanelProps {
|
|
@@ -62,6 +63,13 @@ export function EditorPanel({ panelId, projectName }: EditorPanelProps) {
|
|
|
62
63
|
panel.tabs.map((tab) => {
|
|
63
64
|
const Component = TAB_COMPONENTS[tab.type];
|
|
64
65
|
const isActive = tab.id === panel.activeTabId;
|
|
66
|
+
if (!Component) {
|
|
67
|
+
return (
|
|
68
|
+
<div key={tab.id} className={isActive ? "h-full w-full flex items-center justify-center text-muted-foreground" : "hidden"}>
|
|
69
|
+
Unknown tab type: {tab.type}
|
|
70
|
+
</div>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
65
73
|
return (
|
|
66
74
|
<div key={tab.id} className={isActive ? "h-full w-full" : "hidden"}>
|
|
67
75
|
<Suspense fallback={<div className="flex items-center justify-center h-full"><Loader2 className="size-6 animate-spin text-primary" /></div>}>
|
|
@@ -143,6 +151,10 @@ function EmptyPanel({ panelId }: { panelId: string }) {
|
|
|
143
151
|
}, [activeProject?.name]);
|
|
144
152
|
|
|
145
153
|
function openTab(type: TabType) {
|
|
154
|
+
if (type === "editor") {
|
|
155
|
+
useTabStore.getState().openNewFile();
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
146
158
|
const needsProject = type !== "settings";
|
|
147
159
|
const metadata = needsProject && activeProject ? { projectName: activeProject.name } : undefined;
|
|
148
160
|
usePanelStore.getState().openTab(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useState, useEffect, useRef, useCallback, useMemo } from "react";
|
|
2
2
|
import {
|
|
3
|
-
Terminal, MessageSquare,
|
|
3
|
+
Terminal, MessageSquare, Database,
|
|
4
4
|
FileDiff, FileCode, Settings, Menu, X, ArrowLeft, ArrowRight, SplitSquareVertical, MoveVertical, Layers, Plus,
|
|
5
5
|
ChevronRight, Globe, Puzzle, Copy, Download, Pencil, Trash2,
|
|
6
6
|
} from "lucide-react";
|
|
@@ -21,15 +21,16 @@ import { FileActions } from "@/components/explorer/file-actions";
|
|
|
21
21
|
const NEW_TAB_OPTIONS: { type: TabType; label: string }[] = [
|
|
22
22
|
{ type: "terminal", label: "Terminal" },
|
|
23
23
|
{ type: "chat", label: "AI Chat" },
|
|
24
|
-
{ type: "git-graph", label: "Git Graph" },
|
|
25
24
|
{ type: "settings", label: "Settings" },
|
|
26
25
|
];
|
|
27
26
|
const NEW_TAB_LABELS: Partial<Record<TabType, string>> = Object.fromEntries(NEW_TAB_OPTIONS.map((o) => [o.type, o.label]));
|
|
28
27
|
|
|
29
28
|
const TAB_ICONS: Record<TabType, React.ElementType> = {
|
|
30
29
|
terminal: Terminal, chat: MessageSquare, editor: FileCode, database: Database, sqlite: Database, postgres: Database,
|
|
31
|
-
"git-
|
|
30
|
+
"git-diff": FileDiff, settings: Settings, ports: Globe,
|
|
31
|
+
extension: Puzzle,
|
|
32
32
|
"extension-webview": Puzzle,
|
|
33
|
+
"conflict-editor": FileDiff,
|
|
33
34
|
};
|
|
34
35
|
|
|
35
36
|
interface MobileNavProps { onMenuPress: () => void; onProjectsPress: () => void; }
|
|
@@ -141,7 +142,7 @@ export function MobileNav({ onMenuPress, onProjectsPress }: MobileNavProps) {
|
|
|
141
142
|
function handleNewTab(type: TabType) {
|
|
142
143
|
const state = usePanelStore.getState();
|
|
143
144
|
const firstPanelId = state.grid[0]?.[0] ?? state.focusedPanelId;
|
|
144
|
-
const needsProject = type === "git-
|
|
145
|
+
const needsProject = type === "git-diff" || type === "terminal" || type === "chat";
|
|
145
146
|
const metadata = needsProject ? { projectName: activeProjectForTab?.name } : undefined;
|
|
146
147
|
state.openTab(
|
|
147
148
|
{ type, title: NEW_TAB_LABELS[type] ?? type, metadata, projectId: activeProjectForTab?.name ?? null, closable: true },
|
|
@@ -211,7 +212,7 @@ export function MobileNav({ onMenuPress, onProjectsPress }: MobileNavProps) {
|
|
|
211
212
|
<div className="flex-1 min-w-0 relative flex items-center h-12 -ml-4">
|
|
212
213
|
<div ref={mobileScrollRef} className="flex-1 min-w-0 flex items-center h-12 overflow-x-auto scrollbar-none pl-4">
|
|
213
214
|
{tabs.map((tab) => {
|
|
214
|
-
const Icon = TAB_ICONS[tab.type];
|
|
215
|
+
const Icon = TAB_ICONS[tab.type] || Puzzle;
|
|
215
216
|
const isActive = tab.id === activeTabId;
|
|
216
217
|
const sessionId = tab.type === "chat" ? (tab.metadata?.sessionId as string) : undefined;
|
|
217
218
|
const entry = sessionId ? notifications.get(sessionId) : undefined;
|
|
@@ -3,7 +3,6 @@ import {
|
|
|
3
3
|
Plus,
|
|
4
4
|
Terminal,
|
|
5
5
|
MessageSquare,
|
|
6
|
-
GitBranch,
|
|
7
6
|
FileDiff,
|
|
8
7
|
Settings,
|
|
9
8
|
FileCode,
|
|
@@ -36,11 +35,12 @@ const TAB_ICONS: Record<TabType, React.ElementType> = {
|
|
|
36
35
|
database: Database,
|
|
37
36
|
sqlite: Database,
|
|
38
37
|
postgres: Database,
|
|
39
|
-
"git-graph": GitBranch,
|
|
40
38
|
"git-diff": FileDiff,
|
|
41
39
|
settings: Settings,
|
|
42
40
|
ports: Globe,
|
|
41
|
+
extension: Puzzle,
|
|
43
42
|
"extension-webview": Puzzle,
|
|
43
|
+
"conflict-editor": FileDiff,
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
interface TabBarProps {
|
|
@@ -194,7 +194,7 @@ export function TabBar({ panelId }: TabBarProps) {
|
|
|
194
194
|
key={tab.id}
|
|
195
195
|
tab={tab}
|
|
196
196
|
isActive={tab.id === activeTabId}
|
|
197
|
-
icon={TAB_ICONS[tab.type]}
|
|
197
|
+
icon={TAB_ICONS[tab.type] || Puzzle}
|
|
198
198
|
showDropBefore={dropIndex === i}
|
|
199
199
|
notificationType={notiType}
|
|
200
200
|
onSelect={() => {
|
|
@@ -33,11 +33,6 @@ const TAB_COMPONENTS: Record<TabType, React.LazyExoticComponent<React.ComponentT
|
|
|
33
33
|
default: m.PostgresViewer,
|
|
34
34
|
})),
|
|
35
35
|
),
|
|
36
|
-
"git-graph": lazy(() =>
|
|
37
|
-
import("@/components/git/git-graph").then((m) => ({
|
|
38
|
-
default: m.GitGraph,
|
|
39
|
-
})),
|
|
40
|
-
),
|
|
41
36
|
"git-diff": lazy(() =>
|
|
42
37
|
import("@/components/editor/diff-viewer").then((m) => ({
|
|
43
38
|
default: m.DiffViewer,
|
|
@@ -53,11 +48,21 @@ const TAB_COMPONENTS: Record<TabType, React.LazyExoticComponent<React.ComponentT
|
|
|
53
48
|
default: m.PortForwardingTab,
|
|
54
49
|
})),
|
|
55
50
|
),
|
|
51
|
+
extension: lazy(() =>
|
|
52
|
+
import("@/components/extensions/extension-webview").then((m) => ({
|
|
53
|
+
default: m.ExtensionWebview,
|
|
54
|
+
})),
|
|
55
|
+
),
|
|
56
56
|
"extension-webview": lazy(() =>
|
|
57
57
|
import("@/components/extensions/extension-webview").then((m) => ({
|
|
58
58
|
default: m.ExtensionWebview,
|
|
59
59
|
})),
|
|
60
60
|
),
|
|
61
|
+
"conflict-editor": lazy(() =>
|
|
62
|
+
import("@/components/editor/conflict-editor").then((m) => ({
|
|
63
|
+
default: m.ConflictEditor,
|
|
64
|
+
})),
|
|
65
|
+
),
|
|
61
66
|
};
|
|
62
67
|
|
|
63
68
|
function LoadingFallback() {
|
|
@@ -84,6 +89,13 @@ export function TabContent() {
|
|
|
84
89
|
{tabs.map((tab) => {
|
|
85
90
|
const Component = TAB_COMPONENTS[tab.type];
|
|
86
91
|
const isActive = tab.id === activeTabId;
|
|
92
|
+
if (!Component) {
|
|
93
|
+
return (
|
|
94
|
+
<div key={tab.id} className={isActive ? "h-full w-full flex items-center justify-center text-muted-foreground" : "hidden"}>
|
|
95
|
+
Unknown tab type: {tab.type}
|
|
96
|
+
</div>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
87
99
|
return (
|
|
88
100
|
<div
|
|
89
101
|
key={tab.id}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState, useEffect, useCallback, useRef } from "react";
|
|
2
|
-
import { RotateCcw, AlertTriangle, Lock } from "lucide-react";
|
|
2
|
+
import { RotateCcw, AlertTriangle, Lock, Puzzle } from "lucide-react";
|
|
3
3
|
import { Button } from "@/components/ui/button";
|
|
4
4
|
import {
|
|
5
5
|
KEY_ACTIONS,
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
comboFromEvent,
|
|
9
9
|
type KeyCategory,
|
|
10
10
|
} from "@/stores/keybindings-store";
|
|
11
|
+
import { useExtensionStore } from "@/stores/extension-store";
|
|
11
12
|
|
|
12
13
|
const CATEGORIES: { key: KeyCategory; label: string }[] = [
|
|
13
14
|
{ key: "general", label: "General" },
|
|
@@ -104,6 +105,9 @@ function ShortcutBadge({
|
|
|
104
105
|
|
|
105
106
|
export function KeyboardShortcutsSection() {
|
|
106
107
|
const { getBinding, resetBinding, resetAll, overrides } = useKeybindingsStore();
|
|
108
|
+
const extContributions = useExtensionStore((s) => s.contributions);
|
|
109
|
+
const extKeybindings = extContributions?.keybindings ?? [];
|
|
110
|
+
const extCommands = extContributions?.commands ?? [];
|
|
107
111
|
|
|
108
112
|
return (
|
|
109
113
|
<div className="space-y-3">
|
|
@@ -177,6 +181,47 @@ export function KeyboardShortcutsSection() {
|
|
|
177
181
|
</div>
|
|
178
182
|
);
|
|
179
183
|
})}
|
|
184
|
+
|
|
185
|
+
{/* Extension-contributed keybindings */}
|
|
186
|
+
{extKeybindings.length > 0 && (
|
|
187
|
+
<div className="space-y-1">
|
|
188
|
+
<span className="text-[10px] font-medium text-muted-foreground uppercase tracking-wide">
|
|
189
|
+
Extensions
|
|
190
|
+
</span>
|
|
191
|
+
<div className="space-y-0.5">
|
|
192
|
+
{extKeybindings.map((kb) => {
|
|
193
|
+
const cmd = extCommands.find((c) => c.command === kb.command);
|
|
194
|
+
const label = cmd?.title ?? kb.command;
|
|
195
|
+
const actionId = `ext:${kb.command}`;
|
|
196
|
+
const currentCombo = getBinding(actionId) || kb.key;
|
|
197
|
+
const isOverridden = actionId in overrides;
|
|
198
|
+
return (
|
|
199
|
+
<div
|
|
200
|
+
key={actionId}
|
|
201
|
+
className="flex items-center justify-between py-1 px-1 rounded hover:bg-surface-elevated/50 transition-colors"
|
|
202
|
+
>
|
|
203
|
+
<div className="flex items-center gap-1.5 min-w-0">
|
|
204
|
+
<Puzzle className="size-3 text-muted-foreground shrink-0" />
|
|
205
|
+
<span className="text-xs text-foreground">{label}</span>
|
|
206
|
+
</div>
|
|
207
|
+
<div className="flex items-center gap-1 shrink-0 ml-2">
|
|
208
|
+
<ShortcutBadge actionId={actionId} combo={currentCombo} />
|
|
209
|
+
{isOverridden && (
|
|
210
|
+
<button
|
|
211
|
+
onClick={() => resetBinding(actionId)}
|
|
212
|
+
className="flex items-center justify-center size-5 rounded text-muted-foreground hover:text-foreground hover:bg-surface-elevated transition-colors"
|
|
213
|
+
title="Reset to default"
|
|
214
|
+
>
|
|
215
|
+
<RotateCcw className="size-3" />
|
|
216
|
+
</button>
|
|
217
|
+
)}
|
|
218
|
+
</div>
|
|
219
|
+
</div>
|
|
220
|
+
);
|
|
221
|
+
})}
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
)}
|
|
180
225
|
</div>
|
|
181
226
|
);
|
|
182
227
|
}
|
|
@@ -40,6 +40,14 @@ export function useExtensionWs(enabled = true) {
|
|
|
40
40
|
switch (msg.type) {
|
|
41
41
|
case "contributions:update":
|
|
42
42
|
store.setContributions(msg.contributions);
|
|
43
|
+
if (msg.activationErrors) {
|
|
44
|
+
const prev = store.activationErrors;
|
|
45
|
+
store.setActivationErrors(msg.activationErrors);
|
|
46
|
+
// Only toast NEW errors (avoid spam on repeated contributions:update)
|
|
47
|
+
for (const [extId, error] of Object.entries(msg.activationErrors)) {
|
|
48
|
+
if (!prev[extId]) toast.error(`Extension "${extId}" failed to activate: ${error}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
43
51
|
break;
|
|
44
52
|
|
|
45
53
|
case "statusbar:update":
|
|
@@ -111,7 +119,8 @@ export function useExtensionWs(enabled = true) {
|
|
|
111
119
|
});
|
|
112
120
|
break;
|
|
113
121
|
|
|
114
|
-
case "webview:create":
|
|
122
|
+
case "webview:create": {
|
|
123
|
+
const viewTypeSlug = msg.viewType.replace(/\.view$/, "");
|
|
115
124
|
store.addWebviewPanel({
|
|
116
125
|
id: msg.panelId,
|
|
117
126
|
extensionId: msg.extensionId,
|
|
@@ -119,15 +128,18 @@ export function useExtensionWs(enabled = true) {
|
|
|
119
128
|
title: msg.title,
|
|
120
129
|
html: "",
|
|
121
130
|
});
|
|
122
|
-
// Open a tab
|
|
131
|
+
// Open a tab — use stable viewType slug as identifier (survives reload)
|
|
132
|
+
// Include projectName so reload can resolve project path for re-trigger
|
|
133
|
+
const currentProject = useTabStore.getState().currentProject;
|
|
123
134
|
useTabStore.getState().openTab({
|
|
124
|
-
type: "extension
|
|
135
|
+
type: "extension",
|
|
125
136
|
title: msg.title,
|
|
126
137
|
projectId: null,
|
|
127
138
|
closable: true,
|
|
128
|
-
metadata: { panelId: msg.panelId, extensionId: msg.extensionId },
|
|
139
|
+
metadata: { viewType: viewTypeSlug, panelId: msg.panelId, extensionId: msg.extensionId, ...(currentProject && { projectName: currentProject }) },
|
|
129
140
|
});
|
|
130
141
|
break;
|
|
142
|
+
}
|
|
131
143
|
|
|
132
144
|
case "webview:html":
|
|
133
145
|
store.updateWebviewPanel(msg.panelId, { html: msg.html });
|
|
@@ -142,6 +154,20 @@ export function useExtensionWs(enabled = true) {
|
|
|
142
154
|
detail: { panelId: msg.panelId, message: msg.message },
|
|
143
155
|
}));
|
|
144
156
|
break;
|
|
157
|
+
|
|
158
|
+
case "tab:open":
|
|
159
|
+
useTabStore.getState().openTab({
|
|
160
|
+
type: (msg as any).tabType,
|
|
161
|
+
title: (msg as any).title,
|
|
162
|
+
projectId: (msg as any).projectId ?? null,
|
|
163
|
+
closable: (msg as any).closable ?? true,
|
|
164
|
+
metadata: (msg as any).metadata,
|
|
165
|
+
});
|
|
166
|
+
break;
|
|
167
|
+
|
|
168
|
+
case "project:switch":
|
|
169
|
+
useTabStore.getState().switchProject((msg as any).projectName);
|
|
170
|
+
break;
|
|
145
171
|
}
|
|
146
172
|
});
|
|
147
173
|
|
|
@@ -2,7 +2,8 @@ import { useEffect, useState, useCallback } from "react";
|
|
|
2
2
|
import { useTabStore } from "@/stores/tab-store";
|
|
3
3
|
import { useSettingsStore } from "@/stores/settings-store";
|
|
4
4
|
import { useProjectStore } from "@/stores/project-store";
|
|
5
|
-
import { useKeybindingsStore } from "@/stores/keybindings-store";
|
|
5
|
+
import { useKeybindingsStore, parseCombo, eventMatchesCombo } from "@/stores/keybindings-store";
|
|
6
|
+
import { useExtensionStore } from "@/stores/extension-store";
|
|
6
7
|
|
|
7
8
|
/** Dispatch this event to open the command palette from anywhere, optionally with initial query */
|
|
8
9
|
export function openCommandPalette(initialQuery?: string) {
|
|
@@ -112,7 +113,6 @@ export function useGlobalKeybindings() {
|
|
|
112
113
|
const tabShortcuts: { action: string; type: string; title: string }[] = [
|
|
113
114
|
{ action: "open-chat", type: "chat", title: "AI Chat" },
|
|
114
115
|
{ action: "open-terminal", type: "terminal", title: "Terminal" },
|
|
115
|
-
{ action: "open-git-graph", type: "git-graph", title: "Git Graph" },
|
|
116
116
|
];
|
|
117
117
|
for (const s of tabShortcuts) {
|
|
118
118
|
if (match(e, s.action)) {
|
|
@@ -176,6 +176,28 @@ export function useGlobalKeybindings() {
|
|
|
176
176
|
return;
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
|
+
|
|
180
|
+
// Extension-contributed keybindings (with user override support)
|
|
181
|
+
const extKbs = useExtensionStore.getState().contributions?.keybindings;
|
|
182
|
+
if (extKbs) {
|
|
183
|
+
const mac = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.userAgent);
|
|
184
|
+
const { getBinding: getBind } = useKeybindingsStore.getState();
|
|
185
|
+
for (const kb of extKbs) {
|
|
186
|
+
// User override via "ext:<command>" key, fallback to extension default
|
|
187
|
+
const overrideCombo = getBind(`ext:${kb.command}`);
|
|
188
|
+
const combo = overrideCombo || ((mac && kb.mac) ? kb.mac : kb.key);
|
|
189
|
+
if (combo && eventMatchesCombo(e, parseCombo(combo))) {
|
|
190
|
+
e.preventDefault();
|
|
191
|
+
const project = useProjectStore.getState().activeProject;
|
|
192
|
+
const args: unknown[] = [];
|
|
193
|
+
if (project?.path) args.push(project.path);
|
|
194
|
+
window.dispatchEvent(new CustomEvent("ext:command:execute", {
|
|
195
|
+
detail: { command: kb.command, args },
|
|
196
|
+
}));
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
179
201
|
}
|
|
180
202
|
|
|
181
203
|
// Custom event listener for programmatic opening
|
|
@@ -14,7 +14,8 @@ export interface UrlState {
|
|
|
14
14
|
|
|
15
15
|
const VALID_TAB_TYPES: TabType[] = [
|
|
16
16
|
"terminal", "chat", "editor", "database", "sqlite",
|
|
17
|
-
"postgres", "git-
|
|
17
|
+
"postgres", "git-diff", "settings", "ports",
|
|
18
|
+
"extension",
|
|
18
19
|
];
|
|
19
20
|
|
|
20
21
|
// ---------------------------------------------------------------------------
|
|
@@ -108,7 +109,6 @@ function buildMetadataFromUrl(
|
|
|
108
109
|
return { ...(sessionId && { sessionId }), ...(providerId && { providerId }), projectName };
|
|
109
110
|
}
|
|
110
111
|
case "terminal": return { terminalIndex: parseInt(identifier ?? "1", 10), projectName };
|
|
111
|
-
case "git-graph": return { projectName };
|
|
112
112
|
case "git-diff": return identifier ? { filePath: identifier, projectName } : null;
|
|
113
113
|
case "settings": return {};
|
|
114
114
|
case "database": {
|
|
@@ -121,6 +121,7 @@ function buildMetadataFromUrl(
|
|
|
121
121
|
return connId ? { connectionId: connId, tableName: tableName ?? "" } : null;
|
|
122
122
|
}
|
|
123
123
|
case "ports": return null;
|
|
124
|
+
case "extension": return identifier ? { viewType: identifier, projectName } : null;
|
|
124
125
|
default: return null;
|
|
125
126
|
}
|
|
126
127
|
}
|
|
@@ -130,13 +131,17 @@ function buildTitleFromUrl(type: TabType, identifier: string | null): string {
|
|
|
130
131
|
case "editor": return identifier?.split("/").pop() ?? "File";
|
|
131
132
|
case "chat": return "Chat";
|
|
132
133
|
case "terminal": return `Terminal ${identifier ?? "1"}`;
|
|
133
|
-
case "git-graph": return "Git Graph";
|
|
134
134
|
case "git-diff": return identifier?.split("/").pop() ?? "Diff";
|
|
135
135
|
case "settings": return "Settings";
|
|
136
136
|
case "database": return identifier ?? "Database";
|
|
137
137
|
case "sqlite": return identifier?.split("/").pop() ?? "SQLite";
|
|
138
138
|
case "postgres": return identifier ?? "PostgreSQL";
|
|
139
139
|
case "ports": return "Ports";
|
|
140
|
+
case "extension": {
|
|
141
|
+
if (!identifier) return "Extension";
|
|
142
|
+
// "git-graph" → "Git Graph"
|
|
143
|
+
return identifier.split("-").map(w => (w[0]?.toUpperCase() ?? "") + w.slice(1)).join(" ");
|
|
144
|
+
}
|
|
140
145
|
default: return type;
|
|
141
146
|
}
|
|
142
147
|
}
|
|
@@ -87,6 +87,10 @@ interface ExtensionStore {
|
|
|
87
87
|
contributions: ExtensionContributes | null;
|
|
88
88
|
setContributions: (c: ExtensionContributes) => void;
|
|
89
89
|
|
|
90
|
+
// Activation errors (sent from server)
|
|
91
|
+
activationErrors: Record<string, string>;
|
|
92
|
+
setActivationErrors: (errors: Record<string, string>) => void;
|
|
93
|
+
|
|
90
94
|
// QuickPick modal
|
|
91
95
|
quickPick: QuickPickState | null;
|
|
92
96
|
showQuickPick: (items: QuickPickItemUI[], options?: QuickPickState["options"]) => Promise<QuickPickItemUI[] | undefined>;
|
|
@@ -154,6 +158,10 @@ export const useExtensionStore = create<ExtensionStore>((set, get) => ({
|
|
|
154
158
|
contributions: null,
|
|
155
159
|
setContributions: (c) => set({ contributions: c }),
|
|
156
160
|
|
|
161
|
+
// --- Activation errors ---
|
|
162
|
+
activationErrors: {},
|
|
163
|
+
setActivationErrors: (errors) => set({ activationErrors: errors }),
|
|
164
|
+
|
|
157
165
|
// --- QuickPick ---
|
|
158
166
|
quickPick: null,
|
|
159
167
|
showQuickPick: (items, options = {}) => {
|
|
@@ -34,7 +34,6 @@ export const KEY_ACTIONS: KeyAction[] = [
|
|
|
34
34
|
{ id: "open-chat", label: "Open Chat", category: "tabs", defaultKey: "Mod+L" },
|
|
35
35
|
{ id: "open-terminal", label: "Open Terminal", category: "tabs", defaultKey: "Mod+'" },
|
|
36
36
|
{ id: "open-settings", label: "Open Settings", category: "tabs", defaultKey: "Mod+," },
|
|
37
|
-
{ id: "open-git-graph", label: "Git Graph", category: "tabs", defaultKey: "Mod+G" },
|
|
38
37
|
{ id: "open-git-status", label: "Git Status (sidebar)", category: "tabs", defaultKey: "Mod+Shift+E" },
|
|
39
38
|
{ id: "open-search", label: "Search Files (sidebar)", category: "tabs", defaultKey: "Mod+Shift+F" },
|
|
40
39
|
{ id: "voice-input", label: "Voice Input", category: "general", defaultKey: "Mod+Shift+V", note: "Toggle speech-to-text in chat" },
|
|
@@ -62,7 +61,7 @@ interface ParsedCombo {
|
|
|
62
61
|
key: string; // lowercase
|
|
63
62
|
}
|
|
64
63
|
|
|
65
|
-
function parseCombo(combo: string): ParsedCombo {
|
|
64
|
+
export function parseCombo(combo: string): ParsedCombo {
|
|
66
65
|
const parts = combo.split("+");
|
|
67
66
|
const result: ParsedCombo = { ctrl: false, meta: false, alt: false, shift: false, key: "" };
|
|
68
67
|
for (const part of parts) {
|
|
@@ -82,7 +81,7 @@ function parseCombo(combo: string): ParsedCombo {
|
|
|
82
81
|
return result;
|
|
83
82
|
}
|
|
84
83
|
|
|
85
|
-
function eventMatchesCombo(e: KeyboardEvent, combo: ParsedCombo): boolean {
|
|
84
|
+
export function eventMatchesCombo(e: KeyboardEvent, combo: ParsedCombo): boolean {
|
|
86
85
|
if (e.ctrlKey !== combo.ctrl) return false;
|
|
87
86
|
if (e.metaKey !== combo.meta) return false;
|
|
88
87
|
if (e.altKey !== combo.alt) return false;
|
|
@@ -16,10 +16,10 @@ import {
|
|
|
16
16
|
} from "./panel-utils";
|
|
17
17
|
|
|
18
18
|
/** Tab types that can only have 1 instance per project */
|
|
19
|
-
const SINGLETON_TYPES = new Set<TabType>(["
|
|
19
|
+
const SINGLETON_TYPES = new Set<TabType>(["settings"]);
|
|
20
20
|
|
|
21
21
|
/** Tab types removed in a prior version — filter them out when loading persisted state */
|
|
22
|
-
const OBSOLETE_TAB_TYPES = new Set(["projects", "git-status"]);
|
|
22
|
+
const OBSOLETE_TAB_TYPES = new Set(["projects", "git-status", "git-graph"]);
|
|
23
23
|
|
|
24
24
|
function pushHistory(history: string[], id: string): string[] {
|
|
25
25
|
const filtered = history.filter((h) => h !== id);
|
|
@@ -103,10 +103,14 @@ export function deriveTabId(type: TabType, metadata?: Record<string, unknown>):
|
|
|
103
103
|
return `sqlite:${metadata?.filePath ?? "default"}`;
|
|
104
104
|
case "postgres":
|
|
105
105
|
return `postgres:${metadata?.connectionId ?? "default"}:${metadata?.tableName ?? ""}`;
|
|
106
|
-
case "
|
|
107
|
-
|
|
106
|
+
case "extension": {
|
|
107
|
+
const vt = String(metadata?.viewType ?? "unknown").replace(/\.view$/, "");
|
|
108
|
+
return `extension:${vt}`;
|
|
109
|
+
}
|
|
108
110
|
case "git-diff":
|
|
109
111
|
return `git-diff:${metadata?.filePath ?? "unknown"}`;
|
|
112
|
+
case "conflict-editor":
|
|
113
|
+
return `conflict-editor:${metadata?.filePath ?? "unknown"}`;
|
|
110
114
|
case "settings":
|
|
111
115
|
return "settings";
|
|
112
116
|
case "ports":
|
|
@@ -9,11 +9,12 @@ export type TabType =
|
|
|
9
9
|
| "database"
|
|
10
10
|
| "sqlite"
|
|
11
11
|
| "postgres"
|
|
12
|
-
| "git-graph"
|
|
13
12
|
| "git-diff"
|
|
14
13
|
| "settings"
|
|
15
14
|
| "ports"
|
|
16
|
-
| "extension
|
|
15
|
+
| "extension"
|
|
16
|
+
| "extension-webview"
|
|
17
|
+
| "conflict-editor";
|
|
17
18
|
|
|
18
19
|
export interface Tab {
|
|
19
20
|
id: string;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{o as e}from"./chunk-CFjPhJqf.js";import{t}from"./react-nm2Ru1Pt.js";import{t as n}from"./react-dom-Bpkvzu3U.js";import{t as r}from"./createLucideIcon-PuMiQgHl.js";import{t as i}from"./check-ePA3ZvK4.js";import{t as a}from"./chevron-down-EQA06nR-.js";import{n as o}from"./plus-Iso5r9vD.js";import{t as s}from"./dist-KUoHa6tg.js";import{t as c}from"./refresh-cw-BgQzFNaG.js";import{t as l}from"./trash-2-DYCa06CV.js";import{t as u}from"./jsx-runtime-R_NjdZtX.js";import{A as d,C as f,D as p,E as m,I as h,N as g,O as _,S as v,_ as y,b,d as x,f as S,g as C,h as w,j as T,k as E,m as D,p as ee,t as O,u as k,v as A,w as j,x as te,y as M}from"./input-CcbTF6ih.js";import{n as N}from"./utils-CSCvNZxE.js";import{i as P,t as F}from"./api-client-wQbeUyeh.js";import{a as I,h as L}from"./api-settings-Qi2xRiHa.js";var ne=r(`bell-off`,[[`path`,{d:`M10.268 21a2 2 0 0 0 3.464 0`,key:`vwvbt9`}],[`path`,{d:`M17 17H4a1 1 0 0 1-.74-1.673C4.59 13.956 6 12.499 6 8a6 6 0 0 1 .258-1.742`,key:`178tsu`}],[`path`,{d:`m2 2 20 20`,key:`1ooewy`}],[`path`,{d:`M8.668 3.01A6 6 0 0 1 18 8c0 2.687.77 4.653 1.707 6.05`,key:`1hqiys`}]]),R=r(`bot`,[[`path`,{d:`M12 8V4H8`,key:`hb8ula`}],[`rect`,{width:`16`,height:`12`,x:`4`,y:`8`,rx:`2`,key:`enze0r`}],[`path`,{d:`M2 14h2`,key:`vft8re`}],[`path`,{d:`M20 14h2`,key:`4cs60a`}],[`path`,{d:`M15 13v2`,key:`1xurst`}],[`path`,{d:`M9 13v2`,key:`rq6x2g`}]]),z=r(`lock`,[[`rect`,{width:`18`,height:`11`,x:`3`,y:`11`,rx:`2`,ry:`2`,key:`1w4ew1`}],[`path`,{d:`M7 11V7a5 5 0 0 1 10 0v4`,key:`fwvmzm`}]]),re=r(`pencil`,[[`path`,{d:`M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z`,key:`1a8usu`}],[`path`,{d:`m15 5 4 4`,key:`1mk7zo`}]]),B=e(t(),1),V=u(),ie=Object.freeze({position:`absolute`,border:0,width:1,height:1,padding:0,margin:-1,overflow:`hidden`,clip:`rect(0, 0, 0, 0)`,whiteSpace:`nowrap`,wordWrap:`normal`}),ae=`VisuallyHidden`,oe=B.forwardRef((e,t)=>(0,V.jsx)(T.span,{...e,ref:t,style:{...ie,...e.style}}));oe.displayName=ae;var se=oe;function H(e){let t=B.useRef({value:e,previous:e});return B.useMemo(()=>(t.current.value!==e&&(t.current.previous=t.current.value,t.current.value=e),t.current.previous),[e])}var ce=`Label`,le=B.forwardRef((e,t)=>(0,V.jsx)(T.label,{...e,ref:t,onMouseDown:t=>{t.target.closest(`button, input, select, textarea`)||(e.onMouseDown?.(t),!t.defaultPrevented&&t.detail>1&&t.preventDefault())}}));le.displayName=ce;var ue=le,de=e(n(),1),fe=[` `,`Enter`,`ArrowUp`,`ArrowDown`],pe=[` `,`Enter`],U=`Select`,[W,G,me]=E(U),[K,he]=d(U,[me,D]),q=D(),[ge,J]=K(U),[_e,ve]=K(U),ye=e=>{let{__scopeSelect:t,children:n,open:r,defaultOpen:i,onOpenChange:a,value:o,defaultValue:s,onValueChange:c,dir:l,name:u,autoComplete:d,disabled:p,required:h,form:g}=e,_=q(t),[v,y]=B.useState(null),[b,x]=B.useState(null),[S,C]=B.useState(!1),w=f(l),[T,E]=m({prop:r,defaultProp:i??!1,onChange:a,caller:U}),[D,O]=m({prop:o,defaultProp:s,onChange:c,caller:U}),k=B.useRef(null),A=v?g||!!v.closest(`form`):!0,[te,M]=B.useState(new Set),N=Array.from(te).map(e=>e.props.value).join(`;`);return(0,V.jsx)(ee,{..._,children:(0,V.jsxs)(ge,{required:h,scope:t,trigger:v,onTriggerChange:y,valueNode:b,onValueNodeChange:x,valueNodeHasChildren:S,onValueNodeHasChildrenChange:C,contentId:j(),value:D,onValueChange:O,open:T,onOpenChange:E,dir:w,triggerPointerDownPosRef:k,disabled:p,children:[(0,V.jsx)(W.Provider,{scope:t,children:(0,V.jsx)(_e,{scope:e.__scopeSelect,onNativeOptionAdd:B.useCallback(e=>{M(t=>new Set(t).add(e))},[]),onNativeOptionRemove:B.useCallback(e=>{M(t=>{let n=new Set(t);return n.delete(e),n})},[]),children:n})}),A?(0,V.jsxs)(ut,{"aria-hidden":!0,required:h,tabIndex:-1,name:u,autoComplete:d,value:D,onChange:e=>O(e.target.value),disabled:p,form:g,children:[D===void 0?(0,V.jsx)(`option`,{value:``}):null,Array.from(te)]},N):null]})})};ye.displayName=U;var be=`SelectTrigger`,xe=B.forwardRef((e,t)=>{let{__scopeSelect:n,disabled:r=!1,...i}=e,a=q(n),o=J(be,n),s=o.disabled||r,c=h(t,o.onTriggerChange),l=G(n),u=B.useRef(`touch`),[d,f,p]=ft(e=>{let t=l().filter(e=>!e.disabled),n=pt(t,e,t.find(e=>e.value===o.value));n!==void 0&&o.onValueChange(n.value)}),m=e=>{s||(o.onOpenChange(!0),p()),e&&(o.triggerPointerDownPosRef.current={x:Math.round(e.pageX),y:Math.round(e.pageY)})};return(0,V.jsx)(k,{asChild:!0,...a,children:(0,V.jsx)(T.button,{type:`button`,role:`combobox`,"aria-controls":o.contentId,"aria-expanded":o.open,"aria-required":o.required,"aria-autocomplete":`none`,dir:o.dir,"data-state":o.open?`open`:`closed`,disabled:s,"data-disabled":s?``:void 0,"data-placeholder":dt(o.value)?``:void 0,...i,ref:c,onClick:_(i.onClick,e=>{e.currentTarget.focus(),u.current!==`mouse`&&m(e)}),onPointerDown:_(i.onPointerDown,e=>{u.current=e.pointerType;let t=e.target;t.hasPointerCapture(e.pointerId)&&t.releasePointerCapture(e.pointerId),e.button===0&&e.ctrlKey===!1&&e.pointerType===`mouse`&&(m(e),e.preventDefault())}),onKeyDown:_(i.onKeyDown,e=>{let t=d.current!==``;!(e.ctrlKey||e.altKey||e.metaKey)&&e.key.length===1&&f(e.key),!(t&&e.key===` `)&&fe.includes(e.key)&&(m(),e.preventDefault())})})})});xe.displayName=be;var Se=`SelectValue`,Ce=B.forwardRef((e,t)=>{let{__scopeSelect:n,className:r,style:i,children:a,placeholder:o=``,...s}=e,c=J(Se,n),{onValueNodeHasChildrenChange:l}=c,u=a!==void 0,d=h(t,c.onValueNodeChange);return p(()=>{l(u)},[l,u]),(0,V.jsx)(T.span,{...s,ref:d,style:{pointerEvents:`none`},children:dt(c.value)?(0,V.jsx)(V.Fragment,{children:o}):a})});Ce.displayName=Se;var we=`SelectIcon`,Te=B.forwardRef((e,t)=>{let{__scopeSelect:n,children:r,...i}=e;return(0,V.jsx)(T.span,{"aria-hidden":!0,...i,ref:t,children:r||`▼`})});Te.displayName=we;var Ee=`SelectPortal`,De=e=>(0,V.jsx)(M,{asChild:!0,...e});De.displayName=Ee;var Y=`SelectContent`,Oe=B.forwardRef((e,t)=>{let n=J(Y,e.__scopeSelect),[r,i]=B.useState();if(p(()=>{i(new DocumentFragment)},[]),!n.open){let t=r;return t?de.createPortal((0,V.jsx)(ke,{scope:e.__scopeSelect,children:(0,V.jsx)(W.Slot,{scope:e.__scopeSelect,children:(0,V.jsx)(`div`,{children:e.children})})}),t):null}return(0,V.jsx)(Me,{...e,ref:t})});Oe.displayName=Y;var X=10,[ke,Z]=K(Y),Ae=`SelectContentImpl`,je=g(`SelectContent.RemoveScroll`),Me=B.forwardRef((e,t)=>{let{__scopeSelect:n,position:r=`item-aligned`,onCloseAutoFocus:i,onEscapeKeyDown:a,onPointerDownOutside:o,side:s,sideOffset:c,align:l,alignOffset:u,arrowPadding:d,collisionBoundary:f,collisionPadding:p,sticky:m,hideWhenDetached:g,avoidCollisions:v,...x}=e,S=J(Y,n),[w,T]=B.useState(null),[E,D]=B.useState(null),ee=h(t,e=>T(e)),[O,k]=B.useState(null),[j,M]=B.useState(null),N=G(n),[P,F]=B.useState(!1),I=B.useRef(!1);B.useEffect(()=>{if(w)return C(w)},[w]),A();let L=B.useCallback(e=>{let[t,...n]=N().map(e=>e.ref.current),[r]=n.slice(-1),i=document.activeElement;for(let n of e)if(n===i||(n?.scrollIntoView({block:`nearest`}),n===t&&E&&(E.scrollTop=0),n===r&&E&&(E.scrollTop=E.scrollHeight),n?.focus(),document.activeElement!==i))return},[N,E]),ne=B.useCallback(()=>L([O,w]),[L,O,w]);B.useEffect(()=>{P&&ne()},[P,ne]);let{onOpenChange:R,triggerPointerDownPosRef:z}=S;B.useEffect(()=>{if(w){let e={x:0,y:0},t=t=>{e={x:Math.abs(Math.round(t.pageX)-(z.current?.x??0)),y:Math.abs(Math.round(t.pageY)-(z.current?.y??0))}},n=n=>{e.x<=10&&e.y<=10?n.preventDefault():w.contains(n.target)||R(!1),document.removeEventListener(`pointermove`,t),z.current=null};return z.current!==null&&(document.addEventListener(`pointermove`,t),document.addEventListener(`pointerup`,n,{capture:!0,once:!0})),()=>{document.removeEventListener(`pointermove`,t),document.removeEventListener(`pointerup`,n,{capture:!0})}}},[w,R,z]),B.useEffect(()=>{let e=()=>R(!1);return window.addEventListener(`blur`,e),window.addEventListener(`resize`,e),()=>{window.removeEventListener(`blur`,e),window.removeEventListener(`resize`,e)}},[R]);let[re,ie]=ft(e=>{let t=N().filter(e=>!e.disabled),n=pt(t,e,t.find(e=>e.ref.current===document.activeElement));n&&setTimeout(()=>n.ref.current.focus())}),ae=B.useCallback((e,t,n)=>{let r=!I.current&&!n;(S.value!==void 0&&S.value===t||r)&&(k(e),r&&(I.current=!0))},[S.value]),oe=B.useCallback(()=>w?.focus(),[w]),se=B.useCallback((e,t,n)=>{let r=!I.current&&!n;(S.value!==void 0&&S.value===t||r)&&M(e)},[S.value]),H=r===`popper`?Ie:Pe,ce=H===Ie?{side:s,sideOffset:c,align:l,alignOffset:u,arrowPadding:d,collisionBoundary:f,collisionPadding:p,sticky:m,hideWhenDetached:g,avoidCollisions:v}:{};return(0,V.jsx)(ke,{scope:n,content:w,viewport:E,onViewportChange:D,itemRefCallback:ae,selectedItem:O,onItemLeave:oe,itemTextRefCallback:se,focusSelectedItem:ne,selectedItemText:j,position:r,isPositioned:P,searchRef:re,children:(0,V.jsx)(y,{as:je,allowPinchZoom:!0,children:(0,V.jsx)(b,{asChild:!0,trapped:S.open,onMountAutoFocus:e=>{e.preventDefault()},onUnmountAutoFocus:_(i,e=>{S.trigger?.focus({preventScroll:!0}),e.preventDefault()}),children:(0,V.jsx)(te,{asChild:!0,disableOutsidePointerEvents:!0,onEscapeKeyDown:a,onPointerDownOutside:o,onFocusOutside:e=>e.preventDefault(),onDismiss:()=>S.onOpenChange(!1),children:(0,V.jsx)(H,{role:`listbox`,id:S.contentId,"data-state":S.open?`open`:`closed`,dir:S.dir,onContextMenu:e=>e.preventDefault(),...x,...ce,onPlaced:()=>F(!0),ref:ee,style:{display:`flex`,flexDirection:`column`,outline:`none`,...x.style},onKeyDown:_(x.onKeyDown,e=>{let t=e.ctrlKey||e.altKey||e.metaKey;if(e.key===`Tab`&&e.preventDefault(),!t&&e.key.length===1&&ie(e.key),[`ArrowUp`,`ArrowDown`,`Home`,`End`].includes(e.key)){let t=N().filter(e=>!e.disabled).map(e=>e.ref.current);if([`ArrowUp`,`End`].includes(e.key)&&(t=t.slice().reverse()),[`ArrowUp`,`ArrowDown`].includes(e.key)){let n=e.target,r=t.indexOf(n);t=t.slice(r+1)}setTimeout(()=>L(t)),e.preventDefault()}})})})})})})});Me.displayName=Ae;var Ne=`SelectItemAlignedPosition`,Pe=B.forwardRef((e,t)=>{let{__scopeSelect:n,onPlaced:r,...i}=e,a=J(Y,n),o=Z(Y,n),[c,l]=B.useState(null),[u,d]=B.useState(null),f=h(t,e=>d(e)),m=G(n),g=B.useRef(!1),_=B.useRef(!0),{viewport:v,selectedItem:y,selectedItemText:b,focusSelectedItem:x}=o,S=B.useCallback(()=>{if(a.trigger&&a.valueNode&&c&&u&&v&&y&&b){let e=a.trigger.getBoundingClientRect(),t=u.getBoundingClientRect(),n=a.valueNode.getBoundingClientRect(),i=b.getBoundingClientRect();if(a.dir!==`rtl`){let r=i.left-t.left,a=n.left-r,o=e.left-a,l=e.width+o,u=Math.max(l,t.width),d=window.innerWidth-X,f=s(a,[X,Math.max(X,d-u)]);c.style.minWidth=l+`px`,c.style.left=f+`px`}else{let r=t.right-i.right,a=window.innerWidth-n.right-r,o=window.innerWidth-e.right-a,l=e.width+o,u=Math.max(l,t.width),d=window.innerWidth-X,f=s(a,[X,Math.max(X,d-u)]);c.style.minWidth=l+`px`,c.style.right=f+`px`}let o=m(),l=window.innerHeight-X*2,d=v.scrollHeight,f=window.getComputedStyle(u),p=parseInt(f.borderTopWidth,10),h=parseInt(f.paddingTop,10),_=parseInt(f.borderBottomWidth,10),x=parseInt(f.paddingBottom,10),S=p+h+d+x+_,C=Math.min(y.offsetHeight*5,S),w=window.getComputedStyle(v),T=parseInt(w.paddingTop,10),E=parseInt(w.paddingBottom,10),D=e.top+e.height/2-X,ee=l-D,O=y.offsetHeight/2,k=y.offsetTop+O,A=p+h+k,j=S-A;if(A<=D){let e=o.length>0&&y===o[o.length-1].ref.current;c.style.bottom=`0px`;let t=u.clientHeight-v.offsetTop-v.offsetHeight,n=A+Math.max(ee,O+(e?E:0)+t+_);c.style.height=n+`px`}else{let e=o.length>0&&y===o[0].ref.current;c.style.top=`0px`;let t=Math.max(D,p+v.offsetTop+(e?T:0)+O)+j;c.style.height=t+`px`,v.scrollTop=A-D+v.offsetTop}c.style.margin=`${X}px 0`,c.style.minHeight=C+`px`,c.style.maxHeight=l+`px`,r?.(),requestAnimationFrame(()=>g.current=!0)}},[m,a.trigger,a.valueNode,c,u,v,y,b,a.dir,r]);p(()=>S(),[S]);let[C,w]=B.useState();return p(()=>{u&&w(window.getComputedStyle(u).zIndex)},[u]),(0,V.jsx)(Le,{scope:n,contentWrapper:c,shouldExpandOnScrollRef:g,onScrollButtonChange:B.useCallback(e=>{e&&_.current===!0&&(S(),x?.(),_.current=!1)},[S,x]),children:(0,V.jsx)(`div`,{ref:l,style:{display:`flex`,flexDirection:`column`,position:`fixed`,zIndex:C},children:(0,V.jsx)(T.div,{...i,ref:f,style:{boxSizing:`border-box`,maxHeight:`100%`,...i.style}})})})});Pe.displayName=Ne;var Fe=`SelectPopperPosition`,Ie=B.forwardRef((e,t)=>{let{__scopeSelect:n,align:r=`start`,collisionPadding:i=X,...a}=e,o=q(n);return(0,V.jsx)(S,{...o,...a,ref:t,align:r,collisionPadding:i,style:{boxSizing:`border-box`,...a.style,"--radix-select-content-transform-origin":`var(--radix-popper-transform-origin)`,"--radix-select-content-available-width":`var(--radix-popper-available-width)`,"--radix-select-content-available-height":`var(--radix-popper-available-height)`,"--radix-select-trigger-width":`var(--radix-popper-anchor-width)`,"--radix-select-trigger-height":`var(--radix-popper-anchor-height)`}})});Ie.displayName=Fe;var[Le,Re]=K(Y,{}),ze=`SelectViewport`,Be=B.forwardRef((e,t)=>{let{__scopeSelect:n,nonce:r,...i}=e,a=Z(ze,n),o=Re(ze,n),s=h(t,a.onViewportChange),c=B.useRef(0);return(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(`style`,{dangerouslySetInnerHTML:{__html:`[data-radix-select-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-select-viewport]::-webkit-scrollbar{display:none}`},nonce:r}),(0,V.jsx)(W.Slot,{scope:n,children:(0,V.jsx)(T.div,{"data-radix-select-viewport":``,role:`presentation`,...i,ref:s,style:{position:`relative`,flex:1,overflow:`hidden auto`,...i.style},onScroll:_(i.onScroll,e=>{let t=e.currentTarget,{contentWrapper:n,shouldExpandOnScrollRef:r}=o;if(r?.current&&n){let e=Math.abs(c.current-t.scrollTop);if(e>0){let r=window.innerHeight-X*2,i=parseFloat(n.style.minHeight),a=parseFloat(n.style.height),o=Math.max(i,a);if(o<r){let i=o+e,a=Math.min(r,i),s=i-a;n.style.height=a+`px`,n.style.bottom===`0px`&&(t.scrollTop=s>0?s:0,n.style.justifyContent=`flex-end`)}}}c.current=t.scrollTop})})})]})});Be.displayName=ze;var Ve=`SelectGroup`,[He,Ue]=K(Ve),We=B.forwardRef((e,t)=>{let{__scopeSelect:n,...r}=e,i=j();return(0,V.jsx)(He,{scope:n,id:i,children:(0,V.jsx)(T.div,{role:`group`,"aria-labelledby":i,...r,ref:t})})});We.displayName=Ve;var Ge=`SelectLabel`,Ke=B.forwardRef((e,t)=>{let{__scopeSelect:n,...r}=e,i=Ue(Ge,n);return(0,V.jsx)(T.div,{id:i.id,...r,ref:t})});Ke.displayName=Ge;var qe=`SelectItem`,[Je,Ye]=K(qe),Xe=B.forwardRef((e,t)=>{let{__scopeSelect:n,value:r,disabled:i=!1,textValue:a,...o}=e,s=J(qe,n),c=Z(qe,n),l=s.value===r,[u,d]=B.useState(a??``),[f,p]=B.useState(!1),m=h(t,e=>c.itemRefCallback?.(e,r,i)),g=j(),v=B.useRef(`touch`),y=()=>{i||(s.onValueChange(r),s.onOpenChange(!1))};if(r===``)throw Error(`A <Select.Item /> must have a value prop that is not an empty string. This is because the Select value can be set to an empty string to clear the selection and show the placeholder.`);return(0,V.jsx)(Je,{scope:n,value:r,disabled:i,textId:g,isSelected:l,onItemTextChange:B.useCallback(e=>{d(t=>t||(e?.textContent??``).trim())},[]),children:(0,V.jsx)(W.ItemSlot,{scope:n,value:r,disabled:i,textValue:u,children:(0,V.jsx)(T.div,{role:`option`,"aria-labelledby":g,"data-highlighted":f?``:void 0,"aria-selected":l&&f,"data-state":l?`checked`:`unchecked`,"aria-disabled":i||void 0,"data-disabled":i?``:void 0,tabIndex:i?void 0:-1,...o,ref:m,onFocus:_(o.onFocus,()=>p(!0)),onBlur:_(o.onBlur,()=>p(!1)),onClick:_(o.onClick,()=>{v.current!==`mouse`&&y()}),onPointerUp:_(o.onPointerUp,()=>{v.current===`mouse`&&y()}),onPointerDown:_(o.onPointerDown,e=>{v.current=e.pointerType}),onPointerMove:_(o.onPointerMove,e=>{v.current=e.pointerType,i?c.onItemLeave?.():v.current===`mouse`&&e.currentTarget.focus({preventScroll:!0})}),onPointerLeave:_(o.onPointerLeave,e=>{e.currentTarget===document.activeElement&&c.onItemLeave?.()}),onKeyDown:_(o.onKeyDown,e=>{c.searchRef?.current!==``&&e.key===` `||(pe.includes(e.key)&&y(),e.key===` `&&e.preventDefault())})})})})});Xe.displayName=qe;var Q=`SelectItemText`,Ze=B.forwardRef((e,t)=>{let{__scopeSelect:n,className:r,style:i,...a}=e,o=J(Q,n),s=Z(Q,n),c=Ye(Q,n),l=ve(Q,n),[u,d]=B.useState(null),f=h(t,e=>d(e),c.onItemTextChange,e=>s.itemTextRefCallback?.(e,c.value,c.disabled)),m=u?.textContent,g=B.useMemo(()=>(0,V.jsx)(`option`,{value:c.value,disabled:c.disabled,children:m},c.value),[c.disabled,c.value,m]),{onNativeOptionAdd:_,onNativeOptionRemove:v}=l;return p(()=>(_(g),()=>v(g)),[_,v,g]),(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(T.span,{id:c.textId,...a,ref:f}),c.isSelected&&o.valueNode&&!o.valueNodeHasChildren?de.createPortal(a.children,o.valueNode):null]})});Ze.displayName=Q;var Qe=`SelectItemIndicator`,$e=B.forwardRef((e,t)=>{let{__scopeSelect:n,...r}=e;return Ye(Qe,n).isSelected?(0,V.jsx)(T.span,{"aria-hidden":!0,...r,ref:t}):null});$e.displayName=Qe;var et=`SelectScrollUpButton`,tt=B.forwardRef((e,t)=>{let n=Z(et,e.__scopeSelect),r=Re(et,e.__scopeSelect),[i,a]=B.useState(!1),o=h(t,r.onScrollButtonChange);return p(()=>{if(n.viewport&&n.isPositioned){let e=function(){a(t.scrollTop>0)},t=n.viewport;return e(),t.addEventListener(`scroll`,e),()=>t.removeEventListener(`scroll`,e)}},[n.viewport,n.isPositioned]),i?(0,V.jsx)(it,{...e,ref:o,onAutoScroll:()=>{let{viewport:e,selectedItem:t}=n;e&&t&&(e.scrollTop-=t.offsetHeight)}}):null});tt.displayName=et;var nt=`SelectScrollDownButton`,rt=B.forwardRef((e,t)=>{let n=Z(nt,e.__scopeSelect),r=Re(nt,e.__scopeSelect),[i,a]=B.useState(!1),o=h(t,r.onScrollButtonChange);return p(()=>{if(n.viewport&&n.isPositioned){let e=function(){let e=t.scrollHeight-t.clientHeight;a(Math.ceil(t.scrollTop)<e)},t=n.viewport;return e(),t.addEventListener(`scroll`,e),()=>t.removeEventListener(`scroll`,e)}},[n.viewport,n.isPositioned]),i?(0,V.jsx)(it,{...e,ref:o,onAutoScroll:()=>{let{viewport:e,selectedItem:t}=n;e&&t&&(e.scrollTop+=t.offsetHeight)}}):null});rt.displayName=nt;var it=B.forwardRef((e,t)=>{let{__scopeSelect:n,onAutoScroll:r,...i}=e,a=Z(`SelectScrollButton`,n),o=B.useRef(null),s=G(n),c=B.useCallback(()=>{o.current!==null&&(window.clearInterval(o.current),o.current=null)},[]);return B.useEffect(()=>()=>c(),[c]),p(()=>{s().find(e=>e.ref.current===document.activeElement)?.ref.current?.scrollIntoView({block:`nearest`})},[s]),(0,V.jsx)(T.div,{"aria-hidden":!0,...i,ref:t,style:{flexShrink:0,...i.style},onPointerDown:_(i.onPointerDown,()=>{o.current===null&&(o.current=window.setInterval(r,50))}),onPointerMove:_(i.onPointerMove,()=>{a.onItemLeave?.(),o.current===null&&(o.current=window.setInterval(r,50))}),onPointerLeave:_(i.onPointerLeave,()=>{c()})})}),at=`SelectSeparator`,ot=B.forwardRef((e,t)=>{let{__scopeSelect:n,...r}=e;return(0,V.jsx)(T.div,{"aria-hidden":!0,...r,ref:t})});ot.displayName=at;var st=`SelectArrow`,ct=B.forwardRef((e,t)=>{let{__scopeSelect:n,...r}=e,i=q(n),a=J(st,n),o=Z(st,n);return a.open&&o.position===`popper`?(0,V.jsx)(x,{...i,...r,ref:t}):null});ct.displayName=st;var lt=`SelectBubbleInput`,ut=B.forwardRef(({__scopeSelect:e,value:t,...n},r)=>{let i=B.useRef(null),a=h(r,i),o=H(t);return B.useEffect(()=>{let e=i.current;if(!e)return;let n=window.HTMLSelectElement.prototype,r=Object.getOwnPropertyDescriptor(n,`value`).set;if(o!==t&&r){let n=new Event(`change`,{bubbles:!0});r.call(e,t),e.dispatchEvent(n)}},[o,t]),(0,V.jsx)(T.select,{...n,style:{...ie,...n.style},ref:a,defaultValue:t})});ut.displayName=lt;function dt(e){return e===``||e===void 0}function ft(e){let t=v(e),n=B.useRef(``),r=B.useRef(0),i=B.useCallback(e=>{let i=n.current+e;t(i),(function e(t){n.current=t,window.clearTimeout(r.current),t!==``&&(r.current=window.setTimeout(()=>e(``),1e3))})(i)},[t]),a=B.useCallback(()=>{n.current=``,window.clearTimeout(r.current)},[]);return B.useEffect(()=>()=>window.clearTimeout(r.current),[]),[n,i,a]}function pt(e,t,n){let r=t.length>1&&Array.from(t).every(e=>e===t[0])?t[0]:t,i=n?e.indexOf(n):-1,a=mt(e,Math.max(i,0));r.length===1&&(a=a.filter(e=>e!==n));let o=a.find(e=>e.textValue.toLowerCase().startsWith(r.toLowerCase()));return o===n?void 0:o}function mt(e,t){return e.map((n,r)=>e[(t+r)%e.length])}var ht=ye,gt=xe,_t=Ce,vt=Te,yt=De,bt=Oe,xt=Be,St=Xe,Ct=Ze,wt=$e,Tt=tt,Et=rt,Dt=`Switch`,[Ot,kt]=d(Dt),[At,jt]=Ot(Dt),Mt=B.forwardRef((e,t)=>{let{__scopeSwitch:n,name:r,checked:i,defaultChecked:a,required:o,disabled:s,value:c=`on`,onCheckedChange:l,form:u,...d}=e,[f,p]=B.useState(null),g=h(t,e=>p(e)),v=B.useRef(!1),y=f?u||!!f.closest(`form`):!0,[b,x]=m({prop:i,defaultProp:a??!1,onChange:l,caller:Dt});return(0,V.jsxs)(At,{scope:n,checked:b,disabled:s,children:[(0,V.jsx)(T.button,{type:`button`,role:`switch`,"aria-checked":b,"aria-required":o,"data-state":Lt(b),"data-disabled":s?``:void 0,disabled:s,value:c,...d,ref:g,onClick:_(e.onClick,e=>{x(e=>!e),y&&(v.current=e.isPropagationStopped(),v.current||e.stopPropagation())})}),y&&(0,V.jsx)(It,{control:f,bubbles:!v.current,name:r,value:c,checked:b,required:o,disabled:s,form:u,style:{transform:`translateX(-100%)`}})]})});Mt.displayName=Dt;var Nt=`SwitchThumb`,Pt=B.forwardRef((e,t)=>{let{__scopeSwitch:n,...r}=e,i=jt(Nt,n);return(0,V.jsx)(T.span,{"data-state":Lt(i.checked),"data-disabled":i.disabled?``:void 0,...r,ref:t})});Pt.displayName=Nt;var Ft=`SwitchBubbleInput`,It=B.forwardRef(({__scopeSwitch:e,control:t,checked:n,bubbles:r=!0,...i},a)=>{let o=B.useRef(null),s=h(o,a),c=H(n),l=w(t);return B.useEffect(()=>{let e=o.current;if(!e)return;let t=window.HTMLInputElement.prototype,i=Object.getOwnPropertyDescriptor(t,`checked`).set;if(c!==n&&i){let t=new Event(`click`,{bubbles:r});i.call(e,n),e.dispatchEvent(t)}},[c,n,r]),(0,V.jsx)(`input`,{type:`checkbox`,"aria-hidden":!0,defaultChecked:n,...i,tabIndex:-1,ref:s,style:{...i.style,...l,position:`absolute`,pointerEvents:`none`,opacity:0,margin:0}})});It.displayName=Ft;function Lt(e){return e?`checked`:`unchecked`}var Rt=Mt,zt=Pt;function $({className:e,...t}){return(0,V.jsx)(ue,{"data-slot":`label`,className:N(`flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50`,e),...t})}function Bt({...e}){return(0,V.jsx)(ht,{"data-slot":`select`,...e})}function Vt({...e}){return(0,V.jsx)(_t,{"data-slot":`select-value`,...e})}function Ht({className:e,size:t=`default`,children:n,...r}){return(0,V.jsxs)(gt,{"data-slot":`select-trigger`,"data-size":t,className:N(`flex w-fit items-center justify-between gap-2 rounded-md border border-input bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[placeholder]:text-muted-foreground data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground`,e),...r,children:[n,(0,V.jsx)(vt,{asChild:!0,children:(0,V.jsx)(a,{className:`size-4 opacity-50`})})]})}function Ut({className:e,children:t,position:n=`item-aligned`,align:r=`center`,...i}){return(0,V.jsx)(yt,{children:(0,V.jsxs)(bt,{"data-slot":`select-content`,className:N(`relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border bg-popover text-popover-foreground shadow-md data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95`,n===`popper`&&`data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1`,e),position:n,align:r,...i,children:[(0,V.jsx)(Gt,{}),(0,V.jsx)(xt,{className:N(`p-1`,n===`popper`&&`h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1`),children:t}),(0,V.jsx)(Kt,{})]})})}function Wt({className:e,children:t,...n}){return(0,V.jsxs)(St,{"data-slot":`select-item`,className:N(`relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2`,e),...n,children:[(0,V.jsx)(`span`,{"data-slot":`select-item-indicator`,className:`absolute right-2 flex size-3.5 items-center justify-center`,children:(0,V.jsx)(wt,{children:(0,V.jsx)(i,{className:`size-4`})})}),(0,V.jsx)(Ct,{children:t})]})}function Gt({className:e,...t}){return(0,V.jsx)(Tt,{"data-slot":`select-scroll-up-button`,className:N(`flex cursor-default items-center justify-center py-1`,e),...t,children:(0,V.jsx)(o,{className:`size-4`})})}function Kt({className:e,...t}){return(0,V.jsx)(Et,{"data-slot":`select-scroll-down-button`,className:N(`flex cursor-default items-center justify-center py-1`,e),...t,children:(0,V.jsx)(a,{className:`size-4`})})}var qt=B.forwardRef(({className:e,...t},n)=>(0,V.jsx)(Rt,{className:N(`peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input`,e),...t,ref:n,children:(0,V.jsx)(zt,{className:N(`pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0`)})}));qt.displayName=Rt.displayName;var Jt={claude:`C`,cursor:`▶`,codex:`◆`,gemini:`G`};function Yt({value:e,onChange:t,projectName:n}){let[r,a]=(0,B.useState)([]),[o,s]=(0,B.useState)(!1),c=(0,B.useRef)(null),l=(0,B.useRef)(0);(0,B.useEffect)(()=>{n&&F.get(`${P(n)}/chat/providers`).then(a).catch(()=>{})},[n]),(0,B.useEffect)(()=>{if(!o)return;let e=e=>{c.current&&!c.current.contains(e.target)&&s(!1)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[o]),(0,B.useEffect)(()=>{o&&(l.current=Math.max(0,r.findIndex(t=>t.id===e)))},[o,e,r]);let u=(0,B.useCallback)(e=>{if(e.key===`Escape`){s(!1);return}if(e.key===`ArrowDown`||e.key===`ArrowUp`){e.preventDefault();let t=e.key===`ArrowDown`?1:-1;l.current=(l.current+t+r.length)%r.length,(c.current?.querySelector(`[data-idx="${l.current}"]`))?.focus()}if(e.key===`Enter`){e.preventDefault();let n=r[l.current];n&&(t(n.id),s(!1))}},[t,r]);if(r.length<=1)return null;let d=r.find(t=>t.id===e),f=Jt[e]||`?`;return(0,V.jsxs)(`div`,{className:`relative`,children:[(0,V.jsxs)(`button`,{type:`button`,onClick:e=>{e.stopPropagation(),s(e=>!e)},className:`inline-flex items-center gap-1 px-2 py-1 rounded-md text-[11px] text-text-subtle hover:text-text-primary hover:bg-surface-elevated transition-colors border border-transparent hover:border-border`,"aria-label":`AI Provider: ${d?.name??e}`,children:[(0,V.jsx)(`span`,{className:`inline-flex h-3.5 w-3.5 items-center justify-center rounded text-[9px] font-bold bg-surface-elevated shrink-0`,children:f}),(0,V.jsx)(`span`,{className:`max-w-[80px] truncate capitalize`,children:d?.name??e})]}),o&&(0,V.jsxs)(`div`,{ref:c,role:`listbox`,"aria-label":`AI Providers`,onKeyDown:u,onMouseDown:e=>e.stopPropagation(),onClick:e=>e.stopPropagation(),className:`absolute bottom-full left-0 mb-1 z-50 w-56 rounded-lg border border-border bg-surface shadow-lg`,children:[(0,V.jsx)(`div`,{className:`px-3 py-2 border-b border-border`,children:(0,V.jsx)(`span`,{className:`text-xs font-medium text-text-secondary`,children:`Provider`})}),(0,V.jsx)(`div`,{className:`py-1`,children:r.map((n,r)=>{let a=Jt[n.id]||`?`,o=n.id===e;return(0,V.jsxs)(`button`,{"data-idx":r,role:`option`,"aria-selected":o,tabIndex:0,onClick:()=>{t(n.id),s(!1)},className:`w-full flex items-center gap-3 px-3 py-2 text-left transition-colors hover:bg-surface-elevated focus:bg-surface-elevated focus:outline-none ${o?`bg-surface-elevated`:``}`,children:[(0,V.jsx)(`span`,{className:`inline-flex h-5 w-5 items-center justify-center rounded text-[11px] font-bold bg-surface-elevated text-text-subtle shrink-0`,children:a}),(0,V.jsx)(`span`,{className:`flex-1 text-sm font-medium text-text-primary capitalize`,children:n.name}),o&&(0,V.jsx)(i,{className:`size-4 shrink-0 text-primary`})]},n.id)})})]})]})}function Xt({providerId:e}){return(0,V.jsx)(`span`,{className:`inline-flex h-4 w-4 items-center justify-center rounded text-[10px] font-bold bg-surface-elevated text-text-subtle shrink-0`,title:e,children:Jt[e]||`?`})}var Zt=[{value:`low`,label:`Low`},{value:`medium`,label:`Medium`},{value:`high`,label:`High`}],Qt=[{value:`bypassPermissions`,label:`Bypass permissions (default)`},{value:`default`,label:`Ask before edits`},{value:`acceptEdits`,label:`Edit automatically`},{value:`plan`,label:`Plan mode`}],$t={claude:`Claude`,cursor:`Cursor`,codex:`Codex`,gemini:`Gemini`};function en({compact:e}={}){let[t,n]=(0,B.useState)(null),[r,i]=(0,B.useState)(``),[a,o]=(0,B.useState)([]),[s,c]=(0,B.useState)(!1),[l,u]=(0,B.useState)(!1),[d,f]=(0,B.useState)(null),[p,m]=(0,B.useState)(0);(0,B.useEffect)(()=>{I().then(e=>{n(e),i(e.default_provider??`claude`)}).catch(e=>f(e.message))},[]),(0,B.useEffect)(()=>{r&&(c(!0),F.get(`/api/settings/ai/providers/${r}/models`).then(o).catch(()=>o([])).finally(()=>c(!1)))},[r]);let h=t?Object.keys(t.providers).filter(e=>e!==`mock`).map(e=>({id:e,name:$t[e]??e})):[],g=t?.providers[r],_=g?.type===`agent-sdk`||!g?.type&&r===`claude`,v=async(e,i)=>{if(t){u(!0),f(null);try{n(await L({providers:{[r]:{[e]:i}}})),m(e=>e+1)}catch(e){f(e.message)}finally{u(!1)}}},y=e?`text-[11px]`:`text-sm`,b=e?`text-xs`:`text-sm`,x=e?`space-y-2`:`space-y-4`,S=e?`space-y-1.5`:`space-y-3`,C=e?`space-y-1`:`space-y-1.5`;if(!t)return(0,V.jsxs)(`div`,{className:S,children:[(0,V.jsx)(`h3`,{className:`${b} font-medium text-text-secondary`,children:`AI Settings`}),(0,V.jsx)(`p`,{className:`${y} text-text-subtle`,children:d?`Error: ${d}`:`Loading...`})]});let w=_?a:[{value:`__default__`,label:`Auto (default)`},...a];return(0,V.jsxs)(`div`,{className:x,children:[(0,V.jsx)(`h3`,{className:`${b} font-medium text-text-secondary`,children:`AI Settings`}),h.length>1&&(0,V.jsx)(`div`,{className:`flex gap-0.5 border-b border-border/50 -mx-1 px-1`,children:h.map(e=>(0,V.jsxs)(`button`,{onClick:()=>i(e.id),className:`flex items-center gap-1 px-2 py-1 text-[11px] rounded-t transition-colors ${r===e.id?`text-primary border-b-2 border-primary font-medium`:`text-text-subtle hover:text-text-secondary`}`,children:[(0,V.jsx)(Xt,{providerId:e.id}),(0,V.jsx)(`span`,{className:`capitalize`,children:e.name})]},e.id))}),(0,V.jsxs)(`div`,{className:S,children:[a.length>0&&(0,V.jsxs)(`div`,{className:C,children:[(0,V.jsx)($,{htmlFor:`ai-model`,className:e?y:void 0,children:`Model`}),(0,V.jsxs)(Bt,{value:_?g?.model??a[0]?.value:g?.model||`__default__`,onValueChange:e=>v(`model`,e===`__default__`?void 0:e),disabled:s,children:[(0,V.jsx)(Ht,{id:`ai-model`,className:`w-full ${e?`h-7 text-[11px]`:``}`,children:(0,V.jsx)(Vt,{placeholder:s?`Loading models...`:`Select model`})}),(0,V.jsx)(Ut,{className:`max-h-[300px]`,children:w.map(e=>(0,V.jsx)(Wt,{value:e.value,children:e.label},e.value))})]})]}),_&&(0,V.jsxs)(V.Fragment,{children:[(0,V.jsxs)(`div`,{className:C,children:[(0,V.jsx)($,{htmlFor:`ai-base-url`,className:e?y:void 0,children:`Base URL`}),(0,V.jsx)(O,{id:`ai-base-url`,type:`url`,defaultValue:g?.base_url??``,placeholder:`https://api.anthropic.com (default)`,className:e?`h-7 text-[11px]`:void 0,onBlur:e=>{v(`base_url`,e.target.value.trim()||void 0)}},`baseurl-${r}-${p}`)]}),(0,V.jsxs)(`div`,{className:C,children:[(0,V.jsx)($,{htmlFor:`ai-api-key`,className:e?y:void 0,children:`API Key / Token`}),(0,V.jsx)(O,{id:`ai-api-key`,type:`password`,defaultValue:g?.api_key??``,placeholder:`sk-ant-... (optional, overrides accounts)`,className:e?`h-7 text-[11px] font-mono`:`font-mono`,onBlur:e=>{let t=e.target.value.trim();t.startsWith(`••••`)||v(`api_key`,t||void 0)}},`apikey-${r}-${p}`),(0,V.jsx)(`p`,{className:`${e?`text-[9px]`:`text-[11px]`} text-muted-foreground`,children:`Direct API key or OAuth token. Leave empty to use connected accounts.`})]}),(0,V.jsxs)(`div`,{className:C,children:[(0,V.jsx)($,{htmlFor:`ai-effort`,className:e?y:void 0,children:`Effort`}),(0,V.jsxs)(Bt,{value:g?.effort??`high`,onValueChange:e=>v(`effort`,e),children:[(0,V.jsx)(Ht,{id:`ai-effort`,className:`w-full ${e?`h-7 text-[11px]`:``}`,children:(0,V.jsx)(Vt,{})}),(0,V.jsx)(Ut,{children:Zt.map(e=>(0,V.jsx)(Wt,{value:e.value,children:e.label},e.value))})]})]}),(0,V.jsxs)(`div`,{className:C,children:[(0,V.jsx)($,{htmlFor:`ai-max-turns`,className:e?y:void 0,children:`Max Turns (1-500)`}),(0,V.jsx)(O,{id:`ai-max-turns`,type:`number`,min:1,max:500,defaultValue:g?.max_turns??100,className:e?`h-7 text-[11px]`:void 0,onBlur:e=>{let t=parseInt(e.target.value);isNaN(t)||v(`max_turns`,t)}},`turns-${r}-${p}`)]}),(0,V.jsxs)(`div`,{className:C,children:[(0,V.jsx)($,{htmlFor:`ai-budget`,className:e?y:void 0,children:`Max Budget (USD)`}),(0,V.jsx)(O,{id:`ai-budget`,type:`number`,step:.1,min:.01,max:50,defaultValue:g?.max_budget_usd??``,placeholder:`No limit`,className:e?`h-7 text-[11px]`:void 0,onBlur:e=>{let t=parseFloat(e.target.value);v(`max_budget_usd`,isNaN(t)?void 0:t)}},`budget-${r}-${p}`)]}),(0,V.jsxs)(`div`,{className:C,children:[(0,V.jsx)($,{htmlFor:`ai-thinking`,className:e?y:void 0,children:`Thinking Budget (tokens)`}),(0,V.jsx)(O,{id:`ai-thinking`,type:`number`,min:0,defaultValue:g?.thinking_budget_tokens??``,placeholder:`Disabled`,className:e?`h-7 text-[11px]`:void 0,onBlur:e=>{let t=parseInt(e.target.value);v(`thinking_budget_tokens`,isNaN(t)?void 0:t)}},`thinking-${r}-${p}`)]}),(0,V.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,V.jsxs)(`div`,{children:[(0,V.jsx)($,{htmlFor:`ai-agent-teams`,className:e?y:void 0,children:`Agent Teams`}),(0,V.jsx)(`p`,{className:`${e?`text-[9px]`:`text-[11px]`} text-muted-foreground`,children:`Experimental. Enables multi-agent collaboration with shared tasks and messaging. Uses ~7x more tokens.`})]}),(0,V.jsx)(qt,{id:`ai-agent-teams`,checked:g?.agent_teams??!1,onCheckedChange:e=>v(`agent_teams`,e)})]}),g?.agent_teams&&(0,V.jsx)(tn,{compact:e})]}),(0,V.jsxs)(`div`,{className:C,children:[(0,V.jsx)($,{htmlFor:`ai-permission-mode`,className:e?y:void 0,children:`Default Permission Mode`}),(0,V.jsxs)(Bt,{value:g?.permission_mode??`bypassPermissions`,onValueChange:e=>v(`permission_mode`,e),children:[(0,V.jsx)(Ht,{id:`ai-permission-mode`,className:`w-full ${e?`h-7 text-[11px]`:``}`,children:(0,V.jsx)(Vt,{})}),(0,V.jsx)(Ut,{children:Qt.map(e=>(0,V.jsx)(Wt,{value:e.value,children:e.label},e.value))})]})]}),(0,V.jsxs)(`div`,{className:C,children:[(0,V.jsx)($,{htmlFor:`ai-system-prompt`,className:e?y:void 0,children:`Additional Instructions`}),(0,V.jsx)(`textarea`,{id:`ai-system-prompt`,rows:e?3:4,defaultValue:g?.system_prompt??``,placeholder:`Enter additional instructions for ${r}...`,className:`w-full rounded-md border border-input bg-background px-3 py-2 ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ${e?`text-[11px]`:`text-sm`}`,onBlur:e=>{v(`system_prompt`,e.target.value.trim()||void 0)}},`sysprompt-${r}-${p}`)]})]}),l&&(0,V.jsx)(`p`,{className:`text-xs text-text-subtle`,children:`Saving...`}),d&&(0,V.jsx)(`p`,{className:`text-xs text-red-500`,children:d})]})}function tn({compact:e}){let[t,n]=(0,B.useState)([]),[r,i]=(0,B.useState)(!1),[a,o]=(0,B.useState)(null),s=(0,B.useCallback)(async()=>{i(!0);try{n(await F.get(`/api/teams`)??[])}catch{}i(!1)},[]);(0,B.useEffect)(()=>{s()},[s]);let u=async e=>{try{await F.del(`/api/teams/${encodeURIComponent(e)}`),n(t=>t.filter(t=>t.name!==e)),o(null)}catch{}};return t.length===0&&!r?null:(0,V.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,V.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,V.jsxs)($,{className:e?`text-[11px]`:void 0,children:[`Teams (`,t.length,`)`]}),(0,V.jsx)(`button`,{onClick:s,className:`text-text-subtle hover:text-foreground p-1`,"aria-label":`Refresh teams`,children:(0,V.jsx)(c,{className:`size-3 ${r?`animate-spin`:``}`})})]}),t.map(e=>(0,V.jsxs)(`div`,{className:`flex items-center justify-between p-2 rounded bg-surface-elevated text-xs`,children:[(0,V.jsxs)(`div`,{className:`min-w-0`,children:[(0,V.jsx)(`div`,{className:`font-medium truncate`,children:e.name}),e.description&&(0,V.jsx)(`div`,{className:`text-text-subtle truncate`,children:e.description}),(0,V.jsxs)(`div`,{className:`text-text-subtle`,children:[e.members?.length??e.memberCount??0,` members`,e.createdAt?` · ${new Date(e.createdAt).toLocaleDateString()}`:``]})]}),a===e.name?(0,V.jsxs)(`div`,{className:`flex gap-1 shrink-0 ml-2`,children:[(0,V.jsx)(`button`,{onClick:()=>u(e.name),className:`px-2 py-1 bg-red-600 text-white rounded text-[10px]`,children:`Delete`}),(0,V.jsx)(`button`,{onClick:()=>o(null),className:`px-2 py-1 bg-zinc-600 text-white rounded text-[10px]`,children:`Cancel`})]}):(0,V.jsx)(`button`,{onClick:()=>o(e.name),className:`shrink-0 text-text-subtle hover:text-red-500 p-1 ml-2`,"aria-label":`Delete team ${e.name}`,children:(0,V.jsx)(l,{className:`size-3.5`})})]},e.name))]})}export{Bt as a,Ht as c,se as d,re as f,ne as h,qt as i,Vt as l,R as m,Xt as n,Ut as o,z as p,Yt as r,Wt as s,en as t,$ as u};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"./chunk-XZSTWKYB-Dbp1nUSQ.js";import{n as e}from"./chunk-R5LLSJPH-C37xW0vj.js";export{e as createArchitectureServices};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./createLucideIcon-PuMiQgHl.js";var t=e(`arrow-up`,[[`path`,{d:`m5 12 7-7 7 7`,key:`hav0vg`}],[`path`,{d:`M12 19V5`,key:`x0mq9r`}]]);export{t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{it as e,rt as t}from"./chunk-7R4GIKGN-Czlaj26D.js";var n=(n,r)=>e.lang.round(t.parse(n)[r]);export{n as t};
|