@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.
Files changed (243) hide show
  1. package/260415-0932-git-graph-stash-rebase-conflicts/reports/code-reviewer-260415-1020-stash-rebase-conflicts.md +288 -0
  2. package/260415-0932-git-graph-stash-rebase-conflicts/reports/tester-260415-1020-build-check.md +117 -0
  3. package/260415-1150-ext-silent-failure-debugging/reports/code-reviewer-260415-1159-ext-error-reporting-review.md +205 -0
  4. package/260415-1150-ext-silent-failure-debugging/reports/docs-manager-260415-1206-ext-error-reporting.md +99 -0
  5. package/260415-1150-ext-silent-failure-debugging/reports/tester-260415-1159-extension-error-reporting.md +174 -0
  6. package/CHANGELOG.md +24 -0
  7. package/dist/web/assets/{_basePickBy-D-bUmjma.js → _basePickBy-Bj0dI1ei.js} +1 -1
  8. package/dist/web/assets/{_baseUniq-BnXXIfRB.js → _baseUniq-CyzdZeQH.js} +1 -1
  9. package/dist/web/assets/ai-settings-section-Bo9lCaTd.js +1 -0
  10. package/dist/web/assets/{api-settings-Qi2xRiHa.js → api-settings-CUxg9RE5.js} +1 -1
  11. package/dist/web/assets/{arc-DB9vXGzd.js → arc-CxgHJ7Z4.js} +1 -1
  12. package/dist/web/assets/architecture-PBZL5I3N-DDFO_NKq.js +1 -0
  13. package/dist/web/assets/{architectureDiagram-2XIMDMQ5-BBV25747.js → architectureDiagram-2XIMDMQ5-D16OotsC.js} +1 -1
  14. package/dist/web/assets/arrow-up-I9-21gkR.js +1 -0
  15. package/dist/web/assets/{blockDiagram-WCTKOSBZ-BOTnY2Lq.js → blockDiagram-WCTKOSBZ-Ct57Wtfk.js} +1 -1
  16. package/dist/web/assets/{c4Diagram-IC4MRINW-D7QAUdHD.js → c4Diagram-IC4MRINW-BIymcNsg.js} +1 -1
  17. package/dist/web/assets/channel-wumTB1if.js +1 -0
  18. package/dist/web/assets/chat-tab-R4gKsnxD.js +10 -0
  19. package/dist/web/assets/chevron-right-DY_wImxB.js +1 -0
  20. package/dist/web/assets/{chunk-4BX2VUAB-BnOVw77D.js → chunk-4BX2VUAB-CENmY7Kw.js} +1 -1
  21. package/dist/web/assets/{chunk-55IACEB6-BftA8DxR.js → chunk-55IACEB6-DhZGI1l3.js} +1 -1
  22. package/dist/web/assets/{chunk-7E7YKBS2-B0vnP8v3.js → chunk-7E7YKBS2-DZcnC7Ow.js} +1 -1
  23. package/dist/web/assets/{chunk-7R4GIKGN-Czlaj26D.js → chunk-7R4GIKGN-y8bfHEy-.js} +2 -2
  24. package/dist/web/assets/{chunk-C72U2L5F-DpEbDtMo.js → chunk-C72U2L5F-BHPkfQj2.js} +1 -1
  25. package/dist/web/assets/{chunk-EGIJ26TM-BWXe6lkx.js → chunk-EGIJ26TM-nant2LXl.js} +1 -1
  26. package/dist/web/assets/{chunk-FMBD7UC4-DspqhPfk.js → chunk-FMBD7UC4-Bog4cpN-.js} +1 -1
  27. package/dist/web/assets/{chunk-GEFDOKGD-D6HHRbYk.js → chunk-GEFDOKGD-86LFbsAC.js} +1 -1
  28. package/dist/web/assets/chunk-GLR3WWYH-Re-5eSlQ.js +2 -0
  29. package/dist/web/assets/chunk-HHEYEP7N-C45i5G_3.js +1 -0
  30. package/dist/web/assets/{chunk-JSJVCQXG-BC8wnMwf.js → chunk-JSJVCQXG-23eG9mgt.js} +1 -1
  31. package/dist/web/assets/{chunk-KX2RTZJC-D3VDtyvX.js → chunk-KX2RTZJC-CHj8TnTB.js} +1 -1
  32. package/dist/web/assets/{chunk-KYZI473N-Z-NBw_HS.js → chunk-KYZI473N-gqRLpJ4w.js} +1 -1
  33. package/dist/web/assets/{chunk-L3YUKLVL--RGkEh__.js → chunk-L3YUKLVL-DnSMmNFC.js} +1 -1
  34. package/dist/web/assets/{chunk-MX3YWQON-2B76t_Kx.js → chunk-MX3YWQON-B6g1ZH9X.js} +1 -1
  35. package/dist/web/assets/{chunk-NQ4KR5QH-BekY3tEi.js → chunk-NQ4KR5QH-DX32345Y.js} +1 -1
  36. package/dist/web/assets/{chunk-O4XLMI2P-2CJLfx_1.js → chunk-O4XLMI2P-Vp_V4P-b.js} +1 -1
  37. package/dist/web/assets/{chunk-OZEHJAEY-sug_L09P.js → chunk-OZEHJAEY-lKq2SWjA.js} +1 -1
  38. package/dist/web/assets/{chunk-PQ6SQG4A-_fwPRLQy.js → chunk-PQ6SQG4A-Bik13fTV.js} +1 -1
  39. package/dist/web/assets/{chunk-PU5JKC2W-BUaTFJVQ.js → chunk-PU5JKC2W-DD95Rx35.js} +1 -1
  40. package/dist/web/assets/chunk-QZHKN3VN-N3VXx1VH.js +1 -0
  41. package/dist/web/assets/{chunk-R5LLSJPH-C37xW0vj.js → chunk-R5LLSJPH-dRhXRnrb.js} +1 -1
  42. package/dist/web/assets/{chunk-WL4C6EOR-CCkt_MT6.js → chunk-WL4C6EOR-B1iIvLOG.js} +1 -1
  43. package/dist/web/assets/{chunk-XIRO2GV7-Dz2LBq7Y.js → chunk-XIRO2GV7-DZBoNl1_.js} +1 -1
  44. package/dist/web/assets/{chunk-XPW4576I-DenTbBuj.js → chunk-XPW4576I-CgLyyW03.js} +1 -1
  45. package/dist/web/assets/{chunk-XZSTWKYB-Dbp1nUSQ.js → chunk-XZSTWKYB-DjV8xl5A.js} +1 -1
  46. package/dist/web/assets/{chunk-YBOYWFTD-3OTKowjE.js → chunk-YBOYWFTD-D_ILLe6_.js} +1 -1
  47. package/dist/web/assets/classDiagram-VBA2DB6C-mr-Cb1me.js +1 -0
  48. package/dist/web/assets/classDiagram-v2-RAHNMMFH-BKe8_uda.js +1 -0
  49. package/dist/web/assets/clone--z5KLAuR.js +1 -0
  50. package/dist/web/assets/code-editor-Br0vzTOy.js +8 -0
  51. package/dist/web/assets/columns-2-IeETSfON.js +1 -0
  52. package/dist/web/assets/conflict-editor-BPgCjnNz.js +19 -0
  53. package/dist/web/assets/{cose-bilkent-S5V4N54A-MbmGZnt0.js → cose-bilkent-S5V4N54A-BGNPFv3x.js} +1 -1
  54. package/dist/web/assets/{csv-preview-uZ_7b8I7.js → csv-preview-BZRICDP0.js} +2 -2
  55. package/dist/web/assets/{dagre-CPhI6v-K.js → dagre-CkhlMHnx.js} +1 -1
  56. package/dist/web/assets/{dagre-KLK3FWXG-CmSE-oNj.js → dagre-KLK3FWXG-Cnp996VG.js} +1 -1
  57. package/dist/web/assets/database-CgTomMxt.js +1 -0
  58. package/dist/web/assets/{database-viewer-5xljX0JI.js → database-viewer-DaUoQ-oR.js} +2 -2
  59. package/dist/web/assets/{diagram-E7M64L7V-B5XG3ZT7.js → diagram-E7M64L7V-BZF0tSOr.js} +1 -1
  60. package/dist/web/assets/{diagram-IFDJBPK2-BsP248aX.js → diagram-IFDJBPK2-nUcO8sN8.js} +1 -1
  61. package/dist/web/assets/{diagram-P4PSJMXO-Cna3408N.js → diagram-P4PSJMXO-CW0eCkwC.js} +1 -1
  62. package/dist/web/assets/diff-viewer-BzvK3gAE.js +4 -0
  63. package/dist/web/assets/dist-CM0oD8tQ.js +1 -0
  64. package/dist/web/assets/{erDiagram-INFDFZHY-B7SgktiR.js → erDiagram-INFDFZHY-DSkriYZ9.js} +1 -1
  65. package/dist/web/assets/extension-webview-CGepEw-b.js +3 -0
  66. package/dist/web/assets/{flowDiagram-PKNHOUZH-FOYZZ1OB.js → flowDiagram-PKNHOUZH-CFYAfZBx.js} +1 -1
  67. package/dist/web/assets/{ganttDiagram-A5KZAMGK-CnHVYh9v.js → ganttDiagram-A5KZAMGK-KSn4XAU4.js} +1 -1
  68. package/dist/web/assets/gitGraph-HDMCJU4V-OkvBPi6H.js +1 -0
  69. package/dist/web/assets/{gitGraphDiagram-K3NZZRJ6-0G9XxZay.js → gitGraphDiagram-K3NZZRJ6-BMgjjVys.js} +1 -1
  70. package/dist/web/assets/{graphlib-CNiBwlg_.js → graphlib-BWe1iK_s.js} +1 -1
  71. package/dist/web/assets/index-CKsEzQ4f.js +26 -0
  72. package/dist/web/assets/index-Chf0otez.css +2 -0
  73. package/dist/web/assets/info-3K5VOQVL-BDU2_bYD.js +1 -0
  74. package/dist/web/assets/infoDiagram-LFFYTUFH-Diq4Cyc3.js +2 -0
  75. package/dist/web/assets/input-BHj0veau.js +45 -0
  76. package/dist/web/assets/{isEmpty-CcCb5n2-.js → isEmpty-BfLnxq-B.js} +1 -1
  77. package/dist/web/assets/{ishikawaDiagram-PHBUUO56-D4QCzh5J.js → ishikawaDiagram-PHBUUO56-CiVEvp8o.js} +1 -1
  78. package/dist/web/assets/{journeyDiagram-4ABVD52K-CnHYNfKW.js → journeyDiagram-4ABVD52K-CG_v5Aho.js} +1 -1
  79. package/dist/web/assets/jsx-runtime-BRW_vwa9.js +1 -0
  80. package/dist/web/assets/{kanban-definition-K7BYSVSG-Bh_g3EVu.js → kanban-definition-K7BYSVSG-miB0-_Zq.js} +1 -1
  81. package/dist/web/assets/keybindings-store-D5zgHod8.js +1 -0
  82. package/dist/web/assets/{line-6d3eBADm.js → line-CSuSrJ9J.js} +1 -1
  83. package/dist/web/assets/{linear-cA_2lQy7.js → linear-DFN_MPsw.js} +1 -1
  84. package/dist/web/assets/{markdown-renderer-CZ07F7T6.js → markdown-renderer-DSYnGywb.js} +6 -6
  85. package/dist/web/assets/{mermaid-parser.core-C3kd7JXM.js → mermaid-parser.core-CFdP1Z5_.js} +2 -2
  86. package/dist/web/assets/{mindmap-definition-YRQLILUH-CYiUwhr_.js → mindmap-definition-YRQLILUH-pYPWwASE.js} +1 -1
  87. package/dist/web/assets/{ordinal-XHK5vIzZ.js → ordinal-DpFn432U.js} +1 -1
  88. package/dist/web/assets/packet-RMMSAZCW-BwpIpYB3.js +1 -0
  89. package/dist/web/assets/pie-UPGHQEXC-BPgAfmes.js +1 -0
  90. package/dist/web/assets/{pieDiagram-SKSYHLDU-D0S7jeZA.js → pieDiagram-SKSYHLDU-Dovdlvhu.js} +1 -1
  91. package/dist/web/assets/plus-DQGIb4mQ.js +1 -0
  92. package/dist/web/assets/port-forwarding-tab-vmqDKmk2.js +1 -0
  93. package/dist/web/assets/{postgres-viewer-RldlAO_m.js → postgres-viewer-0lIAosrr.js} +3 -3
  94. package/dist/web/assets/{quadrantDiagram-337W2JSQ-0hNP63hW.js → quadrantDiagram-337W2JSQ-TXe6cU_F.js} +1 -1
  95. package/dist/web/assets/radar-KQ55EAFF-TqxBkWx-.js +1 -0
  96. package/dist/web/assets/refresh-cw-Clk8fdUD.js +1 -0
  97. package/dist/web/assets/{requirementDiagram-Z7DCOOCP-BVnmqFbL.js → requirementDiagram-Z7DCOOCP-CuiiuGS9.js} +1 -1
  98. package/dist/web/assets/{sankeyDiagram-WA2Y5GQK-DVkYdCJb.js → sankeyDiagram-WA2Y5GQK-BbRmhv0t.js} +1 -1
  99. package/dist/web/assets/scroll-area-BpXCNme3.js +1 -0
  100. package/dist/web/assets/{sequenceDiagram-2WXFIKYE-B80s7sOg.js → sequenceDiagram-2WXFIKYE-B2D8IQDb.js} +1 -1
  101. package/dist/web/assets/settings-tab-CMnv1fce.js +1 -0
  102. package/dist/web/assets/{sql-query-editor-CjZ7Z6XL.js → sql-query-editor-Bc2hAwqT.js} +1 -1
  103. package/dist/web/assets/sqlite-viewer-B60MS2Dy.js +1 -0
  104. package/dist/web/assets/square-vBdqj0bF.js +1 -0
  105. package/dist/web/assets/{stateDiagram-RAJIS63D-BPLXgXRR.js → stateDiagram-RAJIS63D-ylr4HxPu.js} +1 -1
  106. package/dist/web/assets/stateDiagram-v2-FVOUBMTO-D6zvxf3M.js +1 -0
  107. package/dist/web/assets/table-Bi27fEaN.js +1 -0
  108. package/dist/web/assets/{terminal-tab-DjzD8GLn.js → terminal-tab-CCJoLstH.js} +2 -2
  109. package/dist/web/assets/text-wrap-D_OmSzhp.js +1 -0
  110. package/dist/web/assets/{timeline-definition-YZTLITO2-fa_51u1X.js → timeline-definition-YZTLITO2-pMv1grvM.js} +1 -1
  111. package/dist/web/assets/trash-2-CNuB-htI.js +1 -0
  112. package/dist/web/assets/treemap-KZPCXAKY-Kck06FKU.js +1 -0
  113. package/dist/web/assets/{use-monaco-theme-D9XFxQuU.js → use-monaco-theme-BJK48EmK.js} +1 -1
  114. package/dist/web/assets/{vennDiagram-LZ73GAT5-kX4jJn6W.js → vennDiagram-LZ73GAT5-C-rkIUbo.js} +1 -1
  115. package/dist/web/assets/x-Dw3TjeY_.js +1 -0
  116. package/dist/web/assets/{xychartDiagram-JWTSCODW-Bzm5lZBs.js → xychartDiagram-JWTSCODW-CtpjAakO.js} +1 -1
  117. package/dist/web/index.html +18 -22
  118. package/dist/web/sw.js +1 -1
  119. package/docs/codebase-summary.md +169 -13
  120. package/docs/extension-development-guide.md +98 -1
  121. package/docs/journals/260414-1400-ext-git-graph-port-complete.md +147 -0
  122. package/docs/journals/260414-1452-git-graph-faithful-port.md +144 -0
  123. package/docs/journals/260414-1810-git-graph-ui-improvements-complete.md +261 -0
  124. package/docs/journals/260414-2001-bundled-extensions.md +219 -0
  125. package/docs/project-changelog.md +123 -21
  126. package/docs/project-roadmap.md +4 -2
  127. package/docs/system-architecture.md +77 -6
  128. package/package.json +1 -1
  129. package/packages/ext-git-graph/package.json +30 -0
  130. package/packages/ext-git-graph/src/extension-integration.test.ts +230 -0
  131. package/packages/ext-git-graph/src/extension-parsers.test.ts +193 -0
  132. package/packages/ext-git-graph/src/extension.ts +921 -0
  133. package/packages/ext-git-graph/src/git-log-parser.test.ts +271 -0
  134. package/packages/ext-git-graph/src/git-log-parser.ts +38 -0
  135. package/packages/ext-git-graph/src/types.ts +192 -0
  136. package/packages/ext-git-graph/src/webview-html.test.ts +142 -0
  137. package/packages/ext-git-graph/src/webview-html.ts +2417 -0
  138. package/packages/vscode-compat/src/index.ts +4 -0
  139. package/packages/vscode-compat/src/process.ts +25 -0
  140. package/packages/vscode-compat/src/window.ts +10 -0
  141. package/src/cli/commands/ext-cmd.ts +3 -1
  142. package/src/server/ws/extensions.ts +34 -4
  143. package/src/services/contribution-registry.ts +14 -1
  144. package/src/services/extension-host-worker.ts +12 -3
  145. package/src/services/extension-manifest.ts +18 -1
  146. package/src/services/extension-rpc-handlers.ts +68 -2
  147. package/src/services/extension.service.ts +63 -9
  148. package/src/types/extension-messages.ts +3 -1
  149. package/src/types/extension.ts +8 -0
  150. package/src/web/components/editor/code-editor.tsx +16 -4
  151. package/src/web/components/editor/conflict-editor.tsx +368 -0
  152. package/src/web/components/extensions/extension-webview.tsx +153 -12
  153. package/src/web/components/layout/command-palette.tsx +41 -17
  154. package/src/web/components/layout/editor-panel.tsx +16 -4
  155. package/src/web/components/layout/mobile-nav.tsx +6 -5
  156. package/src/web/components/layout/tab-bar.tsx +3 -3
  157. package/src/web/components/layout/tab-content.tsx +17 -5
  158. package/src/web/components/settings/keyboard-shortcuts-section.tsx +46 -1
  159. package/src/web/hooks/use-extension-ws.ts +30 -4
  160. package/src/web/hooks/use-global-keybindings.ts +24 -2
  161. package/src/web/hooks/use-url-sync.ts +8 -3
  162. package/src/web/stores/extension-store.ts +8 -0
  163. package/src/web/stores/keybindings-store.ts +2 -3
  164. package/src/web/stores/panel-store.ts +2 -2
  165. package/src/web/stores/panel-utils.ts +6 -2
  166. package/src/web/stores/tab-store.ts +3 -2
  167. package/dist/web/assets/ai-settings-section-D6d-RmR6.js +0 -1
  168. package/dist/web/assets/architecture-PBZL5I3N-DpVzOETR.js +0 -1
  169. package/dist/web/assets/arrow-up-BigIMx-e.js +0 -1
  170. package/dist/web/assets/channel-Cgy1thYT.js +0 -1
  171. package/dist/web/assets/chat-tab-DXBb9Y3U.js +0 -10
  172. package/dist/web/assets/check-ePA3ZvK4.js +0 -1
  173. package/dist/web/assets/chevron-down-EQA06nR-.js +0 -1
  174. package/dist/web/assets/chevron-right-CXzzT44u.js +0 -1
  175. package/dist/web/assets/chunk-GLR3WWYH-CxUl1sdz.js +0 -2
  176. package/dist/web/assets/chunk-HHEYEP7N-DN7ebS2Y.js +0 -1
  177. package/dist/web/assets/chunk-QZHKN3VN-C4La7oLj.js +0 -1
  178. package/dist/web/assets/classDiagram-VBA2DB6C-C3IyfqG-.js +0 -1
  179. package/dist/web/assets/classDiagram-v2-RAHNMMFH-Dcvhz2pb.js +0 -1
  180. package/dist/web/assets/clone--C7Tby8z.js +0 -1
  181. package/dist/web/assets/code-editor-Cr7JrBKC.js +0 -8
  182. package/dist/web/assets/columns-2-BZ9uqssV.js +0 -1
  183. package/dist/web/assets/createLucideIcon-PuMiQgHl.js +0 -1
  184. package/dist/web/assets/database-D1ToEV9d.js +0 -1
  185. package/dist/web/assets/diff-viewer-BBr6e_gb.js +0 -4
  186. package/dist/web/assets/dist-KUoHa6tg.js +0 -1
  187. package/dist/web/assets/extension-webview-B0klBip8.js +0 -3
  188. package/dist/web/assets/eye-CNcBU6Tx.js +0 -1
  189. package/dist/web/assets/git-graph-CDiwGa0g.js +0 -1
  190. package/dist/web/assets/gitGraph-HDMCJU4V-DcPyMEIJ.js +0 -1
  191. package/dist/web/assets/index-CkaCzNgO.css +0 -2
  192. package/dist/web/assets/index-Ic5uTu20.js +0 -26
  193. package/dist/web/assets/info-3K5VOQVL-Dw4O15cw.js +0 -1
  194. package/dist/web/assets/infoDiagram-LFFYTUFH-DFhmsucr.js +0 -2
  195. package/dist/web/assets/input-CcbTF6ih.js +0 -45
  196. package/dist/web/assets/jsx-runtime-R_NjdZtX.js +0 -1
  197. package/dist/web/assets/keybindings-store-CxE6BlG2.js +0 -1
  198. package/dist/web/assets/packet-RMMSAZCW-o3LmdL8H.js +0 -1
  199. package/dist/web/assets/pie-UPGHQEXC-BjNP0M3B.js +0 -1
  200. package/dist/web/assets/plus-Iso5r9vD.js +0 -1
  201. package/dist/web/assets/port-forwarding-tab-BPuSc6pI.js +0 -1
  202. package/dist/web/assets/radar-KQ55EAFF-gDgOiaME.js +0 -1
  203. package/dist/web/assets/refresh-cw-BgQzFNaG.js +0 -1
  204. package/dist/web/assets/scroll-area-i4EZlOl_.js +0 -1
  205. package/dist/web/assets/settings-tab-BzSSN2BQ.js +0 -1
  206. package/dist/web/assets/sqlite-viewer-CoyZOM_Y.js +0 -1
  207. package/dist/web/assets/square-pfn_LYYy.js +0 -1
  208. package/dist/web/assets/stateDiagram-v2-FVOUBMTO-DksQJ7es.js +0 -1
  209. package/dist/web/assets/table-CHv2x_qg.js +0 -1
  210. package/dist/web/assets/tag-Bb_UFXt0.js +0 -1
  211. package/dist/web/assets/text-wrap-D8BbQYTx.js +0 -1
  212. package/dist/web/assets/trash-2-DYCa06CV.js +0 -1
  213. package/dist/web/assets/treemap-KZPCXAKY-DwFqAvnj.js +0 -1
  214. package/dist/web/assets/x-BXecj-16.js +0 -1
  215. package/src/web/components/git/git-graph-branch-label.tsx +0 -124
  216. package/src/web/components/git/git-graph-constants.ts +0 -185
  217. package/src/web/components/git/git-graph-detail.tsx +0 -107
  218. package/src/web/components/git/git-graph-dialog.tsx +0 -72
  219. package/src/web/components/git/git-graph-row.tsx +0 -167
  220. package/src/web/components/git/git-graph-settings-dialog.tsx +0 -104
  221. package/src/web/components/git/git-graph-svg.tsx +0 -54
  222. package/src/web/components/git/git-graph-toolbar.tsx +0 -195
  223. package/src/web/components/git/git-graph.tsx +0 -193
  224. package/src/web/components/git/use-column-resize.ts +0 -33
  225. package/src/web/components/git/use-git-graph.ts +0 -201
  226. /package/dist/web/assets/{api-client-wQbeUyeh.js → api-client-BvxmRZUi.js} +0 -0
  227. /package/dist/web/assets/{array-X0JlPOfd.js → array-BFDiaBgf.js} +0 -0
  228. /package/dist/web/assets/{csv-parser-CElqio6o.js → csv-parser-i7fjqP2H.js} +0 -0
  229. /package/dist/web/assets/{cytoscape.esm-BfIOPvwt.js → cytoscape.esm-C8i2jUzT.js} +0 -0
  230. /package/dist/web/assets/{defaultLocale-B6RGN4id.js → defaultLocale-ZeknFqNe.js} +0 -0
  231. /package/dist/web/assets/{dist-CK1enexV.js → dist-DZmJeHOA.js} +0 -0
  232. /package/dist/web/assets/{init-BmUWJJHz.js → init-0VJVrkRJ.js} +0 -0
  233. /package/dist/web/assets/{isArrayLikeObject-BrCM-iA1.js → isArrayLikeObject-ClzWCpcm.js} +0 -0
  234. /package/dist/web/assets/{katex-xQS_6bNb.js → katex-DR0kdMDv.js} +0 -0
  235. /package/dist/web/assets/{lib-CfWBrYll.js → lib-DSLzfeW0.js} +0 -0
  236. /package/dist/web/assets/{math-CpLFzrfV.js → math-CRc16Nj6.js} +0 -0
  237. /package/dist/web/assets/{path-CoPyR7c2.js → path-INs8XTPH.js} +0 -0
  238. /package/dist/web/assets/{preload-helper-CH6UZRzu.js → preload-helper-mr3rCizq.js} +0 -0
  239. /package/dist/web/assets/{react-j5zqhEum.js → react-0tkk-ztn.js} +0 -0
  240. /package/dist/web/assets/{rough.esm-D5NinLFK.js → rough.esm-eLccZ4OJ.js} +0 -0
  241. /package/dist/web/assets/{sql-completion-provider-D0xutVaK.js → sql-completion-provider-B8uUWWej.js} +0 -0
  242. /package/dist/web/assets/{src-j04igtQ5.js → src-CqyWLlNZ.js} +0 -0
  243. /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, GitBranch, Pin, PinOff } from "lucide-react";
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 { TabType } from "@/stores/tab-store";
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: "git-graph", label: "Git Graph", icon: GitBranch },
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, GitBranch, Database,
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-graph": GitBranch, "git-diff": FileDiff, settings: Settings, ports: Globe,
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-graph" || type === "git-diff" || type === "terminal" || type === "chat";
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 to display the webview panel
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-webview",
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-graph", "git-diff", "settings", "ports",
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>(["git-graph", "settings"]);
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 "git-graph":
107
- return "git-graph";
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-webview";
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};