@bendyline/gezel-service 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/NOTICE.md +3 -3
- package/dist/bin/gezeld.js +8471 -5311
- package/dist/handboek-content/technical/building-connected-apps-with-gezel-app-sdk.md +78 -0
- package/dist/handboek-content/whats-new/{1.26250.md → 1.26251.md} +5 -5
- package/dist/index-store/static-index-worker.js +160 -51
- package/dist/index.d.ts +416 -71
- package/dist/index.js +8465 -5305
- package/dist/memory/embed-worker.js +132 -4
- package/dist/memory/image-embed-worker.js +14 -5
- package/dist/providers/mlx/python/cache_persist.py +52 -8
- package/dist/providers/mlx/python/gezel_mlx_server.py +44 -1
- package/dist/providers/mlx/python/qwen4_ple.py +159 -0
- package/dist/providers/mlx/python/spec_decode.py +73 -31
- package/dist/providers/mlx/python/tool_call_stream.py +10 -2
- package/dist/providers/mlx/python/tool_grammar.py +16 -0
- package/dist/ui/assets/{AmbientDashboardCard-DcVHxEdC.js → AmbientDashboardCard-_xnAQGnk.js} +1 -1
- package/dist/ui/assets/{AudioEngineSettings-BFM2S1mm.js → AudioEngineSettings-CgXgbX0i.js} +1 -1
- package/dist/ui/assets/{BenchmarksView-84-YeULA.js → BenchmarksView-BlExZpYA.js} +1 -1
- package/dist/ui/assets/CatalogBrowser-DYXUZQ_t.js +1 -0
- package/dist/ui/assets/{ChannelsSettings-7NAVUk4k.js → ChannelsSettings-EH27HcqZ.js} +1 -1
- package/dist/ui/assets/ChatTimelineView-Dn1TNyVn.js +7 -0
- package/dist/ui/assets/{ConnectedAppsPanel-CIgF4Q3R.js → ConnectedAppsPanel-BROry-Y0.js} +1 -1
- package/dist/ui/assets/CraftbookEditor-B2RNJnFf.js +1 -0
- package/dist/ui/assets/{CraftbookScriptEditorView-Ck5tzj3Y.js → CraftbookScriptEditorView-B-vySmHP.js} +1 -1
- package/dist/ui/assets/{CraftbookTabContent-BWg7FhK_.js → CraftbookTabContent-BW_2KC89.js} +1 -1
- package/dist/ui/assets/{CraftbookToolsetSetup-EuFOiUzR.js → CraftbookToolsetSetup-J7rEa835.js} +1 -1
- package/dist/ui/assets/{CraftbooksView-BIzQ1VVn.js → CraftbooksView-BjBUWPGF.js} +1 -1
- package/dist/ui/assets/DiffpackReviewView-CD4qJmgT.js +1 -0
- package/dist/ui/assets/DocumentDetail-SYozruTJ.js +1 -0
- package/dist/ui/assets/DocumentsView-DE7eL49Z.js +1 -0
- package/dist/ui/assets/{Ds4Settings-9soZCSeO.js → Ds4Settings-DGzc7JcD.js} +1 -1
- package/dist/ui/assets/{EmbeddedChat-Cce7nxXT.js → EmbeddedChat-D92TaJQ8.js} +1 -1
- package/dist/ui/assets/{FaceRecognitionCard-BVZyOwB8.js → FaceRecognitionCard-CB1Dt9X4.js} +1 -1
- package/dist/ui/assets/FileMapView-kVBG22FU.js +1 -0
- package/dist/ui/assets/FoldersSettings-BWFQU5B4.js +1 -0
- package/dist/ui/assets/GezelDetail-Br4v42Nv.js +1 -0
- package/dist/ui/assets/{GezelJsonEditor-DXXt165-.js → GezelJsonEditor-B9XEiW5Y.js} +1 -1
- package/dist/ui/assets/GezellenView-DheEBAy4.js +1 -0
- package/dist/ui/assets/{GildeUpdatesCard-CtY8mUTA.js → GildeUpdatesCard-BeIYv09f.js} +1 -1
- package/dist/ui/assets/{GithubSignInChip-DT3l6E0Q.js → GithubSignInChip-eEGCe9ar.js} +1 -1
- package/dist/ui/assets/{HandboekMediaProvider-ByJ4NAzz.js → HandboekMediaProvider-D0zcbbpf.js} +1 -1
- package/dist/ui/assets/HandboekView-p0BZT1rH.js +1 -0
- package/dist/ui/assets/{HistoryView-CkinzFEC.js → HistoryView-CKWcWW-Y.js} +1 -1
- package/dist/ui/assets/{HomeView-DNBrQnwy.js → HomeView-b_TT5oV3.js} +1 -1
- package/dist/ui/assets/{ImageEngineSettings-BfM9HSd_.js → ImageEngineSettings-CJfk4OJ4.js} +1 -1
- package/dist/ui/assets/{ImageRecognitionSettings-CaSQu5Br.js → ImageRecognitionSettings-DzbvZk5S.js} +1 -1
- package/dist/ui/assets/{IncompleteDownloads-C36lTCMG.js → IncompleteDownloads-C8_XyP8O.js} +1 -1
- package/dist/ui/assets/{KnowledgeCatalogsCard-CK9bqdf6.js → KnowledgeCatalogsCard-CHopG_j-.js} +1 -1
- package/dist/ui/assets/KnowledgeView-CXNKZUJq.js +1 -0
- package/dist/ui/assets/{LlamaCppSettings-CdNMHBbp.js → LlamaCppSettings-ohcM7kes.js} +1 -1
- package/dist/ui/assets/{MarkdownField-Dugmfr_e.js → MarkdownField-BX0qsaFq.js} +1 -1
- package/dist/ui/assets/{MemoriesTree-CgFqUNEr.js → MemoriesTree-BPj5Rod8.js} +1 -1
- package/dist/ui/assets/{MicrophoneSettings-DzDe9y1q.js → MicrophoneSettings-CWjeYnfI.js} +1 -1
- package/dist/ui/assets/MlxSettings-Dq6dRpcl.js +1 -0
- package/dist/ui/assets/{ModelPicker-BVkJhNAH.js → ModelPicker-0Ue-eEKj.js} +1 -1
- package/dist/ui/assets/NewPathDialog-BhAZm9dp.js +1 -0
- package/dist/ui/assets/{NewScriptDialog-TEAd0KLl.js → NewScriptDialog-DuryIe50.js} +1 -1
- package/dist/ui/assets/NewTaskDialog-BX24flMY.js +2 -0
- package/dist/ui/assets/{OllamaSettings-CPy2vxyZ.js → OllamaSettings-Boj8Nd1G.js} +1 -1
- package/dist/ui/assets/ProjectChat-Dhw_M5bq.js +5 -0
- package/dist/ui/assets/ProjectConnectionsTab-BwpMQNrg.js +1 -0
- package/dist/ui/assets/{ProjectGitStatusBar-BgHZ2ijN.js → ProjectGitStatusBar-BORGYx5l.js} +1 -1
- package/dist/ui/assets/{ProjectGithubView-BV2uTNU0.js → ProjectGithubView-CTP1BOMv.js} +1 -1
- package/dist/ui/assets/{ProjectMailTab-DLtJdXSL.js → ProjectMailTab-qFmAeV3M.js} +1 -1
- package/dist/ui/assets/{ProjectOverviewView-ZMs9nL5N.js → ProjectOverviewView-Cq1FsoaT.js} +1 -1
- package/dist/ui/assets/{ProjectTimeline-CTPcn4Kc.js → ProjectTimeline-Cqae2Z92.js} +1 -1
- package/dist/ui/assets/ProjectsView-D0uJjUB-.js +7 -0
- package/dist/ui/assets/{RecommendedBadge-iUoisQBi.js → RecommendedBadge-CN1jEmSn.js} +1 -1
- package/dist/ui/assets/{RemoteServersPanel-CTVJ0IRh.js → RemoteServersPanel-CMakvCCM.js} +1 -1
- package/dist/ui/assets/{ScriptEditorTabs-CCDFZjdC.js → ScriptEditorTabs-st6dJePd.js} +2 -2
- package/dist/ui/assets/{ScriptEditorView-CergLqKj.js → ScriptEditorView-BkySh57_.js} +2 -2
- package/dist/ui/assets/{ScriptsView-v7ckdhDi.js → ScriptsView-7uPKwjDB.js} +1 -1
- package/dist/ui/assets/{SecurityComplianceSettings-Bd0-66Gs.js → SecurityComplianceSettings-Tsv_pXfy.js} +1 -1
- package/dist/ui/assets/SessionSwitcher-D0fSeeHO.js +1 -0
- package/dist/ui/assets/SettingsView-cli_z8ZW.js +3 -0
- package/dist/ui/assets/{SquisqIntegration-C5l_OPvD.js → SquisqIntegration-BTZ1kBlg.js} +1 -1
- package/dist/ui/assets/{StorageCleanupDialog-3kv9-2mT.js → StorageCleanupDialog-CDBjl8JQ.js} +1 -1
- package/dist/ui/assets/{StorageUsageCard-7sWTrZFa.js → StorageUsageCard-DXY1j0dZ.js} +1 -1
- package/dist/ui/assets/TaskTabContent-C0P681SL.js +1 -0
- package/dist/ui/assets/TasksView-Ddwz10ri.js +1 -0
- package/dist/ui/assets/{TerminalCodeEditor-ChmdzmCz.js → TerminalCodeEditor-BkNQ6QoQ.js} +2 -2
- package/dist/ui/assets/ToolsetsEditor-KVigemfL.js +8 -0
- package/dist/ui/assets/{TransformToolbarButton-gzIxUBH7.js → TransformToolbarButton-8wfJR1bO.js} +2 -2
- package/dist/ui/assets/{UnrecognizedModels-0hptopv6.js → UnrecognizedModels-BzdU1clO.js} +1 -1
- package/dist/ui/assets/{VideoEngineSettings-BdNzCEdR.js → VideoEngineSettings-f79ff57u.js} +1 -1
- package/dist/ui/assets/{WorkspaceIndexPane-DnsOO916.js → WorkspaceIndexPane-fu5V6o1W.js} +1 -1
- package/dist/ui/assets/{api-C0I7spBl.js → api-CmrgM5Rf.js} +1 -1
- package/dist/ui/assets/chat-thread-memory-8MCtb17Q.js +1 -0
- package/dist/ui/assets/{chunk-6ECMNUIP-BvCy0HUI.js → chunk-6ECMNUIP-D5AA6ozp.js} +1 -1
- package/dist/ui/assets/{chunk-A6N6IN3I-ofeM4l8g.js → chunk-A6N6IN3I-BpxihS5H.js} +1 -1
- package/dist/ui/assets/{chunk-ATWVNF7D-CYuW1Yc6.js → chunk-ATWVNF7D-CKIWh7bN.js} +1 -1
- package/dist/ui/assets/{chunk-UBFT2CDQ-FexGDigd.js → chunk-CW24CH7I-BD0FIooX.js} +1 -1
- package/dist/ui/assets/{chunk-DXYWKZ52-zxe8pjH4.js → chunk-DXYWKZ52-DMKPZnpo.js} +1 -1
- package/dist/ui/assets/chunk-IIQYS2YH-BtDJt4Xr.js +1 -0
- package/dist/ui/assets/{chunk-KGWT454C-v5-l6U5m.js → chunk-KGWT454C-DsQOBuLg.js} +1 -1
- package/dist/ui/assets/{chunk-Q77KNJIN-BLuPdsQF.js → chunk-Q77KNJIN-BdWizq9s.js} +1 -1
- package/dist/ui/assets/{chunk-USU6HTKB-B_p-YcDp.js → chunk-USU6HTKB-DyGZplh4.js} +1 -1
- package/dist/ui/assets/{chunk-UXEANVBI-Bt0kX-0Z.js → chunk-UXEANVBI-BUBXvqyE.js} +1 -1
- package/dist/ui/assets/{chunk-O7JILDEF-CqcO1qaI.js → chunk-X7BNDUNI-D14WIvlD.js} +2 -2
- package/dist/ui/assets/{chunk-AE3IUKMM-mZjzzO8Z.js → chunk-ZSU5DJLX-CrjQf-vs.js} +1 -1
- package/dist/ui/assets/{container-BI8hxN1N.js → container-iFj1r6Hk.js} +1 -1
- package/dist/ui/assets/csv-Di411Mv-.js +1 -0
- package/dist/ui/assets/data-Q05qqAp4.js +1 -0
- package/dist/ui/assets/{dist-APSIK7H3.js → dist-1FNFiksd.js} +3 -3
- package/dist/ui/assets/dist-BMZhqfv7.js +2 -0
- package/dist/ui/assets/dist-CE5CbmDb.js +225 -0
- package/dist/ui/assets/doc-BHcGsJZd.js +587 -0
- package/dist/ui/assets/{document-import-DPK4r8Am.js → document-import-B2Ya6sbf.js} +1 -1
- package/dist/ui/assets/{docx-DRLuCTaC.js → docx-B8Pwz5Ih.js} +1 -1
- package/dist/ui/assets/{epub-a0p2Xb1b.js → epub-BQ4g8Q9j.js} +1 -1
- package/dist/ui/assets/{export-options-BqYFyzWx.js → export-options-Dylv69b3.js} +1 -1
- package/dist/ui/assets/file-browser-BLOPfnS0.js +5 -0
- package/dist/ui/assets/{html-BbQNmJ5X.js → html-BnA7qFwq.js} +1 -1
- package/dist/ui/assets/icons-CyM7Cg4E.js +1 -0
- package/dist/ui/assets/index-DW6qHqhU.css +1 -0
- package/dist/ui/assets/index-DivKnJyx.js +36 -0
- package/dist/ui/assets/{mail-link-CWfsP5Aq.js → mail-link-NtlcX5OE.js} +1 -1
- package/dist/ui/assets/{markdown-ryKA_OmY.js → markdown-CLKH_zzl.js} +1 -1
- package/dist/ui/assets/markdown-baseline-0dqv9qbV.js +1 -0
- package/dist/ui/assets/materialize-G4WC5UG3-xq2dcwS8.js +1 -0
- package/dist/ui/assets/{monaco-base-C0VTMpv-.js → monaco-base-BSvdAweA.js} +1 -1
- package/dist/ui/assets/{monaco-setup-CX8q88c5.js → monaco-setup-CT7LZ0o_.js} +1 -1
- package/dist/ui/assets/{new-project-meta-ZmDPGYzC.js → new-project-meta-5Y9Blozr.js} +1 -1
- package/dist/ui/assets/outside-in-Msmhxf_U.js +3 -0
- package/dist/ui/assets/{pdf-BHrygJa5.js → pdf-C4BhW3zg.js} +1 -1
- package/dist/ui/assets/{pending-drafts-27ujtQxX.js → pending-drafts-BD227X9H.js} +1 -1
- package/dist/ui/assets/{poppetje-CfaAvFkE.js → poppetje-DvCJO36y.js} +3 -3
- package/dist/ui/assets/{pptx-nDW64jAN.js → pptx-B6uaM2s7.js} +3 -3
- package/dist/ui/assets/{run-export-86KzLZ7R.js → run-export-TscWwR6y.js} +2 -2
- package/dist/ui/assets/{standalone-source-7QdiNsDW.js → standalone-source-Cw9SF7Zk.js} +1 -1
- package/dist/ui/assets/storage-Cmhlwx70.js +1 -0
- package/dist/ui/assets/styles-BjDaWeMA.css +1 -0
- package/dist/ui/assets/styles-CqO-rmOt.js +554 -0
- package/dist/ui/assets/{terminal-monaco-setup-Bar-sYKd.js → terminal-monaco-setup-me523-j-.js} +1 -1
- package/dist/ui/assets/{transform-CmAXy0Ck.js → transform-DxJCwK68.js} +1 -1
- package/dist/ui/assets/{use-local-model-manager-D1yiurrC.js → use-local-model-manager-8wvk-I-y.js} +1 -1
- package/dist/ui/assets/{useCompactLayout-BDtPQcDh.js → useCompactLayout-cm4E9Vja.js} +0 -0
- package/dist/ui/assets/{useCopilotAvailability-BHOfHrfT.js → useCopilotAvailability-D9hglSH_.js} +1 -1
- package/dist/ui/assets/{useDiffpacks-B0kYhlWQ.js → useDiffpacks-1BN2XJWg.js} +1 -1
- package/dist/ui/assets/{useGitSync-DOt-ODiw.js → useGitSync-7m9YA7h5.js} +1 -1
- package/dist/ui/assets/{useShowWorkInProgressFeatures-BtpredG7.js → useShowWorkInProgressFeatures-D6QOaTUT.js} +1 -1
- package/dist/ui/assets/{useTotalRamBytes-B8NFM27w.js → useTotalRamBytes-Durk383U.js} +1 -1
- package/dist/ui/assets/{xlsx-B_pu1ZvY.js → xlsx-BbHA9bxA.js} +1 -1
- package/dist/ui/index.html +15 -15
- package/package.json +12 -11
- package/dist/ui/assets/CatalogBrowser-7_jHy5Q3.js +0 -1
- package/dist/ui/assets/ChatTimelineView-Cg_kLK_U.js +0 -7
- package/dist/ui/assets/CraftbookEditor-BKAIsnXv.js +0 -1
- package/dist/ui/assets/DiffpackReviewView-B2a3zgE-.js +0 -1
- package/dist/ui/assets/DocumentDetail-GCYhwQqV.js +0 -1
- package/dist/ui/assets/DocumentsView-Cm3RaQ5N.js +0 -1
- package/dist/ui/assets/FileMapView-BKJovLcL.js +0 -1
- package/dist/ui/assets/FoldersSettings-CuJd2JdE.js +0 -1
- package/dist/ui/assets/GezelDetail-D_KIPDhQ.js +0 -1
- package/dist/ui/assets/GezellenView-BOOW1QQU.js +0 -1
- package/dist/ui/assets/HandboekView-gRzJcIbJ.js +0 -1
- package/dist/ui/assets/KnowledgeView-DJ3cJVHA.js +0 -1
- package/dist/ui/assets/MlxSettings-45mBFHbA.js +0 -1
- package/dist/ui/assets/NewTaskDialog-CIXVunZn.js +0 -2
- package/dist/ui/assets/ProjectChat-BiJRweob.js +0 -5
- package/dist/ui/assets/ProjectConnectionsTab-CQgaIzuv.js +0 -1
- package/dist/ui/assets/ProjectsView-BUdR76n6.js +0 -7
- package/dist/ui/assets/SessionSwitcher-BgZqyiRn.js +0 -1
- package/dist/ui/assets/SettingsView-DLhOYiR5.js +0 -3
- package/dist/ui/assets/TaskTabContent-CG2KmfwV.js +0 -1
- package/dist/ui/assets/TasksView-Dy5Ue4zS.js +0 -1
- package/dist/ui/assets/ToolsetsEditor-J9XxQ5Ms.js +0 -8
- package/dist/ui/assets/chat-thread-memory-CI2-giEq.js +0 -1
- package/dist/ui/assets/chunk-IIQYS2YH-DEkyBlHg.js +0 -1
- package/dist/ui/assets/csv-B0D9jJG2.js +0 -1
- package/dist/ui/assets/data-BIL84EaT.js +0 -1
- package/dist/ui/assets/dist-CJqyWK6E.js +0 -2
- package/dist/ui/assets/dist-DOqbRmFj.js +0 -225
- package/dist/ui/assets/doc-C2Ph2FWI.js +0 -584
- package/dist/ui/assets/document-companion-aDThLOwl.js +0 -1
- package/dist/ui/assets/file-browser-DVyWN0LD.js +0 -5
- package/dist/ui/assets/icons-DWaUNQbT.js +0 -1
- package/dist/ui/assets/index-DDu8nyO6.js +0 -34
- package/dist/ui/assets/index-DEDUSiCx.css +0 -1
- package/dist/ui/assets/markdown-baseline-9B52XlX2.js +0 -1
- package/dist/ui/assets/materialize-G4WC5UG3-BlZQe-88.js +0 -1
- package/dist/ui/assets/outside-in-BmIIeMid.js +0 -3
- package/dist/ui/assets/storage-B-vhjyV2.js +0 -1
- package/dist/ui/assets/styles-BvkZd-EV.js +0 -550
- package/dist/ui/assets/styles-IQ4adxWr.css +0 -1
|
@@ -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{Et as r,Qt as i,W as a,fn as o,ht as s,yt as c}from"./dist-DOqbRmFj.js";import{t as l}from"./api-C0I7spBl.js";import{B as u,F as d,I as f,L as p,N as m,P as h,R as g,V as _,z as v}from"./primitives-CWrGZpPI.js";import{t as y}from"./poppetje-CfaAvFkE.js";import{n as b,t as x}from"./relative-time-B2kBaekd.js";import{r as S}from"./model-inventory-ykSm_IT5.js";import{ft as C}from"./doc-C2Ph2FWI.js";import{n as w}from"./chunk-UBFT2CDQ-FexGDigd.js";import"./markdown-ryKA_OmY.js";import{Y as T,z as E}from"./chunk-6ECMNUIP-BvCy0HUI.js";import{n as D}from"./chunk-KGWT454C-v5-l6U5m.js";import{C as O,It as k,Lt as A,M as j,N as M,Rt as N,ft as P,gt as F,ht as I,m as L}from"./index-DDu8nyO6.js";import"./provider-default-BLsHrgzI.js";import{i as R,t as ee}from"./ChatTimelineView-Cg_kLK_U.js";import{n as z}from"./composer-prefill-CbG_i1Rx.js";import{t as te}from"./SessionSwitcher-BgZqyiRn.js";import{c as ne,l as re,o as ie,s as ae,t as B}from"./chat-thread-memory-CI2-giEq.js";import{n as oe}from"./useCompactLayout-BDtPQcDh.js";import{n as se,t as ce}from"./HandboekMediaProvider-ByJ4NAzz.js";import{n as le}from"./useCopilotAvailability-BHOfHrfT.js";import{t as V}from"./security-levels-QFeYFDP-.js";var H=e(t(),1),U=`gezel-first-run-intro`,W=n();function G(e,t,n){let r=e instanceof Error?e.message:String(e),i=e instanceof Error&&`mismatch`in e?e.mismatch:void 0;return i?{kind:`failed`,provider:t,modelId:n,error:r,mismatch:i}:{kind:`failed`,provider:t,modelId:n,error:r}}function ue({config:e,onConfigChanged:t,onModelInstalled:n}){let[r,i]=(0,H.useState)({kind:`hidden`}),[a,o]=(0,H.useState)(!1),[s,c]=(0,H.useState)(!1),[u,d]=(0,H.useState)(!1),f=(0,H.useRef)(!1),p=le(),m=(0,H.useCallback)(async()=>{if(e.provider!==`llama-cpp`&&e.provider!==`mlx`){i({kind:`hidden`});return}let t=e.provider,r=e.defaultModel?.[t];if(!r){i({kind:`hidden`});return}if(e.firstRunInstallError){i({kind:`failed`,provider:t,modelId:r,error:e.firstRunInstallError});return}try{let[e,a,o,s]=await Promise.all([t===`mlx`?l.listMlxModels():l.listLlamaCppModels(),t===`mlx`?l.listMlxActiveInstalls():l.listLlamaCppActiveInstalls(),l.getCatalogItem(`chat-model`,r).catch(()=>null),l.getMemoryProfile().catch(()=>null)]);if(e.models.some(e=>e.id===r)){i({kind:`hidden`}),f.current||(f.current=!0,S(t),n?.());return}let c=be(o,t),u=a.installs.find(e=>e.catalogId===r)??a.installs[0];if(u){i({kind:`installing`,provider:t,modelId:u.catalogId,sizeBytes:u.catalogId===r?c:null,progress:{bytesWritten:u.bytesWritten,totalBytes:u.totalBytes,phase:u.phase}});return}i({kind:`needs-download`,provider:t,modelId:r,sizeBytes:c,memory:s})}catch{}},[e.provider,e.defaultModel,e.firstRunInstallError,n]);(0,H.useEffect)(()=>{if(r.kind!==`installing`&&r.kind!==`hidden`)return;m();let e=setInterval(()=>void m(),3e3);return()=>clearInterval(e)},[m,r.kind]);let h=(0,H.useCallback)(async(e,t,n=!1)=>{let r=null,i=null,a=n?{skipSha:!0}:void 0;if(e===`mlx`?await l.installMlxModel(t,e=>{e.type===`error`&&(r=e.error,e.mismatch&&(i=e.mismatch))},void 0,a):await l.installLlamaCppModel(t,e=>{e.type===`error`&&(r=e.error,e.mismatch&&(i=e.mismatch))},void 0,a),r){let e=Error(r);throw i&&(e.mismatch=i),e}},[]),g=(0,H.useCallback)(async()=>{if(r.kind===`needs-download`){d(!0);try{i({kind:`installing`,provider:r.provider,modelId:r.modelId,sizeBytes:r.sizeBytes,progress:null}),await h(r.provider,r.modelId),await m()}catch(e){i(G(e,r.provider,r.modelId))}finally{d(!1)}}},[r,m,h]),_=(0,H.useCallback)(async()=>{if(r.kind===`failed`){o(!0);try{t(await l.updateConfig({firstRunInstallError:null})),await h(r.provider,r.modelId),await m()}catch(e){i(G(e,r.provider,r.modelId))}finally{o(!1)}}},[r,t,m,h]),v=(0,H.useCallback)(async()=>{if(!(r.kind!==`failed`||!r.mismatch)){o(!0);try{t(await l.updateConfig({firstRunInstallError:null})),i({kind:`installing`,provider:r.provider,modelId:r.modelId,sizeBytes:null,progress:null}),await h(r.provider,r.modelId,!0),await m()}catch(e){i(G(e,r.provider,r.modelId))}finally{o(!1)}}},[r,t,m,h]),y=(0,H.useCallback)(async()=>{if(p?.available===!1){window.dispatchEvent(new CustomEvent(`gezel:navigate`,{detail:{view:`settings`,section:`copilot`}})),i({kind:`hidden`});return}t(await l.updateConfig({provider:`copilot`})),i({kind:`hidden`})},[t,p]),b=(0,H.useCallback)(async()=>{if(r.kind===`failed`){c(!0);try{let n=r.modelId.replace(/-mlx$/,``);t(await l.updateConfig({provider:`llama-cpp`,defaultModel:{...e.defaultModel,"llama-cpp":n},firstRunInstallError:null})),await h(`llama-cpp`,n),await m()}catch(e){i(G(e,r.provider,r.modelId))}finally{c(!1)}}},[r,e.defaultModel,t,m,h]);if(r.kind===`hidden`)return null;if(r.kind===`needs-download`){let e=q(r.modelId),t=r.sizeBytes?ye(r.sizeBytes):null,n=t?`Download recommended model (${e}, ${t})`:`Download recommended model (${e})`;return(0,W.jsxs)(`output`,{className:`first-run-banner first-run-banner-installing`,children:[(0,W.jsx)(`div`,{className:`first-run-banner-head`,children:(0,W.jsx)(`strong`,{children:`Set up your first on-device model`})}),(0,W.jsxs)(`p`,{className:`first-run-banner-body`,children:[_e(r.memory),` We've picked one we think will work well on this device — click below to download it. Usually `,ve(r.sizeBytes),` on fast Internet, and you only have to do this once.`]}),(0,W.jsx)(`div`,{className:`first-run-banner-actions`,children:(0,W.jsx)(`button`,{type:`button`,className:`first-run-banner-btn first-run-banner-btn-primary`,onClick:()=>void g(),disabled:u,children:u?`Starting…`:n})})]})}if(r.kind===`installing`)return(0,W.jsxs)(`output`,{className:`first-run-banner first-run-banner-installing`,children:[(0,W.jsxs)(`div`,{className:`first-run-banner-head`,children:[(0,W.jsx)(`span`,{className:`first-run-banner-spinner`,"aria-hidden":!0}),(0,W.jsxs)(`strong`,{children:[`Downloading `,q(r.modelId),` for first-time setup`]})]}),(0,W.jsxs)(`p`,{className:`first-run-banner-body`,children:[`Gezel is downloading a local AI model so your conversations run on this device. Usually`,` `,ve(r.sizeBytes),` on fast Internet. You can start working with gezellen as soon as this finishes.`]}),(0,W.jsx)(fe,{progress:r.progress}),(0,W.jsx)(de,{})]});let x=r.provider===`mlx`,C=r.mismatch!=null,w=C?`${q(r.modelId)} is newer on Hugging Face than the version Gezel knows about`:`Couldn't download ${q(r.modelId)}`,T=C?(0,W.jsxs)(W.Fragment,{children:[(0,W.jsxs)(`p`,{className:`first-run-banner-body`,children:[`The file `,(0,W.jsx)(`code`,{children:r.mismatch?.file}),` on Hugging Face has changed since this version of Gezel was published, so its checksum doesn't match what we expected. The new file is probably fine — Hugging Face routinely re-publishes models with small upstream fixes — but we can't guarantee it.`]}),(0,W.jsx)(`p`,{className:`first-run-banner-body`,children:`You can download it anyway and start using it now, or wait for a Gezel update with a refreshed catalog.`})]}):(0,W.jsx)(`p`,{className:`first-run-banner-body`,children:r.error});return(0,W.jsxs)(`output`,{className:`first-run-banner first-run-banner-failed`,children:[(0,W.jsx)(`div`,{className:`first-run-banner-head`,children:(0,W.jsx)(`strong`,{children:w})}),T,(0,W.jsxs)(`div`,{className:`first-run-banner-actions`,children:[C&&(0,W.jsx)(`button`,{type:`button`,className:`first-run-banner-btn first-run-banner-btn-primary`,onClick:()=>void v(),disabled:a||s,title:`Download the current file from Hugging Face without verifying it against the catalog's pinned checksum.`,children:a?`Downloading…`:`Download anyway`}),(0,W.jsx)(`button`,{type:`button`,className:C?`first-run-banner-btn`:`first-run-banner-btn first-run-banner-btn-primary`,onClick:()=>void _(),disabled:a||s,children:a&&!C?`Retrying…`:`Retry download`}),x&&(0,W.jsx)(`button`,{type:`button`,className:`first-run-banner-btn`,onClick:()=>void b(),disabled:a||s,title:`Use the llama engine instead. Works without Python; slightly slower than MLX on Apple Silicon.`,children:s?`Switching…`:`Switch to llama`}),(0,W.jsx)(`button`,{type:`button`,className:`first-run-banner-btn`,onClick:()=>void y(),disabled:a||s,children:p?.available===!1?`Set up GitHub Copilot`:`Use GitHub Copilot instead`}),!C&&(0,W.jsx)(P,{className:`first-run-banner-btn`,report:{surface:`model-download`,message:r.error,detail:{code:`first-run-install-failed`,engine:r.provider}}})]})]})}function de(){return(0,W.jsxs)(`p`,{className:`first-run-banner-wait`,children:[`Nothing to do until this finishes — a good moment to read`,` `,(0,W.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:()=>{document.getElementById(U)?.scrollIntoView({behavior:`smooth`,block:`start`})},children:`what gezel is and how to work with your crew →`})]})}function fe({progress:e}){let t=e!=null&&e.totalBytes>0&&e.phase===`downloading`,n=t?Math.min(100,Math.round(e.bytesWritten/e.totalBytes*100)):0,r=e?e.phase===`verifying`?`Checking download…`:e.phase===`extracting-metadata`?`Reading model info…`:t?`${K(e.bytesWritten)} of ${K(e.totalBytes)} · ${n}%`:e.bytesWritten>0?`${K(e.bytesWritten)} downloaded`:`Starting…`:`Starting…`;return(0,W.jsxs)(`div`,{className:`first-run-banner-progress`,children:[(0,W.jsx)(`div`,{className:t?`first-run-banner-bar`:`first-run-banner-bar first-run-banner-bar-indeterminate`,children:(0,W.jsx)(`div`,{className:`first-run-banner-bar-fill`,style:t?{width:`${n}%`}:void 0})}),(0,W.jsx)(`span`,{className:`first-run-banner-progress-label`,children:r})]})}function K(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`}var pe=25e9,me=13e9,he=5e9,ge=8*1024**3;function _e(e){return e?e.source===`gpu-integrated`||e.source===`system-ram-fallback`||e.source!==`darwin-unified`&&e.gpuMemoryKind!==`unified`&&(e.gpuVramBytes==null||e.gpuVramBytes<ge)?`This device is best suited to small AI models.`:`You can run ${e.usableBytes>=pe?`large`:e.usableBytes>=me?`medium-size`:e.usableBytes>=he?`small-size`:`tiny`} AI models${e.source===`darwin-unified`||e.gpuMemoryKind===`discrete`||e.gpuMemoryKind===`unified`?` comfortably`:``} on this device.`:`You can run AI models on this device.`}function ve(e){if(!e)return`2–5 minutes`;let t=e/1024**3;return`~${Math.max(5,Math.ceil(t/5)*5)} minutes`}function ye(e){let t=e/1024**3;if(t>=1)return`~${t.toFixed(1)} GB`;let n=e/1024**2;return`~${Math.round(n)} MB`}function be(e,t){if(!e)return null;let n=e.manifest;return!n||n.kind!==`chat-model`?null:(t===`mlx`?n.mlx?.approxSizeBytes:n.llamaCpp?.approxSizeBytes)??n.approxSizeBytes??null}function q(e){switch(e){case`gemma4-e2b-q4`:case`gemma4-e2b`:case`gemma4-e2b-mlx`:return`Gemma 4 (E2B)`;case`gemma4-e4b-q4`:case`gemma4-e4b`:case`gemma4-e4b-mlx`:return`Gemma 4 (E4B)`;case`gemma4-12b-q4`:case`gemma4-12b-q8`:return`Gemma 4 (12B)`;case`gemma4-26b-q4`:case`gemma4-26b`:case`gemma4-26b-mlx`:return`Gemma 4 (26B-A4B MoE)`;case`gemma4-31b-q4`:return`Gemma 4 (31B)`;case`qwen3.6-27b-q4`:case`qwen3.6-27b-q8`:return`Qwen 3.6 (27B)`;case`qwen3.6-35b-a3b-q4`:case`qwen3.6-35b-a3b-q8`:return`Qwen 3.6 (35B-A3B MoE)`;default:return e}}function J(e){return e==null?``:e>=1024**3?`~${(e/1024**3).toFixed(1)} GB`:`~${Math.round(e/1024**2)} MB`}function Y(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 xe(e,t,n){let i=null;for(let a of e){let e=a.manifest;c(e)&&r(t,n===`image`?{minRamGB:e.minRamGB}:{minVramGB:e.minVramGB})&&(i==null||(e.recoScore??0)>(i.recoScore??0))&&(i=e)}return i}function Se(e){let t=null;for(let n of e)c(n)&&(t==null||(n.recoScore??0)>(t.recoScore??0))&&(t=n);return t}function Ce(e){let t=(e.approxSizeBytes??0)+(e.auxiliaryFiles??[]).reduce((e,t)=>e+(t.sizeBytes??0),0);return t>0?t:null}function X(e,t){return e.models.some(e=>e.id===t)}function we(){let[e,t]=(0,H.useState)(null),[n,r]=(0,H.useState)({}),[i,a]=(0,H.useState)(!1),[o,s]=(0,H.useState)(new Set),[c,y]=(0,H.useState)(null),[b,x]=(0,H.useState)(!1),[S,C]=(0,H.useState)(null),w=(0,H.useRef)(new Map),T=(0,H.useCallback)((e,t)=>{r(n=>({...n,[e]:t}))},[]),E=(0,H.useCallback)(async(e,t)=>{if(w.current.has(e.key))return;let n=new AbortController;w.current.set(e.key,n);let r=null;try{if(await t(t=>{if(t.type===`progress`){let n=t.bytesWrittenAll??t.bytesWritten,r=t.totalBytesAll??t.totalBytes;r&&n!=null&&T(e.key,{status:`installing`,pct:Math.min(100,Math.round(n/r*100)),bytesWritten:n,totalBytes:r})}else t.type===`error`&&(r=t.error??`download failed`)},n.signal),r)throw Error(r);T(e.key,{status:`done`,pct:100})}catch(t){if(n.signal.aborted)return;T(e.key,{status:`error`,pct:null,error:t instanceof Error?t.message:String(t)})}finally{w.current.get(e.key)===n&&w.current.delete(e.key)}},[T]);(0,H.useEffect)(()=>{let e=!1,n={models:[]};return(async()=>{try{let[i,a,o,s,c,u,d,f,p,m,h,g]=await Promise.all([l.getMemoryProfile(),l.listCatalogItems(`image-model`),l.listCatalogItems(`video-model`),l.listAudioCatalog(),l.listInstalledImageModels().catch(()=>n),l.listInstalledVideoModels().catch(()=>n),l.listInstalledSttModels().catch(()=>n),l.listInstalledTtsModels().catch(()=>n),l.listActiveImagePulls().catch(()=>({pulls:[]})),l.listActiveVideoPulls().catch(()=>({pulls:[]})),l.listRecognitionCatalog().catch(()=>({models:[]})),l.listInstalledRecognitionModels().catch(()=>n)]);if(e)return;let _={platform:i.platform,gpuVramBytes:i.gpuVramBytes,totalRamBytes:i.totalRamBytes,usableBytes:i.usableBytes,...i.budgetBytes===void 0?{}:{budgetBytes:i.budgetBytes}},v=[],y=xe(a.items,_,`image`);if(y){let e=p.pulls.find(e=>e.id===y.id&&!e.finished);v.push({key:`image`,id:y.id,what:`image model`,name:y.name,sizeBytes:Ce(y),installed:X(c,y.id),start:(e,t)=>l.pullImageModel(y.id,e,t),cancel:()=>l.cancelImagePull(y.id),...e?{resume:{bytesWritten:e.bytesWritten,totalBytes:e.totalBytes,subscribe:(e,t)=>l.subscribeImagePull(y.id,e,t)}}:{}})}let b=[...h.models].filter(e=>!e.approxSizeBytes||e.approxSizeBytes<=_.usableBytes*.5).sort((e,t)=>t.recoScore-e.recoScore)[0];b&&v.push({key:`recognition`,id:b.id,what:`image reading`,name:b.name,sizeBytes:b.approxSizeBytes,installed:X(g,b.id),start:(e,t)=>l.pullRecognitionModel(b.id,e,t)});let x=Se(s.stt);x&&v.push({key:`stt`,id:x.id,what:`speech-to-text`,name:x.name,sizeBytes:x.approxSizeBytes,installed:X(d,x.id),start:(e,t)=>l.pullAudioModel(`stt`,x.id,e,t)});let S=Se(s.tts);S&&v.push({key:`tts`,id:S.id,what:`text-to-speech`,name:S.name,sizeBytes:S.approxSizeBytes,installed:X(f,S.id),start:(e,t)=>l.pullAudioModel(`tts`,S.id,e,t)});let C=xe(o.items,_,`video`);if(C){let e=m.pulls.find(e=>e.id===C.id&&!e.finished);v.push({key:`video`,id:C.id,what:`video model`,name:C.name,sizeBytes:C.approxSizeBytes??null,installed:X(u,C.id),start:(e,t)=>l.pullVideoModel(C.id,e,t),cancel:()=>l.cancelVideoPull(C.id),...e?{resume:{bytesWritten:e.bytesWritten,totalBytes:e.totalBytes,subscribe:(e,t)=>l.subscribeVideoPull(C.id,e,t)}}:{}})}t(v);let w={};for(let e of v)if(e.installed)w[e.key]={status:`done`,pct:100};else if(e.resume){let{bytesWritten:t,totalBytes:n}=e.resume;w[e.key]={status:`installing`,pct:n>0?Math.min(100,Math.round(t/n*100)):null,bytesWritten:t,totalBytes:n}}r(w);for(let e of v)!e.installed&&e.resume&&E(e,e.resume.subscribe)}catch{e||t([])}})(),()=>{e=!0}},[E]);let D=(0,H.useCallback)(async e=>{r(t=>{let n=t[e.key]?.status;return n===`installing`||n===`done`?t:{...t,[e.key]:{status:`installing`,pct:null}}}),await E(e,e.start)},[E]),O=(0,H.useCallback)(async e=>{w.current.get(e.key)?.abort();try{await e.cancel?.(),T(e.key,{status:`idle`,pct:null})}catch(t){T(e.key,{status:`error`,pct:null,error:t instanceof Error?t.message:String(t)})}},[T]),k=(0,H.useMemo)(()=>(e??[]).filter(e=>{let t=n[e.key]?.status??`idle`;return t===`idle`||t===`error`}),[e,n]),A=(0,H.useMemo)(()=>k.filter(e=>o.has(e.key)),[k,o]),j=(0,H.useMemo)(()=>A.reduce((e,t)=>e+(t.sizeBytes??0),0),[A]),M=(0,H.useMemo)(()=>A.filter(e=>e.sizeBytes==null).length,[A]),N=(0,H.useMemo)(()=>k.filter(e=>e.key!==`video`).reduce((e,t)=>e+(t.sizeBytes??0),0),[k]),P=(0,H.useCallback)(()=>{let e=k.filter(e=>e.key!==`video`);s(new Set(e.map(e=>e.key))),y(null),C(null),x(e.length>0),a(!0)},[k]);(0,H.useEffect)(()=>{if(!i||A.length===0){y(null),x(!1),C(null);return}if(j<=0){y(null),x(!1),C(`Gezel couldn't determine this model's size. Its installer will check space again before writing.`);return}let e=!1;return y(null),C(null),x(!0),l.checkModelDownloadSpace({sizeBytes:Math.ceil(j)}).then(t=>{e||y(t)}).catch(t=>{e||C(`Gezel couldn't measure free space (${t instanceof Error?t.message:String(t)}). Each installer will check again before writing.`)}).finally(()=>{e||x(!1)}),()=>{e=!0}},[i,j,A.length]);let F=(0,H.useCallback)(()=>{for(let e of A)D(e);a(!1)},[D,A]);if((0,H.useEffect)(()=>{let e=w.current;return()=>{for(let t of e.values())t.abort()}},[]),!e||e.length===0)return null;let I=k.length>0,L=A.length>0&&!b&&(c===null||c.ok);return(0,W.jsxs)(`section`,{className:`setup-section home-media-section`,children:[I&&(0,W.jsxs)(W.Fragment,{children:[(0,W.jsxs)(`button`,{type:`button`,className:`gz-link-button home-media-plan-link`,onClick:P,children:[`Also download the optional media models (image + speech)`,N>0?` · ${J(N)}`:``]}),(0,W.jsx)(`p`,{className:`muted small home-media-plan-hint`,children:`Lets your gezellen create images, read pictures, and speak. You review the list — and can add video — before anything downloads.`})]}),(0,W.jsx)(`div`,{className:`home-media-downloads`,children:e.map(e=>{let t=n[e.key]??{status:`idle`,pct:null};return t.status===`idle`?null:(0,W.jsx)(`div`,{className:`home-media-row`,children:t.status===`done`?(0,W.jsxs)(`span`,{className:`home-probe home-probe-ok small`,children:[`✓ `,e.name,` on device`]}):t.status===`installing`?(0,W.jsxs)(`div`,{className:`home-media-progress`,children:[(0,W.jsxs)(`div`,{className:`home-media-progress-heading`,children:[(0,W.jsxs)(`span`,{className:`muted small`,children:[`Downloading `,e.name,`…`]}),(0,W.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:()=>void O(e),"aria-label":`Cancel ${e.name} download`,children:`Cancel`})]}),(0,W.jsx)(`div`,{className:t.pct==null?`first-run-banner-bar first-run-banner-bar-indeterminate`:`first-run-banner-bar`,children:(0,W.jsx)(`div`,{className:`first-run-banner-bar-fill`,style:t.pct==null?void 0:{width:`${t.pct}%`}})}),(0,W.jsx)(`span`,{className:`first-run-banner-progress-label`,children:t.bytesWritten!=null&&t.totalBytes?`${Y(t.bytesWritten)} of ${Y(t.totalBytes)} · ${t.pct??0}%`:`Starting…`})]}):(0,W.jsxs)(`span`,{className:`home-probe home-probe-fail small`,children:[`✗ `,e.name,`: `,t.error]})},e.key)})}),(0,W.jsx)(u,{open:i,onOpenChange:e=>{a(e),e||s(new Set)},children:(0,W.jsxs)(v,{children:[(0,W.jsx)(g,{}),(0,W.jsxs)(f,{className:`home-media-plan-dialog`,children:[(0,W.jsx)(_,{asChild:!0,children:(0,W.jsx)(`h3`,{children:`Review model downloads`})}),(0,W.jsx)(p,{asChild:!0,children:(0,W.jsx)(`p`,{className:`muted small`,children:`Nothing starts until you confirm this plan. Downloads go to Gezel model storage and remain visible below while they run.`})}),(0,W.jsxs)(`fieldset`,{className:`home-media-plan-list`,children:[(0,W.jsx)(`legend`,{className:`sr-only`,children:`Models to download`}),k.map(e=>(0,W.jsxs)(`label`,{className:`home-media-plan-item`,children:[(0,W.jsx)(`input`,{type:`checkbox`,checked:o.has(e.key),onChange:t=>{s(n=>{let r=new Set(n);return t.target.checked?r.add(e.key):r.delete(e.key),r}),y(null),C(null),x(!0)}}),(0,W.jsxs)(`span`,{className:`home-media-plan-copy`,children:[(0,W.jsxs)(`span`,{className:`home-media-plan-name`,children:[e.name,e.key===`video`&&(0,W.jsx)(`span`,{className:`home-media-plan-large`,children:`Large download`})]}),(0,W.jsxs)(`span`,{className:`muted small`,children:[e.what,e.sizeBytes?` · ${J(e.sizeBytes)}`:` · size unavailable`]})]})]},e.key))]}),(0,W.jsxs)(`div`,{className:`home-media-plan-summary`,"aria-live":`polite`,children:[(0,W.jsx)(`strong`,{children:A.length===0?`Select at least one model.`:`${A.length} model${A.length===1?``:`s`} · ${j>0?J(j):`size unavailable`}${M>0?` + ${M} unknown`:``}`}),b?(0,W.jsx)(`span`,{className:`muted small`,children:`Checking free space…`}):c?.known&&c.ok?(0,W.jsxs)(`span`,{className:`muted small`,children:[Y(c.freeBytes),` free in `,c.storageLocation,`; this plan needs `,Y(c.requiredBytes),` including safety headroom.`]}):c?.known&&!c.ok?(0,W.jsxs)(`span`,{className:`error small`,children:[`Not enough free space: this plan needs `,Y(c.requiredBytes),`, but`,` `,c.storageLocation,` has `,Y(c.freeBytes),` free.`]}):c&&!c.known?(0,W.jsx)(`span`,{className:`muted small`,children:`Free space could not be measured. Each installer will check again before writing.`}):S?(0,W.jsx)(`span`,{className:`muted small`,children:S}):null]}),(0,W.jsxs)(h,{children:[(0,W.jsx)(d,{asChild:!0,children:(0,W.jsx)(`button`,{type:`button`,children:`Cancel`})}),(0,W.jsx)(m,{asChild:!0,children:(0,W.jsx)(`button`,{type:`button`,className:`primary`,disabled:!L,onClick:F,children:b?`Checking space…`:A.length>0?`Download ${A.length} model${A.length===1?``:`s`}`:`Choose models`})})]})]})]})})]})}var Z=`welcome`,Te=`gezel:handboek:article`;function Q(e){try{window.localStorage.setItem(Te,e)}catch{}window.dispatchEvent(new CustomEvent(`gezel:navigate`,{detail:{view:`handboek`}}))}function Ee({variant:e=`toggle`}={}){let t=e===`stacked`,[n,r]=(0,H.useState)(null),[i,a]=(0,H.useState)(!1),[o,s]=(0,H.useState)(`doc`),c=I()===`light`?j:void 0;(0,H.useEffect)(()=>{let e=!0;return l.getHandboekArticle(Z).then(t=>{e&&(t&&typeof t.markdown==`string`?r(t):a(!0))}).catch(()=>e&&a(!0)),()=>{e=!1}},[]);let u=(0,H.useMemo)(()=>n?ce(n.figures??[]):null,[n]),d=(0,H.useRef)(u);(0,H.useEffect)(()=>(d.current=u,()=>d.current?.dispose?.()),[u]);let f=(0,H.useMemo)(()=>n?se(n.markdown):null,[n]),p=(0,H.useMemo)(()=>{if(!f)return null;try{return C(w(f))}catch{return null}},[f]),m=(0,H.useMemo)(()=>{if(!n||!f)return null;try{return C(w(f),{articleId:n.id,defaultDuration:n.defaultDuration??6})}catch{return null}},[n,f]);return i?(0,W.jsx)(`p`,{children:(0,W.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:()=>Q(Z),"data-testid":`home-intro-handboek-fallback`,children:`Open the Handboek for an introduction to gezel →`})}):!p||!u?(0,W.jsx)(`p`,{className:`muted`,"aria-live":`polite`,children:`Loading the Handboek…`}):(0,W.jsxs)(`div`,{className:`home-intro-article`,"data-testid":`home-intro-article`,children:[(0,W.jsxs)(`div`,{className:`home-intro-article-controls`,children:[(0,W.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:()=>Q(Z),title:`Read this article in the Handboek`,children:`Open in Handboek →`}),!t&&(0,W.jsxs)(`div`,{className:`gz-tray handboek-mode-tray`,role:`radiogroup`,"aria-label":`View as`,children:[(0,W.jsx)(`button`,{type:`button`,role:`radio`,"aria-checked":o===`doc`,className:o===`doc`?`gz-key gz-key-active`:`gz-key`,onClick:()=>s(`doc`),children:`Read`}),(0,W.jsx)(`button`,{type:`button`,role:`radio`,"aria-checked":o===`video`,className:o===`video`?`gz-key gz-key-active`:`gz-key`,onClick:()=>s(`video`),children:`Watch`})]})]}),(0,W.jsxs)(T.Provider,{value:u,children:[(t||o===`video`)&&(0,W.jsx)(`div`,{className:`home-intro-page home-intro-page-player`,children:(0,W.jsx)(`div`,{className:`home-intro-player`,children:(0,W.jsx)(D,{doc:m??p,theme:M,displayMode:`video`,audioMode:`synthetic`,captionsEnabled:!0,captionStyle:`social`,autoPlay:!t,showControls:!0,showScrubber:!0})})}),(t||o===`doc`)&&(0,W.jsx)(`div`,{className:`home-intro-page`,children:(0,W.jsx)(`div`,{className:`home-intro-doc`,onClickCapture:e=>{let t=e.target.closest(`a`);if(!t)return;let n=t.getAttribute(`href`);!n||/^[a-z][a-z0-9+.-]*:/i.test(n)||n.startsWith(`//`)||n.startsWith(`#`)||(e.preventDefault(),e.stopPropagation(),Q(n.split(/[?#]/)[0].replace(/\.md$/,``).replace(/^(\.\.?\/)+/,``).split(`/`).pop()||Z))},children:(0,W.jsx)(E,{doc:p,className:`gezel-article-view`,theme:M,surface:c,thinMargins:!0,imageDisplayMode:`inline`,showCover:!1})})})]})]})}function De(e){return e<12?`Good morning`:e<18?`Good afternoon`:`Good evening`}function Oe(e,t=Date.now()){if(!e)return null;let n=t-Date.parse(e.generatedAt);return Number.isFinite(n)&&n<1296e5?e:null}function ke(e,t=Date.now()){return b(e,{now:t})}function Ae(e,t){let n=new Set(t.map(e=>e.id)),r=(e?.recentTabs??[]).filter(e=>e.kind===`project`).slice().sort((e,t)=>t.at-e.at);for(let e of r)if(e.kind===`project`&&n.has(e.id))return e.id;let i=t.find(e=>e.id!=="default");return i?i.id:t[0]?.id??`default`}function je({review:e}){let t=e.reports[0],n=e.reports.slice(1),[r,i]=(0,H.useState)(null),[a,o]=(0,H.useState)(null);(0,H.useEffect)(()=>{if(i(null),o(null),!t)return;let e=!1;return l.readProjectArtifact(t.projectId,t.path).then(t=>{e||i(t.content)}).catch(t=>{e||o(t.message)}),()=>{e=!0}},[t]);let s=(0,H.useMemo)(()=>{if(r===null)return null;try{return C(w(r),{articleId:`night-review`})}catch{return null}},[r]),c=(0,H.useMemo)(()=>t?oe({projectId:t.projectId,reportPath:t.path}):void 0,[t]),u=e.reports.reduce((e,t)=>e+t.actionCounts.suggested,0),d=e.diffpacks;return(0,W.jsxs)(`div`,{className:`home-workshop-status-report`,role:`tabpanel`,"data-testid":`night-review-panel`,children:[(0,W.jsxs)(`p`,{className:`home-workshop-night-summary`,children:[e.tasksCompleted.length,` task`,e.tasksCompleted.length===1?``:`s`,` finished overnight, `,e.reports.length,` report`,e.reports.length===1?``:`s`,` written`,d.length>0?`, ${d.length} change proposal${d.length===1?``:`s`} waiting`:``,u>0?` — ${u} suggested action${u===1?``:`s`} to review.`:`.`]}),d.length>0&&(0,W.jsx)(`div`,{className:`home-workshop-night-reports`,children:d.map(e=>(0,W.jsxs)(`button`,{type:`button`,className:`home-workshop-night-report-row`,onClick:()=>window.dispatchEvent(new CustomEvent(`gezel:open-tab`,{detail:{kind:`project`,id:e.projectId,activate:!0}})),children:[(0,W.jsx)(`span`,{className:`home-workshop-night-report-title`,children:e.title}),(0,W.jsxs)(`span`,{className:`muted small`,children:[e.projectName,` · `,e.fileCount,` file`,e.fileCount===1?``:`s`,` · +`,e.additions,` −`,e.deletions,e.drifted?` · out of date`:``]})]},`${e.projectId}:${e.packId}`))}),t&&(0,W.jsx)(`div`,{className:`home-workshop-status-body`,children:s?(0,W.jsx)(E,{doc:s,theme:M,thinMargins:!0,imageDisplayMode:`thumbnail`,fenceRenderers:c}):a?(0,W.jsx)(`p`,{className:`error small`,children:a}):(0,W.jsxs)(`p`,{className:`muted small`,children:[`Loading `,t.title,`…`]})}),n.length>0&&(0,W.jsx)(`div`,{className:`home-workshop-night-reports`,children:n.map(e=>(0,W.jsxs)(`button`,{type:`button`,className:`home-workshop-night-report-row`,onClick:()=>window.dispatchEvent(new CustomEvent(`gezel:open-tab`,{detail:{kind:`project`,id:e.projectId,activate:!0}})),children:[(0,W.jsx)(`span`,{className:`home-workshop-night-report-title`,children:e.title}),(0,W.jsxs)(`span`,{className:`muted small`,children:[e.projectName,e.actionCounts.suggested>0?` · ${e.actionCounts.suggested} action${e.actionCounts.suggested===1?``:`s`} to review`:``]})]},`${e.projectId}:${e.path}`))}),(0,W.jsx)(`div`,{className:`home-workshop-status-foot`,children:(0,W.jsxs)(`span`,{className:`home-workshop-status-meta`,title:x(e.windowEnd),children:[`Night window ended `,ke(e.windowEnd)]})})]})}function Me({report:e,running:t,onRefresh:n}){let r=(0,H.useMemo)(()=>{try{return C(w(e.report),{articleId:`meester-status`})}catch{return null}},[e.report]);return(0,W.jsxs)(`div`,{className:`home-workshop-status-report`,role:`tabpanel`,"data-testid":`status-report-panel`,children:[(0,W.jsx)(`div`,{className:`home-workshop-status-body`,children:r?(0,W.jsx)(E,{doc:r,theme:M,thinMargins:!0,imageDisplayMode:`thumbnail`}):(0,W.jsx)(`p`,{children:e.report})}),(0,W.jsxs)(`div`,{className:`home-workshop-status-foot`,children:[(0,W.jsxs)(`span`,{className:`home-workshop-status-meta`,title:x(e.generatedAt),children:[`Written `,ke(e.generatedAt)]}),n&&(0,W.jsx)(`button`,{type:`button`,className:`home-workshop-tip-action`,onClick:n,disabled:t,children:t?`Meester is writing…`:`Write a fresh report`})]})]})}function Ne({size:e=18,color:t=`var(--sage-deep)`}){return(0,W.jsxs)(`svg`,{width:e,height:e,viewBox:`0 0 24 24`,fill:`none`,stroke:t,strokeWidth:1.7,strokeLinecap:`round`,strokeLinejoin:`round`,"aria-hidden":`true`,children:[(0,W.jsx)(`path`,{d:`M12 21 V11`}),(0,W.jsx)(`path`,{d:`M12 14.4 C8.5 14.4 6.4 11.9 6.4 8.4 C9.9 8.4 12 10.9 12 14`,fill:t,fillOpacity:.18}),(0,W.jsx)(`path`,{d:`M12 12.4 C15.5 12.4 17.6 9.9 17.6 6.4 C14.1 6.4 12 8.9 12 12`,fill:t,fillOpacity:.18})]})}var Pe=[{body:(0,W.jsx)(W.Fragment,{children:`Most of getting great work out of a gezel is shaping its brief. Trim a gezel’s standing orders and it’ll stop over-explaining.`}),action:`Train a gezel`,view:`gezels`},{body:(0,W.jsx)(W.Fragment,{children:`Teach a gezel once and it sticks — stamp today’s steps into a routine it can run on its own.`}),action:`Save a routine`,view:`scripts`},{body:(0,W.jsx)(W.Fragment,{children:`Your crew can grow with your work. A second specialist lets the first stay deep on one project.`}),action:`Hire a gezel`,view:`gezels`},{body:(0,W.jsxs)(W.Fragment,{children:[`Local models come first — cloud and the web are opt-in and `,(0,W.jsx)(`em`,{children:`always marked`}),`. Adjust your providers any time.`]}),action:`Open settings`,view:`settings`},{body:(0,W.jsx)(W.Fragment,{children:`Hand the meester a half-baked idea and they’ll shape it into something your crew can actually start on.`}),action:`See your projects`,view:`projects`}];function Fe({onNavigate:e}){let[t,n]=(0,H.useState)(0),r=Pe[t%Pe.length];return(0,W.jsxs)(`div`,{className:`home-workshop-tip`,children:[(0,W.jsx)(`span`,{className:`home-workshop-tip-sprout`,children:(0,W.jsx)(Ne,{size:18})}),(0,W.jsxs)(`div`,{style:{flex:1,minWidth:0},children:[(0,W.jsxs)(`div`,{className:`home-workshop-tip-label-row`,children:[(0,W.jsx)(`span`,{className:`home-workshop-eyebrow home-workshop-tip-label`,children:`Tip of the day`}),(0,W.jsx)(`button`,{type:`button`,className:`home-workshop-tip-cycle`,title:`Another tip`,"aria-label":`Show another tip`,onClick:()=>n(e=>e+1),children:`↻`})]}),(0,W.jsxs)(`div`,{className:`home-workshop-tip-body`,children:[r.body,` `,(0,W.jsxs)(`button`,{type:`button`,className:`home-workshop-tip-action`,onClick:()=>e?.(r.view),children:[r.action,` →`]})]})]})]})}function Ie({direction:e}){return(0,W.jsx)(`svg`,{"aria-hidden":`true`,width:`18`,height:`18`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2.4`,strokeLinecap:`round`,strokeLinejoin:`round`,children:e===`up`?(0,W.jsx)(`path`,{d:`M6 15 L12 9 L18 15`}):(0,W.jsx)(`path`,{d:`M6 9 L12 15 L18 9`})})}function Le({chips:e}){return(0,W.jsx)(W.Fragment,{children:e.map(e=>(0,W.jsxs)(`span`,{className:`home-workshop-chip`,children:[(0,W.jsx)(`span`,{className:`home-workshop-chip-dot`,style:{background:e.dot}}),e.label]},e.label))})}function Re({statusReport:e,greeting:t,onCtaClick:n}){return e?e.cta&&n?(0,W.jsx)(`h1`,{className:`home-workshop-headline`,children:(0,W.jsx)(`button`,{type:`button`,className:`home-workshop-headline-cta`,onClick:n,title:e.cta.label,children:e.headline})}):(0,W.jsx)(`h1`,{className:`home-workshop-headline`,children:e.headline}):(0,W.jsxs)(`h1`,{className:`home-workshop-headline`,children:[t,`.`]})}function ze({chips:e,meesterName:t,meesterPoppetje:n,meesterIcon:r,meesterIconOverride:i,collapsed:a,onToggleCollapse:o,tab:s,onTabChange:c,statusReport:l,statusRunning:u,onRunStatusReport:d,nightReview:f,onNavigate:p}){let m=A(),h=new Date,g=h.getHours(),_=De(g),v=l??null,b=()=>{let e=v?.cta?.target;e&&(e.kind===`view`?p?.(e.view):e.kind===`project`?window.dispatchEvent(new CustomEvent(`gezel:open-tab`,{detail:{kind:`project`,id:e.projectId,activate:!0}})):window.dispatchEvent(new CustomEvent(`gezel:open-tab`,{detail:{kind:`task`,ref:e.taskRef,activate:!0}})))},x=`${h.toLocaleDateString(void 0,{weekday:`long`})} ${g<12?`morning`:g<18?`afternoon`:`evening`} · ${h.toLocaleTimeString(void 0,{hour:`2-digit`,minute:`2-digit`,hour12:!1})}`;return a?(0,W.jsxs)(`div`,{className:`home-workshop-greeting-collapsed`,children:[(0,W.jsx)(Re,{statusReport:v,greeting:_,onCtaClick:b}),(0,W.jsx)(`div`,{className:`home-workshop-vrule`}),(0,W.jsx)(`div`,{style:{display:`flex`,gap:8,flexWrap:`wrap`,flex:1,minWidth:0},children:(0,W.jsx)(Le,{chips:e})}),(0,W.jsx)(`button`,{type:`button`,className:`home-workshop-collapse-btn`,onClick:o,title:`Expand the greeting`,"aria-label":`Expand the greeting`,children:(0,W.jsx)(Ie,{direction:`down`})})]}):(0,W.jsxs)(`div`,{className:`home-workshop-greeting`,"data-testid":`greeting-band`,children:[(0,W.jsxs)(`div`,{className:`home-workshop-greeting-top`,children:[(0,W.jsxs)(`div`,{className:`home-workshop-tabs`,role:`tablist`,"aria-label":`Home view`,children:[(0,W.jsx)(`button`,{type:`button`,role:`tab`,"aria-selected":s===`greeting`,className:`home-workshop-tab${s===`greeting`?` is-active`:``}`,onClick:()=>c(`greeting`),children:x}),v&&(0,W.jsx)(`button`,{type:`button`,role:`tab`,"aria-selected":s===`status`,className:`home-workshop-tab${s===`status`?` is-active`:``}`,onClick:()=>c(`status`),children:`Status report`}),f&&(0,W.jsx)(`button`,{type:`button`,role:`tab`,"aria-selected":s===`night`,className:`home-workshop-tab${s===`night`?` is-active`:``}`,onClick:()=>c(`night`),children:`Last night`}),(0,W.jsx)(`button`,{type:`button`,role:`tab`,"aria-selected":s===`tour`,className:`home-workshop-tab${s===`tour`?` is-active`:``}`,onClick:()=>c(`tour`),children:`New here? What is gezel`})]}),(0,W.jsx)(`button`,{type:`button`,className:`home-workshop-collapse-btn`,onClick:o,title:`Collapse to a single row`,"aria-label":`Collapse the greeting`,children:(0,W.jsx)(Ie,{direction:`up`})})]}),(0,W.jsxs)(`div`,{className:`home-workshop-greeting-cols`,children:[(0,W.jsxs)(`div`,{className:`home-workshop-greeting-left`,children:[s===`status`&&v?(0,W.jsx)(Me,{report:v,running:u??!1,...d?{onRefresh:d}:{}}):s===`night`&&f?(0,W.jsx)(je,{review:f}):s===`tour`?(0,W.jsx)(`div`,{className:`home-workshop-tour-inline`,role:`tabpanel`,children:(0,W.jsx)(Ee,{})}):(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(Re,{statusReport:v,greeting:_,onCtaClick:b}),(0,W.jsx)(Fe,{onNavigate:p})]}),(0,W.jsx)(`div`,{className:`home-workshop-chips`,children:(0,W.jsx)(Le,{chips:e})})]}),m&&(0,W.jsx)(`div`,{className:`home-workshop-greeting-right`,children:(0,W.jsxs)(`div`,{className:`home-workshop-figure`,children:[n?(0,W.jsx)(y,{poppetje:n,variant:`full`,size:64,title:`${t} poppetje`}):(0,W.jsx)(k,{poppetje:null,svg:r,iconOverride:i,name:t,size:64,variant:`full`}),(0,W.jsx)(`div`,{className:`home-workshop-shelf`}),(0,W.jsxs)(`div`,{className:`home-workshop-figure-label`,children:[t,` `,(0,W.jsx)(`em`,{children:`- Meester`})]})]})})]})]})}function Be({activeSessionId:e,onFocusSession:t,onToolActivity:n,onArtifactReference:r,onArtifactSeen:i,onWorkspaceReference:a,onWorkspaceSeen:o,onOpenReference:s,onTaskReference:c,emptyPlaceholder:u,emptyContent:d}){let f=(0,H.useCallback)(e=>l.listGlobalTimeline(e),[]),p=(0,H.useCallback)(()=>l.allEventsUrl(),[]);return(0,W.jsx)(ee,{scopeKey:`global`,activeSessionId:e,onFocusSession:t,onToolActivity:n,onArtifactReference:r,onArtifactSeen:i,onWorkspaceReference:a,onWorkspaceSeen:o,onOpenReference:s,...c?{onTaskReference:c}:{},emptyPlaceholder:u,emptyContent:d,loadTimeline:f,streamUrl:p,showProjectName:!0})}var Ve=[`I want to start a project — can you help me work out what it needs?`,`What kind of gezellen can you bring on, and what are they good at?`,`Here is what I am working on today. Where should I start?`];function He({meesterName:e,meesterIcon:t,meesterPoppetje:n,meesterIconOverride:r,projectId:i}){return(0,W.jsxs)(`div`,{className:`meester-greeting`,children:[(0,W.jsx)(`div`,{className:`meester-greeting-figure`,children:(0,W.jsx)(k,{svg:t??null,poppetje:n??null,iconOverride:r===!0,name:e,size:64})}),(0,W.jsxs)(`div`,{className:`meester-greeting-body`,children:[(0,W.jsxs)(`h3`,{className:`meester-greeting-title`,children:[`Hello — I'm `,e,`, your meester.`]}),(0,W.jsx)(`p`,{className:`meester-greeting-lede`,children:`I'm the one you talk to first. Tell me what you're trying to get done and I'll work out which gezellen you need, bring them on, and set the project up around them. You can also just talk things through with me.`}),(0,W.jsx)(`fieldset`,{className:`meester-greeting-openers gz-tray`,"aria-label":`Ways to start`,children:Ve.map(e=>(0,W.jsx)(`button`,{type:`button`,className:`gz-key meester-greeting-opener`,onClick:()=>z(i,e),children:e},e))})]})]})}function Ue({meesterGezelId:e,meesterName:t,meesterIcon:n,meesterPoppetje:r,meesterIconOverride:i,emptyPlaceholder:o}){let s=ie(B),[c,u]=(0,H.useState)(s?.sessionId??``),[d,f]=(0,H.useState)(``),[p,m]=(0,H.useState)(0),[h,g]=(0,H.useState)([]),[_,v]=(0,H.useState)(s?.gezelId||e),[y,b]=(0,H.useState)(s?.projectId||`default`),x=O(),S=(0,H.useRef)(e);(0,H.useEffect)(()=>{S.current!==e&&(S.current=e,u(``),v(e),b(`default`)),l.listGezels().then(e=>g(e.gezels)).catch(()=>g([]))},[e]),(0,H.useEffect)(()=>{ae(B,{gezelId:_,projectId:y,sessionId:c})},[_,y,c]);let C=h.find(e=>e.id===_),w=_||e,T=C?a({name:C.name,roleBasedName:C.roleBasedName},x):w===e?t:w,E=C?C.role:w===e?`Meester`:void 0,D=C?C.icon??null:w===e?n:null,k=C?C.poppetje??null:w===e?r:null,A=C?C.iconOverride??!1:w===e&&i,j=(0,H.useMemo)(()=>ne({role:w===e?`meester`:`other`,gezelName:T,gezelGender:C?.gender,fixedFunctionTool:C?.fixedFunction?.tool}),[w,T,e,C?.gender,C?.fixedFunction?.tool]);return(0,W.jsx)(`section`,{className:`home-workshop-conversation`,"data-testid":`meester-chat`,children:(0,W.jsx)(re,{chatKey:`meester:global`,projectId:y,skillsProjectId:y==="default"?void 0:y,children:({onToolActivity:a,onArtifactReference:s,onArtifactSeen:l,onWorkspaceReference:g,onWorkspaceSeen:x,recentReferences:S,onOpenReference:O,onTaskReference:M})=>(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(Be,{activeSessionId:c||void 0,onFocusSession:(e,t,n)=>{v(t),b(n),u(e)},onToolActivity:a,onArtifactReference:s,onArtifactSeen:l,onWorkspaceReference:g,onWorkspaceSeen:x,onOpenReference:O,onTaskReference:M,emptyPlaceholder:o,emptyContent:!_||_===e?(0,W.jsx)(He,{meesterName:t,meesterIcon:n,meesterPoppetje:r,meesterIconOverride:i,projectId:y}):void 0}),(0,W.jsx)(R,{gezelId:w,gezelName:T,gezelRoleBasedName:C?.roleBasedName,gezelRole:E,gezelIcon:D,gezelPoppetje:k,gezelIconOverride:A,recipientGezels:h,onPrimaryRecipientChange:e=>{v(e),b(`default`),u(``)},projectId:y,sessionId:c||void 0,onSessionCreated:e=>{u(e),m(e=>e+1)},onToolActivity:a,recentReferences:S,onOpenReference:O,placeholder:j,draftScope:`meester`,draftId:d||void 0,onDraftIdChange:e=>f(e??``),belowAddressLine:(0,W.jsx)(te,{gezelId:w,projectId:y,sessionId:c||void 0,onSessionIdChange:e=>u(e??``),refreshKey:p,activeDraftId:d||void 0,onDraftSelect:e=>f(e??``),draftScope:`meester`})})]})})})}function We({config:e,projects:t,meesterGezelId:n,meesterName:r,meesterIcon:i,meesterPoppetje:a,meesterIconOverride:o,banner:s,onNavigate:c}){let[u,d]=(0,H.useState)(e?.homeGreetingCollapsed??!1),f=(0,H.useRef)(!1),p=(0,H.useRef)(!1);(0,H.useEffect)(()=>{f.current||p.current||!e||(f.current=!0,d(e.homeGreetingCollapsed===!0))},[e]);let m=(0,H.useCallback)(()=>{p.current=!0,d(e=>{let t=!e;return l.updateConfig({homeGreetingCollapsed:t}).catch(()=>{}),t})},[]),[h,g]=(0,H.useState)(`greeting`),[_,v]=(0,H.useState)(null),[y,b]=(0,H.useState)(!1),[x,S]=(0,H.useState)([]),[C,w]=(0,H.useState)([]),T=(0,H.useMemo)(()=>Ae(e,t),[e,t]),E=(0,H.useCallback)(()=>{l.listQuestions({pending:!0}).then(e=>w(e.questions??[])).catch(()=>{})},[]);(0,H.useEffect)(()=>{E()},[E]);let D=(0,H.useRef)(T);D.current=T;let O=(0,H.useCallback)(()=>{let e=D.current;if(!e){S([]);return}l.listProjectTasks(e).then(t=>{D.current===e&&S(t.tasks??[])}).catch(()=>{})},[]);(0,H.useEffect)(()=>{if(!T){S([]);return}O()},[T,O]);let k=(0,H.useCallback)(()=>{l.getMeesterStatus().then(e=>{v(e),b(e.running)}).catch(()=>{})},[]);(0,H.useEffect)(()=>{k();let e=new AbortController;return(async()=>{try{for await(let t of N({url:l.allEventsUrl(),headers:l.authHeader(),signal:e.signal,fetch:l.getFetch()})){let e=t.event;if(e.type===`question_asked`||e.type===`question_answered`){E();continue}if(e.type===`task_event`){O();continue}e.type===`meester_status`&&(e.state===`started`?b(!0):(b(!1),k()))}}catch{}})(),()=>e.abort()},[k,E,O]);let A=(0,H.useMemo)(()=>Oe(_?.report),[_]),[j,M]=(0,H.useState)(null);(0,H.useEffect)(()=>{let e=!1;return l.getNightShiftReview().then(t=>{if(e)return;let n=Date.parse(t.windowEnd),r=Number.isFinite(n)&&Date.now()-n<720*60*1e3,i=t.tasksCompleted.length>0||t.reports.length>0;M(r&&i?t:null)}).catch(()=>{}),()=>{e=!0}},[]);let P=(0,H.useCallback)(()=>{b(!0),l.runMeesterStatus().catch(()=>b(!1))},[]),F=(0,H.useMemo)(()=>x.filter(e=>e.status!==`canceled`),[x]),I=(0,H.useMemo)(()=>C.filter(e=>!e.answer),[C]).length+F.filter(e=>e.assignee.kind===`user`&&e.status!==`complete`).length,L=[];return I>0&&L.push({dot:`var(--ochre)`,label:`${I} waiting on you`}),(0,W.jsxs)(`div`,{className:`home-workshop`,"data-testid":`home-workshop`,children:[s,(0,W.jsx)(ze,{chips:L,meesterName:r,meesterPoppetje:a,meesterIcon:i,meesterIconOverride:o,collapsed:u,onToggleCollapse:m,tab:h,onTabChange:g,statusReport:A,statusRunning:y,onRunStatusReport:P,nightReview:j,onNavigate:c}),(0,W.jsx)(`div`,{className:`home-workshop-body`,children:(0,W.jsx)(`div`,{className:`home-workshop-main`,children:n?(0,W.jsx)(Ue,{meesterGezelId:n,meesterName:r,meesterIcon:i,meesterPoppetje:a,meesterIconOverride:o}):(0,W.jsxs)(`section`,{className:`home-workshop-conversation`,children:[(0,W.jsx)(`div`,{className:`home-workshop-eyebrow home-workshop-conversation-eyebrow`,children:`Talk to your meester`}),(0,W.jsxs)(`p`,{className:`home-workshop-rail-empty`,children:[`No meester is designated yet. Pick one in`,` `,(0,W.jsx)(`button`,{type:`button`,className:`home-workshop-tip-action`,onClick:()=>c?.(`settings`),children:`Settings`}),`.`]})]})})})]})}function Ge(e){return e===`darwin`?`mlx`:`llama-cpp`}var Ke=2e4,$=720;function qe({platform:e,onNavigate:t}){let[n,r]=(0,H.useState)(null),[i,c]=(0,H.useState)(null),[u,d]=(0,H.useState)([]),[f,p]=(0,H.useState)(void 0),[m,h]=(0,H.useState)(void 0),[g,_]=(0,H.useState)(null),[v,b]=(0,H.useState)(null),[x,S]=(0,H.useState)(!1),C=O(),w=f?a({name:f,roleBasedName:m},C):void 0,[T,E]=(0,H.useState)({kind:`idle`}),[D,k]=(0,H.useState)(null);(0,H.useEffect)(()=>{let e=!1,t=0,n=()=>{l.getConfig().then(t=>{e||r(t)}).catch(()=>{e||t>=40||(t+=1,window.setTimeout(n,500))})};return n(),l.health().then(c).catch(()=>{}),l.listProjects().then(e=>d(e.projects)).catch(()=>{}),()=>{e=!0}},[]),(0,H.useEffect)(()=>{let e=n?.meesterGezelId;if(!e){p(void 0),h(void 0),_(null),b(null),S(!1);return}l.listGezels().then(t=>{let n=t.gezels.find(t=>t.id===e);p(n?.name),h(n?.roleBasedName),_(n?.icon??null),b(n?.poppetje??null),S(n?.iconOverride??!1)}).catch(()=>{})},[n?.meesterGezelId]);let A=n?.provider??`llama-cpp`,j=A===`copilot`?!!n?.hasGithubToken:A!==`openai`||!!n?.hasOpenaiApiKey;(0,H.useEffect)(()=>{n&&T.kind===`idle`&&(A===`copilot`||A===`ollama`||j)&&P(A)},[n?.provider,n?.hasGithubToken,n?.hasOpenaiApiKey,n?.ollamaBaseUrl]);let M=(0,H.useRef)(null),N=(0,H.useCallback)(()=>{M.current&&=(clearTimeout(M.current),null)},[]),P=(0,H.useCallback)(async(e,t=0)=>{N(),E(t>0?{kind:`probing`,retryAttempt:t,retryMax:$}:{kind:`probing`});try{let r=await l.testProvider(e);if(r.ok){E({kind:`ok`,modelCount:r.modelCount});return}if(e===`ollama`&&n?.autoStartOllama!==!1&&t<$){M.current=setTimeout(()=>{P(e,t+1)},Ke),E({kind:`probing`,retryAttempt:t+1,retryMax:$});return}E({kind:`fail`,error:r.error})}catch(e){E({kind:`fail`,error:e.message})}},[N,n?.autoStartOllama]);(0,H.useEffect)(()=>()=>N(),[N]);let I=s(A)&&T.kind===`ok`&&T.modelCount===0;(0,H.useEffect)(()=>{T.kind===`ok`?k(!I):T.kind===`fail`&&k(!1)},[T.kind,I]);let R=A===`copilot`||A===`ollama`||j;(0,H.useEffect)(()=>{n&&!R&&k(!1)},[n,R]),(0,H.useEffect)(()=>{if(D!==null)return;let e=window.setTimeout(()=>k(!1),3e4);return()=>window.clearTimeout(e)},[D]),(0,H.useEffect)(()=>{D!==null&&window.dispatchEvent(new CustomEvent(`gezel:first-run`,{detail:{firstRun:!D}}))},[D]);let ee=(0,H.useCallback)(()=>{P(A)},[P,A]),z=(0,W.jsx)(Je,{state:L(),platform:e});return!n||D===null?(0,W.jsx)(`div`,{className:`home-view home-view-loading`,"aria-busy":`true`,children:(0,W.jsxs)(`div`,{className:`home-loading-placeholder`,"aria-live":`polite`,children:[(0,W.jsx)(`span`,{className:`home-loading-spinner`,"aria-hidden":!0}),(0,W.jsx)(`span`,{children:`Loading…`})]})}):D?(0,W.jsx)(We,{config:n,projects:u,meesterGezelId:n?.meesterGezelId,meesterName:w??`your meester`,meesterIcon:g,meesterPoppetje:v,meesterIconOverride:x,banner:z,onNavigate:t}):(0,W.jsxs)(`div`,{className:`home-view`,children:[z,(0,W.jsxs)(`div`,{className:`home-firstrun-columns`,children:[(0,W.jsxs)(`div`,{className:`home-firstrun-main`,children:[(0,W.jsx)(`h1`,{className:`home-firstrun-heading`,children:`First run setup`}),(0,W.jsx)(`p`,{className:`home-firstrun-lede muted`,children:`Gezel chats through a local AI model that runs privately on this device — download the recommended one to get started.`}),(0,W.jsxs)(`div`,{className:`home-firstrun-body`,children:[n&&(0,W.jsx)(ue,{config:n,onConfigChanged:r,onModelInstalled:ee}),(0,W.jsx)(we,{}),(0,W.jsxs)(`section`,{className:`setup-section home-ondevice-link`,children:[(0,W.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:()=>{let e=Ge(i?.platform)===`mlx`?`mlx`:`llamaCpp`;F(e),window.dispatchEvent(new CustomEvent(`gezel:navigate`,{detail:{view:`settings`,section:e}}))},children:`Manage AI models in Settings →`}),(0,W.jsx)(`p`,{className:`muted small`,style:{marginTop:`0.35rem`,marginBottom:0},children:`Browse other local models, or connect a cloud provider (GitHub Copilot, OpenAI, …).`})]}),(0,W.jsx)(Ye,{level:n?.securityPolicy?.level,onChange:async e=>{try{let t=await l.updateConfig({securityPolicy:o(e)});r(t)}catch{}}}),(0,W.jsxs)(`section`,{className:`setup-section`,children:[(0,W.jsx)(`h3`,{children:`Preferences`}),(0,W.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:`0.75rem`},children:[(0,W.jsxs)(`label`,{className:`debug-toggle`,style:{marginTop:0},children:[(0,W.jsx)(`input`,{type:`checkbox`,checked:n?.roleBasedNameOnlyMode!==!0&&n?.showPoppetjes!==!1,onChange:async e=>{let t=e.target.checked;try{let e=await l.updateConfig({roleBasedNameOnlyMode:!t,showPoppetjes:t});r(e),window.dispatchEvent(new CustomEvent(`gezel:config-updated`,{detail:e}))}catch{}}}),(0,W.jsxs)(`span`,{children:[`Show gezel names and poppetjes`,f?` (e.g., ${f}, your meester)`:``]})]}),v&&(0,W.jsx)(`div`,{className:`gezel-icon`,style:{width:36,height:36},title:f?`${f}'s poppetje`:`example poppetje`,children:(0,W.jsx)(`div`,{className:`gezel-icon-poppetje`,children:(0,W.jsx)(y,{poppetje:v,variant:`headshot`,size:36})})})]}),(0,W.jsx)(`p`,{className:`muted small`,style:{marginTop:`0.35rem`,marginBottom:0},children:`Adjustable any time in Settings.`})]})]})]}),(0,W.jsx)(`aside`,{className:`home-firstrun-tutorial`,id:U,"aria-label":`What is gezel?`,children:(0,W.jsx)(Ee,{variant:`stacked`})})]})]})}function Je({state:e,platform:t}){let[n,r]=(0,H.useState)(!1),[a,o]=(0,H.useState)(null);return!e||e.kind!==`available`&&e.kind!==`ready`?null:e.kind===`available`?(0,W.jsxs)(`output`,{className:`app-fallback-banner`,"data-testid":`update-banner`,children:[(0,W.jsxs)(`strong`,{children:[`Gezel `,e.version,` is available.`]}),(0,W.jsx)(`span`,{children:`Linux updates are installed manually. Open the GitHub release, verify its SLSA build provenance, then install the package for your distribution.`}),(0,W.jsx)(`div`,{className:`app-fallback-banner-actions`,children:(0,W.jsx)(`a`,{className:`app-update-release-link`,href:i(e.version),children:`Open release and verification steps`})})]}):(0,W.jsxs)(`output`,{className:`app-fallback-banner`,"data-testid":`update-banner`,children:[(0,W.jsxs)(`strong`,{children:[`Gezel `,e.version,` is ready to install.`]}),(0,W.jsx)(`span`,{children:t===`darwin`?`Installing replaces Gezel and its background service together, so macOS will ask for an administrator password.`:`The update will install automatically after you quit Gezel completely. Closing the window may leave Gezel running in the system tray.`}),(0,W.jsx)(`div`,{className:`app-fallback-banner-actions`,children:(0,W.jsx)(`button`,{type:`button`,className:`primary`,disabled:n,onClick:()=>{r(!0),o(null),window.__GEZEL__?.update?.install().then(e=>{e.ok||(o(e.error),r(!1))})},children:n?t===`darwin`?`Opening installer…`:`Restarting…`:t===`darwin`?`Open installer`:`Install and restart`})}),a&&(0,W.jsxs)(`details`,{open:!0,children:[(0,W.jsx)(`summary`,{children:`Could not open the installer`}),(0,W.jsx)(`p`,{children:a})]})]})}function Ye({level:e,onChange:t}){let n=e??`lockdown`,r=V.find(e=>e.id===n);return(0,W.jsxs)(`section`,{className:`setup-section engagement-mode-${n}`,children:[(0,W.jsx)(`h3`,{children:`Security & compliance`}),(0,W.jsx)(`p`,{className:`muted`,style:{marginTop:0,marginBottom:`0.5rem`},children:`How much should gezellen be allowed to do? Pick a starting posture — you can fine-tune every capability later in Settings → Security & Compliance.`}),(0,W.jsx)(`div`,{className:`engagement-mode-switch gz-tray gz-tray--described`,role:`radiogroup`,"aria-label":`Security posture`,children:V.map(e=>(0,W.jsxs)(`button`,{type:`button`,role:`radio`,"aria-checked":n===e.id,className:`gz-key${n===e.id?` gz-key-active`:``}`,onClick:()=>void t(e.id),children:[e.label,e.recommended?` ★`:``]},e.id))}),(0,W.jsx)(`p`,{className:`engagement-mode-description gz-tray-description`,"aria-live":`polite`,children:r?(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(`strong`,{children:r.label}),` — `,r.description]}):(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(`strong`,{children:`Custom`}),` — capability switches were adjusted individually. Fine-tune in Settings → Security & Compliance.`]})})]})}export{qe as HomeView};
|
|
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,Dt as i,W as a,bt as o,gt as s,pn as c}from"./dist-CE5CbmDb.js";import{t as l}from"./api-CmrgM5Rf.js";import{B as u,F as d,I as f,L as p,N as m,P as h,R as g,V as _,z as v}from"./primitives-CWrGZpPI.js";import{t as y}from"./poppetje-DvCJO36y.js";import{n as b,t as x}from"./relative-time-B2kBaekd.js";import{r as S}from"./model-inventory-ykSm_IT5.js";import{ft as C}from"./doc-BHcGsJZd.js";import{n as w}from"./chunk-CW24CH7I-BD0FIooX.js";import"./markdown-CLKH_zzl.js";import{Y as T,z as E}from"./chunk-6ECMNUIP-D5AA6ozp.js";import{n as D}from"./chunk-KGWT454C-DsQOBuLg.js";import{B as O,Ct as k,Gt as A,Kt as j,V as M,Wt as N,bt as P,j as F,wt as I,x as L}from"./index-DivKnJyx.js";import"./provider-default-BLsHrgzI.js";import{i as R,t as z}from"./ChatTimelineView-Dn1TNyVn.js";import{n as B}from"./composer-prefill-CbG_i1Rx.js";import{t as ee}from"./SessionSwitcher-D0fSeeHO.js";import{c as te,l as ne,o as re,s as ie,t as ae}from"./chat-thread-memory-8MCtb17Q.js";import{n as oe}from"./useCompactLayout-cm4E9Vja.js";import{n as se,t as ce}from"./HandboekMediaProvider-D0zcbbpf.js";import{n as le}from"./useCopilotAvailability-D9hglSH_.js";import{t as V}from"./security-levels-QFeYFDP-.js";var H=e(t(),1),U=`gezel-first-run-intro`,W=n();function G(e,t,n){let r=e instanceof Error?e.message:String(e),i=e instanceof Error&&`mismatch`in e?e.mismatch:void 0;return i?{kind:`failed`,provider:t,modelId:n,error:r,mismatch:i}:{kind:`failed`,provider:t,modelId:n,error:r}}function ue({config:e,onConfigChanged:t,onModelInstalled:n}){let[r,i]=(0,H.useState)({kind:`hidden`}),[a,o]=(0,H.useState)(!1),[s,c]=(0,H.useState)(!1),[u,d]=(0,H.useState)(!1),f=(0,H.useRef)(!1),p=le(),m=(0,H.useCallback)(async()=>{if(e.provider!==`llama-cpp`&&e.provider!==`mlx`){i({kind:`hidden`});return}let t=e.provider,r=e.defaultModel?.[t];if(!r){i({kind:`hidden`});return}if(e.firstRunInstallError){i({kind:`failed`,provider:t,modelId:r,error:e.firstRunInstallError});return}try{let[e,a,o,s]=await Promise.all([t===`mlx`?l.listMlxModels():l.listLlamaCppModels(),t===`mlx`?l.listMlxActiveInstalls():l.listLlamaCppActiveInstalls(),l.getCatalogItem(`chat-model`,r).catch(()=>null),l.getMemoryProfile().catch(()=>null)]);if(e.models.some(e=>e.id===r)){i({kind:`hidden`}),f.current||(f.current=!0,S(t),n?.());return}let c=be(o,t),u=a.installs.find(e=>e.catalogId===r)??a.installs[0];if(u){i({kind:`installing`,provider:t,modelId:u.catalogId,sizeBytes:u.catalogId===r?c:null,progress:{bytesWritten:u.bytesWritten,totalBytes:u.totalBytes,phase:u.phase}});return}i({kind:`needs-download`,provider:t,modelId:r,sizeBytes:c,memory:s})}catch{}},[e.provider,e.defaultModel,e.firstRunInstallError,n]);(0,H.useEffect)(()=>{if(r.kind!==`installing`&&r.kind!==`hidden`)return;m();let e=setInterval(()=>void m(),3e3);return()=>clearInterval(e)},[m,r.kind]);let h=(0,H.useCallback)(async(e,t,n=!1)=>{let r=null,i=null,a=n?{skipSha:!0}:void 0;if(e===`mlx`?await l.installMlxModel(t,e=>{e.type===`error`&&(r=e.error,e.mismatch&&(i=e.mismatch))},void 0,a):await l.installLlamaCppModel(t,e=>{e.type===`error`&&(r=e.error,e.mismatch&&(i=e.mismatch))},void 0,a),r){let e=Error(r);throw i&&(e.mismatch=i),e}},[]),g=(0,H.useCallback)(async()=>{if(r.kind===`needs-download`){d(!0);try{i({kind:`installing`,provider:r.provider,modelId:r.modelId,sizeBytes:r.sizeBytes,progress:null}),await h(r.provider,r.modelId),await m()}catch(e){i(G(e,r.provider,r.modelId))}finally{d(!1)}}},[r,m,h]),_=(0,H.useCallback)(async()=>{if(r.kind===`failed`){o(!0);try{t(await l.updateConfig({firstRunInstallError:null})),await h(r.provider,r.modelId),await m()}catch(e){i(G(e,r.provider,r.modelId))}finally{o(!1)}}},[r,t,m,h]),v=(0,H.useCallback)(async()=>{if(!(r.kind!==`failed`||!r.mismatch)){o(!0);try{t(await l.updateConfig({firstRunInstallError:null})),i({kind:`installing`,provider:r.provider,modelId:r.modelId,sizeBytes:null,progress:null}),await h(r.provider,r.modelId,!0),await m()}catch(e){i(G(e,r.provider,r.modelId))}finally{o(!1)}}},[r,t,m,h]),y=(0,H.useCallback)(async()=>{if(p?.available===!1){window.dispatchEvent(new CustomEvent(`gezel:navigate`,{detail:{view:`settings`,section:`copilot`}})),i({kind:`hidden`});return}t(await l.updateConfig({provider:`copilot`})),i({kind:`hidden`})},[t,p]),b=(0,H.useCallback)(async()=>{if(r.kind===`failed`){c(!0);try{let n=r.modelId.replace(/-mlx$/,``);t(await l.updateConfig({provider:`llama-cpp`,defaultModel:{...e.defaultModel,"llama-cpp":n},firstRunInstallError:null})),await h(`llama-cpp`,n),await m()}catch(e){i(G(e,r.provider,r.modelId))}finally{c(!1)}}},[r,e.defaultModel,t,m,h]);if(r.kind===`hidden`)return null;if(r.kind===`needs-download`){let e=q(r.modelId),t=r.sizeBytes?ye(r.sizeBytes):null,n=t?`Download recommended model (${e}, ${t})`:`Download recommended model (${e})`;return(0,W.jsxs)(`output`,{className:`first-run-banner first-run-banner-installing`,children:[(0,W.jsx)(`div`,{className:`first-run-banner-head`,children:(0,W.jsx)(`strong`,{children:`Set up your first on-device model`})}),(0,W.jsxs)(`p`,{className:`first-run-banner-body`,children:[_e(r.memory),` We've picked one we think will work well on this device — click below to download it. Usually `,ve(r.sizeBytes),` on fast Internet, and you only have to do this once.`]}),(0,W.jsx)(`div`,{className:`first-run-banner-actions`,children:(0,W.jsx)(`button`,{type:`button`,className:`first-run-banner-btn first-run-banner-btn-primary`,onClick:()=>void g(),disabled:u,children:u?`Starting…`:n})})]})}if(r.kind===`installing`)return(0,W.jsxs)(`output`,{className:`first-run-banner first-run-banner-installing`,children:[(0,W.jsxs)(`div`,{className:`first-run-banner-head`,children:[(0,W.jsx)(`span`,{className:`first-run-banner-spinner`,"aria-hidden":!0}),(0,W.jsxs)(`strong`,{children:[`Downloading `,q(r.modelId),` for first-time setup`]})]}),(0,W.jsxs)(`p`,{className:`first-run-banner-body`,children:[`Gezel is downloading a local AI model so your conversations run on this device. Usually`,` `,ve(r.sizeBytes),` on fast Internet. You can start working with gezellen as soon as this finishes.`]}),(0,W.jsx)(fe,{progress:r.progress}),(0,W.jsx)(de,{})]});let x=r.provider===`mlx`,C=r.mismatch!=null,w=C?`${q(r.modelId)} is newer on Hugging Face than the version Gezel knows about`:`Couldn't download ${q(r.modelId)}`,T=C?(0,W.jsxs)(W.Fragment,{children:[(0,W.jsxs)(`p`,{className:`first-run-banner-body`,children:[`The file `,(0,W.jsx)(`code`,{children:r.mismatch?.file}),` on Hugging Face has changed since this version of Gezel was published, so its checksum doesn't match what we expected. The new file is probably fine — Hugging Face routinely re-publishes models with small upstream fixes — but we can't guarantee it.`]}),(0,W.jsx)(`p`,{className:`first-run-banner-body`,children:`You can download it anyway and start using it now, or wait for a Gezel update with a refreshed catalog.`})]}):(0,W.jsx)(`p`,{className:`first-run-banner-body`,children:r.error});return(0,W.jsxs)(`output`,{className:`first-run-banner first-run-banner-failed`,children:[(0,W.jsx)(`div`,{className:`first-run-banner-head`,children:(0,W.jsx)(`strong`,{children:w})}),T,(0,W.jsxs)(`div`,{className:`first-run-banner-actions`,children:[C&&(0,W.jsx)(`button`,{type:`button`,className:`first-run-banner-btn first-run-banner-btn-primary`,onClick:()=>void v(),disabled:a||s,title:`Download the current file from Hugging Face without verifying it against the catalog's pinned checksum.`,children:a?`Downloading…`:`Download anyway`}),(0,W.jsx)(`button`,{type:`button`,className:C?`first-run-banner-btn`:`first-run-banner-btn first-run-banner-btn-primary`,onClick:()=>void _(),disabled:a||s,children:a&&!C?`Retrying…`:`Retry download`}),x&&(0,W.jsx)(`button`,{type:`button`,className:`first-run-banner-btn`,onClick:()=>void b(),disabled:a||s,title:`Use the llama engine instead. Works without Python; slightly slower than MLX on Apple Silicon.`,children:s?`Switching…`:`Switch to llama`}),(0,W.jsx)(`button`,{type:`button`,className:`first-run-banner-btn`,onClick:()=>void y(),disabled:a||s,children:p?.available===!1?`Set up GitHub Copilot`:`Use GitHub Copilot instead`}),!C&&(0,W.jsx)(P,{className:`first-run-banner-btn`,report:{surface:`model-download`,message:r.error,detail:{code:`first-run-install-failed`,engine:r.provider}}})]})]})}function de(){return(0,W.jsxs)(`p`,{className:`first-run-banner-wait`,children:[`Nothing to do until this finishes — a good moment to read`,` `,(0,W.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:()=>{document.getElementById(U)?.scrollIntoView({behavior:`smooth`,block:`start`})},children:`what gezel is and how to work with your crew →`})]})}function fe({progress:e}){let t=e!=null&&e.totalBytes>0&&e.phase===`downloading`,n=t?Math.min(100,Math.round(e.bytesWritten/e.totalBytes*100)):0,r=e?e.phase===`verifying`?`Checking download…`:e.phase===`extracting-metadata`?`Reading model info…`:t?`${K(e.bytesWritten)} of ${K(e.totalBytes)} · ${n}%`:e.bytesWritten>0?`${K(e.bytesWritten)} downloaded`:`Starting…`:`Starting…`;return(0,W.jsxs)(`div`,{className:`first-run-banner-progress`,children:[(0,W.jsx)(`div`,{className:t?`first-run-banner-bar`:`first-run-banner-bar first-run-banner-bar-indeterminate`,children:(0,W.jsx)(`div`,{className:`first-run-banner-bar-fill`,style:t?{width:`${n}%`}:void 0})}),(0,W.jsx)(`span`,{className:`first-run-banner-progress-label`,children:r})]})}function K(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`}var pe=25e9,me=13e9,he=5e9,ge=8*1024**3;function _e(e){return e?e.source===`gpu-integrated`||e.source===`system-ram-fallback`||e.source!==`darwin-unified`&&e.gpuMemoryKind!==`unified`&&(e.gpuVramBytes==null||e.gpuVramBytes<ge)?`This device is best suited to small AI models.`:`You can run ${e.usableBytes>=pe?`large`:e.usableBytes>=me?`medium-size`:e.usableBytes>=he?`small-size`:`tiny`} AI models${e.source===`darwin-unified`||e.gpuMemoryKind===`discrete`||e.gpuMemoryKind===`unified`?` comfortably`:``} on this device.`:`You can run AI models on this device.`}function ve(e){if(!e)return`2–5 minutes`;let t=e/1024**3;return`~${Math.max(5,Math.ceil(t/5)*5)} minutes`}function ye(e){let t=e/1024**3;if(t>=1)return`~${t.toFixed(1)} GB`;let n=e/1024**2;return`~${Math.round(n)} MB`}function be(e,t){if(!e)return null;let n=e.manifest;return!n||n.kind!==`chat-model`?null:(t===`mlx`?n.mlx?.approxSizeBytes:n.llamaCpp?.approxSizeBytes)??n.approxSizeBytes??null}function q(e){switch(e){case`gemma4-e2b-q4`:case`gemma4-e2b`:case`gemma4-e2b-mlx`:return`Gemma 4 (E2B)`;case`gemma4-e4b-q4`:case`gemma4-e4b`:case`gemma4-e4b-mlx`:return`Gemma 4 (E4B)`;case`gemma4-12b-q4`:case`gemma4-12b-q8`:return`Gemma 4 (12B)`;case`gemma4-26b-q4`:case`gemma4-26b`:case`gemma4-26b-mlx`:return`Gemma 4 (26B-A4B MoE)`;case`gemma4-31b-q4`:return`Gemma 4 (31B)`;case`qwen3.6-27b-q4`:case`qwen3.6-27b-q8`:return`Qwen 3.6 (27B)`;case`qwen3.6-35b-a3b-q4`:case`qwen3.6-35b-a3b-q8`:return`Qwen 3.6 (35B-A3B MoE)`;default:return e}}function J(e){return e==null?``:e>=1024**3?`~${(e/1024**3).toFixed(1)} GB`:`~${Math.round(e/1024**2)} MB`}function Y(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 xe(e,t,n){let r=null;for(let a of e){let e=a.manifest;o(e)&&i(t,n===`image`?{minRamGB:e.minRamGB}:{minVramGB:e.minVramGB})&&(r==null||(e.recoScore??0)>(r.recoScore??0))&&(r=e)}return r}function Se(e){let t=null;for(let n of e)o(n)&&(t==null||(n.recoScore??0)>(t.recoScore??0))&&(t=n);return t}function Ce(e){let t=(e.approxSizeBytes??0)+(e.auxiliaryFiles??[]).reduce((e,t)=>e+(t.sizeBytes??0),0);return t>0?t:null}function X(e,t){return e.models.some(e=>e.id===t)}function we(){let[e,t]=(0,H.useState)(null),[n,r]=(0,H.useState)({}),[i,a]=(0,H.useState)(!1),[o,s]=(0,H.useState)(new Set),[c,y]=(0,H.useState)(null),[b,x]=(0,H.useState)(!1),[S,C]=(0,H.useState)(null),w=(0,H.useRef)(new Map),T=(0,H.useCallback)((e,t)=>{r(n=>({...n,[e]:t}))},[]),E=(0,H.useCallback)(async(e,t)=>{if(w.current.has(e.key))return;let n=new AbortController;w.current.set(e.key,n);let r=null;try{if(await t(t=>{if(t.type===`progress`){let n=t.bytesWrittenAll??t.bytesWritten,r=t.totalBytesAll??t.totalBytes;r&&n!=null&&T(e.key,{status:`installing`,pct:Math.min(100,Math.round(n/r*100)),bytesWritten:n,totalBytes:r})}else t.type===`error`&&(r=t.error??`download failed`)},n.signal),r)throw Error(r);T(e.key,{status:`done`,pct:100})}catch(t){if(n.signal.aborted)return;T(e.key,{status:`error`,pct:null,error:t instanceof Error?t.message:String(t)})}finally{w.current.get(e.key)===n&&w.current.delete(e.key)}},[T]);(0,H.useEffect)(()=>{let e=!1,n={models:[]};return(async()=>{try{let[i,a,o,s,c,u,d,f,p,m,h,g]=await Promise.all([l.getMemoryProfile(),l.listCatalogItems(`image-model`),l.listCatalogItems(`video-model`),l.listAudioCatalog(),l.listInstalledImageModels().catch(()=>n),l.listInstalledVideoModels().catch(()=>n),l.listInstalledSttModels().catch(()=>n),l.listInstalledTtsModels().catch(()=>n),l.listActiveImagePulls().catch(()=>({pulls:[]})),l.listActiveVideoPulls().catch(()=>({pulls:[]})),l.listRecognitionCatalog().catch(()=>({models:[]})),l.listInstalledRecognitionModels().catch(()=>n)]);if(e)return;let _={platform:i.platform,gpuVramBytes:i.gpuVramBytes,totalRamBytes:i.totalRamBytes,usableBytes:i.usableBytes,...i.budgetBytes===void 0?{}:{budgetBytes:i.budgetBytes}},v=[],y=xe(a.items,_,`image`);if(y){let e=p.pulls.find(e=>e.id===y.id&&!e.finished);v.push({key:`image`,id:y.id,what:`image model`,name:y.name,sizeBytes:Ce(y),installed:X(c,y.id),start:(e,t)=>l.pullImageModel(y.id,e,t),cancel:()=>l.cancelImagePull(y.id),...e?{resume:{bytesWritten:e.bytesWritten,totalBytes:e.totalBytes,subscribe:(e,t)=>l.subscribeImagePull(y.id,e,t)}}:{}})}let b=[...h.models].filter(e=>!e.approxSizeBytes||e.approxSizeBytes<=_.usableBytes*.5).sort((e,t)=>t.recoScore-e.recoScore)[0];b&&v.push({key:`recognition`,id:b.id,what:`image reading`,name:b.name,sizeBytes:b.approxSizeBytes,installed:X(g,b.id),start:(e,t)=>l.pullRecognitionModel(b.id,e,t)});let x=Se(s.stt);x&&v.push({key:`stt`,id:x.id,what:`speech-to-text`,name:x.name,sizeBytes:x.approxSizeBytes,installed:X(d,x.id),start:(e,t)=>l.pullAudioModel(`stt`,x.id,e,t)});let S=Se(s.tts);S&&v.push({key:`tts`,id:S.id,what:`text-to-speech`,name:S.name,sizeBytes:S.approxSizeBytes,installed:X(f,S.id),start:(e,t)=>l.pullAudioModel(`tts`,S.id,e,t)});let C=xe(o.items,_,`video`);if(C){let e=m.pulls.find(e=>e.id===C.id&&!e.finished);v.push({key:`video`,id:C.id,what:`video model`,name:C.name,sizeBytes:C.approxSizeBytes??null,installed:X(u,C.id),start:(e,t)=>l.pullVideoModel(C.id,e,t),cancel:()=>l.cancelVideoPull(C.id),...e?{resume:{bytesWritten:e.bytesWritten,totalBytes:e.totalBytes,subscribe:(e,t)=>l.subscribeVideoPull(C.id,e,t)}}:{}})}t(v);let w={};for(let e of v)if(e.installed)w[e.key]={status:`done`,pct:100};else if(e.resume){let{bytesWritten:t,totalBytes:n}=e.resume;w[e.key]={status:`installing`,pct:n>0?Math.min(100,Math.round(t/n*100)):null,bytesWritten:t,totalBytes:n}}r(w);for(let e of v)!e.installed&&e.resume&&E(e,e.resume.subscribe)}catch{e||t([])}})(),()=>{e=!0}},[E]);let D=(0,H.useCallback)(async e=>{r(t=>{let n=t[e.key]?.status;return n===`installing`||n===`done`?t:{...t,[e.key]:{status:`installing`,pct:null}}}),await E(e,e.start)},[E]),O=(0,H.useCallback)(async e=>{w.current.get(e.key)?.abort();try{await e.cancel?.(),T(e.key,{status:`idle`,pct:null})}catch(t){T(e.key,{status:`error`,pct:null,error:t instanceof Error?t.message:String(t)})}},[T]),k=(0,H.useMemo)(()=>(e??[]).filter(e=>{let t=n[e.key]?.status??`idle`;return t===`idle`||t===`error`}),[e,n]),A=(0,H.useMemo)(()=>k.filter(e=>o.has(e.key)),[k,o]),j=(0,H.useMemo)(()=>A.reduce((e,t)=>e+(t.sizeBytes??0),0),[A]),M=(0,H.useMemo)(()=>A.filter(e=>e.sizeBytes==null).length,[A]),N=(0,H.useMemo)(()=>k.filter(e=>e.key!==`video`).reduce((e,t)=>e+(t.sizeBytes??0),0),[k]),P=(0,H.useCallback)(()=>{let e=k.filter(e=>e.key!==`video`);s(new Set(e.map(e=>e.key))),y(null),C(null),x(e.length>0),a(!0)},[k]);(0,H.useEffect)(()=>{if(!i||A.length===0){y(null),x(!1),C(null);return}if(j<=0){y(null),x(!1),C(`Gezel couldn't determine this model's size. Its installer will check space again before writing.`);return}let e=!1;return y(null),C(null),x(!0),l.checkModelDownloadSpace({sizeBytes:Math.ceil(j)}).then(t=>{e||y(t)}).catch(t=>{e||C(`Gezel couldn't measure free space (${t instanceof Error?t.message:String(t)}). Each installer will check again before writing.`)}).finally(()=>{e||x(!1)}),()=>{e=!0}},[i,j,A.length]);let F=(0,H.useCallback)(()=>{for(let e of A)D(e);a(!1)},[D,A]);if((0,H.useEffect)(()=>{let e=w.current;return()=>{for(let t of e.values())t.abort()}},[]),!e||e.length===0)return null;let I=k.length>0,L=A.length>0&&!b&&(c===null||c.ok);return(0,W.jsxs)(`section`,{className:`setup-section home-media-section`,children:[I&&(0,W.jsxs)(W.Fragment,{children:[(0,W.jsxs)(`button`,{type:`button`,className:`gz-link-button home-media-plan-link`,onClick:P,children:[`Also download the optional media models (image + speech)`,N>0?` · ${J(N)}`:``]}),(0,W.jsx)(`p`,{className:`muted small home-media-plan-hint`,children:`Lets your gezellen create images, read pictures, and speak. You review the list — and can add video — before anything downloads.`})]}),(0,W.jsx)(`div`,{className:`home-media-downloads`,children:e.map(e=>{let t=n[e.key]??{status:`idle`,pct:null};return t.status===`idle`?null:(0,W.jsx)(`div`,{className:`home-media-row`,children:t.status===`done`?(0,W.jsxs)(`span`,{className:`home-probe home-probe-ok small`,children:[`✓ `,e.name,` on device`]}):t.status===`installing`?(0,W.jsxs)(`div`,{className:`home-media-progress`,children:[(0,W.jsxs)(`div`,{className:`home-media-progress-heading`,children:[(0,W.jsxs)(`span`,{className:`muted small`,children:[`Downloading `,e.name,`…`]}),(0,W.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:()=>void O(e),"aria-label":`Cancel ${e.name} download`,children:`Cancel`})]}),(0,W.jsx)(`div`,{className:t.pct==null?`first-run-banner-bar first-run-banner-bar-indeterminate`:`first-run-banner-bar`,children:(0,W.jsx)(`div`,{className:`first-run-banner-bar-fill`,style:t.pct==null?void 0:{width:`${t.pct}%`}})}),(0,W.jsx)(`span`,{className:`first-run-banner-progress-label`,children:t.bytesWritten!=null&&t.totalBytes?`${Y(t.bytesWritten)} of ${Y(t.totalBytes)} · ${t.pct??0}%`:`Starting…`})]}):(0,W.jsxs)(`span`,{className:`home-probe home-probe-fail small`,children:[`✗ `,e.name,`: `,t.error]})},e.key)})}),(0,W.jsx)(u,{open:i,onOpenChange:e=>{a(e),e||s(new Set)},children:(0,W.jsxs)(v,{children:[(0,W.jsx)(g,{}),(0,W.jsxs)(f,{className:`home-media-plan-dialog`,children:[(0,W.jsx)(_,{asChild:!0,children:(0,W.jsx)(`h3`,{children:`Review model downloads`})}),(0,W.jsx)(p,{asChild:!0,children:(0,W.jsx)(`p`,{className:`muted small`,children:`Nothing starts until you confirm this plan. Downloads go to Gezel model storage and remain visible below while they run.`})}),(0,W.jsxs)(`fieldset`,{className:`home-media-plan-list`,children:[(0,W.jsx)(`legend`,{className:`sr-only`,children:`Models to download`}),k.map(e=>(0,W.jsxs)(`label`,{className:`home-media-plan-item`,children:[(0,W.jsx)(`input`,{type:`checkbox`,checked:o.has(e.key),onChange:t=>{s(n=>{let r=new Set(n);return t.target.checked?r.add(e.key):r.delete(e.key),r}),y(null),C(null),x(!0)}}),(0,W.jsxs)(`span`,{className:`home-media-plan-copy`,children:[(0,W.jsxs)(`span`,{className:`home-media-plan-name`,children:[e.name,e.key===`video`&&(0,W.jsx)(`span`,{className:`home-media-plan-large`,children:`Large download`})]}),(0,W.jsxs)(`span`,{className:`muted small`,children:[e.what,e.sizeBytes?` · ${J(e.sizeBytes)}`:` · size unavailable`]})]})]},e.key))]}),(0,W.jsxs)(`div`,{className:`home-media-plan-summary`,"aria-live":`polite`,children:[(0,W.jsx)(`strong`,{children:A.length===0?`Select at least one model.`:`${A.length} model${A.length===1?``:`s`} · ${j>0?J(j):`size unavailable`}${M>0?` + ${M} unknown`:``}`}),b?(0,W.jsx)(`span`,{className:`muted small`,children:`Checking free space…`}):c?.known&&c.ok?(0,W.jsxs)(`span`,{className:`muted small`,children:[Y(c.freeBytes),` free in `,c.storageLocation,`; this plan needs `,Y(c.requiredBytes),` including safety headroom.`]}):c?.known&&!c.ok?(0,W.jsxs)(`span`,{className:`error small`,children:[`Not enough free space: this plan needs `,Y(c.requiredBytes),`, but`,` `,c.storageLocation,` has `,Y(c.freeBytes),` free.`]}):c&&!c.known?(0,W.jsx)(`span`,{className:`muted small`,children:`Free space could not be measured. Each installer will check again before writing.`}):S?(0,W.jsx)(`span`,{className:`muted small`,children:S}):null]}),(0,W.jsxs)(h,{children:[(0,W.jsx)(d,{asChild:!0,children:(0,W.jsx)(`button`,{type:`button`,children:`Cancel`})}),(0,W.jsx)(m,{asChild:!0,children:(0,W.jsx)(`button`,{type:`button`,className:`primary`,disabled:!L,onClick:F,children:b?`Checking space…`:A.length>0?`Download ${A.length} model${A.length===1?``:`s`}`:`Choose models`})})]})]})]})})]})}var Z=`welcome`,Te=`gezel:handboek:article`;function Q(e){try{window.localStorage.setItem(Te,e)}catch{}window.dispatchEvent(new CustomEvent(`gezel:navigate`,{detail:{view:`handboek`}}))}function Ee({variant:e=`toggle`}={}){let t=e===`stacked`,[n,r]=(0,H.useState)(null),[i,a]=(0,H.useState)(!1),[o,s]=(0,H.useState)(`doc`),c=k()===`light`?O:void 0;(0,H.useEffect)(()=>{let e=!0;return l.getHandboekArticle(Z).then(t=>{e&&(t&&typeof t.markdown==`string`?r(t):a(!0))}).catch(()=>e&&a(!0)),()=>{e=!1}},[]);let u=(0,H.useMemo)(()=>n?ce(n.figures??[]):null,[n]),d=(0,H.useRef)(u);(0,H.useEffect)(()=>(d.current=u,()=>d.current?.dispose?.()),[u]);let f=(0,H.useMemo)(()=>n?se(n.markdown):null,[n]),p=(0,H.useMemo)(()=>{if(!f)return null;try{return C(w(f))}catch{return null}},[f]),m=(0,H.useMemo)(()=>{if(!n||!f)return null;try{return C(w(f),{articleId:n.id,defaultDuration:n.defaultDuration??6})}catch{return null}},[n,f]);return i?(0,W.jsx)(`p`,{children:(0,W.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:()=>Q(Z),"data-testid":`home-intro-handboek-fallback`,children:`Open the Handboek for an introduction to gezel →`})}):!p||!u?(0,W.jsx)(`p`,{className:`muted`,"aria-live":`polite`,children:`Loading the Handboek…`}):(0,W.jsxs)(`div`,{className:`home-intro-article`,"data-testid":`home-intro-article`,children:[(0,W.jsxs)(`div`,{className:`home-intro-article-controls`,children:[(0,W.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:()=>Q(Z),title:`Read this article in the Handboek`,children:`Open in Handboek →`}),!t&&(0,W.jsxs)(`div`,{className:`gz-tray handboek-mode-tray`,role:`radiogroup`,"aria-label":`View as`,children:[(0,W.jsx)(`button`,{type:`button`,role:`radio`,"aria-checked":o===`doc`,className:o===`doc`?`gz-key gz-key-active`:`gz-key`,onClick:()=>s(`doc`),children:`Read`}),(0,W.jsx)(`button`,{type:`button`,role:`radio`,"aria-checked":o===`video`,className:o===`video`?`gz-key gz-key-active`:`gz-key`,onClick:()=>s(`video`),children:`Watch`})]})]}),(0,W.jsxs)(T.Provider,{value:u,children:[(t||o===`video`)&&(0,W.jsx)(`div`,{className:`home-intro-page home-intro-page-player`,children:(0,W.jsx)(`div`,{className:`home-intro-player`,children:(0,W.jsx)(D,{doc:m??p,theme:M,displayMode:`video`,audioMode:`synthetic`,captionsEnabled:!0,captionStyle:`social`,autoPlay:!t,showControls:!0,showScrubber:!0})})}),(t||o===`doc`)&&(0,W.jsx)(`div`,{className:`home-intro-page`,children:(0,W.jsx)(`div`,{className:`home-intro-doc`,onClickCapture:e=>{let t=e.target.closest(`a`);if(!t)return;let n=t.getAttribute(`href`);!n||/^[a-z][a-z0-9+.-]*:/i.test(n)||n.startsWith(`//`)||n.startsWith(`#`)||(e.preventDefault(),e.stopPropagation(),Q(n.split(/[?#]/)[0].replace(/\.md$/,``).replace(/^(\.\.?\/)+/,``).split(`/`).pop()||Z))},children:(0,W.jsx)(E,{doc:p,className:`gezel-article-view`,theme:M,surface:c,thinMargins:!0,imageDisplayMode:`inline`,showCover:!1})})})]})]})}function De(e){return e<12?`Good morning`:e<18?`Good afternoon`:`Good evening`}function Oe(e,t=Date.now()){if(!e)return null;let n=t-Date.parse(e.generatedAt);return Number.isFinite(n)&&n<1296e5?e:null}function ke(e,t=Date.now()){return b(e,{now:t})}function Ae(e,t){let n=new Set(t.map(e=>e.id)),r=(e?.recentTabs??[]).filter(e=>e.kind===`project`).slice().sort((e,t)=>t.at-e.at);for(let e of r)if(e.kind===`project`&&n.has(e.id))return e.id;let i=t.find(e=>e.id!=="default");return i?i.id:t[0]?.id??`default`}function je({review:e}){let t=e.reports[0],n=e.reports.slice(1),[r,i]=(0,H.useState)(null),[a,o]=(0,H.useState)(null);(0,H.useEffect)(()=>{if(i(null),o(null),!t)return;let e=!1;return l.readProjectArtifact(t.projectId,t.path).then(t=>{e||i(t.content)}).catch(t=>{e||o(t.message)}),()=>{e=!0}},[t]);let s=(0,H.useMemo)(()=>{if(r===null)return null;try{return C(w(r),{articleId:`night-review`})}catch{return null}},[r]),c=(0,H.useMemo)(()=>t?oe({projectId:t.projectId,reportPath:t.path}):void 0,[t]),u=e.reports.reduce((e,t)=>e+t.actionCounts.suggested,0),d=e.diffpacks;return(0,W.jsxs)(`div`,{className:`home-workshop-status-report`,role:`tabpanel`,"data-testid":`night-review-panel`,children:[(0,W.jsxs)(`p`,{className:`home-workshop-night-summary`,children:[e.tasksCompleted.length,` task`,e.tasksCompleted.length===1?``:`s`,` finished overnight, `,e.reports.length,` report`,e.reports.length===1?``:`s`,` written`,d.length>0?`, ${d.length} change proposal${d.length===1?``:`s`} waiting`:``,u>0?` — ${u} suggested action${u===1?``:`s`} to review.`:`.`]}),d.length>0&&(0,W.jsx)(`div`,{className:`home-workshop-night-reports`,children:d.map(e=>(0,W.jsxs)(`button`,{type:`button`,className:`home-workshop-night-report-row`,onClick:()=>window.dispatchEvent(new CustomEvent(`gezel:open-tab`,{detail:{kind:`project`,id:e.projectId,activate:!0}})),children:[(0,W.jsx)(`span`,{className:`home-workshop-night-report-title`,children:e.title}),(0,W.jsxs)(`span`,{className:`muted small`,children:[e.projectName,` · `,e.fileCount,` file`,e.fileCount===1?``:`s`,` · +`,e.additions,` −`,e.deletions,e.drifted?` · out of date`:``]})]},`${e.projectId}:${e.packId}`))}),t&&(0,W.jsx)(`div`,{className:`home-workshop-status-body`,children:s?(0,W.jsx)(E,{doc:s,theme:M,thinMargins:!0,imageDisplayMode:`thumbnail`,fenceRenderers:c}):a?(0,W.jsx)(`p`,{className:`error small`,children:a}):(0,W.jsxs)(`p`,{className:`muted small`,children:[`Loading `,t.title,`…`]})}),n.length>0&&(0,W.jsx)(`div`,{className:`home-workshop-night-reports`,children:n.map(e=>(0,W.jsxs)(`button`,{type:`button`,className:`home-workshop-night-report-row`,onClick:()=>window.dispatchEvent(new CustomEvent(`gezel:open-tab`,{detail:{kind:`project`,id:e.projectId,activate:!0}})),children:[(0,W.jsx)(`span`,{className:`home-workshop-night-report-title`,children:e.title}),(0,W.jsxs)(`span`,{className:`muted small`,children:[e.projectName,e.actionCounts.suggested>0?` · ${e.actionCounts.suggested} action${e.actionCounts.suggested===1?``:`s`} to review`:``]})]},`${e.projectId}:${e.path}`))}),(0,W.jsx)(`div`,{className:`home-workshop-status-foot`,children:(0,W.jsxs)(`span`,{className:`home-workshop-status-meta`,title:x(e.windowEnd),children:[`Night window ended `,ke(e.windowEnd)]})})]})}function Me({report:e,running:t,onRefresh:n}){let r=(0,H.useMemo)(()=>{try{return C(w(e.report),{articleId:`meester-status`})}catch{return null}},[e.report]);return(0,W.jsxs)(`div`,{className:`home-workshop-status-report`,role:`tabpanel`,"data-testid":`status-report-panel`,children:[(0,W.jsx)(`div`,{className:`home-workshop-status-body`,children:r?(0,W.jsx)(E,{doc:r,theme:M,thinMargins:!0,imageDisplayMode:`thumbnail`}):(0,W.jsx)(`p`,{children:e.report})}),(0,W.jsxs)(`div`,{className:`home-workshop-status-foot`,children:[(0,W.jsxs)(`span`,{className:`home-workshop-status-meta`,title:x(e.generatedAt),children:[`Written `,ke(e.generatedAt)]}),n&&(0,W.jsx)(`button`,{type:`button`,className:`home-workshop-tip-action`,onClick:n,disabled:t,children:t?`Meester is writing…`:`Write a fresh report`})]})]})}function Ne({size:e=18,color:t=`var(--sage-deep)`}){return(0,W.jsxs)(`svg`,{width:e,height:e,viewBox:`0 0 24 24`,fill:`none`,stroke:t,strokeWidth:1.7,strokeLinecap:`round`,strokeLinejoin:`round`,"aria-hidden":`true`,children:[(0,W.jsx)(`path`,{d:`M12 21 V11`}),(0,W.jsx)(`path`,{d:`M12 14.4 C8.5 14.4 6.4 11.9 6.4 8.4 C9.9 8.4 12 10.9 12 14`,fill:t,fillOpacity:.18}),(0,W.jsx)(`path`,{d:`M12 12.4 C15.5 12.4 17.6 9.9 17.6 6.4 C14.1 6.4 12 8.9 12 12`,fill:t,fillOpacity:.18})]})}var Pe=[{body:(0,W.jsx)(W.Fragment,{children:`Most of getting great work out of a gezel is shaping its brief. Trim a gezel’s standing orders and it’ll stop over-explaining.`}),action:`Train a gezel`,view:`gezels`},{body:(0,W.jsx)(W.Fragment,{children:`Teach a gezel once and it sticks — stamp today’s steps into a routine it can run on its own.`}),action:`Save a routine`,view:`scripts`},{body:(0,W.jsx)(W.Fragment,{children:`Your crew can grow with your work. A second specialist lets the first stay deep on one project.`}),action:`Hire a gezel`,view:`gezels`},{body:(0,W.jsxs)(W.Fragment,{children:[`Local models come first — cloud and the web are opt-in and `,(0,W.jsx)(`em`,{children:`always marked`}),`. Adjust your providers any time.`]}),action:`Open settings`,view:`settings`},{body:(0,W.jsx)(W.Fragment,{children:`Hand the meester a half-baked idea and they’ll shape it into something your crew can actually start on.`}),action:`See your projects`,view:`projects`}];function Fe({onNavigate:e}){let[t,n]=(0,H.useState)(0),r=Pe[t%Pe.length];return(0,W.jsxs)(`div`,{className:`home-workshop-tip`,children:[(0,W.jsx)(`span`,{className:`home-workshop-tip-sprout`,children:(0,W.jsx)(Ne,{size:18})}),(0,W.jsxs)(`div`,{style:{flex:1,minWidth:0},children:[(0,W.jsxs)(`div`,{className:`home-workshop-tip-label-row`,children:[(0,W.jsx)(`span`,{className:`home-workshop-eyebrow home-workshop-tip-label`,children:`Tip of the day`}),(0,W.jsx)(`button`,{type:`button`,className:`home-workshop-tip-cycle`,title:`Another tip`,"aria-label":`Show another tip`,onClick:()=>n(e=>e+1),children:`↻`})]}),(0,W.jsxs)(`div`,{className:`home-workshop-tip-body`,children:[r.body,` `,(0,W.jsxs)(`button`,{type:`button`,className:`home-workshop-tip-action`,onClick:()=>e?.(r.view),children:[r.action,` →`]})]})]})]})}function Ie({direction:e}){return(0,W.jsx)(`svg`,{"aria-hidden":`true`,width:`18`,height:`18`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2.4`,strokeLinecap:`round`,strokeLinejoin:`round`,children:e===`up`?(0,W.jsx)(`path`,{d:`M6 15 L12 9 L18 15`}):(0,W.jsx)(`path`,{d:`M6 9 L12 15 L18 9`})})}function Le({chips:e}){return(0,W.jsx)(W.Fragment,{children:e.map(e=>(0,W.jsxs)(`span`,{className:`home-workshop-chip`,children:[(0,W.jsx)(`span`,{className:`home-workshop-chip-dot`,style:{background:e.dot}}),e.label]},e.label))})}function Re({statusReport:e,greeting:t,onCtaClick:n}){return e?e.cta&&n?(0,W.jsx)(`h1`,{className:`home-workshop-headline`,children:(0,W.jsx)(`button`,{type:`button`,className:`home-workshop-headline-cta`,onClick:n,title:e.cta.label,children:e.headline})}):(0,W.jsx)(`h1`,{className:`home-workshop-headline`,children:e.headline}):(0,W.jsxs)(`h1`,{className:`home-workshop-headline`,children:[t,`.`]})}function ze({chips:e,meesterName:t,meesterPoppetje:n,meesterIcon:r,meesterIconOverride:i,collapsed:a,onToggleCollapse:o,tab:s,onTabChange:c,statusReport:l,statusRunning:u,onRunStatusReport:d,nightReview:f,onNavigate:p}){let m=A(),h=new Date,g=h.getHours(),_=De(g),v=l??null,b=()=>{let e=v?.cta?.target;e&&(e.kind===`view`?p?.(e.view):e.kind===`project`?window.dispatchEvent(new CustomEvent(`gezel:open-tab`,{detail:{kind:`project`,id:e.projectId,activate:!0}})):window.dispatchEvent(new CustomEvent(`gezel:open-tab`,{detail:{kind:`task`,ref:e.taskRef,activate:!0}})))},x=`${h.toLocaleDateString(void 0,{weekday:`long`})} ${g<12?`morning`:g<18?`afternoon`:`evening`} · ${h.toLocaleTimeString(void 0,{hour:`2-digit`,minute:`2-digit`,hour12:!1})}`;return a?(0,W.jsxs)(`div`,{className:`home-workshop-greeting-collapsed`,children:[(0,W.jsx)(Re,{statusReport:v,greeting:_,onCtaClick:b}),(0,W.jsx)(`div`,{className:`home-workshop-vrule`}),(0,W.jsx)(`div`,{style:{display:`flex`,gap:8,flexWrap:`wrap`,flex:1,minWidth:0},children:(0,W.jsx)(Le,{chips:e})}),(0,W.jsx)(`button`,{type:`button`,className:`home-workshop-collapse-btn`,onClick:o,title:`Expand the greeting`,"aria-label":`Expand the greeting`,children:(0,W.jsx)(Ie,{direction:`down`})})]}):(0,W.jsxs)(`div`,{className:`home-workshop-greeting`,"data-testid":`greeting-band`,children:[(0,W.jsxs)(`div`,{className:`home-workshop-greeting-top`,children:[(0,W.jsxs)(`div`,{className:`home-workshop-tabs`,role:`tablist`,"aria-label":`Home view`,children:[(0,W.jsx)(`button`,{type:`button`,role:`tab`,"aria-selected":s===`greeting`,className:`home-workshop-tab${s===`greeting`?` is-active`:``}`,onClick:()=>c(`greeting`),children:x}),v&&(0,W.jsx)(`button`,{type:`button`,role:`tab`,"aria-selected":s===`status`,className:`home-workshop-tab${s===`status`?` is-active`:``}`,onClick:()=>c(`status`),children:`Status report`}),f&&(0,W.jsx)(`button`,{type:`button`,role:`tab`,"aria-selected":s===`night`,className:`home-workshop-tab${s===`night`?` is-active`:``}`,onClick:()=>c(`night`),children:`Last night`}),(0,W.jsx)(`button`,{type:`button`,role:`tab`,"aria-selected":s===`tour`,className:`home-workshop-tab${s===`tour`?` is-active`:``}`,onClick:()=>c(`tour`),children:`New here? What is gezel`})]}),(0,W.jsx)(`button`,{type:`button`,className:`home-workshop-collapse-btn`,onClick:o,title:`Collapse to a single row`,"aria-label":`Collapse the greeting`,children:(0,W.jsx)(Ie,{direction:`up`})})]}),(0,W.jsxs)(`div`,{className:`home-workshop-greeting-cols`,children:[(0,W.jsxs)(`div`,{className:`home-workshop-greeting-left`,children:[s===`status`&&v?(0,W.jsx)(Me,{report:v,running:u??!1,...d?{onRefresh:d}:{}}):s===`night`&&f?(0,W.jsx)(je,{review:f}):s===`tour`?(0,W.jsx)(`div`,{className:`home-workshop-tour-inline`,role:`tabpanel`,children:(0,W.jsx)(Ee,{})}):(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(Re,{statusReport:v,greeting:_,onCtaClick:b}),(0,W.jsx)(Fe,{onNavigate:p})]}),(0,W.jsx)(`div`,{className:`home-workshop-chips`,children:(0,W.jsx)(Le,{chips:e})})]}),m&&(0,W.jsx)(`div`,{className:`home-workshop-greeting-right`,children:(0,W.jsxs)(`div`,{className:`home-workshop-figure`,children:[n?(0,W.jsx)(y,{poppetje:n,variant:`full`,size:64,title:`${t} poppetje`}):(0,W.jsx)(N,{poppetje:null,svg:r,iconOverride:i,name:t,size:64,variant:`full`}),(0,W.jsx)(`div`,{className:`home-workshop-shelf`}),(0,W.jsxs)(`div`,{className:`home-workshop-figure-label`,children:[t,` `,(0,W.jsx)(`em`,{children:`- Meester`})]})]})})]})]})}function Be({activeSessionId:e,onFocusSession:t,onToolActivity:n,onArtifactReference:r,onArtifactSeen:i,onWorkspaceReference:a,onWorkspaceSeen:o,onOpenReference:s,onTaskReference:c,emptyPlaceholder:u,emptyContent:d}){let f=(0,H.useCallback)(e=>l.listGlobalTimeline(e),[]),p=(0,H.useCallback)(()=>l.allEventsUrl(),[]);return(0,W.jsx)(z,{scopeKey:`global`,activeSessionId:e,onFocusSession:t,onToolActivity:n,onArtifactReference:r,onArtifactSeen:i,onWorkspaceReference:a,onWorkspaceSeen:o,onOpenReference:s,...c?{onTaskReference:c}:{},emptyPlaceholder:u,emptyContent:d,loadTimeline:f,streamUrl:p,showProjectName:!0})}var Ve=[`I want to start a project — can you help me work out what it needs?`,`What kind of gezellen can you bring on, and what are they good at?`,`Here is what I am working on today. Where should I start?`];function He({meesterName:e,meesterIcon:t,meesterPoppetje:n,meesterIconOverride:r,projectId:i}){return(0,W.jsxs)(`div`,{className:`meester-greeting`,children:[(0,W.jsx)(`div`,{className:`meester-greeting-figure`,children:(0,W.jsx)(N,{svg:t??null,poppetje:n??null,iconOverride:r===!0,name:e,size:64})}),(0,W.jsxs)(`div`,{className:`meester-greeting-body`,children:[(0,W.jsxs)(`h3`,{className:`meester-greeting-title`,children:[`Hello — I'm `,e,`, your meester.`]}),(0,W.jsx)(`p`,{className:`meester-greeting-lede`,children:`I'm the one you talk to first. Tell me what you're trying to get done and I'll work out which gezellen you need, bring them on, and set the project up around them. You can also just talk things through with me.`}),(0,W.jsx)(`fieldset`,{className:`meester-greeting-openers gz-tray`,"aria-label":`Ways to start`,children:Ve.map(e=>(0,W.jsx)(`button`,{type:`button`,className:`gz-key meester-greeting-opener`,onClick:()=>B(i,e),children:e},e))})]})]})}function Ue({meesterGezelId:e,meesterName:t,meesterIcon:n,meesterPoppetje:r,meesterIconOverride:i,emptyPlaceholder:o}){let s=re(ae),[c,u]=(0,H.useState)(s?.sessionId??``),[d,f]=(0,H.useState)(``),[p,m]=(0,H.useState)(0),[h,g]=(0,H.useState)([]),[_,v]=(0,H.useState)(s?.gezelId||e),[y,b]=(0,H.useState)(s?.projectId||`default`),x=F(),S=(0,H.useRef)(e);(0,H.useEffect)(()=>{S.current!==e&&(S.current=e,u(``),v(e),b(`default`)),l.listGezels().then(e=>g(e.gezels)).catch(()=>g([]))},[e]),(0,H.useEffect)(()=>{ie(ae,{gezelId:_,projectId:y,sessionId:c})},[_,y,c]);let C=h.find(e=>e.id===_),w=_||e,T=C?a({name:C.name,roleBasedName:C.roleBasedName},x):w===e?t:w,E=C?C.role:w===e?`Meester`:void 0,D=C?C.icon??null:w===e?n:null,O=C?C.poppetje??null:w===e?r:null,k=C?C.iconOverride??!1:w===e&&i,A=(0,H.useMemo)(()=>te({role:w===e?`meester`:`other`,gezelName:T,gezelGender:C?.gender,fixedFunctionTool:C?.fixedFunction?.tool}),[w,T,e,C?.gender,C?.fixedFunction?.tool]);return(0,W.jsx)(`section`,{className:`home-workshop-conversation`,"data-testid":`meester-chat`,children:(0,W.jsx)(ne,{chatKey:`meester:global`,projectId:y,skillsProjectId:y==="default"?void 0:y,children:({onToolActivity:a,onArtifactReference:s,onArtifactSeen:l,onWorkspaceReference:g,onWorkspaceSeen:x,recentReferences:S,onOpenReference:j,onTaskReference:M})=>(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(Be,{activeSessionId:c||void 0,onFocusSession:(e,t,n)=>{v(t),b(n),u(e)},onToolActivity:a,onArtifactReference:s,onArtifactSeen:l,onWorkspaceReference:g,onWorkspaceSeen:x,onOpenReference:j,onTaskReference:M,emptyPlaceholder:o,emptyContent:!_||_===e?(0,W.jsx)(He,{meesterName:t,meesterIcon:n,meesterPoppetje:r,meesterIconOverride:i,projectId:y}):void 0}),(0,W.jsx)(R,{gezelId:w,gezelName:T,gezelRoleBasedName:C?.roleBasedName,gezelRole:E,gezelIcon:D,gezelPoppetje:O,gezelIconOverride:k,recipientGezels:h,onPrimaryRecipientChange:e=>{v(e),b(`default`),u(``)},projectId:y,sessionId:c||void 0,onSessionCreated:e=>{u(e),m(e=>e+1)},onToolActivity:a,recentReferences:S,onOpenReference:j,placeholder:A,draftScope:`meester`,draftId:d||void 0,onDraftIdChange:e=>f(e??``),belowAddressLine:(0,W.jsx)(ee,{gezelId:w,projectId:y,sessionId:c||void 0,onSessionIdChange:e=>u(e??``),refreshKey:p,activeDraftId:d||void 0,onDraftSelect:e=>f(e??``),draftScope:`meester`})})]})})})}function We({config:e,projects:t,meesterGezelId:n,meesterName:r,meesterIcon:i,meesterPoppetje:a,meesterIconOverride:o,banner:s,onNavigate:c}){let[u,d]=(0,H.useState)(e?.homeGreetingCollapsed??!1),f=(0,H.useRef)(!1),p=(0,H.useRef)(!1);(0,H.useEffect)(()=>{f.current||p.current||!e||(f.current=!0,d(e.homeGreetingCollapsed===!0))},[e]);let m=(0,H.useCallback)(()=>{p.current=!0,d(e=>{let t=!e;return l.updateConfig({homeGreetingCollapsed:t}).catch(()=>{}),t})},[]),[h,g]=(0,H.useState)(`greeting`),[_,v]=(0,H.useState)(null),[y,b]=(0,H.useState)(!1),[x,S]=(0,H.useState)([]),[C,w]=(0,H.useState)([]),T=(0,H.useMemo)(()=>Ae(e,t),[e,t]),E=(0,H.useCallback)(()=>{l.listQuestions({pending:!0}).then(e=>w(e.questions??[])).catch(()=>{})},[]);(0,H.useEffect)(()=>{E()},[E]);let D=(0,H.useRef)(T);D.current=T;let O=(0,H.useCallback)(()=>{let e=D.current;if(!e){S([]);return}l.listProjectTasks(e).then(t=>{D.current===e&&S(t.tasks??[])}).catch(()=>{})},[]);(0,H.useEffect)(()=>{if(!T){S([]);return}O()},[T,O]);let k=(0,H.useCallback)(()=>{l.getMeesterStatus().then(e=>{v(e),b(e.running)}).catch(()=>{})},[]);(0,H.useEffect)(()=>{k();let e=new AbortController;return(async()=>{try{for await(let t of j({url:l.allEventsUrl(),headers:l.authHeader(),signal:e.signal,fetch:l.getFetch()})){let e=t.event;if(e.type===`question_asked`||e.type===`question_answered`){E();continue}if(e.type===`task_event`){O();continue}e.type===`meester_status`&&(e.state===`started`?b(!0):(b(!1),k()))}}catch{}})(),()=>e.abort()},[k,E,O]);let A=(0,H.useMemo)(()=>Oe(_?.report),[_]),[M,N]=(0,H.useState)(null);(0,H.useEffect)(()=>{let e=!1;return l.getNightShiftReview().then(t=>{if(e)return;let n=Date.parse(t.windowEnd),r=Number.isFinite(n)&&Date.now()-n<720*60*1e3,i=t.tasksCompleted.length>0||t.reports.length>0;N(r&&i?t:null)}).catch(()=>{}),()=>{e=!0}},[]);let P=(0,H.useCallback)(()=>{b(!0),l.runMeesterStatus().catch(()=>b(!1))},[]),F=(0,H.useMemo)(()=>x.filter(e=>e.status!==`canceled`),[x]),I=(0,H.useMemo)(()=>C.filter(e=>!e.answer),[C]).length+F.filter(e=>e.assignee.kind===`user`&&e.status!==`complete`).length,L=[];return I>0&&L.push({dot:`var(--ochre)`,label:`${I} waiting on you`}),(0,W.jsxs)(`div`,{className:`home-workshop`,"data-testid":`home-workshop`,children:[s,(0,W.jsx)(ze,{chips:L,meesterName:r,meesterPoppetje:a,meesterIcon:i,meesterIconOverride:o,collapsed:u,onToggleCollapse:m,tab:h,onTabChange:g,statusReport:A,statusRunning:y,onRunStatusReport:P,nightReview:M,onNavigate:c}),(0,W.jsx)(`div`,{className:`home-workshop-body`,children:(0,W.jsx)(`div`,{className:`home-workshop-main`,children:n?(0,W.jsx)(Ue,{meesterGezelId:n,meesterName:r,meesterIcon:i,meesterPoppetje:a,meesterIconOverride:o}):(0,W.jsxs)(`section`,{className:`home-workshop-conversation`,children:[(0,W.jsx)(`div`,{className:`home-workshop-eyebrow home-workshop-conversation-eyebrow`,children:`Talk to your meester`}),(0,W.jsxs)(`p`,{className:`home-workshop-rail-empty`,children:[`No meester is designated yet. Pick one in`,` `,(0,W.jsx)(`button`,{type:`button`,className:`home-workshop-tip-action`,onClick:()=>c?.(`settings`),children:`Settings`}),`.`]})]})})})]})}function Ge(e){return e===`darwin`?`mlx`:`llama-cpp`}var Ke=2e4,$=720;function qe({platform:e,onNavigate:t}){let[n,r]=(0,H.useState)(null),[i,o]=(0,H.useState)(null),[u,d]=(0,H.useState)([]),[f,p]=(0,H.useState)(void 0),[m,h]=(0,H.useState)(void 0),[g,_]=(0,H.useState)(null),[v,b]=(0,H.useState)(null),[x,S]=(0,H.useState)(!1),C=F(),w=f?a({name:f,roleBasedName:m},C):void 0,[T,E]=(0,H.useState)({kind:`idle`}),[D,O]=(0,H.useState)(null);(0,H.useEffect)(()=>{let e=!1,t=0,n=()=>{l.getConfig().then(t=>{e||r(t)}).catch(()=>{e||t>=40||(t+=1,window.setTimeout(n,500))})};return n(),l.health().then(o).catch(()=>{}),l.listProjects().then(e=>d(e.projects)).catch(()=>{}),()=>{e=!0}},[]),(0,H.useEffect)(()=>{let e=n?.meesterGezelId;if(!e){p(void 0),h(void 0),_(null),b(null),S(!1);return}l.listGezels().then(t=>{let n=t.gezels.find(t=>t.id===e);p(n?.name),h(n?.roleBasedName),_(n?.icon??null),b(n?.poppetje??null),S(n?.iconOverride??!1)}).catch(()=>{})},[n?.meesterGezelId]);let k=n?.provider??`llama-cpp`,A=k===`copilot`?!!n?.hasGithubToken:k!==`openai`||!!n?.hasOpenaiApiKey;(0,H.useEffect)(()=>{n&&T.kind===`idle`&&(k===`copilot`||k===`ollama`||A)&&N(k)},[n?.provider,n?.hasGithubToken,n?.hasOpenaiApiKey,n?.ollamaBaseUrl]);let j=(0,H.useRef)(null),M=(0,H.useCallback)(()=>{j.current&&=(clearTimeout(j.current),null)},[]),N=(0,H.useCallback)(async(e,t=0)=>{M(),E(t>0?{kind:`probing`,retryAttempt:t,retryMax:$}:{kind:`probing`});try{let r=await l.testProvider(e);if(r.ok){E({kind:`ok`,modelCount:r.modelCount});return}if(e===`ollama`&&n?.autoStartOllama!==!1&&t<$){j.current=setTimeout(()=>{N(e,t+1)},Ke),E({kind:`probing`,retryAttempt:t+1,retryMax:$});return}E({kind:`fail`,error:r.error})}catch(e){E({kind:`fail`,error:e.message})}},[M,n?.autoStartOllama]);(0,H.useEffect)(()=>()=>M(),[M]);let P=s(k)&&T.kind===`ok`&&T.modelCount===0;(0,H.useEffect)(()=>{T.kind===`ok`?O(!P):T.kind===`fail`&&O(!1)},[T.kind,P]);let R=k===`copilot`||k===`ollama`||A;(0,H.useEffect)(()=>{n&&!R&&O(!1)},[n,R]),(0,H.useEffect)(()=>{if(D!==null)return;let e=window.setTimeout(()=>O(!1),3e4);return()=>window.clearTimeout(e)},[D]),(0,H.useEffect)(()=>{D!==null&&window.dispatchEvent(new CustomEvent(`gezel:first-run`,{detail:{firstRun:!D}}))},[D]);let z=(0,H.useCallback)(()=>{N(k)},[N,k]),B=(0,W.jsx)(Je,{state:L(),platform:e});return!n||D===null?(0,W.jsx)(`div`,{className:`home-view home-view-loading`,"aria-busy":`true`,children:(0,W.jsxs)(`div`,{className:`home-loading-placeholder`,"aria-live":`polite`,children:[(0,W.jsx)(`span`,{className:`home-loading-spinner`,"aria-hidden":!0}),(0,W.jsx)(`span`,{children:`Loading…`})]})}):D?(0,W.jsx)(We,{config:n,projects:u,meesterGezelId:n?.meesterGezelId,meesterName:w??`your meester`,meesterIcon:g,meesterPoppetje:v,meesterIconOverride:x,banner:B,onNavigate:t}):(0,W.jsxs)(`div`,{className:`home-view`,children:[B,(0,W.jsxs)(`div`,{className:`home-firstrun-columns`,children:[(0,W.jsxs)(`div`,{className:`home-firstrun-main`,children:[(0,W.jsx)(`h1`,{className:`home-firstrun-heading`,children:`First run setup`}),(0,W.jsx)(`p`,{className:`home-firstrun-lede muted`,children:`Gezel chats through a local AI model that runs privately on this device — download the recommended one to get started.`}),(0,W.jsxs)(`div`,{className:`home-firstrun-body`,children:[n&&(0,W.jsx)(ue,{config:n,onConfigChanged:r,onModelInstalled:z}),(0,W.jsx)(we,{}),(0,W.jsxs)(`section`,{className:`setup-section home-ondevice-link`,children:[(0,W.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:()=>{let e=Ge(i?.platform)===`mlx`?`mlx`:`llamaCpp`;I(e),window.dispatchEvent(new CustomEvent(`gezel:navigate`,{detail:{view:`settings`,section:e}}))},children:`Manage AI models in Settings →`}),(0,W.jsx)(`p`,{className:`muted small`,style:{marginTop:`0.35rem`,marginBottom:0},children:`Browse other local models, or connect a cloud provider (GitHub Copilot, OpenAI, …).`})]}),(0,W.jsx)(Ye,{level:n?.securityPolicy?.level,onChange:async e=>{try{let t=await l.updateConfig({securityPolicy:c(e)});r(t)}catch{}}}),(0,W.jsxs)(`section`,{className:`setup-section`,children:[(0,W.jsx)(`h3`,{children:`Preferences`}),(0,W.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:`0.75rem`},children:[(0,W.jsxs)(`label`,{className:`debug-toggle`,style:{marginTop:0},children:[(0,W.jsx)(`input`,{type:`checkbox`,checked:n?.roleBasedNameOnlyMode!==!0&&n?.showPoppetjes!==!1,onChange:async e=>{let t=e.target.checked;try{let e=await l.updateConfig({roleBasedNameOnlyMode:!t,showPoppetjes:t});r(e),window.dispatchEvent(new CustomEvent(`gezel:config-updated`,{detail:e}))}catch{}}}),(0,W.jsxs)(`span`,{children:[`Show gezel names and poppetjes`,f?` (e.g., ${f}, your meester)`:``]})]}),v&&(0,W.jsx)(`div`,{className:`gezel-icon`,style:{width:36,height:36},title:f?`${f}'s poppetje`:`example poppetje`,children:(0,W.jsx)(`div`,{className:`gezel-icon-poppetje`,children:(0,W.jsx)(y,{poppetje:v,variant:`headshot`,size:36})})})]}),(0,W.jsx)(`p`,{className:`muted small`,style:{marginTop:`0.35rem`,marginBottom:0},children:`Adjustable any time in Settings.`})]})]})]}),(0,W.jsx)(`aside`,{className:`home-firstrun-tutorial`,id:U,"aria-label":`What is gezel?`,children:(0,W.jsx)(Ee,{variant:`stacked`})})]})]})}function Je({state:e,platform:t}){let[n,i]=(0,H.useState)(!1),[a,o]=(0,H.useState)(null);return!e||e.kind!==`available`&&e.kind!==`ready`?null:e.kind===`available`?(0,W.jsxs)(`output`,{className:`app-fallback-banner`,"data-testid":`update-banner`,children:[(0,W.jsxs)(`strong`,{children:[`Gezel `,e.version,` is available.`]}),(0,W.jsx)(`span`,{children:`Linux updates are installed manually. Open the GitHub release, verify its SLSA build provenance, then install the package for your distribution.`}),(0,W.jsx)(`div`,{className:`app-fallback-banner-actions`,children:(0,W.jsx)(`a`,{className:`app-update-release-link`,href:r(e.version),children:`Open release and verification steps`})})]}):(0,W.jsxs)(`output`,{className:`app-fallback-banner`,"data-testid":`update-banner`,children:[(0,W.jsxs)(`strong`,{children:[`Gezel `,e.version,` is ready to install.`]}),(0,W.jsx)(`span`,{children:t===`darwin`?`Installing replaces Gezel and its background service together, so macOS will ask for an administrator password.`:`The update will install automatically after you quit Gezel completely. Closing the window may leave Gezel running in the system tray.`}),(0,W.jsx)(`div`,{className:`app-fallback-banner-actions`,children:(0,W.jsx)(`button`,{type:`button`,className:`primary`,disabled:n,onClick:()=>{i(!0),o(null),window.__GEZEL__?.update?.install().then(e=>{e.ok||(o(e.error),i(!1))})},children:n?t===`darwin`?`Opening installer…`:`Restarting…`:t===`darwin`?`Open installer`:`Install and restart`})}),a&&(0,W.jsxs)(`details`,{open:!0,children:[(0,W.jsx)(`summary`,{children:`Could not open the installer`}),(0,W.jsx)(`p`,{children:a})]})]})}function Ye({level:e,onChange:t}){let n=e??`lockdown`,r=V.find(e=>e.id===n);return(0,W.jsxs)(`section`,{className:`setup-section engagement-mode-${n}`,children:[(0,W.jsx)(`h3`,{children:`Security & compliance`}),(0,W.jsx)(`p`,{className:`muted`,style:{marginTop:0,marginBottom:`0.5rem`},children:`How much should gezellen be allowed to do? Pick a starting posture — you can fine-tune every capability later in Settings → Security & Compliance.`}),(0,W.jsx)(`div`,{className:`engagement-mode-switch gz-tray gz-tray--described`,role:`radiogroup`,"aria-label":`Security posture`,children:V.map(e=>(0,W.jsxs)(`button`,{type:`button`,role:`radio`,"aria-checked":n===e.id,className:`gz-key${n===e.id?` gz-key-active`:``}`,onClick:()=>void t(e.id),children:[e.label,e.recommended?` ★`:``]},e.id))}),(0,W.jsx)(`p`,{className:`engagement-mode-description gz-tray-description`,"aria-live":`polite`,children:r?(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(`strong`,{children:r.label}),` — `,r.description]}):(0,W.jsxs)(W.Fragment,{children:[(0,W.jsx)(`strong`,{children:`Custom`}),` — capability switches were adjusted individually. Fine-tune in Settings → Security & Compliance.`]})})]})}export{qe as HomeView};
|
|
@@ -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{zt as r}from"./dist-DOqbRmFj.js";import{t as i}from"./api-C0I7spBl.js";import{G as a,J as o,K as s,W as c,Y as l,q as u}from"./primitives-CWrGZpPI.js";import{t as d}from"./ConfirmDialog-Dt1ed4Fh.js";import{t as f}from"./CatalogBrowser-7_jHy5Q3.js";import{t as p}from"./LicenseButton-D3VmcVG1.js";var m=e(t(),1),h=n(),g=`image-generator`,_=`generate_image`;function v(){let[e,t]=(0,m.useState)([]),[n,r]=(0,m.useState)(!0),[a,o]=(0,m.useState)(!1),s=(0,m.useCallback)(async()=>{r(!0);try{let e=await i.listGezels();t(e.gezels)}catch{}finally{r(!1)}},[]);(0,m.useEffect)(()=>{s();let e=()=>void s();return window.addEventListener(`gezel:gezel-updated`,e),()=>window.removeEventListener(`gezel:gezel-updated`,e)},[s]);let c=(0,m.useMemo)(()=>e.filter(e=>e.fixedFunction?.tool===_),[e]),l=(0,m.useCallback)(e=>{window.dispatchEvent(new CustomEvent(`gezel:open-tab`,{detail:{kind:`gezel`,id:e,activate:!0}}))},[]),u=(0,m.useCallback)(e=>{o(!1),s(),l(e.id)},[s,l]);return n?null:(0,h.jsxs)(`div`,{className:`ff-img-hint`,children:[c.length>0?(0,h.jsxs)(`div`,{className:`ff-img-hint-have`,children:[(0,h.jsx)(`span`,{className:`muted small`,children:`Image-generator gezel`}),c.length===1?(0,h.jsx)(`button`,{type:`button`,className:`link-btn`,onClick:()=>l(c[0].id),title:`Open ${c[0].name}`,children:c[0].name}):(0,h.jsx)(`span`,{children:c.map((e,t)=>(0,h.jsxs)(`span`,{children:[(0,h.jsx)(`button`,{type:`button`,className:`link-btn`,onClick:()=>l(e.id),title:`Open ${e.name}`,children:e.name}),t<c.length-1&&(0,h.jsx)(`span`,{className:`muted`,children:`, `})]},e.id))}),(0,h.jsx)(`span`,{className:`muted small`,children:`— @-mention them in chat to generate.`})]}):(0,h.jsxs)(`div`,{className:`ff-img-hint-empty`,children:[(0,h.jsxs)(`p`,{className:`muted small`,children:[`Once an engine is set up, the easiest way to use it from chat is to add an`,` `,(0,h.jsx)(`strong`,{children:`image-generator gezel`}),`. They forward your @-mention text straight to`,` `,(0,h.jsx)(`code`,{children:_}),` — no LLM in the middle.`]}),(0,h.jsx)(`button`,{type:`button`,className:`primary`,onClick:()=>o(!0),children:`Add an image-generator gezel`})]}),(0,h.jsx)(y,{open:a,onClose:()=>o(!1),onCreated:u})]})}function y({open:e,onClose:t,onCreated:n}){let[d,f]=(0,m.useState)(()=>r()),[p,v]=(0,m.useState)(null),[y,b]=(0,m.useState)(!1),[x,S]=(0,m.useState)(null),[C,w]=(0,m.useState)(!1),T=(0,m.useRef)(!1);(0,m.useEffect)(()=>{!e||T.current||(T.current=!0,w(!0),i.getCatalogItem(`gezel-template`,g).then(e=>{e.manifest.kind===`gezel-template`&&v(e.manifest.description)}).catch(e=>{S(e instanceof Error?e.message:String(e))}).finally(()=>w(!1)))},[e]),(0,m.useEffect)(()=>{e&&(f(r()),S(null),b(!1))},[e]);let E=()=>f(r()),D=(0,m.useCallback)(async()=>{if(d.trim()){b(!0),S(null);try{n(await i.createGezelFromTemplate(g,{name:d.trim()}))}catch(e){S(e instanceof Error?e.message:String(e))}finally{b(!1)}}},[d,n]);return(0,h.jsx)(o,{open:e,onOpenChange:e=>{!e&&!y&&t()},children:(0,h.jsxs)(u,{children:[(0,h.jsx)(s,{}),(0,h.jsxs)(c,{className:`template-picker-dialog`,children:[(0,h.jsxs)(`header`,{style:{display:`flex`,justifyContent:`space-between`,alignItems:`baseline`},children:[(0,h.jsx)(l,{asChild:!0,children:(0,h.jsx)(`h3`,{style:{margin:0},children:`Add an image-generator gezel`})}),(0,h.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:t,disabled:y,children:`Cancel`})]}),(0,h.jsxs)(a,{className:`muted small`,style:{margin:`0.25rem 0 0.5rem 0`},children:[`Forwards your @-mention text straight to `,(0,h.jsx)(`code`,{children:_}),`. No LLM is invoked.`]}),C&&(0,h.jsx)(`p`,{className:`muted small`,children:`Loading template…`}),p&&(0,h.jsx)(`p`,{className:`muted small`,children:p}),(0,h.jsx)(`form`,{onSubmit:e=>{e.preventDefault(),D()},style:{marginTop:`0.5rem`,padding:`0.6rem`,background:`rgba(79, 125, 255, 0.06)`,borderRadius:`6px`,display:`flex`,flexDirection:`column`,gap:`0.5rem`},children:(0,h.jsxs)(`div`,{style:{display:`flex`,gap:`0.5rem`,alignItems:`center`},children:[(0,h.jsx)(`span`,{className:`muted small`,style:{flexShrink:0},children:`Name:`}),(0,h.jsx)(`input`,{value:d,onChange:e=>f(e.target.value),disabled:y,style:{flex:1}}),(0,h.jsx)(`button`,{type:`button`,className:`dice-btn`,onClick:E,disabled:y,title:`Pick a random name`,"aria-label":`Pick a random name`,children:`🎲`}),(0,h.jsx)(`button`,{type:`submit`,className:`primary`,disabled:y||!d.trim(),children:y?`Creating…`:`Create`})]})}),x&&(0,h.jsx)(`p`,{className:`error`,children:x})]})]})})}function b(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 x(e,t){switch(e){case`low`:return`Runs on ${t} GB`;case`mid`:return`${t} GB+`;case`high`:return`${t} GB+ recommended`;case`workstation`:return`${t} GB+ workstation`}}function S({disabledReason:e,onModelsChanged:t,configuredDefaultModelId:n,onSetActiveModel:r}){let[a,o]=(0,m.useState)([]),[s,c]=(0,m.useState)(null),[l,u]=(0,m.useState)(new Map),[g,_]=(0,m.useState)(null),v=(0,m.useRef)(l);v.current=l;let y=(0,m.useCallback)(async()=>{try{let e=await i.listInstalledImageModels();o(e.models),c(null)}catch(e){o([]),c(e.message)}},[]),S=(0,m.useCallback)((e,n)=>{let r=new AbortController;u(t=>{let n=new Map(t),i=n.get(e);return n.set(e,{...i??{id:e,bytesWritten:0,totalBytes:0},controller:r}),n}),n(n=>{n.type===`progress`?u(t=>{let r=new Map(t),i=r.get(e);if(!i)return t;let{retrying:a,...o}=i;return r.set(e,{...o,bytesWritten:n.bytesWritten,totalBytes:n.totalBytes??i.totalBytes}),r}):n.type===`retrying`?u(t=>{let r=new Map(t),i=r.get(e);return i?(r.set(e,{...i,retrying:{attempt:n.attempt,maxAttempts:n.maxAttempts,delayMs:n.delayMs,reason:n.reason}}),r):t}):n.type===`error`?u(t=>{let r=new Map(t),i=r.get(e);return i&&r.set(e,{...i,error:n.error,retrying:void 0}),r}):n.type===`done`&&setTimeout(()=>{u(t=>{let n=new Map(t);return n.delete(e),n}),y(),t?.()},800)},r.signal).catch(t=>{r.signal.aborted||u(n=>{let r=new Map(n),i=r.get(e);return i&&r.set(e,{...i,error:t.message}),r})})},[y,t]);(0,m.useEffect)(()=>{y();let e=!1;return i.listActiveImagePulls().then(({pulls:t})=>{if(!e)for(let e of t)e.finished||(u(t=>{if(t.has(e.id))return t;let n=new Map(t);return n.set(e.id,{id:e.id,bytesWritten:e.bytesWritten,totalBytes:e.totalBytes,controller:new AbortController,...e.retrying?{retrying:e.retrying}:{},...e.error?{error:e.error}:{}}),n}),S(e.id,(t,n)=>i.subscribeImagePull(e.id,t,n)))}).catch(()=>{}),()=>{e=!0}},[y,S]);let w=(0,m.useCallback)(e=>{v.current.has(e)||S(e,(t,n)=>i.pullImageModel(e,t,n))},[S]),T=(0,m.useCallback)(e=>{v.current.get(e)?.controller.abort(),u(t=>{let n=new Map(t);return n.delete(e),n}),S(e,(t,n)=>i.pullImageModel(e,t,n))},[S]),E=(0,m.useCallback)(e=>{v.current.get(e)?.controller.abort(),u(t=>{let n=new Map(t);return n.delete(e),n}),i.cancelImagePull(e).catch(()=>{})},[]),D=(0,m.useCallback)(async()=>{if(g)try{await i.deleteImageModel(g),await y(),t?.()}catch(e){c(e.message)}finally{_(null)}},[g,y,t]),O=(0,m.useMemo)(()=>new Set(a.map(e=>e.id)),[a]),k=!!r&&a.length>0,A=n&&O.has(n)?n:a[0]?.id;return(0,h.jsxs)(`div`,{className:`ollama-model-manager`,children:[l.size>0&&(0,h.jsxs)(`div`,{className:`ollama-section`,children:[(0,h.jsx)(`h4`,{children:`Downloading…`}),(0,h.jsx)(`div`,{className:`ollama-pull-list`,children:Array.from(l.values()).map(e=>(0,h.jsx)(C,{pull:e,onCancel:()=>E(e.id),onRetry:()=>T(e.id)},e.id))})]}),(a.length>0||s)&&(0,h.jsxs)(`div`,{className:`ollama-section`,children:[(0,h.jsx)(`h4`,{children:`Local models`}),s&&(0,h.jsx)(`p`,{className:`error`,children:s}),k&&a.length>1&&(0,h.jsxs)(`p`,{className:`muted small`,children:[`The `,(0,h.jsx)(`strong`,{children:`active`}),` model is what the image-generator gezel and the`,` `,(0,h.jsx)(`code`,{children:`render_image`}),` tool use by default. A gezel can still ask for a specific model per image; switching reloads the engine, which takes a moment.`]}),a.length>0&&(0,h.jsxs)(`table`,{className:`ollama-model-table`,children:[(0,h.jsx)(`thead`,{children:(0,h.jsxs)(`tr`,{children:[k&&(0,h.jsx)(`th`,{scope:`col`,className:`gz-active-model-column`,children:`Active`}),(0,h.jsx)(`th`,{children:`Name`}),(0,h.jsx)(`th`,{children:`Size`}),(0,h.jsx)(`th`,{children:`Added`}),(0,h.jsx)(`th`,{})]})}),(0,h.jsx)(`tbody`,{children:a.map(e=>(0,h.jsxs)(`tr`,{children:[k&&(0,h.jsx)(`td`,{className:`gz-active-model-column`,children:(0,h.jsx)(`input`,{type:`radio`,name:`active-image-model`,className:`gz-active-model-radio`,"aria-label":`Use ${e.id} as the active image model`,checked:A===e.id,onChange:()=>{A!==e.id&&r?.(e.id)}})}),(0,h.jsxs)(`td`,{children:[(0,h.jsx)(`code`,{children:e.id}),(0,h.jsx)(`div`,{className:`muted small`,children:e.name})]}),(0,h.jsx)(`td`,{children:b(e.approxSizeBytes)}),(0,h.jsx)(`td`,{className:`muted small`,children:new Date(e.installedAt).toLocaleDateString()}),(0,h.jsx)(`td`,{children:(0,h.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:()=>_(e.id),children:`Delete`})})]},e.id))})]})]}),(0,h.jsxs)(`div`,{className:`ollama-section ollama-section--flat ollama-section--download`,children:[(0,h.jsx)(`h4`,{children:`Download a model`}),(0,h.jsx)(f,{kind:`image-model`,emptyMessage:`No image models in the catalog yet. Remote catalog sources can add entries without an app update.`,action:t=>{if(t.manifest.kind!==`image-model`)return null;let n=t.manifest,r=O.has(n.id),i=l.get(n.id),a=!!i,o=i&&i.totalBytes>0?Math.min(100,Math.round(i.bytesWritten/i.totalBytes*100)):null;return(0,h.jsxs)(`div`,{className:`catalog-ollama-action`,children:[(0,h.jsxs)(`div`,{className:`catalog-ollama-meta`,children:[(0,h.jsxs)(`div`,{className:`catalog-ollama-specs muted small`,children:[(0,h.jsx)(`code`,{children:n.id}),(0,h.jsx)(`span`,{children:`·`}),(0,h.jsx)(`span`,{children:b(n.approxSizeBytes)}),n.quantization&&(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`span`,{children:`·`}),(0,h.jsx)(`span`,{children:n.quantization})]}),(0,h.jsx)(`span`,{children:`·`}),(0,h.jsx)(`span`,{children:x(n.hardwareTier,n.minRamGB)})]}),(0,h.jsx)(`div`,{className:`catalog-ollama-pills`,children:(0,h.jsx)(p,{manifest:n})})]}),(0,h.jsx)(`button`,{type:`button`,disabled:r||a||!!e,title:e??void 0,onClick:()=>void w(n.id),children:r?`On device`:a?o===null?`Downloading…`:`Downloading… ${o}%`:`Download`})]})}})]}),(0,h.jsx)(d,{open:g!==null,title:`Delete image model?`,message:g?`"${g}" will be removed from local storage. This frees disk space; download it again later to use it.`:``,confirmLabel:`Delete`,danger:!0,onCancel:()=>_(null),onConfirm:D})]})}function C({pull:e,onCancel:t,onRetry:n}){let r=e.totalBytes>0,i=r?Math.min(100,Math.round(e.bytesWritten/e.totalBytes*100)):0,a;if(e.error)a=e.error;else if(e.retrying){let t=Math.max(1,Math.round(e.retrying.delayMs/1e3));a=`${e.retrying.reason} — retrying in ${t}s (attempt ${e.retrying.attempt}/${e.retrying.maxAttempts})`}else a=r?`Downloading… (${b(e.bytesWritten)} of ${b(e.totalBytes)}, ${i}%)`:e.bytesWritten>0?`Downloading… (${b(e.bytesWritten)})`:`Preparing download…`;return(0,h.jsxs)(`div`,{className:`ollama-pull${e.error?` ollama-pull-error`:e.retrying?` ollama-pull-warning`:``}`,children:[(0,h.jsxs)(`div`,{className:`ollama-pull-head`,children:[(0,h.jsx)(`code`,{children:e.id}),(0,h.jsx)(`span`,{className:`muted small`,children:a}),e.error?(0,h.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:n,children:`Retry`}):(0,h.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:t,children:`Cancel`})]}),r?(0,h.jsxs)(`div`,{className:`ollama-pull-bar`,children:[(0,h.jsx)(`div`,{className:`ollama-pull-bar-fill`,style:{width:`${i}%`}}),(0,h.jsxs)(`span`,{className:`ollama-pull-bar-label`,children:[i,`%`]})]}):(0,h.jsx)(`div`,{className:`ollama-pull-bar ollama-pull-bar-indeterminate`,children:(0,h.jsx)(`div`,{className:`ollama-pull-bar-fill`})})]})}function w({onModelsChanged:e}){let[t,n]=(0,m.useState)({kind:`idle`}),[r,a]=(0,m.useState)(0),[o,s]=(0,m.useState)(null),[c,l]=(0,m.useState)(``),[u,d]=(0,m.useState)(null),f=(0,m.useCallback)(async()=>{n({kind:`probing`});try{let[e,t]=await Promise.all([i.getImageEngineStatus(),i.getConfig()]);s(t),e.engine.status===`not-configured`?n({kind:`engine-not-configured`,status:e}):e.engine.status===`unreachable`?n({kind:`engine-unreachable`,status:e}):e.modelCount===0?n({kind:`no-models`,status:e}):n({kind:`ready`,status:e})}catch(e){n({kind:`probe-failed`,error:e.message})}},[]);(0,m.useEffect)(()=>{f()},[f,r]);let p=t.kind===`engine-not-configured`||t.kind===`engine-unreachable`||t.kind===`probe-failed`,g=o?.imageProvider??`sd-cpp`,_=`status`in t?t.status.engine.kind??`local`:`local`,y=g===`google-ai`||g===`openai`,b=(0,m.useCallback)(async e=>{d(`switching engine…`);try{let t=await i.updateConfig({imageProvider:e});s(t),l(``),d(null),a(e=>e+1)}catch(e){d(`switch failed: ${e.message}`)}},[]),x=(0,m.useCallback)(async()=>{if(c.trim()){d(`saving key…`);try{let e=g===`google-ai`?{googleAiApiKey:c.trim()}:g===`openai`?{openaiApiKey:c.trim()}:{},t=await i.updateConfig(e);s(t),l(``),d(`key saved`),a(e=>e+1)}catch(e){d(`save failed: ${e.message}`)}}},[c,g]),C=(0,m.useCallback)(async()=>{d(`clearing key…`);try{let e=g===`google-ai`?{googleAiApiKey:``}:g===`openai`?{openaiApiKey:``}:{},t=await i.updateConfig(e);s(t),l(``),d(`key cleared`),a(e=>e+1)}catch(e){d(`clear failed: ${e.message}`)}},[g]),w=(0,m.useCallback)(async e=>{d(`saving…`);try{let t=await i.updateConfig({defaultImageModel:{...o?.defaultImageModel,"sd-cpp":e}});s(t),d(null)}catch(e){d(`save failed: ${e.message}`)}},[o?.defaultImageModel]),O=(0,m.useCallback)(async e=>{d(`saving…`);try{let t=await i.updateConfig({imageGenerationConfirmation:e});s(t),d(null)}catch(e){d(`save failed: ${e.message}`)}},[]),k=E(o?.imageGenerationConfirmation);return(0,h.jsxs)(`div`,{className:`provider-card`,children:[(0,h.jsxs)(`div`,{className:`settings-card-header`,children:[(0,h.jsx)(`h3`,{children:`Image generation`}),(0,h.jsx)(D,{probe:t})]}),(0,h.jsx)(v,{}),(0,h.jsxs)(`label`,{className:`provider-row`,children:[(0,h.jsx)(`span`,{children:`Engine`}),(0,h.jsxs)(`select`,{value:g,onChange:e=>void b(e.target.value),children:[(0,h.jsx)(`option`,{value:`sd-cpp`,children:`Local (Stable Diffusion)`}),(0,h.jsx)(`option`,{value:`google-ai`,children:`Google Nano Banana 2 (cloud)`}),(0,h.jsx)(`option`,{value:`openai`,children:`OpenAI GPT Image 2 (cloud)`})]})]}),g===`sd-cpp`&&(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`p`,{className:`muted small`,children:`Generate images locally through the bundled Stable Diffusion engine.`}),t.kind===`engine-not-configured`&&(0,h.jsxs)(`p`,{className:`error`,children:[`The image engine isn't wired up on this install. Models on disk can't run on their own — they need the `,(0,h.jsx)(`code`,{children:`sd-server`}),` binary or an external server. Set`,` `,(0,h.jsx)(`code`,{children:`GEZEL_SD_SERVER_URL`}),` to point at a running sd-server, or build the bundled binary at`,` `,(0,h.jsxs)(`code`,{children:[`native/build/`,`<`,`platform`,`>`,`/sd-server`]}),`.`,t.status.engine.error&&(0,h.jsxs)(h.Fragment,{children:[` `,(0,h.jsxs)(`span`,{className:`muted small`,children:[`Details: `,t.status.engine.error]})]})]}),t.kind===`engine-unreachable`&&(0,h.jsxs)(`p`,{className:`error`,children:[`The image engine is configured but isn't responding at`,` `,(0,h.jsx)(`code`,{children:t.status.engine.baseUrl}),`. Check whether `,(0,h.jsx)(`code`,{children:`sd-server`}),` is running.`,t.status.engine.error&&(0,h.jsxs)(h.Fragment,{children:[` `,(0,h.jsxs)(`span`,{className:`muted small`,children:[`Details: `,t.status.engine.error]})]})]}),t.kind===`probe-failed`&&(0,h.jsxs)(`p`,{className:`error`,children:[`Couldn't reach the Gezel service. Details: `,t.error]}),(0,h.jsx)(S,{...p?{disabledReason:t.kind===`engine-not-configured`?`Image engine is not configured — downloading a model now would still leave it unrunnable.`:`Image engine is not reachable.`}:{},...o?.defaultImageModel?.[`sd-cpp`]?{configuredDefaultModelId:o.defaultImageModel[`sd-cpp`]}:{},onSetActiveModel:w,onModelsChanged:()=>{a(e=>e+1),e?.()}})]}),g===`google-ai`&&(0,h.jsx)(T,{providerLabel:`Google Nano Banana 2`,modelId:`gemini-3.1-flash-image-preview`,docsHref:`https://ai.google.dev/gemini-api/docs/image-generation`,hasKey:o?.hasGoogleAiApiKey===!0,maskedKey:o?.googleAiApiKey,keyPlaceholder:`AIza…`,keyDraft:c,onKeyDraftChange:l,onSaveKey:x,onClearKey:C,probe:t}),g===`openai`&&(0,h.jsx)(T,{providerLabel:`OpenAI GPT Image 2`,modelId:`gpt-image-2`,docsHref:`https://developers.openai.com/api/docs/models/gpt-image-2`,hasKey:o?.hasOpenaiApiKey===!0,maskedKey:o?.openaiApiKey,keyPlaceholder:`sk-…`,keyDraft:c,onKeyDraftChange:l,onSaveKey:x,onClearKey:C,probe:t}),(y||_===`cloud`)&&(0,h.jsxs)(`fieldset`,{className:`provider-row`,style:{flexDirection:`column`,alignItems:`flex-start`},children:[(0,h.jsx)(`legend`,{children:`Cost confirmation`}),(0,h.jsx)(`p`,{className:`muted small`,children:`Cloud image generations cost real money. Choose whether you want to be asked before each cloud generation.`}),(0,h.jsxs)(`label`,{className:`provider-row`,children:[(0,h.jsx)(`input`,{type:`radio`,name:`image-confirmation`,value:`ask`,checked:k===`ask`,onChange:()=>void O(`ask`)}),(0,h.jsx)(`span`,{children:`Ask before each cloud image (default)`})]}),(0,h.jsxs)(`label`,{className:`provider-row`,children:[(0,h.jsx)(`input`,{type:`radio`,name:`image-confirmation`,value:`always-allow`,checked:k===`always-allow`,onChange:()=>void O(`always-allow`)}),(0,h.jsx)(`span`,{children:`Always allow without asking`})]})]}),u&&(0,h.jsx)(`p`,{className:`muted small`,children:u})]})}function T({providerLabel:e,modelId:t,docsHref:n,hasKey:r,maskedKey:i,keyPlaceholder:a,keyDraft:o,onKeyDraftChange:s,onSaveKey:c,onClearKey:l,probe:u}){return(0,h.jsxs)(h.Fragment,{children:[(0,h.jsxs)(`p`,{className:`muted small`,children:[`Generate images through `,(0,h.jsx)(`strong`,{children:e}),`. Models are managed by the provider; you only need an API key. Default model: `,(0,h.jsx)(`code`,{children:t}),`.`,` `,(0,h.jsx)(`a`,{href:n,target:`_blank`,rel:`noreferrer`,children:`Provider docs ↗`})]}),u.kind===`engine-not-configured`&&(0,h.jsxs)(`p`,{className:`error`,children:[`API key not configured. Add a key below to enable `,e,`.`]}),u.kind===`engine-unreachable`&&(0,h.jsxs)(`p`,{className:`error`,children:[e,` isn't reachable.`,u.status.engine.error&&(0,h.jsxs)(h.Fragment,{children:[` `,(0,h.jsxs)(`span`,{className:`muted small`,children:[`Details: `,u.status.engine.error]})]})]}),(0,h.jsxs)(`div`,{className:`provider-row`,children:[(0,h.jsxs)(`span`,{children:[`API key `,r&&(0,h.jsxs)(`span`,{className:`muted small`,children:[`(`,i,`)`]})]}),(0,h.jsx)(`input`,{type:`password`,autoComplete:`off`,placeholder:a,value:o,onChange:e=>s(e.target.value),style:{flex:1}}),(0,h.jsx)(`button`,{type:`button`,onClick:c,disabled:!o.trim(),children:`Save`}),r&&(0,h.jsx)(`button`,{type:`button`,className:`subtle`,onClick:l,children:`Clear`})]})]})}function E(e){return e===`always-allow`?`always-allow`:`ask`}function D({probe:e}){switch(e.kind){case`idle`:case`probing`:return(0,h.jsx)(`span`,{className:`gz-status-pill`,children:`Probing…`});case`ready`:return(0,h.jsx)(`span`,{className:`gz-status-pill gz-status-pill--ok`,children:`Ready`});case`no-models`:return(0,h.jsx)(`span`,{className:`gz-status-pill gz-status-pill--warn`,children:`No local models`});case`engine-not-configured`:return(0,h.jsx)(`span`,{className:`gz-status-pill gz-status-pill--warn`,children:`Engine not configured`});case`engine-unreachable`:return(0,h.jsx)(`span`,{className:`gz-status-pill gz-status-pill--fail`,children:`Engine unreachable`});case`probe-failed`:return(0,h.jsx)(`span`,{className:`gz-status-pill gz-status-pill--fail`,children:`Service unreachable`})}}export{w as ImageEngineSettings};
|
|
1
|
+
import{i as e}from"./rolldown-runtime-aKtaBQYM.js";import{n as t,t as n}from"./jsx-runtime-CEpd2cAX.js";import{Bt as r}from"./dist-CE5CbmDb.js";import{t as i}from"./api-CmrgM5Rf.js";import{G as a,J as o,K as s,W as c,Y as l,q as u}from"./primitives-CWrGZpPI.js";import{t as d}from"./ConfirmDialog-Dt1ed4Fh.js";import{t as f}from"./CatalogBrowser-DYXUZQ_t.js";import{t as p}from"./LicenseButton-D3VmcVG1.js";var m=e(t(),1),h=n(),g=`image-generator`,_=`generate_image`;function v(){let[e,t]=(0,m.useState)([]),[n,r]=(0,m.useState)(!0),[a,o]=(0,m.useState)(!1),s=(0,m.useCallback)(async()=>{r(!0);try{let e=await i.listGezels();t(e.gezels)}catch{}finally{r(!1)}},[]);(0,m.useEffect)(()=>{s();let e=()=>void s();return window.addEventListener(`gezel:gezel-updated`,e),()=>window.removeEventListener(`gezel:gezel-updated`,e)},[s]);let c=(0,m.useMemo)(()=>e.filter(e=>e.fixedFunction?.tool===_),[e]),l=(0,m.useCallback)(e=>{window.dispatchEvent(new CustomEvent(`gezel:open-tab`,{detail:{kind:`gezel`,id:e,activate:!0}}))},[]),u=(0,m.useCallback)(e=>{o(!1),s(),l(e.id)},[s,l]);return n?null:(0,h.jsxs)(`div`,{className:`ff-img-hint`,children:[c.length>0?(0,h.jsxs)(`div`,{className:`ff-img-hint-have`,children:[(0,h.jsx)(`span`,{className:`muted small`,children:`Image-generator gezel`}),c.length===1?(0,h.jsx)(`button`,{type:`button`,className:`link-btn`,onClick:()=>l(c[0].id),title:`Open ${c[0].name}`,children:c[0].name}):(0,h.jsx)(`span`,{children:c.map((e,t)=>(0,h.jsxs)(`span`,{children:[(0,h.jsx)(`button`,{type:`button`,className:`link-btn`,onClick:()=>l(e.id),title:`Open ${e.name}`,children:e.name}),t<c.length-1&&(0,h.jsx)(`span`,{className:`muted`,children:`, `})]},e.id))}),(0,h.jsx)(`span`,{className:`muted small`,children:`— @-mention them in chat to generate.`})]}):(0,h.jsxs)(`div`,{className:`ff-img-hint-empty`,children:[(0,h.jsxs)(`p`,{className:`muted small`,children:[`Once an engine is set up, the easiest way to use it from chat is to add an`,` `,(0,h.jsx)(`strong`,{children:`image-generator gezel`}),`. They forward your @-mention text straight to`,` `,(0,h.jsx)(`code`,{children:_}),` — no LLM in the middle.`]}),(0,h.jsx)(`button`,{type:`button`,className:`primary`,onClick:()=>o(!0),children:`Add an image-generator gezel`})]}),(0,h.jsx)(y,{open:a,onClose:()=>o(!1),onCreated:u})]})}function y({open:e,onClose:t,onCreated:n}){let[d,f]=(0,m.useState)(()=>r()),[p,v]=(0,m.useState)(null),[y,b]=(0,m.useState)(!1),[x,S]=(0,m.useState)(null),[C,w]=(0,m.useState)(!1),T=(0,m.useRef)(!1);(0,m.useEffect)(()=>{!e||T.current||(T.current=!0,w(!0),i.getCatalogItem(`gezel-template`,g).then(e=>{e.manifest.kind===`gezel-template`&&v(e.manifest.description)}).catch(e=>{S(e instanceof Error?e.message:String(e))}).finally(()=>w(!1)))},[e]),(0,m.useEffect)(()=>{e&&(f(r()),S(null),b(!1))},[e]);let E=()=>f(r()),D=(0,m.useCallback)(async()=>{if(d.trim()){b(!0),S(null);try{n(await i.createGezelFromTemplate(g,{name:d.trim()}))}catch(e){S(e instanceof Error?e.message:String(e))}finally{b(!1)}}},[d,n]);return(0,h.jsx)(o,{open:e,onOpenChange:e=>{!e&&!y&&t()},children:(0,h.jsxs)(u,{children:[(0,h.jsx)(s,{}),(0,h.jsxs)(c,{className:`template-picker-dialog`,children:[(0,h.jsxs)(`header`,{style:{display:`flex`,justifyContent:`space-between`,alignItems:`baseline`},children:[(0,h.jsx)(l,{asChild:!0,children:(0,h.jsx)(`h3`,{style:{margin:0},children:`Add an image-generator gezel`})}),(0,h.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:t,disabled:y,children:`Cancel`})]}),(0,h.jsxs)(a,{className:`muted small`,style:{margin:`0.25rem 0 0.5rem 0`},children:[`Forwards your @-mention text straight to `,(0,h.jsx)(`code`,{children:_}),`. No LLM is invoked.`]}),C&&(0,h.jsx)(`p`,{className:`muted small`,children:`Loading template…`}),p&&(0,h.jsx)(`p`,{className:`muted small`,children:p}),(0,h.jsx)(`form`,{onSubmit:e=>{e.preventDefault(),D()},style:{marginTop:`0.5rem`,padding:`0.6rem`,background:`rgba(79, 125, 255, 0.06)`,borderRadius:`6px`,display:`flex`,flexDirection:`column`,gap:`0.5rem`},children:(0,h.jsxs)(`div`,{style:{display:`flex`,gap:`0.5rem`,alignItems:`center`},children:[(0,h.jsx)(`span`,{className:`muted small`,style:{flexShrink:0},children:`Name:`}),(0,h.jsx)(`input`,{value:d,onChange:e=>f(e.target.value),disabled:y,style:{flex:1}}),(0,h.jsx)(`button`,{type:`button`,className:`dice-btn`,onClick:E,disabled:y,title:`Pick a random name`,"aria-label":`Pick a random name`,children:`🎲`}),(0,h.jsx)(`button`,{type:`submit`,className:`primary`,disabled:y||!d.trim(),children:y?`Creating…`:`Create`})]})}),x&&(0,h.jsx)(`p`,{className:`error`,children:x})]})]})})}function b(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 x(e,t){switch(e){case`low`:return`Runs on ${t} GB`;case`mid`:return`${t} GB+`;case`high`:return`${t} GB+ recommended`;case`workstation`:return`${t} GB+ workstation`}}function S({disabledReason:e,onModelsChanged:t,configuredDefaultModelId:n,onSetActiveModel:r}){let[a,o]=(0,m.useState)([]),[s,c]=(0,m.useState)(null),[l,u]=(0,m.useState)(new Map),[g,_]=(0,m.useState)(null),v=(0,m.useRef)(l);v.current=l;let y=(0,m.useCallback)(async()=>{try{let e=await i.listInstalledImageModels();o(e.models),c(null)}catch(e){o([]),c(e.message)}},[]),S=(0,m.useCallback)((e,n)=>{let r=new AbortController;u(t=>{let n=new Map(t),i=n.get(e);return n.set(e,{...i??{id:e,bytesWritten:0,totalBytes:0},controller:r}),n}),n(n=>{n.type===`progress`?u(t=>{let r=new Map(t),i=r.get(e);if(!i)return t;let{retrying:a,...o}=i;return r.set(e,{...o,bytesWritten:n.bytesWritten,totalBytes:n.totalBytes??i.totalBytes}),r}):n.type===`retrying`?u(t=>{let r=new Map(t),i=r.get(e);return i?(r.set(e,{...i,retrying:{attempt:n.attempt,maxAttempts:n.maxAttempts,delayMs:n.delayMs,reason:n.reason}}),r):t}):n.type===`error`?u(t=>{let r=new Map(t),i=r.get(e);return i&&r.set(e,{...i,error:n.error,retrying:void 0}),r}):n.type===`done`&&setTimeout(()=>{u(t=>{let n=new Map(t);return n.delete(e),n}),y(),t?.()},800)},r.signal).catch(t=>{r.signal.aborted||u(n=>{let r=new Map(n),i=r.get(e);return i&&r.set(e,{...i,error:t.message}),r})})},[y,t]);(0,m.useEffect)(()=>{y();let e=!1;return i.listActiveImagePulls().then(({pulls:t})=>{if(!e)for(let e of t)e.finished||(u(t=>{if(t.has(e.id))return t;let n=new Map(t);return n.set(e.id,{id:e.id,bytesWritten:e.bytesWritten,totalBytes:e.totalBytes,controller:new AbortController,...e.retrying?{retrying:e.retrying}:{},...e.error?{error:e.error}:{}}),n}),S(e.id,(t,n)=>i.subscribeImagePull(e.id,t,n)))}).catch(()=>{}),()=>{e=!0}},[y,S]);let w=(0,m.useCallback)(e=>{v.current.has(e)||S(e,(t,n)=>i.pullImageModel(e,t,n))},[S]),T=(0,m.useCallback)(e=>{v.current.get(e)?.controller.abort(),u(t=>{let n=new Map(t);return n.delete(e),n}),S(e,(t,n)=>i.pullImageModel(e,t,n))},[S]),E=(0,m.useCallback)(e=>{v.current.get(e)?.controller.abort(),u(t=>{let n=new Map(t);return n.delete(e),n}),i.cancelImagePull(e).catch(()=>{})},[]),D=(0,m.useCallback)(async()=>{if(g)try{await i.deleteImageModel(g),await y(),t?.()}catch(e){c(e.message)}finally{_(null)}},[g,y,t]),O=(0,m.useMemo)(()=>new Set(a.map(e=>e.id)),[a]),k=!!r&&a.length>0,A=n&&O.has(n)?n:a[0]?.id;return(0,h.jsxs)(`div`,{className:`ollama-model-manager`,children:[l.size>0&&(0,h.jsxs)(`div`,{className:`ollama-section`,children:[(0,h.jsx)(`h4`,{children:`Downloading…`}),(0,h.jsx)(`div`,{className:`ollama-pull-list`,children:Array.from(l.values()).map(e=>(0,h.jsx)(C,{pull:e,onCancel:()=>E(e.id),onRetry:()=>T(e.id)},e.id))})]}),(a.length>0||s)&&(0,h.jsxs)(`div`,{className:`ollama-section`,children:[(0,h.jsx)(`h4`,{children:`Local models`}),s&&(0,h.jsx)(`p`,{className:`error`,children:s}),k&&a.length>1&&(0,h.jsxs)(`p`,{className:`muted small`,children:[`The `,(0,h.jsx)(`strong`,{children:`active`}),` model is what the image-generator gezel and the`,` `,(0,h.jsx)(`code`,{children:`render_image`}),` tool use by default. A gezel can still ask for a specific model per image; switching reloads the engine, which takes a moment.`]}),a.length>0&&(0,h.jsxs)(`table`,{className:`ollama-model-table`,children:[(0,h.jsx)(`thead`,{children:(0,h.jsxs)(`tr`,{children:[k&&(0,h.jsx)(`th`,{scope:`col`,className:`gz-active-model-column`,children:`Active`}),(0,h.jsx)(`th`,{children:`Name`}),(0,h.jsx)(`th`,{children:`Size`}),(0,h.jsx)(`th`,{children:`Added`}),(0,h.jsx)(`th`,{})]})}),(0,h.jsx)(`tbody`,{children:a.map(e=>(0,h.jsxs)(`tr`,{children:[k&&(0,h.jsx)(`td`,{className:`gz-active-model-column`,children:(0,h.jsx)(`input`,{type:`radio`,name:`active-image-model`,className:`gz-active-model-radio`,"aria-label":`Use ${e.id} as the active image model`,checked:A===e.id,onChange:()=>{A!==e.id&&r?.(e.id)}})}),(0,h.jsxs)(`td`,{children:[(0,h.jsx)(`code`,{children:e.id}),(0,h.jsx)(`div`,{className:`muted small`,children:e.name})]}),(0,h.jsx)(`td`,{children:b(e.approxSizeBytes)}),(0,h.jsx)(`td`,{className:`muted small`,children:new Date(e.installedAt).toLocaleDateString()}),(0,h.jsx)(`td`,{children:(0,h.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:()=>_(e.id),children:`Delete`})})]},e.id))})]})]}),(0,h.jsxs)(`div`,{className:`ollama-section ollama-section--flat ollama-section--download`,children:[(0,h.jsx)(`h4`,{children:`Download a model`}),(0,h.jsx)(f,{kind:`image-model`,emptyMessage:`No image models in the catalog yet. Remote catalog sources can add entries without an app update.`,action:t=>{if(t.manifest.kind!==`image-model`)return null;let n=t.manifest,r=O.has(n.id),i=l.get(n.id),a=!!i,o=i&&i.totalBytes>0?Math.min(100,Math.round(i.bytesWritten/i.totalBytes*100)):null;return(0,h.jsxs)(`div`,{className:`catalog-ollama-action`,children:[(0,h.jsxs)(`div`,{className:`catalog-ollama-meta`,children:[(0,h.jsxs)(`div`,{className:`catalog-ollama-specs muted small`,children:[(0,h.jsx)(`code`,{children:n.id}),(0,h.jsx)(`span`,{children:`·`}),(0,h.jsx)(`span`,{children:b(n.approxSizeBytes)}),n.quantization&&(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`span`,{children:`·`}),(0,h.jsx)(`span`,{children:n.quantization})]}),(0,h.jsx)(`span`,{children:`·`}),(0,h.jsx)(`span`,{children:x(n.hardwareTier,n.minRamGB)})]}),(0,h.jsx)(`div`,{className:`catalog-ollama-pills`,children:(0,h.jsx)(p,{manifest:n})})]}),(0,h.jsx)(`button`,{type:`button`,disabled:r||a||!!e,title:e??void 0,onClick:()=>void w(n.id),children:r?`On device`:a?o===null?`Downloading…`:`Downloading… ${o}%`:`Download`})]})}})]}),(0,h.jsx)(d,{open:g!==null,title:`Delete image model?`,message:g?`"${g}" will be removed from local storage. This frees disk space; download it again later to use it.`:``,confirmLabel:`Delete`,danger:!0,onCancel:()=>_(null),onConfirm:D})]})}function C({pull:e,onCancel:t,onRetry:n}){let r=e.totalBytes>0,i=r?Math.min(100,Math.round(e.bytesWritten/e.totalBytes*100)):0,a;if(e.error)a=e.error;else if(e.retrying){let t=Math.max(1,Math.round(e.retrying.delayMs/1e3));a=`${e.retrying.reason} — retrying in ${t}s (attempt ${e.retrying.attempt}/${e.retrying.maxAttempts})`}else a=r?`Downloading… (${b(e.bytesWritten)} of ${b(e.totalBytes)}, ${i}%)`:e.bytesWritten>0?`Downloading… (${b(e.bytesWritten)})`:`Preparing download…`;return(0,h.jsxs)(`div`,{className:`ollama-pull${e.error?` ollama-pull-error`:e.retrying?` ollama-pull-warning`:``}`,children:[(0,h.jsxs)(`div`,{className:`ollama-pull-head`,children:[(0,h.jsx)(`code`,{children:e.id}),(0,h.jsx)(`span`,{className:`muted small`,children:a}),e.error?(0,h.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:n,children:`Retry`}):(0,h.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:t,children:`Cancel`})]}),r?(0,h.jsxs)(`div`,{className:`ollama-pull-bar`,children:[(0,h.jsx)(`div`,{className:`ollama-pull-bar-fill`,style:{width:`${i}%`}}),(0,h.jsxs)(`span`,{className:`ollama-pull-bar-label`,children:[i,`%`]})]}):(0,h.jsx)(`div`,{className:`ollama-pull-bar ollama-pull-bar-indeterminate`,children:(0,h.jsx)(`div`,{className:`ollama-pull-bar-fill`})})]})}function w({onModelsChanged:e}){let[t,n]=(0,m.useState)({kind:`idle`}),[r,a]=(0,m.useState)(0),[o,s]=(0,m.useState)(null),[c,l]=(0,m.useState)(``),[u,d]=(0,m.useState)(null),f=(0,m.useCallback)(async()=>{n({kind:`probing`});try{let[e,t]=await Promise.all([i.getImageEngineStatus(),i.getConfig()]);s(t),e.engine.status===`not-configured`?n({kind:`engine-not-configured`,status:e}):e.engine.status===`unreachable`?n({kind:`engine-unreachable`,status:e}):e.modelCount===0?n({kind:`no-models`,status:e}):n({kind:`ready`,status:e})}catch(e){n({kind:`probe-failed`,error:e.message})}},[]);(0,m.useEffect)(()=>{f()},[f,r]);let p=t.kind===`engine-not-configured`||t.kind===`engine-unreachable`||t.kind===`probe-failed`,g=o?.imageProvider??`sd-cpp`,_=`status`in t?t.status.engine.kind??`local`:`local`,y=g===`google-ai`||g===`openai`,b=(0,m.useCallback)(async e=>{d(`switching engine…`);try{let t=await i.updateConfig({imageProvider:e});s(t),l(``),d(null),a(e=>e+1)}catch(e){d(`switch failed: ${e.message}`)}},[]),x=(0,m.useCallback)(async()=>{if(c.trim()){d(`saving key…`);try{let e=g===`google-ai`?{googleAiApiKey:c.trim()}:g===`openai`?{openaiApiKey:c.trim()}:{},t=await i.updateConfig(e);s(t),l(``),d(`key saved`),a(e=>e+1)}catch(e){d(`save failed: ${e.message}`)}}},[c,g]),C=(0,m.useCallback)(async()=>{d(`clearing key…`);try{let e=g===`google-ai`?{googleAiApiKey:``}:g===`openai`?{openaiApiKey:``}:{},t=await i.updateConfig(e);s(t),l(``),d(`key cleared`),a(e=>e+1)}catch(e){d(`clear failed: ${e.message}`)}},[g]),w=(0,m.useCallback)(async e=>{d(`saving…`);try{let t=await i.updateConfig({defaultImageModel:{...o?.defaultImageModel,"sd-cpp":e}});s(t),d(null)}catch(e){d(`save failed: ${e.message}`)}},[o?.defaultImageModel]),O=(0,m.useCallback)(async e=>{d(`saving…`);try{let t=await i.updateConfig({imageGenerationConfirmation:e});s(t),d(null)}catch(e){d(`save failed: ${e.message}`)}},[]),k=E(o?.imageGenerationConfirmation);return(0,h.jsxs)(`div`,{className:`provider-card`,children:[(0,h.jsxs)(`div`,{className:`settings-card-header`,children:[(0,h.jsx)(`h3`,{children:`Image generation`}),(0,h.jsx)(D,{probe:t})]}),(0,h.jsx)(v,{}),(0,h.jsxs)(`label`,{className:`provider-row`,children:[(0,h.jsx)(`span`,{children:`Engine`}),(0,h.jsxs)(`select`,{value:g,onChange:e=>void b(e.target.value),children:[(0,h.jsx)(`option`,{value:`sd-cpp`,children:`Local (Stable Diffusion)`}),(0,h.jsx)(`option`,{value:`google-ai`,children:`Google Nano Banana 2 (cloud)`}),(0,h.jsx)(`option`,{value:`openai`,children:`OpenAI GPT Image 2 (cloud)`})]})]}),g===`sd-cpp`&&(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`p`,{className:`muted small`,children:`Generate images locally through the bundled Stable Diffusion engine.`}),t.kind===`engine-not-configured`&&(0,h.jsxs)(`p`,{className:`error`,children:[`The image engine isn't wired up on this install. Models on disk can't run on their own — they need the `,(0,h.jsx)(`code`,{children:`sd-server`}),` binary or an external server. Set`,` `,(0,h.jsx)(`code`,{children:`GEZEL_SD_SERVER_URL`}),` to point at a running sd-server, or build the bundled binary at`,` `,(0,h.jsxs)(`code`,{children:[`native/build/`,`<`,`platform`,`>`,`/sd-server`]}),`.`,t.status.engine.error&&(0,h.jsxs)(h.Fragment,{children:[` `,(0,h.jsxs)(`span`,{className:`muted small`,children:[`Details: `,t.status.engine.error]})]})]}),t.kind===`engine-unreachable`&&(0,h.jsxs)(`p`,{className:`error`,children:[`The image engine is configured but isn't responding at`,` `,(0,h.jsx)(`code`,{children:t.status.engine.baseUrl}),`. Check whether `,(0,h.jsx)(`code`,{children:`sd-server`}),` is running.`,t.status.engine.error&&(0,h.jsxs)(h.Fragment,{children:[` `,(0,h.jsxs)(`span`,{className:`muted small`,children:[`Details: `,t.status.engine.error]})]})]}),t.kind===`probe-failed`&&(0,h.jsxs)(`p`,{className:`error`,children:[`Couldn't reach the Gezel service. Details: `,t.error]}),(0,h.jsx)(S,{...p?{disabledReason:t.kind===`engine-not-configured`?`Image engine is not configured — downloading a model now would still leave it unrunnable.`:`Image engine is not reachable.`}:{},...o?.defaultImageModel?.[`sd-cpp`]?{configuredDefaultModelId:o.defaultImageModel[`sd-cpp`]}:{},onSetActiveModel:w,onModelsChanged:()=>{a(e=>e+1),e?.()}})]}),g===`google-ai`&&(0,h.jsx)(T,{providerLabel:`Google Nano Banana 2`,modelId:`gemini-3.1-flash-image-preview`,docsHref:`https://ai.google.dev/gemini-api/docs/image-generation`,hasKey:o?.hasGoogleAiApiKey===!0,maskedKey:o?.googleAiApiKey,keyPlaceholder:`AIza…`,keyDraft:c,onKeyDraftChange:l,onSaveKey:x,onClearKey:C,probe:t}),g===`openai`&&(0,h.jsx)(T,{providerLabel:`OpenAI GPT Image 2`,modelId:`gpt-image-2`,docsHref:`https://developers.openai.com/api/docs/models/gpt-image-2`,hasKey:o?.hasOpenaiApiKey===!0,maskedKey:o?.openaiApiKey,keyPlaceholder:`sk-…`,keyDraft:c,onKeyDraftChange:l,onSaveKey:x,onClearKey:C,probe:t}),(y||_===`cloud`)&&(0,h.jsxs)(`fieldset`,{className:`provider-row`,style:{flexDirection:`column`,alignItems:`flex-start`},children:[(0,h.jsx)(`legend`,{children:`Cost confirmation`}),(0,h.jsx)(`p`,{className:`muted small`,children:`Cloud image generations cost real money. Choose whether you want to be asked before each cloud generation.`}),(0,h.jsxs)(`label`,{className:`provider-row`,children:[(0,h.jsx)(`input`,{type:`radio`,name:`image-confirmation`,value:`ask`,checked:k===`ask`,onChange:()=>void O(`ask`)}),(0,h.jsx)(`span`,{children:`Ask before each cloud image (default)`})]}),(0,h.jsxs)(`label`,{className:`provider-row`,children:[(0,h.jsx)(`input`,{type:`radio`,name:`image-confirmation`,value:`always-allow`,checked:k===`always-allow`,onChange:()=>void O(`always-allow`)}),(0,h.jsx)(`span`,{children:`Always allow without asking`})]})]}),u&&(0,h.jsx)(`p`,{className:`muted small`,children:u})]})}function T({providerLabel:e,modelId:t,docsHref:n,hasKey:r,maskedKey:i,keyPlaceholder:a,keyDraft:o,onKeyDraftChange:s,onSaveKey:c,onClearKey:l,probe:u}){return(0,h.jsxs)(h.Fragment,{children:[(0,h.jsxs)(`p`,{className:`muted small`,children:[`Generate images through `,(0,h.jsx)(`strong`,{children:e}),`. Models are managed by the provider; you only need an API key. Default model: `,(0,h.jsx)(`code`,{children:t}),`.`,` `,(0,h.jsx)(`a`,{href:n,target:`_blank`,rel:`noreferrer`,children:`Provider docs ↗`})]}),u.kind===`engine-not-configured`&&(0,h.jsxs)(`p`,{className:`error`,children:[`API key not configured. Add a key below to enable `,e,`.`]}),u.kind===`engine-unreachable`&&(0,h.jsxs)(`p`,{className:`error`,children:[e,` isn't reachable.`,u.status.engine.error&&(0,h.jsxs)(h.Fragment,{children:[` `,(0,h.jsxs)(`span`,{className:`muted small`,children:[`Details: `,u.status.engine.error]})]})]}),(0,h.jsxs)(`div`,{className:`provider-row`,children:[(0,h.jsxs)(`span`,{children:[`API key `,r&&(0,h.jsxs)(`span`,{className:`muted small`,children:[`(`,i,`)`]})]}),(0,h.jsx)(`input`,{type:`password`,autoComplete:`off`,placeholder:a,value:o,onChange:e=>s(e.target.value),style:{flex:1}}),(0,h.jsx)(`button`,{type:`button`,onClick:c,disabled:!o.trim(),children:`Save`}),r&&(0,h.jsx)(`button`,{type:`button`,className:`subtle`,onClick:l,children:`Clear`})]})]})}function E(e){return e===`always-allow`?`always-allow`:`ask`}function D({probe:e}){switch(e.kind){case`idle`:case`probing`:return(0,h.jsx)(`span`,{className:`gz-status-pill`,children:`Probing…`});case`ready`:return(0,h.jsx)(`span`,{className:`gz-status-pill gz-status-pill--ok`,children:`Ready`});case`no-models`:return(0,h.jsx)(`span`,{className:`gz-status-pill gz-status-pill--warn`,children:`No local models`});case`engine-not-configured`:return(0,h.jsx)(`span`,{className:`gz-status-pill gz-status-pill--warn`,children:`Engine not configured`});case`engine-unreachable`:return(0,h.jsx)(`span`,{className:`gz-status-pill gz-status-pill--fail`,children:`Engine unreachable`});case`probe-failed`:return(0,h.jsx)(`span`,{className:`gz-status-pill gz-status-pill--fail`,children:`Service unreachable`})}}export{w as ImageEngineSettings};
|
package/dist/ui/assets/{ImageRecognitionSettings-CaSQu5Br.js → ImageRecognitionSettings-DzbvZk5S.js}
RENAMED
|
@@ -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-
|
|
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-CmrgM5Rf.js";import{t as i}from"./ConfirmDialog-Dt1ed4Fh.js";var a=e(t(),1),o=n();function s(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`}var c=[{value:`auto`,label:`When needed`,hint:`Only when the model can't see`},{value:`always`,label:`Always`,hint:`Even for models that can`},{value:`off`,label:`Never`,hint:`Metadata only`}];function l(){let[e,t]=(0,a.useState)(null),[n,l]=(0,a.useState)([]),[f,p]=(0,a.useState)([]),[m,h]=(0,a.useState)(null),[g,_]=(0,a.useState)(`auto`),[v,y]=(0,a.useState)(!1),[b,x]=(0,a.useState)(new Map),[S,C]=(0,a.useState)(null),[w,T]=(0,a.useState)(!1),E=(0,a.useRef)(b);E.current=b;let D=(0,a.useCallback)(async()=>{try{let[e,n,i,a]=await Promise.all([r.getRecognitionHealth(),r.listInstalledRecognitionModels(),r.listRecognitionCatalog(),r.getConfig()]);t(e),l(n.models),p(i.models),_(a.recognition?.mode??`auto`),h(null)}catch(e){h(e.message)}},[]);(0,a.useEffect)(()=>{D()},[D]);let O=(0,a.useCallback)(async e=>{let t=g;_(e),y(!0);try{let t=await r.updateConfig({recognition:{mode:e}});window.dispatchEvent(new CustomEvent(`gezel:config-updated`,{detail:t}))}catch(e){_(t),h(e.message)}finally{y(!1)}},[g]),k=(0,a.useCallback)(e=>{let t=new AbortController;x(n=>new Map(n).set(e.id,{id:e.id,bytesWritten:0,totalBytes:e.approxSizeBytes,controller:t})),r.pullRecognitionModel(e.id,t=>{x(n=>{let r=new Map(n),i=r.get(e.id);return i?(t.type===`progress`?r.set(e.id,{...i,bytesWritten:t.bytesWritten,totalBytes:t.totalBytes??i.totalBytes}):t.type===`error`?r.set(e.id,{...i,error:t.error}):r.delete(e.id),r):n}),t.type===`done`&&D()},t.signal).catch(t=>{x(n=>{let r=new Map(n),i=r.get(e.id);return i&&r.set(e.id,{...i,error:t.message}),r})})},[D]),A=(0,a.useCallback)(async e=>{C(null);try{await r.deleteRecognitionModel(e),await D()}catch(e){h(e.message)}},[D]),j=(0,a.useCallback)(async()=>{try{await r.clearRecognitionCache(),T(!0),window.setTimeout(()=>T(!1),2500)}catch(e){h(e.message)}},[]),M=new Set(n.map(e=>e.id));return(0,o.jsxs)(`div`,{className:`provider-card`,children:[(0,o.jsxs)(`div`,{className:`settings-card-header`,children:[(0,o.jsx)(`h3`,{children:`Image recognition`}),e&&(0,o.jsx)(u,{health:e})]}),(0,o.jsxs)(`p`,{className:`muted small`,children:[`Most models can't see images. When someone pastes a screenshot into a chat with a model that has no vision, a small local model reads the image and passes along a description — so the conversation still works. Runs entirely on this device; weights live under`,` `,(0,o.jsx)(`code`,{children:`~/.gezel/engines/recognition/`}),`. Also available to any gezel through the`,` `,(0,o.jsx)(`code`,{children:`describe_image`}),` tool.`]}),m&&(0,o.jsx)(`p`,{className:`error`,children:m}),(0,o.jsx)(d,{health:e}),(0,o.jsxs)(`section`,{style:{marginTop:`1rem`},children:[(0,o.jsx)(`h4`,{style:{margin:`0 0 0.35rem`},children:`When to read images locally`}),(0,o.jsx)(`p`,{className:`muted small`,style:{marginTop:0},children:`"Always" keeps images on this device even when the chat model could see them itself — cheaper than sending pictures to a paid model, and nothing leaves the machine. Individual gezels can override this.`}),(0,o.jsx)(`div`,{className:`gz-tray`,role:`radiogroup`,"aria-label":`When to read images locally`,children:c.map(e=>(0,o.jsxs)(`button`,{type:`button`,role:`radio`,"aria-checked":g===e.value,disabled:v,className:`gz-key gz-key--stacked${g===e.value?` gz-key-active`:``}`,onClick:()=>void O(e.value),children:[(0,o.jsx)(`span`,{children:e.label}),(0,o.jsx)(`small`,{children:e.hint})]},e.value))})]}),(0,o.jsxs)(`section`,{className:`ollama-section`,style:{marginTop:`1.5rem`},children:[(0,o.jsx)(`h4`,{children:`Models`}),(0,o.jsx)(`div`,{className:`catalog-ollama-list`,children:f.map(e=>{let t=M.has(e.id),n=b.get(e.id),r=n&&n.totalBytes>0?Math.min(100,Math.round(n.bytesWritten/n.totalBytes*100)):null;return(0,o.jsxs)(`div`,{className:`catalog-ollama-action`,children:[(0,o.jsxs)(`div`,{className:`catalog-ollama-meta`,children:[(0,o.jsxs)(`div`,{className:`catalog-ollama-specs muted small`,children:[(0,o.jsx)(`code`,{children:e.id}),(0,o.jsx)(`span`,{children:`·`}),(0,o.jsx)(`span`,{children:s(e.approxSizeBytes)}),(0,o.jsx)(`span`,{children:`·`}),(0,o.jsx)(`span`,{children:e.license})]}),(0,o.jsxs)(`div`,{className:`muted small`,children:[(0,o.jsx)(`strong`,{children:e.name}),` — `,e.description]}),n?.error&&(0,o.jsx)(`div`,{className:`error small`,children:n.error})]}),n?(0,o.jsx)(`button`,{type:`button`,onClick:()=>{n.controller.abort(),x(t=>{let n=new Map(t);return n.delete(e.id),n})},children:r===null?`Downloading…`:`Downloading… ${r}%`}):t?(0,o.jsx)(`button`,{type:`button`,onClick:()=>C(e.id),children:`Remove`}):(0,o.jsx)(`button`,{type:`button`,onClick:()=>k(e),children:`Download`})]},e.id)})})]}),(0,o.jsxs)(`section`,{className:`ollama-section`,style:{marginTop:`1.25rem`},children:[(0,o.jsx)(`h4`,{children:`Cached descriptions`}),(0,o.jsx)(`p`,{className:`muted small`,style:{marginTop:0},children:`Each image is read once and the result is reused, keyed by its contents. Clearing is safe — anything still needed is read again on demand.`}),(0,o.jsx)(`button`,{type:`button`,onClick:()=>void j(),children:w?`Cleared`:`Clear cache`})]}),(0,o.jsx)(i,{open:S!==null,title:`Remove this model?`,message:`The weights are deleted from this device. You can download them again later.`,confirmLabel:`Remove`,danger:!0,onConfirm:()=>{S&&A(S)},onCancel:()=>C(null)})]})}function u({health:e}){return e.state===`ok`?(0,o.jsx)(`span`,{className:`gz-status-pill gz-status-pill--ok`,children:`Ready`}):e.state===`no-model`?(0,o.jsx)(`span`,{className:`gz-status-pill gz-status-pill--warn`,children:`No model`}):e.state===`error`?(0,o.jsx)(`span`,{className:`gz-status-pill gz-status-pill--error`,children:`Error`}):(0,o.jsx)(`span`,{className:`gz-status-pill gz-status-pill--warn`,children:`Unavailable`})}function d({health:e}){return!e||e.state===`ok`?null:e.state===`no-model`?(0,o.jsx)(`p`,{className:`muted small`,children:`Download a model below to turn this on. Until then, images pasted into a chat with a model that can't see are described only by their file details — size, format, and any text stored inside the file.`}):(0,o.jsx)(`p`,{className:`muted small`,children:e.detail??`The recognition engine is unavailable.`})}export{l as ImageRecognitionSettings};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./jsx-runtime-CEpd2cAX.js";import{
|
|
1
|
+
import{t as e}from"./jsx-runtime-CEpd2cAX.js";import{Ut as t}from"./index-DivKnJyx.js";var n=e();function r({items:e,onResume:r,onDelete:i}){return e.length===0?null:(0,n.jsxs)(`div`,{className:`ollama-section`,children:[(0,n.jsx)(`h4`,{children:`Incomplete downloads`}),(0,n.jsx)(`p`,{className:`muted small`,style:{marginBottom:`0.5rem`},children:`These downloads were interrupted or never finished checking. They take up disk space but aren't usable yet.`}),(0,n.jsx)(`div`,{className:`ollama-pull-list`,children:e.map(e=>(0,n.jsx)(`div`,{className:`ollama-pull`,children:(0,n.jsxs)(`div`,{className:`ollama-pull-head`,children:[(0,n.jsx)(`code`,{children:e.name??e.id}),(0,n.jsxs)(`span`,{className:`muted small`,children:[t(e.bytes),e.resumable?``:` · no longer in the catalog`]}),(0,n.jsxs)(`span`,{style:{display:`inline-flex`,gap:`0.75rem`},children:[e.resumable&&(0,n.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:()=>r(e.id),children:`Resume`}),(0,n.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:()=>i(e.id),children:`Delete`})]})]})},e.id))})]})}export{r as t};
|
package/dist/ui/assets/{KnowledgeCatalogsCard-CK9bqdf6.js → KnowledgeCatalogsCard-CHopG_j-.js}
RENAMED
|
@@ -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-CJqyWK6E.js";import{t as i}from"./api-C0I7spBl.js";import{t as a}from"./ConfirmDialog-Dt1ed4Fh.js";import{i as o,n as s,t as c}from"./model-inventory-ykSm_IT5.js";import{Ft as l}from"./index-DDu8nyO6.js";import{t as u}from"./CatalogBrowser-7_jHy5Q3.js";import{n as ee,r as d,t as f}from"./InstallProgressRow-DyKOI4MU.js";import{t as te}from"./IncompleteDownloads-C36lTCMG.js";import{t as ne}from"./LicenseButton-D3VmcVG1.js";var p=e(t(),1),m=n(),h=`Downloading knowledge catalogs needs app network access, which the security policy turns off (Settings → Security).`;function g(e){return e instanceof Error?e.message:String(e)}function _(e){return e instanceof r&&e.status===403?h:`download failed: ${g(e)}`}function re(e){return e.disabledReason?`quarantined — ${e.disabledReason}`:e.enabled?e.mounted?e.vectorCompatible===!1?`active · keyword search only`:`active`:`enabled (not mounted)`:`disabled`}function ie(e){return e.semanticSearch===`keyword-only`||e.vectorCompatible===!1?`Keyword only`:`Semantic`}function v(e){let t=new Date(e);return Number.isNaN(t.getTime())?null:t.toLocaleDateString(void 0,{year:`numeric`,month:`short`})}function y(e){if(e.error)return e.error;if(e.retrying){let t=Math.max(1,Math.round(e.retrying.delayMs/1e3));return`${e.retrying.reason} — retrying in ${t}s (attempt ${e.retrying.attempt}/${e.retrying.maxAttempts})`}switch(e.phase){case`download`:return e.bytesTotal>0?`Downloading ${l(e.bytesDone)} of ${l(e.bytesTotal)}`:e.bytesDone>0?`Downloading ${l(e.bytesDone)}…`:`Preparing download…`;case`retrying`:return`Connection dropped — retrying…`;case`verifying`:return`Checking download…`;case`extract`:return`Unpacking and verifying the catalog…`;case`embedder`:return`Fetching the search model for this catalog…`}}function b(e){return e.error||e.retrying||e.phase!==`download`||e.bytesTotal<=0?null:e.bytesDone/e.bytesTotal*100}function ae(e){return e.kind===`knowledge-catalog`?e:null}function x(e){let t=e.trim();if(!t)return null;if(/^https?:\/\//i.test(t))try{let e=new URL(t);if((e.protocol===`http:`||e.protocol===`https:`)&&e.hostname)return`url`}catch{}if(!/\.gezk$/i.test(t))return null;let n=/^[a-z]:[\\/]/i.test(t),r=/^(?:\\\\|\/\/)[^\\/]+[\\/][^\\/]+/.test(t),i=t.startsWith(`/`);return n||r||i?`file`:null}function S(){let[e,t]=(0,p.useState)(null),[n,r]=(0,p.useState)(new Map),[h,S]=(0,p.useState)([]),[C,w]=(0,p.useState)(new Map),[T,E]=(0,p.useState)(null),[D,O]=(0,p.useState)(null),[k,A]=(0,p.useState)(null),[j,M]=(0,p.useState)(null),[N,P]=(0,p.useState)(``),[F,I]=(0,p.useState)(``),[L,R]=(0,p.useState)(null),z=(0,p.useRef)(!1),B=(0,p.useCallback)(async()=>{try{let[e,n,a]=await Promise.all([i.listKnowledgeCatalogs(),i.listAvailableKnowledgeCatalogs().catch(()=>({catalogs:[]})),i.listIncompleteKnowledgeDownloads().catch(()=>({incomplete:[]}))]);t(e.catalogs),r(new Map(n.catalogs.map(e=>[e.id,e]))),S(a.incomplete)}catch(e){M(g(e))}},[]);(0,p.useEffect)(()=>{B();let e=e=>{o(e)===`knowledge`&&B()};return window.addEventListener(c,e),()=>window.removeEventListener(c,e)},[B]),(0,p.useEffect)(()=>{let e=!1,t=async()=>{try{let t=await i.listKnowledgeActiveInstalls();if(e)return;w(e=>{let n=new Map(e),r=new Set;for(let e of t.installs)r.add(e.jobId),n.get(e.jobId)?.origin!==`local`&&n.set(e.jobId,{jobId:e.jobId,...e.catalogId?{catalogId:e.catalogId}:{},phase:e.phase,bytesDone:e.bytesDone,bytesTotal:e.bytesTotal,origin:`remote`});for(let[e,t]of n)t.origin===`remote`&&!r.has(e)&&n.delete(e);return n});let n=z.current;z.current=t.installs.length>0,n&&t.installs.length===0&&B()}catch{}};t();let n=setInterval(()=>void t(),2e3);return()=>{e=!0,clearInterval(n)}},[B]);let V=(0,p.useCallback)((e,t)=>{if(t.type===`progress`)w(n=>{let r=n.get(e);if(!r)return n;let i=new Map(n),{retrying:a,error:o,...s}=r;return i.set(e,{...s,phase:t.phase,bytesDone:t.bytesDone,bytesTotal:t.bytesTotal||(t.phase===r.phase?r.bytesTotal:0)}),i});else if(t.type===`retrying`)w(n=>{let r=n.get(e);if(!r)return n;let i=new Map(n);return i.set(e,{...r,retrying:{attempt:t.attempt,maxAttempts:t.maxAttempts,delayMs:t.delayMs,reason:t.reason}}),i});else if(t.type===`verifying`)w(t=>{let n=t.get(e);if(!n)return t;let r=new Map(t);return r.set(e,{...n,phase:`verifying`}),r});else if(t.type===`done`)t.warning&&O({id:t.ref.catalogId,message:t.warning});else if(t.type===`error`){if(t.mismatch){w(t=>{let n=new Map(t);return n.delete(e),n}),A({id:e,...t.mismatch});return}w(n=>{let r=n.get(e);if(!r)return n;let i=new Map(n);return i.set(e,{...r,error:t.error,retrying:void 0}),i}),E(t.error)}},[]),H=(0,p.useCallback)(e=>{w(t=>{let n=new Map(t),r=n.get(e);return r?.error?(n.set(e,{...r,controller:void 0}),n):(n.delete(e),n)}),s(`knowledge`),B()},[B]),U=(0,p.useCallback)((e,t,n)=>{if(t.signal.aborted)return;let r=_(n);E(r),w(t=>{let n=t.get(e);if(!n)return t;let i=new Map(t);return i.set(e,{...n,error:n.error??r,retrying:void 0}),i})},[]),W=(0,p.useCallback)((e,t)=>{if(C.has(e))return;E(null),A(null);let n=new AbortController;w(t=>{let r=new Map(t);return r.set(e,{jobId:e,catalogId:e,phase:`download`,bytesDone:0,bytesTotal:0,origin:`local`,controller:n}),r}),(async()=>{try{await i.installKnowledgeCatalogFromCatalog(e,t=>V(e,t),n.signal,t?.version?{version:t.version}:void 0)}catch(t){U(e,n,t)}finally{H(e)}})()},[C,V,U,H]),G=(0,p.useCallback)(async e=>{E(null),A(null);let t;try{({jobId:t}=await i.installKnowledgeCatalog({source:e}))}catch(e){E(_(e));return}let n=new AbortController;w(r=>{let i=new Map(r);return i.set(t,{jobId:t,phase:e.kind===`file`?`verifying`:`download`,bytesDone:0,bytesTotal:0,origin:`local`,controller:n,source:e}),i});try{await i.subscribeKnowledgeInstall(t,e=>V(t,e),n.signal),P(``),I(``)}catch(e){U(t,n,e)}finally{H(t)}},[V,U,H]),K=(0,p.useCallback)(e=>{C.get(e)?.controller?.abort(),i.cancelKnowledgeJob(e).catch(()=>{}),w(t=>{let n=new Map(t);return n.delete(e),n}),B()},[C,B]),q=(0,p.useCallback)(e=>{w(t=>{let n=new Map(t);return n.delete(e.jobId),n}),E(null),e.catalogId?W(e.catalogId):e.source&&G(e.source)},[W,G]),J=(0,p.useCallback)(async e=>{let t=e.trim(),n=x(t);if(!n)return;M(null);let r=F.trim().toLowerCase();if(n===`url`&&!/^[a-f0-9]{64}$/.test(r)){M(`Paste the publisher-provided SHA-256 digest before installing a URL.`);return}await G(n===`url`?{kind:`url`,url:t,expectedSha256:r}:{kind:`file`,path:t})},[F,G]),oe=(0,p.useCallback)(async()=>{let e=await window.__GEZEL__?.selectKnowledgeArchive?.();e&&(P(e),await J(e))},[J]),se=(0,p.useCallback)(async(e,t)=>{M(null);try{await i.updateKnowledgeCatalog(e,{enabled:t})}catch(e){M(g(e))}s(`knowledge`),await B()},[B]),Y=(0,p.useCallback)(async e=>{R(null),M(null);try{await i.removeKnowledgeCatalog(e)}catch(e){M(g(e))}s(`knowledge`),await B()},[B]),ce=(0,p.useCallback)(async e=>{M(null),S(t=>t.filter(t=>t.key!==e));try{await i.deleteIncompleteKnowledgeDownload(e)}catch(e){M(g(e))}await B()},[B]),le=(0,p.useMemo)(()=>h.filter(e=>!(e.catalogId&&C.has(e.catalogId))).map(e=>({id:e.key,name:e.name??e.catalogId??e.key,bytes:e.bytes,updatedAt:e.updatedAt,hasPartial:!0,resumable:e.resumable})),[h,C]),ue=(0,p.useMemo)(()=>new Map(h.map(e=>[e.key,e])),[h]),X=e?.find(e=>e.ref.catalogId===L),Z=x(N),Q=Z===`url`,de=/^[a-fA-F0-9]{64}$/.test(F.trim()),fe=[...C.values()].some(e=>e.source&&!e.error),$=Z!==null&&(!Q||de)&&!fe;return(0,m.jsxs)(`div`,{className:`ollama-model-manager`,"data-testid":`knowledge-catalog-manager`,children:[C.size>0&&(0,m.jsxs)(`div`,{className:`ollama-section`,children:[(0,m.jsx)(`h4`,{children:`Downloading…`}),(0,m.jsx)(`div`,{className:`ollama-pull-list`,children:Array.from(C.values()).map(e=>(0,m.jsx)(f,{title:(0,m.jsx)(`code`,{children:e.catalogId??e.source?.kind??e.jobId}),status:y(e),percent:b(e),tone:e.error?`error`:e.retrying?`warning`:`normal`,onCancel:()=>K(e.jobId),...e.catalogId||e.source?{onRetry:()=>q(e)}:{}},e.jobId))})]}),(0,m.jsx)(te,{items:le,onResume:e=>{let t=ue.get(e);t?.catalogId&&W(t.catalogId)},onDelete:e=>void ce(e)}),k&&(0,m.jsxs)(`div`,{className:`ollama-section`,children:[(0,m.jsxs)(`div`,{className:`gz-status-pill gz-status-pill--warn`,style:{marginBottom:`0.5rem`},children:[`The download of `,(0,m.jsx)(`code`,{children:k.id}),` did not match the catalog's pinned checksum`]}),(0,m.jsx)(`p`,{style:{marginBottom:`0.5rem`},children:`Nothing was installed. The bytes Gezel received are not the release this build's catalog vouches for, so either the catalog entry is wrong or the download was tampered with. Try again later, or wait for a Gezel update with a refreshed catalog.`}),(0,m.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:()=>A(null),children:`Dismiss`})]}),T&&(0,m.jsx)(`div`,{className:`ollama-section`,children:(0,m.jsx)(`p`,{className:`error`,style:{marginBottom:`0.5rem`},children:T})}),D&&(0,m.jsx)(`div`,{className:`ollama-section`,children:(0,m.jsxs)(`div`,{className:`gz-status-pill gz-status-pill--warn`,style:{marginBottom:`0.5rem`},children:[D.id,`: `,D.message]})}),(0,m.jsxs)(`div`,{className:`ollama-section`,children:[(0,m.jsx)(`h4`,{children:`Installed catalogs`}),e===null&&(0,m.jsx)(`p`,{className:`muted small`,children:`loading…`}),e?.length===0&&(0,m.jsxs)(`p`,{className:`muted small`,children:[`Nothing installed yet. Download one below, build one from a folder of Markdown with`,` `,(0,m.jsx)(`code`,{children:`gezel knowledge init`}),` and `,(0,m.jsx)(`code`,{children:`gezel knowledge build`}),`, or install a published .gezk file.`]}),e&&e.length>0&&(0,m.jsx)(`div`,{className:`ollama-model-table-wrap`,children:(0,m.jsxs)(`table`,{className:`ollama-model-table`,children:[(0,m.jsx)(`thead`,{children:(0,m.jsxs)(`tr`,{children:[(0,m.jsx)(`th`,{children:`Name`}),(0,m.jsx)(`th`,{children:`Version`}),(0,m.jsx)(`th`,{children:`Documents`}),(0,m.jsx)(`th`,{children:`Size`}),(0,m.jsx)(`th`,{title:`Semantic search embeds your question with the catalog's own model; keyword-only catalogs match words`,children:`Search`}),(0,m.jsx)(`th`,{children:`Storage`}),(0,m.jsx)(`th`,{children:`Status`}),(0,m.jsx)(`th`,{children:`Enabled`}),(0,m.jsx)(`th`,{})]})}),(0,m.jsx)(`tbody`,{children:e.map(e=>{let t=C.has(e.ref.catalogId);return(0,m.jsxs)(`tr`,{"data-testid":`knowledge-catalog-${e.ref.catalogId}`,children:[(0,m.jsx)(`td`,{className:`model-name-table-cell`,children:(0,m.jsxs)(`div`,{className:`model-name-cell`,children:[(0,m.jsx)(`strong`,{children:e.name??e.ref.catalogId}),(0,m.jsxs)(`div`,{className:`model-name-meta`,children:[(0,m.jsx)(`code`,{children:e.ref.catalogId}),e.language&&(0,m.jsx)(`span`,{className:`muted small`,children:e.language}),e.updateAvailable&&(0,m.jsx)(`span`,{className:`gz-status-pill gz-status-pill--warn`,title:`A newer release is available in the catalog (→ v${e.availableVersion??``}).`,children:`update available`})]})]})}),(0,m.jsxs)(`td`,{children:[`v`,e.ref.version]}),(0,m.jsx)(`td`,{children:e.documents===void 0?`—`:e.documents.toLocaleString()}),(0,m.jsx)(`td`,{children:e.sizeBytes?l(e.sizeBytes):`—`}),(0,m.jsx)(`td`,{children:e.mounted?ie(e):`—`}),(0,m.jsx)(`td`,{title:e.ref.storageScope===`machine-shared`?`Installed once for everyone on this device; removing it only drops it from your account.`:`Stored in your own home folder.`,children:e.ref.storageScope===`machine-shared`?`Shared on this device`:`Only for you`}),(0,m.jsx)(`td`,{className:e.disabledReason?`error`:void 0,children:re(e)}),(0,m.jsx)(`td`,{children:(0,m.jsx)(`input`,{type:`checkbox`,"aria-label":`Enable ${e.name??e.ref.catalogId}`,checked:e.enabled,onChange:t=>void se(e.ref.catalogId,t.target.checked)})}),(0,m.jsx)(`td`,{className:`model-actions-table-cell`,children:(0,m.jsxs)(`div`,{className:`model-action-links`,children:[e.updateAvailable&&e.source===`gilde`&&(0,m.jsx)(`button`,{type:`button`,className:`gz-link-button`,disabled:t,onClick:()=>W(e.ref.catalogId),children:`Update`}),(0,m.jsx)(`button`,{type:`button`,className:`gz-link-button danger`,disabled:t,onClick:()=>R(e.ref.catalogId),children:`Remove`})]})})]},e.ref.catalogId)})})]})})]}),(0,m.jsxs)(`div`,{className:`ollama-section ollama-section--flat ollama-section--download`,children:[(0,m.jsx)(`h4`,{children:`Download a catalog`}),(0,m.jsxs)(`p`,{className:`muted small`,style:{marginTop:0},children:[`Knowledge catalogs are hosted by`,` `,(0,m.jsx)(`a`,{href:`https://huggingface.co`,target:`_blank`,rel:`noreferrer`,style:{color:`inherit`},children:`Hugging Face`}),` `,`as open datasets in the gezk format. Your device downloads them directly and checks every byte against the checksum this version of Gezel pinned.`]}),(0,m.jsx)(u,{kind:`knowledge-catalog`,emptyMessage:`No knowledge catalogs in the catalog for this build yet.`,action:e=>{let t=ae(e.manifest);if(!t)return null;let r=n.get(t.id),i=C.get(t.id),a=i?b(i):null,o=r?.installed,s=o?.updateAvailable??!1,c=!!i||!!o&&!s,u=i?i.phase===`download`?a===null?`Downloading…`:`Downloading… ${Math.round(a)}%`:i.phase===`embedder`?`Fetching search model…`:`Installing…`:o?s?`Update to v${t.version}`:`Installed`:r?.incompleteDownload?`Resume download`:r?.sharedOnDevice?`Add`:`Download`,f=v(t.releasedAt);return(0,m.jsxs)(`div`,{className:`catalog-ollama-action`,children:[(0,m.jsxs)(`div`,{className:`catalog-ollama-meta`,children:[(0,m.jsxs)(`div`,{className:`catalog-ollama-specs muted small`,children:[(0,m.jsx)(ee,{repo:t.huggingface.repo,repoType:`dataset`}),(0,m.jsx)(`span`,{children:`·`}),(0,m.jsx)(`span`,{children:l(t.archiveBytes)}),(0,m.jsx)(`span`,{children:`·`}),(0,m.jsxs)(`span`,{children:[t.documents.toLocaleString(),` documents`]}),(0,m.jsx)(`span`,{children:`·`}),(0,m.jsx)(`span`,{children:t.language}),f&&(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(`span`,{children:`·`}),(0,m.jsx)(`span`,{children:f})]})]}),(0,m.jsxs)(`div`,{className:`catalog-ollama-pills`,children:[(0,m.jsx)(ne,{manifest:t,fallbackHref:d(t.huggingface.repo,`dataset`)}),t.parquet&&(0,m.jsx)(`a`,{className:`hf-repo-link`,href:`${d(t.parquet.repo,`dataset`)}/tree/${encodeURIComponent(t.parquet.revision)}/${t.parquet.dir.split(`/`).map(encodeURIComponent).join(`/`)}`,target:`_blank`,rel:`noreferrer`,title:`The same documents, chunks and embeddings as Parquet tables, for data tools`,children:`Parquet`}),r?.sharedOnDevice&&!o&&(0,m.jsx)(`span`,{className:`gz-status-pill gz-status-pill--ok`,title:`Another account on this device already installed it; adding it to yours takes no download.`,children:`on this device`})]})]}),(0,m.jsx)(`button`,{type:`button`,disabled:c,title:o&&!s?`Installed (v${o.version})`:r?.incompleteDownload?`A partial download is on disk; installing picks up where it stopped.`:void 0,onClick:()=>W(t.id),children:u})]})}})]}),(0,m.jsxs)(`div`,{className:`ollama-section ollama-section--flat`,children:[(0,m.jsx)(`h4`,{children:`Add from a file or URL`}),(0,m.jsxs)(`div`,{className:`new-row`,style:{alignItems:`center`},children:[(0,m.jsx)(`input`,{type:`text`,style:{flex:1},placeholder:`Path to a .gezk file, or an https:// URL`,"aria-label":`Catalog file path or URL`,value:N,onChange:e=>P(e.target.value),onKeyDown:e=>{e.key===`Enter`&&$&&J(N)}}),window.__GEZEL__?.selectKnowledgeArchive&&(0,m.jsx)(`button`,{type:`button`,onClick:()=>void oe(),children:`Browse…`}),Z!==null&&(0,m.jsx)(`button`,{type:`button`,disabled:!$,onClick:()=>void J(N),children:`Install`})]}),Q&&(0,m.jsxs)(`div`,{style:{marginTop:`0.5rem`},children:[(0,m.jsx)(`input`,{type:`text`,style:{width:`100%`},placeholder:`Publisher SHA-256 digest (64 hexadecimal characters)`,"aria-label":`Catalog SHA-256 digest`,value:F,spellCheck:!1,autoCapitalize:`none`,onChange:e=>I(e.target.value),onKeyDown:e=>{e.key===`Enter`&&$&&J(N)}}),(0,m.jsx)(`p`,{className:`muted small`,style:{margin:`0.35rem 0 0`},children:`Remote catalogs are installed only when their bytes match a SHA-256 digest you received from the publisher.`})]})]}),j&&(0,m.jsx)(`p`,{className:`error small`,children:j}),(0,m.jsx)(a,{open:L!==null,title:`Remove ${X?.name??L??``}?`,message:X?.ref.storageScope===`machine-shared`?`Removes this catalog from your account. The shared copy other people on this device use is not touched.`:X?.source===`gilde`?`Deletes this catalog and its files from your account. You can download it again from the catalog any time.`:`Deletes this catalog and its files from your account. If you built it yourself and no longer have the .gezk, this is the only copy.`,confirmLabel:`Remove catalog`,danger:!0,onConfirm:()=>{L&&Y(L)},onCancel:()=>R(null)})]})}function C(){return(0,m.jsxs)(`section`,{style:{marginBottom:`2rem`},"data-testid":`knowledge-settings`,children:[(0,m.jsx)(`h3`,{children:`Knowledge`}),(0,m.jsx)(`p`,{className:`muted`,style:{marginTop:0},children:`Knowledge catalogs are searchable, citable reference libraries — encyclopedias, manuals, your own notes — packaged as .gezk files. Installed catalogs appear in the Knowledge area and your gezellen can search them and cite their sources. Everything stays on this device.`}),(0,m.jsx)(S,{})]})}export{C as KnowledgeCatalogsCard};
|
|
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-BMZhqfv7.js";import{t as i}from"./api-CmrgM5Rf.js";import{t as a}from"./ConfirmDialog-Dt1ed4Fh.js";import{i as o,n as s,t as c}from"./model-inventory-ykSm_IT5.js";import{Ut as l}from"./index-DivKnJyx.js";import{t as u}from"./CatalogBrowser-DYXUZQ_t.js";import{n as ee,r as d,t as f}from"./InstallProgressRow-DyKOI4MU.js";import{t as te}from"./IncompleteDownloads-C8_XyP8O.js";import{t as ne}from"./LicenseButton-D3VmcVG1.js";var p=e(t(),1),m=n(),h=`Downloading knowledge catalogs needs app network access, which the security policy turns off (Settings → Security).`;function g(e){return e instanceof Error?e.message:String(e)}function _(e){return e instanceof r&&e.status===403?h:`download failed: ${g(e)}`}function re(e){return e.disabledReason?`quarantined — ${e.disabledReason}`:e.enabled?e.mounted?e.vectorCompatible===!1?`active · keyword search only`:`active`:`enabled (not mounted)`:`disabled`}function ie(e){return e.semanticSearch===`keyword-only`||e.vectorCompatible===!1?`Keyword only`:`Semantic`}function v(e){let t=new Date(e);return Number.isNaN(t.getTime())?null:t.toLocaleDateString(void 0,{year:`numeric`,month:`short`})}function y(e){if(e.error)return e.error;if(e.retrying){let t=Math.max(1,Math.round(e.retrying.delayMs/1e3));return`${e.retrying.reason} — retrying in ${t}s (attempt ${e.retrying.attempt}/${e.retrying.maxAttempts})`}switch(e.phase){case`download`:return e.bytesTotal>0?`Downloading ${l(e.bytesDone)} of ${l(e.bytesTotal)}`:e.bytesDone>0?`Downloading ${l(e.bytesDone)}…`:`Preparing download…`;case`retrying`:return`Connection dropped — retrying…`;case`verifying`:return`Checking download…`;case`extract`:return`Unpacking and verifying the catalog…`;case`embedder`:return`Fetching the search model for this catalog…`}}function b(e){return e.error||e.retrying||e.phase!==`download`||e.bytesTotal<=0?null:e.bytesDone/e.bytesTotal*100}function ae(e){return e.kind===`knowledge-catalog`?e:null}function x(e){let t=e.trim();if(!t)return null;if(/^https?:\/\//i.test(t))try{let e=new URL(t);if((e.protocol===`http:`||e.protocol===`https:`)&&e.hostname)return`url`}catch{}if(!/\.gezk$/i.test(t))return null;let n=/^[a-z]:[\\/]/i.test(t),r=/^(?:\\\\|\/\/)[^\\/]+[\\/][^\\/]+/.test(t),i=t.startsWith(`/`);return n||r||i?`file`:null}function S(){let[e,t]=(0,p.useState)(null),[n,r]=(0,p.useState)(new Map),[h,S]=(0,p.useState)([]),[C,w]=(0,p.useState)(new Map),[T,E]=(0,p.useState)(null),[D,O]=(0,p.useState)(null),[k,A]=(0,p.useState)(null),[j,M]=(0,p.useState)(null),[N,P]=(0,p.useState)(``),[F,I]=(0,p.useState)(``),[L,R]=(0,p.useState)(null),z=(0,p.useRef)(!1),B=(0,p.useCallback)(async()=>{try{let[e,n,a]=await Promise.all([i.listKnowledgeCatalogs(),i.listAvailableKnowledgeCatalogs().catch(()=>({catalogs:[]})),i.listIncompleteKnowledgeDownloads().catch(()=>({incomplete:[]}))]);t(e.catalogs),r(new Map(n.catalogs.map(e=>[e.id,e]))),S(a.incomplete)}catch(e){M(g(e))}},[]);(0,p.useEffect)(()=>{B();let e=e=>{o(e)===`knowledge`&&B()};return window.addEventListener(c,e),()=>window.removeEventListener(c,e)},[B]),(0,p.useEffect)(()=>{let e=!1,t=async()=>{try{let t=await i.listKnowledgeActiveInstalls();if(e)return;w(e=>{let n=new Map(e),r=new Set;for(let e of t.installs)r.add(e.jobId),n.get(e.jobId)?.origin!==`local`&&n.set(e.jobId,{jobId:e.jobId,...e.catalogId?{catalogId:e.catalogId}:{},phase:e.phase,bytesDone:e.bytesDone,bytesTotal:e.bytesTotal,origin:`remote`});for(let[e,t]of n)t.origin===`remote`&&!r.has(e)&&n.delete(e);return n});let n=z.current;z.current=t.installs.length>0,n&&t.installs.length===0&&B()}catch{}};t();let n=setInterval(()=>void t(),2e3);return()=>{e=!0,clearInterval(n)}},[B]);let V=(0,p.useCallback)((e,t)=>{if(t.type===`progress`)w(n=>{let r=n.get(e);if(!r)return n;let i=new Map(n),{retrying:a,error:o,...s}=r;return i.set(e,{...s,phase:t.phase,bytesDone:t.bytesDone,bytesTotal:t.bytesTotal||(t.phase===r.phase?r.bytesTotal:0)}),i});else if(t.type===`retrying`)w(n=>{let r=n.get(e);if(!r)return n;let i=new Map(n);return i.set(e,{...r,retrying:{attempt:t.attempt,maxAttempts:t.maxAttempts,delayMs:t.delayMs,reason:t.reason}}),i});else if(t.type===`verifying`)w(t=>{let n=t.get(e);if(!n)return t;let r=new Map(t);return r.set(e,{...n,phase:`verifying`}),r});else if(t.type===`done`)t.warning&&O({id:t.ref.catalogId,message:t.warning});else if(t.type===`error`){if(t.mismatch){w(t=>{let n=new Map(t);return n.delete(e),n}),A({id:e,...t.mismatch});return}w(n=>{let r=n.get(e);if(!r)return n;let i=new Map(n);return i.set(e,{...r,error:t.error,retrying:void 0}),i}),E(t.error)}},[]),H=(0,p.useCallback)(e=>{w(t=>{let n=new Map(t),r=n.get(e);return r?.error?(n.set(e,{...r,controller:void 0}),n):(n.delete(e),n)}),s(`knowledge`),B()},[B]),U=(0,p.useCallback)((e,t,n)=>{if(t.signal.aborted)return;let r=_(n);E(r),w(t=>{let n=t.get(e);if(!n)return t;let i=new Map(t);return i.set(e,{...n,error:n.error??r,retrying:void 0}),i})},[]),W=(0,p.useCallback)((e,t)=>{if(C.has(e))return;E(null),A(null);let n=new AbortController;w(t=>{let r=new Map(t);return r.set(e,{jobId:e,catalogId:e,phase:`download`,bytesDone:0,bytesTotal:0,origin:`local`,controller:n}),r}),(async()=>{try{await i.installKnowledgeCatalogFromCatalog(e,t=>V(e,t),n.signal,t?.version?{version:t.version}:void 0)}catch(t){U(e,n,t)}finally{H(e)}})()},[C,V,U,H]),G=(0,p.useCallback)(async e=>{E(null),A(null);let t;try{({jobId:t}=await i.installKnowledgeCatalog({source:e}))}catch(e){E(_(e));return}let n=new AbortController;w(r=>{let i=new Map(r);return i.set(t,{jobId:t,phase:e.kind===`file`?`verifying`:`download`,bytesDone:0,bytesTotal:0,origin:`local`,controller:n,source:e}),i});try{await i.subscribeKnowledgeInstall(t,e=>V(t,e),n.signal),P(``),I(``)}catch(e){U(t,n,e)}finally{H(t)}},[V,U,H]),K=(0,p.useCallback)(e=>{C.get(e)?.controller?.abort(),i.cancelKnowledgeJob(e).catch(()=>{}),w(t=>{let n=new Map(t);return n.delete(e),n}),B()},[C,B]),q=(0,p.useCallback)(e=>{w(t=>{let n=new Map(t);return n.delete(e.jobId),n}),E(null),e.catalogId?W(e.catalogId):e.source&&G(e.source)},[W,G]),J=(0,p.useCallback)(async e=>{let t=e.trim(),n=x(t);if(!n)return;M(null);let r=F.trim().toLowerCase();if(n===`url`&&!/^[a-f0-9]{64}$/.test(r)){M(`Paste the publisher-provided SHA-256 digest before installing a URL.`);return}await G(n===`url`?{kind:`url`,url:t,expectedSha256:r}:{kind:`file`,path:t})},[F,G]),oe=(0,p.useCallback)(async()=>{let e=await window.__GEZEL__?.selectKnowledgeArchive?.();e&&(P(e),await J(e))},[J]),se=(0,p.useCallback)(async(e,t)=>{M(null);try{await i.updateKnowledgeCatalog(e,{enabled:t})}catch(e){M(g(e))}s(`knowledge`),await B()},[B]),Y=(0,p.useCallback)(async e=>{R(null),M(null);try{await i.removeKnowledgeCatalog(e)}catch(e){M(g(e))}s(`knowledge`),await B()},[B]),ce=(0,p.useCallback)(async e=>{M(null),S(t=>t.filter(t=>t.key!==e));try{await i.deleteIncompleteKnowledgeDownload(e)}catch(e){M(g(e))}await B()},[B]),le=(0,p.useMemo)(()=>h.filter(e=>!(e.catalogId&&C.has(e.catalogId))).map(e=>({id:e.key,name:e.name??e.catalogId??e.key,bytes:e.bytes,updatedAt:e.updatedAt,hasPartial:!0,resumable:e.resumable})),[h,C]),ue=(0,p.useMemo)(()=>new Map(h.map(e=>[e.key,e])),[h]),X=e?.find(e=>e.ref.catalogId===L),Z=x(N),Q=Z===`url`,de=/^[a-fA-F0-9]{64}$/.test(F.trim()),fe=[...C.values()].some(e=>e.source&&!e.error),$=Z!==null&&(!Q||de)&&!fe;return(0,m.jsxs)(`div`,{className:`ollama-model-manager`,"data-testid":`knowledge-catalog-manager`,children:[C.size>0&&(0,m.jsxs)(`div`,{className:`ollama-section`,children:[(0,m.jsx)(`h4`,{children:`Downloading…`}),(0,m.jsx)(`div`,{className:`ollama-pull-list`,children:Array.from(C.values()).map(e=>(0,m.jsx)(f,{title:(0,m.jsx)(`code`,{children:e.catalogId??e.source?.kind??e.jobId}),status:y(e),percent:b(e),tone:e.error?`error`:e.retrying?`warning`:`normal`,onCancel:()=>K(e.jobId),...e.catalogId||e.source?{onRetry:()=>q(e)}:{}},e.jobId))})]}),(0,m.jsx)(te,{items:le,onResume:e=>{let t=ue.get(e);t?.catalogId&&W(t.catalogId)},onDelete:e=>void ce(e)}),k&&(0,m.jsxs)(`div`,{className:`ollama-section`,children:[(0,m.jsxs)(`div`,{className:`gz-status-pill gz-status-pill--warn`,style:{marginBottom:`0.5rem`},children:[`The download of `,(0,m.jsx)(`code`,{children:k.id}),` did not match the catalog's pinned checksum`]}),(0,m.jsx)(`p`,{style:{marginBottom:`0.5rem`},children:`Nothing was installed. The bytes Gezel received are not the release this build's catalog vouches for, so either the catalog entry is wrong or the download was tampered with. Try again later, or wait for a Gezel update with a refreshed catalog.`}),(0,m.jsx)(`button`,{type:`button`,className:`gz-link-button`,onClick:()=>A(null),children:`Dismiss`})]}),T&&(0,m.jsx)(`div`,{className:`ollama-section`,children:(0,m.jsx)(`p`,{className:`error`,style:{marginBottom:`0.5rem`},children:T})}),D&&(0,m.jsx)(`div`,{className:`ollama-section`,children:(0,m.jsxs)(`div`,{className:`gz-status-pill gz-status-pill--warn`,style:{marginBottom:`0.5rem`},children:[D.id,`: `,D.message]})}),(0,m.jsxs)(`div`,{className:`ollama-section`,children:[(0,m.jsx)(`h4`,{children:`Installed catalogs`}),e===null&&(0,m.jsx)(`p`,{className:`muted small`,children:`loading…`}),e?.length===0&&(0,m.jsxs)(`p`,{className:`muted small`,children:[`Nothing installed yet. Download one below, build one from a folder of Markdown with`,` `,(0,m.jsx)(`code`,{children:`gezel knowledge init`}),` and `,(0,m.jsx)(`code`,{children:`gezel knowledge build`}),`, or install a published .gezk file.`]}),e&&e.length>0&&(0,m.jsx)(`div`,{className:`ollama-model-table-wrap`,children:(0,m.jsxs)(`table`,{className:`ollama-model-table`,children:[(0,m.jsx)(`thead`,{children:(0,m.jsxs)(`tr`,{children:[(0,m.jsx)(`th`,{children:`Name`}),(0,m.jsx)(`th`,{children:`Version`}),(0,m.jsx)(`th`,{children:`Documents`}),(0,m.jsx)(`th`,{children:`Size`}),(0,m.jsx)(`th`,{title:`Semantic search embeds your question with the catalog's own model; keyword-only catalogs match words`,children:`Search`}),(0,m.jsx)(`th`,{children:`Storage`}),(0,m.jsx)(`th`,{children:`Status`}),(0,m.jsx)(`th`,{children:`Enabled`}),(0,m.jsx)(`th`,{})]})}),(0,m.jsx)(`tbody`,{children:e.map(e=>{let t=C.has(e.ref.catalogId);return(0,m.jsxs)(`tr`,{"data-testid":`knowledge-catalog-${e.ref.catalogId}`,children:[(0,m.jsx)(`td`,{className:`model-name-table-cell`,children:(0,m.jsxs)(`div`,{className:`model-name-cell`,children:[(0,m.jsx)(`strong`,{children:e.name??e.ref.catalogId}),(0,m.jsxs)(`div`,{className:`model-name-meta`,children:[(0,m.jsx)(`code`,{children:e.ref.catalogId}),e.language&&(0,m.jsx)(`span`,{className:`muted small`,children:e.language}),e.updateAvailable&&(0,m.jsx)(`span`,{className:`gz-status-pill gz-status-pill--warn`,title:`A newer release is available in the catalog (→ v${e.availableVersion??``}).`,children:`update available`})]})]})}),(0,m.jsxs)(`td`,{children:[`v`,e.ref.version]}),(0,m.jsx)(`td`,{children:e.documents===void 0?`—`:e.documents.toLocaleString()}),(0,m.jsx)(`td`,{children:e.sizeBytes?l(e.sizeBytes):`—`}),(0,m.jsx)(`td`,{children:e.mounted?ie(e):`—`}),(0,m.jsx)(`td`,{title:e.ref.storageScope===`machine-shared`?`Installed once for everyone on this device; removing it only drops it from your account.`:`Stored in your own home folder.`,children:e.ref.storageScope===`machine-shared`?`Shared on this device`:`Only for you`}),(0,m.jsx)(`td`,{className:e.disabledReason?`error`:void 0,children:re(e)}),(0,m.jsx)(`td`,{children:(0,m.jsx)(`input`,{type:`checkbox`,"aria-label":`Enable ${e.name??e.ref.catalogId}`,checked:e.enabled,onChange:t=>void se(e.ref.catalogId,t.target.checked)})}),(0,m.jsx)(`td`,{className:`model-actions-table-cell`,children:(0,m.jsxs)(`div`,{className:`model-action-links`,children:[e.updateAvailable&&e.source===`gilde`&&(0,m.jsx)(`button`,{type:`button`,className:`gz-link-button`,disabled:t,onClick:()=>W(e.ref.catalogId),children:`Update`}),(0,m.jsx)(`button`,{type:`button`,className:`gz-link-button danger`,disabled:t,onClick:()=>R(e.ref.catalogId),children:`Remove`})]})})]},e.ref.catalogId)})})]})})]}),(0,m.jsxs)(`div`,{className:`ollama-section ollama-section--flat ollama-section--download`,children:[(0,m.jsx)(`h4`,{children:`Download a catalog`}),(0,m.jsxs)(`p`,{className:`muted small`,style:{marginTop:0},children:[`Knowledge catalogs are hosted by`,` `,(0,m.jsx)(`a`,{href:`https://huggingface.co`,target:`_blank`,rel:`noreferrer`,style:{color:`inherit`},children:`Hugging Face`}),` `,`as open datasets in the gezk format. Your device downloads them directly and checks every byte against the checksum this version of Gezel pinned.`]}),(0,m.jsx)(u,{kind:`knowledge-catalog`,emptyMessage:`No knowledge catalogs in the catalog for this build yet.`,action:e=>{let t=ae(e.manifest);if(!t)return null;let r=n.get(t.id),i=C.get(t.id),a=i?b(i):null,o=r?.installed,s=o?.updateAvailable??!1,c=!!i||!!o&&!s,u=i?i.phase===`download`?a===null?`Downloading…`:`Downloading… ${Math.round(a)}%`:i.phase===`embedder`?`Fetching search model…`:`Installing…`:o?s?`Update to v${t.version}`:`Installed`:r?.incompleteDownload?`Resume download`:r?.sharedOnDevice?`Add`:`Download`,f=v(t.releasedAt);return(0,m.jsxs)(`div`,{className:`catalog-ollama-action`,children:[(0,m.jsxs)(`div`,{className:`catalog-ollama-meta`,children:[(0,m.jsxs)(`div`,{className:`catalog-ollama-specs muted small`,children:[(0,m.jsx)(ee,{repo:t.huggingface.repo,repoType:`dataset`}),(0,m.jsx)(`span`,{children:`·`}),(0,m.jsx)(`span`,{children:l(t.archiveBytes)}),(0,m.jsx)(`span`,{children:`·`}),(0,m.jsxs)(`span`,{children:[t.documents.toLocaleString(),` documents`]}),(0,m.jsx)(`span`,{children:`·`}),(0,m.jsx)(`span`,{children:t.language}),f&&(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(`span`,{children:`·`}),(0,m.jsx)(`span`,{children:f})]})]}),(0,m.jsxs)(`div`,{className:`catalog-ollama-pills`,children:[(0,m.jsx)(ne,{manifest:t,fallbackHref:d(t.huggingface.repo,`dataset`)}),t.parquet&&(0,m.jsx)(`a`,{className:`hf-repo-link`,href:`${d(t.parquet.repo,`dataset`)}/tree/${encodeURIComponent(t.parquet.revision)}/${t.parquet.dir.split(`/`).map(encodeURIComponent).join(`/`)}`,target:`_blank`,rel:`noreferrer`,title:`The same documents, chunks and embeddings as Parquet tables, for data tools`,children:`Parquet`}),r?.sharedOnDevice&&!o&&(0,m.jsx)(`span`,{className:`gz-status-pill gz-status-pill--ok`,title:`Another account on this device already installed it; adding it to yours takes no download.`,children:`on this device`})]})]}),(0,m.jsx)(`button`,{type:`button`,disabled:c,title:o&&!s?`Installed (v${o.version})`:r?.incompleteDownload?`A partial download is on disk; installing picks up where it stopped.`:void 0,onClick:()=>W(t.id),children:u})]})}})]}),(0,m.jsxs)(`div`,{className:`ollama-section ollama-section--flat`,children:[(0,m.jsx)(`h4`,{children:`Add from a file or URL`}),(0,m.jsxs)(`div`,{className:`new-row`,style:{alignItems:`center`},children:[(0,m.jsx)(`input`,{type:`text`,style:{flex:1},placeholder:`Path to a .gezk file, or an https:// URL`,"aria-label":`Catalog file path or URL`,value:N,onChange:e=>P(e.target.value),onKeyDown:e=>{e.key===`Enter`&&$&&J(N)}}),window.__GEZEL__?.selectKnowledgeArchive&&(0,m.jsx)(`button`,{type:`button`,onClick:()=>void oe(),children:`Browse…`}),Z!==null&&(0,m.jsx)(`button`,{type:`button`,disabled:!$,onClick:()=>void J(N),children:`Install`})]}),Q&&(0,m.jsxs)(`div`,{style:{marginTop:`0.5rem`},children:[(0,m.jsx)(`input`,{type:`text`,style:{width:`100%`},placeholder:`Publisher SHA-256 digest (64 hexadecimal characters)`,"aria-label":`Catalog SHA-256 digest`,value:F,spellCheck:!1,autoCapitalize:`none`,onChange:e=>I(e.target.value),onKeyDown:e=>{e.key===`Enter`&&$&&J(N)}}),(0,m.jsx)(`p`,{className:`muted small`,style:{margin:`0.35rem 0 0`},children:`Remote catalogs are installed only when their bytes match a SHA-256 digest you received from the publisher.`})]})]}),j&&(0,m.jsx)(`p`,{className:`error small`,children:j}),(0,m.jsx)(a,{open:L!==null,title:`Remove ${X?.name??L??``}?`,message:X?.ref.storageScope===`machine-shared`?`Removes this catalog from your account. The shared copy other people on this device use is not touched.`:X?.source===`gilde`?`Deletes this catalog and its files from your account. You can download it again from the catalog any time.`:`Deletes this catalog and its files from your account. If you built it yourself and no longer have the .gezk, this is the only copy.`,confirmLabel:`Remove catalog`,danger:!0,onConfirm:()=>{L&&Y(L)},onCancel:()=>R(null)})]})}function C(){return(0,m.jsxs)(`section`,{style:{marginBottom:`2rem`},"data-testid":`knowledge-settings`,children:[(0,m.jsx)(`h3`,{children:`Knowledge`}),(0,m.jsx)(`p`,{className:`muted`,style:{marginTop:0},children:`Knowledge catalogs are searchable, citable reference libraries — encyclopedias, manuals, your own notes — packaged as .gezk files. Installed catalogs appear in the Knowledge area and your gezellen can search them and cite their sources. Everything stays on this device.`}),(0,m.jsx)(S,{})]})}export{C as KnowledgeCatalogsCard};
|
|
@@ -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{An as r,kn as i}from"./dist-CE5CbmDb.js";import{t as a}from"./api-CmrgM5Rf.js";import{i as o,t as s}from"./model-inventory-ykSm_IT5.js";import{ft as c}from"./doc-BHcGsJZd.js";import{n as ee}from"./chunk-CW24CH7I-BD0FIooX.js";import"./markdown-CLKH_zzl.js";import{Y as te,z as ne}from"./chunk-6ECMNUIP-D5AA6ozp.js";import{B as re,Ct as l,V as ie,Z as u,tt as ae,wt as oe}from"./index-DivKnJyx.js";import{n as se}from"./composer-prefill-CbG_i1Rx.js";var d=e(t(),1);function ce(e){let t=new Map,n=new Map,r=r=>{let i=t.get(r);if(i)return Promise.resolve(i);let o=n.get(r);if(o)return o;let s=a.fetchKnowledgeAsset(e.catalogId,r,e.version?{version:e.version}:{}).then(e=>{let n=URL.createObjectURL(e);return t.set(r,n),n}).finally(()=>n.delete(r));return n.set(r,s),s};return{async addMedia(){throw Error(`knowledge catalogs are read-only`)},async resolveUrl(e){let t=e.replace(/^\.\//,``);if(!t.startsWith(`assets/`))return e;try{return await r(t)}catch{return e}},async listMedia(){return[]},async removeMedia(){},dispose(){for(let e of t.values())URL.revokeObjectURL(e);t.clear(),n.clear()}}}var f=n(),p=`gezel:knowledge:catalog`,m=`gezel:knowledge:document`,h=50;function g(e){let t=new Map(e.map(e=>[e.id,{...e,children:[]}])),n=[];for(let e of t.values()){let r=e.parentId?t.get(e.parentId):void 0;r?r.children.push(e):n.push(e)}return n}function _(){let[e,t]=(0,d.useState)(null),[n,_]=(0,d.useState)(()=>{try{return window.localStorage.getItem(p)}catch{return null}}),[v,y]=(0,d.useState)([]),[b,x]=(0,d.useState)(null),[S,C]=(0,d.useState)(null),[w,le]=(0,d.useState)(0),[T,E]=(0,d.useState)(!1),[D,O]=(0,d.useState)(()=>{try{return window.localStorage.getItem(m)}catch{return null}}),[k,A]=(0,d.useState)(null),[j,M]=(0,d.useState)(!1),[N,P]=(0,d.useState)(null),[F,I]=(0,d.useState)(``),[L,R]=(0,d.useState)(null),[z,B]=(0,d.useState)(!1),[V,H]=(0,d.useState)(!1),U=(0,d.useRef)(null),W=l()===`light`?re:void 0;(0,d.useEffect)(()=>{let e=!0,n=ae();n&&(_(n.catalogId),n.documentId&&O(n.documentId));let r=()=>{a.listKnowledgeCatalogs().then(n=>{if(!e)return;let r=n.catalogs.filter(e=>e.mounted);t(r),_(e=>(e&&r.some(t=>t.ref.catalogId===e)?e:null)??r[0]?.ref.catalogId??null)}).catch(()=>{e&&t([])})};r();let i=e=>{o(e)===`knowledge`&&r()};window.addEventListener(s,i);let c=e=>{let t=e.detail;t?.catalogId&&(_(t.catalogId),t.documentId&&O(t.documentId))};return window.addEventListener(`gezel:open-knowledge-document`,c),()=>{e=!1,window.removeEventListener(s,i),window.removeEventListener(`gezel:open-knowledge-document`,c)}},[]),(0,d.useEffect)(()=>{try{n&&window.localStorage.setItem(p,n)}catch{}},[n]),(0,d.useEffect)(()=>{if(!n)return;let e=!0;return y([]),x(null),a.knowledgeCatalogTopics(n).then(t=>{e&&y(t.topics)}).catch(()=>{}),()=>{e=!1}},[n]);let G=(0,d.useCallback)(async e=>{if(!n)return;let t=await a.knowledgeCatalogDocuments(n,{...b?{topicId:b}:{},offset:e,limit:h});le(t.total),C(n=>e===0||!n?t.documents:[...n,...t.documents])},[n,b]);(0,d.useEffect)(()=>{C(null),G(0).catch(()=>C([]))},[G]),(0,d.useEffect)(()=>{if(!n||!D){A(null);return}let e=!0;M(!0),P(null),a.readKnowledgeDocument(n,D).then(t=>{e&&A(t)}).catch(t=>{e&&P(t instanceof Error?t.message:String(t))}).finally(()=>{e&&M(!1)});try{window.localStorage.setItem(m,D)}catch{}return()=>{e=!1}},[n,D]),(0,d.useEffect)(()=>{U.current&&window.clearTimeout(U.current);let e=F.trim();if(!e){R(null),B(!1);return}return B(!0),U.current=window.setTimeout(()=>{a.searchKnowledge({query:e,maxResults:20,...n?{catalogs:[n]}:{}}).then(e=>{R(e.results)}).catch(()=>{R([])}).finally(()=>B(!1))},250),()=>{U.current&&window.clearTimeout(U.current)}},[F,n]);let K=(0,d.useMemo)(()=>e?.find(e=>e.ref.catalogId===n)??null,[e,n]),ue=(0,d.useMemo)(()=>g(v),[v]),q=(0,d.useMemo)(()=>new Map(v.map(e=>[e.id,e.name])),[v]),J=(0,d.useMemo)(()=>n?ce({catalogId:n,...K?.ref.version?{version:K.ref.version}:{}}):null,[n,K?.ref.version]),Y=(0,d.useRef)(J);(0,d.useEffect)(()=>(Y.current=J,()=>Y.current?.dispose?.()),[J]);let X=(0,d.useCallback)(t=>{let i=(t.target?.closest?.(`a[href]`))?.getAttribute(`href`);if(!i)return;let a=r(i);if(!a)return;if(t.preventDefault(),t.stopPropagation(),a.catalogId===n){O(a.documentId);return}let o=e?.find(e=>e.ref.catalogId===a.catalogId&&e.ref.publisherId===a.publisherId);o&&(_(o.ref.catalogId),O(a.documentId))},[e,n]),Z=(0,d.useMemo)(()=>{if(!k)return null;try{return c(ee(k.markdown),{articleId:k.id})}catch{return null}},[k]),Q=(0,d.useMemo)(()=>{if(!n||!k)return null;let t=e?.find(e=>e.ref.catalogId===n)?.ref.publisherId;return t?i({publisherId:t,catalogId:n,documentId:k.id}):null},[e,n,k]),de=(0,d.useCallback)(()=>{Q&&navigator.clipboard?.writeText(Q).then(()=>{H(!0),window.setTimeout(()=>H(!1),2e3)})},[Q]),fe=(0,d.useCallback)(()=>{!Q||!k||(se(`default`,`I'm reading "${k.title}" (${Q}). Can you help me with a question about it?\n\n`),u({kind:`project`,id:`default`}))},[Q,k]),pe=(0,d.useCallback)(()=>{oe(`knowledge`),u({kind:`area`,area:`settings`})},[]);if(e!==null&&e.length===0)return(0,f.jsx)(`div`,{className:`knowledge-view`,"data-testid":`knowledge-view`,children:(0,f.jsxs)(`div`,{className:`knowledge-empty`,style:{gridColumn:`1 / -1`},children:[(0,f.jsx)(`h2`,{children:`Knowledge`}),(0,f.jsx)(`p`,{className:`muted`,children:`No knowledge catalogs are installed yet. A catalog is a searchable, citable reference library — install one and your gezellen can look things up and cite their sources.`}),(0,f.jsx)(`button`,{type:`button`,onClick:pe,children:`Open knowledge settings`})]})});let $=(e,t)=>(0,f.jsxs)(`li`,{children:[(0,f.jsxs)(`button`,{type:`button`,className:`knowledge-topic-row`,"aria-current":b===e.id?`true`:void 0,onClick:()=>{x(t=>t===e.id?null:e.id),I(``)},children:[(0,f.jsx)(`span`,{children:e.name}),(0,f.jsx)(`span`,{className:`knowledge-topic-count`,children:e.totalDocumentCount})]}),e.children.length>0&&(0,f.jsx)(`ul`,{children:e.children.map(e=>$(e,t+1))})]},e.id);return(0,f.jsxs)(`div`,{className:`knowledge-view`,"data-testid":`knowledge-view`,children:[(0,f.jsxs)(`nav`,{className:`knowledge-rail`,"aria-label":`Knowledge catalogs and topics`,children:[e&&e.length>1&&(0,f.jsx)(`select`,{"aria-label":`Catalog`,value:n??``,onChange:e=>{_(e.target.value),O(null)},children:e.map(e=>(0,f.jsx)(`option`,{value:e.ref.catalogId,children:e.name??e.ref.catalogId},e.ref.catalogId))}),K&&(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(`h2`,{className:`knowledge-catalog-name`,children:K.name??n}),(0,f.jsxs)(`p`,{className:`knowledge-catalog-meta`,children:[K.documents??`?`,` documents · `,K.license??``,K.ref.version?` · v${K.ref.version}`:``]})]}),(0,f.jsx)(`input`,{type:`search`,className:`knowledge-rail-search`,placeholder:`Search this catalog…`,"aria-label":`Search knowledge`,value:F,onChange:e=>I(e.target.value)}),(0,f.jsx)(`ul`,{className:`knowledge-topics`,children:ue.map(e=>$(e,0))})]}),(0,f.jsx)(`section`,{className:`knowledge-list`,"aria-label":`Documents`,children:F.trim()?(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(`div`,{className:`knowledge-list-header`,children:`Search results`}),z&&(0,f.jsx)(`p`,{className:`muted small`,style:{padding:`0 1rem`},children:`Searching…`}),!z&&L?.length===0&&(0,f.jsxs)(`p`,{className:`muted small`,style:{padding:`0 1rem`},children:[`No results for “`,F.trim(),`”.`]}),(0,f.jsx)(`ul`,{className:`knowledge-doc-list`,children:(L??[]).map(e=>(0,f.jsx)(`li`,{children:(0,f.jsxs)(`button`,{type:`button`,className:`knowledge-doc-row`,"aria-current":e.documentId===D?`true`:void 0,onClick:()=>{e.documentId&&O(e.documentId)},children:[(0,f.jsx)(`span`,{className:`knowledge-doc-title`,children:e.title}),e.snippet&&(0,f.jsx)(`span`,{className:`knowledge-doc-summary`,children:e.snippet})]})},e.id))})]}):(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(`div`,{className:`knowledge-list-header`,children:b?q.get(b)??`Documents`:`All documents`}),S===null&&(0,f.jsx)(`p`,{className:`muted small`,style:{padding:`0 1rem`},children:`Loading…`}),(0,f.jsx)(`ul`,{className:`knowledge-doc-list`,children:(S??[]).map(e=>(0,f.jsx)(`li`,{children:(0,f.jsxs)(`button`,{type:`button`,className:`knowledge-doc-row`,"aria-current":e.id===D?`true`:void 0,onClick:()=>O(e.id),children:[(0,f.jsx)(`span`,{className:`knowledge-doc-title`,children:e.title}),e.summary&&(0,f.jsx)(`span`,{className:`knowledge-doc-summary`,children:e.summary})]})},e.id))}),S&&S.length<w&&(0,f.jsx)(`button`,{type:`button`,className:`knowledge-list-more`,disabled:T,onClick:()=>{E(!0),G(S.length).finally(()=>E(!1))},children:T?`Loading…`:`Show more (${w-S.length} left)`})]})}),(0,f.jsx)(`section`,{className:`knowledge-reader`,"aria-label":`Article`,children:k?(0,f.jsxs)(f.Fragment,{children:[(0,f.jsxs)(`header`,{className:`knowledge-reader-header`,children:[(0,f.jsx)(`h2`,{children:k.title}),(0,f.jsxs)(`p`,{className:`knowledge-reader-meta`,children:[q.get(k.topicId)??k.topicId,k.sourceUpdatedAt?` · snapshot ${k.sourceUpdatedAt.slice(0,10)}`:``]})]}),(0,f.jsx)(`div`,{className:`knowledge-reader-body`,onClickCapture:X,children:Z&&J?(0,f.jsx)(te.Provider,{value:J,children:(0,f.jsx)(ne,{doc:Z,className:`gezel-article-view`,theme:ie,...W?{surface:W}:{},imageDisplayMode:`inline`,showCover:!1})}):(0,f.jsx)(`p`,{className:`error small`,children:`This document could not be rendered.`})}),(0,f.jsxs)(`footer`,{className:`knowledge-reader-footer`,children:[(0,f.jsxs)(`span`,{children:[K?.license??``,k.attribution?.text?` · ${k.attribution.text}`:``]}),(0,f.jsxs)(`span`,{className:`knowledge-footer-actions`,children:[(0,f.jsx)(`button`,{type:`button`,onClick:de,children:V?`Copied`:`Copy citation`}),k.sourceUrl&&(0,f.jsx)(`a`,{href:k.sourceUrl,target:`_blank`,rel:`noreferrer`,children:(0,f.jsx)(`button`,{type:`button`,children:`Open source`})}),(0,f.jsx)(`button`,{type:`button`,onClick:fe,children:`Ask a gezel about this`})]})]})]}):(0,f.jsx)(`div`,{className:`knowledge-empty`,children:j?(0,f.jsx)(`p`,{className:`muted`,children:`Loading…`}):N?(0,f.jsx)(`p`,{className:`error`,children:N}):(0,f.jsx)(`p`,{className:`placeholder`,children:`Pick a document on the left to read it here.`})})})]})}export{_ as KnowledgeView};
|