@bendyline/gezel-service 1.0.7 → 1.1.0

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 (237) hide show
  1. package/dist/bin/gezeld.js +6253 -3616
  2. package/dist/handboek-content/whats-new/1.26224.md +1 -0
  3. package/dist/handboek-content/whats-new/1.26226.md +1 -0
  4. package/dist/handboek-content/whats-new/1.26231.md +1 -0
  5. package/dist/handboek-content/whats-new/1.26234.md +1 -0
  6. package/dist/handboek-content/whats-new/1.26237.md +1 -0
  7. package/dist/handboek-content/whats-new/1.26244.md +2 -1
  8. package/dist/handboek-content/whats-new/1.26247.md +88 -0
  9. package/dist/handboek-content/whats-new/whats-new-index.md +1 -0
  10. package/dist/index-store/static-index-worker.js +17 -1
  11. package/dist/index.d.ts +473 -209
  12. package/dist/index.js +6251 -3614
  13. package/dist/memory/embed-worker.js +58 -2
  14. package/dist/memory/image-embed-worker.js +8 -0
  15. package/dist/providers/llama-cpp/gguf-metadata-worker.js +2 -0
  16. package/dist/providers/mlx/python/gezel_mlx_server.py +18 -18
  17. package/dist/ui/assets/AmbientDashboardCard-Cf5fi_fY.js +1 -0
  18. package/dist/ui/assets/{AudioEngineSettings-BDrNIGGm.js → AudioEngineSettings-D3L7HOHe.js} +1 -1
  19. package/dist/ui/assets/{BenchmarksView-CHyujjs8.js → BenchmarksView-B68hrLCl.js} +1 -1
  20. package/dist/ui/assets/CatalogBrowser-DEM9t7Es.js +1 -0
  21. package/dist/ui/assets/{ChannelsSettings-Be_W1mr8.js → ChannelsSettings-DtK_k0Ul.js} +1 -1
  22. package/dist/ui/assets/ChatTimelineView-CQ4Sf4Ip.js +7 -0
  23. package/dist/ui/assets/ConfirmDialog-Dt1ed4Fh.js +1 -0
  24. package/dist/ui/assets/ConnectedAppsPanel-Cl8LEkrt.js +1 -0
  25. package/dist/ui/assets/CraftbookEditor-DEQRlQ2p.js +1 -0
  26. package/dist/ui/assets/{CraftbookScriptEditorView-DXIZYZT3.js → CraftbookScriptEditorView-DhXkkIdK.js} +1 -1
  27. package/dist/ui/assets/{CraftbookTabContent-Bm7t_b37.js → CraftbookTabContent-_oIdpQTG.js} +1 -1
  28. package/dist/ui/assets/{CraftbookToolsetSetup-DTEA-3K3.js → CraftbookToolsetSetup-BKg136L1.js} +1 -1
  29. package/dist/ui/assets/{CraftbooksView-C4X99TTe.js → CraftbooksView-Dm2zH-nW.js} +2 -2
  30. package/dist/ui/assets/{DiffpackReviewView-ClcNxtmF.js → DiffpackReviewView-EFLGJnwr.js} +1 -1
  31. package/dist/ui/assets/DocumentDetail-ClDRj2N-.js +1 -0
  32. package/dist/ui/assets/DocumentsView-ny9oieg2.js +1 -0
  33. package/dist/ui/assets/DropdownMenu-S4d9-3j3.js +1 -0
  34. package/dist/ui/assets/Ds4Settings-CeWlm5Vf.js +1 -0
  35. package/dist/ui/assets/EmbeddedChat-Hjrrgpao.js +1 -0
  36. package/dist/ui/assets/{FaceRecognitionCard-D3hdc7uU.js → FaceRecognitionCard-D7ufKqjI.js} +1 -1
  37. package/dist/ui/assets/FileMapView-DRjf59RH.js +1 -0
  38. package/dist/ui/assets/{FoldersSettings-BcNzl4vT.js → FoldersSettings-DDUhaFio.js} +1 -1
  39. package/dist/ui/assets/GezelDetail-Cph6pVGb.js +1 -0
  40. package/dist/ui/assets/{GezelJsonEditor-fOvYclu9.js → GezelJsonEditor-7vDGyBib.js} +1 -1
  41. package/dist/ui/assets/{GezellenView-BTzhHrxi.js → GezellenView-DQhcO1CP.js} +1 -1
  42. package/dist/ui/assets/{GildeUpdatesCard-Bq6XEpLP.js → GildeUpdatesCard-UKKNm_U8.js} +1 -1
  43. package/dist/ui/assets/{GithubSignInChip-CnlTCG8G.js → GithubSignInChip-DjM3qZsL.js} +1 -1
  44. package/dist/ui/assets/{HandboekMediaProvider-BfQW8_Nr.js → HandboekMediaProvider-DixaXTAH.js} +1 -1
  45. package/dist/ui/assets/HandboekView-BeNQqho9.js +1 -0
  46. package/dist/ui/assets/HistoryView-E2szGNGS.js +1 -0
  47. package/dist/ui/assets/{HomeView-CB_5TJIp.css → HomeView-CNeqCFPc.css} +1 -1
  48. package/dist/ui/assets/HomeView-CkiS3DXy.js +1 -0
  49. package/dist/ui/assets/{ImageEngineSettings-BpMfQy4f.js → ImageEngineSettings-BCKT7Gvi.js} +1 -1
  50. package/dist/ui/assets/{ImageRecognitionSettings-Ct-7-Oas.js → ImageRecognitionSettings-DD6syFez.js} +1 -1
  51. package/dist/ui/assets/IncompleteDownloads-BiPaaahS.js +1 -0
  52. package/dist/ui/assets/InstallProgressRow-DyKOI4MU.js +1 -0
  53. package/dist/ui/assets/KnowledgeCatalogsCard-B132vzRa.js +1 -0
  54. package/dist/ui/assets/KnowledgeView-CtPuIlN4.js +1 -0
  55. package/dist/ui/assets/LlamaCppSettings-D6zHcu4W.js +1 -0
  56. package/dist/ui/assets/{MarkdownField-D-0Zw7gM.js → MarkdownField-CK8K3fzj.js} +1 -1
  57. package/dist/ui/assets/MemoriesTree-DzjXzIrM.js +1 -0
  58. package/dist/ui/assets/{MicrophoneSettings-BIaFxyY_.js → MicrophoneSettings-1FH83SCq.js} +1 -1
  59. package/dist/ui/assets/MlxSettings-BYxUqFnJ.js +1 -0
  60. package/dist/ui/assets/ModelPicker-DoXPfQkQ.js +1 -0
  61. package/dist/ui/assets/{NewScriptDialog-D-gkY8TS.js → NewScriptDialog-C5X-7PMt.js} +1 -1
  62. package/dist/ui/assets/NewTaskDialog-Cyqtmigv.js +2 -0
  63. package/dist/ui/assets/{OllamaSettings-oIE2Mech.js → OllamaSettings-DkjmA-sB.js} +1 -1
  64. package/dist/ui/assets/ProjectChat-YEqUME6k.js +5 -0
  65. package/dist/ui/assets/{ProjectConnectionsTab-BZqp-oKI.js → ProjectConnectionsTab-dFCJpW93.js} +1 -1
  66. package/dist/ui/assets/ProjectGitStatusBar-CjZxG54t.js +1 -0
  67. package/dist/ui/assets/{ProjectGithubView-w8suLCsA.js → ProjectGithubView-CQ4-tmPx.js} +1 -1
  68. package/dist/ui/assets/{ProjectMailTab-DGo7eyB8.js → ProjectMailTab-NaScsZJf.js} +1 -1
  69. package/dist/ui/assets/ProjectOverviewView-ChjxbQas.js +1 -0
  70. package/dist/ui/assets/{ProjectTimeline-DRe3D9qY.js → ProjectTimeline-BZpdCisR.js} +1 -1
  71. package/dist/ui/assets/ProjectsView-J77ECk6V.js +7 -0
  72. package/dist/ui/assets/{RecommendedBadge-BKiDixnB.js → RecommendedBadge-D0m68PAu.js} +1 -1
  73. package/dist/ui/assets/{RemoteServersPanel-DGyl6-Rg.js → RemoteServersPanel-BdLOoORu.js} +1 -1
  74. package/dist/ui/assets/ScriptEditorTabs-BFvIiDFZ.js +2 -0
  75. package/dist/ui/assets/ScriptEditorView-B09rm1vz.js +5 -0
  76. package/dist/ui/assets/{ScriptsView-WQc28TmQ.js → ScriptsView-BvNAJXpo.js} +1 -1
  77. package/dist/ui/assets/{SecurityComplianceSettings-DsMEA4J3.js → SecurityComplianceSettings-DzGOnptO.js} +1 -1
  78. package/dist/ui/assets/SessionSwitcher-6okzcxT7.js +1 -0
  79. package/dist/ui/assets/SettingsView-Dur4dLhW.js +3 -0
  80. package/dist/ui/assets/SquisqIntegration-6v3yNOIP.js +2 -0
  81. package/dist/ui/assets/{StorageCleanupDialog-DHqwyMZZ.js → StorageCleanupDialog-OQlomMJD.js} +1 -1
  82. package/dist/ui/assets/{StorageUsageCard-CdT6SU51.js → StorageUsageCard-f6c6qTbM.js} +1 -1
  83. package/dist/ui/assets/Tabs-jE0Z5Tzd.js +1 -0
  84. package/dist/ui/assets/TaskTabContent-0w3kAUWR.js +1 -0
  85. package/dist/ui/assets/TasksView-BVMT4BAY.js +1 -0
  86. package/dist/ui/assets/{TerminalCodeEditor-77pBm6f3.js → TerminalCodeEditor-DO7zLKy-.js} +2 -2
  87. package/dist/ui/assets/ToolsetsEditor-Bb1wD5mV.js +8 -0
  88. package/dist/ui/assets/TransformToolbarButton-BWYkEB0d.js +5 -0
  89. package/dist/ui/assets/UnrecognizedModels-HtdMZUqK.js +1 -0
  90. package/dist/ui/assets/{VideoEngineSettings-DzMeINuv.js → VideoEngineSettings-Dq8Nw_tK.js} +1 -1
  91. package/dist/ui/assets/{WorkspaceIndexPane-DU4yd4Ai.js → WorkspaceIndexPane-fpDz4MwZ.js} +1 -1
  92. package/dist/ui/assets/{api-BX5xXiFs.js → api-BPraLwsh.js} +1 -1
  93. package/dist/ui/assets/chat-thread-memory-Be48zsyG.js +1 -0
  94. package/dist/ui/assets/chunk-6ECMNUIP-DDVjPyfK.js +15 -0
  95. package/dist/ui/assets/{chunk-6N2J7C2B-B5QIrD9m.js → chunk-6N2J7C2B-CsppiLVr.js} +1 -1
  96. package/dist/ui/assets/{chunk-A6N6IN3I-DXok09eC.js → chunk-A6N6IN3I-ofeM4l8g.js} +1 -1
  97. package/dist/ui/assets/chunk-B7GEAZBI-Divd2h1k.js +1 -0
  98. package/dist/ui/assets/chunk-DXYWKZ52-BXcAlClu.js +1 -0
  99. package/dist/ui/assets/chunk-FLR2ARKC-D7wrvQgT.js +2 -0
  100. package/dist/ui/assets/chunk-IIQYS2YH-DKZhWMpn.js +1 -0
  101. package/dist/ui/assets/{chunk-ILCJ3WFD-WRukZ7R1.js → chunk-ILCJ3WFD-CLZxw4Ge.js} +3 -3
  102. package/dist/ui/assets/chunk-OBADJV7C-CDVOcmYt.js +1 -0
  103. package/dist/ui/assets/chunk-Q77KNJIN-BIDRf0aP.js +6 -0
  104. package/dist/ui/assets/chunk-S5PCVMKU-Df5XzhSE.js +6 -0
  105. package/dist/ui/assets/chunk-UBFT2CDQ-FexGDigd.js +31 -0
  106. package/dist/ui/assets/{chunk-USU6HTKB-D5FmDzJU.js → chunk-USU6HTKB-B_p-YcDp.js} +1 -1
  107. package/dist/ui/assets/chunk-VKXOZTYP-BoVvWSBR.js +5 -0
  108. package/dist/ui/assets/{chunk-6RQOV3B3-CwvKotJw.js → chunk-VPWPEMZJ-DRKoa_j0.js} +1 -1
  109. package/dist/ui/assets/{chunk-WATAOG4Y-DXg2lov5.js → chunk-WATAOG4Y-C1EXVPmG.js} +1 -1
  110. package/dist/ui/assets/{container-B7jJtK5V.js → container-Ce94efbg.js} +1 -1
  111. package/dist/ui/assets/csv-62UGQMzZ.js +1 -0
  112. package/dist/ui/assets/data-B2kHjlc5.js +1 -0
  113. package/dist/ui/assets/dist-B9-VrAP8.js +2 -0
  114. package/dist/ui/assets/dist-BaHut5iX.js +2 -0
  115. package/dist/ui/assets/dist-BqGwkOe5.js +225 -0
  116. package/dist/ui/assets/dist-ZnIgkoEi.js +4 -0
  117. package/dist/ui/assets/{dist-BHl1ZAVG.js → dist-l6uUFZMV.js} +2 -2
  118. package/dist/ui/assets/dist-pLLFUPO-.js +1 -0
  119. package/dist/ui/assets/{doc-s6H7T0IO.js → doc-Dr5K49bx.js} +28 -28
  120. package/dist/ui/assets/document-companion-BQk2kS0F.js +1 -0
  121. package/dist/ui/assets/document-import-QoM9UxJr.js +1 -0
  122. package/dist/ui/assets/docx-sXa1Rf41.js +2 -0
  123. package/dist/ui/assets/{epub-B98SgHBz.js → epub-RopMP0ec.js} +4 -4
  124. package/dist/ui/assets/{export-options-Bu-tI6og.js → export-options-f7PKjEBb.js} +1 -1
  125. package/dist/ui/assets/extract-UTAOG7LV-4WDRw1o4.js +1 -0
  126. package/dist/ui/assets/file-browser-c2tf4MIb.js +5 -0
  127. package/dist/ui/assets/html-BGVOMhkv.js +253 -0
  128. package/dist/ui/assets/icons-DWaUNQbT.js +1 -0
  129. package/dist/ui/assets/images-JLBFCDD4-6JitW0hD.js +1 -0
  130. package/dist/ui/assets/index-B8NcxqcR.css +1 -0
  131. package/dist/ui/assets/index-C0DYtvfg.js +34 -0
  132. package/dist/ui/assets/index-J8TOMdvV.js +2 -0
  133. package/dist/ui/assets/{infer-kCLH1C8z.js → infer-LEGOsu64.js} +2 -2
  134. package/dist/ui/assets/ironcalc-BAi5gOlE.js +3 -0
  135. package/dist/ui/assets/layouts-2A7QNF6Y-CVwP7noP.js +1 -0
  136. package/dist/ui/assets/{mail-link-CI6YD6k2.js → mail-link-DXkmCd5b.js} +1 -1
  137. package/dist/ui/assets/markdown-baseline-9B52XlX2.js +1 -0
  138. package/dist/ui/assets/{markdown-Bi9b5f5Y.js → markdown-ryKA_OmY.js} +1 -1
  139. package/dist/ui/assets/materialize-A34OZGEU-xNNKzytx.js +1 -0
  140. package/dist/ui/assets/model-inventory-ykSm_IT5.js +1 -0
  141. package/dist/ui/assets/{model-quantization-BDzrELN_.js → model-quantization-CLO7XLoF.js} +1 -1
  142. package/dist/ui/assets/{monaco-base-BiVSa1J-.js → monaco-base-B1H1U1Sw.js} +1 -1
  143. package/dist/ui/assets/{monaco-setup-UeltVkg_.js → monaco-setup-DjhrGQui.js} +1 -1
  144. package/dist/ui/assets/{new-project-meta-0xhggGA_.js → new-project-meta-_f9sfcRX.js} +1 -1
  145. package/dist/ui/assets/outside-in-D73N1g_b.js +3 -0
  146. package/dist/ui/assets/{pdf-DgTjy3rN.js → pdf-BOjVDlCK.js} +3 -3
  147. package/dist/ui/assets/{pending-drafts-YVW6X55O.js → pending-drafts-B11MKQ9R.js} +1 -1
  148. package/dist/ui/assets/{poppetje-Ce-02Aqi.js → poppetje-DLB8uevw.js} +2 -2
  149. package/dist/ui/assets/pptx-BuxyNxQh.js +6 -0
  150. package/dist/ui/assets/primitives-CWrGZpPI.js +41 -0
  151. package/dist/ui/assets/run-export-ChaMXrKS.js +23 -0
  152. package/dist/ui/assets/squisq-formats-aAdypXoy.js +1 -0
  153. package/dist/ui/assets/standalone-source-q_Zzd1bd.js +11 -0
  154. package/dist/ui/assets/storage-D8pE2zg0.js +1 -0
  155. package/dist/ui/assets/styles-BhnF3s2q.css +1 -0
  156. package/dist/ui/assets/styles-CKVKwqoQ.js +550 -0
  157. package/dist/ui/assets/table-fcouR4db.js +1 -0
  158. package/dist/ui/assets/{terminal-monaco-setup-DNoK2tN4.js → terminal-monaco-setup-BAzrVzeR.js} +1 -1
  159. package/dist/ui/assets/{useCompactLayout-BarJPYcv.js → useCompactLayout-Dtolvzye.js} +0 -0
  160. package/dist/ui/assets/{useCopilotAvailability-BH1nLXQI.js → useCopilotAvailability-3xZvKgTF.js} +1 -1
  161. package/dist/ui/assets/{useDiffpacks-CK8W_OD_.js → useDiffpacks-Dsnr0wtX.js} +1 -1
  162. package/dist/ui/assets/{useGitSync-DWxX5-7K.js → useGitSync-BCTptQsp.js} +1 -1
  163. package/dist/ui/assets/{useShowWorkInProgressFeatures-DwwviLRO.js → useShowWorkInProgressFeatures-BhDNuQiU.js} +1 -1
  164. package/dist/ui/assets/{useTotalRamBytes-WoN_mi-V.js → useTotalRamBytes-DIx-_pf8.js} +1 -1
  165. package/dist/ui/assets/wasm-DdxEDD2H.js +1 -0
  166. package/dist/ui/assets/wasm_bg-DW9Xt_vt.wasm +0 -0
  167. package/dist/ui/assets/xlsx-DyBGuAO1.js +4 -0
  168. package/dist/ui/index.html +19 -18
  169. package/package.json +11 -11
  170. package/dist/ui/assets/AmbientDashboardCard-C1Ee-FKZ.js +0 -1
  171. package/dist/ui/assets/CatalogBrowser-Bz8ZtxPn.js +0 -1
  172. package/dist/ui/assets/ChatTimelineView-Do9EryEH.js +0 -7
  173. package/dist/ui/assets/ConfirmDialog-BHFs6vmJ.js +0 -1
  174. package/dist/ui/assets/ConnectedAppsPanel-BtMayq0R.js +0 -1
  175. package/dist/ui/assets/CraftbookEditor-D5jTzWwF.js +0 -1
  176. package/dist/ui/assets/DocumentDetail-CPU51d04.js +0 -1
  177. package/dist/ui/assets/DocumentsView-B6OyjvJ0.js +0 -1
  178. package/dist/ui/assets/DropdownMenu-D5fCzIrh.js +0 -1
  179. package/dist/ui/assets/Ds4Settings-CrUM_KGP.js +0 -1
  180. package/dist/ui/assets/EmbeddedChat-ue9ia-WY.js +0 -1
  181. package/dist/ui/assets/FileMapView-CxvfDLGA.js +0 -1
  182. package/dist/ui/assets/GezelDetail-DHuqBK55.js +0 -1
  183. package/dist/ui/assets/HandboekView-CPnnyj29.js +0 -1
  184. package/dist/ui/assets/HistoryView-B4VAfEMe.js +0 -1
  185. package/dist/ui/assets/HomeView-ccH60J6f.js +0 -1
  186. package/dist/ui/assets/KnowledgeCatalogsCard-Bi5Rx9Iz.js +0 -1
  187. package/dist/ui/assets/KnowledgeView-DAwjwLZo.js +0 -1
  188. package/dist/ui/assets/LlamaCppSettings-Ceyk9pDP.js +0 -1
  189. package/dist/ui/assets/MemoriesTree-BKZEPJpm.js +0 -1
  190. package/dist/ui/assets/MlxSettings-CG3wfuc3.js +0 -1
  191. package/dist/ui/assets/ModelPicker-CCBVjLMS.js +0 -1
  192. package/dist/ui/assets/NewPathDialog-D4jnNBfP.js +0 -1
  193. package/dist/ui/assets/NewTaskDialog-Ox9D612Z.js +0 -2
  194. package/dist/ui/assets/ProjectChat-DMwKnkW-.js +0 -5
  195. package/dist/ui/assets/ProjectGitStatusBar-C6bkCSby.js +0 -1
  196. package/dist/ui/assets/ProjectOverviewView-NNwXd_QQ.js +0 -1
  197. package/dist/ui/assets/ProjectsView-SBPgYOq8.js +0 -7
  198. package/dist/ui/assets/ScriptEditorTabs-paocQ6dj.js +0 -2
  199. package/dist/ui/assets/ScriptEditorView-N9zSLqqi.js +0 -5
  200. package/dist/ui/assets/SessionSwitcher-C8te7YSe.js +0 -1
  201. package/dist/ui/assets/SettingsView-Brl4JQkW.js +0 -3
  202. package/dist/ui/assets/Tabs-BAY1Q79B.js +0 -1
  203. package/dist/ui/assets/TaskTabContent-CNPJ4DQj.js +0 -1
  204. package/dist/ui/assets/TasksView-DuMjFS8S.js +0 -1
  205. package/dist/ui/assets/ToolsetsEditor-BdxHnIBj.js +0 -8
  206. package/dist/ui/assets/TransformToolbarButton-CVg5nz36.js +0 -5
  207. package/dist/ui/assets/UnrecognizedModels-Cw9Ku_bW.js +0 -1
  208. package/dist/ui/assets/chat-thread-memory-CZGcwgGo.js +0 -1
  209. package/dist/ui/assets/chunk-6ECMNUIP-C1kohb1U.js +0 -15
  210. package/dist/ui/assets/chunk-AONELFLA-Cv2nS9ga.js +0 -1
  211. package/dist/ui/assets/chunk-IIQYS2YH-Dxg6MAfT.js +0 -1
  212. package/dist/ui/assets/chunk-MIKKUKOD-XIkmalSN.js +0 -31
  213. package/dist/ui/assets/chunk-NNJLSQPW-DJA6camf.js +0 -5
  214. package/dist/ui/assets/chunk-S5PCVMKU-DbCZ5AUH.js +0 -6
  215. package/dist/ui/assets/csv-xmd1_Aqd.js +0 -4
  216. package/dist/ui/assets/dist-BPx-FyRH.js +0 -222
  217. package/dist/ui/assets/dist-Bvo52IGx.js +0 -1
  218. package/dist/ui/assets/dist-D5aoNQwk.js +0 -2
  219. package/dist/ui/assets/docx-Cj4A9MhC.js +0 -2
  220. package/dist/ui/assets/extract-UTAOG7LV-C4b7ycaL.js +0 -1
  221. package/dist/ui/assets/file-browser-80qWoVju.js +0 -5
  222. package/dist/ui/assets/html-C9TlzI57.js +0 -253
  223. package/dist/ui/assets/icons-C9dD-bDi.js +0 -1
  224. package/dist/ui/assets/images-ESPQKVTW-D7SgdVJ_.js +0 -1
  225. package/dist/ui/assets/index-D1m4Wx8V.css +0 -1
  226. package/dist/ui/assets/index-DXWR4qW1.js +0 -34
  227. package/dist/ui/assets/layouts-2A7QNF6Y-De2t-YXl.js +0 -1
  228. package/dist/ui/assets/markdown-baseline-HMqF2ChK.js +0 -1
  229. package/dist/ui/assets/outside-in-BFVUUcLa.js +0 -3
  230. package/dist/ui/assets/pptx-6ChgUEf4.js +0 -6
  231. package/dist/ui/assets/primitives-DEsn1shf.js +0 -41
  232. package/dist/ui/assets/run-export-BrYhHj1O.js +0 -23
  233. package/dist/ui/assets/standalone-source-D6mbpa3h.js +0 -11
  234. package/dist/ui/assets/storage-fn4FCEVK.js +0 -1
  235. package/dist/ui/assets/styles-C0EoNJbk.css +0 -1
  236. package/dist/ui/assets/styles-CKr_yrbn.js +0 -541
  237. package/dist/ui/assets/xlsx-DH7sTb3W.js +0 -4
@@ -6,6 +6,13 @@ import { parentPort } from "worker_threads";
6
6
  // src/memory/embed-core.ts
7
7
  import { createHash } from "crypto";
8
8
  import { createLogger as createLogger2 } from "@bendyline/gezel";
9
+ import {
10
+ EmbedderUnavailableError,
11
+ KNOWLEDGE_EMBEDDING_PROFILES,
12
+ createProfileEmbedder,
13
+ resolveTransformersModelOptions,
14
+ verifyProfileArtifacts
15
+ } from "@bendyline/gezel-knowledge";
9
16
 
10
17
  // src/transformers-cache.ts
11
18
  import { mkdir } from "fs/promises";
@@ -69,6 +76,16 @@ var DEFAULT_EMBED_MODEL = "Xenova/bge-small-en-v1.5";
69
76
  function embedModelId() {
70
77
  return process.env.GEZEL_EMBED_MODEL || DEFAULT_EMBED_MODEL;
71
78
  }
79
+ function daemonEmbedderPin() {
80
+ const modelId = embedModelId();
81
+ return KNOWLEDGE_EMBEDDING_PROFILES.find((p) => p.model.repo === modelId) ?? null;
82
+ }
83
+ function daemonLoadOptions() {
84
+ const pin = daemonEmbedderPin();
85
+ if (!pin) return {};
86
+ const { dtype, subfolder, model_file_name } = resolveTransformersModelOptions(pin);
87
+ return { dtype, subfolder, model_file_name };
88
+ }
72
89
  var PipelineLoadError = class extends Error {
73
90
  code = "PIPELINE_LOAD_FAILED";
74
91
  /**
@@ -107,7 +124,7 @@ async function loadPipeline() {
107
124
  const { pipeline } = await import("@huggingface/transformers");
108
125
  const modelId = embedModelId();
109
126
  if (modelId !== DEFAULT_EMBED_MODEL) log2.info(`[embed] using model ${modelId}`);
110
- return await pipeline("feature-extraction", modelId);
127
+ return await pipeline("feature-extraction", modelId, daemonLoadOptions());
111
128
  } catch (err) {
112
129
  const missing = isMissingModule(err, TRANSFORMERS_MODULE);
113
130
  const message = missing ? "Local memory embeddings are an optional npm feature. Install @huggingface/transformers@^3.8.1 alongside @bendyline/gezel-service (see the service README)." : err instanceof Error ? err.message : String(err);
@@ -135,6 +152,45 @@ async function runEmbed(texts) {
135
152
  }
136
153
  return out;
137
154
  }
155
+ var PROFILE_IDLE_MS = 10 * 60 * 1e3;
156
+ var profileEmbedders = /* @__PURE__ */ new Map();
157
+ function armIdleDisposal(id, entry) {
158
+ if (entry.idleTimer) clearTimeout(entry.idleTimer);
159
+ entry.idleTimer = setTimeout(() => {
160
+ profileEmbedders.delete(id);
161
+ void entry.promise.then((embedder) => embedder.dispose()).catch(() => {
162
+ });
163
+ }, PROFILE_IDLE_MS);
164
+ entry.idleTimer.unref();
165
+ }
166
+ async function loadProfileEmbedder(profile) {
167
+ let entry = profileEmbedders.get(profile.id);
168
+ if (!entry) {
169
+ const cacheDir = process.env[HF_CACHE_DIR_ENV];
170
+ const promise = createProfileEmbedder(profile, cacheDir ? { cacheDir } : {}).catch((err) => {
171
+ profileEmbedders.delete(profile.id);
172
+ if (err instanceof PipelineLoadError) throw err;
173
+ const missing = err instanceof EmbedderUnavailableError || isMissingModule(err, TRANSFORMERS_MODULE);
174
+ throw new PipelineLoadError(
175
+ err instanceof Error ? err.message : String(err),
176
+ missing,
177
+ !missing && isRetryablePipelineLoadFailure(err)
178
+ );
179
+ });
180
+ entry = { promise };
181
+ profileEmbedders.set(profile.id, entry);
182
+ log2.info(`[embed] loading knowledge profile ${profile.id} (${profile.model.repo})`);
183
+ }
184
+ armIdleDisposal(profile.id, entry);
185
+ return entry.promise;
186
+ }
187
+ async function runProfileQueryEmbed(texts, profile) {
188
+ if (texts.length === 0) return [];
189
+ const embedder = await loadProfileEmbedder(profile);
190
+ const out = [];
191
+ for (const text of texts) out.push(Array.from(await embedder.embedQuery(capText(text))));
192
+ return out;
193
+ }
138
194
  function capText(s) {
139
195
  if (!s) return " ";
140
196
  return s.length > MAX_CHARS ? s.slice(0, MAX_CHARS) : s;
@@ -148,7 +204,7 @@ var port = parentPort;
148
204
  port.on("message", (msg) => {
149
205
  void (async () => {
150
206
  try {
151
- const vectors = await runEmbed(msg.texts);
207
+ const vectors = msg.profile ? await runProfileQueryEmbed(msg.texts, msg.profile) : await runEmbed(msg.texts);
152
208
  port.postMessage({ id: msg.id, vectors });
153
209
  } catch (err) {
154
210
  port.postMessage({
@@ -6,6 +6,13 @@ import { parentPort } from "worker_threads";
6
6
  // src/memory/embed-core.ts
7
7
  import { createHash } from "crypto";
8
8
  import { createLogger as createLogger2 } from "@bendyline/gezel";
9
+ import {
10
+ EmbedderUnavailableError,
11
+ KNOWLEDGE_EMBEDDING_PROFILES,
12
+ createProfileEmbedder,
13
+ resolveTransformersModelOptions,
14
+ verifyProfileArtifacts
15
+ } from "@bendyline/gezel-knowledge";
9
16
 
10
17
  // src/transformers-cache.ts
11
18
  import { mkdir } from "fs/promises";
@@ -91,6 +98,7 @@ function isRetryablePipelineLoadFailure(error) {
91
98
  `${code} ${message}`
92
99
  );
93
100
  }
101
+ var PROFILE_IDLE_MS = 10 * 60 * 1e3;
94
102
 
95
103
  // src/memory/face-embed-core.ts
96
104
  import { createRequire as createRequire2 } from "module";
@@ -365,6 +365,8 @@ function readGgufSummary(path, opts) {
365
365
  if (pattern) summary.slidingWindowPattern = pattern;
366
366
  } else if (key.endsWith(".attention.shared_kv_layers")) {
367
367
  summary.sharedKvLayers = readUintScalar(r, type);
368
+ } else if (key.endsWith(".num_loops")) {
369
+ summary.loopCount = readUintScalar(r, type);
368
370
  } else if (key.endsWith(".attention.key_length_swa")) {
369
371
  summary.keyLengthSwa = readUintScalar(r, type);
370
372
  } else if (key.endsWith(".attention.value_length_swa")) {
@@ -1807,26 +1807,24 @@ class BatchEngine:
1807
1807
  def _admit_count(self, pending: int) -> int:
1808
1808
  """How many of the `pending` co-arrived subs to start THIS wave.
1809
1809
 
1810
- Ground-truth backstop to the TS-side slot ceiling: even within a
1811
- memory-safe width, the coarse pre-spawn KV estimate can be wrong (KV
1812
- scales with a model's layer/head geometry, which the broker estimates
1813
- from weight bytes). So before co-batching concurrent prefills we check
1814
- LIVE allocation against the ceiling and collapse toward serial when
1815
- tight one large prefill on an already-full device is what aborts
1816
- Metal. Returns `pending` unchanged when no ceiling is configured or
1817
- memory is roomy, so the common case is byte-identical to before."""
1818
- if pending <= 1 or _MEM_LIMIT_BYTES <= 0:
1819
- return pending
1810
+ `self._max` is the hard concurrency contract advertised by the engine;
1811
+ pending work beyond it must remain queued for the next static wave.
1812
+ Within that width, live allocation is a second backstop to the TS-side
1813
+ slot estimate: when the device is already tight, collapse the wave to
1814
+ one request rather than risking a Metal abort."""
1815
+ capped = min(pending, self._max)
1816
+ if capped <= 1 or _MEM_LIMIT_BYTES <= 0:
1817
+ return capped
1820
1818
  threshold = _MEM_LIMIT_BYTES * _MEM_ADMIT_FRACTION
1821
1819
  active = _safe_active_memory()
1822
1820
  if active <= 0:
1823
- return pending # can't read usage → don't second-guess the width
1821
+ return capped # can't read usage → keep the configured hard cap
1824
1822
  if active >= threshold:
1825
1823
  # Already tight before this wave even starts — reclaim any freed
1826
1824
  # buffer cache and re-check once before forcing serial.
1827
1825
  _reclaim_mlx_buffer_cache("batch-admission", force=True)
1828
1826
  active = _safe_active_memory()
1829
- return 1 if active >= threshold else pending
1827
+ return 1 if active >= threshold else capped
1830
1828
 
1831
1829
  async def _run(self):
1832
1830
  while True:
@@ -1858,14 +1856,16 @@ class BatchEngine:
1858
1856
  batch = self._pending[:admit_n]
1859
1857
  self._pending = self._pending[admit_n:]
1860
1858
  if self._pending:
1861
- # Deferred under memory pressure the remaining subs run in
1862
- # the next wave, after this one drains and frees its KV. The
1863
- # outer loop re-enters admission once _subs empties (it never
1864
- # blocks on _wake while _pending is non-empty).
1859
+ # Deferred by the configured concurrency ceiling or live
1860
+ # memory pressure. The remaining subs run in the next wave,
1861
+ # after this one drains and frees its KV. The outer loop
1862
+ # re-enters admission once _subs empties (it never blocks on
1863
+ # _wake while _pending is non-empty).
1865
1864
  print(
1866
- f"[batch] memory-throttled: admitting {len(batch)}, "
1865
+ f"[batch] admission-throttled: admitting {len(batch)}, "
1867
1866
  f"deferring {len(self._pending)} to next wave "
1868
- f"(active={_safe_active_memory() // (1024 * 1024)}MB, "
1867
+ f"(max_concurrency={self._max}, "
1868
+ f"active={_safe_active_memory() // (1024 * 1024)}MB, "
1869
1869
  f"ceiling={_MEM_LIMIT_BYTES // (1024 * 1024)}MB)",
1870
1870
  flush=True,
1871
1871
  )
@@ -0,0 +1 @@
1
+ import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{n as t,t as n}from"./jsx-runtime-CEpd2cAX.js";import{t as r}from"./api-BPraLwsh.js";import{d as i,l as a,p as o,s}from"./primitives-CWrGZpPI.js";import{n as c,t as l}from"./relative-time-B2kBaekd.js";import{O as u,k as d,s as f}from"./chunk-GAZKTT4R-BkP6-w3z.js";import"./schemas-JY4jmLbC.js";var p=e(t(),1),m=n();function h({summary:e,compact:t=!1}){let n=d(e.id),r=u(n.typography.titleFont,f.sans);return(0,m.jsxs)(`span`,{className:`ambient-theme-preview${t?` ambient-theme-preview--compact`:``}`,"data-theme-id":e.id,children:[(0,m.jsx)(`span`,{className:`ambient-theme-name-chip`,style:{background:n.colors.background,borderColor:n.colors.backgroundLight,color:n.colors.text,fontFamily:r},children:e.name}),(0,m.jsxs)(`span`,{className:`ambient-theme-swatches`,"aria-hidden":`true`,children:[(0,m.jsx)(`span`,{className:`ambient-theme-swatch`,style:{background:n.colors.primary}}),(0,m.jsx)(`span`,{className:`ambient-theme-swatch`,style:{background:n.colors.secondary}}),(0,m.jsx)(`span`,{className:`ambient-theme-swatch`,style:{background:n.colors.highlight}})]}),!t&&e.description&&(0,m.jsx)(`span`,{className:`ambient-theme-description`,"aria-hidden":`true`,children:e.description})]})}function g({value:e,themes:t,disabled:n,labelledBy:r,onValueChange:c}){let l=t.find(t=>t.id===e);return(0,m.jsxs)(i,{value:e,onValueChange:e=>c(e),disabled:n,children:[(0,m.jsx)(o,{"aria-labelledby":r,className:`ambient-theme-select-trigger`,style:{width:`100%`,marginTop:`0.25rem`},children:l&&(0,m.jsx)(h,{summary:l,compact:!0})}),(0,m.jsx)(s,{className:`ambient-theme-select-menu`,align:`start`,children:t.map(e=>(0,m.jsx)(a,{value:e.id,textValue:e.name,children:(0,m.jsx)(h,{summary:e})},e.id))})]})}function _(e){return e===`darwin`?{title:`Point macOS at the folder yourself`,lines:[`System Settings → Wallpaper → Add Folder or Album… → choose the ambient folder, then pick a rotation interval.`,`The macOS lock screen follows the desktop wallpaper automatically.`]}:e===`win32`?{title:`Point Windows at the folder yourself`,lines:[`Settings → Personalization → Background → Slideshow → choose the ambient folder.`,`Lock screen: Settings → Personalization → Lock screen → Slideshow → add the ambient folder (turn off Windows Spotlight first).`]}:{title:`Point your desktop at the folder yourself`,lines:[`GNOME and KDE are handled by the automatic toggle above when available.`,`On other desktops, point your environment's wallpaper slideshow at the ambient folder (e.g. XFCE: Desktop settings → Background → Folder).`]}}function v(){let[e,t]=(0,p.useState)(!1),[n,i]=(0,p.useState)(null),[a,o]=(0,p.useState)(null),[s,u]=(0,p.useState)(!1),[d,f]=(0,p.useState)(!1),[h,v]=(0,p.useState)(null),[y,b]=(0,p.useState)(null),x=(0,p.useRef)(null),S=(0,p.useRef)(null),C=window.__GEZEL__?.ambient,w=window.__GEZEL__?.platform,T=(0,p.useCallback)(async()=>{try{let e=await r.getFetch()(r.ambientDashboardLatestUrl(),{headers:r.authHeader()});if(!e.ok)return;let t=await e.blob(),n=URL.createObjectURL(t);S.current&&URL.revokeObjectURL(S.current),S.current=n,v(n)}catch{}},[]),E=(0,p.useCallback)(async()=>{try{let e=await r.getAmbientDashboard();return i(e),t(e.enabled),e}catch{return null}},[]),D=(0,p.useCallback)(async()=>{if(C)try{let e=await C.status();e.ok&&(o(e),u(e.enabled))}catch{}},[C]),O=(0,p.useCallback)(()=>{if(x.current!==null)return;let e=480,t=async()=>{x.current=null;let n=await E();--e,n?.running&&e>0?x.current=window.setTimeout(()=>void t(),2e3):T()};x.current=window.setTimeout(()=>void t(),2e3)},[E,T]);(0,p.useEffect)(()=>(E(),T(),D(),()=>{x.current!==null&&window.clearTimeout(x.current),S.current&&URL.revokeObjectURL(S.current)}),[E,T,D]);let k=(0,p.useCallback)(async n=>{let i=e;t(n),b(null);try{await r.updateConfig({ambientDashboard:{enabled:n}}),E()}catch(e){t(i),b(e instanceof Error?e.message:String(e))}},[e,E]),A=(0,p.useCallback)(async()=>{b(null);try{await r.runAmbientDashboard(),i(e=>e&&{...e,running:!0}),O()}catch(e){b(e instanceof Error?e.message:String(e))}},[O]),j=(0,p.useCallback)(async e=>{if(!n?.themeId||!n.themes?.some(t=>t.id===e))return;let t=e,a=n.themeId;if(t!==a){f(!0),b(null),i(e=>e&&{...e,themeId:t});try{await r.updateConfig({ambientDashboard:{themeId:t}}),await E()}catch(e){i(e=>e&&{...e,themeId:a}),b(e instanceof Error?e.message:String(e))}finally{f(!1)}}},[E,n]),M=(0,p.useCallback)(async e=>{if(!C)return;let t=s;u(e),b(null);let n=e?await C.enable():await C.disable();if(!n.ok){u(t),b(n.error);return}!e&&`reason`in n&&n.reason===`nothing-captured`&&b(`No previous wallpaper was captured, so the current one was left in place.`),D()},[C,s,D]),N=a?.capability,P=C?N&&!N.supported?N.reason===`unknown-desktop`?`Automatic wallpaper is not supported on this desktop (${N.desktop??`unknown`}).`:N.reason===`command-missing`?`The desktop wallpaper tool was not found on this system.`:`Automatic wallpaper is not supported on this platform.`:e?null:`Turn on dashboard generation first.`:`Available in the Gezel desktop app.`,F=_(w),I=n?.themes?.find(e=>e.id===n.themeId),L=!!(n?.lastError&&n.lastFailedAt&&(!n.lastGeneratedAt||Date.parse(n.lastFailedAt)>=Date.parse(n.lastGeneratedAt))),R=y??(L?`Dashboard generation failed: ${n?.lastError}`:null);return(0,m.jsxs)(`section`,{style:{marginBottom:`2rem`},children:[(0,m.jsx)(`h3`,{children:`Ambient display`}),(0,m.jsx)(`p`,{className:`muted`,style:{marginTop:0},children:`When on, your meester composes a dashboard of what moved across your projects — roughly once an hour while the workshop changes — and renders it as an image made to be shown as a wallpaper or lock screen. Images land in the ambient folder; the newest one is always available as latest.png.`}),(0,m.jsxs)(`label`,{className:`debug-toggle`,children:[(0,m.jsx)(`input`,{type:`checkbox`,checked:e,onChange:e=>void k(e.target.checked)}),(0,m.jsx)(`span`,{children:`Generate an ambient dashboard`})]}),e&&(0,m.jsxs)(`div`,{className:`new-row`,style:{marginTop:`0.75rem`,alignItems:`flex-start`,flexDirection:`column`,gap:`0.5rem`},children:[n?.themeId&&n.themes&&(0,m.jsxs)(`div`,{style:{width:`min(320px, 100%)`,marginBottom:`0.25rem`},children:[(0,m.jsx)(`span`,{id:`ambient-dashboard-theme-label`,className:`small`,children:`Dashboard theme`}),(0,m.jsx)(g,{value:n.themeId,themes:n.themes,disabled:d||n.running,labelledBy:`ambient-dashboard-theme-label`,onValueChange:e=>void j(e)}),(0,m.jsx)(`p`,{className:`muted small`,style:{margin:`0.25rem 0 0`},children:d?`Saving theme…`:`${I?.description??`Squisq dashboard theme.`} Applies to the next generated image.`})]}),(0,m.jsx)(`span`,{className:`muted small`,title:n?.lastGeneratedAt?l(n.lastGeneratedAt):void 0,children:n?.running?`The meester is composing a dashboard…`:n?.lastGeneratedAt?`Last generated ${c(n.lastGeneratedAt)}`:`Nothing generated yet. The first image may wait for the browser runtime download to finish.`}),(0,m.jsx)(`button`,{type:`button`,onClick:()=>void A(),disabled:n?.running,children:`Generate now`}),h&&(0,m.jsx)(`img`,{src:h,alt:`Latest ambient dashboard`,style:{maxWidth:`min(420px, 100%)`,border:`1px solid var(--border, #8883)`,borderRadius:`4px`}})]}),(0,m.jsxs)(`div`,{style:{marginTop:`1rem`},children:[(0,m.jsxs)(`label`,{className:`debug-toggle`,children:[(0,m.jsx)(`input`,{type:`checkbox`,checked:s,disabled:P!==null,onChange:e=>void M(e.target.checked)}),(0,m.jsx)(`span`,{children:`Keep my desktop wallpaper set to the latest dashboard`})]}),(0,m.jsx)(`p`,{className:`muted small`,style:{marginTop:`0.25rem`},children:P??(N?.canRestore?`Turning this on changes your wallpaper right away; turning it off restores the previous one.`:`Turning this on changes your wallpaper right away. On this desktop the previous wallpaper cannot be restored automatically.`)})]}),C&&(0,m.jsxs)(`div`,{className:`new-row`,style:{marginTop:`0.5rem`,gap:`0.5rem`},children:[(0,m.jsx)(`button`,{type:`button`,onClick:()=>void C.openFolder(),children:`Open ambient folder`}),a?.folder&&(0,m.jsx)(`span`,{className:`muted small`,children:a.folder})]}),(0,m.jsxs)(`details`,{style:{marginTop:`0.75rem`},children:[(0,m.jsx)(`summary`,{className:`muted small`,children:F.title}),(0,m.jsx)(`ul`,{className:`muted small`,style:{marginTop:`0.5rem`},children:F.lines.map(e=>(0,m.jsx)(`li`,{children:e},e))})]}),R&&(0,m.jsx)(`p`,{className:`error small`,children:R})]})}export{v as AmbientDashboardCard};
@@ -1 +1 @@
1
- import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{n as t,t as n}from"./jsx-runtime-CEpd2cAX.js";import{t as r}from"./dist-D5aoNQwk.js";import{t as i}from"./api-BX5xXiFs.js";import{t as a}from"./ConfirmDialog-BHFs6vmJ.js";import{t as o}from"./RecommendedBadge-BKiDixnB.js";import{t as s}from"./LicenseButton-D3VmcVG1.js";var c=e(t(),1),l=n();function u(e){return e>=1024**3?`${(e/1024**3).toFixed(1)} GB`:e>=1024**2?`${(e/1024**2).toFixed(0)} MB`:e>=1024?`${(e/1024).toFixed(0)} KB`:`${e} B`}function d({kind:e,disabledReason:t,onModelsChanged:n,configuredDefaultModelId:r,onSetActiveModel:d}){let[p,m]=(0,c.useState)([]),[h,g]=(0,c.useState)([]),[_,v]=(0,c.useState)(null),[y,b]=(0,c.useState)(new Map),[x,S]=(0,c.useState)(null),C=(0,c.useRef)(y);C.current=y;let w=(0,c.useCallback)(async()=>{try{let[t,n]=await Promise.all([e===`stt`?i.listInstalledSttModels():i.listInstalledTtsModels(),i.listAudioCatalog()]);m(t.models),g(e===`stt`?n.stt:n.tts),v(null)}catch(e){m([]),v(e.message)}},[e]);(0,c.useEffect)(()=>{w()},[w]);let T=(0,c.useCallback)(async t=>{if(C.current.has(t))return;let r=new AbortController;b(e=>new Map(e).set(t,{id:t,bytesWritten:0,totalBytes:0,controller:r}));try{await i.pullAudioModel(e,t,e=>{e.type===`progress`?b(n=>{let r=new Map(n),i=r.get(t);return i?(r.set(t,{...i,bytesWritten:e.bytesWritten,totalBytes:e.totalBytes??i.totalBytes}),r):n}):e.type===`error`&&b(n=>{let r=new Map(n),i=r.get(t);return i&&r.set(t,{...i,error:e.error}),r})},r.signal),setTimeout(()=>{b(e=>{if(e.get(t)?.error)return e;let n=new Map(e);return n.delete(t),n}),w(),n?.()},800)}catch(e){if(r.signal.aborted){b(e=>{let n=new Map(e);return n.delete(t),n});return}b(n=>{let r=new Map(n),i=r.get(t);return i&&r.set(t,{...i,error:e.message}),r})}},[e,w,n]),E=(0,c.useCallback)(e=>{let t=C.current.get(e);if(t?.error){b(t=>{let n=new Map(t);return n.delete(e),n});return}t?.controller.abort()},[]),D=(0,c.useCallback)(async()=>{if(x)try{e===`stt`?await i.deleteSttModel(x):await i.deleteTtsModel(x),await w(),n?.()}catch(e){v(e.message)}finally{S(null)}},[e,x,w,n]),O=new Set(p.map(e=>e.id)),k=!!d&&p.length>1,A=r&&O.has(r)?r:p[0]?.id;return(0,l.jsxs)(`div`,{className:`ollama-model-manager`,children:[y.size>0&&(0,l.jsxs)(`div`,{className:`ollama-section`,children:[(0,l.jsx)(`h4`,{children:`Downloading…`}),(0,l.jsx)(`div`,{className:`ollama-pull-list`,children:Array.from(y.values()).map(e=>(0,l.jsx)(f,{pull:e,onCancel:()=>E(e.id)},e.id))})]}),(p.length>0||_)&&(0,l.jsxs)(`div`,{className:`ollama-section`,children:[(0,l.jsx)(`h4`,{children:`Local models`}),_&&(0,l.jsx)(`p`,{className:`error`,children:_}),k&&(0,l.jsxs)(`p`,{className:`muted small`,children:[`The `,(0,l.jsx)(`strong`,{children:`active`}),` model is the one transcription runs on. The engine binds one model at a time, so switching reloads it — the next transcription takes a moment longer.`]}),p.length>0&&(0,l.jsxs)(`table`,{className:`ollama-model-table`,children:[(0,l.jsx)(`thead`,{children:(0,l.jsxs)(`tr`,{children:[k&&(0,l.jsx)(`th`,{scope:`col`,className:`gz-active-model-column`,children:`Active`}),(0,l.jsx)(`th`,{children:`Name`}),(0,l.jsx)(`th`,{children:`Size`}),(0,l.jsx)(`th`,{children:`Added`}),(0,l.jsx)(`th`,{})]})}),(0,l.jsx)(`tbody`,{children:p.map(t=>(0,l.jsxs)(`tr`,{children:[k&&(0,l.jsx)(`td`,{className:`gz-active-model-column`,children:(0,l.jsx)(`input`,{type:`radio`,name:`active-${e}-model`,className:`gz-active-model-radio`,"aria-label":`Use ${t.id} as the active ${e===`stt`?`speech-to-text`:`text-to-speech`} model`,checked:A===t.id,onChange:()=>{A!==t.id&&d?.(t.id)}})}),(0,l.jsxs)(`td`,{children:[(0,l.jsx)(`code`,{children:t.id}),(0,l.jsx)(`div`,{className:`muted small`,children:t.name})]}),(0,l.jsx)(`td`,{children:u(t.approxSizeBytes)}),(0,l.jsx)(`td`,{className:`muted small`,children:new Date(t.installedAt).toLocaleDateString()}),(0,l.jsx)(`td`,{children:(0,l.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:()=>S(t.id),children:`Delete`})})]},t.id))})]})]}),(0,l.jsxs)(`div`,{className:`ollama-section ollama-section--flat ollama-section--download`,children:[(0,l.jsx)(`h4`,{children:`Download a model`}),h.length===0?(0,l.jsx)(`p`,{className:`muted small`,children:`No models in the catalog yet.`}):(0,l.jsx)(`div`,{className:`catalog-ollama-list`,children:h.map(e=>{let n=O.has(e.id),r=y.get(e.id),i=!!r,a=r&&r.totalBytes>0?Math.min(100,Math.round(r.bytesWritten/r.totalBytes*100)):null;return(0,l.jsxs)(`div`,{className:`catalog-ollama-action`,children:[(0,l.jsxs)(`div`,{className:`catalog-ollama-meta`,children:[(0,l.jsxs)(`div`,{className:`catalog-ollama-specs muted small`,children:[(0,l.jsx)(`code`,{children:e.id}),(0,l.jsx)(`span`,{children:`·`}),(0,l.jsx)(`span`,{children:u(e.approxSizeBytes)})]}),(0,l.jsxs)(`div`,{className:`muted small`,children:[(0,l.jsx)(`strong`,{children:e.name}),` — `,e.description]}),(0,l.jsxs)(`div`,{className:`catalog-ollama-pills`,children:[(0,l.jsx)(s,{manifest:e}),(0,l.jsx)(o,{manifest:e})]})]}),(0,l.jsx)(`button`,{type:`button`,disabled:n||i||!!t,title:t??void 0,onClick:()=>void T(e.id),children:n?`On device`:i?a===null?`Downloading…`:`Downloading… ${a}%`:`Download`})]},e.id)})})]}),(0,l.jsx)(a,{open:x!==null,title:`Delete ${e===`stt`?`STT`:`TTS`} model?`,message:x?`"${x}" will be removed from local storage. This frees disk space; download it again later to use it.`:``,confirmLabel:`Delete`,danger:!0,onCancel:()=>S(null),onConfirm:D})]})}function f({pull:e,onCancel:t}){let n=e.totalBytes>0,r=n?Math.min(100,Math.round(e.bytesWritten/e.totalBytes*100)):0,i=e.error?e.error:n?`Downloading… (${u(e.bytesWritten)} of ${u(e.totalBytes)}, ${r}%)`:e.bytesWritten>0?`Downloading… (${u(e.bytesWritten)})`:`Preparing download…`;return(0,l.jsxs)(`div`,{className:`ollama-pull${e.error?` ollama-pull-error`:``}`,children:[(0,l.jsxs)(`div`,{className:`ollama-pull-head`,children:[(0,l.jsx)(`code`,{children:e.id}),(0,l.jsx)(`span`,{className:`muted small`,children:i}),(0,l.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:t,children:e.error?`Dismiss`:`Cancel`})]}),n?(0,l.jsxs)(`div`,{className:`ollama-pull-bar`,children:[(0,l.jsx)(`div`,{className:`ollama-pull-bar-fill`,style:{width:`${r}%`}}),(0,l.jsxs)(`span`,{className:`ollama-pull-bar-label`,children:[r,`%`]})]}):(0,l.jsx)(`div`,{className:`ollama-pull-bar ollama-pull-bar-indeterminate`,children:(0,l.jsx)(`div`,{className:`ollama-pull-bar-fill`})})]})}function p(){let[e,t]=(0,c.useState)(null),[n,r]=(0,c.useState)(null),[a,o]=(0,c.useState)([]),[s,u]=(0,c.useState)(`af_heart`),[f,p]=(0,c.useState)(`The quick brown fox jumps over the lazy dog.`),[v,y]=(0,c.useState)({kind:`idle`}),[b,x]=(0,c.useState)(void 0),[S,C]=(0,c.useState)(!1),[w,T]=(0,c.useState)(!1),E=(0,c.useRef)(null),D=(0,c.useCallback)(async()=>{try{let[e,n,a]=await Promise.all([i.getAudioEngineStatus(),i.listAudioVoices(),i.getConfig()]);t(e),o(n.voices),C(a.narrateAssistantReplies??!1),x(a.defaultSttModel),r(null)}catch(e){t(null),r(e.message)}},[]);(0,c.useEffect)(()=>{D()},[D]);let O=(0,c.useCallback)(async e=>{T(!0),C(e);try{let t=await i.updateConfig({narrateAssistantReplies:e});window.dispatchEvent(new CustomEvent(`gezel:config-updated`,{detail:t}))}catch(t){C(!e),r(t.message)}finally{T(!1)}},[]),k=(0,c.useCallback)(async e=>{x(e);try{let t=await i.updateConfig({defaultSttModel:e});x(t.defaultSttModel)}catch(e){x(void 0),r(e.message)}},[]),A=(0,c.useCallback)(async()=>{if(f.trim()){y({kind:`synthesizing`});try{let e=await i.synthesizeSpeech({text:f,voice:s,inline:!0});e.b64Wav&&E.current&&(E.current.src=`data:audio/wav;base64,${e.b64Wav}`,await E.current.play().catch(()=>{})),y({kind:`idle`})}catch(e){y({kind:`error`,msg:m(e)})}}},[f,s]);return(0,l.jsxs)(`div`,{className:`provider-card`,children:[(0,l.jsx)(`div`,{className:`settings-card-header`,children:(0,l.jsx)(`h3`,{children:`Audio`})}),(0,l.jsxs)(`p`,{className:`muted small`,children:[`Speech-to-text via the bundled `,(0,l.jsx)(`code`,{children:`whisper.cpp`}),` engine and text-to-speech via the bundled `,(0,l.jsx)(`code`,{children:`Kokoro`}),` engine — both run locally.`]}),n&&(0,l.jsxs)(`p`,{className:`error`,children:[`Couldn't reach the Gezel service. `,n]}),(0,l.jsxs)(`section`,{style:{marginTop:`1rem`},children:[(0,l.jsxs)(`div`,{className:`settings-card-header`,children:[(0,l.jsx)(`h4`,{style:{margin:0},children:`Speech-to-text (whisper.cpp)`}),e&&(0,l.jsx)(g,{engine:e.stt})]}),(0,l.jsx)(_,{engine:e?.stt}),(0,l.jsx)(d,{kind:`stt`,...b?{configuredDefaultModelId:b}:{},onSetActiveModel:k,...h(e?.stt)?{disabledReason:e?.stt.status===`not-configured`?`whisper.cpp engine is not wired up — downloading a model now would still leave it unrunnable.`:`whisper.cpp engine is not reachable.`}:{},onModelsChanged:()=>void D()})]}),(0,l.jsxs)(`section`,{style:{marginTop:`1.5rem`},children:[(0,l.jsxs)(`div`,{className:`settings-card-header`,children:[(0,l.jsx)(`h4`,{style:{margin:0},children:`Text-to-speech (Kokoro)`}),e&&(0,l.jsx)(g,{engine:e.tts})]}),(0,l.jsx)(_,{engine:e?.tts}),(0,l.jsx)(d,{kind:`tts`,...h(e?.tts)?{disabledReason:`Kokoro engine is not configured.`}:{},onModelsChanged:()=>void D()}),e?.tts.status===`ok`&&(0,l.jsx)(`div`,{className:`ollama-section`,style:{marginTop:`1rem`},children:(0,l.jsxs)(`label`,{className:`provider-row`,children:[(0,l.jsx)(`input`,{type:`checkbox`,checked:S,disabled:w,onChange:e=>void O(e.target.checked)}),(0,l.jsxs)(`span`,{children:[`Narrate assistant replies`,(0,l.jsx)(`span`,{className:`muted small`,style:{marginLeft:`0.5rem`},children:`— speak each completed gezel reply aloud using that gezel's voice.`})]})]})}),e?.tts.status===`ok`&&(0,l.jsxs)(`div`,{className:`ollama-section`,style:{marginTop:`1rem`},children:[(0,l.jsx)(`h4`,{children:`Preview a voice`}),(0,l.jsxs)(`div`,{style:{display:`flex`,gap:`0.5rem`,alignItems:`center`,flexWrap:`wrap`},children:[(0,l.jsxs)(`label`,{className:`provider-row`,children:[(0,l.jsx)(`span`,{children:`Voice`}),(0,l.jsx)(`select`,{value:s,onChange:e=>u(e.target.value),children:a.map(e=>(0,l.jsxs)(`option`,{value:e.id,children:[e.name,` (`,e.language,`)`]},e.id))})]}),(0,l.jsx)(`input`,{type:`text`,value:f,onChange:e=>p(e.target.value),style:{minWidth:280,flex:1}}),(0,l.jsx)(`button`,{type:`button`,onClick:()=>void A(),disabled:v.kind===`synthesizing`||!f.trim(),children:v.kind===`synthesizing`?`Synthesizing…`:`Preview`})]}),v.kind===`error`&&(0,l.jsx)(`p`,{className:`error`,children:v.msg}),(0,l.jsx)(`audio`,{ref:E,controls:!0,style:{width:`100%`,marginTop:`0.5rem`}})]})]})]})}function m(e){if(e instanceof r){let t=e.details;if(t&&typeof t==`object`&&`error`in t){let n=t.error;if(typeof n==`string`&&n.length>0)return`${e.message}: ${n}`}if(typeof t==`string`&&t.length>0)return`${e.message}: ${t}`}return e instanceof Error?e.message:String(e)}function h(e){return!e||e.status===`not-configured`||e.status===`unreachable`}function g({engine:e}){return e.status===`ok`?(0,l.jsx)(`span`,{className:`gz-status-pill gz-status-pill--ok`,children:`Ready`}):e.status===`no-model`?(0,l.jsx)(`span`,{className:`gz-status-pill gz-status-pill--warn`,children:`No model`}):e.status===`unreachable`?(0,l.jsx)(`span`,{className:`gz-status-pill gz-status-pill--error`,children:`Unreachable`}):(0,l.jsx)(`span`,{className:`gz-status-pill gz-status-pill--warn`,children:`Not configured`})}function _({engine:e}){return e?e.status===`not-configured`?(0,l.jsxs)(`p`,{className:`muted small`,children:[`Engine isn't wired up on this install yet.`,e.error?(0,l.jsxs)(l.Fragment,{children:[` `,e.error]}):null]}):e.status===`unreachable`?(0,l.jsxs)(`p`,{className:`error`,children:[`Engine isn't responding`,e.baseUrl?(0,l.jsxs)(l.Fragment,{children:[` `,`at `,(0,l.jsx)(`code`,{children:e.baseUrl})]}):null,`.`,e.error?(0,l.jsxs)(l.Fragment,{children:[` `,e.error]}):null]}):e.status===`no-model`?(0,l.jsx)(`p`,{className:`muted small`,children:`Engine is ready — download a model below to start using it.`}):null:null}export{p as AudioEngineSettings};
1
+ import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{n as t,t as n}from"./jsx-runtime-CEpd2cAX.js";import{t as r}from"./dist-BaHut5iX.js";import{t as i}from"./api-BPraLwsh.js";import{t as a}from"./ConfirmDialog-Dt1ed4Fh.js";import{t as o}from"./RecommendedBadge-D0m68PAu.js";import{t as s}from"./LicenseButton-D3VmcVG1.js";var c=e(t(),1),l=n();function u(e){return e>=1024**3?`${(e/1024**3).toFixed(1)} GB`:e>=1024**2?`${(e/1024**2).toFixed(0)} MB`:e>=1024?`${(e/1024).toFixed(0)} KB`:`${e} B`}function d({kind:e,disabledReason:t,onModelsChanged:n,configuredDefaultModelId:r,onSetActiveModel:d}){let[p,m]=(0,c.useState)([]),[h,g]=(0,c.useState)([]),[_,v]=(0,c.useState)(null),[y,b]=(0,c.useState)(new Map),[x,S]=(0,c.useState)(null),C=(0,c.useRef)(y);C.current=y;let w=(0,c.useCallback)(async()=>{try{let[t,n]=await Promise.all([e===`stt`?i.listInstalledSttModels():i.listInstalledTtsModels(),i.listAudioCatalog()]);m(t.models),g(e===`stt`?n.stt:n.tts),v(null)}catch(e){m([]),v(e.message)}},[e]);(0,c.useEffect)(()=>{w()},[w]);let T=(0,c.useCallback)(async t=>{if(C.current.has(t))return;let r=new AbortController;b(e=>new Map(e).set(t,{id:t,bytesWritten:0,totalBytes:0,controller:r}));try{await i.pullAudioModel(e,t,e=>{e.type===`progress`?b(n=>{let r=new Map(n),i=r.get(t);return i?(r.set(t,{...i,bytesWritten:e.bytesWritten,totalBytes:e.totalBytes??i.totalBytes}),r):n}):e.type===`error`&&b(n=>{let r=new Map(n),i=r.get(t);return i&&r.set(t,{...i,error:e.error}),r})},r.signal),setTimeout(()=>{b(e=>{if(e.get(t)?.error)return e;let n=new Map(e);return n.delete(t),n}),w(),n?.()},800)}catch(e){if(r.signal.aborted){b(e=>{let n=new Map(e);return n.delete(t),n});return}b(n=>{let r=new Map(n),i=r.get(t);return i&&r.set(t,{...i,error:e.message}),r})}},[e,w,n]),E=(0,c.useCallback)(e=>{let t=C.current.get(e);if(t?.error){b(t=>{let n=new Map(t);return n.delete(e),n});return}t?.controller.abort()},[]),D=(0,c.useCallback)(async()=>{if(x)try{e===`stt`?await i.deleteSttModel(x):await i.deleteTtsModel(x),await w(),n?.()}catch(e){v(e.message)}finally{S(null)}},[e,x,w,n]),O=new Set(p.map(e=>e.id)),k=!!d&&p.length>1,A=r&&O.has(r)?r:p[0]?.id;return(0,l.jsxs)(`div`,{className:`ollama-model-manager`,children:[y.size>0&&(0,l.jsxs)(`div`,{className:`ollama-section`,children:[(0,l.jsx)(`h4`,{children:`Downloading…`}),(0,l.jsx)(`div`,{className:`ollama-pull-list`,children:Array.from(y.values()).map(e=>(0,l.jsx)(f,{pull:e,onCancel:()=>E(e.id)},e.id))})]}),(p.length>0||_)&&(0,l.jsxs)(`div`,{className:`ollama-section`,children:[(0,l.jsx)(`h4`,{children:`Local models`}),_&&(0,l.jsx)(`p`,{className:`error`,children:_}),k&&(0,l.jsxs)(`p`,{className:`muted small`,children:[`The `,(0,l.jsx)(`strong`,{children:`active`}),` model is the one transcription runs on. The engine binds one model at a time, so switching reloads it — the next transcription takes a moment longer.`]}),p.length>0&&(0,l.jsxs)(`table`,{className:`ollama-model-table`,children:[(0,l.jsx)(`thead`,{children:(0,l.jsxs)(`tr`,{children:[k&&(0,l.jsx)(`th`,{scope:`col`,className:`gz-active-model-column`,children:`Active`}),(0,l.jsx)(`th`,{children:`Name`}),(0,l.jsx)(`th`,{children:`Size`}),(0,l.jsx)(`th`,{children:`Added`}),(0,l.jsx)(`th`,{})]})}),(0,l.jsx)(`tbody`,{children:p.map(t=>(0,l.jsxs)(`tr`,{children:[k&&(0,l.jsx)(`td`,{className:`gz-active-model-column`,children:(0,l.jsx)(`input`,{type:`radio`,name:`active-${e}-model`,className:`gz-active-model-radio`,"aria-label":`Use ${t.id} as the active ${e===`stt`?`speech-to-text`:`text-to-speech`} model`,checked:A===t.id,onChange:()=>{A!==t.id&&d?.(t.id)}})}),(0,l.jsxs)(`td`,{children:[(0,l.jsx)(`code`,{children:t.id}),(0,l.jsx)(`div`,{className:`muted small`,children:t.name})]}),(0,l.jsx)(`td`,{children:u(t.approxSizeBytes)}),(0,l.jsx)(`td`,{className:`muted small`,children:new Date(t.installedAt).toLocaleDateString()}),(0,l.jsx)(`td`,{children:(0,l.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:()=>S(t.id),children:`Delete`})})]},t.id))})]})]}),(0,l.jsxs)(`div`,{className:`ollama-section ollama-section--flat ollama-section--download`,children:[(0,l.jsx)(`h4`,{children:`Download a model`}),h.length===0?(0,l.jsx)(`p`,{className:`muted small`,children:`No models in the catalog yet.`}):(0,l.jsx)(`div`,{className:`catalog-ollama-list`,children:h.map(e=>{let n=O.has(e.id),r=y.get(e.id),i=!!r,a=r&&r.totalBytes>0?Math.min(100,Math.round(r.bytesWritten/r.totalBytes*100)):null;return(0,l.jsxs)(`div`,{className:`catalog-ollama-action`,children:[(0,l.jsxs)(`div`,{className:`catalog-ollama-meta`,children:[(0,l.jsxs)(`div`,{className:`catalog-ollama-specs muted small`,children:[(0,l.jsx)(`code`,{children:e.id}),(0,l.jsx)(`span`,{children:`·`}),(0,l.jsx)(`span`,{children:u(e.approxSizeBytes)})]}),(0,l.jsxs)(`div`,{className:`muted small`,children:[(0,l.jsx)(`strong`,{children:e.name}),` — `,e.description]}),(0,l.jsxs)(`div`,{className:`catalog-ollama-pills`,children:[(0,l.jsx)(s,{manifest:e}),(0,l.jsx)(o,{manifest:e})]})]}),(0,l.jsx)(`button`,{type:`button`,disabled:n||i||!!t,title:t??void 0,onClick:()=>void T(e.id),children:n?`On device`:i?a===null?`Downloading…`:`Downloading… ${a}%`:`Download`})]},e.id)})})]}),(0,l.jsx)(a,{open:x!==null,title:`Delete ${e===`stt`?`STT`:`TTS`} model?`,message:x?`"${x}" will be removed from local storage. This frees disk space; download it again later to use it.`:``,confirmLabel:`Delete`,danger:!0,onCancel:()=>S(null),onConfirm:D})]})}function f({pull:e,onCancel:t}){let n=e.totalBytes>0,r=n?Math.min(100,Math.round(e.bytesWritten/e.totalBytes*100)):0,i=e.error?e.error:n?`Downloading… (${u(e.bytesWritten)} of ${u(e.totalBytes)}, ${r}%)`:e.bytesWritten>0?`Downloading… (${u(e.bytesWritten)})`:`Preparing download…`;return(0,l.jsxs)(`div`,{className:`ollama-pull${e.error?` ollama-pull-error`:``}`,children:[(0,l.jsxs)(`div`,{className:`ollama-pull-head`,children:[(0,l.jsx)(`code`,{children:e.id}),(0,l.jsx)(`span`,{className:`muted small`,children:i}),(0,l.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:t,children:e.error?`Dismiss`:`Cancel`})]}),n?(0,l.jsxs)(`div`,{className:`ollama-pull-bar`,children:[(0,l.jsx)(`div`,{className:`ollama-pull-bar-fill`,style:{width:`${r}%`}}),(0,l.jsxs)(`span`,{className:`ollama-pull-bar-label`,children:[r,`%`]})]}):(0,l.jsx)(`div`,{className:`ollama-pull-bar ollama-pull-bar-indeterminate`,children:(0,l.jsx)(`div`,{className:`ollama-pull-bar-fill`})})]})}function p(){let[e,t]=(0,c.useState)(null),[n,r]=(0,c.useState)(null),[a,o]=(0,c.useState)([]),[s,u]=(0,c.useState)(`af_heart`),[f,p]=(0,c.useState)(`The quick brown fox jumps over the lazy dog.`),[v,y]=(0,c.useState)({kind:`idle`}),[b,x]=(0,c.useState)(void 0),[S,C]=(0,c.useState)(!1),[w,T]=(0,c.useState)(!1),E=(0,c.useRef)(null),D=(0,c.useCallback)(async()=>{try{let[e,n,a]=await Promise.all([i.getAudioEngineStatus(),i.listAudioVoices(),i.getConfig()]);t(e),o(n.voices),C(a.narrateAssistantReplies??!1),x(a.defaultSttModel),r(null)}catch(e){t(null),r(e.message)}},[]);(0,c.useEffect)(()=>{D()},[D]);let O=(0,c.useCallback)(async e=>{T(!0),C(e);try{let t=await i.updateConfig({narrateAssistantReplies:e});window.dispatchEvent(new CustomEvent(`gezel:config-updated`,{detail:t}))}catch(t){C(!e),r(t.message)}finally{T(!1)}},[]),k=(0,c.useCallback)(async e=>{x(e);try{let t=await i.updateConfig({defaultSttModel:e});x(t.defaultSttModel)}catch(e){x(void 0),r(e.message)}},[]),A=(0,c.useCallback)(async()=>{if(f.trim()){y({kind:`synthesizing`});try{let e=await i.synthesizeSpeech({text:f,voice:s,inline:!0});e.b64Wav&&E.current&&(E.current.src=`data:audio/wav;base64,${e.b64Wav}`,await E.current.play().catch(()=>{})),y({kind:`idle`})}catch(e){y({kind:`error`,msg:m(e)})}}},[f,s]);return(0,l.jsxs)(`div`,{className:`provider-card`,children:[(0,l.jsx)(`div`,{className:`settings-card-header`,children:(0,l.jsx)(`h3`,{children:`Audio`})}),(0,l.jsxs)(`p`,{className:`muted small`,children:[`Speech-to-text via the bundled `,(0,l.jsx)(`code`,{children:`whisper.cpp`}),` engine and text-to-speech via the bundled `,(0,l.jsx)(`code`,{children:`Kokoro`}),` engine — both run locally.`]}),n&&(0,l.jsxs)(`p`,{className:`error`,children:[`Couldn't reach the Gezel service. `,n]}),(0,l.jsxs)(`section`,{style:{marginTop:`1rem`},children:[(0,l.jsxs)(`div`,{className:`settings-card-header`,children:[(0,l.jsx)(`h4`,{style:{margin:0},children:`Speech-to-text (whisper.cpp)`}),e&&(0,l.jsx)(g,{engine:e.stt})]}),(0,l.jsx)(_,{engine:e?.stt}),(0,l.jsx)(d,{kind:`stt`,...b?{configuredDefaultModelId:b}:{},onSetActiveModel:k,...h(e?.stt)?{disabledReason:e?.stt.status===`not-configured`?`whisper.cpp engine is not wired up — downloading a model now would still leave it unrunnable.`:`whisper.cpp engine is not reachable.`}:{},onModelsChanged:()=>void D()})]}),(0,l.jsxs)(`section`,{style:{marginTop:`1.5rem`},children:[(0,l.jsxs)(`div`,{className:`settings-card-header`,children:[(0,l.jsx)(`h4`,{style:{margin:0},children:`Text-to-speech (Kokoro)`}),e&&(0,l.jsx)(g,{engine:e.tts})]}),(0,l.jsx)(_,{engine:e?.tts}),(0,l.jsx)(d,{kind:`tts`,...h(e?.tts)?{disabledReason:`Kokoro engine is not configured.`}:{},onModelsChanged:()=>void D()}),e?.tts.status===`ok`&&(0,l.jsx)(`div`,{className:`ollama-section`,style:{marginTop:`1rem`},children:(0,l.jsxs)(`label`,{className:`provider-row`,children:[(0,l.jsx)(`input`,{type:`checkbox`,checked:S,disabled:w,onChange:e=>void O(e.target.checked)}),(0,l.jsxs)(`span`,{children:[`Narrate assistant replies`,(0,l.jsx)(`span`,{className:`muted small`,style:{marginLeft:`0.5rem`},children:`— speak each completed gezel reply aloud using that gezel's voice.`})]})]})}),e?.tts.status===`ok`&&(0,l.jsxs)(`div`,{className:`ollama-section`,style:{marginTop:`1rem`},children:[(0,l.jsx)(`h4`,{children:`Preview a voice`}),(0,l.jsxs)(`div`,{style:{display:`flex`,gap:`0.5rem`,alignItems:`center`,flexWrap:`wrap`},children:[(0,l.jsxs)(`label`,{className:`provider-row`,children:[(0,l.jsx)(`span`,{children:`Voice`}),(0,l.jsx)(`select`,{value:s,onChange:e=>u(e.target.value),children:a.map(e=>(0,l.jsxs)(`option`,{value:e.id,children:[e.name,` (`,e.language,`)`]},e.id))})]}),(0,l.jsx)(`input`,{type:`text`,value:f,onChange:e=>p(e.target.value),style:{minWidth:280,flex:1}}),(0,l.jsx)(`button`,{type:`button`,onClick:()=>void A(),disabled:v.kind===`synthesizing`||!f.trim(),children:v.kind===`synthesizing`?`Synthesizing…`:`Preview`})]}),v.kind===`error`&&(0,l.jsx)(`p`,{className:`error`,children:v.msg}),(0,l.jsx)(`audio`,{ref:E,controls:!0,style:{width:`100%`,marginTop:`0.5rem`}})]})]})]})}function m(e){if(e instanceof r){let t=e.details;if(t&&typeof t==`object`&&`error`in t){let n=t.error;if(typeof n==`string`&&n.length>0)return`${e.message}: ${n}`}if(typeof t==`string`&&t.length>0)return`${e.message}: ${t}`}return e instanceof Error?e.message:String(e)}function h(e){return!e||e.status===`not-configured`||e.status===`unreachable`}function g({engine:e}){return e.status===`ok`?(0,l.jsx)(`span`,{className:`gz-status-pill gz-status-pill--ok`,children:`Ready`}):e.status===`no-model`?(0,l.jsx)(`span`,{className:`gz-status-pill gz-status-pill--warn`,children:`No model`}):e.status===`unreachable`?(0,l.jsx)(`span`,{className:`gz-status-pill gz-status-pill--error`,children:`Unreachable`}):(0,l.jsx)(`span`,{className:`gz-status-pill gz-status-pill--warn`,children:`Not configured`})}function _({engine:e}){return e?e.status===`not-configured`?(0,l.jsxs)(`p`,{className:`muted small`,children:[`Engine isn't wired up on this install yet.`,e.error?(0,l.jsxs)(l.Fragment,{children:[` `,e.error]}):null]}):e.status===`unreachable`?(0,l.jsxs)(`p`,{className:`error`,children:[`Engine isn't responding`,e.baseUrl?(0,l.jsxs)(l.Fragment,{children:[` `,`at `,(0,l.jsx)(`code`,{children:e.baseUrl})]}):null,`.`,e.error?(0,l.jsxs)(l.Fragment,{children:[` `,e.error]}):null]}):e.status===`no-model`?(0,l.jsx)(`p`,{className:`muted small`,children:`Engine is ready — download a model below to start using it.`}):null:null}export{p as AudioEngineSettings};
@@ -1,2 +1,2 @@
1
- import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{n as t,t as n}from"./jsx-runtime-CEpd2cAX.js";import{t as r}from"./api-BX5xXiFs.js";var i=e(t(),1),a=n();function o(e){return e<1e3?`${Math.round(e)}ms`:e<6e4?`${(e/1e3).toFixed(1)}s`:`${Math.floor(e/6e4)}m ${Math.floor(e%6e4/1e3).toString().padStart(2,`0`)}s`}function s(){let[e,t]=(0,i.useState)([]),[n,s]=(0,i.useState)({available:!0,reason:null}),[u,d]=(0,i.useState)(``),[f,p]=(0,i.useState)(``),[m,h]=(0,i.useState)(``),[g,_]=(0,i.useState)(0),[v,y]=(0,i.useState)([]),[b,x]=(0,i.useState)([]),[S,C]=(0,i.useState)(``),[w,T]=(0,i.useState)(`list`),[E,D]=(0,i.useState)(null),[O,k]=(0,i.useState)(null);(0,i.useEffect)(()=>{let e=!1;async function n(){try{let[n,i,a]=await Promise.all([r.listEvalScenarios(),r.getEvalAvailability(),r.listLlamaCppModels().catch(()=>({models:[]}))]);if(e)return;t(n.scenarios.slice()),s(i);let o=a.models.map(e=>typeof e.id==`string`?e.id:null).filter(e=>!!e);if(y(o),n.scenarios.length>0&&!u){let e=n.scenarios[0];e&&(d(e.id),p(e.defaultModel),h(e.defaultImageModel??``))}}catch(t){e||k(t instanceof Error?t.message:String(t))}}return n(),()=>{e=!0}},[u]);let A=(0,i.useCallback)(async()=>{try{let e=await r.listEvalResults({...S?{scenarioId:S}:{},limit:200});x(e.results)}catch(e){k(e instanceof Error?e.message:String(e))}},[S]);(0,i.useEffect)(()=>{A()},[A]);let j=(0,i.useMemo)(()=>e.find(e=>e.id===u),[e,u]),M=(0,i.useCallback)(t=>{d(t);let n=e.find(e=>e.id===t);n&&(p(n.defaultModel),h(n.defaultImageModel??``))},[e]),N=(0,i.useCallback)(async()=>{if(!j)return;let e=new AbortController,t={scenarioId:j.id,modelId:f,startedAt:Date.now(),trialId:null,runDir:null,logTail:[],ac:e};D(t),k(null);try{await r.runEval({scenarioId:j.id,modelId:f,...m?{imageModelId:m}:{},...g>0?{timeoutMs:g*6e4}:{}},e=>{D(t=>{if(!t)return t;let n={...t,logTail:t.logTail};return e.type===`spawned`?(n.trialId=e.trialId??null,n.runDir=e.runDir??null):e.type===`log`?n.logTail=[...t.logTail,e.line].slice(-200):e.type===`error`&&k(e.error),n})},e.signal)}catch(e){k(e instanceof Error?e.message:String(e))}finally{D(null),A()}},[j,f,m,g,A]),P=(0,i.useCallback)(()=>{E&&E.ac.abort()},[E]);return(0,a.jsxs)(`div`,{className:`benchmarks-view`,style:{padding:16},children:[(0,a.jsxs)(`header`,{style:{display:`flex`,alignItems:`baseline`,gap:12},children:[(0,a.jsx)(`h2`,{style:{margin:0},children:`Benchmarks`}),(0,a.jsx)(`span`,{style:{color:`var(--muted)`,fontSize:13},children:`Run eval scenarios and review outcomes on this device.`})]}),!n.available&&(0,a.jsxs)(`div`,{style:{margin:`12px 0`,padding:10,background:`rgba(220, 170, 0, 0.1)`,border:`1px solid rgba(220, 170, 0, 0.35)`,borderRadius:6,fontSize:13},children:[(0,a.jsx)(`strong`,{children:`In-app eval runner unavailable.`}),` `,n.reason??`The harness binary was not found on disk.`,` You can still review past results below; new runs need `,(0,a.jsx)(`code`,{children:`pnpm eval:run`}),` from the repo.`]}),O&&(0,a.jsx)(`div`,{style:{margin:`12px 0`,padding:10,background:`rgba(220, 80, 80, 0.1)`,border:`1px solid rgba(220, 80, 80, 0.35)`,borderRadius:6,fontSize:13},children:O}),(0,a.jsxs)(`section`,{style:{marginTop:16},children:[(0,a.jsx)(`h3`,{style:{marginBottom:8},children:`Run a trial`}),(0,a.jsxs)(`div`,{style:{display:`grid`,gridTemplateColumns:`180px 1fr`,gap:8,alignItems:`center`},children:[(0,a.jsx)(`label`,{htmlFor:`bench-scenario`,children:`Scenario`}),(0,a.jsx)(`select`,{id:`bench-scenario`,value:u,onChange:e=>M(e.currentTarget.value),style:{padding:4},children:e.map(e=>(0,a.jsxs)(`option`,{value:e.id,children:[e.name,` — `,e.capabilityAxis,` `,e.anchored?`(anchored)`:``]},e.id))}),(0,a.jsx)(`label`,{htmlFor:`bench-model`,children:`Model`}),(0,a.jsxs)(`select`,{id:`bench-model`,value:f,onChange:e=>p(e.currentTarget.value),style:{padding:4},children:[(0,a.jsxs)(`option`,{value:j?.defaultModel??``,children:[j?.defaultModel??`(no scenario)`,` (default)`]}),v.filter(e=>e!==j?.defaultModel).map(e=>(0,a.jsxs)(`option`,{value:e,children:[e,` (local)`]},e))]}),j?.defaultImageModel&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`label`,{htmlFor:`bench-image-model`,children:`Image model`}),(0,a.jsx)(`input`,{id:`bench-image-model`,type:`text`,value:m,onChange:e=>h(e.currentTarget.value),style:{padding:4}})]}),(0,a.jsx)(`label`,{htmlFor:`bench-timeout`,children:`Timeout (min)`}),(0,a.jsx)(`input`,{id:`bench-timeout`,type:`number`,min:0,max:120,value:g,onChange:e=>_(Number(e.currentTarget.value)||0),style:{padding:4,width:80}})]}),(0,a.jsxs)(`div`,{style:{marginTop:12,display:`flex`,gap:8},children:[E?(0,a.jsx)(`button`,{type:`button`,onClick:P,children:`Cancel running trial`}):(0,a.jsxs)(`button`,{type:`button`,onClick:()=>void N(),disabled:!j||!f||!n.available,children:[`Run `,j?.name??`scenario`]}),(0,a.jsx)(`span`,{style:{color:`var(--muted)`,fontSize:12,alignSelf:`center`},children:j?`Default timeout: ${Math.round(j.timeoutMs/6e4)} min`:``})]})]}),E&&(0,a.jsxs)(`section`,{style:{marginTop:24},children:[(0,a.jsxs)(`h3`,{style:{marginBottom:8},children:[`Running: `,E.scenarioId,` / `,E.modelId,` `,(0,a.jsxs)(`span`,{style:{color:`var(--muted)`,fontSize:13,fontWeight:`normal`},children:[`(`,o(Date.now()-E.startedAt),`)`]})]}),E.runDir&&(0,a.jsxs)(`div`,{style:{fontSize:12,color:`var(--muted)`},children:[`runDir: `,E.runDir]}),(0,a.jsx)(`pre`,{style:{maxHeight:280,overflow:`auto`,background:`var(--code-bg, #0e1014)`,color:`var(--code-fg, #d6d6d6)`,padding:8,fontSize:12,lineHeight:1.4},children:E.logTail.join(`
1
+ import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{n as t,t as n}from"./jsx-runtime-CEpd2cAX.js";import{t as r}from"./api-BPraLwsh.js";var i=e(t(),1),a=n();function o(e){return e<1e3?`${Math.round(e)}ms`:e<6e4?`${(e/1e3).toFixed(1)}s`:`${Math.floor(e/6e4)}m ${Math.floor(e%6e4/1e3).toString().padStart(2,`0`)}s`}function s(){let[e,t]=(0,i.useState)([]),[n,s]=(0,i.useState)({available:!0,reason:null}),[u,d]=(0,i.useState)(``),[f,p]=(0,i.useState)(``),[m,h]=(0,i.useState)(``),[g,_]=(0,i.useState)(0),[v,y]=(0,i.useState)([]),[b,x]=(0,i.useState)([]),[S,C]=(0,i.useState)(``),[w,T]=(0,i.useState)(`list`),[E,D]=(0,i.useState)(null),[O,k]=(0,i.useState)(null);(0,i.useEffect)(()=>{let e=!1;async function n(){try{let[n,i,a]=await Promise.all([r.listEvalScenarios(),r.getEvalAvailability(),r.listLlamaCppModels().catch(()=>({models:[]}))]);if(e)return;t(n.scenarios.slice()),s(i);let o=a.models.map(e=>typeof e.id==`string`?e.id:null).filter(e=>!!e);if(y(o),n.scenarios.length>0&&!u){let e=n.scenarios[0];e&&(d(e.id),p(e.defaultModel),h(e.defaultImageModel??``))}}catch(t){e||k(t instanceof Error?t.message:String(t))}}return n(),()=>{e=!0}},[u]);let A=(0,i.useCallback)(async()=>{try{let e=await r.listEvalResults({...S?{scenarioId:S}:{},limit:200});x(e.results)}catch(e){k(e instanceof Error?e.message:String(e))}},[S]);(0,i.useEffect)(()=>{A()},[A]);let j=(0,i.useMemo)(()=>e.find(e=>e.id===u),[e,u]),M=(0,i.useCallback)(t=>{d(t);let n=e.find(e=>e.id===t);n&&(p(n.defaultModel),h(n.defaultImageModel??``))},[e]),N=(0,i.useCallback)(async()=>{if(!j)return;let e=new AbortController,t={scenarioId:j.id,modelId:f,startedAt:Date.now(),trialId:null,runDir:null,logTail:[],ac:e};D(t),k(null);try{await r.runEval({scenarioId:j.id,modelId:f,...m?{imageModelId:m}:{},...g>0?{timeoutMs:g*6e4}:{}},e=>{D(t=>{if(!t)return t;let n={...t,logTail:t.logTail};return e.type===`spawned`?(n.trialId=e.trialId??null,n.runDir=e.runDir??null):e.type===`log`?n.logTail=[...t.logTail,e.line].slice(-200):e.type===`error`&&k(e.error),n})},e.signal)}catch(e){k(e instanceof Error?e.message:String(e))}finally{D(null),A()}},[j,f,m,g,A]),P=(0,i.useCallback)(()=>{E&&E.ac.abort()},[E]);return(0,a.jsxs)(`div`,{className:`benchmarks-view`,style:{padding:16},children:[(0,a.jsxs)(`header`,{style:{display:`flex`,alignItems:`baseline`,gap:12},children:[(0,a.jsx)(`h2`,{style:{margin:0},children:`Benchmarks`}),(0,a.jsx)(`span`,{style:{color:`var(--muted)`,fontSize:13},children:`Run eval scenarios and review outcomes on this device.`})]}),!n.available&&(0,a.jsxs)(`div`,{style:{margin:`12px 0`,padding:10,background:`rgba(220, 170, 0, 0.1)`,border:`1px solid rgba(220, 170, 0, 0.35)`,borderRadius:6,fontSize:13},children:[(0,a.jsx)(`strong`,{children:`In-app eval runner unavailable.`}),` `,n.reason??`The harness binary was not found on disk.`,` You can still review past results below; new runs need `,(0,a.jsx)(`code`,{children:`pnpm eval:run`}),` from the repo.`]}),O&&(0,a.jsx)(`div`,{style:{margin:`12px 0`,padding:10,background:`rgba(220, 80, 80, 0.1)`,border:`1px solid rgba(220, 80, 80, 0.35)`,borderRadius:6,fontSize:13},children:O}),(0,a.jsxs)(`section`,{style:{marginTop:16},children:[(0,a.jsx)(`h3`,{style:{marginBottom:8},children:`Run a trial`}),(0,a.jsxs)(`div`,{style:{display:`grid`,gridTemplateColumns:`180px 1fr`,gap:8,alignItems:`center`},children:[(0,a.jsx)(`label`,{htmlFor:`bench-scenario`,children:`Scenario`}),(0,a.jsx)(`select`,{id:`bench-scenario`,value:u,onChange:e=>M(e.currentTarget.value),style:{padding:4},children:e.map(e=>(0,a.jsxs)(`option`,{value:e.id,children:[e.name,` — `,e.capabilityAxis,` `,e.anchored?`(anchored)`:``]},e.id))}),(0,a.jsx)(`label`,{htmlFor:`bench-model`,children:`Model`}),(0,a.jsxs)(`select`,{id:`bench-model`,value:f,onChange:e=>p(e.currentTarget.value),style:{padding:4},children:[(0,a.jsxs)(`option`,{value:j?.defaultModel??``,children:[j?.defaultModel??`(no scenario)`,` (default)`]}),v.filter(e=>e!==j?.defaultModel).map(e=>(0,a.jsxs)(`option`,{value:e,children:[e,` (local)`]},e))]}),j?.defaultImageModel&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`label`,{htmlFor:`bench-image-model`,children:`Image model`}),(0,a.jsx)(`input`,{id:`bench-image-model`,type:`text`,value:m,onChange:e=>h(e.currentTarget.value),style:{padding:4}})]}),(0,a.jsx)(`label`,{htmlFor:`bench-timeout`,children:`Timeout (min)`}),(0,a.jsx)(`input`,{id:`bench-timeout`,type:`number`,min:0,max:120,value:g,onChange:e=>_(Number(e.currentTarget.value)||0),style:{padding:4,width:80}})]}),(0,a.jsxs)(`div`,{style:{marginTop:12,display:`flex`,gap:8},children:[E?(0,a.jsx)(`button`,{type:`button`,onClick:P,children:`Cancel running trial`}):(0,a.jsxs)(`button`,{type:`button`,onClick:()=>void N(),disabled:!j||!f||!n.available,children:[`Run `,j?.name??`scenario`]}),(0,a.jsx)(`span`,{style:{color:`var(--muted)`,fontSize:12,alignSelf:`center`},children:j?`Default timeout: ${Math.round(j.timeoutMs/6e4)} min`:``})]})]}),E&&(0,a.jsxs)(`section`,{style:{marginTop:24},children:[(0,a.jsxs)(`h3`,{style:{marginBottom:8},children:[`Running: `,E.scenarioId,` / `,E.modelId,` `,(0,a.jsxs)(`span`,{style:{color:`var(--muted)`,fontSize:13,fontWeight:`normal`},children:[`(`,o(Date.now()-E.startedAt),`)`]})]}),E.runDir&&(0,a.jsxs)(`div`,{style:{fontSize:12,color:`var(--muted)`},children:[`runDir: `,E.runDir]}),(0,a.jsx)(`pre`,{style:{maxHeight:280,overflow:`auto`,background:`var(--code-bg, #0e1014)`,color:`var(--code-fg, #d6d6d6)`,padding:8,fontSize:12,lineHeight:1.4},children:E.logTail.join(`
2
2
  `)})]}),(0,a.jsxs)(`section`,{style:{marginTop:24},children:[(0,a.jsxs)(`div`,{style:{display:`flex`,alignItems:`baseline`,gap:12},children:[(0,a.jsxs)(`h3`,{style:{marginBottom:0},children:[`Past results (`,b.length,`)`]}),(0,a.jsxs)(`select`,{value:S,onChange:e=>C(e.currentTarget.value),style:{padding:4},children:[(0,a.jsx)(`option`,{value:``,children:`All scenarios`}),e.map(e=>(0,a.jsx)(`option`,{value:e.id,children:e.name},e.id))]}),(0,a.jsx)(`button`,{type:`button`,onClick:()=>void A(),children:`Refresh`}),(0,a.jsxs)(`span`,{style:{marginLeft:`auto`},children:[(0,a.jsx)(`button`,{type:`button`,onClick:()=>T(`list`),disabled:w===`list`,children:`List`}),(0,a.jsx)(`button`,{type:`button`,onClick:()=>T(`matrix`),disabled:w===`matrix`,children:`Matrix`})]})]}),w===`list`&&(0,a.jsx)(c,{results:b}),w===`matrix`&&(0,a.jsx)(l,{results:b,scenarios:e})]})]})}function c({results:e}){return e.length===0?(0,a.jsx)(`p`,{style:{color:`var(--muted)`,marginTop:12},children:`No results yet for this filter.`}):(0,a.jsxs)(`table`,{style:{marginTop:12,width:`100%`,borderCollapse:`collapse`,fontSize:13},children:[(0,a.jsx)(`thead`,{children:(0,a.jsxs)(`tr`,{style:{borderBottom:`1px solid var(--border, #444)`,textAlign:`left`},children:[(0,a.jsx)(`th`,{style:{padding:`6px 8px`},children:`When`}),(0,a.jsx)(`th`,{style:{padding:`6px 8px`},children:`Scenario`}),(0,a.jsx)(`th`,{style:{padding:`6px 8px`},children:`Model`}),(0,a.jsx)(`th`,{style:{padding:`6px 8px`},children:`Outcome`}),(0,a.jsx)(`th`,{style:{padding:`6px 8px`},children:`Duration`}),(0,a.jsx)(`th`,{style:{padding:`6px 8px`},children:`Reason`})]})}),(0,a.jsx)(`tbody`,{children:e.map(e=>(0,a.jsxs)(`tr`,{style:{borderBottom:`1px solid rgba(128,128,128,0.15)`},children:[(0,a.jsx)(`td`,{style:{padding:`6px 8px`,whiteSpace:`nowrap`},children:new Date(e.startedAt).toLocaleString()}),(0,a.jsx)(`td`,{style:{padding:`6px 8px`},children:e.scenarioId}),(0,a.jsx)(`td`,{style:{padding:`6px 8px`},children:e.modelId}),(0,a.jsx)(`td`,{style:{padding:`6px 8px`},children:e.success?(0,a.jsx)(`span`,{style:{color:`var(--ok, #5bbf5e)`},children:`PASS`}):(0,a.jsxs)(`span`,{style:{color:`var(--fail, #d57070)`},children:[`FAIL`,e.failureMode?` (${e.failureMode})`:``]})}),(0,a.jsx)(`td`,{style:{padding:`6px 8px`},children:o(e.durationMs)}),(0,a.jsx)(`td`,{style:{padding:`6px 8px`,maxWidth:360,overflow:`hidden`,textOverflow:`ellipsis`,whiteSpace:`nowrap`},title:e.reason,children:e.reason})]},e.trialId))})]})}function l({results:e,scenarios:t}){let n=(0,i.useMemo)(()=>{let t=new Map,n=new Set;for(let r of e){let e=`${r.scenarioId}::${r.modelId}`,i=t.get(e);n.add(r.modelId),i?t.set(e,{passes:i.passes+ +!!r.success,total:i.total+1,latest:i.latest}):t.set(e,{passes:+!!r.success,total:1,latest:r})}return{cells:t,models:[...n].sort()}},[e]);return e.length===0?(0,a.jsx)(`p`,{style:{color:`var(--muted)`,marginTop:12},children:`No data to compare yet.`}):(0,a.jsxs)(`table`,{style:{marginTop:12,borderCollapse:`collapse`,fontSize:13},children:[(0,a.jsx)(`thead`,{children:(0,a.jsxs)(`tr`,{style:{borderBottom:`1px solid var(--border, #444)`},children:[(0,a.jsx)(`th`,{style:{padding:`6px 8px`,textAlign:`left`},children:`Scenario`}),n.models.map(e=>(0,a.jsx)(`th`,{style:{padding:`6px 8px`,textAlign:`left`},children:e},e))]})}),(0,a.jsx)(`tbody`,{children:t.map(e=>(0,a.jsxs)(`tr`,{style:{borderBottom:`1px solid rgba(128,128,128,0.15)`},children:[(0,a.jsx)(`td`,{style:{padding:`6px 8px`},children:e.name}),n.models.map(t=>{let r=n.cells.get(`${e.id}::${t}`);if(!r)return(0,a.jsx)(`td`,{style:{padding:`6px 8px`,color:`var(--muted)`},children:`—`},t);let i=Math.round(r.passes/r.total*100);return(0,a.jsxs)(`td`,{style:{padding:`6px 8px`,color:i>=75?`var(--ok, #5bbf5e)`:i>=50?`#cc9b3c`:`var(--fail, #d57070)`},title:`${r.passes}/${r.total} passes — most recent: ${new Date(r.latest.startedAt).toLocaleString()} (${r.latest.success?`PASS`:`FAIL`})`,children:[r.passes,`/`,r.total,` (`,i,`%)`]},t)})]},e.id))})]})}export{s as BenchmarksView};
@@ -0,0 +1 @@
1
+ import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{n as t,t as n}from"./jsx-runtime-CEpd2cAX.js";import{Tt as r,_t as i}from"./dist-BqGwkOe5.js";import{t as a}from"./api-BPraLwsh.js";import{n as o}from"./primitives-CWrGZpPI.js";import{Z as s}from"./index-C0DYtvfg.js";import{t as c}from"./RecommendedBadge-D0m68PAu.js";var l=e(t(),1),u=n(),d={search:`Search`,"dev-tools":`Dev tools`,data:`Data`,cloud:`Cloud`,productivity:`Productivity`,communication:`Communication`,content:`Content`,ai:`AI`,media:`Media`,other:`Other`},f=[`search`,`dev-tools`,`data`,`cloud`,`productivity`,`communication`,`content`,`media`,`ai`,`other`];function p({item:e}){return(0,u.jsx)(s,{iconSvg:e.iconSvg,logoUrl:e.logoUrl,svgClassName:`catalog-item-logo catalog-item-logo-svg`,imageClassName:`catalog-item-logo`,fallback:(0,u.jsx)(`div`,{className:`catalog-item-logo catalog-item-logo-placeholder`,children:e.manifest.name.slice(0,1)})})}function m(e){return e.manifest.kind===`chat-model`?r(e.manifest):e.manifest.kind===`image-model`||e.manifest.kind===`video-model`?{maker:e.manifest.maintainer.name,customizers:[]}:null}function h(e){let t=e.manifest;return t.kind===`chat-model`||t.kind===`image-model`||t.kind===`video-model`?t:null}function g({kind:e,action:t,emptyMessage:n,filterTags:r,filter:s,onItemsLoaded:g,tagTooltips:_,initialItems:v}){let[y,b]=(0,l.useState)(v??[]),[x,S]=(0,l.useState)(v===void 0),[C,w]=(0,l.useState)(null),[T,E]=(0,l.useState)(``),[D,O]=(0,l.useState)(`all`),k=(0,l.useCallback)(async()=>{S(!0),w(null);try{let t=await a.listCatalogItems(e);b(t.items),g?.(t.items)}catch(e){w(e.message)}finally{S(!1)}},[e,g]);(0,l.useEffect)(()=>{if(v!==void 0){b(v),S(!1);return}k()},[k,v]);let A=(0,l.useMemo)(()=>{if(e!==`toolset`)return null;let t=new Map,n=0;for(let e of y){if(e.manifest.kind!==`toolset`)continue;let r=e.manifest.category??`other`;t.set(r,(t.get(r)??0)+1),n++}return n===0?null:t},[y,e]),j=(0,l.useMemo)(()=>{let t=y;if(e===`toolset`&&D!==`all`&&(t=t.filter(e=>e.manifest.kind===`toolset`&&(e.manifest.category??`other`)===D)),r&&r.length>0){let e=new Set(r);t=t.filter(t=>t.manifest.tags.some(t=>e.has(t.toLowerCase())))}if(T.trim()){let e=T.toLowerCase();t=t.filter(t=>{let n=m(t);return t.manifest.name.toLowerCase().includes(e)||t.manifest.description.toLowerCase().includes(e)||t.manifest.tags.some(t=>t.toLowerCase().includes(e))||t.manifest.id.toLowerCase().includes(e)||n?.maker.toLowerCase().includes(e)||n?.customizers.some(t=>t.toLowerCase().includes(e))})}return s&&(t=t.filter(s)),t},[y,T,r,s,D,e]);return(0,u.jsxs)(`div`,{className:`catalog-browser${e===`chat-model`||e===`image-model`||e===`video-model`||e===`knowledge-catalog`?` catalog-browser--models`:``}`,children:[(0,u.jsxs)(`div`,{className:`catalog-filter`,children:[(0,u.jsx)(`input`,{placeholder:`Filter…`,value:T,onChange:e=>E(e.target.value)}),(0,u.jsx)(`button`,{type:`button`,onClick:()=>void k(),children:`Refresh`})]}),A&&A.size>0&&(0,u.jsxs)(`div`,{className:`catalog-categories`,role:`tablist`,"aria-label":`Filter by category`,children:[(0,u.jsxs)(`button`,{type:`button`,role:`tab`,"aria-selected":D===`all`,className:`catalog-category${D===`all`?` catalog-category-active`:``}`,onClick:()=>O(`all`),children:[`All `,(0,u.jsx)(`span`,{className:`catalog-category-count`,children:y.length})]}),f.filter(e=>(A.get(e)??0)>0).map(e=>(0,u.jsxs)(`button`,{type:`button`,role:`tab`,"aria-selected":D===e,className:`catalog-category${D===e?` catalog-category-active`:``}`,onClick:()=>O(e),children:[d[e],` `,(0,u.jsx)(`span`,{className:`catalog-category-count`,children:A.get(e)})]},e))]}),x&&(0,u.jsx)(`p`,{className:`muted small`,children:`Loading…`}),C&&(0,u.jsx)(`p`,{className:`error`,children:C}),!x&&j.length===0&&(0,u.jsx)(`p`,{className:`muted small`,children:n??`Nothing in the catalog for this kind yet.`}),(0,u.jsx)(`ul`,{className:`catalog-grid`,children:j.map(e=>{let n=m(e),r=h(e),a=i(e.manifest);return(0,u.jsxs)(`li`,{className:`catalog-item`,children:[(0,u.jsxs)(`div`,{className:`catalog-item-header`,children:[(0,u.jsx)(p,{item:e}),(0,u.jsxs)(`div`,{className:`catalog-item-head`,children:[(0,u.jsx)(`div`,{className:`catalog-item-name`,children:e.manifest.name}),e.manifest.kind===`knowledge-catalog`&&(0,u.jsx)(`div`,{className:`catalog-item-attribution`,children:(0,u.jsxs)(`div`,{children:[`Published by `,(0,u.jsx)(`strong`,{children:e.manifest.maintainer.name})]})}),n&&(0,u.jsxs)(`div`,{className:`catalog-item-attribution`,children:[(0,u.jsxs)(`div`,{children:[`Made by `,(0,u.jsx)(`strong`,{children:n.maker})]}),n.customizers.length>0&&(0,u.jsxs)(`div`,{children:[`Customized by `,(0,u.jsx)(`strong`,{children:n.customizers.join(`, `)})]})]}),e.manifest.tags.length>0&&(0,u.jsx)(`div`,{className:`catalog-item-tags`,children:e.manifest.tags.map(e=>{let t=e.trim().toLowerCase(),n=t===`retired`,r=_?.[t]??(n?`This model is kept for compatibility but is no longer recommended for new downloads.`:void 0),i=(0,u.jsx)(`span`,{className:`catalog-item-tag${n?` catalog-item-tag--retired`:``}`,style:r?{cursor:`help`}:void 0,children:e},e);return r?(0,u.jsx)(o,{text:r,children:i},e):i})}),r&&!a&&(0,u.jsx)(c,{manifest:r})]})]}),(0,u.jsx)(`p`,{className:`catalog-item-description`,children:e.manifest.description}),(0,u.jsx)(`div`,{className:`catalog-item-action`,children:t(e)})]},`${e.sourceId}:${e.manifest.id}`)})})]})}export{g as t};
@@ -1 +1 @@
1
- import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{n as t,t as n}from"./jsx-runtime-CEpd2cAX.js";import{t as r}from"./api-BX5xXiFs.js";var i=e(t(),1),a=n(),o=0;function s(e=``,t=``){return o+=1,{id:`h-${o}`,key:e,value:t}}function c(e){return e?.channels?.webhook}function l({config:e,onConfigChanged:t}){let n=c(e),[o,l]=(0,i.useState)(n?.url??``),[f,p]=(0,i.useState)(n?.method??`POST`),[m,h]=(0,i.useState)(n?.bodyTemplate??``),[g,_]=(0,i.useState)(n?.bodyContentType??``),[v,y]=(0,i.useState)(()=>Object.entries(n?.headers??{}).map(([e,t])=>s(e,t))),[b,x]=(0,i.useState)(``),[S,C]=(0,i.useState)(``),[w,T]=(0,i.useState)([]),[E,D]=(0,i.useState)({kind:`idle`}),[O,k]=(0,i.useState)(null);(0,i.useEffect)(()=>{let t=c(e);l(t?.url??``),p(t?.method??`POST`),h(t?.bodyTemplate??``),_(t?.bodyContentType??``),y(Object.entries(t?.headers??{}).map(([e,t])=>s(e,t)))},[e]);let A=(0,i.useCallback)(async()=>{try{let e=await r.listChannels();T(e.channels)}catch{}},[]);(0,i.useEffect)(()=>{A()},[A]);let j=w.find(e=>e.name===`webhook`),M=e?.hasWebhookBearerToken??!1,N=e?.hasWebhookBasicAuth??!1,P=(0,i.useCallback)(async()=>{if(!o.trim()){k(`A URL is required.`);return}let n={};for(let e of v){let t=e.key.trim();t&&(n[t]=e.value)}let i={url:o.trim(),method:f,...m.trim()?{bodyTemplate:m}:{},...g.trim()?{bodyContentType:g.trim()}:{},...Object.keys(n).length>0?{headers:n}:{}};k(`saving…`);try{t(await r.updateConfig({channels:{...e?.channels??{},webhook:i},...b.trim()?{webhookBearerToken:b.trim()}:{},...S.trim()?{webhookBasicAuth:S.trim()}:{}})),x(``),C(``),k(`Saved.`),A()}catch(e){k(`Save failed: ${e.message}`)}},[o,f,m,g,v,b,S,e,t,A]),F=(0,i.useCallback)(async()=>{k(`clearing…`);try{t(await r.updateConfig({channels:{...e?.channels??{},webhook:void 0},webhookBearerToken:``,webhookBasicAuth:``})),k(`Cleared.`),A()}catch(e){k(`Clear failed: ${e.message}`)}},[e,t,A]),I=(0,i.useCallback)(async()=>{try{t(await r.updateConfig({webhookBearerToken:``})),k(`Bearer token cleared.`)}catch(e){k(`Clear failed: ${e.message}`)}},[t]),L=(0,i.useCallback)(async()=>{try{t(await r.updateConfig({webhookBasicAuth:``})),k(`Basic auth cleared.`)}catch(e){k(`Clear failed: ${e.message}`)}},[t]),R=(0,i.useCallback)(async()=>{D({kind:`probing`});try{let e=await r.testChannel(`webhook`);e.ok?D({kind:`ok`}):D({kind:`fail`,error:e.error})}catch(e){D({kind:`fail`,error:e.message})}},[]);return(0,a.jsx)(a.Fragment,{children:(0,a.jsxs)(`section`,{className:`provider-card`,children:[(0,a.jsx)(`h3`,{children:`Webhook`}),(0,a.jsx)(`p`,{className:`muted`,style:{marginTop:0},children:`A generic HTTP channel. Gezels (and the service itself) can POST a message here, and whatever listens on the other end decides what to do with it — push to your phone via ntfy.sh, drop into a Slack channel via an incoming webhook, forward to Discord, or relay through a self-hosted service.`}),(0,a.jsx)(u,{status:j}),(0,a.jsxs)(`details`,{className:`home-section-fold`,style:{marginTop:`1rem`},open:!0,children:[(0,a.jsx)(`summary`,{className:`home-section-fold-summary`,children:(0,a.jsx)(`strong`,{children:`Endpoint`})}),(0,a.jsxs)(`div`,{className:`new-row`,style:{flexWrap:`wrap`,marginTop:`0.5rem`},children:[(0,a.jsx)(`input`,{type:`url`,placeholder:`https://ntfy.sh/your-topic`,value:o,onChange:e=>l(e.target.value),style:{flex:`1 1 260px`}}),(0,a.jsxs)(`select`,{value:f,onChange:e=>p(e.target.value),children:[(0,a.jsx)(`option`,{value:`POST`,children:`POST`}),(0,a.jsx)(`option`,{value:`PUT`,children:`PUT`})]})]}),(0,a.jsxs)(`div`,{style:{marginTop:`0.75rem`},children:[(0,a.jsx)(`label`,{className:`muted small`,children:`Headers (optional)`}),(0,a.jsx)(d,{rows:v,onChange:y})]}),(0,a.jsxs)(`div`,{style:{marginTop:`0.75rem`},children:[(0,a.jsxs)(`label`,{className:`muted small`,children:[`Body template (optional — `,(0,a.jsx)(`code`,{children:`{{message}}`}),` is replaced with the JSON-encoded message text)`]}),(0,a.jsx)(`textarea`,{placeholder:`{"message":{{message}}}`,value:m,onChange:e=>h(e.target.value),rows:3,style:{width:`100%`,fontFamily:`var(--font-mono, monospace)`}})]}),(0,a.jsxs)(`div`,{style:{marginTop:`0.5rem`},children:[(0,a.jsx)(`label`,{className:`muted small`,children:`Content-Type (optional, default application/json)`}),(0,a.jsx)(`input`,{type:`text`,placeholder:`application/json`,value:g,onChange:e=>_(e.target.value),style:{width:`100%`}})]})]}),(0,a.jsxs)(`details`,{className:`home-section-fold`,style:{marginTop:`1rem`},children:[(0,a.jsxs)(`summary`,{className:`home-section-fold-summary`,children:[(0,a.jsx)(`strong`,{children:`Auth`}),` `,(0,a.jsx)(`span`,{className:`muted small`,children:M?`— bearer set`:N?`— basic set`:`— none`})]}),(0,a.jsxs)(`div`,{style:{marginTop:`0.5rem`},children:[(0,a.jsx)(`label`,{className:`muted small`,children:`Bearer token (optional)`}),(0,a.jsxs)(`div`,{className:`new-row`,children:[(0,a.jsx)(`input`,{type:`password`,placeholder:M?`Replace bearer token…`:`Paste bearer token`,value:b,onChange:e=>x(e.target.value),style:{flex:1}}),M&&(0,a.jsx)(`button`,{type:`button`,onClick:()=>void I(),children:`Clear`})]})]}),(0,a.jsxs)(`div`,{style:{marginTop:`0.5rem`},children:[(0,a.jsx)(`label`,{className:`muted small`,children:`Basic auth (optional — "user:pass")`}),(0,a.jsxs)(`div`,{className:`new-row`,children:[(0,a.jsx)(`input`,{type:`password`,placeholder:N?`Replace basic auth…`:`user:pass`,value:S,onChange:e=>C(e.target.value),style:{flex:1}}),N&&(0,a.jsx)(`button`,{type:`button`,onClick:()=>void L(),children:`Clear`})]})]})]}),(0,a.jsxs)(`div`,{className:`new-row`,style:{marginTop:`1rem`},children:[(0,a.jsx)(`button`,{type:`button`,className:`primary`,onClick:()=>void P(),children:`Save webhook`}),j?.configured&&(0,a.jsx)(`button`,{type:`button`,onClick:()=>void F(),children:`Remove`}),(0,a.jsx)(`button`,{type:`button`,onClick:()=>void R(),disabled:!j?.configured||E.kind===`probing`,style:{marginLeft:`auto`},children:E.kind===`probing`?`Sending…`:`Send test message`})]}),E.kind===`ok`&&(0,a.jsx)(`p`,{className:`muted small`,style:{marginTop:`0.5rem`},children:`Test sent.`}),E.kind===`fail`&&(0,a.jsxs)(`p`,{className:`error small`,style:{marginTop:`0.5rem`},children:[`Test failed: `,E.error]}),O&&(0,a.jsx)(`p`,{className:`muted small`,style:{marginTop:`0.5rem`},children:O}),(0,a.jsxs)(`details`,{className:`home-section-fold`,style:{marginTop:`1rem`},children:[(0,a.jsx)(`summary`,{className:`home-section-fold-summary`,children:(0,a.jsx)(`strong`,{children:`Recipes`})}),(0,a.jsxs)(`ul`,{className:`muted small`,style:{marginTop:`0.5rem`},children:[(0,a.jsxs)(`li`,{children:[(0,a.jsx)(`strong`,{children:`ntfy.sh (mobile push):`}),` install the ntfy app on your phone, subscribe to a random topic like `,(0,a.jsx)(`code`,{children:`gezel-xyz123`}),`, and paste`,` `,(0,a.jsx)(`code`,{children:`https://ntfy.sh/gezel-xyz123`}),` as the URL. No auth needed; leave the body template blank.`]}),(0,a.jsxs)(`li`,{children:[(0,a.jsx)(`strong`,{children:`Slack:`}),` create an incoming webhook in your workspace, paste the URL. Set the body template to `,(0,a.jsx)(`code`,{children:`{"text":{{message}}}`}),`.`]}),(0,a.jsxs)(`li`,{children:[(0,a.jsx)(`strong`,{children:`Discord:`}),` paste a channel webhook URL. Set the body template to`,` `,(0,a.jsx)(`code`,{children:`{"content":{{message}}}`}),`.`]})]})]})]})})}function u({status:e}){if(!e||!e.configured)return(0,a.jsx)(`p`,{className:`muted small`,style:{marginTop:0},children:`Not configured.`});if(e.ready){let t=e.detail?.url;return(0,a.jsxs)(`p`,{className:`muted small`,style:{marginTop:0},children:[`Active`,t?` — ${t}`:``]})}return(0,a.jsxs)(`p`,{className:`error small`,style:{marginTop:0},children:[`Not ready`,e.lastError?`: ${e.lastError}`:``]})}function d({rows:e,onChange:t}){return(0,a.jsxs)(`div`,{children:[e.map((n,r)=>(0,a.jsxs)(`div`,{className:`new-row`,style:{marginTop:r===0?`0.25rem`:`0.35rem`},children:[(0,a.jsx)(`input`,{type:`text`,placeholder:`Header name`,value:n.key,onChange:i=>{let a=[...e];a[r]={...n,key:i.target.value},t(a)},style:{flex:1}}),(0,a.jsx)(`input`,{type:`text`,placeholder:`Value`,value:n.value,onChange:i=>{let a=[...e];a[r]={...n,value:i.target.value},t(a)},style:{flex:2}}),(0,a.jsx)(`button`,{type:`button`,onClick:()=>t(e.filter((e,t)=>t!==r)),"aria-label":`Remove header`,children:`−`})]},n.id)),(0,a.jsx)(`div`,{style:{marginTop:`0.35rem`},children:(0,a.jsx)(`button`,{type:`button`,onClick:()=>t([...e,s()]),children:`+ Add header`})})]})}export{l as ChannelsSettings};
1
+ import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{n as t,t as n}from"./jsx-runtime-CEpd2cAX.js";import{t as r}from"./api-BPraLwsh.js";var i=e(t(),1),a=n(),o=0;function s(e=``,t=``){return o+=1,{id:`h-${o}`,key:e,value:t}}function c(e){return e?.channels?.webhook}function l({config:e,onConfigChanged:t}){let n=c(e),[o,l]=(0,i.useState)(n?.url??``),[f,p]=(0,i.useState)(n?.method??`POST`),[m,h]=(0,i.useState)(n?.bodyTemplate??``),[g,_]=(0,i.useState)(n?.bodyContentType??``),[v,y]=(0,i.useState)(()=>Object.entries(n?.headers??{}).map(([e,t])=>s(e,t))),[b,x]=(0,i.useState)(``),[S,C]=(0,i.useState)(``),[w,T]=(0,i.useState)([]),[E,D]=(0,i.useState)({kind:`idle`}),[O,k]=(0,i.useState)(null);(0,i.useEffect)(()=>{let t=c(e);l(t?.url??``),p(t?.method??`POST`),h(t?.bodyTemplate??``),_(t?.bodyContentType??``),y(Object.entries(t?.headers??{}).map(([e,t])=>s(e,t)))},[e]);let A=(0,i.useCallback)(async()=>{try{let e=await r.listChannels();T(e.channels)}catch{}},[]);(0,i.useEffect)(()=>{A()},[A]);let j=w.find(e=>e.name===`webhook`),M=e?.hasWebhookBearerToken??!1,N=e?.hasWebhookBasicAuth??!1,P=(0,i.useCallback)(async()=>{if(!o.trim()){k(`A URL is required.`);return}let n={};for(let e of v){let t=e.key.trim();t&&(n[t]=e.value)}let i={url:o.trim(),method:f,...m.trim()?{bodyTemplate:m}:{},...g.trim()?{bodyContentType:g.trim()}:{},...Object.keys(n).length>0?{headers:n}:{}};k(`saving…`);try{t(await r.updateConfig({channels:{...e?.channels??{},webhook:i},...b.trim()?{webhookBearerToken:b.trim()}:{},...S.trim()?{webhookBasicAuth:S.trim()}:{}})),x(``),C(``),k(`Saved.`),A()}catch(e){k(`Save failed: ${e.message}`)}},[o,f,m,g,v,b,S,e,t,A]),F=(0,i.useCallback)(async()=>{k(`clearing…`);try{t(await r.updateConfig({channels:{...e?.channels??{},webhook:void 0},webhookBearerToken:``,webhookBasicAuth:``})),k(`Cleared.`),A()}catch(e){k(`Clear failed: ${e.message}`)}},[e,t,A]),I=(0,i.useCallback)(async()=>{try{t(await r.updateConfig({webhookBearerToken:``})),k(`Bearer token cleared.`)}catch(e){k(`Clear failed: ${e.message}`)}},[t]),L=(0,i.useCallback)(async()=>{try{t(await r.updateConfig({webhookBasicAuth:``})),k(`Basic auth cleared.`)}catch(e){k(`Clear failed: ${e.message}`)}},[t]),R=(0,i.useCallback)(async()=>{D({kind:`probing`});try{let e=await r.testChannel(`webhook`);e.ok?D({kind:`ok`}):D({kind:`fail`,error:e.error})}catch(e){D({kind:`fail`,error:e.message})}},[]);return(0,a.jsx)(a.Fragment,{children:(0,a.jsxs)(`section`,{className:`provider-card`,children:[(0,a.jsx)(`h3`,{children:`Webhook`}),(0,a.jsx)(`p`,{className:`muted`,style:{marginTop:0},children:`A generic HTTP channel. Gezels (and the service itself) can POST a message here, and whatever listens on the other end decides what to do with it — push to your phone via ntfy.sh, drop into a Slack channel via an incoming webhook, forward to Discord, or relay through a self-hosted service.`}),(0,a.jsx)(u,{status:j}),(0,a.jsxs)(`details`,{className:`home-section-fold`,style:{marginTop:`1rem`},open:!0,children:[(0,a.jsx)(`summary`,{className:`home-section-fold-summary`,children:(0,a.jsx)(`strong`,{children:`Endpoint`})}),(0,a.jsxs)(`div`,{className:`new-row`,style:{flexWrap:`wrap`,marginTop:`0.5rem`},children:[(0,a.jsx)(`input`,{type:`url`,placeholder:`https://ntfy.sh/your-topic`,value:o,onChange:e=>l(e.target.value),style:{flex:`1 1 260px`}}),(0,a.jsxs)(`select`,{value:f,onChange:e=>p(e.target.value),children:[(0,a.jsx)(`option`,{value:`POST`,children:`POST`}),(0,a.jsx)(`option`,{value:`PUT`,children:`PUT`})]})]}),(0,a.jsxs)(`div`,{style:{marginTop:`0.75rem`},children:[(0,a.jsx)(`label`,{className:`muted small`,children:`Headers (optional)`}),(0,a.jsx)(d,{rows:v,onChange:y})]}),(0,a.jsxs)(`div`,{style:{marginTop:`0.75rem`},children:[(0,a.jsxs)(`label`,{className:`muted small`,children:[`Body template (optional — `,(0,a.jsx)(`code`,{children:`{{message}}`}),` is replaced with the JSON-encoded message text)`]}),(0,a.jsx)(`textarea`,{placeholder:`{"message":{{message}}}`,value:m,onChange:e=>h(e.target.value),rows:3,style:{width:`100%`,fontFamily:`var(--font-mono, monospace)`}})]}),(0,a.jsxs)(`div`,{style:{marginTop:`0.5rem`},children:[(0,a.jsx)(`label`,{className:`muted small`,children:`Content-Type (optional, default application/json)`}),(0,a.jsx)(`input`,{type:`text`,placeholder:`application/json`,value:g,onChange:e=>_(e.target.value),style:{width:`100%`}})]})]}),(0,a.jsxs)(`details`,{className:`home-section-fold`,style:{marginTop:`1rem`},children:[(0,a.jsxs)(`summary`,{className:`home-section-fold-summary`,children:[(0,a.jsx)(`strong`,{children:`Auth`}),` `,(0,a.jsx)(`span`,{className:`muted small`,children:M?`— bearer set`:N?`— basic set`:`— none`})]}),(0,a.jsxs)(`div`,{style:{marginTop:`0.5rem`},children:[(0,a.jsx)(`label`,{className:`muted small`,children:`Bearer token (optional)`}),(0,a.jsxs)(`div`,{className:`new-row`,children:[(0,a.jsx)(`input`,{type:`password`,placeholder:M?`Replace bearer token…`:`Paste bearer token`,value:b,onChange:e=>x(e.target.value),style:{flex:1}}),M&&(0,a.jsx)(`button`,{type:`button`,onClick:()=>void I(),children:`Clear`})]})]}),(0,a.jsxs)(`div`,{style:{marginTop:`0.5rem`},children:[(0,a.jsx)(`label`,{className:`muted small`,children:`Basic auth (optional — "user:pass")`}),(0,a.jsxs)(`div`,{className:`new-row`,children:[(0,a.jsx)(`input`,{type:`password`,placeholder:N?`Replace basic auth…`:`user:pass`,value:S,onChange:e=>C(e.target.value),style:{flex:1}}),N&&(0,a.jsx)(`button`,{type:`button`,onClick:()=>void L(),children:`Clear`})]})]})]}),(0,a.jsxs)(`div`,{className:`new-row`,style:{marginTop:`1rem`},children:[(0,a.jsx)(`button`,{type:`button`,className:`primary`,onClick:()=>void P(),children:`Save webhook`}),j?.configured&&(0,a.jsx)(`button`,{type:`button`,onClick:()=>void F(),children:`Remove`}),(0,a.jsx)(`button`,{type:`button`,onClick:()=>void R(),disabled:!j?.configured||E.kind===`probing`,style:{marginLeft:`auto`},children:E.kind===`probing`?`Sending…`:`Send test message`})]}),E.kind===`ok`&&(0,a.jsx)(`p`,{className:`muted small`,style:{marginTop:`0.5rem`},children:`Test sent.`}),E.kind===`fail`&&(0,a.jsxs)(`p`,{className:`error small`,style:{marginTop:`0.5rem`},children:[`Test failed: `,E.error]}),O&&(0,a.jsx)(`p`,{className:`muted small`,style:{marginTop:`0.5rem`},children:O}),(0,a.jsxs)(`details`,{className:`home-section-fold`,style:{marginTop:`1rem`},children:[(0,a.jsx)(`summary`,{className:`home-section-fold-summary`,children:(0,a.jsx)(`strong`,{children:`Recipes`})}),(0,a.jsxs)(`ul`,{className:`muted small`,style:{marginTop:`0.5rem`},children:[(0,a.jsxs)(`li`,{children:[(0,a.jsx)(`strong`,{children:`ntfy.sh (mobile push):`}),` install the ntfy app on your phone, subscribe to a random topic like `,(0,a.jsx)(`code`,{children:`gezel-xyz123`}),`, and paste`,` `,(0,a.jsx)(`code`,{children:`https://ntfy.sh/gezel-xyz123`}),` as the URL. No auth needed; leave the body template blank.`]}),(0,a.jsxs)(`li`,{children:[(0,a.jsx)(`strong`,{children:`Slack:`}),` create an incoming webhook in your workspace, paste the URL. Set the body template to `,(0,a.jsx)(`code`,{children:`{"text":{{message}}}`}),`.`]}),(0,a.jsxs)(`li`,{children:[(0,a.jsx)(`strong`,{children:`Discord:`}),` paste a channel webhook URL. Set the body template to`,` `,(0,a.jsx)(`code`,{children:`{"content":{{message}}}`}),`.`]})]})]})]})})}function u({status:e}){if(!e||!e.configured)return(0,a.jsx)(`p`,{className:`muted small`,style:{marginTop:0},children:`Not configured.`});if(e.ready){let t=e.detail?.url;return(0,a.jsxs)(`p`,{className:`muted small`,style:{marginTop:0},children:[`Active`,t?` — ${t}`:``]})}return(0,a.jsxs)(`p`,{className:`error small`,style:{marginTop:0},children:[`Not ready`,e.lastError?`: ${e.lastError}`:``]})}function d({rows:e,onChange:t}){return(0,a.jsxs)(`div`,{children:[e.map((n,r)=>(0,a.jsxs)(`div`,{className:`new-row`,style:{marginTop:r===0?`0.25rem`:`0.35rem`},children:[(0,a.jsx)(`input`,{type:`text`,placeholder:`Header name`,value:n.key,onChange:i=>{let a=[...e];a[r]={...n,key:i.target.value},t(a)},style:{flex:1}}),(0,a.jsx)(`input`,{type:`text`,placeholder:`Value`,value:n.value,onChange:i=>{let a=[...e];a[r]={...n,value:i.target.value},t(a)},style:{flex:2}}),(0,a.jsx)(`button`,{type:`button`,onClick:()=>t(e.filter((e,t)=>t!==r)),"aria-label":`Remove header`,children:`−`})]},n.id)),(0,a.jsx)(`div`,{style:{marginTop:`0.35rem`},children:(0,a.jsx)(`button`,{type:`button`,onClick:()=>t([...e,s()]),children:`+ Add header`})})]})}export{l as ChannelsSettings};